diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -233,6 +233,9 @@ MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override; + MCSection *getSectionForJumpTable(const Function &F, + const TargetMachine &TM) const override; + static XCOFF::StorageClass getStorageClassForGlobal(const GlobalObject *GO); }; diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1754,6 +1754,11 @@ if (!Sym->isUndefined()) continue; + if (TM.getTargetTriple().isOSBinFormatXCOFF()) { + cast(Sym)->setContainingCsect( + cast(CPSections[i].S)); + } + if (CurSection != CPSections[i].S) { OutStreamer->SwitchSection(CPSections[i].S); EmitAlignment(Align(CPSections[i].Alignment)); @@ -1843,10 +1848,16 @@ // second label is actually referenced by the code. if (JTInDiffSection && DL.hasLinkerPrivateGlobalPrefix()) // FIXME: This doesn't have to have any specific name, just any randomly - // named and numbered 'l' label would work. Simplify GetJTISymbol. + // named and numbered local label started with 'l' would work. Simplify + // GetJTISymbol. OutStreamer->EmitLabel(GetJTISymbol(JTI, true)); - OutStreamer->EmitLabel(GetJTISymbol(JTI)); + MCSymbol* JTISymbol = GetJTISymbol(JTI); + if (TM.getTargetTriple().isOSBinFormatXCOFF()) { + cast(JTISymbol)->setContainingCsect( + cast(TLOF.getSectionForJumpTable(F, TM))); + } + OutStreamer->EmitLabel(JTISymbol); for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) EmitJumpTableEntry(MJTI, JTBBs[ii], JTI); diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp --- a/llvm/lib/CodeGen/MachineModuleInfo.cpp +++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp @@ -22,6 +22,7 @@ #include "llvm/IR/ValueHandle.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolXCOFF.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" @@ -116,7 +117,17 @@ BBCallbacks.back().setMap(this); Entry.Index = BBCallbacks.size() - 1; Entry.Fn = BB->getParent(); - Entry.Symbols.push_back(Context.createTempSymbol(!BB->hasAddressTaken())); + MCSymbol *Sym = Context.createTempSymbol(!BB->hasAddressTaken()); + if (Context.getObjectFileInfo()->getTargetTriple().isOSBinFormatXCOFF()) { + MCSymbol *FnEntryPointSym = + Context.lookupSymbol("." + Entry.Fn->getName()); + assert(FnEntryPointSym && "The function entry pointer symbol should has" + " already been initialized."); + MCSectionXCOFF *CSect = + cast(FnEntryPointSym)->getContainingCsect(); + cast(Sym)->setContainingCsect(CSect); + } + Entry.Symbols.push_back(Sym); return Entry.Symbols; } diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1868,9 +1868,18 @@ report_fatal_error("XCOFF other section types not yet implemented."); } +MCSection *TargetLoweringObjectFileXCOFF::getSectionForJumpTable( + const Function &F, const TargetMachine &TM) const { + assert (!TM.getFunctionSections() && "Unique sections not supported on XCOFF" + " yet."); + assert (!F.getComdat() && "Comdat not supported on XCOFF yet."); + //TODO: Enable emiting jump table to unique sections when we support it. + return ReadOnlySection; +} + bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection( bool UsesLabelDifference, const Function &F) const { - report_fatal_error("TLOF XCOFF not yet implemented."); + return false; } void TargetLoweringObjectFileXCOFF::Initialize(MCContext &Ctx, diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2749,14 +2749,14 @@ bool PPCTargetLowering::isJumpTableRelative() const { if (UseAbsoluteJumpTables) return false; - if (Subtarget.isPPC64()) + if (Subtarget.isPPC64() || Subtarget.isAIXABI()) return true; return TargetLowering::isJumpTableRelative(); } SDValue PPCTargetLowering::getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const { - if (!Subtarget.isPPC64()) + if (!Subtarget.isPPC64() || Subtarget.isAIXABI()) return TargetLowering::getPICJumpTableRelocBase(Table, DAG); switch (getTargetMachine().getCodeModel()) { @@ -2773,7 +2773,7 @@ PPCTargetLowering::getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const { - if (!Subtarget.isPPC64()) + if (!Subtarget.isPPC64() || Subtarget.isAIXABI()) return TargetLowering::getPICJumpTableRelocBaseExpr(MF, JTI, Ctx); switch (getTargetMachine().getCodeModel()) { diff --git a/llvm/test/CodeGen/PowerPC/aix-lower-block-address.ll b/llvm/test/CodeGen/PowerPC/aix-lower-block-address.ll --- a/llvm/test/CodeGen/PowerPC/aix-lower-block-address.ll +++ b/llvm/test/CodeGen/PowerPC/aix-lower-block-address.ll @@ -14,6 +14,18 @@ ; RUN: -code-model=large -stop-after=machine-cp < %s | FileCheck \ ; RUN: --check-prefix=64LARGE-MIR %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc-ibm-aix-xcoff \ +; RUN: -code-model=small < %s | FileCheck --check-prefixes=32SMALL-ASM,CHECK %s + +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc-ibm-aix-xcoff \ +; RUN: -code-model=large < %s | FileCheck --check-prefixes=32LARGE-ASM,CHECK %s + +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -code-model=small < %s | FileCheck --check-prefixes=64SMALL-ASM,CHECK %s + +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -code-model=large < %s | FileCheck --check-prefixes=64LARGE-ASM,CHECK %s + define void @foo() { entry: %tmp = alloca i64 @@ -33,3 +45,28 @@ ; 64LARGE-MIR: renamable $x[[REG1:[0-9]+]] = ADDIStocHA8 $x2, blockaddress(@foo, %ir-block.__here) ; 64LARGE-MIR: renamable $x[[REG2:[0-9]+]] = LDtocL blockaddress(@foo, %ir-block.__here), killed renamable $x[[REG1]], implicit $x2 :: (load 8 from got) + +; 32SMALL-ASM-LABEL: foo +; 32SMALL-ASM: .foo: +; 32SMALL-ASM: Ltmp0: +; 32SMALL-ASM: lwz [[REG1:[0-9]+]], LC0(2) + +; 32LARGE-ASM-LABEL: foo +; 32LARGE-ASM: .foo: +; 32LARGE-ASM: Ltmp0: +; 32LARGE-ASM: addis [[REG1:[0-9]+]], LC0@u(2) +; 32LARGE-ASM: lwz [[REG2:[0-9]+]], LC0@l([[REG1]]) + +; 64SMALL-ASM-LABEL: foo +; 64SMALL-ASM: .foo: +; 64SMALL-ASM: Ltmp0: +; 64SMALL-ASM: ld [[REG1:[0-9]+]], LC0(2) + +; 64LARGE-ASM-LABEL: foo +; 64LARGE-ASM: .foo: +; 64LARGE-ASM: Ltmp0: +; 64LARGE-ASM: addis [[REG1:[0-9]+]], LC0@u(2) +; 64LARGE-ASM: ld [[REG2:[0-9]+]], LC0@l([[REG1]]) + +; CHECK: .toc +; CHECK-NOT: .tc diff --git a/llvm/test/CodeGen/PowerPC/aix-lower-constant-pool-index.ll b/llvm/test/CodeGen/PowerPC/aix-lower-constant-pool-index.ll --- a/llvm/test/CodeGen/PowerPC/aix-lower-constant-pool-index.ll +++ b/llvm/test/CodeGen/PowerPC/aix-lower-constant-pool-index.ll @@ -14,6 +14,18 @@ ; RUN: -code-model=large -stop-after=machine-cp < %s | FileCheck \ ; RUN: --check-prefix=64LARGE-MIR %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc-ibm-aix-xcoff \ +; RUN: -code-model=small < %s | FileCheck --check-prefixes=32SMALL-ASM,CHECK %s + +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc-ibm-aix-xcoff \ +; RUN: -code-model=large < %s | FileCheck --check-prefixes=32LARGE-ASM,CHECK %s + +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -code-model=small < %s | FileCheck --check-prefixes=64SMALL-ASM,CHECK %s + +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -code-model=large < %s | FileCheck --check-prefixes=64LARGE-ASM,CHECK %s + define float @test_float() { entry: ret float 5.500000e+00 @@ -32,3 +44,44 @@ ; 64LARGE-MIR: renamable $x[[REG1:[0-9]+]] = ADDIStocHA8 $x2, %const.0 ; 64LARGE-MIR: renamable $x[[REG2:[0-9]+]] = LDtocL %const.0, killed renamable $x[[REG1]], implicit $x2 :: (load 8 from got) ; 64LARGE-MIR: renamable $f[[REG3:[0-9]+]] = LFS 0, killed renamable $x[[REG2]] :: (load 4 from constant-pool) + +; 32SMALL-ASM: .csect .rodata[RO] +; 32SMALL-ASM: .align 2 +; 32SMALL-ASM: .LCPI0_0: +; 32SMALL-ASM: .long 1085276160 +; 32SMALL-ASM: .test_float: +; 32SMALL-ASM: lwz [[REG1:[0-9]+]], LC0(2) +; 32SMALL-ASM: lfs 1, 0([[REG1]]) +; 32SMALL-ASM: blr + +; 32LARGE-ASM: .csect .rodata[RO] +; 32LARGE-ASM: .align 2 +; 32LARGE-ASM: .LCPI0_0: +; 32LARGE-ASM: .long 1085276160 +; 32LARGE-ASM: .test_float: +; 32LARGE-ASM: addis [[REG1:[0-9]+]], LC0@u(2) +; 32LARGE-ASM: lwz [[REG2:[0-9]+]], LC0@l([[REG1]]) +; 32LARGE-ASM: lfs 1, 0([[REG2]]) +; 32LARGE-ASM: blr + +; 64SMALL-ASM: .csect .rodata[RO] +; 64SMALL-ASM: .align 2 +; 64SMALL-ASM: .LCPI0_0: +; 64SMALL-ASM: .long 1085276160 +; 64SMALL-ASM: .test_float: +; 64SMALL-ASM: ld [[REG1:[0-9]+]], LC0(2) +; 64SMALL-ASM: lfs 1, 0([[REG1]]) +; 64SMALL-ASM: blr + +; 64LARGE-ASM: .csect .rodata[RO] +; 64LARGE-ASM: .align 2 +; 64LARGE-ASM: .LCPI0_0: +; 64LARGE-ASM: .long 1085276160 +; 64LARGE-ASM: .test_float: +; 64LARGE-ASM: addis [[REG1:[0-9]+]], LC0@u(2) +; 64LARGE-ASM: ld [[REG2:[0-9]+]], LC0@l([[REG1]]) +; 64LARGE-ASM: lfs 1, 0([[REG2]]) +; 64LARGE-ASM: blr + +; CHECK: .toc +; CHECK-NOT: .tc diff --git a/llvm/test/CodeGen/PowerPC/aix-lower-jump-table.ll b/llvm/test/CodeGen/PowerPC/aix-lower-jump-table.ll --- a/llvm/test/CodeGen/PowerPC/aix-lower-jump-table.ll +++ b/llvm/test/CodeGen/PowerPC/aix-lower-jump-table.ll @@ -14,6 +14,18 @@ ; RUN: -code-model=large -stop-after=machine-cp < %s | FileCheck \ ; RUN: --check-prefix=64LARGE-MIR %s +; RUN: llc -mtriple powerpc-ibm-aix-xcoff -code-model=small < %s | FileCheck \ +; RUN: --check-prefixes=32SMALL-ASM,CHECK %s + +; RUN: llc -mtriple powerpc-ibm-aix-xcoff -code-model=large < %s | FileCheck \ +; RUN: --check-prefixes=32LARGE-ASM,CHECK %s + +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -code-model=small < %s | FileCheck \ +; RUN: --check-prefixes=64SMALL-ASM,CHECK %s + +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -code-model=large < %s | FileCheck \ +; RUN: --check-prefixes=64LARGE-ASM,CHECK %s + define i32 @jump_table(i32 %a) { entry: switch i32 %a, label %sw.epilog [ @@ -46,18 +58,131 @@ ; 32SMALL-MIR: renamable $r[[REG1:[0-9]+]] = LWZtoc %jump-table.0, $r2 :: (load 4 from got) ; 32SMALL-MIR: renamable $r[[REG3:[0-9]+]] = RLWINM killed renamable $r[[REG2:[0-9]+]], 2, 0, 29 -; 32SMALL-MIR: renamable $r[[REG4:[0-9]+]] = LWZX killed renamable $r[[REG3]], killed renamable $r[[REG1]] :: (load 4 from jump-table) +; 32SMALL-MIR: renamable $r[[REG4:[0-9]+]] = LWZX killed renamable $r[[REG3]], renamable $r[[REG1]] :: (load 4 from jump-table) +; 32SMALL-MIR: renamable $r[[REG5:[0-9]+]] = ADD4 killed renamable $r[[REG4]], killed renamable $r[[REG1]] ; 32LARGE-MIR: renamable $r[[REG1:[0-9]+]] = ADDIStocHA $r2, %jump-table.0 ; 32LARGE-MIR: renamable $r[[REG2:[0-9]+]] = LWZtocL %jump-table.0, killed renamable $r[[REG1]], implicit $r2 :: (load 4 from got) ; 32LARGE-MIR: renamable $r[[REG4:[0-9]+]] = RLWINM killed renamable $r[[REG3:[0-9]+]], 2, 0, 29 -; 32LARGE-MIR: renamable $r[[REG5:[0-9]+]] = LWZX killed renamable $r[[REG4]], killed renamable $r[[REG2]] :: (load 4 from jump-table) +; 32LARGE-MIR: renamable $r[[REG5:[0-9]+]] = LWZX killed renamable $r[[REG4]], renamable $r[[REG2]] :: (load 4 from jump-table) +; 32LARGE-MIR: renamable $r[[REG6:[0-9]+]] = ADD4 killed renamable $r[[REG5]], killed renamable $r[[REG2]] ; 64SMALL-MIR: renamable $x[[REG1:[0-9]+]] = LDtocJTI %jump-table.0, $x2 :: (load 8 from got) ; 64SMALL-MIR: renamable $x[[REG3:[0-9]+]] = RLDIC killed renamable $x[[REG2:[0-9]+]], 2, 30 ; 64SMALL-MIR: renamable $x[[REG4:[0-9]+]] = LWAX killed renamable $x[[REG3]], renamable $x[[REG1]] :: (load 4 from jump-table) +; 64SMALL-MIR: renamable $x[[REG6:[0-9]+]] = ADD8 killed renamable $x[[REG4]], killed renamable $x[[REG1]] ; 64LARGE-MIR: renamable $x[[REG1:[0-9]+]] = ADDIStocHA8 $x2, %jump-table.0 ; 64LARGE-MIR: renamable $x[[REG2:[0-9]+]] = LDtocL %jump-table.0, killed renamable $x[[REG1]], implicit $x2 :: (load 8 from got) ; 64LARGE-MIR: renamable $x[[REG4:[0-9]+]] = RLDIC killed renamable $x[[REG3:[0-9]+]], 2, 30 -; 64LARGE-MIR: renamable $x[[REG5:[0-9]+]] = LWAX killed renamable $x[[REG4]], killed renamable $x[[REG2]] :: (load 4 from jump-table) +; 64LARGE-MIR: renamable $x[[REG5:[0-9]+]] = LWAX killed renamable $x[[REG4]], renamable $x[[REG2]] :: (load 4 from jump-table) +; 64LARGE-MIR: renamable $x[[REG6:[0-9]+]] = ADD8 killed renamable $x[[REG5]], killed renamable $x[[REG2]] + +; 32SMALL-ASM-LABEL: jump_table +; 32SMALL-ASM: .jump_table: +; 32SMALL-ASM: addi 3, 3, -1 +; 32SMALL-ASM: cmplwi 3, 3 +; 32SMALL-ASM: bgt 0, LBB0_6 +; 32SMALL-ASM: lwz 4, LC0(2) +; 32SMALL-ASM: slwi 3, 3, 2 +; 32SMALL-ASM: lwzx 3, 3, 4 +; 32SMALL-ASM: add 3, 3, 4 +; 32SMALL-ASM: mtctr 3 +; 32SMALL-ASM: bctr +; 32SMALL-ASM: LBB0_2: +; 32SMALL-ASM: LBB0_3: +; 32SMALL-ASM: LBB0_4: +; 32SMALL-ASM: LBB0_5: +; 32SMALL-ASM: LBB0_6: +; 32SMALL-ASM: li 3, 0 +; 32SMALL-ASM: blr +; 32SMALL-ASM: .csect .rodata[RO] +; 32SMALL-ASM: .align 2 +; 32SMALL-ASM: .LJTI0_0: +; 32SMALL-ASM: .long LBB0_2-.LJTI0_0 +; 32SMALL-ASM: .long LBB0_3-.LJTI0_0 +; 32SMALL-ASM: .long LBB0_4-.LJTI0_0 +; 32SMALL-ASM: .long LBB0_5-.LJTI0_0 + +; 32LARGE-ASM-LABEL: jump_table +; 32LARGE-ASM: .jump_table: +; 32LARGE-ASM: addi 3, 3, -1 +; 32LARGE-ASM: cmplwi 3, 3 +; 32LARGE-ASM: bgt 0, LBB0_6 +; 32LARGE-ASM: addis 4, LC0@u(2) +; 32LARGE-ASM: slwi 3, 3, 2 +; 32LARGE-ASM: lwz 4, LC0@l(4) +; 32LARGE-ASM: lwzx 3, 3, 4 +; 32LARGE-ASM: add 3, 3, 4 +; 32LARGE-ASM: mtctr 3 +; 32LARGE-ASM: bctr +; 32LARGE-ASM: LBB0_2: +; 32LARGE-ASM: LBB0_3: +; 32LARGE-ASM: LBB0_4: +; 32LARGE-ASM: LBB0_5: +; 32LARGE-ASM: LBB0_6: +; 32LARGE-ASM: li 3, 0 +; 32LARGE-ASM: blr +; 32LARGE-ASM: .csect .rodata[RO] +; 32LARGE-ASM: .align 2 +; 32LARGE-ASM: .LJTI0_0: +; 32LARGE-ASM: .long LBB0_2-.LJTI0_0 +; 32LARGE-ASM: .long LBB0_3-.LJTI0_0 +; 32LARGE-ASM: .long LBB0_4-.LJTI0_0 +; 32LARGE-ASM: .long LBB0_5-.LJTI0_0 + +; 64SMALL-ASM-LABEL: jump_table +; 64SMALL-ASM: .jump_table: +; 64SMALL-ASM: addi 3, 3, -1 +; 64SMALL-ASM: cmplwi 3, 3 +; 64SMALL-ASM: bgt 0, LBB0_6 +; 64SMALL-ASM: ld 4, LC0(2) +; 64SMALL-ASM: rldic 3, 3, 2, 30 +; 64SMALL-ASM: lwax 3, 3, 4 +; 64SMALL-ASM: add 3, 3, 4 +; 64SMALL-ASM: mtctr 3 +; 64SMALL-ASM: bctr +; 64SMALL-ASM: LBB0_2: +; 64SMALL-ASM: LBB0_3: +; 64SMALL-ASM: LBB0_4: +; 64SMALL-ASM: LBB0_5: +; 64SMALL-ASM: LBB0_6: +; 64SMALL-ASM: li 3, 0 +; 64SMALL-ASM: blr +; 64SMALL-ASM: .csect .rodata[RO] +; 64SMALL-ASM: .align 2 +; 64SMALL-ASM: .LJTI0_0: +; 64SMALL-ASM: .long LBB0_2-.LJTI0_0 +; 64SMALL-ASM: .long LBB0_3-.LJTI0_0 +; 64SMALL-ASM: .long LBB0_4-.LJTI0_0 +; 64SMALL-ASM: .long LBB0_5-.LJTI0_0 + +; 64LARGE-ASM-LABEL: jump_table +; 64LARGE-ASM: .jump_table: +; 64LARGE-ASM: addi 3, 3, -1 +; 64LARGE-ASM: cmplwi 3, 3 +; 64LARGE-ASM: bgt 0, LBB0_6 +; 64LARGE-ASM: addis 4, LC0@u(2) +; 64LARGE-ASM: rldic 3, 3, 2, 30 +; 64LARGE-ASM: ld 4, LC0@l(4) +; 64LARGE-ASM: lwax 3, 3, 4 +; 64LARGE-ASM: add 3, 3, 4 +; 64LARGE-ASM: mtctr 3 +; 64LARGE-ASM: bctr +; 64LARGE-ASM: LBB0_2: +; 64LARGE-ASM: LBB0_3: +; 64LARGE-ASM: LBB0_4: +; 64LARGE-ASM: LBB0_5: +; 64LARGE-ASM: LBB0_6: +; 64LARGE-ASM: li 3, 0 +; 64LARGE-ASM: blr +; 64LARGE-ASM: .csect .rodata[RO] +; 64LARGE-ASM: .align 2 +; 64LARGE-ASM: .LJTI0_0: +; 64LARGE-ASM: .long LBB0_2-.LJTI0_0 +; 64LARGE-ASM: .long LBB0_3-.LJTI0_0 +; 64LARGE-ASM: .long LBB0_4-.LJTI0_0 +; 64LARGE-ASM: .long LBB0_5-.LJTI0_0 + +; CHECK: .toc +; CHECK-NOT: .tc