diff --git a/lld/test/ELF/ppc64-toc-call-to-pcrel.s b/lld/test/ELF/ppc64-toc-call-to-pcrel.s --- a/lld/test/ELF/ppc64-toc-call-to-pcrel.s +++ b/lld/test/ELF/ppc64-toc-call-to-pcrel.s @@ -29,23 +29,22 @@ # SYMBOL: 10020020 0 NOTYPE LOCAL DEFAULT [] 2 caller_14 # SYMBOL: 10020040 8 FUNC LOCAL DEFAULT 2 __toc_save_callee -# CHECK-LABEL: callee -# CHECK: blr +# CHECK: +# CHECK: blr -# CHECK-LABEL: caller -# CHECK: bl 0x10020040 -# CHECK-NEXT: ld 2, 24(1) -# CHECK-NEXT: blr +# CHECK: +# CHECK: bl 0x10020040 <__toc_save_callee> +# CHECK-NEXT: ld 2, 24(1) +# CHECK-NEXT: blr -# CHECK-LABEL: caller_14 -# CHECK: bfl 0, 0x10020040 -# CHECK-NEXT: ld 2, 24(1) -# CHECK-NEXT: blr - -# CHECK-LABEL: __toc_save_callee -# CHECK-NEXT: std 2, 24(1) -# CHECK-NEXT: b 0x10010000 +# CHECK: +# CHECK: bfl 0, 0x10020040 <__toc_save_callee> +# CHECK-NEXT: ld 2, 24(1) +# CHECK-NEXT: blr +# CHECK: <__toc_save_callee> +# CHECK-NEXT: std 2, 24(1) +# CHECK-NEXT: b 0x10010000 .section .text_callee, "ax", %progbits callee: diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -28,6 +28,7 @@ #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCRegisterInfo.h" @@ -368,6 +369,31 @@ return new PPCInstPrinter(MAI, MII, MRI, T); } +namespace { + +class PPCMCInstrAnalysis : public MCInstrAnalysis { +public: + explicit PPCMCInstrAnalysis(const MCInstrInfo *Info) + : MCInstrAnalysis(Info) {} + + bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, + uint64_t &Target) const override { + unsigned NumOps = Inst.getNumOperands(); + if (NumOps == 0 || + Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType != + MCOI::OPERAND_PCREL) + return false; + Target = Addr + Inst.getOperand(NumOps - 1).getImm() * Size; + return true; + } +}; + +} // end anonymous namespace + +static MCInstrAnalysis *createPPCMCInstrAnalysis(const MCInstrInfo *Info) { + return new PPCMCInstrAnalysis(Info); +} + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() { for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(), &getThePPC64Target(), &getThePPC64LETarget()}) { @@ -383,6 +409,9 @@ // Register the MC subtarget info. TargetRegistry::RegisterMCSubtargetInfo(*T, createPPCMCSubtargetInfo); + // Register the MC instruction analyzer. + TargetRegistry::RegisterMCInstrAnalysis(*T, createPPCMCInstrAnalysis); + // Register the MC Code Emitter TargetRegistry::RegisterMCCodeEmitter(*T, createPPCMCCodeEmitter); diff --git a/llvm/test/tools/llvm-objdump/ELF/PowerPC/disassemble-symbolize-operands.ll b/llvm/test/tools/llvm-objdump/ELF/PowerPC/disassemble-symbolize-operands.ll --- a/llvm/test/tools/llvm-objdump/ELF/PowerPC/disassemble-symbolize-operands.ll +++ b/llvm/test/tools/llvm-objdump/ELF/PowerPC/disassemble-symbolize-operands.ll @@ -0,0 +1,36 @@ +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu %s -filetype=obj -o %t +; RUN: llvm-objdump %t -d --symbolize-operands --no-show-raw-insn --no-leading-addr \ +; RUN: | FileCheck %s + +;; Expect to find the branch labels. +; CHECK: : +; CHECK-NEXT: andi. 4, 4, 1 +; CHECK-NEXT: li 4, 1 +; CHECK-NEXT: b 0x28 +; CHECK: : +; CHECK-NEXT: addi 4, 4, 1 +; CHECK-NEXT: bclr 4, 1 +; CHECK-NEXT: : +; CHECK-NEXT: cmplw 1, 3, 4 +; CHECK-NEXT: bf 4, 0x20 +; CHECK-NEXT: dcbf 0, 3 +; CHECK-NEXT: b 0x20 + +define void @break_cond_is_arg(i32 %arg, i1 %breakcond) { +entry: + br label %loop +loop: + %tmp23phi = phi i32 [ %tmp23, %endif ], [ 0, %entry ] + %tmp23 = add nuw i32 %tmp23phi, 1 + %tmp27 = icmp ult i32 %arg, %tmp23 + br i1 %tmp27, label %then, label %endif +then: ; preds = %bb + tail call void @llvm.ppc.dcbf(i8* undef) + br label %endif +endif: ; preds = %bb28, %bb + br i1 %breakcond, label %loop, label %loopexit +loopexit: + ret void +} + +declare void @llvm.ppc.dcbf(i8*) diff --git a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll --- a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll +++ b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbolize-operands.ll @@ -0,0 +1,36 @@ +; RUN: llc -mtriple=powerpc-ibm-aix-xcoff %s -filetype=obj -o %t +; RUN: llvm-objdump %t -d --symbolize-operands --no-show-raw-insn --no-leading-addr \ +; RUN: | FileCheck %s + +;; Expect to find the branch labels. +; CHECK: <.text>: +; CHECK-NEXT: andi. 4, 4, 1 +; CHECK-NEXT: li 4, 1 +; CHECK-NEXT: b 0x14 +; CHECK-NEXT: : +; CHECK-NEXT: addi 4, 4, 1 +; CHECK-NEXT: bclr 4, 1 +; CHECK-NEXT: : +; CHECK-NEXT: cmplw 1, 3, 4 +; CHECK-NEXT: bf 4, 0xc +; CHECK-NEXT: dcbf 0, 3 +; CHECK-NEXT: b 0xc + +define void @break_cond_is_arg(i32 %arg, i1 %breakcond) { +entry: + br label %loop +loop: + %tmp23phi = phi i32 [ %tmp23, %endif ], [ 0, %entry ] + %tmp23 = add nuw i32 %tmp23phi, 1 + %tmp27 = icmp ult i32 %arg, %tmp23 + br i1 %tmp27, label %then, label %endif +then: ; preds = %bb + tail call void @llvm.ppc.dcbf(i8* undef) + br label %endif +endif: ; preds = %bb28, %bb + br i1 %breakcond, label %loop, label %loopexit +loopexit: + ret void +} + +declare void @llvm.ppc.dcbf(i8*) diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -978,8 +978,8 @@ const MCSubtargetInfo *STI, uint64_t SectionAddr, uint64_t Start, uint64_t End, std::unordered_map &Labels) { - // So far only supports X86. - if (!STI->getTargetTriple().isX86()) + // So far only supports PowerPC and X86. + if (!STI->getTargetTriple().isPPC() && !STI->getTargetTriple().isX86()) return; Labels.clear();