diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h --- a/llvm/include/llvm/MC/MCExpr.h +++ b/llvm/include/llvm/MC/MCExpr.h @@ -235,6 +235,8 @@ VK_PPC_TOC_LO, // symbol@toc@l VK_PPC_TOC_HI, // symbol@toc@h VK_PPC_TOC_HA, // symbol@toc@ha + VK_PPC_U, // symbol@u + VK_PPC_L, // symbol@l VK_PPC_DTPMOD, // symbol@dtpmod VK_PPC_TPREL_LO, // symbol@tprel@l VK_PPC_TPREL_HI, // symbol@tprel@h diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -259,6 +259,8 @@ case VK_PPC_TOC_LO: return "toc@l"; case VK_PPC_TOC_HI: return "toc@h"; case VK_PPC_TOC_HA: return "toc@ha"; + case VK_PPC_U: return "u"; + case VK_PPC_L: return "l"; case VK_PPC_DTPMOD: return "dtpmod"; case VK_PPC_TPREL_LO: return "tprel@l"; case VK_PPC_TPREL_HI: return "tprel@h"; @@ -373,6 +375,8 @@ .Case("toc@l", VK_PPC_TOC_LO) .Case("toc@h", VK_PPC_TOC_HI) .Case("toc@ha", VK_PPC_TOC_HA) + .Case("u", VK_PPC_U) + .Case("l", VK_PPC_L) .Case("tls", VK_PPC_TLS) .Case("dtpmod", VK_PPC_DTPMOD) .Case("tprel@l", VK_PPC_TPREL_LO) diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp @@ -66,6 +66,32 @@ void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) { + // Customize printing of the addis instruction on AIX. When an operand is a + // symbol reference, the instruction syntax is changed to look like a load + // operation, i.e: + // Transform: addis $rD, $rA, $src --> addis $rD, $src($rA). + if (TT.isOSAIX() && + (MI->getOpcode() == PPC::ADDIS8 || MI->getOpcode() == PPC::ADDIS) && + MI->getOperand(2).isExpr()) { + assert((MI->getOperand(0).isReg() && MI->getOperand(1).isReg()) && + "The first and the second operand of addis instruction" + " should be registers."); + + const MCSymbolRefExpr *SRE = + dyn_cast(MI->getOperand(2).getExpr()); + assert(SRE && "The third operand of addis instruction should be a symbol" + " reference expression."); + + O << "\taddis "; + printOperand(MI, 0, O); + O << ", "; + printOperand(MI, 2, O); + O << "("; + printOperand(MI, 1, O); + O << ")"; + return; + } + // Check for slwi/srwi mnemonics. if (MI->getOpcode() == PPC::RLWINM) { unsigned char SH = MI->getOperand(2).getImm(); diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -512,12 +512,28 @@ .addExpr(SymVar)); } +// Map the machine operand to its corresponding MCSymbol. +static MCSymbol *getMCSymbolForMO(const MachineOperand &MO, AsmPrinter &AP) { + if (MO.isGlobal()) + return AP.getSymbol(MO.getGlobal()); + if (MO.isCPI()) + return AP.GetCPISymbol(MO.getIndex()); + if (MO.isJTI()) + return AP.GetJTISymbol(MO.getIndex()); + if (MO.isBlockAddress()) + return AP.GetBlockAddressSymbol(MO.getBlockAddress()); + + llvm_unreachable("Unsupported machine operand type."); +} + /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to /// the current output stream. /// void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCInst TmpInst; bool isDarwin = TM.getTargetTriple().isOSDarwin(); + const bool IsPPC64 = Subtarget->isPPC64(); + const bool IsAIX = Subtarget->isAIXABI(); const Module *M = MF->getFunction().getParent(); PICLevel::Level PL = M->getPICLevel(); @@ -668,17 +684,7 @@ "Unexpected operand type for LWZtoc pseudo."); // Map the operand to its corresponding MCSymbol. - MCSymbol *MOSymbol = nullptr; - if (MO.isGlobal()) - MOSymbol = getSymbol(MO.getGlobal()); - else if (MO.isCPI()) - MOSymbol = GetCPISymbol(MO.getIndex()); - else if (MO.isJTI()) - MOSymbol = GetJTISymbol(MO.getIndex()); - else if (MO.isBlockAddress()) - MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); - - const bool IsAIX = TM.getTargetTriple().isOSAIX(); + MCSymbol *MOSymbol = getMCSymbolForMO(MO, *this); // Create a reference to the GOT entry for the symbol. The GOT entry will be // synthesized later. @@ -723,71 +729,124 @@ case PPC::LDtocCPT: case PPC::LDtocBA: case PPC::LDtoc: { + assert (!isDarwin && "TOC is an ELF/XCOFF construct"); + // Transform %x3 = LDtoc @min1, %x2 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); - // Change the opcode to LD, and the global address operand to be a - // reference to the TOC entry we will synthesize later. + // Change the opcode to LD. TmpInst.setOpcode(PPC::LD); + const MachineOperand &MO = MI->getOperand(1); + assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && + "Unexpected operand type."); - // Map symbol -> label of TOC entry - assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()); - MCSymbol *MOSymbol = nullptr; - if (MO.isGlobal()) - MOSymbol = getSymbol(MO.getGlobal()); - else if (MO.isCPI()) - MOSymbol = GetCPISymbol(MO.getIndex()); - else if (MO.isJTI()) - MOSymbol = GetJTISymbol(MO.getIndex()); - else if (MO.isBlockAddress()) - MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); + // Map the machine operand to its corresponding MCSymbol. + MCSymbol *MOSymbol = getMCSymbolForMO(MO, *this); + // Map the global address operand to be a reference to the TOC entry we + // will synthesize later. MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); + const MCSymbolRefExpr::VariantKind VK = + !IsAIX ? MCSymbolRefExpr::VK_PPC_TOC : MCSymbolRefExpr::VK_None; const MCExpr *Exp = - MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC, - OutContext); + MCSymbolRefExpr::create(TOCEntry, VK, OutContext); TmpInst.getOperand(1) = MCOperand::createExpr(Exp); EmitToStreamer(*OutStreamer, TmpInst); return; } + case PPC::ADDIStocHA: { + assert((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) && + "This pseudo should only be selected for 32-bit large code model on" + " AIX."); + + // Transform %rd = ADDIStocHA %rA, @sym(%r2) + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); + + // Change the opcode to ADDIS. + TmpInst.setOpcode(PPC::ADDIS); + + const MachineOperand &MO = MI->getOperand(2); + assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && + "Unexpected operand type for ADDIStocHA pseudo."); + + // Map the machine operand to its corresponding MCSymbol. + MCSymbol *MOSymbol = getMCSymbolForMO(MO, *this); + + // Always use TOC on AIX. Map the global address operand to be a reference + // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to + // reference the storage allocated in the TOC which contains the address of + // 'MOSymbol'. + MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); + const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, + MCSymbolRefExpr::VK_PPC_U, + OutContext); + TmpInst.getOperand(2) = MCOperand::createExpr(Exp); + EmitToStreamer(*OutStreamer, TmpInst); + return; + } + case PPC::LWZtocL: { + assert(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large && + "This pseudo should only be selected for 32-bit large code model on" + " AIX."); + + // Transform %rd = LWZtocL @sym, %rs. + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); + + // Change the opcode to lwz. + TmpInst.setOpcode(PPC::LWZ); + + const MachineOperand &MO = MI->getOperand(1); + assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && + "Unexpected operand type for LWZtocL pseudo."); + // Map the machine operand to its corresponding MCSymbol. + MCSymbol *MOSymbol = getMCSymbolForMO(MO, *this); + + // Always use TOC on AIX. Map the global address operand to be a reference + // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to + // reference the storage allocated in the TOC which contains the address of + // 'MOSymbol'. + MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); + const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, + MCSymbolRefExpr::VK_PPC_L, + OutContext); + TmpInst.getOperand(1) = MCOperand::createExpr(Exp); + EmitToStreamer(*OutStreamer, TmpInst); + return; + } case PPC::ADDIStocHA8: { + assert (!isDarwin && "TOC is an ELF/XCOFF construct"); + // Transform %xd = ADDIStocHA8 %x2, @sym LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); - // Change the opcode to ADDIS8. If the global address is external, has - // common linkage, is a non-local function address, or is a jump table - // address, then generate a TOC entry and reference that. Otherwise - // reference the symbol directly. + // Change the opcode to ADDIS8. If the global address is the address of + // an external symbol, is a jump table address, is a block address; or if + // large code model is enabled then generate a TOC entry and reference that. + // Otherwise reference the symbol directly. TmpInst.setOpcode(PPC::ADDIS8); + const MachineOperand &MO = MI->getOperand(2); - assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || - MO.isBlockAddress()) && - "Invalid operand for ADDIStocHA8!"); - MCSymbol *MOSymbol = nullptr; - bool GlobalToc = false; + assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && + "Unexpected operand type for ADDIStocHA8 pseudo."); + + MCSymbol *MOSymbol = getMCSymbolForMO(MO, *this); + bool GlobalToc = false; if (MO.isGlobal()) { - const GlobalValue *GV = MO.getGlobal(); - MOSymbol = getSymbol(GV); - GlobalToc = Subtarget->isGVIndirectSymbol(GV); - } else if (MO.isCPI()) { - MOSymbol = GetCPISymbol(MO.getIndex()); - } else if (MO.isJTI()) { - MOSymbol = GetJTISymbol(MO.getIndex()); - } else if (MO.isBlockAddress()) { - MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); + GlobalToc = Subtarget->isGVIndirectSymbol(MO.getGlobal()); } if (GlobalToc || MO.isJTI() || MO.isBlockAddress() || - TM.getCodeModel() == CodeModel::Large) + (MO.isCPI() && TM.getCodeModel() == CodeModel::Large)) MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); + const MCSymbolRefExpr::VariantKind VK = + !IsAIX ? MCSymbolRefExpr::VK_PPC_TOC_HA : MCSymbolRefExpr::VK_PPC_U; const MCExpr *Exp = - MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA, - OutContext); + MCSymbolRefExpr::create(MOSymbol, VK, OutContext); if (!MO.isJTI() && MO.getOffset()) Exp = MCBinaryExpr::createAdd(Exp, @@ -800,43 +859,37 @@ return; } case PPC::LDtocL: { + assert (!isDarwin && "TOC is an ELF/XCOFF construct"); + // Transform %xd = LDtocL @sym, %xs LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); - // Change the opcode to LD. If the global address is external, has - // common linkage, or is a jump table address, then reference the - // associated TOC entry. Otherwise reference the symbol directly. + // Change the opcode to LD. If the global address is the address of + // an external symbol, is a jump table address, is a block address; or if + // large code model is enabled then generate a TOC entry and reference that. + // Otherwise reference the symbol directly. TmpInst.setOpcode(PPC::LD); + const MachineOperand &MO = MI->getOperand(1); - assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || - MO.isBlockAddress()) && - "Invalid operand for LDtocL!"); - MCSymbol *MOSymbol = nullptr; + assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && + "Unexpected operand type for LDtocL pseudo."); - if (MO.isJTI()) - MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex())); - else if (MO.isBlockAddress()) { - MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); - MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); - } - else if (MO.isCPI()) { - MOSymbol = GetCPISymbol(MO.getIndex()); - if (TM.getCodeModel() == CodeModel::Large) - MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); - } - else if (MO.isGlobal()) { - const GlobalValue *GV = MO.getGlobal(); - MOSymbol = getSymbol(GV); + MCSymbol *MOSymbol = getMCSymbolForMO(MO, *this); + + if (MO.isGlobal()) { LLVM_DEBUG( - assert((Subtarget->isGVIndirectSymbol(GV)) && + assert((Subtarget->isGVIndirectSymbol(MO.getGlobal())) && "LDtocL used on symbol that could be accessed directly is " "invalid. Must match ADDIStocHA8.")); - MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); } + if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large) + MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); + + const MCSymbolRefExpr::VariantKind VK = + !IsAIX ? MCSymbolRefExpr::VK_PPC_TOC_LO : MCSymbolRefExpr::VK_PPC_L; const MCExpr *Exp = - MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, - OutContext); + MCSymbolRefExpr::create(MOSymbol, VK, OutContext); TmpInst.getOperand(1) = MCOperand::createExpr(Exp); EmitToStreamer(*OutStreamer, TmpInst); return; @@ -849,17 +902,15 @@ // generate a TOC entry and reference that. Otherwise reference the // symbol directly. TmpInst.setOpcode(PPC::ADDI8); + const MachineOperand &MO = MI->getOperand(2); assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL"); - MCSymbol *MOSymbol = nullptr; + + MCSymbol *MOSymbol = getMCSymbolForMO(MO, *this); if (MO.isGlobal()) { - const GlobalValue *GV = MO.getGlobal(); - LLVM_DEBUG(assert(!(Subtarget->isGVIndirectSymbol(GV)) && + LLVM_DEBUG(assert(!(Subtarget->isGVIndirectSymbol(MO.getGlobal())) && "Interposable definitions must use indirect access.")); - MOSymbol = getSymbol(GV); - } else if (MO.isCPI()) { - MOSymbol = GetCPISymbol(MO.getIndex()); } const MCExpr *Exp = @@ -872,7 +923,7 @@ case PPC::ADDISgotTprelHA: { // Transform: %xd = ADDISgotTprelHA %x2, @sym // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha - assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); + assert(IsPPC64 && "Not supported for 32-bit PowerPC"); const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); @@ -891,14 +942,14 @@ LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); // Change the opcode to LD. - TmpInst.setOpcode(Subtarget->isPPC64() ? PPC::LD : PPC::LWZ); + TmpInst.setOpcode(IsPPC64? PPC::LD : PPC::LWZ); const MachineOperand &MO = MI->getOperand(1); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); const MCExpr *Exp = MCSymbolRefExpr::create( MOSymbol, - Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO - : MCSymbolRefExpr::VK_PPC_GOT_TPREL, + IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO + : MCSymbolRefExpr::VK_PPC_GOT_TPREL, OutContext); TmpInst.getOperand(1) = MCOperand::createExpr(Exp); EmitToStreamer(*OutStreamer, TmpInst); @@ -952,7 +1003,7 @@ case PPC::ADDIStlsgdHA: { // Transform: %xd = ADDIStlsgdHA %x2, @sym // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha - assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); + assert(IsPPC64 && "Not supported for 32-bit PowerPC"); const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); @@ -974,12 +1025,13 @@ const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); - const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create( - MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO - : MCSymbolRefExpr::VK_PPC_GOT_TLSGD, - OutContext); + const MCExpr *SymGotTlsGD = + MCSymbolRefExpr::create(MOSymbol, + IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO + : MCSymbolRefExpr::VK_PPC_GOT_TLSGD, + OutContext); EmitToStreamer(*OutStreamer, - MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) + MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addExpr(SymGotTlsGD)); @@ -997,7 +1049,7 @@ case PPC::ADDIStlsldHA: { // Transform: %xd = ADDIStlsldHA %x2, @sym // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha - assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); + assert(IsPPC64 && "Not supported for 32-bit PowerPC"); const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); @@ -1020,11 +1072,10 @@ const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create( - MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO - : MCSymbolRefExpr::VK_PPC_GOT_TLSLD, - OutContext); + MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO + : MCSymbolRefExpr::VK_PPC_GOT_TLSLD, OutContext); EmitToStreamer(*OutStreamer, - MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) + MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addExpr(SymGotTlsLD)); @@ -1053,7 +1104,7 @@ OutContext); EmitToStreamer( *OutStreamer, - MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDIS8 : PPC::ADDIS) + MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addExpr(SymDtprel)); @@ -1072,7 +1123,7 @@ MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO, OutContext); EmitToStreamer(*OutStreamer, - MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) + MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addExpr(SymDtprel)); diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -329,6 +329,7 @@ case PPC::LIS8: case PPC::QVGPCI: case PPC::ADDIStocHA8: + case PPC::ADDIStocHA: case PPC::ADDItocL: case PPC::LOAD_STACK_GUARD: case PPC::XXLXORz: diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -3168,10 +3168,12 @@ "#LWZtocL", [(set i32:$rD, (PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>; -def ADDIStocHA : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, tocentry32:$disp), - "#ADDIStocHA", - [(set i32:$rD, - (PPCtoc_entry i32:$reg, tglobaladdr:$disp))]>; +let hasSideEffects = 0, isReMaterializable = 1 in { +def ADDIStocHA: PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, tocentry32:$disp), + "#ADDIStocHA", + [(set i32:$rD, + (PPCtoc_entry i32:$reg, tglobaladdr:$disp))]>; +} // Get Global (GOT) Base Register offset, from the word immediately preceding // the function label. diff --git a/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll b/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll --- a/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll +++ b/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll @@ -1,5 +1,8 @@ ; RUN: llc -mtriple powerpc-ibm-aix-xcoff \ -; RUN: -code-model=small < %s | FileCheck %s +; RUN: -code-model=small < %s | FileCheck %s --check-prefix=SMALL + +; RUN: llc -mtriple powerpc-ibm-aix-xcoff \ +; RUN: -code-model=large < %s | FileCheck %s --check-prefix=LARGE @b = common global i32 0 @a = common global i32 0 @@ -9,13 +12,18 @@ store i32 %1, i32* @a ret void } +; SMALL: lwz [[REG1:[0-9]+]], LC0(2) +; SMALL: lwz [[REG2:[0-9]+]], LC1(2) +; SMALL: lwz [[REG3:[0-9]+]], 0([[REG1]]) +; SMALL: stw [[REG3]], 0([[REG2]]) +; SMALL: blr + +; LARGE: addis [[REG1:[0-9]+]], LC0@u(2) +; LARGE: lwz [[REG2:[0-9]+]], LC0@l([[REG1]]) +; LARGE: lwz [[REG3:[0-9]+]], 0([[REG2]]) +; LARGE: addis [[REG4:[0-9]+]], LC1@u(2) +; LARGE: lwz [[REG5:[0-9]+]], LC1@l([[REG4]]) -; CHECK-LABEL: test -; CHECK-DAG: lwz [[REG1:[0-9]+]], LC0(2) -; CHECK-DAG: lwz [[REG2:[0-9]+]], LC1(2) -; CHECK-DAG: lwz [[REG3:[0-9]+]], 0([[REG1]]) -; CHECK: stw [[REG3]], 0([[REG2]]) -; CHECK: blr ; TODO Update test when TOC-entry emission lands. ; CHECK-NOT: .tc diff --git a/llvm/test/CodeGen/PowerPC/lower-globaladdr64-aix-asm.ll b/llvm/test/CodeGen/PowerPC/lower-globaladdr64-aix-asm.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/lower-globaladdr64-aix-asm.ll @@ -0,0 +1,30 @@ +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -code-model=small < %s | FileCheck %s --check-prefix=SMALL + +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -code-model=large < %s | FileCheck %s --check-prefix=LARGE + +@b = common global i32 0 +@a = common global i32 0 + +define void @test() { + %1 = load i32, i32* @b + store i32 %1, i32* @a + ret void +} + +; SMALL: ld [[REG1:[0-9]+]], LC0(2) +; SMALL: ld [[REG2:[0-9]+]], LC1(2) +; SMALL: lwz [[REG3:[0-9]+]], 0([[REG1]]) +; SMALL: stw [[REG3]], 0([[REG2]]) +; SMALL: blr + +; LARGE: addis [[REG1:[0-9]+]], LC0@u(2) +; LARGE: addis [[REG2:[0-9]+]], LC1@u(2) +; LARGE: ld [[REG3:[0-9]+]], LC0@l([[REG1]]) +; LARGE: ld [[REG4:[0-9]+]], LC1@l([[REG2]]) +; LARGE: lwz [[REG4:[0-9]+]], 0([[REG3]]) + + +; TODO Update test when TOC-entry emission lands. +; CHECK-NOT: .tc