[RISCV] Store fli min/nan/inf in index form in RISCVOperand.
authorCraig Topper <craig.topper@sifive.com>
Wed, 8 Mar 2023 17:10:18 +0000 (09:10 -0800)
committerCraig Topper <craig.topper@sifive.com>
Wed, 8 Mar 2023 17:24:58 +0000 (09:24 -0800)
Instead of converting to FP value, store them as Index using an
immediate operand.

Do the same for the explicit index form.

This avoids using the FP32 version of these special values as the
representation for fli.h and fli.d. inf/nan aren't so bad, but
"min" is problematic as the current implementation allows fli.d and
fli.h to accept the decimal version of the fp32 minimum value. I
will submit another patch to fix that.

Differential Revision: https://reviews.llvm.org/D145535

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

index 4abd8f7..b2f7092 100644 (file)
@@ -492,6 +492,8 @@ public:
 
   /// Return true if the operand is a valid fli.s floating-point immediate.
   bool isLoadFPImm() const {
+    if (isImm())
+      return isUImm5();
     return Kind == KindTy::FPImmediate &&
            RISCVLoadFPImm::getLoadFP32Imm(APInt(32, getFPConst())) != -1;
   }
@@ -973,6 +975,11 @@ public:
 
   void addFPImmOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
+    if (isImm()) {
+      addExpr(Inst, getImm(), isRV64Imm());
+      return;
+    }
+
     int Imm = RISCVLoadFPImm::getLoadFP32Imm(APInt(32, getFPConst()));
     Inst.addOperand(MCOperand::createImm(Imm));
   }
@@ -1567,16 +1574,17 @@ OperandMatchResultTy RISCVAsmParser::parseFPImm(OperandVector &Operands) {
   if (getTok().is(AsmToken::Identifier)) {
     StringRef Identifier = getTok().getIdentifier();
     if (Identifier.compare_insensitive("inf") == 0) {
-      APFloat SpecialVal = APFloat::getInf(APFloat::IEEEsingle());
-      Operands.push_back(RISCVOperand::createFPImm(
-          SpecialVal.bitcastToAPInt().getZExtValue(), S));
+      Operands.push_back(
+          RISCVOperand::createImm(MCConstantExpr::create(30, getContext()), S,
+                                  getTok().getEndLoc(), isRV64()));
     } else if (Identifier.compare_insensitive("nan") == 0) {
-      APFloat SpecialVal = APFloat::getNaN(APFloat::IEEEsingle());
-      Operands.push_back(RISCVOperand::createFPImm(
-          SpecialVal.bitcastToAPInt().getZExtValue(), S));
+      Operands.push_back(
+          RISCVOperand::createImm(MCConstantExpr::create(31, getContext()), S,
+                                  getTok().getEndLoc(), isRV64()));
     } else if (Identifier.compare_insensitive("min") == 0) {
-      unsigned SpecialVal = RISCVLoadFPImm::getFPImm(1);
-      Operands.push_back(RISCVOperand::createFPImm(SpecialVal, S));
+      Operands.push_back(
+          RISCVOperand::createImm(MCConstantExpr::create(1, getContext()), S,
+                                  getTok().getEndLoc(), isRV64()));
     } else {
       TokError("invalid floating point literal");
       return MatchOperand_ParseFail;
@@ -1602,8 +1610,9 @@ OperandMatchResultTy RISCVAsmParser::parseFPImm(OperandVector &Operands) {
       TokError("encoded floating point value out of range");
       return MatchOperand_ParseFail;
     }
-    unsigned F = RISCVLoadFPImm::getFPImm(Tok.getIntVal());
-    Operands.push_back(RISCVOperand::createFPImm(F, S));
+    Operands.push_back(RISCVOperand::createImm(
+        MCConstantExpr::create(Tok.getIntVal(), getContext()), S,
+        Tok.getEndLoc(), isRV64()));
   } else {
     // Parse FP representation.
     APFloat RealVal(APFloat::IEEEsingle());
index 8ea9330..ac7fe95 100644 (file)
@@ -376,6 +376,7 @@ static inline int getLoadFPImm(uint8_t Sign, uint8_t Exp, uint8_t Mantissa) {
 
 namespace RISCVLoadFPImm {
 inline static uint32_t getFPImm(unsigned Imm) {
+  assert(Imm != 1 && Imm != 30 && Imm != 31 && "Unsupported immediate");
   uint8_t Sign;
   uint8_t Exp;
   uint8_t Mantissa;