Skip to content

Commit 4130544

Browse files
committed
[XCOFF][AIX] Support relocation generation for large code model
Summary: Support TOCU and TOCL relocation type for object file generation. Reviewed by: DiggerLin Differential Revision: https://reviews.llvm.org/D84549
1 parent 1f47f89 commit 4130544

File tree

3 files changed

+107
-4
lines changed

3 files changed

+107
-4
lines changed

llvm/lib/MC/XCOFFObjectWriter.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace {
4949

5050
constexpr unsigned DefaultSectionAlign = 4;
5151
constexpr int16_t MaxSectionIndex = INT16_MAX;
52+
constexpr uint16_t MaxTOCSizeInARegion = UINT16_MAX;
5253

5354
// Packs the csect's alignment and type into a byte.
5455
uint8_t getEncodedType(const MCSectionXCOFF *);
@@ -309,6 +310,7 @@ CsectGroup &XCOFFObjectWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {
309310
"in this CsectGroup.");
310311
return TOCCsects;
311312
case XCOFF::XMC_TC:
313+
case XCOFF::XMC_TE:
312314
assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
313315
"Only an initialized csect can contain TC entry.");
314316
assert(!TOCCsects.empty() &&
@@ -432,9 +434,15 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
432434
// The FixedValue should be symbol's virtual address in this object file
433435
// plus any constant value that we might get.
434436
FixedValue = getVirtualAddress(SymA, SymASec) + Target.getConstant();
435-
else if (Type == XCOFF::RelocationType::R_TOC)
437+
else if (Type == XCOFF::RelocationType::R_TOC ||
438+
Type == XCOFF::RelocationType::R_TOCL) {
436439
// The FixedValue should be the TC entry offset from TOC-base.
437440
FixedValue = SectionMap[SymASec]->Address - TOCCsects.front().Address;
441+
if (FixedValue >= MaxTOCSizeInARegion)
442+
report_fatal_error(
443+
"handling of TOC entries could not fit in the initial TOC "
444+
"entry region is not yet supported");
445+
}
438446

439447
assert(
440448
(TargetObjectWriter->is64Bit() ||

llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,19 @@ std::pair<uint8_t, uint8_t> PPCXCOFFObjectWriter::getRelocTypeAndSignSize(
5858
switch ((unsigned)Fixup.getKind()) {
5959
default:
6060
report_fatal_error("Unimplemented fixup kind.");
61-
case PPC::fixup_ppc_half16:
61+
case PPC::fixup_ppc_half16: {
62+
const uint8_t SignAndSizeForHalf16 = EncodedSignednessIndicator | 15;
6263
switch (Modifier) {
6364
default:
6465
report_fatal_error("Unsupported modifier for half16 fixup.");
6566
case MCSymbolRefExpr::VK_None:
66-
return {XCOFF::RelocationType::R_TOC, EncodedSignednessIndicator | 15};
67+
return {XCOFF::RelocationType::R_TOC, SignAndSizeForHalf16};
68+
case MCSymbolRefExpr::VK_PPC_U:
69+
return {XCOFF::RelocationType::R_TOCU, SignAndSizeForHalf16};
70+
case MCSymbolRefExpr::VK_PPC_L:
71+
return {XCOFF::RelocationType::R_TOCL, SignAndSizeForHalf16};
6772
}
68-
break;
73+
} break;
6974
case PPC::fixup_ppc_br24:
7075
// Branches are 4 byte aligned, so the 24 bits we encode in
7176
// the instruction actually represents a 26 bit offset.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
; RUN: llc -verify-machineinstrs -mcpu=pwr4 -mtriple powerpc-ibm-aix-xcoff \
2+
; RUN: -filetype=obj -code-model=large -o %t.o < %s
3+
; RUN: llvm-readobj --relocs --expand-relocs %t.o | FileCheck --check-prefixes=RELOC %s
4+
; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck --check-prefix=DIS %s
5+
6+
@a = global i32 2, align 4
7+
@b = global i32 10, align 4
8+
@c = global i32 11, align 4
9+
10+
define i32 @foo() {
11+
entry:
12+
%0 = load i32, i32* @a, align 4
13+
%1 = load i32, i32* @b, align 4
14+
%add = add nsw i32 %0, %1
15+
%2 = load i32, i32* @c, align 4
16+
%add1 = add nsw i32 %add, %2
17+
ret i32 %add1
18+
}
19+
20+
; RELOC: Section (index: {{[0-9]+}}) .text {
21+
; RELOC-NEXT: Relocation {
22+
; RELOC-NEXT: Virtual Address: 0x2
23+
; RELOC-NEXT: Symbol: a ([[#INDX:]])
24+
; RELOC-NEXT: IsSigned: No
25+
; RELOC-NEXT: FixupBitValue: 0
26+
; RELOC-NEXT: Length: 16
27+
; RELOC-NEXT: Type: R_TOCU (0x30)
28+
; RELOC-NEXT: }
29+
; RELOC-NEXT: Relocation {
30+
; RELOC-NEXT: Virtual Address: 0x6
31+
; RELOC-NEXT: Symbol: a ([[#INDX]])
32+
; RELOC-NEXT: IsSigned: No
33+
; RELOC-NEXT: FixupBitValue: 0
34+
; RELOC-NEXT: Length: 16
35+
; RELOC-NEXT: Type: R_TOCL (0x31)
36+
; RELOC-NEXT: }
37+
; RELOC-NEXT: Relocation {
38+
; RELOC-NEXT: Virtual Address: 0xE
39+
; RELOC-NEXT: Symbol: b ([[#INDX+2]])
40+
; RELOC-NEXT: IsSigned: No
41+
; RELOC-NEXT: FixupBitValue: 0
42+
; RELOC-NEXT: Length: 16
43+
; RELOC-NEXT: Type: R_TOCU (0x30)
44+
; RELOC-NEXT: }
45+
; RELOC-NEXT: Relocation {
46+
; RELOC-NEXT: Virtual Address: 0x12
47+
; RELOC-NEXT: Symbol: b ([[#INDX+2]])
48+
; RELOC-NEXT: IsSigned: No
49+
; RELOC-NEXT: FixupBitValue: 0
50+
; RELOC-NEXT: Length: 16
51+
; RELOC-NEXT: Type: R_TOCL (0x31)
52+
; RELOC-NEXT: }
53+
; RELOC-NEXT: Relocation {
54+
; RELOC-NEXT: Virtual Address: 0x1A
55+
; RELOC-NEXT: Symbol: c ([[#INDX+4]])
56+
; RELOC-NEXT: IsSigned: No
57+
; RELOC-NEXT: FixupBitValue: 0
58+
; RELOC-NEXT: Length: 16
59+
; RELOC-NEXT: Type: R_TOCU (0x30)
60+
; RELOC-NEXT: }
61+
; RELOC-NEXT: Relocation {
62+
; RELOC-NEXT: Virtual Address: 0x1E
63+
; RELOC-NEXT: Symbol: c ([[#INDX+4]])
64+
; RELOC-NEXT: IsSigned: No
65+
; RELOC-NEXT: FixupBitValue: 0
66+
; RELOC-NEXT: Length: 16
67+
; RELOC-NEXT: Type: R_TOCL (0x31)
68+
; RELOC-NEXT: }
69+
70+
; DIS: Disassembly of section .text:
71+
; DIS-EMPTY:
72+
; DIS-NEXT: 00000000 (idx: {{[0-9]+}}) .foo:
73+
; DIS-NEXT: 0: 3c 62 00 00 addis 3, 2, 0
74+
; DIS-NEXT: 00000002: R_TOCU (idx: [[#INDX:]]) a[TE]
75+
; DIS-NEXT: 4: 80 63 00 00 lwz 3, 0(3)
76+
; DIS-NEXT: 00000006: R_TOCL (idx: [[#INDX]]) a[TE]
77+
; DIS-NEXT: 8: 80 63 00 00 lwz 3, 0(3)
78+
; DIS-NEXT: c: 3c 82 00 00 addis 4, 2, 0
79+
; DIS-NEXT: 0000000e: R_TOCU (idx: [[#INDX+2]]) b[TE]
80+
; DIS-NEXT: 10: 80 84 00 04 lwz 4, 4(4)
81+
; DIS-NEXT: 00000012: R_TOCL (idx: [[#INDX+2]]) b[TE]
82+
; DIS-NEXT: 14: 80 84 00 00 lwz 4, 0(4)
83+
; DIS-NEXT: 18: 3c a2 00 00 addis 5, 2, 0
84+
; DIS-NEXT: 0000001a: R_TOCU (idx: [[#INDX+4]]) c[TE]
85+
; DIS-NEXT: 1c: 80 a5 00 08 lwz 5, 8(5)
86+
; DIS-NEXT: 0000001e: R_TOCL (idx: [[#INDX+4]]) c[TE]
87+
; DIS-NEXT: 20: 7c 63 22 14 add 3, 3, 4
88+
; DIS-NEXT: 24: 80 a5 00 00 lwz 5, 0(5)
89+
; DIS-NEXT: 28: 7c 63 2a 14 add 3, 3, 5
90+
; DIS-NEXT: 2c: 4e 80 00 20 blr

0 commit comments

Comments
 (0)