[llvm] [RISC-V][Mach-O] Print immediate operands in hexadecimal format. (PR #174505)

Francesco Petrogalli via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 6 22:17:06 PST 2026


https://github.com/fpetrogalli updated https://github.com/llvm/llvm-project/pull/174505

>From 3307698c5bcf3bb73ee77d9a45b549a8336d17e7 Mon Sep 17 00:00:00 2001
From: Francesco Petrogalli <francesco.petrogalli at apple.com>
Date: Thu, 9 Oct 2025 14:51:26 -0700
Subject: [PATCH 1/3] [RISC-V][Mach-O] Print immediate operands in hexadecimal
 format.

This is done for the logical operations and auipc/lui.

Patch based on code written by Tim Northover.
---
 .../RISCV/MCTargetDesc/RISCVInstPrinter.cpp   | 29 +++++++++++++++++++
 .../RISCV/MCTargetDesc/RISCVInstPrinter.h     |  2 ++
 llvm/test/MC/RISCV/hex-imm-macho.s            | 16 ++++++++++
 3 files changed, 47 insertions(+)
 create mode 100644 llvm/test/MC/RISCV/hex-imm-macho.s

diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index f2c5f6947aa00..2bfe477d4a940 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -95,6 +95,11 @@ void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
     return;
   }
 
+  if (MO.isImm() && STI.getTargetTriple().isOSBinFormatMachO()) {
+    printImmMachO(MI, OpNo, STI, O);
+    return;
+  }
+
   if (MO.isImm()) {
     markup(O, Markup::Immediate) << formatImm(MO.getImm());
     return;
@@ -337,6 +342,30 @@ void RISCVInstPrinter::printVMaskReg(const MCInst *MI, unsigned OpNo,
   O << ".t";
 }
 
+void RISCVInstPrinter::printImmMachO(const MCInst *MI, unsigned OpNo,
+                                     const MCSubtargetInfo &STI,
+                                     raw_ostream &O) {
+  const MCOperand &Op = MI->getOperand(OpNo);
+
+  switch (MI->getOpcode()) {
+  case RISCV::ANDI:
+  case RISCV::ORI:
+  case RISCV::XORI:
+  case RISCV::C_ANDI:
+  case RISCV::AUIPC:
+  case RISCV::LUI:
+    break;
+  default:
+    markup(O, Markup::Immediate) << formatImm(Op.getImm());
+    return;
+  }
+
+  uint64_t Imm = Op.getImm();
+  if (!STI.hasFeature(RISCV::Feature64Bit))
+    Imm = static_cast<uint32_t>(Imm);
+  markup(O, Markup::Immediate) << formatHex(Imm);
+}
+
 const char *RISCVInstPrinter::getRegisterName(MCRegister Reg) {
   // When PrintAliases is enabled, and EmitX8AsFP is enabled, x8 will be printed
   // as fp instead of s0. Note that these similar registers are not replaced:
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
index f8b8fd34abbb4..0e71765d46833 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
@@ -52,6 +52,8 @@ class RISCVInstPrinter : public MCInstPrinter {
                        const MCSubtargetInfo &STI, raw_ostream &O);
   void printVMaskReg(const MCInst *MI, unsigned OpNo,
                      const MCSubtargetInfo &STI, raw_ostream &O);
+  void printImmMachO(const MCInst *MI, unsigned OpNo,
+                     const MCSubtargetInfo &STI, raw_ostream &O);
   void printRegList(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
                     raw_ostream &O);
   void printStackAdj(const MCInst *MI, unsigned OpNo,
diff --git a/llvm/test/MC/RISCV/hex-imm-macho.s b/llvm/test/MC/RISCV/hex-imm-macho.s
new file mode 100644
index 0000000000000..5344bf2a41858
--- /dev/null
+++ b/llvm/test/MC/RISCV/hex-imm-macho.s
@@ -0,0 +1,16 @@
+// RUN: llvm-mc -triple riscv32-apple-unknown-macho -mattr=+c --riscv-no-aliases %s | FileCheck %s
+
+// CHECK: andi a0, a0, 0x190
+// CHECK: ori a0, a0, 0x400
+// CHECK: xori a0, a0, 0xfffffff4
+andi a0, a0, 400
+ori a0, a0, 1024
+xori a0, a0, -12
+
+// CHECK: c.andi s0, 0x1f
+c.andi s0, 31
+
+// CHECK: auipc a0, 0x3e8
+// CHECK: lui a0, 0x2710
+auipc a0, 1000
+lui a0, 10000

>From ad1ed8899be11a51e5be24c318e3452f91e74830 Mon Sep 17 00:00:00 2001
From: Francesco Petrogalli <francesco.petrogalli at apple.com>
Date: Tue, 6 Jan 2026 17:15:17 -0800
Subject: [PATCH 2/3] [review] Use &= instead of static_cast. [NFC]

---
 llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index 2bfe477d4a940..6d7cf5c018b0f 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -362,7 +362,7 @@ void RISCVInstPrinter::printImmMachO(const MCInst *MI, unsigned OpNo,
 
   uint64_t Imm = Op.getImm();
   if (!STI.hasFeature(RISCV::Feature64Bit))
-    Imm = static_cast<uint32_t>(Imm);
+    Imm &= 0xffffffff;
   markup(O, Markup::Immediate) << formatHex(Imm);
 }
 

>From e96165143446052660f63f45a5ee0e9e8fcf7725 Mon Sep 17 00:00:00 2001
From: Francesco Petrogalli <francesco.petrogalli at apple.com>
Date: Tue, 6 Jan 2026 22:11:31 -0800
Subject: [PATCH 3/3] Use a generic printImm function that handles both mach-o
 and not mach-o targets, to highlight what differs.

---
 .../RISCV/MCTargetDesc/RISCVInstPrinter.cpp   | 39 +++++++------------
 .../RISCV/MCTargetDesc/RISCVInstPrinter.h     |  4 +-
 2 files changed, 15 insertions(+), 28 deletions(-)

diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index 6d7cf5c018b0f..1fa5eea4cac9b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -95,13 +95,8 @@ void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
     return;
   }
 
-  if (MO.isImm() && STI.getTargetTriple().isOSBinFormatMachO()) {
-    printImmMachO(MI, OpNo, STI, O);
-    return;
-  }
-
   if (MO.isImm()) {
-    markup(O, Markup::Immediate) << formatImm(MO.getImm());
+    printImm(MI, OpNo, STI, O);
     return;
   }
 
@@ -342,28 +337,20 @@ void RISCVInstPrinter::printVMaskReg(const MCInst *MI, unsigned OpNo,
   O << ".t";
 }
 
-void RISCVInstPrinter::printImmMachO(const MCInst *MI, unsigned OpNo,
-                                     const MCSubtargetInfo &STI,
-                                     raw_ostream &O) {
+void RISCVInstPrinter::printImm(const MCInst *MI, unsigned OpNo,
+                                const MCSubtargetInfo &STI, raw_ostream &O) {
   const MCOperand &Op = MI->getOperand(OpNo);
-
-  switch (MI->getOpcode()) {
-  case RISCV::ANDI:
-  case RISCV::ORI:
-  case RISCV::XORI:
-  case RISCV::C_ANDI:
-  case RISCV::AUIPC:
-  case RISCV::LUI:
-    break;
-  default:
-    markup(O, Markup::Immediate) << formatImm(Op.getImm());
-    return;
-  }
-
+  const unsigned Opcode = MI->getOpcode();
   uint64_t Imm = Op.getImm();
-  if (!STI.hasFeature(RISCV::Feature64Bit))
-    Imm &= 0xffffffff;
-  markup(O, Markup::Immediate) << formatHex(Imm);
+  if (STI.getTargetTriple().isOSBinFormatMachO() &&
+      (Opcode == RISCV::ANDI || Opcode == RISCV::ORI || Opcode == RISCV::XORI ||
+       Opcode == RISCV::C_ANDI || Opcode == RISCV::AUIPC ||
+       Opcode == RISCV::LUI)) {
+    if (!STI.hasFeature(RISCV::Feature64Bit))
+      Imm &= 0xffffffff;
+    markup(O, Markup::Immediate) << formatHex(Imm);
+  } else
+    markup(O, Markup::Immediate) << formatImm(Imm);
 }
 
 const char *RISCVInstPrinter::getRegisterName(MCRegister Reg) {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
index 0e71765d46833..17469bd87e34e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
@@ -52,8 +52,8 @@ class RISCVInstPrinter : public MCInstPrinter {
                        const MCSubtargetInfo &STI, raw_ostream &O);
   void printVMaskReg(const MCInst *MI, unsigned OpNo,
                      const MCSubtargetInfo &STI, raw_ostream &O);
-  void printImmMachO(const MCInst *MI, unsigned OpNo,
-                     const MCSubtargetInfo &STI, raw_ostream &O);
+  void printImm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
+                raw_ostream &O);
   void printRegList(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
                     raw_ostream &O);
   void printStackAdj(const MCInst *MI, unsigned OpNo,



More information about the llvm-commits mailing list