@@ -135,6 +135,9 @@ class X86FastISel final : public FastISel {
135
135
136
136
bool handleConstantAddresses (const Value *V, X86AddressMode &AM);
137
137
138
+ unsigned X86MaterializeInt (const ConstantInt *CI, MVT VT);
139
+ unsigned X86MaterializeFP (const ConstantFP *CFP, MVT VT);
140
+ unsigned X86MaterializeGV (const GlobalValue *GV,MVT VT);
138
141
unsigned TargetMaterializeConstant (const Constant *C) override ;
139
142
140
143
unsigned TargetMaterializeAlloca (const AllocaInst *C) override ;
@@ -3099,10 +3102,15 @@ X86FastISel::TargetSelectInstruction(const Instruction *I) {
3099
3102
return false ;
3100
3103
}
3101
3104
3102
- unsigned X86FastISel::TargetMaterializeConstant (const Constant *C) {
3103
- MVT VT;
3104
- if (!isTypeLegal (C->getType (), VT))
3105
+ unsigned X86FastISel::X86MaterializeInt (const ConstantInt *CI, MVT VT) {
3106
+ if (VT > MVT::i64)
3105
3107
return 0 ;
3108
+ return FastEmit_i (VT, VT, ISD::Constant, CI->getZExtValue ());
3109
+ }
3110
+
3111
+ unsigned X86FastISel::X86MaterializeFP (const ConstantFP *CFP, MVT VT) {
3112
+ if (CFP->isNullValue ())
3113
+ return TargetMaterializeFloatZero (CFP);
3106
3114
3107
3115
// Can't handle alternate code models yet.
3108
3116
if (TM.getCodeModel () != CodeModel::Small)
@@ -3113,23 +3121,6 @@ unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
3113
3121
const TargetRegisterClass *RC = nullptr ;
3114
3122
switch (VT.SimpleTy ) {
3115
3123
default : return 0 ;
3116
- case MVT::i8:
3117
- Opc = X86::MOV8rm;
3118
- RC = &X86::GR8RegClass;
3119
- break ;
3120
- case MVT::i16:
3121
- Opc = X86::MOV16rm;
3122
- RC = &X86::GR16RegClass;
3123
- break ;
3124
- case MVT::i32:
3125
- Opc = X86::MOV32rm;
3126
- RC = &X86::GR32RegClass;
3127
- break ;
3128
- case MVT::i64:
3129
- // Must be in x86-64 mode.
3130
- Opc = X86::MOV64rm;
3131
- RC = &X86::GR64RegClass;
3132
- break ;
3133
3124
case MVT::f32:
3134
3125
if (X86ScalarSSEf32) {
3135
3126
Opc = Subtarget->hasAVX () ? X86::VMOVSSrm : X86::MOVSSrm;
@@ -3153,39 +3144,11 @@ unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
3153
3144
return 0 ;
3154
3145
}
3155
3146
3156
- // Materialize addresses with LEA/MOV instructions.
3157
- if (isa<GlobalValue>(C)) {
3158
- X86AddressMode AM;
3159
- if (X86SelectAddress (C, AM)) {
3160
- // If the expression is just a basereg, then we're done, otherwise we need
3161
- // to emit an LEA.
3162
- if (AM.BaseType == X86AddressMode::RegBase &&
3163
- AM.IndexReg == 0 && AM.Disp == 0 && AM.GV == nullptr )
3164
- return AM.Base .Reg ;
3165
-
3166
- unsigned ResultReg = createResultReg (RC);
3167
- if (TM.getRelocationModel () == Reloc::Static &&
3168
- TLI.getPointerTy () == MVT::i64) {
3169
- // The displacement code be more than 32 bits away so we need to use
3170
- // an instruction with a 64 bit immediate
3171
- Opc = X86::MOV64ri;
3172
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DbgLoc,
3173
- TII.get (Opc), ResultReg).addGlobalAddress (cast<GlobalValue>(C));
3174
- } else {
3175
- Opc = TLI.getPointerTy () == MVT::i32 ? X86::LEA32r : X86::LEA64r;
3176
- addFullAddress (BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DbgLoc,
3177
- TII.get (Opc), ResultReg), AM);
3178
- }
3179
- return ResultReg;
3180
- }
3181
- return 0 ;
3182
- }
3183
-
3184
3147
// MachineConstantPool wants an explicit alignment.
3185
- unsigned Align = DL.getPrefTypeAlignment (C ->getType ());
3148
+ unsigned Align = DL.getPrefTypeAlignment (CFP ->getType ());
3186
3149
if (Align == 0 ) {
3187
- // Alignment of vector types. FIXME!
3188
- Align = DL.getTypeAllocSize (C ->getType ());
3150
+ // Alignment of vector types. FIXME!
3151
+ Align = DL.getTypeAllocSize (CFP ->getType ());
3189
3152
}
3190
3153
3191
3154
// x86-32 PIC requires a PIC base register for constant pools.
@@ -3203,15 +3166,65 @@ unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
3203
3166
}
3204
3167
3205
3168
// Create the load from the constant pool.
3206
- unsigned MCPOffset = MCP.getConstantPoolIndex (C , Align);
3169
+ unsigned CPI = MCP.getConstantPoolIndex (CFP , Align);
3207
3170
unsigned ResultReg = createResultReg (RC);
3171
+
3208
3172
addConstantPoolReference (BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DbgLoc,
3209
3173
TII.get (Opc), ResultReg),
3210
- MCPOffset, PICBase, OpFlag);
3211
-
3174
+ CPI, PICBase, OpFlag);
3212
3175
return ResultReg;
3213
3176
}
3214
3177
3178
+ unsigned X86FastISel::X86MaterializeGV (const GlobalValue *GV, MVT VT) {
3179
+ // Can't handle alternate code models yet.
3180
+ if (TM.getCodeModel () != CodeModel::Small)
3181
+ return 0 ;
3182
+
3183
+ // Materialize addresses with LEA/MOV instructions.
3184
+ X86AddressMode AM;
3185
+ if (X86SelectAddress (GV, AM)) {
3186
+ // If the expression is just a basereg, then we're done, otherwise we need
3187
+ // to emit an LEA.
3188
+ if (AM.BaseType == X86AddressMode::RegBase &&
3189
+ AM.IndexReg == 0 && AM.Disp == 0 && AM.GV == nullptr )
3190
+ return AM.Base .Reg ;
3191
+
3192
+ unsigned ResultReg = createResultReg (TLI.getRegClassFor (VT));
3193
+ if (TM.getRelocationModel () == Reloc::Static &&
3194
+ TLI.getPointerTy () == MVT::i64) {
3195
+ // The displacement code could be more than 32 bits away so we need to use
3196
+ // an instruction with a 64 bit immediate
3197
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DbgLoc, TII.get (X86::MOV64ri),
3198
+ ResultReg)
3199
+ .addGlobalAddress (GV);
3200
+ } else {
3201
+ unsigned Opc = TLI.getPointerTy () == MVT::i32 ? X86::LEA32r : X86::LEA64r;
3202
+ addFullAddress (BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DbgLoc,
3203
+ TII.get (Opc), ResultReg), AM);
3204
+ }
3205
+ return ResultReg;
3206
+ }
3207
+ return 0 ;
3208
+ }
3209
+
3210
+ unsigned X86FastISel::TargetMaterializeConstant (const Constant *C) {
3211
+ EVT CEVT = TLI.getValueType (C->getType (), true );
3212
+
3213
+ // Only handle simple types.
3214
+ if (!CEVT.isSimple ())
3215
+ return 0 ;
3216
+ MVT VT = CEVT.getSimpleVT ();
3217
+
3218
+ if (const auto *CI = dyn_cast<ConstantInt>(C))
3219
+ return X86MaterializeInt (CI, VT);
3220
+ else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
3221
+ return X86MaterializeFP (CFP, VT);
3222
+ else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
3223
+ return X86MaterializeGV (GV, VT);
3224
+
3225
+ return 0 ;
3226
+ }
3227
+
3215
3228
unsigned X86FastISel::TargetMaterializeAlloca (const AllocaInst *C) {
3216
3229
// Fail on dynamic allocas. At this point, getRegForValue has already
3217
3230
// checked its CSE maps, so if we're here trying to handle a dynamic
0 commit comments