diff --git a/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s b/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s index da28388c96094..a4350fc6dc2cb 100644 --- a/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s +++ b/llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s @@ -37,3 +37,39 @@ RUN: FileCheck %s --check-prefix=FPR64-ASM < %t.s FPR64-ASM: : FPR64-ASM: movi d{{[0-9]+}}, #0000000000000000 FPR64-ASM-NEXT: addv h{{[0-9]+}}, v{{[0-9]+}}.4h + +## FPR32 Register Class Initialization Testcase +RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=FABSSr --benchmark-phase=assemble-measured-code 2>&1 +RUN: llvm-objdump -d %d > %t.s +RUN: FileCheck %s --check-prefix=FPR32-ASM < %t.s +FPR32-ASM: : +FPR32-ASM: movi d{{[0-9]+}}, #0000000000000000 +FPR32-ASM-NEXT: fabs s{{[0-9]+}}, s{{[0-9]+}} + + +## FPR16 Register Class Initialization Testcase +RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=FABSHr --benchmark-phase=assemble-measured-code 2>&1 +RUN: llvm-objdump -d %d > %t.s +RUN: FileCheck %s --check-prefix=FPR16-ASM < %t.s +FPR16-ASM: : +FPR16-ASM: movi d{{[0-9]+}}, #0000000000000000 +FPR16-ASM-NEXT: fabs h{{[0-9]+}}, h{{[0-9]+}} + +## FPR8 Register Class Initialization Testcase +RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=SQABSv1i8 --benchmark-phase=assemble-measured-code 2>&1 +RUN: llvm-objdump -d %d > %t.s +RUN: FileCheck %s --check-prefix=FPR8-ASM < %t.s +FPR8-ASM: : +FPR8-ASM: movi d{{[0-9]+}}, #0000000000000000 +FPR8-ASM-NEXT: sqabs b{{[0-9]+}}, b{{[0-9]+}} + + +## FPCR Register Class Initialization Testcase +RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=BFCVT --benchmark-phase=assemble-measured-code 2>&1 +RUN: llvm-objdump -d %d > %t.s +RUN: FileCheck %s --check-prefix=FPCR-ASM < %t.s +FPCR-ASM: : +FPCR-ASM: movi d{{[0-9]+}}, #0000000000000000 +FPCR-ASM-NEXT: mov x8, #0x0 +FPCR-ASM-NEXT: msr FPCR, x8 +FPCR-ASM-NEXT: bfcvt h{{[0-9]+}}, s{{[0-9]+}} diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp index ed36cb2f75d5b..bf2b053003ce3 100644 --- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp @@ -28,8 +28,8 @@ static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) { // Generates instruction to load an immediate value into a register. static MCInst loadImmediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value) { - assert (Value.getBitWidth() <= RegBitWidth && - "Value must fit in the Register"); + assert(Value.getBitWidth() <= RegBitWidth && + "Value must fit in the Register"); return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth)) .addReg(Reg) .addImm(Value.getZExtValue()); @@ -53,11 +53,25 @@ static MCInst loadPPRImmediate(MCRegister Reg, unsigned RegBitWidth, .addImm(31); // All lanes true for 16 bits } +// Generates instructions to load an immediate value into an FPCR register. +static std::vector +loadFPCRImmediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value) { + MCRegister TempReg = AArch64::X8; + MCInst LoadImm = MCInstBuilder(AArch64::MOVi64imm).addReg(TempReg).addImm(0); + MCInst MoveToFPCR = + MCInstBuilder(AArch64::MSR).addImm(AArch64SysReg::FPCR).addReg(TempReg); + return {LoadImm, MoveToFPCR}; +} + // Fetch base-instruction to load an FP immediate value into a register. static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) { switch (RegBitWidth) { + case 16: + return AArch64::FMOVH0; // FMOVHi; + case 32: + return AArch64::FMOVS0; // FMOVSi; case 64: - return AArch64::MOVID; //FMOVDi; + return AArch64::MOVID; // FMOVDi; case 128: return AArch64::MOVIv2d_ns; } @@ -67,11 +81,12 @@ static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) { // Generates instruction to load an FP immediate value into a register. static MCInst loadFPImmediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value) { - assert(Value.getZExtValue() == 0 && - "Expected initialisation value 0"); - return MCInstBuilder(getLoadFPImmediateOpcode(RegBitWidth)) - .addReg(Reg) - .addImm(Value.getZExtValue()); + assert(Value.getZExtValue() == 0 && "Expected initialisation value 0"); + MCInst Instructions = + MCInstBuilder(getLoadFPImmediateOpcode(RegBitWidth)).addReg(Reg); + if (RegBitWidth >= 64) + Instructions.addOperand(MCOperand::createImm(Value.getZExtValue())); + return Instructions; } #include "AArch64GenExegesis.inc" @@ -92,12 +107,20 @@ class ExegesisAArch64Target : public ExegesisTarget { return {loadImmediate(Reg, 64, Value)}; if (AArch64::PPRRegClass.contains(Reg)) return {loadPPRImmediate(Reg, 16, Value)}; + if (AArch64::FPR8RegClass.contains(Reg)) + return {loadFPImmediate(Reg - AArch64::B0 + AArch64::D0, 64, Value)}; + if (AArch64::FPR16RegClass.contains(Reg)) + return {loadFPImmediate(Reg, 16, Value)}; + if (AArch64::FPR32RegClass.contains(Reg)) + return {loadFPImmediate(Reg, 32, Value)}; if (AArch64::FPR64RegClass.contains(Reg)) return {loadFPImmediate(Reg, 64, Value)}; if (AArch64::FPR128RegClass.contains(Reg)) return {loadFPImmediate(Reg, 128, Value)}; if (AArch64::ZPRRegClass.contains(Reg)) return {loadZPRImmediate(Reg, 128, Value)}; + if (Reg == AArch64::FPCR) + return {loadFPCRImmediate(Reg, 32, Value)}; errs() << "setRegTo is not implemented, results will be unreliable\n"; return {};