@@ -28,8 +28,8 @@ static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
2828// Generates instruction to load an immediate value into a register.
2929static 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.
5788static 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.
68103static 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