Skip to content

[SPARC] Print target address when disassembling branches and calls #140340

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 3 commits into from
May 19, 2025
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
25 changes: 19 additions & 6 deletions llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,10 @@ static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address,
const MCDisassembler *Decoder);
static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address,
const MCDisassembler *Decoder);

template <unsigned N>
constexpr static DecodeStatus DecodeDisp(MCInst &MI, uint32_t ImmVal,
uint64_t Address,
const MCDisassembler *Decoder);
#include "SparcGenDisassemblerTables.inc"

/// Read four bytes from the ArrayRef and return 32 bit word.
Expand Down Expand Up @@ -326,11 +329,10 @@ static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,

static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, uint64_t Address,
const MCDisassembler *Decoder) {
unsigned tgt = fieldFromInstruction(insn, 0, 30);
tgt <<= 2;
if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
0, 30, MI, Decoder))
MI.addOperand(MCOperand::createImm(tgt));
int64_t CallOffset = SignExtend64(fieldFromInstruction(insn, 0, 30), 30) * 4;
if (!tryAddingSymbolicOperand(Address + CallOffset, false, Address, 0, 30, MI,
Decoder))
MI.addOperand(MCOperand::createImm(CallOffset));
return MCDisassembler::Success;
}

Expand All @@ -340,3 +342,14 @@ static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address,
MI.addOperand(MCOperand::createImm(SignExtend64<13>(insn)));
return MCDisassembler::Success;
}

template <unsigned N>
constexpr static DecodeStatus DecodeDisp(MCInst &MI, uint32_t ImmVal,
uint64_t Address,
const MCDisassembler *Decoder) {
int64_t BranchOffset = SignExtend64(ImmVal, N) * 4;
if (!tryAddingSymbolicOperand(Address + BranchOffset, true, Address, 0, N, MI,
Decoder))
MI.addOperand(MCOperand::createImm(BranchOffset));
return MCDisassembler::Success;
}
27 changes: 27 additions & 0 deletions llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,30 @@ void SparcInstPrinter::printPrefetchTag(const MCInst *MI, int opNum,
else
O << Imm;
}

void SparcInstPrinter::printCTILabel(const MCInst *MI, uint64_t Address,
unsigned OpNum, const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNum);

// If the label has already been resolved to an immediate offset (say, when
// we're running the disassembler), just print the immediate.
if (Op.isImm()) {
int64_t Offset = Op.getImm();
if (PrintBranchImmAsAddress) {
uint64_t Target = Address + Offset;
if (STI.getTargetTriple().isSPARC32())
Target &= 0xffffffff;
O << formatHex(Target);
} else {
O << ".";
if (Offset >= 0)
O << "+";
O << Offset;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the isImm case when PrintBranchImmAsAddress is false, print .+imm or .-imm like PowerPC.

}
return;
}

// Otherwise, just print the expression.
Op.getExpr()->print(O, &MAI);
}
2 changes: 2 additions & 0 deletions llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class SparcInstPrinter : public MCInstPrinter {
getMnemonic(const MCInst &MI) const override;
void printInstruction(const MCInst *MI, uint64_t Address,
const MCSubtargetInfo &STI, raw_ostream &O);
void printCTILabel(const MCInst *MI, uint64_t Address, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
bool printAliasInstr(const MCInst *MI, uint64_t Address,
const MCSubtargetInfo &STI, raw_ostream &O);
void printCustomAliasOperand(const MCInst *MI, uint64_t Address,
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/Target/Sparc/SparcInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,23 @@ def PrefetchTag : Operand<i32> {
// Branch targets have OtherVT type.
def brtarget : Operand<OtherVT> {
let EncoderMethod = "getBranchTargetOpValue";
let DecoderMethod = "DecodeDisp<22>";
let PrintMethod = "printCTILabel";
let OperandType = "OPERAND_PCREL";
}

def bprtarget : Operand<OtherVT> {
let EncoderMethod = "getBranchPredTargetOpValue";
let DecoderMethod = "DecodeDisp<19>";
let PrintMethod = "printCTILabel";
let OperandType = "OPERAND_PCREL";
}

def bprtarget16 : Operand<OtherVT> {
let EncoderMethod = "getBranchOnRegTargetOpValue";
let DecoderMethod = "DecodeDisp<16>";
let PrintMethod = "printCTILabel";
let OperandType = "OPERAND_PCREL";
}

def SparcCallTargetAsmOperand : AsmOperandClass {
Expand All @@ -246,6 +255,8 @@ def calltarget : Operand<i32> {
let EncoderMethod = "getCallTargetOpValue";
let DecoderMethod = "DecodeCall";
let ParserMatchClass = SparcCallTargetAsmOperand;
let PrintMethod = "printCTILabel";
let OperandType = "OPERAND_PCREL";
}

// Operand for printing out a condition code.
Expand Down
90 changes: 45 additions & 45 deletions llvm/test/MC/Disassembler/Sparc/sparc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,142 +81,142 @@
# CHECK: subxcc %g1, %g2, %g3
0x86 0xe0 0x40 0x02

# CHECK: ba 4194303
# CHECK: ba .-4
0x10 0xbf 0xff 0xff

# CHECK: bne 4194303
# CHECK: bne .-4
0x12 0xbf 0xff 0xff

# CHECK: be 4194303
# CHECK: be .-4
0x02 0xbf 0xff 0xff

# CHECK: bg 4194303
# CHECK: bg .-4
0x14 0xbf 0xff 0xff

# CHECK: ble 4194303
# CHECK: ble .-4
0x04 0xbf 0xff 0xff

# CHECK: bge 4194303
# CHECK: bge .-4
0x16 0xbf 0xff 0xff

# CHECK: bl 4194303
# CHECK: bl .-4
0x06 0xbf 0xff 0xff

# CHECK: bgu 4194303
# CHECK: bgu .-4
0x18 0xbf 0xff 0xff

# CHECK: bleu 4194303
# CHECK: bleu .-4
0x08 0xbf 0xff 0xff

# CHECK: bcc 4194303
# CHECK: bcc .-4
0x1a 0xbf 0xff 0xff

# CHECK: bcs 4194303
# CHECK: bcs .-4
0x0a 0xbf 0xff 0xff

# CHECK: bpos 4194303
# CHECK: bpos .-4
0x1c 0xbf 0xff 0xff

# CHECK: bneg 4194303
# CHECK: bneg .-4
0x0c 0xbf 0xff 0xff

# CHECK: bvc 4194303
# CHECK: bvc .-4
0x1e 0xbf 0xff 0xff

# CHECK: bvs 4194303
# CHECK: bvs .-4
0x0e 0xbf 0xff 0xff

# CHECK: fbu 4194303
# CHECK: fbu .-4
0x0f 0xbf 0xff 0xff

# CHECK: fbg 4194303
# CHECK: fbg .-4
0x0d 0xbf 0xff 0xff

# CHECK: fbug 4194303
# CHECK: fbug .-4
0x0b 0xbf 0xff 0xff

# CHECK: fbl 4194303
# CHECK: fbl .-4
0x09 0xbf 0xff 0xff

# CHECK: fbul 4194303
# CHECK: fbul .-4
0x07 0xbf 0xff 0xff

# CHECK: fblg 4194303
# CHECK: fblg .-4
0x05 0xbf 0xff 0xff

# CHECK: fbne 4194303
# CHECK: fbne .-4
0x03 0xbf 0xff 0xff

# CHECK: fbe 4194303
# CHECK: fbe .-4
0x13 0xbf 0xff 0xff

# CHECK: fbue 4194303
# CHECK: fbue .-4
0x15 0xbf 0xff 0xff

# CHECK: fbge 4194303
# CHECK: fbge .-4
0x17 0xbf 0xff 0xff

# CHECK: fbuge 4194303
# CHECK: fbuge .-4
0x19 0xbf 0xff 0xff

# CHECK: fble 4194303
# CHECK: fble .-4
0x1b 0xbf 0xff 0xff

# CHECK: fbule 4194303
# CHECK: fbule .-4
0x1d 0xbf 0xff 0xff

# CHECK: fbo 4194303
# CHECK: fbo .-4
0x1f 0xbf 0xff 0xff

# CHECK: cba 4194303
# CHECK: cba .-4
0x11 0xff 0xff 0xff

# CHECK: cbn 4194303
# CHECK: cbn .-4
0x01 0xff 0xff 0xff

# CHECK: cb3 4194303
# CHECK: cb3 .-4
0x0f 0xff 0xff 0xff

# CHECK: cb2 4194303
# CHECK: cb2 .-4
0x0d 0xff 0xff 0xff

# CHECK: cb23 4194303
# CHECK: cb23 .-4
0x0b 0xff 0xff 0xff

# CHECK: cb1 4194303
# CHECK: cb1 .-4
0x09 0xff 0xff 0xff

# CHECK: cb13 4194303
# CHECK: cb13 .-4
0x07 0xff 0xff 0xff

# CHECK: cb12 4194303
# CHECK: cb12 .-4
0x05 0xff 0xff 0xff

# CHECK: cb123 4194303
# CHECK: cb123 .-4
0x03 0xff 0xff 0xff

# CHECK: cb03 4194303
# CHECK: cb03 .-4
0x15 0xff 0xff 0xff

# CHECK: cb02 4194303
# CHECK: cb02 .-4
0x17 0xff 0xff 0xff

# CHECK: cb023 4194303
# CHECK: cb023 .-4
0x19 0xff 0xff 0xff

# CHECK: cb01 4194303
# CHECK: cb01 .-4
0x1b 0xff 0xff 0xff

# CHECK: cb013 4194303
# CHECK: cb013 .-4
0x1d 0xff 0xff 0xff

# CHECK: cb012 4194303
# CHECK: cb012 .-4
0x1f 0xff 0xff 0xff

# CHECK: restore
0x81 0xe8 0x00 0x00

# CHECK: call 16
# CHECK: call .+16
0x40 0x00 0x00 0x04

# CHECK: add %g1, -10, %g2
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/MC/Sparc/Misc/little-endian.s
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
! ...and that fixups are applied to the correct bytes.

! CHECK: ba .BB0 ! encoding: [A,A,0b10AAAAAA,0x10]
! CHECK-OBJ: 4: ff ff bf 10 ba 0x3fffff
! CHECK-OBJ: 4: ff ff bf 10 ba 0x0
ba .BB0
2 changes: 1 addition & 1 deletion llvm/test/MC/Sparc/Relocations/expr.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
mov ((12+3)<<2), %o2

! CHECK: ba symStart+4
! OBJDUMP: ba 0x1
! OBJDUMP: ba 0xc
symStart:
b symStart + 4

Expand Down
16 changes: 8 additions & 8 deletions llvm/test/MC/Sparc/Relocations/relocation.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
# ASM: call local1
# ASM-NEXT: call undef
# OBJDUMP: call 0x14
# OBJDUMP-NEXT: call 0x0
# OBJDUMP-NEXT: call 0x4
# OBJDUMP-NEXT: R_SPARC_WDISP30 .text1+0x4
# OBJDUMP-NEXT: call 0x0
# OBJDUMP-NEXT: call 0x8
# OBJDUMP-NEXT: R_SPARC_WDISP30 undef{{$}}
call local
call local1
Expand All @@ -28,15 +28,15 @@ local:

# ASM: brz %g1, undef
# ASM: brlz %g1, .Ltmp{{.}}-8
# OBJDUMP: brz %g1, 0x0
# OBJDUMP: brz %g1, 0x14
# OBJDUMP-NEXT: R_SPARC_WDISP16 undef
# OBJDUMP-NEXT: brlz %g1, 0xfffe
# OBJDUMP-NEXT: bg %icc, 0x0
# OBJDUMP-NEXT: brlz %g1, 0x10
# OBJDUMP-NEXT: bg %icc, 0x1c
# OBJDUMP-NEXT: R_SPARC_WDISP19 undef
# OBJDUMP-NEXT: bg %icc, 0x7fffe
# OBJDUMP-NEXT: cbn 0x0
# OBJDUMP-NEXT: bg %icc, 0x18
# OBJDUMP-NEXT: cbn 0x24
# OBJDUMP-NEXT: R_SPARC_WDISP22 undef
# OBJDUMP-NEXT: cbn 0x3ffffe
# OBJDUMP-NEXT: cbn 0x20
brz %g1, undef
brlz %g1, .-8
bg %icc, undef
Expand Down
24 changes: 12 additions & 12 deletions llvm/test/MC/Sparc/sparc64-bpr-offset.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@
!! make sure that our offset bits don't trample on other fields.
!! This is particularly important with backwards branches.

! BIN: 0: 02 c8 40 01 brz %g1, 1
! BIN: 4: 04 c8 40 01 brlez %g1, 1
! BIN: 8: 06 c8 40 01 brlz %g1, 1
! BIN: c: 0a c8 40 01 brnz %g1, 1
! BIN: 10: 0c c8 40 01 brgz %g1, 1
! BIN: 14: 0e c8 40 01 brgez %g1, 1
! BIN: 0: 02 c8 40 01 brz %g1, 0x4
! BIN: 4: 04 c8 40 01 brlez %g1, 0x8
! BIN: 8: 06 c8 40 01 brlz %g1, 0xc
! BIN: c: 0a c8 40 01 brnz %g1, 0x10
! BIN: 10: 0c c8 40 01 brgz %g1, 0x14
! BIN: 14: 0e c8 40 01 brgez %g1, 0x18
brz %g1, .+4
brlez %g1, .+4
brlz %g1, .+4
brnz %g1, .+4
brgz %g1, .+4
brgez %g1, .+4

! BIN: 18: 02 f8 7f ff brz %g1, 65535
! BIN: 1c: 04 f8 7f ff brlez %g1, 65535
! BIN: 20: 06 f8 7f ff brlz %g1, 65535
! BIN: 24: 0a f8 7f ff brnz %g1, 65535
! BIN: 28: 0c f8 7f ff brgz %g1, 65535
! BIN: 2c: 0e f8 7f ff brgez %g1, 65535
! BIN: 18: 02 f8 7f ff brz %g1, 0x14
! BIN: 1c: 04 f8 7f ff brlez %g1, 0x18
! BIN: 20: 06 f8 7f ff brlz %g1, 0x1c
! BIN: 24: 0a f8 7f ff brnz %g1, 0x20
! BIN: 28: 0c f8 7f ff brgz %g1, 0x24
! BIN: 2c: 0e f8 7f ff brgez %g1, 0x28
brz %g1, .-4
brlez %g1, .-4
brlz %g1, .-4
Expand Down