mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 05:36:07 +00:00
[RISCV] Correctly Decode Unsigned Immediates with Ranges (#128584)
We currently have two operands upstream that are an unsigned immediate with a range constraint - `uimm8ge32` (for `cm.jalt`) and `uimm5gt3` (for `qc.shladd`). Both of these were using `decodeUImmOperand<N>` for decoding. For `Zcmt` this worked, because the generated decoder automatically checked for `cm.jt` first because the 8 undefined bits in `cm.jalt` are `000?????` in `cm.jt` (this is to do with the range lower-bound being a power-of-two). For Zcmt, this patch is NFC. We have less luck with `Xqciac` - `qc.shladd` is being decoded where the `uimm5` field is 3 or lower. This patch fixes this by introducing a `decodeUImmOperandGE<Width, LowerBound>` helper, which will corretly return `MCDisassembler::Fail` when the immediate is below the lower bound. I have added a test to show the encoding where `uimm5` is equal to 3 is no longer disassembled as `qc.shladd`.
This commit is contained in:
parent
9102afcd01
commit
c8136da26c
@ -328,6 +328,19 @@ static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
template <unsigned Width, unsigned LowerBound>
|
||||
static DecodeStatus decodeUImmOperandGE(MCInst &Inst, uint32_t Imm,
|
||||
int64_t Address,
|
||||
const MCDisassembler *Decoder) {
|
||||
assert(isUInt<Width>(Imm) && "Invalid immediate");
|
||||
|
||||
if (Imm < LowerBound)
|
||||
return MCDisassembler::Fail;
|
||||
|
||||
Inst.addOperand(MCOperand::createImm(Imm));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeUImmLog2XLenOperand(MCInst &Inst, uint32_t Imm,
|
||||
int64_t Address,
|
||||
const MCDisassembler *Decoder) {
|
||||
|
@ -24,7 +24,7 @@ def uimm5nonzero : RISCVOp<XLenVT>,
|
||||
def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
|
||||
[{return (Imm > 3) && isUInt<5>(Imm);}]> {
|
||||
let ParserMatchClass = UImmAsmOperand<5, "GT3">;
|
||||
let DecoderMethod = "decodeUImmOperand<5>";
|
||||
let DecoderMethod = "decodeUImmOperandGE<5, 4>";
|
||||
let OperandType = "OPERAND_UIMM5_GT3";
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ def uimm2_lsb0 : RISCVOp,
|
||||
|
||||
def uimm8ge32 : RISCVOp {
|
||||
let ParserMatchClass = UImmAsmOperand<8, "GE32">;
|
||||
let DecoderMethod = "decodeUImmOperand<8>";
|
||||
let DecoderMethod = "decodeUImmOperandGE<8, 32>";
|
||||
let OperandType = "OPERAND_UIMM8_GE32";
|
||||
}
|
||||
|
||||
|
10
llvm/test/MC/Disassembler/RISCV/xqci-invalid.txt
Normal file
10
llvm/test/MC/Disassembler/RISCV/xqci-invalid.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# RUN: not llvm-mc -disassemble -triple=riscv32 -mattr=+experimental-xqciac %s | FileCheck %s
|
||||
|
||||
[0x00,0x00]
|
||||
# CHECK: unimp
|
||||
|
||||
[0x8b,0x30,0x31,0x46]
|
||||
# CHECK-NOT: qc.shladd x1, x2, x3, {{[0-9]+}}
|
||||
|
||||
[0x00,0x00]
|
||||
# CHECK: unimp
|
Loading…
x
Reference in New Issue
Block a user