@@ -372,6 +372,10 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
372
372
setOperationAction (ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
373
373
}
374
374
375
+ if (Subtarget.hasStdExtF ()) {
376
+ setOperationAction (ISD::FLT_ROUNDS_, XLenVT, Custom);
377
+ }
378
+
375
379
setOperationAction (ISD::GlobalAddress, XLenVT, Custom);
376
380
setOperationAction (ISD::BlockAddress, XLenVT, Custom);
377
381
setOperationAction (ISD::ConstantPool, XLenVT, Custom);
@@ -2161,6 +2165,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
2161
2165
return lowerMGATHER (Op, DAG);
2162
2166
case ISD::MSCATTER:
2163
2167
return lowerMSCATTER (Op, DAG);
2168
+ case ISD::FLT_ROUNDS_:
2169
+ return lowerGET_ROUNDING (Op, DAG);
2164
2170
}
2165
2171
}
2166
2172
@@ -4107,6 +4113,37 @@ SDValue RISCVTargetLowering::lowerMSCATTER(SDValue Op,
4107
4113
MSN->getMemoryVT (), MSN->getMemOperand ());
4108
4114
}
4109
4115
4116
+ SDValue RISCVTargetLowering::lowerGET_ROUNDING (SDValue Op,
4117
+ SelectionDAG &DAG) const {
4118
+ const MVT XLenVT = Subtarget.getXLenVT ();
4119
+ SDLoc DL (Op);
4120
+ SDValue Chain = Op->getOperand (0 );
4121
+ SDValue SysRegNo = DAG.getConstant (
4122
+ RISCVSysReg::lookupSysRegByName (" FRM" )->Encoding , DL, XLenVT);
4123
+ SDVTList VTs = DAG.getVTList (XLenVT, MVT::Other);
4124
+ SDValue RM = DAG.getNode (RISCVISD::READ_CSR, DL, VTs, Chain, SysRegNo);
4125
+
4126
+ // Encoding used for rounding mode in RISCV differs from that used in
4127
+ // FLT_ROUNDS. To convert it the RISCV rounding mode is used as an index in a
4128
+ // table, which consists of a sequence of 4-bit fields, each representing
4129
+ // corresponding FLT_ROUNDS mode.
4130
+ static const int Table =
4131
+ (int (RoundingMode::NearestTiesToEven) << 4 * RISCVFPRndMode::RNE) |
4132
+ (int (RoundingMode::TowardZero) << 4 * RISCVFPRndMode::RTZ) |
4133
+ (int (RoundingMode::TowardNegative) << 4 * RISCVFPRndMode::RDN) |
4134
+ (int (RoundingMode::TowardPositive) << 4 * RISCVFPRndMode::RUP) |
4135
+ (int (RoundingMode::NearestTiesToAway) << 4 * RISCVFPRndMode::RMM);
4136
+
4137
+ SDValue Shift =
4138
+ DAG.getNode (ISD::SHL, DL, XLenVT, RM, DAG.getConstant (2 , DL, XLenVT));
4139
+ SDValue Shifted = DAG.getNode (ISD::SRL, DL, XLenVT,
4140
+ DAG.getConstant (Table, DL, XLenVT), Shift);
4141
+ SDValue Masked = DAG.getNode (ISD::AND, DL, XLenVT, Shifted,
4142
+ DAG.getConstant (7 , DL, XLenVT));
4143
+
4144
+ return DAG.getMergeValues ({Masked, Chain}, DL);
4145
+ }
4146
+
4110
4147
// Returns the opcode of the target-specific SDNode that implements the 32-bit
4111
4148
// form of the given Opcode.
4112
4149
static RISCVISD::NodeType getRISCVWOpcode (unsigned Opcode) {
@@ -4584,6 +4621,13 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
4584
4621
if (SDValue V = lowerVECREDUCE (SDValue (N, 0 ), DAG))
4585
4622
Results.push_back (V);
4586
4623
break ;
4624
+ case ISD::FLT_ROUNDS_: {
4625
+ SDVTList VTs = DAG.getVTList (Subtarget.getXLenVT (), MVT::Other);
4626
+ SDValue Res = DAG.getNode (ISD::FLT_ROUNDS_, DL, VTs, N->getOperand (0 ));
4627
+ Results.push_back (Res.getValue (0 ));
4628
+ Results.push_back (Res.getValue (1 ));
4629
+ break ;
4630
+ }
4587
4631
}
4588
4632
}
4589
4633
0 commit comments