Index: lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp =================================================================== --- lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "MCTargetDesc/RISCVBaseInfo.h" #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" @@ -243,6 +244,17 @@ return MCDisassembler::Success; } +static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, + int64_t Address, + const void *Decoder) { + assert(isUInt<3>(Imm) && "Invalid immediate"); + if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm)) + return MCDisassembler::Fail; + + Inst.addOperand(MCOperand::createImm(Imm)); + return MCDisassembler::Success; +} + #include "RISCVGenDisassemblerTables.inc" DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, Index: lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -104,6 +104,22 @@ .Case("dyn", RISCVFPRndMode::DYN) .Default(RISCVFPRndMode::Invalid); } + +inline static bool isValidRoundingMode(unsigned Mode) { + switch (Mode) { + default: + return false; + case RISCVFPRndMode::RNE: + case RISCVFPRndMode::RTZ: + case RISCVFPRndMode::RDN: + case RISCVFPRndMode::RUP: + case RISCVFPRndMode::RMM: + case RISCVFPRndMode::DYN: + return true; + } + return false; +} + } // namespace RISCVFPRndMode } // namespace llvm Index: lib/Target/RISCV/RISCVInstrInfoF.td =================================================================== --- lib/Target/RISCV/RISCVInstrInfoF.td +++ lib/Target/RISCV/RISCVInstrInfoF.td @@ -27,7 +27,7 @@ def frmarg : Operand { let ParserMatchClass = FRMArg; let PrintMethod = "printFRMArg"; - let DecoderMethod = "decodeUImmOperand<3>"; + let DecoderMethod = "decodeFRMArg"; } //===----------------------------------------------------------------------===// Index: test/MC/RISCV/fuzzer-invalid.txt =================================================================== --- /dev/null +++ test/MC/RISCV/fuzzer-invalid.txt @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -disassemble -triple=riscv32 -mattr=+f,+d < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -disassemble -triple=riscv64 -mattr=+f,+d < %s 2>&1 | FileCheck %s +# +# Test generated by a LLVM MC Disassembler Protocol Buffer Fuzzer +# for the RISC-V assembly language. + +# This decodes as fadd.s ft0, ft0, ft0 with unknown floating point rounding mode +[0x53 0x50 0x00 0x00] +# CHECK: warning: invalid instruction encoding