@@ -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);
@@ -175,6 +184,103 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
175
184
setOperationAction (ISD::VACOPY, MVT::Other, Custom);
176
185
setOperationAction (ISD::VAEND, MVT::Other, Expand);
177
186
187
+ // Handle floating-point types.
188
+ for (unsigned I = MVT::FIRST_FP_VALUETYPE; I <= MVT::LAST_FP_VALUETYPE; ++I) {
189
+ MVT VT = MVT::SimpleValueType (I);
190
+ if (isTypeLegal (VT)) {
191
+ // We can use FI for FRINT.
192
+ // setOperationAction(ISD::FRINT, VT, Legal);
193
+ if (VT.getSizeInBits () == 32 && Subtarget.hasSingleFloat ()) {
194
+ setOperationAction (ISD::FABS, VT, Legal);
195
+ setOperationAction (ISD::FADD, VT, Legal);
196
+ setOperationAction (ISD::FSUB, VT, Legal);
197
+ setOperationAction (ISD::FMA, VT, Legal);
198
+ setOperationAction (ISD::FMUL, VT, Legal);
199
+ setOperationAction (ISD::FNEG, VT, Legal);
200
+ } else {
201
+ setOperationAction (ISD::FABS, VT, Expand);
202
+ setOperationAction (ISD::FADD, VT, Expand);
203
+ setOperationAction (ISD::FSUB, VT, Expand);
204
+ setOperationAction (ISD::FMA, VT, Expand);
205
+ setOperationAction (ISD::FMUL, VT, Expand);
206
+ setOperationAction (ISD::FNEG, VT, Expand);
207
+ }
208
+
209
+ // TODO: once implemented in InstrInfo uncomment
210
+ setOperationAction (ISD::FSQRT, VT, Expand);
211
+
212
+ // No special instructions for these.
213
+ setOperationAction (ISD::FCBRT, VT, Expand);
214
+ setOperationAction (ISD::FCEIL, VT, Expand);
215
+ setOperationAction (ISD::FSIN, VT, Expand);
216
+ setOperationAction (ISD::FCOS, VT, Expand);
217
+ setOperationAction (ISD::FREM, VT, Expand);
218
+ setOperationAction (ISD::FDIV, VT, Expand);
219
+ setOperationAction (ISD::FEXP, VT, Expand);
220
+ setOperationAction (ISD::FEXP2, VT, Expand);
221
+ setOperationAction (ISD::FFLOOR, VT, Expand);
222
+ setOperationAction (ISD::FLOG, VT, Expand);
223
+ setOperationAction (ISD::FLOG2, VT, Expand);
224
+ setOperationAction (ISD::FLOG10, VT, Expand);
225
+ setOperationAction (ISD::FMAXIMUM, VT, Expand);
226
+ setOperationAction (ISD::FMINIMUM, VT, Expand);
227
+ setOperationAction (ISD::FMAXNUM, VT, Expand);
228
+ setOperationAction (ISD::FMINNUM, VT, Expand);
229
+ setOperationAction (ISD::FNEARBYINT, VT, Expand);
230
+ setOperationAction (ISD::FPOW, VT, Expand);
231
+ setOperationAction (ISD::FPOWI, VT, Expand);
232
+ setOperationAction (ISD::FRINT, VT, Expand);
233
+ setOperationAction (ISD::FROUND, VT, Expand);
234
+ setOperationAction (ISD::FSINCOS, VT, Expand);
235
+ setOperationAction (ISD::FSQRT, VT, Expand);
236
+ setOperationAction (ISD::FTRUNC, VT, Expand);
237
+ setOperationAction (ISD::LLRINT, VT, Expand);
238
+ setOperationAction (ISD::LLROUND, VT, Expand);
239
+ setOperationAction (ISD::LRINT, VT, Expand);
240
+ setOperationAction (ISD::LROUND, VT, Expand);
241
+ }
242
+ }
243
+
244
+ // Handle floating-point types.
245
+ if (Subtarget.hasSingleFloat ()) {
246
+ setOperationAction (ISD::BITCAST, MVT::i32, Legal);
247
+ setOperationAction (ISD::BITCAST, MVT::f32, Legal);
248
+ setOperationAction (ISD::UINT_TO_FP, MVT::i32, Legal);
249
+ setOperationAction (ISD::SINT_TO_FP, MVT::i32, Legal);
250
+ setOperationAction (ISD::FP_TO_UINT, MVT::i32, Legal);
251
+ setOperationAction (ISD::FP_TO_SINT, MVT::i32, Legal);
252
+
253
+ setCondCodeAction (ISD::SETOGT, MVT::f32, Expand);
254
+ setCondCodeAction (ISD::SETOGE, MVT::f32, Expand);
255
+ setCondCodeAction (ISD::SETONE, MVT::f32, Expand);
256
+ setCondCodeAction (ISD::SETUGE, MVT::f32, Expand);
257
+ setCondCodeAction (ISD::SETUGT, MVT::f32, Expand);
258
+ } else {
259
+ setOperationAction (ISD::BITCAST, MVT::i32, Expand);
260
+ setOperationAction (ISD::BITCAST, MVT::f32, Expand);
261
+ setOperationAction (ISD::UINT_TO_FP, MVT::i32, Expand);
262
+ setOperationAction (ISD::SINT_TO_FP, MVT::i32, Expand);
263
+ setOperationAction (ISD::FP_TO_UINT, MVT::i32, Expand);
264
+ setOperationAction (ISD::FP_TO_SINT, MVT::i32, Expand);
265
+ }
266
+ setOperationAction (ISD::FMA, MVT::f64, Expand);
267
+ setOperationAction (ISD::SETCC, MVT::f64, Expand);
268
+ setOperationAction (ISD::BITCAST, MVT::i64, Expand);
269
+ setOperationAction (ISD::BITCAST, MVT::f64, Expand);
270
+ setOperationAction (ISD::UINT_TO_FP, MVT::i64, Expand);
271
+ setOperationAction (ISD::SINT_TO_FP, MVT::i64, Expand);
272
+ setOperationAction (ISD::FP_TO_UINT, MVT::i64, Expand);
273
+ setOperationAction (ISD::FP_TO_SINT, MVT::i64, Expand);
274
+
275
+ // Needed so that we don't try to implement f128 constant loads using
276
+ // a load-and-extend of a f80 constant (in cases where the constant
277
+ // would fit in an f80).
278
+ for (MVT VT : MVT::fp_valuetypes ())
279
+ setLoadExtAction (ISD::EXTLOAD, VT, MVT::f80, Expand);
280
+
281
+ // Floating-point truncation and stores need to be done separately.
282
+ setTruncStoreAction (MVT::f64, MVT::f32, Expand);
283
+
178
284
// Compute derived properties from the register classes
179
285
computeRegisterProperties (STI.getRegisterInfo ());
180
286
}
@@ -185,6 +291,11 @@ bool XtensaTargetLowering::isOffsetFoldingLegal(
185
291
return false ;
186
292
}
187
293
294
+ bool XtensaTargetLowering::isFPImmLegal (const APFloat &Imm, EVT VT,
295
+ bool ForCodeSize) const {
296
+ return false ;
297
+ }
298
+
188
299
// ===----------------------------------------------------------------------===//
189
300
// Inline asm support
190
301
// ===----------------------------------------------------------------------===//
@@ -335,6 +446,16 @@ static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
335
446
return false ;
336
447
}
337
448
449
+ // / Return the register type for a given MVT
450
+ MVT XtensaTargetLowering::getRegisterTypeForCallingConv (LLVMContext &Context,
451
+ CallingConv::ID CC,
452
+ EVT VT) const {
453
+ if (VT.isFloatingPoint ())
454
+ return MVT::i32;
455
+
456
+ return TargetLowering::getRegisterTypeForCallingConv (Context, CC, VT);
457
+ }
458
+
338
459
CCAssignFn *XtensaTargetLowering::CCAssignFnForCall (CallingConv::ID CC,
339
460
bool IsVarArg) const {
340
461
return CC_Xtensa_Custom;
@@ -815,6 +936,21 @@ SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
815
936
return Op;
816
937
}
817
938
939
+ SDValue XtensaTargetLowering::LowerImmediateFP (SDValue Op,
940
+ SelectionDAG &DAG) const {
941
+ const ConstantFPSDNode *CN = cast<ConstantFPSDNode>(Op);
942
+ SDLoc DL (CN);
943
+ APFloat apval = CN->getValueAPF ();
944
+ int64_t value = llvm::bit_cast<uint32_t >(CN->getValueAPF ().convertToFloat ());
945
+ if (Op.getValueType () == MVT::f32) {
946
+ Type *Ty = Type::getInt32Ty (*DAG.getContext ());
947
+ Constant *CV = ConstantInt::get (Ty, value);
948
+ SDValue CP = DAG.getConstantPool (CV, MVT::i32);
949
+ return DAG.getNode (ISD::BITCAST, DL, MVT::f32, CP);
950
+ }
951
+ return Op;
952
+ }
953
+
818
954
SDValue XtensaTargetLowering::LowerGlobalAddress (SDValue Op,
819
955
SelectionDAG &DAG) const {
820
956
const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
@@ -1248,6 +1384,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
1248
1384
return LowerBR_JT (Op, DAG);
1249
1385
case ISD::Constant:
1250
1386
return LowerImmediate (Op, DAG);
1387
+ case ISD::ConstantFP:
1388
+ return LowerImmediateFP (Op, DAG);
1251
1389
case ISD::RETURNADDR:
1252
1390
return LowerRETURNADDR (Op, DAG);
1253
1391
case ISD::GlobalAddress:
@@ -1311,6 +1449,26 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
1311
1449
return " XtensaISD::SRCL" ;
1312
1450
case XtensaISD::SRCR:
1313
1451
return " XtensaISD::SRCR" ;
1452
+ case XtensaISD::CMPUO:
1453
+ return " XtensaISD::CMPUO" ;
1454
+ case XtensaISD::CMPUEQ:
1455
+ return " XtensaISD::CMPUEQ" ;
1456
+ case XtensaISD::CMPULE:
1457
+ return " XtensaISD::CMPULE" ;
1458
+ case XtensaISD::CMPULT:
1459
+ return " XtensaISD::CMPULT" ;
1460
+ case XtensaISD::CMPOEQ:
1461
+ return " XtensaISD::CMPOEQ" ;
1462
+ case XtensaISD::CMPOLE:
1463
+ return " XtensaISD::CMPOLE" ;
1464
+ case XtensaISD::CMPOLT:
1465
+ return " XtensaISD::CMPOLT" ;
1466
+ case XtensaISD::MADD:
1467
+ return " XtensaISD::MADD" ;
1468
+ case XtensaISD::MSUB:
1469
+ return " XtensaISD::MSUB" ;
1470
+ case XtensaISD::MOVS:
1471
+ return " XtensaISD::MOVS" ;
1314
1472
}
1315
1473
return nullptr ;
1316
1474
}
@@ -1395,11 +1553,19 @@ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(
1395
1553
case Xtensa::S16I:
1396
1554
case Xtensa::S32I:
1397
1555
case Xtensa::S32I_N:
1556
+ case Xtensa::SSI:
1557
+ case Xtensa::SSIP:
1558
+ case Xtensa::SSX:
1559
+ case Xtensa::SSXP:
1398
1560
case Xtensa::L8UI:
1399
1561
case Xtensa::L16SI:
1400
1562
case Xtensa::L16UI:
1401
1563
case Xtensa::L32I:
1402
- case Xtensa::L32I_N: {
1564
+ case Xtensa::L32I_N:
1565
+ case Xtensa::LSI:
1566
+ case Xtensa::LSIP:
1567
+ case Xtensa::LSX:
1568
+ case Xtensa::LSXP: {
1403
1569
// Insert memory wait instruction "memw" before volatile load/store as it is
1404
1570
// implemented in gcc. If memoperands is empty then assume that it aslo
1405
1571
// maybe volatile load/store and insert "memw".
0 commit comments