diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index 220e4d4e6e56e..1a2d679b4ac10 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -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 +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. @@ -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; } @@ -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 +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; +} diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp index 4cb1df29ca6d2..936518da35110 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp @@ -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; + } + return; + } + + // Otherwise, just print the expression. + Op.getExpr()->print(O, &MAI); +} diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h index 6a1d2394d488e..a6d7f9236f552 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h @@ -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, diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index dd77432c8e8d9..21379950485e6 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -227,14 +227,23 @@ def PrefetchTag : Operand { // Branch targets have OtherVT type. def brtarget : Operand { let EncoderMethod = "getBranchTargetOpValue"; + let DecoderMethod = "DecodeDisp<22>"; + let PrintMethod = "printCTILabel"; + let OperandType = "OPERAND_PCREL"; } def bprtarget : Operand { let EncoderMethod = "getBranchPredTargetOpValue"; + let DecoderMethod = "DecodeDisp<19>"; + let PrintMethod = "printCTILabel"; + let OperandType = "OPERAND_PCREL"; } def bprtarget16 : Operand { let EncoderMethod = "getBranchOnRegTargetOpValue"; + let DecoderMethod = "DecodeDisp<16>"; + let PrintMethod = "printCTILabel"; + let OperandType = "OPERAND_PCREL"; } def SparcCallTargetAsmOperand : AsmOperandClass { @@ -246,6 +255,8 @@ def calltarget : Operand { let EncoderMethod = "getCallTargetOpValue"; let DecoderMethod = "DecodeCall"; let ParserMatchClass = SparcCallTargetAsmOperand; + let PrintMethod = "printCTILabel"; + let OperandType = "OPERAND_PCREL"; } // Operand for printing out a condition code. diff --git a/llvm/test/MC/Disassembler/Sparc/sparc.txt b/llvm/test/MC/Disassembler/Sparc/sparc.txt index da1ac062f7220..7b8ca86260fd5 100644 --- a/llvm/test/MC/Disassembler/Sparc/sparc.txt +++ b/llvm/test/MC/Disassembler/Sparc/sparc.txt @@ -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 diff --git a/llvm/test/MC/Sparc/Misc/little-endian.s b/llvm/test/MC/Sparc/Misc/little-endian.s index d02dfd40d195b..d30db6e6aa0d7 100644 --- a/llvm/test/MC/Sparc/Misc/little-endian.s +++ b/llvm/test/MC/Sparc/Misc/little-endian.s @@ -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 diff --git a/llvm/test/MC/Sparc/Relocations/expr.s b/llvm/test/MC/Sparc/Relocations/expr.s index 68ea447a226d6..fcde7d6a1d905 100644 --- a/llvm/test/MC/Sparc/Relocations/expr.s +++ b/llvm/test/MC/Sparc/Relocations/expr.s @@ -7,7 +7,7 @@ mov ((12+3)<<2), %o2 ! CHECK: ba symStart+4 - ! OBJDUMP: ba 0x1 + ! OBJDUMP: ba 0xc symStart: b symStart + 4 diff --git a/llvm/test/MC/Sparc/Relocations/relocation.s b/llvm/test/MC/Sparc/Relocations/relocation.s index 30c2b9409e765..8e632e05def7e 100644 --- a/llvm/test/MC/Sparc/Relocations/relocation.s +++ b/llvm/test/MC/Sparc/Relocations/relocation.s @@ -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 @@ -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 diff --git a/llvm/test/MC/Sparc/sparc64-bpr-offset.s b/llvm/test/MC/Sparc/sparc64-bpr-offset.s index 37453567924f3..3abae6a5b5710 100644 --- a/llvm/test/MC/Sparc/sparc64-bpr-offset.s +++ b/llvm/test/MC/Sparc/sparc64-bpr-offset.s @@ -4,12 +4,12 @@ !! 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 @@ -17,12 +17,12 @@ 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