@@ -58,6 +58,10 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
58
58
// Set up the register classes.
59
59
addRegisterClass (MVT::i32, &Xtensa::ARRegClass);
60
60
61
+ if (Subtarget.hasSingleFloat ()) {
62
+ addRegisterClass (MVT::f32, &Xtensa::FPRRegClass);
63
+ }
64
+
61
65
if (Subtarget.hasBoolean ()) {
62
66
addRegisterClass (MVT::v1i1, &Xtensa::BRRegClass);
63
67
}
@@ -71,6 +75,8 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
71
75
72
76
setOperationAction (ISD::Constant, MVT::i32, Custom);
73
77
setOperationAction (ISD::Constant, MVT::i64, Expand);
78
+ setOperationAction (ISD::ConstantFP, MVT::f32, Custom);
79
+ setOperationAction (ISD::ConstantFP, MVT::f64, Expand);
74
80
75
81
setBooleanContents (ZeroOrOneBooleanContent);
76
82
@@ -108,7 +114,10 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
108
114
109
115
setOperationAction (ISD::SELECT, MVT::i32, Expand);
110
116
setOperationAction (ISD::SELECT_CC, MVT::i32, Custom);
117
+ setOperationAction (ISD::SELECT_CC, MVT::f32, Expand);
118
+
111
119
setOperationAction (ISD::SETCC, MVT::i32, Expand);
120
+ setOperationAction (ISD::SETCC, MVT::f32, Expand);
112
121
113
122
setCondCodeAction (ISD::SETGT, MVT::i32, Expand);
114
123
setCondCodeAction (ISD::SETLE, MVT::i32, Expand);
@@ -157,6 +166,103 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
157
166
setOperationAction (ISD::VACOPY, MVT::Other, Custom);
158
167
setOperationAction (ISD::VAEND, MVT::Other, Expand);
159
168
169
+ // Handle floating-point types.
170
+ for (unsigned I = MVT::FIRST_FP_VALUETYPE; I <= MVT::LAST_FP_VALUETYPE; ++I) {
171
+ MVT VT = MVT::SimpleValueType (I);
172
+ if (isTypeLegal (VT)) {
173
+ // We can use FI for FRINT.
174
+ // setOperationAction(ISD::FRINT, VT, Legal);
175
+ if (VT.getSizeInBits () == 32 && Subtarget.hasSingleFloat ()) {
176
+ setOperationAction (ISD::FABS, VT, Legal);
177
+ setOperationAction (ISD::FADD, VT, Legal);
178
+ setOperationAction (ISD::FSUB, VT, Legal);
179
+ setOperationAction (ISD::FMA, VT, Legal);
180
+ setOperationAction (ISD::FMUL, VT, Legal);
181
+ setOperationAction (ISD::FNEG, VT, Legal);
182
+ } else {
183
+ setOperationAction (ISD::FABS, VT, Expand);
184
+ setOperationAction (ISD::FADD, VT, Expand);
185
+ setOperationAction (ISD::FSUB, VT, Expand);
186
+ setOperationAction (ISD::FMA, VT, Expand);
187
+ setOperationAction (ISD::FMUL, VT, Expand);
188
+ setOperationAction (ISD::FNEG, VT, Expand);
189
+ }
190
+
191
+ // TODO: once implemented in InstrInfo uncomment
192
+ setOperationAction (ISD::FSQRT, VT, Expand);
193
+
194
+ // No special instructions for these.
195
+ setOperationAction (ISD::FCBRT, VT, Expand);
196
+ setOperationAction (ISD::FCEIL, VT, Expand);
197
+ setOperationAction (ISD::FSIN, VT, Expand);
198
+ setOperationAction (ISD::FCOS, VT, Expand);
199
+ setOperationAction (ISD::FREM, VT, Expand);
200
+ setOperationAction (ISD::FDIV, VT, Expand);
201
+ setOperationAction (ISD::FEXP, VT, Expand);
202
+ setOperationAction (ISD::FEXP2, VT, Expand);
203
+ setOperationAction (ISD::FFLOOR, VT, Expand);
204
+ setOperationAction (ISD::FLOG, VT, Expand);
205
+ setOperationAction (ISD::FLOG2, VT, Expand);
206
+ setOperationAction (ISD::FLOG10, VT, Expand);
207
+ setOperationAction (ISD::FMAXIMUM, VT, Expand);
208
+ setOperationAction (ISD::FMINIMUM, VT, Expand);
209
+ setOperationAction (ISD::FMAXNUM, VT, Expand);
210
+ setOperationAction (ISD::FMINNUM, VT, Expand);
211
+ setOperationAction (ISD::FNEARBYINT, VT, Expand);
212
+ setOperationAction (ISD::FPOW, VT, Expand);
213
+ setOperationAction (ISD::FPOWI, VT, Expand);
214
+ setOperationAction (ISD::FRINT, VT, Expand);
215
+ setOperationAction (ISD::FROUND, VT, Expand);
216
+ setOperationAction (ISD::FSINCOS, VT, Expand);
217
+ setOperationAction (ISD::FSQRT, VT, Expand);
218
+ setOperationAction (ISD::FTRUNC, VT, Expand);
219
+ setOperationAction (ISD::LLRINT, VT, Expand);
220
+ setOperationAction (ISD::LLROUND, VT, Expand);
221
+ setOperationAction (ISD::LRINT, VT, Expand);
222
+ setOperationAction (ISD::LROUND, VT, Expand);
223
+ }
224
+ }
225
+
226
+ // Handle floating-point types.
227
+ if (Subtarget.hasSingleFloat ()) {
228
+ setOperationAction (ISD::BITCAST, MVT::i32, Legal);
229
+ setOperationAction (ISD::BITCAST, MVT::f32, Legal);
230
+ setOperationAction (ISD::UINT_TO_FP, MVT::i32, Legal);
231
+ setOperationAction (ISD::SINT_TO_FP, MVT::i32, Legal);
232
+ setOperationAction (ISD::FP_TO_UINT, MVT::i32, Legal);
233
+ setOperationAction (ISD::FP_TO_SINT, MVT::i32, Legal);
234
+
235
+ setCondCodeAction (ISD::SETOGT, MVT::f32, Expand);
236
+ setCondCodeAction (ISD::SETOGE, MVT::f32, Expand);
237
+ setCondCodeAction (ISD::SETONE, MVT::f32, Expand);
238
+ setCondCodeAction (ISD::SETUGE, MVT::f32, Expand);
239
+ setCondCodeAction (ISD::SETUGT, MVT::f32, Expand);
240
+ } else {
241
+ setOperationAction (ISD::BITCAST, MVT::i32, Expand);
242
+ setOperationAction (ISD::BITCAST, MVT::f32, Expand);
243
+ setOperationAction (ISD::UINT_TO_FP, MVT::i32, Expand);
244
+ setOperationAction (ISD::SINT_TO_FP, MVT::i32, Expand);
245
+ setOperationAction (ISD::FP_TO_UINT, MVT::i32, Expand);
246
+ setOperationAction (ISD::FP_TO_SINT, MVT::i32, Expand);
247
+ }
248
+ setOperationAction (ISD::FMA, MVT::f64, Expand);
249
+ setOperationAction (ISD::SETCC, MVT::f64, Expand);
250
+ setOperationAction (ISD::BITCAST, MVT::i64, Expand);
251
+ setOperationAction (ISD::BITCAST, MVT::f64, Expand);
252
+ setOperationAction (ISD::UINT_TO_FP, MVT::i64, Expand);
253
+ setOperationAction (ISD::SINT_TO_FP, MVT::i64, Expand);
254
+ setOperationAction (ISD::FP_TO_UINT, MVT::i64, Expand);
255
+ setOperationAction (ISD::FP_TO_SINT, MVT::i64, Expand);
256
+
257
+ // Needed so that we don't try to implement f128 constant loads using
258
+ // a load-and-extend of a f80 constant (in cases where the constant
259
+ // would fit in an f80).
260
+ for (MVT VT : MVT::fp_valuetypes ())
261
+ setLoadExtAction (ISD::EXTLOAD, VT, MVT::f80, Expand);
262
+
263
+ // Floating-point truncation and stores need to be done separately.
264
+ setTruncStoreAction (MVT::f64, MVT::f32, Expand);
265
+
160
266
// Compute derived properties from the register classes
161
267
computeRegisterProperties (STI.getRegisterInfo ());
162
268
}
@@ -167,6 +273,11 @@ bool XtensaTargetLowering::isOffsetFoldingLegal(
167
273
return false ;
168
274
}
169
275
276
+ bool XtensaTargetLowering::isFPImmLegal (const APFloat &Imm, EVT VT,
277
+ bool ForCodeSize) const {
278
+ return false ;
279
+ }
280
+
170
281
// ===----------------------------------------------------------------------===//
171
282
// Inline asm support
172
283
// ===----------------------------------------------------------------------===//
@@ -317,6 +428,16 @@ static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
317
428
return false ;
318
429
}
319
430
431
+ // / Return the register type for a given MVT
432
+ MVT XtensaTargetLowering::getRegisterTypeForCallingConv (LLVMContext &Context,
433
+ CallingConv::ID CC,
434
+ EVT VT) const {
435
+ if (VT.isFloatingPoint ())
436
+ return MVT::i32;
437
+
438
+ return TargetLowering::getRegisterTypeForCallingConv (Context, CC, VT);
439
+ }
440
+
320
441
CCAssignFn *XtensaTargetLowering::CCAssignFnForCall (CallingConv::ID CC,
321
442
bool IsVarArg) const {
322
443
return CC_Xtensa_Custom;
@@ -797,6 +918,21 @@ SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
797
918
return Op;
798
919
}
799
920
921
+ SDValue XtensaTargetLowering::LowerImmediateFP (SDValue Op,
922
+ SelectionDAG &DAG) const {
923
+ const ConstantFPSDNode *CN = cast<ConstantFPSDNode>(Op);
924
+ SDLoc DL (CN);
925
+ APFloat apval = CN->getValueAPF ();
926
+ int64_t value = llvm::bit_cast<uint32_t >(CN->getValueAPF ().convertToFloat ());
927
+ if (Op.getValueType () == MVT::f32) {
928
+ Type *Ty = Type::getInt32Ty (*DAG.getContext ());
929
+ Constant *CV = ConstantInt::get (Ty, value);
930
+ SDValue CP = DAG.getConstantPool (CV, MVT::i32);
931
+ return DAG.getNode (ISD::BITCAST, DL, MVT::f32, CP);
932
+ }
933
+ return Op;
934
+ }
935
+
800
936
SDValue XtensaTargetLowering::LowerGlobalAddress (SDValue Op,
801
937
SelectionDAG &DAG) const {
802
938
const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
@@ -1230,6 +1366,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
1230
1366
return LowerBR_JT (Op, DAG);
1231
1367
case ISD::Constant:
1232
1368
return LowerImmediate (Op, DAG);
1369
+ case ISD::ConstantFP:
1370
+ return LowerImmediateFP (Op, DAG);
1233
1371
case ISD::RETURNADDR:
1234
1372
return LowerRETURNADDR (Op, DAG);
1235
1373
case ISD::GlobalAddress:
@@ -1293,6 +1431,26 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
1293
1431
return " XtensaISD::SRCL" ;
1294
1432
case XtensaISD::SRCR:
1295
1433
return " XtensaISD::SRCR" ;
1434
+ case XtensaISD::CMPUO:
1435
+ return " XtensaISD::CMPUO" ;
1436
+ case XtensaISD::CMPUEQ:
1437
+ return " XtensaISD::CMPUEQ" ;
1438
+ case XtensaISD::CMPULE:
1439
+ return " XtensaISD::CMPULE" ;
1440
+ case XtensaISD::CMPULT:
1441
+ return " XtensaISD::CMPULT" ;
1442
+ case XtensaISD::CMPOEQ:
1443
+ return " XtensaISD::CMPOEQ" ;
1444
+ case XtensaISD::CMPOLE:
1445
+ return " XtensaISD::CMPOLE" ;
1446
+ case XtensaISD::CMPOLT:
1447
+ return " XtensaISD::CMPOLT" ;
1448
+ case XtensaISD::MADD:
1449
+ return " XtensaISD::MADD" ;
1450
+ case XtensaISD::MSUB:
1451
+ return " XtensaISD::MSUB" ;
1452
+ case XtensaISD::MOVS:
1453
+ return " XtensaISD::MOVS" ;
1296
1454
}
1297
1455
return nullptr ;
1298
1456
}
@@ -1377,11 +1535,19 @@ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(
1377
1535
case Xtensa::S16I:
1378
1536
case Xtensa::S32I:
1379
1537
case Xtensa::S32I_N:
1538
+ case Xtensa::SSI:
1539
+ case Xtensa::SSIP:
1540
+ case Xtensa::SSX:
1541
+ case Xtensa::SSXP:
1380
1542
case Xtensa::L8UI:
1381
1543
case Xtensa::L16SI:
1382
1544
case Xtensa::L16UI:
1383
1545
case Xtensa::L32I:
1384
- case Xtensa::L32I_N: {
1546
+ case Xtensa::L32I_N:
1547
+ case Xtensa::LSI:
1548
+ case Xtensa::LSIP:
1549
+ case Xtensa::LSX:
1550
+ case Xtensa::LSXP: {
1385
1551
// Insert memory wait instruction "memw" before volatile load/store as it is
1386
1552
// implemented in gcc. If memoperands is empty then assume that it aslo
1387
1553
// maybe volatile load/store and insert "memw".
0 commit comments