diff options
Diffstat (limited to 'llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp')
| -rw-r--r-- | llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 3f76ce3b24a..0037d8d8af4 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -185,6 +185,20 @@ public: return true; } + /// Return true if the operand is a valid floating point rounding mode. + bool isFRMArg() const { + if (!isImm()) + return false; + const MCExpr *Val = getImm(); + auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); + if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) + return false; + + StringRef Str = SVal->getSymbol().getName(); + + return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; + } + bool isUImm5() const { int64_t Imm; RISCVMCExpr::VariantKind VK; @@ -344,6 +358,22 @@ public: } Inst.addOperand(MCOperand::createImm(Imm)); } + + // 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<MCSymbolRefExpr>(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. @@ -411,6 +441,12 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, ErrorLoc, "operand must be formed of letters selected in-order from 'iorw'"); } + case Match_InvalidFRMArg: { + SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error( + ErrorLoc, + "operand must be a valid floating point rounding mode mnemonic"); + } } llvm_unreachable("Unknown match type detected!"); |

