Skip to content

Commit c8094b6

Browse files
author
Wael Yehia
committed
support large code model
1 parent a25cbf1 commit c8094b6

File tree

2 files changed

+49
-18
lines changed

2 files changed

+49
-18
lines changed

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3398,7 +3398,8 @@ static bool TOCRestoreNeededForCallToImplementation(const GlobalIFunc &GI) {
33983398
// Query if the given function is local to the load module.
33993399
auto IsLocalFunc = [](const Function *F) -> IsLocal {
34003400
bool Result = F->isStrongDefinitionForLinker() && F->isDSOLocal();
3401-
LLVM_DEBUG(dbgs() << F->getName() << " is " << (Result ? "local\n" : "not local\n"));
3401+
LLVM_DEBUG(dbgs() << F->getName() << " is "
3402+
<< (Result ? "local\n" : "not local\n"));
34023403
return Result ? IsLocal::True : IsLocal::False;
34033404
};
34043405

@@ -3489,12 +3490,13 @@ static bool TOCRestoreNeededForCallToImplementation(const GlobalIFunc &GI) {
34893490
* .vbyte 4, 0
34903491
* .csect .foo[PR],5
34913492
* .ref ifunc_sec.foo[RW]
3492-
* lwz 12, L..foo_desc(2) # load foo's descriptor address
3493-
* lwz 11, 8(12) # load the env pointer if target might be a non-C/C++ function
3494-
* lwz 12, 0(12) # load foo.addr
3493+
* lwz 12, L..foo_desc(2) # load foo's descriptor address
3494+
* lwz 11, 8(12) # load the env pointer (for non-C/C++ functions)
3495+
* lwz 12, 0(12) # load foo.addr
34953496
* mtctr 12
3496-
* bctr # branch to CR without setting LR so that callee returns to the caller of .foo
3497-
* # -- End function
3497+
* bctr # branch to CR without setting LR so that callee
3498+
* # returns to the caller of .foo
3499+
* # -- End function
34983500
*/
34993501
void PPCAIXAsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
35003502
// Set the Subtarget to that of the resolver.
@@ -3571,23 +3573,41 @@ void PPCAIXAsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
35713573
if (TOCRestoreNeededForCallToImplementation(GI)) {
35723574
reportFatalUsageError(
35733575
"unimplemented: TOC register save/restore needed for ifunc \"" +
3574-
Twine(GI.getName()) + "\", because couldn't prove all candidates are "
3575-
"static or hidden/protected visibility definitions");
3576+
Twine(GI.getName()) + "\", because couldn't prove all candidates "
3577+
"are static or hidden/protected visibility definitions");
35763578
return;
35773579
}
35783580

3579-
// lwz 12, L..foo_desc(2)
35803581
auto FnDescTOCEntryType = getTOCEntryTypeForLinkage(GI.getLinkage());
35813582
auto *FnDescTOCEntrySym =
35823583
lookUpOrCreateTOCEntry(CurrentFnDescSym, FnDescTOCEntryType);
3583-
auto *Exp = MCSymbolRefExpr::create(FnDescTOCEntrySym, OutContext);
3584-
// Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);// TODO: need this?
3585-
// need this uncommented
3586-
OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3587-
.addReg(PPC::X12)
3588-
.addExpr(Exp)
3589-
.addReg(PPC::X2),
3590-
*Subtarget);
3584+
3585+
if (TM.getCodeModel() == CodeModel::Large) {
3586+
// addis 12, L..foo_desc@u(2)
3587+
// lwz 12, L..foo_desc@l(12)
3588+
auto *Exp_U = symbolWithSpecifier(FnDescTOCEntrySym, PPC::S_U);
3589+
OutStreamer->emitInstruction(MCInstBuilder(PPC::ADDIS)
3590+
.addReg(PPC::X12)
3591+
.addReg(PPC::X2)
3592+
.addExpr(Exp_U),
3593+
*Subtarget);
3594+
auto *Exp_L = symbolWithSpecifier(FnDescTOCEntrySym, PPC::S_L);
3595+
OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3596+
.addReg(PPC::X12)
3597+
.addExpr(Exp_L)
3598+
.addReg(PPC::X12),
3599+
*Subtarget);
3600+
} else {
3601+
// lwz 12, L..foo_desc(2)
3602+
auto *Exp = MCSymbolRefExpr::create(FnDescTOCEntrySym, OutContext);
3603+
// Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
3604+
// TODO: do we need to uncomment this?
3605+
OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3606+
.addReg(PPC::X12)
3607+
.addExpr(Exp)
3608+
.addReg(PPC::X2),
3609+
*Subtarget);
3610+
}
35913611
// lwz 11, 8(12)
35923612
OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
35933613
.addReg(PPC::X11)

llvm/test/CodeGen/PowerPC/aix-ifunc.ll

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
; RUN: llc -mtriple=powerpc64-ibm-aix-xcoff --function-sections %s -o - | FileCheck %s --check-prefixes=COMMON,FUNCSECT -DALIGN=3 -DPTR_SIZE=8 -DLOAD=ld -DOFF=16
55
; RUN: llc -mtriple=powerpc-ibm-aix-xcoff --function-sections %s -o - | FileCheck %s --check-prefixes=COMMON,FUNCSECT -DALIGN=2 -DPTR_SIZE=4 -DLOAD=lwz -DOFF=8
66

7+
; RUN: llc -mtriple=powerpc64-ibm-aix-xcoff --function-sections --code-model=large %s -o - | FileCheck %s --check-prefixes=LARGE -DALIGN=3 -DPTR_SIZE=8 -DLOAD=ld -DOFF=16
8+
; RUN: llc -mtriple=powerpc-ibm-aix-xcoff --function-sections --code-model=large %s -o - | FileCheck %s --check-prefixes=LARGE -DALIGN=2 -DPTR_SIZE=4 -DLOAD=lwz -DOFF=8
9+
710
;;;; section __ifunc_sec holding the [foo:foo_resolver] pairs
811
; COMMON: .csect __ifunc_sec[RW],2
912
; COMMON-NEXT: .align [[ALIGN]]
@@ -46,10 +49,18 @@
4649
; COMMON-NEXT: mtctr 12
4750
; COMMON-NEXT: bctr
4851

52+
; -mcmodel=large:
53+
; LARGE: .csect .foo[PR],5
54+
; LARGE: addis 12, [[FOO_TOC:.*]]@u(2)
55+
; LARGE-NEXT: [[LOAD]] 12, [[FOO_TOC]]@l(12)
56+
; LARGE-NEXT: [[LOAD]] 11, [[OFF]](12)
57+
; LARGE-NEXT: [[LOAD]] 12, 0(12)
58+
4959
;;;; foo's TOC entry
5060
; COMMON: [[FOO_TOC]]:
5161
; COMMON-NEXT: .tc foo[TC],foo[DS]
52-
62+
; LARGE: [[FOO_TOC]]:
63+
; LARGE-NEXT: .tc foo[TE],foo[DS]
5364

5465
@foo = ifunc i32 (...), ptr @foo.resolver
5566

0 commit comments

Comments
 (0)