Skip to content

[MC][RISCV] Add assembly syntax highlighting for RISCV #65853

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 47 additions & 20 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
Expand Down Expand Up @@ -75,7 +76,7 @@ void RISCVInstPrinter::printInst(const MCInst *MI, uint64_t Address,
}

void RISCVInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {
O << getRegisterName(Reg);
markup(O, Markup::Register) << getRegisterName(Reg);
}

void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
Expand All @@ -90,7 +91,7 @@ void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}

if (MO.isImm()) {
O << MO.getImm();
markup(O, Markup::Immediate) << MO.getImm();
return;
}

Expand All @@ -110,9 +111,9 @@ void RISCVInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address,
uint64_t Target = Address + MO.getImm();
if (!STI.hasFeature(RISCV::Feature64Bit))
Target &= 0xffffffff;
O << formatHex(Target);
markup(O, Markup::Target) << formatHex(Target);
} else {
O << MO.getImm();
markup(O, Markup::Target) << MO.getImm();
}
}

Expand All @@ -123,11 +124,11 @@ void RISCVInstPrinter::printCSRSystemRegister(const MCInst *MI, unsigned OpNo,
auto SiFiveReg = RISCVSysReg::lookupSiFiveRegByEncoding(Imm);
auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
if (SiFiveReg && SiFiveReg->haveVendorRequiredFeatures(STI.getFeatureBits()))
O << SiFiveReg->Name;
markup(O, Markup::Register) << SiFiveReg->Name;
else if (SysReg && SysReg->haveRequiredFeatures(STI.getFeatureBits()))
O << SysReg->Name;
markup(O, Markup::Register) << SysReg->Name;
else
O << Imm;
markup(O, Markup::Register) << Imm;
}

void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo,
Expand Down Expand Up @@ -162,21 +163,21 @@ void RISCVInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
unsigned Imm = MI->getOperand(OpNo).getImm();
if (Imm == 1) {
O << "min";
markup(O, Markup::Immediate) << "min";
} else if (Imm == 30) {
O << "inf";
markup(O, Markup::Immediate) << "inf";
} else if (Imm == 31) {
O << "nan";
markup(O, Markup::Immediate) << "nan";
} else {
float FPVal = RISCVLoadFPImm::getFPImm(Imm);
// If the value is an integer, print a .0 fraction. Otherwise, use %g to
// which will not print trailing zeros and will use scientific notation
// if it is shorter than printing as a decimal. The smallest value requires
// 12 digits of precision including the decimal.
if (FPVal == (int)(FPVal))
O << format("%.1f", FPVal);
markup(O, Markup::Immediate) << format("%.1f", FPVal);
else
O << format("%.12g", FPVal);
markup(O, Markup::Immediate) << format("%.12g", FPVal);
}
}

Expand Down Expand Up @@ -211,16 +212,30 @@ void RISCVInstPrinter::printRlist(const MCInst *MI, unsigned OpNo,
O << "{";
switch (Imm) {
case RISCVZC::RLISTENCODE::RA:
O << (ArchRegNames ? "x1" : "ra");
markup(O, Markup::Register) << (ArchRegNames ? "x1" : "ra");
break;
case RISCVZC::RLISTENCODE::RA_S0:
O << (ArchRegNames ? "x1, x8" : "ra, s0");
markup(O, Markup::Register) << (ArchRegNames ? "x1" : "ra");
O << ", ";
markup(O, Markup::Register) << (ArchRegNames ? "x8" : "s0");
break;
case RISCVZC::RLISTENCODE::RA_S0_S1:
O << (ArchRegNames ? "x1, x8-x9" : "ra, s0-s1");
markup(O, Markup::Register) << (ArchRegNames ? "x1" : "ra");
O << ", ";
markup(O, Markup::Register) << (ArchRegNames ? "x8" : "s0");
O << '-';
markup(O, Markup::Register) << (ArchRegNames ? "x9" : "s1");
break;
case RISCVZC::RLISTENCODE::RA_S0_S2:
O << (ArchRegNames ? "x1, x8-x9, x18" : "ra, s0-s2");
markup(O, Markup::Register) << (ArchRegNames ? "x1" : "ra");
O << ", ";
markup(O, Markup::Register) << (ArchRegNames ? "x8" : "s0");
O << '-';
markup(O, Markup::Register) << (ArchRegNames ? "x9" : "s2");
if (ArchRegNames) {
O << ", ";
markup(O, Markup::Register) << "x18";
}
break;
case RISCVZC::RLISTENCODE::RA_S0_S3:
case RISCVZC::RLISTENCODE::RA_S0_S4:
Expand All @@ -229,11 +244,21 @@ void RISCVInstPrinter::printRlist(const MCInst *MI, unsigned OpNo,
case RISCVZC::RLISTENCODE::RA_S0_S7:
case RISCVZC::RLISTENCODE::RA_S0_S8:
case RISCVZC::RLISTENCODE::RA_S0_S9:
O << (ArchRegNames ? "x1, x8-x9, x18-" : "ra, s0-")
<< getRegisterName(RISCV::X19 + (Imm - RISCVZC::RLISTENCODE::RA_S0_S3));
break;
case RISCVZC::RLISTENCODE::RA_S0_S11:
O << (ArchRegNames ? "x1, x8-x9, x18-x27" : "ra, s0-s11");
markup(O, Markup::Register) << (ArchRegNames ? "x1" : "ra");
O << ", ";
markup(O, Markup::Register) << (ArchRegNames ? "x8" : "s0");
O << '-';
if (ArchRegNames) {
markup(O, Markup::Register) << "x9";
O << ", ";
markup(O, Markup::Register) << "x18";
O << '-';
}
markup(O, Markup::Register) << getRegisterName(
RISCV::X19 + (Imm == RISCVZC::RLISTENCODE::RA_S0_S11
? 8
: Imm - RISCVZC::RLISTENCODE::RA_S0_S3));
break;
default:
llvm_unreachable("invalid register list");
Expand All @@ -256,6 +281,8 @@ void RISCVInstPrinter::printSpimm(const MCInst *MI, unsigned OpNo,
if (Opcode == RISCV::CM_PUSH)
Spimm = -Spimm;

// RAII guard for ANSI color escape sequences
WithMarkup ScopedMarkup = markup(O, Markup::Immediate);
RISCVZC::printSpimm(Spimm, O);
}

Expand Down
48 changes: 48 additions & 0 deletions llvm/test/MC/Disassembler/RISCV/colored.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# UNSUPPORTED: system-windows
# RUN: llvm-mc -triple=riscv64 -mattr=+zcmp,+experimental-zfa,+v --cdis %s | FileCheck %s --strict-whitespace --match-full-lines -check-prefixes=CHECK,ASM,ABINAME
# RUN: llvm-mc -triple=riscv64 -mattr=+zcmp,+experimental-zfa,+v -M numeric --cdis %s | FileCheck %s --strict-whitespace --match-full-lines -check-prefixes=CHECK,ASM,ARCHNAME

# CHECK: .text
# Registers and immediates
0x03 0xe0 0x40 0x00
# ABINAME-NEXT: lwu zero, 4(ra)
# ARCHNAME-NEXT: lwu x0, 4(x1)

# Branch targets
0x63 0x00 0xb5 0x04
# ABINAME-NEXT: beq a0, a1, 64
# ARCHNAME-NEXT: beq x10, x11, 64

# CSRs
0xf3 0x23 0x10 0xf1
# ABINAME-NEXT: csrr t2, mvendorid
# ARCHNAME-NEXT: csrr x7, mvendorid

# FP immediates
0xd3 0x00 0x1f 0xf0
# ABINAME-NEXT: fli.s ft1, inf
# ARCHNAME-NEXT: fli.s f1, inf
0xd3 0x80 0x1e 0xf0
# ABINAME-NEXT: fli.s ft1, 65536.0
# ARCHNAME-NEXT: fli.s f1, 65536.0

# Rlist and spimm
0x42 0xbe
# ABINAME-NEXT: cm.popret {ra}, 16
# ARCHNAME-NEXT: cm.popret {x1}, 16
0x5e 0xbe
# ABINAME-NEXT: cm.popret {ra, s0}, 64
# ARCHNAME-NEXT: cm.popret {x1, x8}, 64
0x62 0xbe
# ABINAME-NEXT: cm.popret {ra, s0-s1}, 32
# ARCHNAME-NEXT: cm.popret {x1, x8-x9}, 32
0x76 0xbe
# ABINAME-NEXT: cm.popret {ra, s0-s2}, 48
# ARCHNAME-NEXT: cm.popret {x1, x8-x9, x18}, 48
0xfe 0xbe
# ABINAME-NEXT: cm.popret {ra, s0-s11}, 160
# ARCHNAME-NEXT: cm.popret {x1, x8-x9, x18-x27}, 160

# mask registers
0x57 0x04 0x4a 0x00
# ASM-NEXT: vadd.vv v8, v4, v20, v0.t