[llvm] 625f7e5 - [RISCV][Disassembler] Symbolize UImm20 and SImm12Lo operands (#217550)

via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 23:45:32 PDT 2026


Author: Thrrreeee
Date: 2026-08-21T14:45:27+08:00
New Revision: 625f7e514be2246826093bc3fee68003deaf20a9

URL: https://github.com/llvm/llvm-project/commit/625f7e514be2246826093bc3fee68003deaf20a9
DIFF: https://github.com/llvm/llvm-project/commit/625f7e514be2246826093bc3fee68003deaf20a9.diff

LOG: [RISCV][Disassembler] Symbolize UImm20 and SImm12Lo operands (#217550)

he RISC-V disassembler currently decodes operands represented by
`UImm20OperandMaybeSym` and `Simm12LoOp` directly into immediate
operands. As a result, an installed `MCSymbolizer` has no opportunity to
recover relocation-backed symbolic expressions for these operands.

Enable `MCSymbolizer` handling for RISC-V `UImm20` and `SImm12Lo`
operands. Fall back to the original immediate when symbolization is not
available. `SImm12Lo` values are sign-extended, while `UImm20` values
remain unchanged.

This enables clients such as BOLT to reconstruct symbolic operands for
HI20/LO12, PC-relative, and GOT relocations during instruction decoding.

This change only adds symbolizer hooks for these operands; the actual
symbolization is delegated to the installed `MCSymbolizer`. When no
symbolizer is installed, the existing immediate-based disassembly
behavior is preserved. Test coverage may need to be added after
RISCVMCSymbolizer is implemented in BOLT.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfo.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 3b3eb5195a9b4..024862e63521f 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -65,17 +65,37 @@ static MCDisassembler *createRISCVDisassembler(const Target &T,
   return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
 }
 
+static MCSymbolizer *
+createRISCVMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
+                        LLVMSymbolLookupCallback /*SymbolLookUp*/,
+                        void *DisInfo, MCContext *Ctx,
+                        std::unique_ptr<MCRelocationInfo> &&RelInfo) {
+  // RISC-V only asks MCSymbolizer to decode HI20/LO12 address fragments. They
+  // require relocation information and cannot be looked up as absolute
+  // addresses when GetOpInfo fails.
+  return llvm::createMCSymbolizer(TT, GetOpInfo, /*SymbolLookUp=*/nullptr,
+                                  DisInfo, Ctx, std::move(RelInfo));
+}
+
 extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
 LLVMInitializeRISCVDisassembler() {
   // Register the disassembler for each target.
   TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
                                          createRISCVDisassembler);
+  TargetRegistry::RegisterMCSymbolizer(getTheRISCV32Target(),
+                                       createRISCVMCSymbolizer);
   TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
                                          createRISCVDisassembler);
+  TargetRegistry::RegisterMCSymbolizer(getTheRISCV64Target(),
+                                       createRISCVMCSymbolizer);
   TargetRegistry::RegisterMCDisassembler(getTheRISCV32beTarget(),
                                          createRISCVDisassembler);
+  TargetRegistry::RegisterMCSymbolizer(getTheRISCV32beTarget(),
+                                       createRISCVMCSymbolizer);
   TargetRegistry::RegisterMCDisassembler(getTheRISCV64beTarget(),
                                          createRISCVDisassembler);
+  TargetRegistry::RegisterMCSymbolizer(getTheRISCV64beTarget(),
+                                       createRISCVMCSymbolizer);
 }
 
 template <unsigned FirstReg, unsigned NumRegsInClass, unsigned RVELimit = 0>
@@ -403,6 +423,32 @@ static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus decodeSImm12LoOperand(MCInst &Inst, uint32_t Imm,
+                                          int64_t Address,
+                                          const MCDisassembler *Decoder) {
+  assert(isUInt<12>(Imm) && "Invalid immediate");
+  const int64_t Value = SignExtend64<12>(Imm);
+  if (!Decoder->tryAddingSymbolicOperand(Inst, Value, Address,
+                                         /*IsBranch=*/false,
+                                         /*Offset=*/0, /*OpSize=*/4,
+                                         /*InstSize=*/4))
+    Inst.addOperand(MCOperand::createImm(Value));
+  return MCDisassembler::Success;
+}
+
+static DecodeStatus decodeUImm20Operand(MCInst &Inst, uint32_t Imm,
+                                        int64_t Address,
+                                        const MCDisassembler *Decoder) {
+  assert(isUInt<20>(Imm) && "Invalid immediate");
+  const int64_t Value = SignExtend64<32>(Imm << 12);
+  if (!Decoder->tryAddingSymbolicOperand(Inst, Value, Address,
+                                         /*IsBranch=*/false,
+                                         /*Offset=*/0, /*OpSize=*/4,
+                                         /*InstSize=*/4))
+    Inst.addOperand(MCOperand::createImm(Imm));
+  return MCDisassembler::Success;
+}
+
 template <unsigned N>
 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
                                              int64_t Address,

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 5be74d729c5b0..5a37b229664c4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -400,6 +400,7 @@ def uimm64 : RISCVUImmOp<64>;
 def simm12 : RISCVSImmLeafOp<12>;
 
 class Simm12LoOp : RISCVSImmLeafOp<12> {
+  let DecoderMethod = "decodeSImm12LoOperand";
   let MCOperandPredicate = [{
     int64_t Imm;
     if (MCOp.evaluateAsConstantImm(Imm))
@@ -455,6 +456,7 @@ def bare_simm13_lsb0 : BareSImm13Lsb0MaybeSym,
 def bare_simm13_lsb0_bb : BareSImm13Lsb0MaybeSym;
 
 class UImm20OperandMaybeSym : RISCVUImmOp<20> {
+  let DecoderMethod = "decodeUImm20Operand";
   let MCOperandPredicate = [{
     int64_t Imm;
     if (MCOp.evaluateAsConstantImm(Imm))


        


More information about the llvm-commits mailing list