summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Fertile <sfertile@ca.ibm.com>2019-09-24 18:04:51 +0000
committerSean Fertile <sfertile@ca.ibm.com>2019-09-24 18:04:51 +0000
commitb3a9320c08ef45de8039075cc532bdb89b5d88f9 (patch)
tree28af73242d4dcfde7888be3fde2b014b46489dd4
parentd9629b88ff72927cac6494293e5a5501e504b222 (diff)
downloadbcm5719-llvm-b3a9320c08ef45de8039075cc532bdb89b5d88f9.tar.gz
bcm5719-llvm-b3a9320c08ef45de8039075cc532bdb89b5d88f9.zip
Extends the expansion of the LWZtoc pseduo op for AIX.
Differential Revision: https://reviews.llvm.org/D67853 llvm-svn: 372772
-rw-r--r--llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp53
-rw-r--r--llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll21
2 files changed, 59 insertions, 15 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index c835df3cabc..5ab2701be0e 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -649,16 +649,19 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
}
case PPC::LWZtoc: {
- // Transform %r3 = LWZtoc @min1, %r2
+ assert(!isDarwin && "TOC is an ELF/XCOFF construct.");
+
+ // Transform %rN = LWZtoc @op1, %r2
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
- // Change the opcode to LWZ, and the global address operand to be a
- // reference to the GOT entry we will synthesize later.
+ // 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 LWZtoc pseudo.");
- // Map symbol -> label of TOC entry
- assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
+ // Map the operand to its corresponding MCSymbol.
MCSymbol *MOSymbol = nullptr;
if (MO.isGlobal())
MOSymbol = getSymbol(MO.getGlobal());
@@ -669,23 +672,43 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
else if (MO.isBlockAddress())
MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
- if (PL == PICLevel::SmallPIC) {
+ const bool IsAIX = TM.getTargetTriple().isOSAIX();
+
+ // Create a reference to the GOT entry for the symbol. The GOT entry will be
+ // synthesized later.
+ if (PL == PICLevel::SmallPIC && !IsAIX) {
const MCExpr *Exp =
MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT,
OutContext);
TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
- } else {
- MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
+ EmitToStreamer(*OutStreamer, TmpInst);
+ return;
+ }
- const MCExpr *Exp =
- MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None,
- OutContext);
- const MCExpr *PB =
- MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
- OutContext);
- Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
+ // Otherwise use the TOC. 'TOCEntry' is a local symbol used to reference
+ // the storage allocated in the TOC which contains the address of
+ // 'MOSymbol'. Said TOC entry will be synthesized later.
+ MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
+ const MCExpr *Exp =
+ MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None, OutContext);
+
+ // AIX uses the local symbol directly for the operand; that the symbol is
+ // accessed toc-relative is implicit.
+ if (IsAIX) {
+ assert(
+ TM.getCodeModel() == CodeModel::Small &&
+ "This pseudo should only be selected for 32-bit small code model.");
TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
+ EmitToStreamer(*OutStreamer, TmpInst);
+ return;
}
+
+ // Create an explicit subtract expression between the local symbol and
+ // '.LTOC' to manifest the toc-relative offset.
+ const MCExpr *PB = MCSymbolRefExpr::create(
+ OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext);
+ Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
+ TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
EmitToStreamer(*OutStreamer, TmpInst);
return;
}
diff --git a/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll b/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll
new file mode 100644
index 00000000000..b368cb43dbb
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/lower-globaladdr32-aix-asm.ll
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff \
+; RUN: -code-model=small < %s | FileCheck %s
+
+@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
+}
+
+; 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
OpenPOWER on IntegriCloud