aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
diff options
context:
space:
mode:
authorSam Elliott <quic_aelliott@quicinc.com>2025-02-25 11:12:08 -0800
committerGitHub <noreply@github.com>2025-02-25 11:12:08 -0800
commitc8136da26c56f44ab6a217853c58f79b88ceeb97 (patch)
tree1e1b74ff09c0829aa0ddc5420cc27814280e88b2 /llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
parent9102afcd0146e4e0be7e10ecd6a2537a6960cfcd (diff)
downloadllvm-c8136da26c56f44ab6a217853c58f79b88ceeb97.zip
llvm-c8136da26c56f44ab6a217853c58f79b88ceeb97.tar.gz
llvm-c8136da26c56f44ab6a217853c58f79b88ceeb97.tar.bz2
[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`.
Diffstat (limited to 'llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp')
-rw-r--r--llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 8c07d87..830dc28 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -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) {