}
case ISD::ConstantFP: {
const APFloat &APF = cast<ConstantFPSDNode>(Node)->getValueAPF();
- if (static_cast<const RISCVTargetLowering *>(TLI)->isLegalZfaFPImm(APF, VT))
- break;
+ int FPImm = static_cast<const RISCVTargetLowering *>(TLI)->getLegalZfaFPImm(
+ APF, VT);
+ if (FPImm >= 0) {
+ unsigned Opc;
+ switch (VT.SimpleTy) {
+ default:
+ llvm_unreachable("Unexpected size");
+ case MVT::f16:
+ Opc = RISCV::FLI_H;
+ break;
+ case MVT::f32:
+ Opc = RISCV::FLI_S;
+ break;
+ case MVT::f64:
+ Opc = RISCV::FLI_D;
+ break;
+ }
+
+ SDNode *Res = CurDAG->getMachineNode(
+ Opc, DL, VT, CurDAG->getTargetConstant(FPImm, DL, XLenVT));
+ ReplaceNode(Node, Res);
+ return;
+ }
bool NegZeroF64 = APF.isNegZero() && VT == MVT::f64;
SDValue Imm;
MVT VT = CFP->getSimpleValueType(0);
- if (static_cast<const RISCVTargetLowering *>(TLI)->isLegalZfaFPImm(APF, VT))
+ if (static_cast<const RISCVTargetLowering *>(TLI)->getLegalZfaFPImm(APF,
+ VT) >= 0)
return false;
MVT XLenVT = Subtarget->getXLenVT();
return false;
}
-bool RISCVTargetLowering::isLegalZfaFPImm(const APFloat &Imm, EVT VT) const {
+// Returns 0-31 if the fli instruction is available for the type and this is
+// legal FP immediate for the type. Returns -1 otherwise.
+int RISCVTargetLowering::getLegalZfaFPImm(const APFloat &Imm, EVT VT) const {
if (!Subtarget.hasStdExtZfa())
- return false;
+ return -1;
bool IsSupportedVT = false;
if (VT == MVT::f16) {
IsSupportedVT = true;
}
- return IsSupportedVT && RISCVLoadFPImm::getLoadFPImm(Imm) != -1;
+ if (!IsSupportedVT)
+ return -1;
+
+ return RISCVLoadFPImm::getLoadFPImm(Imm);
}
bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
if (!IsLegalVT)
return false;
- if (isLegalZfaFPImm(Imm, VT))
+ if (getLegalZfaFPImm(Imm, VT) >= 0)
return true;
// Cannot create a 64 bit floating-point immediate value for rv32.
SmallVectorImpl<Use *> &Ops) const override;
bool shouldScalarizeBinop(SDValue VecOp) const override;
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
- bool isLegalZfaFPImm(const APFloat &Imm, EVT VT) const;
+ int getLegalZfaFPImm(const APFloat &Imm, EVT VT) const;
bool isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const override;
bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
: RVInstR<funct7, funct3, OPC_OP_FP, (outs rdty:$rd),
(ins rsty:$rs1, rsty:$rs2), opcodestr, "$rd, $rs1, $rs2">;
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class FPUnaryOp_imm<bits<7> funct7, bits<5> rs2val, bits<3> funct3, RISCVOpcode opcode,
dag outs, dag ins, string opcodestr, string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
// Codegen patterns
//===----------------------------------------------------------------------===//
-def fpimm_to_loadfpimm : SDNodeXForm<fpimm, [{
- return CurDAG->getTargetConstant(RISCVLoadFPImm::getLoadFPImm(N->getValueAPF()),
- SDLoc(N), Subtarget->getXLenVT());}]>;
-
-
let Predicates = [HasStdExtZfa] in {
-def : Pat<(f32 fpimm:$imm), (FLI_S (fpimm_to_loadfpimm fpimm:$imm))>;
-
def: PatFprFpr<fminimum, FMINM_S, FPR32>;
def: PatFprFpr<fmaximum, FMAXM_S, FPR32>;
} // Predicates = [HasStdExtZfa]
let Predicates = [HasStdExtZfa, HasStdExtD] in {
-def : Pat<(f64 fpimm:$imm), (FLI_D (fpimm_to_loadfpimm fpimm:$imm))>;
-
def: PatFprFpr<fminimum, FMINM_D, FPR64>;
def: PatFprFpr<fmaximum, FMAXM_D, FPR64>;
}
let Predicates = [HasStdExtZfa, HasStdExtZfh] in {
-def : Pat<(f16 fpimm:$imm), (FLI_H (fpimm_to_loadfpimm fpimm:$imm))>;
-
def: PatFprFpr<fminimum, FMINM_H, FPR16>;
def: PatFprFpr<fmaximum, FMAXM_H, FPR16>;