@@ -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,11 +53,25 @@ 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+
5666// Fetch base-instruction to load an FP immediate value into a register.
5767static unsigned getLoadFPImmediateOpcode (unsigned RegBitWidth) {
5868 switch (RegBitWidth) {
69+ case 16 :
70+ return AArch64::FMOVH0; // FMOVHi;
71+ case 32 :
72+ return AArch64::FMOVS0; // FMOVSi;
5973 case 64 :
60- return AArch64::MOVID; // FMOVDi;
74+ return AArch64::MOVID; // FMOVDi;
6175 case 128 :
6276 return AArch64::MOVIv2d_ns;
6377 }
@@ -67,11 +81,12 @@ static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) {
6781// Generates instruction to load an FP immediate value into a register.
6882static MCInst loadFPImmediate (MCRegister Reg, unsigned RegBitWidth,
6983 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 ());
84+ assert (Value.getZExtValue () == 0 && " Expected initialisation value 0" );
85+ MCInst Instructions =
86+ MCInstBuilder (getLoadFPImmediateOpcode (RegBitWidth)).addReg (Reg);
87+ if (RegBitWidth >= 64 )
88+ Instructions.addOperand (MCOperand::createImm (Value.getZExtValue ()));
89+ return Instructions;
7590}
7691
7792#include " AArch64GenExegesis.inc"
@@ -92,12 +107,20 @@ class ExegesisAArch64Target : public ExegesisTarget {
92107 return {loadImmediate (Reg, 64 , Value)};
93108 if (AArch64::PPRRegClass.contains (Reg))
94109 return {loadPPRImmediate (Reg, 16 , Value)};
110+ if (AArch64::FPR8RegClass.contains (Reg))
111+ return {loadFPImmediate (Reg - AArch64::B0 + AArch64::D0, 64 , Value)};
112+ if (AArch64::FPR16RegClass.contains (Reg))
113+ return {loadFPImmediate (Reg, 16 , Value)};
114+ if (AArch64::FPR32RegClass.contains (Reg))
115+ return {loadFPImmediate (Reg, 32 , Value)};
95116 if (AArch64::FPR64RegClass.contains (Reg))
96117 return {loadFPImmediate (Reg, 64 , Value)};
97118 if (AArch64::FPR128RegClass.contains (Reg))
98119 return {loadFPImmediate (Reg, 128 , Value)};
99120 if (AArch64::ZPRRegClass.contains (Reg))
100121 return {loadZPRImmediate (Reg, 128 , Value)};
122+ if (Reg == AArch64::FPCR)
123+ return {loadFPCRImmediate (Reg, 32 , Value)};
101124
102125 errs () << " setRegTo is not implemented, results will be unreliable\n " ;
103126 return {};
0 commit comments