Index: lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp =================================================================== --- lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -60,6 +60,14 @@ createPPCLEDisassembler); } +static DecodeStatus DecodePCRel24BranchTarget(MCInst &Inst, unsigned Imm, + uint64_t Addr, + const void *Decoder) { + int32_t Offset = SignExtend32<24>(Imm); + Inst.addOperand(MCOperand::createImm(Offset)); + return MCDisassembler::Success; +} + // FIXME: These can be generated by TableGen from the existing register // encoding values! Index: lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp =================================================================== --- lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp +++ lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp @@ -381,8 +381,11 @@ // Branches can take an immediate operand. This is used by the branch // selection pass to print .+8, an eight byte displacement from the PC. - O << ".+"; - printAbsBranchOperand(MI, OpNo, O); + O << "."; + int32_t Imm = MI->getOperand(OpNo).getImm() << 2; + if (Imm >= 0) + O << "+"; + O << Imm; } void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo, Index: lib/Target/PowerPC/PPCInstrInfo.td =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.td +++ lib/Target/PowerPC/PPCInstrInfo.td @@ -736,7 +736,9 @@ def calltarget : Operand { let PrintMethod = "printBranchOperand"; let EncoderMethod = "getDirectBrEncoding"; + let DecoderMethod = "DecodePCRel24BranchTarget"; let ParserMatchClass = PPCDirectBrAsmOperand; + let OperandType = "OPERAND_PCREL"; } def abscalltarget : Operand { let PrintMethod = "printAbsBranchOperand"; Index: test/tools/llvm-objdump/PowerPC/branch-offset.s =================================================================== --- /dev/null +++ test/tools/llvm-objdump/PowerPC/branch-offset.s @@ -0,0 +1,43 @@ +# RUN: llvm-mc -triple=powerpc64le-unknown-linux -filetype=obj %s -o %t.o +# RUN: llvm-objdump -d %t.o | FileCheck %s + +# RUN: llvm-mc -triple=powerpc64-unknown-linux -filetype=obj %s -o %t.o +# RUN: llvm-objdump -d %t.o | FileCheck %s + +# RUN: llvm-mc -triple=powerpc-unknown-linux -filetype=obj %s -o %t.o +# RUN: llvm-objdump -d %t.o | FileCheck %s + +# CHECK: 0000000000000000 callee_back: +# CHECK: 18: {{.*}} bl .-24 +# CHECK: 20: {{.*}} bl .+16 +# CHECK: 0000000000000030 callee_forward: + + .text + .global caller + .type caller,@function + .type callee_forward,@function + .type callee_back,@function + + .p2align 4 +callee_back: + li 3, 55 + blr + + .p2align 4 +caller: +.Lgep: + addis 2, 12, .TOC.-.Lgep@ha + addi 2, 2, .TOC.-.Lgep@l +.Llep: + .localentry caller, .Llep-.Lgep + bl callee_back + mr 31, 3 + bl callee_forward + add 3, 3, 31 + blr + + .p2align 4 +callee_forward: + li 3, 66 + blr + Index: test/tools/llvm-objdump/PowerPC/lit.local.cfg =================================================================== --- /dev/null +++ test/tools/llvm-objdump/PowerPC/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'PowerPC' in config.root.targets: + config.unsupported = True