@@ -28,8 +28,8 @@ static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
28
28
// Generates instruction to load an immediate value into a register.
29
29
static MCInst loadImmediate (MCRegister Reg, unsigned RegBitWidth,
30
30
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" );
33
33
return MCInstBuilder (getLoadImmediateOpcode (RegBitWidth))
34
34
.addReg (Reg)
35
35
.addImm (Value.getZExtValue ());
@@ -53,11 +53,25 @@ static MCInst loadPPRImmediate(MCRegister Reg, unsigned RegBitWidth,
53
53
.addImm (31 ); // All lanes true for 16 bits
54
54
}
55
55
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
+
56
66
// Fetch base-instruction to load an FP immediate value into a register.
57
67
static unsigned getLoadFPImmediateOpcode (unsigned RegBitWidth) {
58
68
switch (RegBitWidth) {
69
+ case 16 :
70
+ return AArch64::FMOVH0; // FMOVHi;
71
+ case 32 :
72
+ return AArch64::FMOVS0; // FMOVSi;
59
73
case 64 :
60
- return AArch64::MOVID; // FMOVDi;
74
+ return AArch64::MOVID; // FMOVDi;
61
75
case 128 :
62
76
return AArch64::MOVIv2d_ns;
63
77
}
@@ -67,11 +81,12 @@ static unsigned getLoadFPImmediateOpcode(unsigned RegBitWidth) {
67
81
// Generates instruction to load an FP immediate value into a register.
68
82
static MCInst loadFPImmediate (MCRegister Reg, unsigned RegBitWidth,
69
83
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;
75
90
}
76
91
77
92
#include " AArch64GenExegesis.inc"
@@ -92,12 +107,20 @@ class ExegesisAArch64Target : public ExegesisTarget {
92
107
return {loadImmediate (Reg, 64 , Value)};
93
108
if (AArch64::PPRRegClass.contains (Reg))
94
109
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)};
95
116
if (AArch64::FPR64RegClass.contains (Reg))
96
117
return {loadFPImmediate (Reg, 64 , Value)};
97
118
if (AArch64::FPR128RegClass.contains (Reg))
98
119
return {loadFPImmediate (Reg, 128 , Value)};
99
120
if (AArch64::ZPRRegClass.contains (Reg))
100
121
return {loadZPRImmediate (Reg, 128 , Value)};
122
+ if (Reg == AArch64::FPCR)
123
+ return {loadFPCRImmediate (Reg, 32 , Value)};
101
124
102
125
errs () << " setRegTo is not implemented, results will be unreliable\n " ;
103
126
return {};
0 commit comments