From 61ae2aaf52b4c40bf297daa4bbf36d46bfecd1d3 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 8 Mar 2023 09:10:18 -0800 Subject: [PATCH] [RISCV] Store fli min/nan/inf in index form in RISCVOperand. 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 | 29 ++++++++++++++-------- llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 + 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 4abd8f7..b2f7092 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -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()); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 8ea9330..ac7fe95 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -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; -- 2.7.4