diff options
Diffstat (limited to 'lib/Target/PowerPC/PPCAsmPrinter.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCAsmPrinter.cpp | 127 |
1 files changed, 91 insertions, 36 deletions
diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index 17451900840a..a9da64cc216f 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -510,6 +510,32 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const Module *M = MF->getFunction().getParent(); PICLevel::Level PL = M->getPICLevel(); +#ifndef NDEBUG + // Validate that SPE and FPU are mutually exclusive in codegen + if (!MI->isInlineAsm()) { + for (const MachineOperand &MO: MI->operands()) { + if (MO.isReg()) { + unsigned Reg = MO.getReg(); + if (Subtarget->hasSPE()) { + if (PPC::F4RCRegClass.contains(Reg) || + PPC::F8RCRegClass.contains(Reg) || + PPC::QBRCRegClass.contains(Reg) || + PPC::QFRCRegClass.contains(Reg) || + PPC::QSRCRegClass.contains(Reg) || + PPC::VFRCRegClass.contains(Reg) || + PPC::VRRCRegClass.contains(Reg) || + PPC::VSFRCRegClass.contains(Reg) || + PPC::VSSRCRegClass.contains(Reg) + ) + llvm_unreachable("SPE targets cannot have FPRegs!"); + } else { + if (PPC::SPERCRegClass.contains(Reg)) + llvm_unreachable("SPE register found in FPU-targeted code!"); + } + } + } + } +#endif // Lower multi-instruction pseudo operations. switch (MI->getOpcode()) { default: break; @@ -563,33 +589,63 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { // Transform %rd = UpdateGBR(%rt, %ri) // Into: lwz %rt, .L0$poff - .L0$pb(%ri) // add %rd, %rt, %ri + // or into (if secure plt mode is on): + // addis r30, r30, .LTOC - .L0$pb@ha + // addi r30, r30, .LTOC - .L0$pb@l // Get the offset from the GOT Base Register to the GOT LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); - MCSymbol *PICOffset = - MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(); - TmpInst.setOpcode(PPC::LWZ); - const MCExpr *Exp = - MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext); - const MCExpr *PB = - MCSymbolRefExpr::create(MF->getPICBaseSymbol(), - MCSymbolRefExpr::VK_None, - OutContext); - const MCOperand TR = TmpInst.getOperand(1); - const MCOperand PICR = TmpInst.getOperand(0); - - // Step 1: lwz %rt, .L$poff - .L$pb(%ri) - TmpInst.getOperand(1) = - MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext)); - TmpInst.getOperand(0) = TR; - TmpInst.getOperand(2) = PICR; - EmitToStreamer(*OutStreamer, TmpInst); + if (Subtarget->isSecurePlt() && isPositionIndependent() ) { + unsigned PICR = TmpInst.getOperand(0).getReg(); + MCSymbol *LTOCSymbol = OutContext.getOrCreateSymbol(StringRef(".LTOC")); + const MCExpr *PB = + MCSymbolRefExpr::create(MF->getPICBaseSymbol(), + OutContext); - TmpInst.setOpcode(PPC::ADD4); - TmpInst.getOperand(0) = PICR; - TmpInst.getOperand(1) = TR; - TmpInst.getOperand(2) = PICR; - EmitToStreamer(*OutStreamer, TmpInst); - return; + const MCExpr *LTOCDeltaExpr = + MCBinaryExpr::createSub(MCSymbolRefExpr::create(LTOCSymbol, OutContext), + PB, OutContext); + + const MCExpr *LTOCDeltaHi = + PPCMCExpr::createHa(LTOCDeltaExpr, false, OutContext); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS) + .addReg(PICR) + .addReg(PICR) + .addExpr(LTOCDeltaHi)); + + const MCExpr *LTOCDeltaLo = + PPCMCExpr::createLo(LTOCDeltaExpr, false, OutContext); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI) + .addReg(PICR) + .addReg(PICR) + .addExpr(LTOCDeltaLo)); + return; + } else { + MCSymbol *PICOffset = + MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(); + TmpInst.setOpcode(PPC::LWZ); + const MCExpr *Exp = + MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext); + const MCExpr *PB = + MCSymbolRefExpr::create(MF->getPICBaseSymbol(), + MCSymbolRefExpr::VK_None, + OutContext); + const MCOperand TR = TmpInst.getOperand(1); + const MCOperand PICR = TmpInst.getOperand(0); + + // Step 1: lwz %rt, .L$poff - .L$pb(%ri) + TmpInst.getOperand(1) = + MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext)); + TmpInst.getOperand(0) = TR; + TmpInst.getOperand(2) = PICR; + EmitToStreamer(*OutStreamer, TmpInst); + + TmpInst.setOpcode(PPC::ADD4); + TmpInst.getOperand(0) = PICR; + TmpInst.getOperand(1) = TR; + TmpInst.getOperand(2) = PICR; + EmitToStreamer(*OutStreamer, TmpInst); + return; + } } case PPC::LWZtoc: { // Transform %r3 = LWZtoc @min1, %r2 @@ -741,11 +797,11 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { else if (MO.isGlobal()) { const GlobalValue *GV = MO.getGlobal(); MOSymbol = getSymbol(GV); - DEBUG( - unsigned char GVFlags = Subtarget->classifyGlobalReference(GV); - assert((GVFlags & PPCII::MO_NLP_FLAG) && - "LDtocL used on symbol that could be accessed directly is " - "invalid. Must match ADDIStocHA.")); + LLVM_DEBUG( + unsigned char GVFlags = Subtarget->classifyGlobalReference(GV); + assert((GVFlags & PPCII::MO_NLP_FLAG) && + "LDtocL used on symbol that could be accessed directly is " + "invalid. Must match ADDIStocHA.")); MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); } @@ -770,11 +826,9 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { if (MO.isGlobal()) { const GlobalValue *GV = MO.getGlobal(); - DEBUG( - unsigned char GVFlags = Subtarget->classifyGlobalReference(GV); - assert ( - !(GVFlags & PPCII::MO_NLP_FLAG) && - "Interposable definitions must use indirect access.")); + LLVM_DEBUG(unsigned char GVFlags = Subtarget->classifyGlobalReference(GV); + assert(!(GVFlags & PPCII::MO_NLP_FLAG) && + "Interposable definitions must use indirect access.")); MOSymbol = getSymbol(GV); } else if (MO.isCPI()) { MOSymbol = GetCPISymbol(MO.getIndex()); @@ -1233,7 +1287,7 @@ void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { if (!Subtarget->isPPC64()) { const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); - if (PPCFI->usesPICBase()) { + if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) { MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(); MCSymbol *PICBase = MF->getPICBaseSymbol(); OutStreamer->EmitLabel(RelocSymbol); @@ -1255,7 +1309,7 @@ void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { if (Subtarget->isELFv2ABI()) { // In the Large code model, we allow arbitrary displacements between // the text section and its associated TOC section. We place the - // full 8-byte offset to the TOC in memory immediatedly preceding + // full 8-byte offset to the TOC in memory immediately preceding // the function global entry point. if (TM.getCodeModel() == CodeModel::Large && !MF->getRegInfo().use_empty(PPC::X2)) { @@ -1458,6 +1512,7 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { "ppc750", "ppc970", "ppcA2", + "ppce500", "ppce500mc", "ppce5500", "power3", |