Skip to content

Commit 5f3de22

Browse files
committed
[llvm-exegesis] Adding support for FPR8/16/32 and FPCR for setReg warning in Aarch64.
Current implementation (for Aarch64) in llvm-exegesis only supports GRP32, GPR64, FPR64/128, PPR16 and ZPR128 register class, thus for opcodes variants which used llvm-exegesis throws warning "setReg is not implemented". This code will handle the all rest floating point register classes and initialize the registers using appropriate base instruction. And appropriate testcases for the four register classes.
1 parent 4fee398 commit 5f3de22

File tree

2 files changed

+88
-7
lines changed

2 files changed

+88
-7
lines changed

llvm/test/tools/llvm-exegesis/AArch64/setReg_init_check.s

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,40 @@ RUN: FileCheck %s --check-prefix=FPR64-ASM < %t.s
3737
FPR64-ASM: <foo>:
3838
FPR64-ASM: movi d{{[0-9]+}}, #0000000000000000
3939
FPR64-ASM-NEXT: addv h{{[0-9]+}}, v{{[0-9]+}}.4h
40+
41+
## FPR32 Register Class Initialization Testcase
42+
RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=FABSSr --benchmark-phase=assemble-measured-code 2>&1
43+
RUN: llvm-objdump -d %d > %t.s
44+
RUN: FileCheck %s --check-prefix=FPR32-ASM < %t.s
45+
FPR32-ASM: <foo>:
46+
FPR32-ASM: movi d{{[0-9]+}}, #0000000000000000
47+
FPR32-ASM-NEXT: fabs s{{[0-9]+}}, s{{[0-9]+}}
48+
49+
50+
## FPR16 Register Class Initialization Testcase
51+
RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=FABSHr --benchmark-phase=assemble-measured-code 2>&1
52+
RUN: llvm-objdump -d %d > %t.s
53+
RUN: FileCheck %s --check-prefix=FPR16-ASM < %t.s
54+
FPR16-ASM: <foo>:
55+
FPR16-ASM: movi d{{[0-9]+}}, #0000000000000000
56+
FPR16-ASM-NEXT: fabs h{{[0-9]+}}, h{{[0-9]+}}
57+
58+
## FPR8 Register Class Initialization Testcase
59+
RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=SQABSv1i8 --benchmark-phase=assemble-measured-code 2>&1
60+
RUN: llvm-objdump -d %d > %t.s
61+
RUN: FileCheck %s --check-prefix=FPR8-ASM < %t.s
62+
FPR8-ASM: <foo>:
63+
FPR8-ASM: mov w{{[0-9]+}}, #0x0
64+
FPR8-ASM-NEXT: fmov h{{[0-9]+}}, w{{[0-9]+}}
65+
FPR8-ASM-NEXT: sqabs b{{[0-9]+}}, b{{[0-9]+}}
66+
67+
68+
## FPCR Register Class Initialization Testcase
69+
RUN: llvm-exegesis -mcpu=neoverse-v2 -mode=latency --dump-object-to-disk=%d --opcode-name=BFCVT --benchmark-phase=assemble-measured-code 2>&1
70+
RUN: llvm-objdump -d %d > %t.s
71+
RUN: FileCheck %s --check-prefix=FPCR-ASM < %t.s
72+
FPCR-ASM: <foo>:
73+
FPCR-ASM: movi d{{[0-9]+}}, #0000000000000000
74+
FPCR-ASM-NEXT: mov x{{[0-9]+}}, #0x0
75+
FPCR-ASM-NEXT: msr FPCR, x{{[0-9]+}}
76+
FPCR-ASM-NEXT: bfcvt h{{[0-9]+}}, s{{[0-9]+}}

llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
2828
// Generates instruction to load an immediate value into a register.
2929
static MCInst loadImmediate(MCRegister Reg, unsigned RegBitWidth,
3030
const APInt &Value) {
31-
assert (Value.getBitWidth() <= RegBitWidth &&
32-
"Value must fit in the Register");
31+
assert(Value.getBitWidth() <= RegBitWidth &&
32+
"Value must fit in the Register");
3333
return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
3434
.addReg(Reg)
3535
.addImm(Value.getZExtValue());
@@ -53,9 +53,44 @@ static MCInst loadPPRImmediate(MCRegister Reg, unsigned RegBitWidth,
5353
.addImm(31); // All lanes true for 16 bits
5454
}
5555

56+
// Generates instructions to load an immediate value into an FPCR register.
57+
static std::vector<MCInst>
58+
loadFPCRImmediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value) {
59+
MCRegister TempReg = AArch64::X8;
60+
MCInst LoadImm = MCInstBuilder(AArch64::MOVi64imm).addReg(TempReg).addImm(0);
61+
MCInst MoveToFPCR =
62+
MCInstBuilder(AArch64::MSR).addImm(AArch64SysReg::FPCR).addReg(TempReg);
63+
return {LoadImm, MoveToFPCR};
64+
}
65+
66+
// Generates instructions to load an immediate value into an FPR8 register.
67+
static std::vector<MCInst>
68+
loadFP8Immediate(MCRegister Reg, unsigned RegBitWidth, const APInt &Value) {
69+
assert(Value.getBitWidth() <= 8 && "Value must fit in 8 bits");
70+
71+
// Use a temporary general-purpose register (W8) to hold the 8-bit value
72+
MCRegister TempReg = AArch64::W8;
73+
74+
// Load the 8-bit value into a general-purpose register (W8)
75+
MCInst LoadImm = MCInstBuilder(AArch64::MOVi32imm)
76+
.addReg(TempReg)
77+
.addImm(Value.getZExtValue());
78+
79+
// Move the value from the general-purpose register to the FPR16 register
80+
// Convert the FPR8 register to an FPR16 register
81+
MCRegister FPR16Reg = Reg + (AArch64::H0 - AArch64::B0);
82+
MCInst MoveToFPR =
83+
MCInstBuilder(AArch64::FMOVWHr).addReg(FPR16Reg).addReg(TempReg);
84+
return {LoadImm, MoveToFPR};
85+
}
86+
5687
// Fetch base-instruction to load an FP immediate value into a register.
5788
static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) {
5889
switch (RegBitWidth) {
90+
case 16:
91+
return AArch64::FMOVH0; //FMOVHi;
92+
case 32:
93+
return AArch64::FMOVS0; //FMOVSi;
5994
case 64:
6095
return AArch64::MOVID; //FMOVDi;
6196
case 128:
@@ -67,11 +102,12 @@ static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) {
67102
// Generates instruction to load an FP immediate value into a register.
68103
static MCInst loadFPImmediate(MCRegister Reg, unsigned RegBitWidth,
69104
const APInt &Value) {
70-
assert(Value.getZExtValue() == 0 &&
71-
"Expected initialisation value 0");
72-
return MCInstBuilder(getLoadFPImmediateOpcode(RegBitWidth))
73-
.addReg(Reg)
74-
.addImm(Value.getZExtValue());
105+
assert(Value.getZExtValue() == 0 && "Expected initialisation value 0");
106+
MCInst Instructions =
107+
MCInstBuilder(getLoadFPImmediateOpcode(RegBitWidth)).addReg(Reg);
108+
if (RegBitWidth >= 64)
109+
Instructions.addOperand(MCOperand::createImm(Value.getZExtValue()));
110+
return Instructions;
75111
}
76112

77113
#include "AArch64GenExegesis.inc"
@@ -92,12 +128,20 @@ class ExegesisAArch64Target : public ExegesisTarget {
92128
return {loadImmediate(Reg, 64, Value)};
93129
if (AArch64::PPRRegClass.contains(Reg))
94130
return {loadPPRImmediate(Reg, 16, Value)};
131+
if (AArch64::FPR8RegClass.contains(Reg))
132+
return loadFP8Immediate(Reg, 8, Value);
133+
if (AArch64::FPR16RegClass.contains(Reg))
134+
return {loadFPImmediate(Reg, 16, Value)};
135+
if (AArch64::FPR32RegClass.contains(Reg))
136+
return {loadFPImmediate(Reg, 32, Value)};
95137
if (AArch64::FPR64RegClass.contains(Reg))
96138
return {loadFPImmediate(Reg, 64, Value)};
97139
if (AArch64::FPR128RegClass.contains(Reg))
98140
return {loadFPImmediate(Reg, 128, Value)};
99141
if (AArch64::ZPRRegClass.contains(Reg))
100142
return {loadZPRImmediate(Reg, 128, Value)};
143+
if (Reg == AArch64::FPCR)
144+
return {loadFPCRImmediate(Reg, 32, Value)};
101145

102146
errs() << "setRegTo is not implemented, results will be unreliable\n";
103147
return {};

0 commit comments

Comments
 (0)