diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -158,6 +158,7 @@ OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands); OperandMatchResultTy parseFenceArg(OperandVector &Operands); + OperandMatchResultTy parseFRMArg(OperandVector &Operands); OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); OperandMatchResultTy parseBareSymbol(OperandVector &Operands); OperandMatchResultTy parseCallSymbol(OperandVector &Operands); @@ -432,16 +433,14 @@ /// Return true if the operand is a valid floating point rounding mode. bool isFRMArg() const { + int64_t Imm; + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; if (!isImm()) return false; - const MCExpr *Val = getImm(); - auto *SVal = dyn_cast(Val); - if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + if (!IsConstantImm) return false; - - StringRef Str = SVal->getSymbol().getName(); - - return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; + return RISCVFPRndMode::isValidRoundingMode(Imm); } bool isImmXLenLI() const { @@ -829,22 +828,6 @@ assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::createImm(getVType())); } - - // Returns the rounding mode represented by this RISCVOperand. Should only - // be called after checking isFRMArg. - RISCVFPRndMode::RoundingMode getRoundingMode() const { - // isFRMArg has validated the operand, meaning this cast is safe. - auto SE = cast(getImm()); - RISCVFPRndMode::RoundingMode FRM = - RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); - assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); - return FRM; - } - - void addFRMArgOperands(MCInst &Inst, unsigned N) const { - assert(N == 1 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::createImm(getRoundingMode())); - } }; } // end anonymous namespace. @@ -1091,12 +1074,6 @@ "operand must be a valid system register " "name or an integer in the range"); } - case Match_InvalidFRMArg: { - SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); - return Error( - ErrorLoc, - "operand must be a valid floating point rounding mode mnemonic"); - } case Match_InvalidBareSymbol: { SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error(ErrorLoc, "operand must be a bare symbol name"); @@ -1735,6 +1712,31 @@ return MatchOperand_Success; } +OperandMatchResultTy RISCVAsmParser::parseFRMArg(OperandVector &Operands) { + SMLoc S = getLoc(); + SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); + const MCExpr *Res; + + if (getLexer().getKind() != AsmToken::Identifier) { + Error(S, "operand must be a valid floating point rounding mode mnemonic"); + return MatchOperand_ParseFail; + } + + StringRef Identifier = getParser().getTok().getIdentifier(); + getParser().Lex(); + + RISCVFPRndMode::RoundingMode FRM = + RISCVFPRndMode::stringToRoundingMode(Identifier); + if (FRM == RISCVFPRndMode::Invalid) { + Error(S, "operand must be a valid floating point rounding mode mnemonic"); + return MatchOperand_ParseFail; + } + + Res = MCConstantExpr::create(FRM, getContext()); + Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); + return MatchOperand_Success; +} + /// Looks at a token type and creates the relevant operand from this /// information, adding to Operands. If operand was parsed, returns false, else /// true. diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td @@ -33,8 +33,8 @@ def FRMArg : AsmOperandClass { let Name = "FRMArg"; - let RenderMethod = "addFRMArgOperands"; - let DiagnosticType = "InvalidFRMArg"; + let RenderMethod = "addImmOperands"; + let ParserMethod = "parseFRMArg"; } def frmarg : Operand {