diff options
Diffstat (limited to 'lib/Target/PowerPC/PPCAsmPrinter.cpp')
| -rw-r--r-- | lib/Target/PowerPC/PPCAsmPrinter.cpp | 170 |
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()) { |
