From 07f9e742691f10b7ff8b0107415eb94e157c2b33 Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Fri, 21 Apr 2017 13:10:07 -0700 Subject: Use SOperand and DOperand for cmp and cmpe. Change-Id: Ie5419a9f423c9dca7e21308ce3b35909500f2ca2 --- src/aarch32/assembler-aarch32.cc | 295 +++++++++++++++++---------------- src/aarch32/assembler-aarch32.h | 114 +++++-------- src/aarch32/disasm-aarch32.cc | 54 +----- src/aarch32/disasm-aarch32.h | 22 ++- src/aarch32/macro-assembler-aarch32.h | 84 ++++------ src/aarch32/operands-aarch32.h | 14 +- test/aarch32/test-assembler-aarch32.cc | 120 ++++++++++++++ test/aarch32/test-disasm-a32.cc | 17 ++ 8 files changed, 398 insertions(+), 322 deletions(-) diff --git a/src/aarch32/assembler-aarch32.cc b/src/aarch32/assembler-aarch32.cc index 239c76c9..183b364a 100644 --- a/src/aarch32/assembler-aarch32.cc +++ b/src/aarch32/assembler-aarch32.cc @@ -15425,168 +15425,176 @@ void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) { Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm); } -void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm) { +void Assembler::vcmp(Condition cond, + DataType dt, + SRegister rd, + const SOperand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); - if (IsUsingT32()) { - // VCMP{}{}.F32 , ; T1 - if (dt.Is(F32)) { - EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); - AdvanceIT(); - return; - } - } else { - // VCMP{}{}.F32 , ; A1 - if (dt.Is(F32) && cond.IsNotNever()) { - EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | - rm.Encode(5, 0)); - return; + if (operand.IsRegister()) { + SRegister rm = operand.GetRegister(); + if (IsUsingT32()) { + // VCMP{}{}.F32 , ; T1 + if (dt.Is(F32)) { + EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0)); + AdvanceIT(); + return; + } + } else { + // VCMP{}{}.F32 , ; A1 + if (dt.Is(F32) && cond.IsNotNever()) { + EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | + rm.Encode(5, 0)); + return; + } } } - Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm); -} - -void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm) { - VIXL_ASSERT(AllowAssembler()); - CheckIT(cond); - if (IsUsingT32()) { - // VCMP{}{}.F64
, ; T1 - if (dt.Is(F64)) { - EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); - AdvanceIT(); - return; - } - } else { - // VCMP{}{}.F64
, ; A1 - if (dt.Is(F64) && cond.IsNotNever()) { - EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | - rm.Encode(5, 0)); - return; + if (operand.IsImmediate()) { + if (IsUsingT32()) { + // VCMP{}{}.F32 , #0.0 ; T2 + if (dt.Is(F32) && (operand.IsFloatZero())) { + EmitT32_32(0xeeb50a40U | rd.Encode(22, 12)); + AdvanceIT(); + return; + } + } else { + // VCMP{}{}.F32 , #0.0 ; A2 + if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) { + EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); + return; + } } } - Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm); + Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand); } -void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, double imm) { +void Assembler::vcmp(Condition cond, + DataType dt, + DRegister rd, + const DOperand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); - if (IsUsingT32()) { - // VCMP{}{}.F32 , #0.0 ; T2 - if (dt.Is(F32) && (imm == 0.0)) { - EmitT32_32(0xeeb50a40U | rd.Encode(22, 12)); - AdvanceIT(); - return; - } - } else { - // VCMP{}{}.F32 , #0.0 ; A2 - if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) { - EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); - return; + if (operand.IsRegister()) { + DRegister rm = operand.GetRegister(); + if (IsUsingT32()) { + // VCMP{}{}.F64
, ; T1 + if (dt.Is(F64)) { + EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0)); + AdvanceIT(); + return; + } + } else { + // VCMP{}{}.F64
, ; A1 + if (dt.Is(F64) && cond.IsNotNever()) { + EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | + rm.Encode(5, 0)); + return; + } } } - Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm); -} - -void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, double imm) { - VIXL_ASSERT(AllowAssembler()); - CheckIT(cond); - if (IsUsingT32()) { - // VCMP{}{}.F64
, #0.0 ; T2 - if (dt.Is(F64) && (imm == 0.0)) { - EmitT32_32(0xeeb50b40U | rd.Encode(22, 12)); - AdvanceIT(); - return; - } - } else { - // VCMP{}{}.F64
, #0.0 ; A2 - if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) { - EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); - return; + if (operand.IsImmediate()) { + if (IsUsingT32()) { + // VCMP{}{}.F64
, #0.0 ; T2 + if (dt.Is(F64) && (operand.IsFloatZero())) { + EmitT32_32(0xeeb50b40U | rd.Encode(22, 12)); + AdvanceIT(); + return; + } + } else { + // VCMP{}{}.F64
, #0.0 ; A2 + if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) { + EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); + return; + } } } - Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm); + Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand); } -void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm) { +void Assembler::vcmpe(Condition cond, + DataType dt, + SRegister rd, + const SOperand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); - if (IsUsingT32()) { - // VCMPE{}{}.F32 , ; T1 - if (dt.Is(F32)) { - EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); - AdvanceIT(); - return; - } - } else { - // VCMPE{}{}.F32 , ; A1 - if (dt.Is(F32) && cond.IsNotNever()) { - EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | - rm.Encode(5, 0)); - return; + if (operand.IsRegister()) { + SRegister rm = operand.GetRegister(); + if (IsUsingT32()) { + // VCMPE{}{}.F32 , ; T1 + if (dt.Is(F32)) { + EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0)); + AdvanceIT(); + return; + } + } else { + // VCMPE{}{}.F32 , ; A1 + if (dt.Is(F32) && cond.IsNotNever()) { + EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | + rm.Encode(5, 0)); + return; + } } } - Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm); -} - -void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm) { - VIXL_ASSERT(AllowAssembler()); - CheckIT(cond); - if (IsUsingT32()) { - // VCMPE{}{}.F64
, ; T1 - if (dt.Is(F64)) { - EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); - AdvanceIT(); - return; - } - } else { - // VCMPE{}{}.F64
, ; A1 - if (dt.Is(F64) && cond.IsNotNever()) { - EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | - rm.Encode(5, 0)); - return; + if (operand.IsImmediate()) { + if (IsUsingT32()) { + // VCMPE{}{}.F32 , #0.0 ; T2 + if (dt.Is(F32) && (operand.IsFloatZero())) { + EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12)); + AdvanceIT(); + return; + } + } else { + // VCMPE{}{}.F32 , #0.0 ; A2 + if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) { + EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); + return; + } } } - Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm); + Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand); } -void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, double imm) { +void Assembler::vcmpe(Condition cond, + DataType dt, + DRegister rd, + const DOperand& operand) { VIXL_ASSERT(AllowAssembler()); CheckIT(cond); - if (IsUsingT32()) { - // VCMPE{}{}.F32 , #0.0 ; T2 - if (dt.Is(F32) && (imm == 0.0)) { - EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12)); - AdvanceIT(); - return; - } - } else { - // VCMPE{}{}.F32 , #0.0 ; A2 - if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) { - EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); - return; + if (operand.IsRegister()) { + DRegister rm = operand.GetRegister(); + if (IsUsingT32()) { + // VCMPE{}{}.F64
, ; T1 + if (dt.Is(F64)) { + EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0)); + AdvanceIT(); + return; + } + } else { + // VCMPE{}{}.F64
, ; A1 + if (dt.Is(F64) && cond.IsNotNever()) { + EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | + rm.Encode(5, 0)); + return; + } } } - Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm); -} - -void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, double imm) { - VIXL_ASSERT(AllowAssembler()); - CheckIT(cond); - if (IsUsingT32()) { - // VCMPE{}{}.F64
, #0.0 ; T2 - if (dt.Is(F64) && (imm == 0.0)) { - EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12)); - AdvanceIT(); - return; - } - } else { - // VCMPE{}{}.F64
, #0.0 ; A2 - if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) { - EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); - return; + if (operand.IsImmediate()) { + if (IsUsingT32()) { + // VCMPE{}{}.F64
, #0.0 ; T2 + if (dt.Is(F64) && (operand.IsFloatZero())) { + EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12)); + AdvanceIT(); + return; + } + } else { + // VCMPE{}{}.F64
, #0.0 ; A2 + if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) { + EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12)); + return; + } } } - Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm); + Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand); } void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) { @@ -20298,7 +20306,6 @@ void Assembler::vmov(Condition cond, CheckIT(cond); if (operand.IsImmediate()) { ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate()); - ImmediateVFP vfp(operand.GetNeonImmediate()); if (IsUsingT32()) { // VMOV{}{}.
, # ; T1 if (encoded_dt.IsValid()) { @@ -20313,14 +20320,6 @@ void Assembler::vmov(Condition cond, return; } } - // VMOV{}{}.F64
, # ; T2 - if (dt.Is(F64) && vfp.IsValid()) { - EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) | - (vfp.GetEncodingValue() & 0xf) | - ((vfp.GetEncodingValue() & 0xf0) << 12)); - AdvanceIT(); - return; - } } else { // VMOV{}{}.
, # ; A1 if (encoded_dt.IsValid()) { @@ -20333,6 +20332,20 @@ void Assembler::vmov(Condition cond, return; } } + } + } + if (operand.IsImmediate()) { + ImmediateVFP vfp(operand.GetNeonImmediate()); + if (IsUsingT32()) { + // VMOV{}{}.F64
, # ; T2 + if (dt.Is(F64) && vfp.IsValid()) { + EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) | + (vfp.GetEncodingValue() & 0xf) | + ((vfp.GetEncodingValue() & 0xf0) << 12)); + AdvanceIT(); + return; + } + } else { // VMOV{}{}.F64
, # ; A2 if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) { EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) | diff --git a/src/aarch32/assembler-aarch32.h b/src/aarch32/assembler-aarch32.h index 521c806f..8ac0bca7 100644 --- a/src/aarch32/assembler-aarch32.h +++ b/src/aarch32/assembler-aarch32.h @@ -381,14 +381,14 @@ class Assembler : public internal::AssemblerBase { QRegister rd, QRegister rn, const QOperand& operand); - typedef void (Assembler::*InstructionCondDtSFi)(Condition cond, - DataType dt, - SRegister rd, - double imm); - typedef void (Assembler::*InstructionCondDtDFi)(Condition cond, - DataType dt, - DRegister rd, - double imm); + typedef void (Assembler::*InstructionCondDtSSop)(Condition cond, + DataType dt, + SRegister rd, + const SOperand& operand); + typedef void (Assembler::*InstructionCondDtDDop)(Condition cond, + DataType dt, + DRegister rd, + const DOperand& operand); typedef void (Assembler::*InstructionCondDtDtDS)( Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm); typedef void (Assembler::*InstructionCondDtDtSD)( @@ -546,18 +546,10 @@ class Assembler : public internal::AssemblerBase { DataType dt, DRegisterLane rd, Register rt); - typedef void (Assembler::*InstructionCondDtDDop)(Condition cond, - DataType dt, - DRegister rd, - const DOperand& operand); typedef void (Assembler::*InstructionCondDtQQop)(Condition cond, DataType dt, QRegister rd, const QOperand& operand); - typedef void (Assembler::*InstructionCondDtSSop)(Condition cond, - DataType dt, - SRegister rd, - const SOperand& operand); typedef void (Assembler::*InstructionCondDtRDx)(Condition cond, DataType dt, Register rt, @@ -1120,12 +1112,12 @@ class Assembler : public internal::AssemblerBase { DRegister /*rm*/) { USE(type); VIXL_ASSERT((type == kVabs) || (type == kVcls) || (type == kVclz) || - (type == kVcmp) || (type == kVcmpe) || (type == kVcnt) || - (type == kVneg) || (type == kVpadal) || (type == kVpaddl) || - (type == kVqabs) || (type == kVqneg) || (type == kVrecpe) || - (type == kVrev16) || (type == kVrev32) || (type == kVrev64) || - (type == kVrsqrte) || (type == kVsqrt) || (type == kVswp) || - (type == kVtrn) || (type == kVuzp) || (type == kVzip)); + (type == kVcnt) || (type == kVneg) || (type == kVpadal) || + (type == kVpaddl) || (type == kVqabs) || (type == kVqneg) || + (type == kVrecpe) || (type == kVrev16) || (type == kVrev32) || + (type == kVrev64) || (type == kVrsqrte) || (type == kVsqrt) || + (type == kVswp) || (type == kVtrn) || (type == kVuzp) || + (type == kVzip)); UnimplementedDelegate(type); } virtual void Delegate(InstructionType type, @@ -1150,8 +1142,7 @@ class Assembler : public internal::AssemblerBase { SRegister /*rd*/, SRegister /*rm*/) { USE(type); - VIXL_ASSERT((type == kVabs) || (type == kVcmp) || (type == kVcmpe) || - (type == kVneg) || (type == kVsqrt)); + VIXL_ASSERT((type == kVabs) || (type == kVneg) || (type == kVsqrt)); UnimplementedDelegate(type); } virtual void Delegate(InstructionType type, @@ -1225,23 +1216,24 @@ class Assembler : public internal::AssemblerBase { UnimplementedDelegate(type); } virtual void Delegate(InstructionType type, - InstructionCondDtSFi /*instruction*/, + InstructionCondDtSSop /*instruction*/, Condition /*cond*/, DataType /*dt*/, SRegister /*rd*/, - double /*imm*/) { + const SOperand& /*operand*/) { USE(type); - VIXL_ASSERT((type == kVcmp) || (type == kVcmpe)); + VIXL_ASSERT((type == kVcmp) || (type == kVcmpe) || (type == kVmov)); UnimplementedDelegate(type); } virtual void Delegate(InstructionType type, - InstructionCondDtDFi /*instruction*/, + InstructionCondDtDDop /*instruction*/, Condition /*cond*/, DataType /*dt*/, DRegister /*rd*/, - double /*imm*/) { + const DOperand& /*operand*/) { USE(type); - VIXL_ASSERT((type == kVcmp) || (type == kVcmpe)); + VIXL_ASSERT((type == kVcmp) || (type == kVcmpe) || (type == kVmov) || + (type == kVmvn)); UnimplementedDelegate(type); } virtual void Delegate(InstructionType type, @@ -1686,16 +1678,6 @@ class Assembler : public internal::AssemblerBase { VIXL_ASSERT((type == kVmov)); UnimplementedDelegate(type); } - virtual void Delegate(InstructionType type, - InstructionCondDtDDop /*instruction*/, - Condition /*cond*/, - DataType /*dt*/, - DRegister /*rd*/, - const DOperand& /*operand*/) { - USE(type); - VIXL_ASSERT((type == kVmov) || (type == kVmvn)); - UnimplementedDelegate(type); - } virtual void Delegate(InstructionType type, InstructionCondDtQQop /*instruction*/, Condition /*cond*/, @@ -1706,16 +1688,6 @@ class Assembler : public internal::AssemblerBase { VIXL_ASSERT((type == kVmov) || (type == kVmvn)); UnimplementedDelegate(type); } - virtual void Delegate(InstructionType type, - InstructionCondDtSSop /*instruction*/, - Condition /*cond*/, - DataType /*dt*/, - SRegister /*rd*/, - const SOperand& /*operand*/) { - USE(type); - VIXL_ASSERT((type == kVmov)); - UnimplementedDelegate(type); - } virtual void Delegate(InstructionType type, InstructionCondDtRDx /*instruction*/, Condition /*cond*/, @@ -4111,29 +4083,31 @@ class Assembler : public internal::AssemblerBase { void vclz(Condition cond, DataType dt, QRegister rd, QRegister rm); void vclz(DataType dt, QRegister rd, QRegister rm) { vclz(al, dt, rd, rm); } - void vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm); - void vcmp(DataType dt, SRegister rd, SRegister rm) { vcmp(al, dt, rd, rm); } - - void vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm); - void vcmp(DataType dt, DRegister rd, DRegister rm) { vcmp(al, dt, rd, rm); } - - void vcmp(Condition cond, DataType dt, SRegister rd, double imm); - void vcmp(DataType dt, SRegister rd, double imm) { vcmp(al, dt, rd, imm); } - - void vcmp(Condition cond, DataType dt, DRegister rd, double imm); - void vcmp(DataType dt, DRegister rd, double imm) { vcmp(al, dt, rd, imm); } - - void vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm); - void vcmpe(DataType dt, SRegister rd, SRegister rm) { vcmpe(al, dt, rd, rm); } + void vcmp(Condition cond, DataType dt, SRegister rd, const SOperand& operand); + void vcmp(DataType dt, SRegister rd, const SOperand& operand) { + vcmp(al, dt, rd, operand); + } - void vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm); - void vcmpe(DataType dt, DRegister rd, DRegister rm) { vcmpe(al, dt, rd, rm); } + void vcmp(Condition cond, DataType dt, DRegister rd, const DOperand& operand); + void vcmp(DataType dt, DRegister rd, const DOperand& operand) { + vcmp(al, dt, rd, operand); + } - void vcmpe(Condition cond, DataType dt, SRegister rd, double imm); - void vcmpe(DataType dt, SRegister rd, double imm) { vcmpe(al, dt, rd, imm); } + void vcmpe(Condition cond, + DataType dt, + SRegister rd, + const SOperand& operand); + void vcmpe(DataType dt, SRegister rd, const SOperand& operand) { + vcmpe(al, dt, rd, operand); + } - void vcmpe(Condition cond, DataType dt, DRegister rd, double imm); - void vcmpe(DataType dt, DRegister rd, double imm) { vcmpe(al, dt, rd, imm); } + void vcmpe(Condition cond, + DataType dt, + DRegister rd, + const DOperand& operand); + void vcmpe(DataType dt, DRegister rd, const DOperand& operand) { + vcmpe(al, dt, rd, operand); + } void vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm); void vcnt(DataType dt, DRegister rd, DRegister rm) { vcnt(al, dt, rd, rm); } diff --git a/src/aarch32/disasm-aarch32.cc b/src/aarch32/disasm-aarch32.cc index 6249fa72..c06597fa 100644 --- a/src/aarch32/disasm-aarch32.cc +++ b/src/aarch32/disasm-aarch32.cc @@ -4346,75 +4346,37 @@ void Disassembler::vclz(Condition cond, void Disassembler::vcmp(Condition cond, DataType dt, SRegister rd, - SRegister rm) { + const SOperand& operand) { os().SetCurrentInstruction(kVcmp, kFpNeon); os() << ToCString(kVcmp) << ConditionPrinter(it_block_, cond) << dt << " " - << rd << ", " << rm; + << rd << ", " << operand; } void Disassembler::vcmp(Condition cond, DataType dt, DRegister rd, - DRegister rm) { - os().SetCurrentInstruction(kVcmp, kFpNeon); - os() << ToCString(kVcmp) << ConditionPrinter(it_block_, cond) << dt << " " - << rd << ", " << rm; -} - -void Disassembler::vcmp(Condition cond, DataType dt, SRegister rd, double imm) { - os().SetCurrentInstruction(kVcmp, kFpNeon); - os() << ToCString(kVcmp) << ConditionPrinter(it_block_, cond) << dt << " " - << rd << ", " - << "#" << std::fixed << std::setprecision(1) << imm - << std::resetiosflags(std::ios_base::floatfield); -} - -void Disassembler::vcmp(Condition cond, DataType dt, DRegister rd, double imm) { + const DOperand& operand) { os().SetCurrentInstruction(kVcmp, kFpNeon); os() << ToCString(kVcmp) << ConditionPrinter(it_block_, cond) << dt << " " - << rd << ", " - << "#" << std::fixed << std::setprecision(1) << imm - << std::resetiosflags(std::ios_base::floatfield); -} - -void Disassembler::vcmpe(Condition cond, - DataType dt, - SRegister rd, - SRegister rm) { - os().SetCurrentInstruction(kVcmpe, kFpNeon); - os() << ToCString(kVcmpe) << ConditionPrinter(it_block_, cond) << dt << " " - << rd << ", " << rm; -} - -void Disassembler::vcmpe(Condition cond, - DataType dt, - DRegister rd, - DRegister rm) { - os().SetCurrentInstruction(kVcmpe, kFpNeon); - os() << ToCString(kVcmpe) << ConditionPrinter(it_block_, cond) << dt << " " - << rd << ", " << rm; + << rd << ", " << operand; } void Disassembler::vcmpe(Condition cond, DataType dt, SRegister rd, - double imm) { + const SOperand& operand) { os().SetCurrentInstruction(kVcmpe, kFpNeon); os() << ToCString(kVcmpe) << ConditionPrinter(it_block_, cond) << dt << " " - << rd << ", " - << "#" << std::fixed << std::setprecision(1) << imm - << std::resetiosflags(std::ios_base::floatfield); + << rd << ", " << operand; } void Disassembler::vcmpe(Condition cond, DataType dt, DRegister rd, - double imm) { + const DOperand& operand) { os().SetCurrentInstruction(kVcmpe, kFpNeon); os() << ToCString(kVcmpe) << ConditionPrinter(it_block_, cond) << dt << " " - << rd << ", " - << "#" << std::fixed << std::setprecision(1) << imm - << std::resetiosflags(std::ios_base::floatfield); + << rd << ", " << operand; } void Disassembler::vcnt(Condition cond, diff --git a/src/aarch32/disasm-aarch32.h b/src/aarch32/disasm-aarch32.h index b5948045..5e0ba2bb 100644 --- a/src/aarch32/disasm-aarch32.h +++ b/src/aarch32/disasm-aarch32.h @@ -1537,21 +1537,19 @@ class Disassembler { void vclz(Condition cond, DataType dt, QRegister rd, QRegister rm); - void vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm); + void vcmp(Condition cond, DataType dt, SRegister rd, const SOperand& operand); - void vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm); + void vcmp(Condition cond, DataType dt, DRegister rd, const DOperand& operand); - void vcmp(Condition cond, DataType dt, SRegister rd, double imm); - - void vcmp(Condition cond, DataType dt, DRegister rd, double imm); - - void vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm); - - void vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm); - - void vcmpe(Condition cond, DataType dt, SRegister rd, double imm); + void vcmpe(Condition cond, + DataType dt, + SRegister rd, + const SOperand& operand); - void vcmpe(Condition cond, DataType dt, DRegister rd, double imm); + void vcmpe(Condition cond, + DataType dt, + DRegister rd, + const DOperand& operand); void vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm); diff --git a/src/aarch32/macro-assembler-aarch32.h b/src/aarch32/macro-assembler-aarch32.h index cf444a77..d018bafb 100644 --- a/src/aarch32/macro-assembler-aarch32.h +++ b/src/aarch32/macro-assembler-aarch32.h @@ -6256,89 +6256,69 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface { } void Vclz(DataType dt, QRegister rd, QRegister rm) { Vclz(al, dt, rd, rm); } - void Vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm) { + void Vcmp(Condition cond, + DataType dt, + SRegister rd, + const SOperand& operand) { VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); - VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); + VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); VIXL_ASSERT(allow_macro_instructions_); VIXL_ASSERT(OutsideITBlock()); MacroEmissionCheckScope guard(this); ITScope it_scope(this, &cond); - vcmp(cond, dt, rd, rm); + vcmp(cond, dt, rd, operand); } - void Vcmp(DataType dt, SRegister rd, SRegister rm) { Vcmp(al, dt, rd, rm); } - - void Vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm) { - VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); - VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); - VIXL_ASSERT(allow_macro_instructions_); - VIXL_ASSERT(OutsideITBlock()); - MacroEmissionCheckScope guard(this); - ITScope it_scope(this, &cond); - vcmp(cond, dt, rd, rm); + void Vcmp(DataType dt, SRegister rd, const SOperand& operand) { + Vcmp(al, dt, rd, operand); } - void Vcmp(DataType dt, DRegister rd, DRegister rm) { Vcmp(al, dt, rd, rm); } - void Vcmp(Condition cond, DataType dt, SRegister rd, double imm) { + void Vcmp(Condition cond, + DataType dt, + DRegister rd, + const DOperand& operand) { VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); + VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); VIXL_ASSERT(allow_macro_instructions_); VIXL_ASSERT(OutsideITBlock()); MacroEmissionCheckScope guard(this); ITScope it_scope(this, &cond); - vcmp(cond, dt, rd, imm); + vcmp(cond, dt, rd, operand); } - void Vcmp(DataType dt, SRegister rd, double imm) { Vcmp(al, dt, rd, imm); } - - void Vcmp(Condition cond, DataType dt, DRegister rd, double imm) { - VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); - VIXL_ASSERT(allow_macro_instructions_); - VIXL_ASSERT(OutsideITBlock()); - MacroEmissionCheckScope guard(this); - ITScope it_scope(this, &cond); - vcmp(cond, dt, rd, imm); + void Vcmp(DataType dt, DRegister rd, const DOperand& operand) { + Vcmp(al, dt, rd, operand); } - void Vcmp(DataType dt, DRegister rd, double imm) { Vcmp(al, dt, rd, imm); } - void Vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm) { + void Vcmpe(Condition cond, + DataType dt, + SRegister rd, + const SOperand& operand) { VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); - VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); + VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); VIXL_ASSERT(allow_macro_instructions_); VIXL_ASSERT(OutsideITBlock()); MacroEmissionCheckScope guard(this); ITScope it_scope(this, &cond); - vcmpe(cond, dt, rd, rm); + vcmpe(cond, dt, rd, operand); } - void Vcmpe(DataType dt, SRegister rd, SRegister rm) { Vcmpe(al, dt, rd, rm); } - - void Vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm) { - VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); - VIXL_ASSERT(!AliasesAvailableScratchRegister(rm)); - VIXL_ASSERT(allow_macro_instructions_); - VIXL_ASSERT(OutsideITBlock()); - MacroEmissionCheckScope guard(this); - ITScope it_scope(this, &cond); - vcmpe(cond, dt, rd, rm); + void Vcmpe(DataType dt, SRegister rd, const SOperand& operand) { + Vcmpe(al, dt, rd, operand); } - void Vcmpe(DataType dt, DRegister rd, DRegister rm) { Vcmpe(al, dt, rd, rm); } - void Vcmpe(Condition cond, DataType dt, SRegister rd, double imm) { + void Vcmpe(Condition cond, + DataType dt, + DRegister rd, + const DOperand& operand) { VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); + VIXL_ASSERT(!AliasesAvailableScratchRegister(operand)); VIXL_ASSERT(allow_macro_instructions_); VIXL_ASSERT(OutsideITBlock()); MacroEmissionCheckScope guard(this); ITScope it_scope(this, &cond); - vcmpe(cond, dt, rd, imm); + vcmpe(cond, dt, rd, operand); } - void Vcmpe(DataType dt, SRegister rd, double imm) { Vcmpe(al, dt, rd, imm); } - - void Vcmpe(Condition cond, DataType dt, DRegister rd, double imm) { - VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); - VIXL_ASSERT(allow_macro_instructions_); - VIXL_ASSERT(OutsideITBlock()); - MacroEmissionCheckScope guard(this); - ITScope it_scope(this, &cond); - vcmpe(cond, dt, rd, imm); + void Vcmpe(DataType dt, DRegister rd, const DOperand& operand) { + Vcmpe(al, dt, rd, operand); } - void Vcmpe(DataType dt, DRegister rd, double imm) { Vcmpe(al, dt, rd, imm); } void Vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) { VIXL_ASSERT(!AliasesAvailableScratchRegister(rd)); diff --git a/src/aarch32/operands-aarch32.h b/src/aarch32/operands-aarch32.h index 27497968..1d18bfd3 100644 --- a/src/aarch32/operands-aarch32.h +++ b/src/aarch32/operands-aarch32.h @@ -314,6 +314,11 @@ class NeonImmediate { bool IsInteger() const { return IsInteger32() | IsInteger64(); } bool IsFloat() const { return immediate_type_.Is(F32); } bool IsDouble() const { return immediate_type_.Is(F64); } + bool IsFloatZero() const { + if (immediate_type_.Is(F32)) return imm_.f_ == 0.0f; + if (immediate_type_.Is(F64)) return imm_.d_ == 0.0; + return false; + } template bool CanConvert() const { @@ -397,6 +402,10 @@ class NeonOperand { bool IsImmediate() const { return !rm_.IsValid(); } bool IsRegister() const { return rm_.IsValid(); } + bool IsFloatZero() const { + VIXL_ASSERT(IsImmediate()); + return imm_.IsFloatZero(); + } const NeonImmediate& GetNeonImmediate() const { return imm_; } @@ -427,6 +436,9 @@ class SOperand : public NeonOperand { // where is 32bit float SOperand(float immediate) // NOLINT(runtime/explicit) : NeonOperand(immediate) {} + // where is 64bit float + SOperand(double immediate) // NOLINT(runtime/explicit) + : NeonOperand(immediate) {} SOperand(const NeonImmediate& imm) // NOLINT(runtime/explicit) : NeonOperand(imm) {} @@ -541,7 +553,7 @@ class ImmediateVFP : public EncodingValue { } else if (neon_imm.IsDouble()) { const double imm = neon_imm.GetImmediate(); if (VFP::IsImmFP64(imm)) { - SetEncodingValue(VFP::FP32ToImm8(imm)); + SetEncodingValue(VFP::FP64ToImm8(imm)); } } } diff --git a/test/aarch32/test-assembler-aarch32.cc b/test/aarch32/test-assembler-aarch32.cc index 7ebd9022..23881f77 100644 --- a/test/aarch32/test-assembler-aarch32.cc +++ b/test/aarch32/test-assembler-aarch32.cc @@ -2835,6 +2835,126 @@ TEST(msr_i) { } +TEST(vcmp_s) { + SETUP(); + + START(); + + __ Vmov(s0, 1.0); + __ Vmov(s1, 2.0); + __ Vmov(s2, 0.0); + + __ Vcmp(F32, s1, s0); + __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR); + + __ Vcmp(F32, s0, 0.0f); + __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR); + + __ Vcmp(F32, s2, 0.0f); + __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR); + + END(); + + RUN(); + + ASSERT_EQUAL_32(0x20000000, r0); + ASSERT_EQUAL_32(0x80000000, r1); + ASSERT_EQUAL_32(0x60000000, r2); + + TEARDOWN(); +} + + +TEST(vcmp_d) { + SETUP(); + + START(); + + __ Vmov(d0, 1.0); + __ Vmov(d1, 2.0); + __ Vmov(d2, 0.0); + + __ Vcmp(F64, d1, d0); + __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR); + + __ Vcmp(F64, d0, 0.0); + __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR); + + __ Vcmp(F64, d2, 0.0); + __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR); + + END(); + + RUN(); + + ASSERT_EQUAL_32(0x20000000, r0); + ASSERT_EQUAL_32(0x80000000, r1); + ASSERT_EQUAL_32(0x60000000, r2); + + TEARDOWN(); +} + + +TEST(vcmpe_s) { + SETUP(); + + START(); + + __ Vmov(s0, 1.0); + __ Vmov(s1, 2.0); + __ Vmov(s2, 0.0); + + __ Vcmpe(F32, s1, s0); + __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR); + + __ Vcmpe(F32, s0, 0.0f); + __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR); + + __ Vcmpe(F32, s2, 0.0f); + __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR); + + END(); + + RUN(); + + ASSERT_EQUAL_32(0x20000000, r0); + ASSERT_EQUAL_32(0x80000000, r1); + ASSERT_EQUAL_32(0x60000000, r2); + + TEARDOWN(); +} + + +TEST(vcmpe_d) { + SETUP(); + + START(); + + __ Vmov(d0, 1.0); + __ Vmov(d1, 2.0); + __ Vmov(d2, 0.0); + + __ Vcmpe(F64, d1, d0); + __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR); + + __ Vcmpe(F64, d0, 0.0); + __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR); + + __ Vcmpe(F64, d2, 0.0); + __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR); + + END(); + + RUN(); + + ASSERT_EQUAL_32(0x20000000, r0); + ASSERT_EQUAL_32(0x80000000, r1); + ASSERT_EQUAL_32(0x60000000, r2); + + TEARDOWN(); +} + + TEST(vmrs_vmsr) { SETUP(); diff --git a/test/aarch32/test-disasm-a32.cc b/test/aarch32/test-disasm-a32.cc index b5b41ce5..dae911dc 100644 --- a/test/aarch32/test-disasm-a32.cc +++ b/test/aarch32/test-disasm-a32.cc @@ -3477,6 +3477,23 @@ TEST(preloads) { } +TEST(vcmp_vcmpe) { + SETUP(); + + COMPARE_BOTH(Vcmp(F32, s0, s1), "vcmp.f32 s0, s1\n"); + COMPARE_BOTH(Vcmp(F64, d0, d1), "vcmp.f64 d0, d1\n"); + COMPARE_BOTH(Vcmp(F32, s0, 0.0f), "vcmp.f32 s0, #0.0\n"); + COMPARE_BOTH(Vcmp(F64, d0, 0.0), "vcmp.f64 d0, #0.0\n"); + + COMPARE_BOTH(Vcmpe(F32, s0, s1), "vcmpe.f32 s0, s1\n"); + COMPARE_BOTH(Vcmpe(F64, d0, d1), "vcmpe.f64 d0, d1\n"); + COMPARE_BOTH(Vcmpe(F32, s0, 0.0f), "vcmpe.f32 s0, #0.0\n"); + COMPARE_BOTH(Vcmpe(F64, d0, 0.0), "vcmpe.f64 d0, #0.0\n"); + + CLEANUP(); +} + + TEST(vmrs_vmsr) { SETUP(); -- cgit v1.2.3