@@ -353,7 +353,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
353
353
if (Subtarget.hasStdExtZfhOrZfhmin()) {
354
354
if (Subtarget.hasStdExtZfh()) {
355
355
setOperationAction(FPLegalNodeTypes, MVT::f16, Legal);
356
- setOperationAction(FPRndMode, MVT::f16, Custom);
356
+ setOperationAction(FPRndMode, MVT::f16,
357
+ Subtarget.hasStdExtZfa() ? Legal : Custom);
357
358
setOperationAction(ISD::SELECT, MVT::f16, Custom);
358
359
} else {
359
360
static const unsigned ZfhminPromoteOps[] = {
@@ -382,7 +383,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
382
383
setOperationAction(ISD::SELECT_CC, MVT::f16, Expand);
383
384
setOperationAction(ISD::BR_CC, MVT::f16, Expand);
384
385
385
- setOperationAction({ISD::FREM, ISD::FNEARBYINT, ISD::FPOW, ISD::FPOWI,
386
+ setOperationAction(ISD::FNEARBYINT, MVT::f16,
387
+ Subtarget.hasStdExtZfa() ? Legal : Promote);
388
+ setOperationAction({ISD::FREM, ISD::FPOW, ISD::FPOWI,
386
389
ISD::FCOS, ISD::FSIN, ISD::FSINCOS, ISD::FEXP,
387
390
ISD::FEXP2, ISD::FLOG, ISD::FLOG2, ISD::FLOG10},
388
391
MVT::f16, Promote);
@@ -402,24 +405,36 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
402
405
403
406
if (Subtarget.hasStdExtF()) {
404
407
setOperationAction(FPLegalNodeTypes, MVT::f32, Legal);
405
- setOperationAction(FPRndMode, MVT::f32, Custom);
408
+ setOperationAction(FPRndMode, MVT::f32,
409
+ Subtarget.hasStdExtZfa() ? Legal : Custom);
406
410
setCondCodeAction(FPCCToExpand, MVT::f32, Expand);
407
411
setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
408
412
setOperationAction(ISD::SELECT, MVT::f32, Custom);
409
413
setOperationAction(ISD::BR_CC, MVT::f32, Expand);
410
414
setOperationAction(FPOpToExpand, MVT::f32, Expand);
411
415
setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
412
416
setTruncStoreAction(MVT::f32, MVT::f16, Expand);
417
+
418
+ if (Subtarget.hasStdExtZfa())
419
+ setOperationAction(ISD::FNEARBYINT, MVT::f32, Legal);
413
420
}
414
421
415
422
if (Subtarget.hasStdExtF() && Subtarget.is64Bit())
416
423
setOperationAction(ISD::BITCAST, MVT::i32, Custom);
417
424
418
425
if (Subtarget.hasStdExtD()) {
419
426
setOperationAction(FPLegalNodeTypes, MVT::f64, Legal);
420
- if (Subtarget.is64Bit()) {
421
- setOperationAction(FPRndMode, MVT::f64, Custom);
427
+ if (Subtarget.hasStdExtZfa()) {
428
+ setOperationAction(FPRndMode, MVT::f64, Legal);
429
+ setOperationAction(ISD::FNEARBYINT, MVT::f64, Legal);
430
+ setOperationAction(ISD::BITCAST, MVT::i64, Custom);
431
+ setOperationAction(ISD::BITCAST, MVT::f64, Custom);
422
432
}
433
+
434
+ if (Subtarget.is64Bit())
435
+ setOperationAction(FPRndMode, MVT::f64,
436
+ Subtarget.hasStdExtZfa() ? Legal : Custom);
437
+
423
438
setOperationAction(ISD::STRICT_FP_ROUND, MVT::f32, Legal);
424
439
setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f64, Legal);
425
440
setCondCodeAction(FPCCToExpand, MVT::f64, Expand);
@@ -3812,6 +3827,16 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
3812
3827
DAG.getNode(RISCVISD::FMV_W_X_RV64, DL, MVT::f32, NewOp0);
3813
3828
return FPConv;
3814
3829
}
3830
+ if (VT == MVT::f64 && Op0VT == MVT::i64 && XLenVT == MVT::i32 &&
3831
+ Subtarget.hasStdExtZfa()) {
3832
+ SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op0,
3833
+ DAG.getConstant(0, DL, MVT::i32));
3834
+ SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op0,
3835
+ DAG.getConstant(1, DL, MVT::i32));
3836
+ SDValue RetReg =
3837
+ DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
3838
+ return RetReg;
3839
+ }
3815
3840
3816
3841
// Consider other scalar<->scalar casts as legal if the types are legal.
3817
3842
// Otherwise expand them.
@@ -8020,6 +8045,14 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
8020
8045
SDValue FPConv =
8021
8046
DAG.getNode(RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64, Op0);
8022
8047
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, FPConv));
8048
+ } else if (VT == MVT::i64 && Op0VT == MVT::f64 && XLenVT == MVT::i32 &&
8049
+ Subtarget.hasStdExtZfa()) {
8050
+ SDValue NewReg = DAG.getNode(RISCVISD::SplitF64, DL,
8051
+ DAG.getVTList(MVT::i32, MVT::i32), Op0);
8052
+ SDValue Lo = NewReg.getValue(0);
8053
+ SDValue Hi = NewReg.getValue(1);
8054
+ SDValue RetReg = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
8055
+ Results.push_back(RetReg);
8023
8056
} else if (!VT.isVector() && Op0VT.isFixedLengthVector() &&
8024
8057
isTypeLegal(Op0VT)) {
8025
8058
// Custom-legalize bitcasts from fixed-length vector types to illegal
@@ -11124,7 +11157,8 @@ static MachineBasicBlock *emitReadCycleWidePseudo(MachineInstr &MI,
11124
11157
}
11125
11158
11126
11159
static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
11127
- MachineBasicBlock *BB) {
11160
+ MachineBasicBlock *BB,
11161
+ const RISCVSubtarget &Subtarget) {
11128
11162
assert(MI.getOpcode() == RISCV::SplitF64Pseudo && "Unexpected instruction");
11129
11163
11130
11164
MachineFunction &MF = *BB->getParent();
@@ -11134,6 +11168,13 @@ static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
11134
11168
Register LoReg = MI.getOperand(0).getReg();
11135
11169
Register HiReg = MI.getOperand(1).getReg();
11136
11170
Register SrcReg = MI.getOperand(2).getReg();
11171
+ if (Subtarget.hasStdExtD() && Subtarget.hasStdExtZfa() && !Subtarget.is64Bit()) {
11172
+ BuildMI(*BB, MI, DL, TII.get(RISCV::FMV_X_W_FPR64), LoReg).addReg(SrcReg);
11173
+ BuildMI(*BB, MI, DL, TII.get(RISCV::FMVH_X_D), HiReg).addReg(SrcReg);
11174
+ MI.eraseFromParent(); // The pseudo instruction is gone now.
11175
+ return BB;
11176
+ }
11177
+
11137
11178
const TargetRegisterClass *SrcRC = &RISCV::FPR64RegClass;
11138
11179
int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF);
11139
11180
@@ -11157,7 +11198,8 @@ static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
11157
11198
}
11158
11199
11159
11200
static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
11160
- MachineBasicBlock *BB) {
11201
+ MachineBasicBlock *BB,
11202
+ const RISCVSubtarget &Subtarget) {
11161
11203
assert(MI.getOpcode() == RISCV::BuildPairF64Pseudo &&
11162
11204
"Unexpected instruction");
11163
11205
@@ -11168,6 +11210,14 @@ static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
11168
11210
Register DstReg = MI.getOperand(0).getReg();
11169
11211
Register LoReg = MI.getOperand(1).getReg();
11170
11212
Register HiReg = MI.getOperand(2).getReg();
11213
+ if (Subtarget.hasStdExtD() && Subtarget.hasStdExtZfa() && !Subtarget.is64Bit()) {
11214
+ BuildMI(*BB, MI, DL, TII.get(RISCV::FMVP_D_X), DstReg)
11215
+ .addReg(LoReg)
11216
+ .addReg(HiReg);
11217
+ MI.eraseFromParent();
11218
+ return BB;
11219
+ }
11220
+
11171
11221
const TargetRegisterClass *DstRC = &RISCV::FPR64RegClass;
11172
11222
int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF);
11173
11223
@@ -11683,9 +11733,9 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
11683
11733
case RISCV::Select_FPR64_Using_CC_GPR:
11684
11734
return emitSelectPseudo(MI, BB, Subtarget);
11685
11735
case RISCV::BuildPairF64Pseudo:
11686
- return emitBuildPairF64Pseudo(MI, BB);
11736
+ return emitBuildPairF64Pseudo(MI, BB, Subtarget );
11687
11737
case RISCV::SplitF64Pseudo:
11688
- return emitSplitF64Pseudo(MI, BB);
11738
+ return emitSplitF64Pseudo(MI, BB, Subtarget );
11689
11739
case RISCV::PseudoQuietFLE_H:
11690
11740
return emitQuietFCMP(MI, BB, RISCV::FLE_H, RISCV::FEQ_H, Subtarget);
11691
11741
case RISCV::PseudoQuietFLT_H:
0 commit comments