[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