diff --git a/lld/test/ELF/riscv-branch.s b/lld/test/ELF/riscv-branch.s --- a/lld/test/ELF/riscv-branch.s +++ b/lld/test/ELF/riscv-branch.s @@ -5,17 +5,21 @@ # RUN: ld.lld %t.rv32.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv32 # RUN: ld.lld %t.rv64.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv64 -# RUN: llvm-objdump -d %t.rv32 | FileCheck %s -# RUN: llvm-objdump -d %t.rv64 | FileCheck %s -# CHECK: 63 02 00 00 beqz zero, 4 -# CHECK: e3 1e 00 fe bnez zero, -4 +# RUN: llvm-objdump -d %t.rv32 | FileCheck --check-prefix=CHECK32 %s +# RUN: llvm-objdump -d %t.rv64 | FileCheck --check-prefix=CHECK64 %s +# CHECK32: 63 02 00 00 beqz zero, 0x110b8 +# CHECK32: e3 1e 00 fe bnez zero, 0x110b4 +# CHECK64: 63 02 00 00 beqz zero, 0x11124 +# CHECK64: e3 1e 00 fe bnez zero, 0x11120 # # RUN: ld.lld %t.rv32.o --defsym foo=_start+0xffe --defsym bar=_start+4-0x1000 -o %t.rv32.limits # RUN: ld.lld %t.rv64.o --defsym foo=_start+0xffe --defsym bar=_start+4-0x1000 -o %t.rv64.limits -# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s -# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s -# LIMITS: e3 0f 00 7e beqz zero, 4094 -# LIMITS-NEXT: 63 10 00 80 bnez zero, -4096 +# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS32 %s +# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS64 %s +# LIMITS32: e3 0f 00 7e beqz zero, 0x120b2 +# LIMITS32-NEXT: 63 10 00 80 bnez zero, 0x100b8 +# LIMITS64: e3 0f 00 7e beqz zero, 0x1211e +# LIMITS64-NEXT: 63 10 00 80 bnez zero, 0x10124 # RUN: not ld.lld %t.rv32.o --defsym foo=_start+0x1000 --defsym bar=_start+4-0x1002 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s # RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x1000 --defsym bar=_start+4-0x1002 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s diff --git a/lld/test/ELF/riscv-jal.s b/lld/test/ELF/riscv-jal.s --- a/lld/test/ELF/riscv-jal.s +++ b/lld/test/ELF/riscv-jal.s @@ -5,17 +5,21 @@ # RUN: ld.lld %t.rv32.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv32 # RUN: ld.lld %t.rv64.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv64 -# RUN: llvm-objdump -d %t.rv32 | FileCheck %s -# RUN: llvm-objdump -d %t.rv64 | FileCheck %s -# CHECK: 6f 00 40 00 j 4 -# CHECK: ef f0 df ff jal -4 +# RUN: llvm-objdump -d %t.rv32 | FileCheck --check-prefix=CHECK32 %s +# RUN: llvm-objdump -d %t.rv64 | FileCheck --check-prefix=CHECK64 %s +# CHECK32: 6f 00 40 00 j 0x110b8 +# CHECK32: ef f0 df ff jal 0x110b4 +# CHECK64: 6f 00 40 00 j 0x11124 +# CHECK64: ef f0 df ff jal 0x11120 # RUN: ld.lld %t.rv32.o --defsym foo=_start+0xffffe --defsym bar=_start+4-0x100000 -o %t.rv32.limits # RUN: ld.lld %t.rv64.o --defsym foo=_start+0xffffe --defsym bar=_start+4-0x100000 -o %t.rv64.limits -# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s -# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s -# LIMITS: 6f f0 ff 7f j 1048574 -# LIMITS-NEXT: ef 00 00 80 jal -1048576 +# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS32 %s +# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS64 %s +# LIMITS32: 6f f0 ff 7f j 0x1110b2 +# LIMITS32-NEXT: ef 00 00 80 jal 0xfff110b8 +# LIMITS64: 6f f0 ff 7f j 0x11111e +# LIMITS64-NEXT: ef 00 00 80 jal 0xfffffffffff11124 # RUN: not ld.lld %t.rv32.o --defsym foo=_start+0x100000 --defsym bar=_start+4-0x100002 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s # RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x100000 --defsym bar=_start+4-0x100002 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s diff --git a/lld/test/ELF/riscv-undefined-weak.s b/lld/test/ELF/riscv-undefined-weak.s --- a/lld/test/ELF/riscv-undefined-weak.s +++ b/lld/test/ELF/riscv-undefined-weak.s @@ -52,15 +52,14 @@ # PC-LABEL: : # PC-NEXT: auipc ra, 1048559 # PC-NEXT: jalr -368(ra) -## FIXME: llvm-objdump -d should print the address, instead of the offset. -# PC-NEXT: j -70008 +# PC-NEXT: j 0x0 ## If .dynsym exists, an undefined weak symbol is preemptible. ## We create a PLT entry and redirect the reference to it. # PLT-LABEL: : # PLT-NEXT: auipc ra, 0 # PLT-NEXT: jalr 56(ra) -# PLT-NEXT: j -70448 +# PLT-NEXT: 0x0 branch: call target jal x0, target diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -808,6 +808,7 @@ class Operand : DAGOperand { ValueType Type = ty; string PrintMethod = "printOperand"; + bit PrintRequiresAddr = 0; string EncoderMethod = ""; bit hasCompleteDecoder = 1; string OperandType = "OPERAND_UNKNOWN"; @@ -837,6 +838,9 @@ // this type. The method normally will just use an alt-name index to look // up the name to print. Default to the generic printOperand(). string PrintMethod = pm; + // PrintRequiresAddr - The target method PrintMethod requires the program + // counter to print the operand. + bit PrintRequiresAddr = 0; // EncoderMethod - The target method name to call to encode this register // operand. diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -30,6 +30,9 @@ const MCSubtargetInfo &STI, raw_ostream &O) override; void printRegName(raw_ostream &O, unsigned RegNo) const override; + void printPCRelOp(const MCInst *MI, uint64_t Address, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O, + const char *Modifier = nullptr); void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O, const char *Modifier = nullptr); void printCSRSystemRegister(const MCInst *MI, unsigned OpNo, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -82,6 +82,22 @@ O << getRegisterName(RegNo); } +void RISCVInstPrinter::printPCRelOp(const MCInst *MI, uint64_t Address, + unsigned OpNo, const MCSubtargetInfo &STI, + raw_ostream &O, const char *Modifier) { + assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"); + + if (PrintBranchImmAsAddress && MI->getOperand(OpNo).isImm()) { + uint64_t TargetAddress = Address + MI->getOperand(OpNo).getImm(); + if (!STI.getFeatureBits()[RISCV::Feature64Bit]) + TargetAddress &= 0xffffffff; + O << formatHex(TargetAddress); + return; + } + + printOperand(MI, OpNo, STI, O, Modifier); +} + void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O, const char *Modifier) { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -163,6 +163,8 @@ let ParserMatchClass = SImmAsmOperand<13, "Lsb0">; let EncoderMethod = "getImmOpValueAsr1"; let DecoderMethod = "decodeSImmOperandAndLsl1<13>"; + let PrintMethod = "printPCRelOp"; + let PrintRequiresAddr = 1; let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) @@ -202,6 +204,8 @@ let ParserMatchClass = Simm21Lsb0JALAsmOperand; let EncoderMethod = "getImmOpValueAsr1"; let DecoderMethod = "decodeSImmOperandAndLsl1<21>"; + let PrintMethod = "printPCRelOp"; + let PrintRequiresAddr = 1; let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -142,6 +142,8 @@ let ParserMatchClass = SImmAsmOperand<9, "Lsb0">; let EncoderMethod = "getImmOpValueAsr1"; let DecoderMethod = "decodeSImmOperandAndLsl1<9>"; + let PrintMethod = "printPCRelOp"; + let PrintRequiresAddr = 1; let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) @@ -202,6 +204,8 @@ let ParserMatchClass = SImmAsmOperand<12, "Lsb0">; let EncoderMethod = "getImmOpValueAsr1"; let DecoderMethod = "decodeSImmOperandAndLsl1<12>"; + let PrintMethod = "printPCRelOp"; + let PrintRequiresAddr = 1; let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) diff --git a/llvm/test/CodeGen/RISCV/compress.ll b/llvm/test/CodeGen/RISCV/compress.ll --- a/llvm/test/CodeGen/RISCV/compress.ll +++ b/llvm/test/CodeGen/RISCV/compress.ll @@ -50,34 +50,34 @@ define i32 @select(i32 %a, i32 *%b) #0 { ; RV32IC-LABEL: