[llvm] [LoongArch][MC] Add basic assembly syntax highlighting for LoongArch (PR #218946)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 08:00:53 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-loongarch

Author: Rong "Mantle" Bao (CSharperMantle)

<details>
<summary>Changes</summary>

This PR adds color highlighting of registers and immediates in LoongArch disassembly.

This is similar to #<!-- -->65853, but does not distinguish regular immediates and branch offsets, due to needing to edit the same file as #<!-- -->217971. Branch target colorization will be added in a follow-up PR.

After this PR:

<img width="1492" height="868" alt="colorized output" src="https://github.com/user-attachments/assets/b48f494e-8354-4c98-8394-b6c20c473c06" />

CC: @<!-- -->SixWeining, @<!-- -->wangleiat


---
Full diff: https://github.com/llvm/llvm-project/pull/218946.diff


5 Files Affected:

- (modified) llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td (+4-2) 
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp (+12-2) 
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h (+2) 
- (added) llvm/test/MC/Disassembler/LoongArch/lit.local.cfg (+2) 
- (added) llvm/test/MC/Disassembler/LoongArch/marked-up.txt (+12) 


``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td b/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td
index ce42236895c76..c8fd203aa5898 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td
+++ b/llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td
@@ -219,6 +219,8 @@ class FP_STORE_2RI12<bits<32> op, RegisterClass rc = FPR32>
                  "$fd, $rj, $imm12">;
 } // hasSideEffects = 0, mayLoad = 0, mayStore = 1
 
+def CFRSetDest : RegisterOperand<CFR, "printCFRSetDest">;
+
 // This class is used to define `SET_CFR_{FALSE,TRUE}` instructions which are
 // used to expand `PseudoCopyCFR`.
 class SET_CFR<bits<32> op, string opcstr>
@@ -226,7 +228,7 @@ class SET_CFR<bits<32> op, string opcstr>
   let isCodeGenOnly = 1;
   let fj = 0; // fa0
   let fk = 0; // fa0
-  let AsmString = opcstr # "\t$cd, $$fa0, $$fa0";
-  let OutOperandList = (outs CFR:$cd);
+  let AsmString = opcstr # "\t$cd";
+  let OutOperandList = (outs CFRSetDest:$cd);
   let InOperandList = (ins);
 }
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp
index f912af330e34e..3a0aa20e56a33 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp
@@ -65,7 +65,7 @@ void LoongArchInstPrinter::printInst(const MCInst *MI, uint64_t Address,
 }
 
 void LoongArchInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) {
-  O << '$' << getRegisterName(Reg);
+  markup(O, Markup::Register) << '$' << getRegisterName(Reg);
 }
 
 void LoongArchInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
@@ -79,7 +79,7 @@ void LoongArchInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
   }
 
   if (MO.isImm()) {
-    O << MO.getImm();
+    markup(O, Markup::Immediate) << MO.getImm();
     return;
   }
 
@@ -95,6 +95,16 @@ void LoongArchInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo,
   printRegName(O, MO.getReg());
 }
 
+void LoongArchInstPrinter::printCFRSetDest(const MCInst *MI, unsigned OpNo,
+                                           const MCSubtargetInfo &STI,
+                                           raw_ostream &O) {
+  printRegName(O, MI->getOperand(OpNo).getReg());
+  O << ", ";
+  printRegName(O, LoongArch::F0);
+  O << ", ";
+  printRegName(O, LoongArch::F0);
+}
+
 const char *LoongArchInstPrinter::getRegisterName(MCRegister Reg) {
   // Default print reg alias name
   return getRegisterName(Reg, NumericReg ? LoongArch::NoRegAltName
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h
index 235f967f50ff4..bf96d869f185c 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.h
@@ -31,6 +31,8 @@ class LoongArchInstPrinter : public MCInstPrinter {
   void printRegName(raw_ostream &O, MCRegister Reg) override;
   void printAtomicMemOp(const MCInst *MI, unsigned OpNo,
                         const MCSubtargetInfo &STI, raw_ostream &O);
+  void printCFRSetDest(const MCInst *MI, unsigned OpNo,
+                       const MCSubtargetInfo &STI, raw_ostream &O);
 
   // Autogenerated by tblgen.
   std::pair<const char *, uint64_t>
diff --git a/llvm/test/MC/Disassembler/LoongArch/lit.local.cfg b/llvm/test/MC/Disassembler/LoongArch/lit.local.cfg
new file mode 100644
index 0000000000000..cc24278acbb41
--- /dev/null
+++ b/llvm/test/MC/Disassembler/LoongArch/lit.local.cfg
@@ -0,0 +1,2 @@
+if not "LoongArch" in config.root.targets:
+    config.unsupported = True
diff --git a/llvm/test/MC/Disassembler/LoongArch/marked-up.txt b/llvm/test/MC/Disassembler/LoongArch/marked-up.txt
new file mode 100644
index 0000000000000..c1f2d153f6457
--- /dev/null
+++ b/llvm/test/MC/Disassembler/LoongArch/marked-up.txt
@@ -0,0 +1,12 @@
+# RUN: llvm-mc -triple=loongarch64 -mattr=+f --mdis < %s | FileCheck %s
+
+## Ordinary registers and immediates remain marked up.
+0xe5 0xd8 0x83 0x02
+# CHECK: addi.w <reg:$a1>, <reg:$a3>, <imm:246>
+
+## The encoding is decoded as the architectural compare instruction. This
+## covers the visible fixed-register spelling used by SET_CFR.
+0x00 0x00 0x10 0x0c
+# CHECK: fcmp.caf.s <reg:$fcc0>, <reg:$fa0>, <reg:$fa0>
+0x00 0x00 0x16 0x0c
+# CHECK: fcmp.cueq.s <reg:$fcc0>, <reg:$fa0>, <reg:$fa0>

``````````

</details>


https://github.com/llvm/llvm-project/pull/218946


More information about the llvm-commits mailing list