summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/PowerPC/PPCAsmPrinter.cpp')
-rw-r--r--lib/Target/PowerPC/PPCAsmPrinter.cpp170
1 files changed, 109 insertions, 61 deletions
diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 841b8c514464..17451900840a 100644
--- a/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -19,6 +19,7 @@
#include "InstPrinter/PPCInstPrinter.h"
#include "MCTargetDesc/PPCMCExpr.h"
#include "MCTargetDesc/PPCMCTargetDesc.h"
+#include "MCTargetDesc/PPCPredicates.h"
#include "PPC.h"
#include "PPCInstrInfo.h"
#include "PPCMachineFunctionInfo.h"
@@ -506,7 +507,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInst TmpInst;
bool isPPC64 = Subtarget->isPPC64();
bool isDarwin = TM.getTargetTriple().isOSDarwin();
- const Module *M = MF->getFunction()->getParent();
+ const Module *M = MF->getFunction().getParent();
PICLevel::Level PL = M->getPICLevel();
// Lower multi-instruction pseudo operations.
@@ -520,7 +521,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return LowerPATCHPOINT(SM, *MI);
case PPC::MoveGOTtoLR: {
- // Transform %LR = MoveGOTtoLR
+ // Transform %lr = MoveGOTtoLR
// Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
// _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
// _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
@@ -541,7 +542,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
case PPC::MovePCtoLR:
case PPC::MovePCtoLR8: {
- // Transform %LR = MovePCtoLR
+ // Transform %lr = MovePCtoLR
// Into this, where the label is the PIC base:
// bl L1$pb
// L1$pb:
@@ -559,9 +560,9 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::UpdateGBR: {
- // Transform %Rd = UpdateGBR(%Rt, %Ri)
- // Into: lwz %Rt, .L0$poff - .L0$pb(%Ri)
- // add %Rd, %Rt, %Ri
+ // Transform %rd = UpdateGBR(%rt, %ri)
+ // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
+ // add %rd, %rt, %ri
// Get the offset from the GOT Base Register to the GOT
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
MCSymbol *PICOffset =
@@ -576,7 +577,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
const MCOperand TR = TmpInst.getOperand(1);
const MCOperand PICR = TmpInst.getOperand(0);
- // Step 1: lwz %Rt, .L$poff - .L$pb(%Ri)
+ // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
TmpInst.getOperand(1) =
MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
TmpInst.getOperand(0) = TR;
@@ -591,7 +592,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::LWZtoc: {
- // Transform %R3 = LWZtoc <ga:@min1>, %R2
+ // Transform %r3 = LWZtoc @min1, %r2
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to LWZ, and the global address operand to be a
@@ -635,7 +636,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case PPC::LDtocCPT:
case PPC::LDtocBA:
case PPC::LDtoc: {
- // Transform %X3 = LDtoc <ga:@min1>, %X2
+ // Transform %x3 = LDtoc @min1, %x2
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to LD, and the global address operand to be a
@@ -666,7 +667,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
case PPC::ADDIStocHA: {
- // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
+ // Transform %xd = ADDIStocHA %x2, @sym
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to ADDIS8. If the global address is external, has
@@ -713,7 +714,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::LDtocL: {
- // Transform %Xd = LDtocL <ga:@sym>, %Xs
+ // Transform %xd = LDtocL @sym, %xs
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to LD. If the global address is external, has
@@ -756,7 +757,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::ADDItocL: {
- // Transform %Xd = ADDItocL %Xs, <ga:@sym>
+ // Transform %xd = ADDItocL %xs, @sym
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to ADDI8. If the global address is external, then
@@ -787,8 +788,8 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::ADDISgotTprelHA: {
- // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym>
- // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
+ // Transform: %xd = ADDISgotTprelHA %x2, @sym
+ // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
@@ -804,7 +805,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
case PPC::LDgotTprelL:
case PPC::LDgotTprelL32: {
- // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
+ // Transform %xd = LDgotTprelL @sym, %xs
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
// Change the opcode to LD.
@@ -865,8 +866,8 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::ADDIStlsgdHA: {
- // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
- // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
+ // Transform: %xd = ADDIStlsgdHA %x2, @sym
+ // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
@@ -881,11 +882,11 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::ADDItlsgdL:
- // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
- // Into: %Xd = ADDI8 %Xs, sym@got@tlsgd@l
+ // Transform: %xd = ADDItlsgdL %xs, @sym
+ // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
case PPC::ADDItlsgdL32: {
- // Transform: %Rd = ADDItlsgdL32 %Rs, <ga:@sym>
- // Into: %Rd = ADDI %Rs, sym@got@tlsgd
+ // Transform: %rd = ADDItlsgdL32 %rs, @sym
+ // Into: %rd = ADDI %rs, sym@got@tlsgd
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
@@ -901,17 +902,17 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::GETtlsADDR:
- // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
+ // Transform: %x3 = GETtlsADDR %x3, @sym
// Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
case PPC::GETtlsADDR32: {
- // Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym>
+ // Transform: %r3 = GETtlsADDR32 %r3, @sym
// Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD);
return;
}
case PPC::ADDIStlsldHA: {
- // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
- // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha
+ // Transform: %xd = ADDIStlsldHA %x2, @sym
+ // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
@@ -926,11 +927,11 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::ADDItlsldL:
- // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
- // Into: %Xd = ADDI8 %Xs, sym@got@tlsld@l
+ // Transform: %xd = ADDItlsldL %xs, @sym
+ // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
case PPC::ADDItlsldL32: {
- // Transform: %Rd = ADDItlsldL32 %Rs, <ga:@sym>
- // Into: %Rd = ADDI %Rs, sym@got@tlsld
+ // Transform: %rd = ADDItlsldL32 %rs, @sym
+ // Into: %rd = ADDI %rs, sym@got@tlsld
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
@@ -946,20 +947,20 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::GETtlsldADDR:
- // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
+ // Transform: %x3 = GETtlsldADDR %x3, @sym
// Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
case PPC::GETtlsldADDR32: {
- // Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym>
+ // Transform: %r3 = GETtlsldADDR32 %r3, @sym
// Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD);
return;
}
case PPC::ADDISdtprelHA:
- // Transform: %Xd = ADDISdtprelHA %Xs, <ga:@sym>
- // Into: %Xd = ADDIS8 %Xs, sym@dtprel@ha
+ // Transform: %xd = ADDISdtprelHA %xs, @sym
+ // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
case PPC::ADDISdtprelHA32: {
- // Transform: %Rd = ADDISdtprelHA32 %Rs, <ga:@sym>
- // Into: %Rd = ADDIS %Rs, sym@dtprel@ha
+ // Transform: %rd = ADDISdtprelHA32 %rs, @sym
+ // Into: %rd = ADDIS %rs, sym@dtprel@ha
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
@@ -975,11 +976,11 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
case PPC::ADDIdtprelL:
- // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
- // Into: %Xd = ADDI8 %Xs, sym@dtprel@l
+ // Transform: %xd = ADDIdtprelL %xs, @sym
+ // Into: %xd = ADDI8 %xs, sym@dtprel@l
case PPC::ADDIdtprelL32: {
- // Transform: %Rd = ADDIdtprelL32 %Rs, <ga:@sym>
- // Into: %Rd = ADDI %Rs, sym@dtprel@l
+ // Transform: %rd = ADDIdtprelL32 %rs, @sym
+ // Into: %rd = ADDI %rs, sym@dtprel@l
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
@@ -996,8 +997,8 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case PPC::MFOCRF:
case PPC::MFOCRF8:
if (!Subtarget->hasMFOCRF()) {
- // Transform: %R3 = MFOCRF %CR7
- // Into: %R3 = MFCR ;; cr7
+ // Transform: %r3 = MFOCRF %cr7
+ // Into: %r3 = MFCR ;; cr7
unsigned NewOpcode =
MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
OutStreamer->AddComment(PPCInstPrinter::
@@ -1010,8 +1011,8 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case PPC::MTOCRF:
case PPC::MTOCRF8:
if (!Subtarget->hasMFOCRF()) {
- // Transform: %CR7 = MTOCRF %R3
- // Into: MTCRF mask, %R3 ;; cr7
+ // Transform: %cr7 = MTOCRF %r3
+ // Into: MTCRF mask, %r3 ;; cr7
unsigned NewOpcode =
MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
@@ -1089,7 +1090,61 @@ void PPCLinuxAsmPrinter::EmitInstruction(const MachineInstr *MI) {
recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER);
break;
}
- case TargetOpcode::PATCHABLE_FUNCTION_EXIT: {
+ case TargetOpcode::PATCHABLE_RET: {
+ unsigned RetOpcode = MI->getOperand(0).getImm();
+ MCInst RetInst;
+ RetInst.setOpcode(RetOpcode);
+ for (const auto &MO :
+ make_range(std::next(MI->operands_begin()), MI->operands_end())) {
+ MCOperand MCOp;
+ if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this, false))
+ RetInst.addOperand(MCOp);
+ }
+
+ bool IsConditional;
+ if (RetOpcode == PPC::BCCLR) {
+ IsConditional = true;
+ } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
+ RetOpcode == PPC::TCRETURNai8) {
+ break;
+ } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
+ IsConditional = false;
+ } else {
+ EmitToStreamer(*OutStreamer, RetInst);
+ break;
+ }
+
+ MCSymbol *FallthroughLabel;
+ if (IsConditional) {
+ // Before:
+ // bgtlr cr0
+ //
+ // After:
+ // ble cr0, .end
+ // .p2align 3
+ // .begin:
+ // blr # lis 0, FuncId[16..32]
+ // nop # li 0, FuncId[0..15]
+ // std 0, -8(1)
+ // mflr 0
+ // bl __xray_FunctionExit
+ // mtlr 0
+ // blr
+ // .end:
+ //
+ // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
+ // of instructions change.
+ FallthroughLabel = OutContext.createTempSymbol();
+ EmitToStreamer(
+ *OutStreamer,
+ MCInstBuilder(PPC::BCC)
+ .addImm(PPC::InvertPredicate(
+ static_cast<PPC::Predicate>(MI->getOperand(1).getImm())))
+ .addReg(MI->getOperand(2).getReg())
+ .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext)));
+ RetInst = MCInst();
+ RetInst.setOpcode(PPC::BLR8);
+ }
// .p2align 3
// .begin:
// b(lr)? # lis 0, FuncId[16..32]
@@ -1098,24 +1153,14 @@ void PPCLinuxAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// mflr 0
// bl __xray_FunctionExit
// mtlr 0
- // .end:
// b(lr)?
//
// Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
// of instructions change.
- const MachineInstr *Next = [&] {
- MachineBasicBlock::const_iterator It(MI);
- assert(It != MI->getParent()->end());
- ++It;
- assert(It->isReturn());
- return &*It;
- }();
OutStreamer->EmitCodeAlignment(8);
MCSymbol *BeginOfSled = OutContext.createTempSymbol();
OutStreamer->EmitLabel(BeginOfSled);
- MCInst TmpInst;
- LowerPPCMachineInstrToMCInst(Next, TmpInst, *this, false);
- EmitToStreamer(*OutStreamer, TmpInst);
+ EmitToStreamer(*OutStreamer, RetInst);
EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
EmitToStreamer(
*OutStreamer,
@@ -1127,15 +1172,18 @@ void PPCLinuxAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutContext.getOrCreateSymbol("__xray_FunctionExit"),
OutContext)));
EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
+ EmitToStreamer(*OutStreamer, RetInst);
+ if (IsConditional)
+ OutStreamer->EmitLabel(FallthroughLabel);
recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT);
break;
}
+ case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
+ llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
case TargetOpcode::PATCHABLE_TAIL_CALL:
- case TargetOpcode::PATCHABLE_RET:
- // PPC's tail call instruction, e.g. PPC::TCRETURNdi8, doesn't really
- // lower to a PPC::B instruction. The PPC::B instruction is generated
- // before it, and handled by the normal case.
- llvm_unreachable("Tail call is handled in the normal case. See comments"
+ // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
+ // normal function exit from a tail exit.
+ llvm_unreachable("Tail call is handled in the normal case. See comments "
"around this assert.");
}
}
@@ -1180,7 +1228,7 @@ void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
// linux/ppc32 - Normal entry label.
if (!Subtarget->isPPC64() &&
(!isPositionIndependent() ||
- MF->getFunction()->getParent()->getPICLevel() == PICLevel::SmallPIC))
+ MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))
return AsmPrinter::EmitFunctionEntryLabel();
if (!Subtarget->isPPC64()) {