llvm.org GIT mirror llvm / aa71428
Initial TOC support for PowerPC64 object creation This patch adds initial PPC64 TOC MC object creation using the small mcmodel (a single 64K TOC) adding the some TOC relocations (R_PPC64_TOC, R_PPC64_TOC16, and R_PPC64_TOC16DS). The addition of 'undefinedExplicitRelSym' hook on 'MCELFObjectTargetWriter' is meant to avoid the creation of an unreferenced ".TOC." symbol (used in the .odp creation) as well to set the R_PPC64_TOC relocation target as the temporary ".TOC." symbol. On PPC64 ABI, the R_PPC64_TOC relocation should not point to any symbol. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166677 91177308-0d34-0410-b5e6-96231b3b80d8 Adhemerval Zanella 8 years ago
11 changed file(s) with 223 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
8484 const MCFragment &F,
8585 const MCFixup &Fixup,
8686 bool IsPCRel) const;
87 virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
88 const MCFixup &Fixup,
89 bool IsPCRel) const;
8790 virtual void adjustFixupOffset(const MCFixup &Fixup,
8891 uint64_t &RelocOffset);
8992
132132 bool IsPCRel) const {
133133 return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
134134 }
135 const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
136 const MCFixup &Fixup,
137 bool IsPCRel) const {
138 return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup, IsPCRel);
139 }
135140
136141 bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
137142 bool hasRelocationAddend() const {
638643 if (ASymbol.isUndefined()) {
639644 if (Renamed)
640645 return Renamed;
641 return &ASymbol;
646 return undefinedExplicitRelSym(Target, Fixup, IsPCRel);
642647 }
643648
644649 if (SD.isExternal()) {
720725 MCSymbolData &SD = Asm.getSymbolData(ASymbol);
721726 MCFragment *F = SD.getFragment();
722727
723 Index = F->getParent()->getOrdinal() + 1;
724
725 // Offset of the symbol in the section
726 Value += Layout.getSymbolOffset(&SD);
728 if (F) {
729 Index = F->getParent()->getOrdinal() + 1;
730 // Offset of the symbol in the section
731 Value += Layout.getSymbolOffset(&SD);
732 } else {
733 Index = 0;
734 }
727735 } else {
728736 if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
729737 WeakrefUsedInReloc.insert(RelocSymbol);
88
99 #include "llvm/ADT/STLExtras.h"
1010 #include "llvm/MC/MCELFObjectWriter.h"
11 #include "llvm/MC/MCExpr.h"
12 #include "llvm/MC/MCValue.h"
1113
1214 using namespace llvm;
1315
3436 return NULL;
3537 }
3638
39 const MCSymbol *MCELFObjectTargetWriter::undefinedExplicitRelSym(const MCValue &Target,
40 const MCFixup &Fixup,
41 bool IsPCRel) const {
42 const MCSymbol &Symbol = Target.getSymA()->getSymbol();
43 return &Symbol.AliasedSymbol();
44 }
3745
3846 void MCELFObjectTargetWriter::adjustFixupOffset(const MCFixup &Fixup,
3947 uint64_t &RelocOffset) {
2828 case FK_Data_1:
2929 case FK_Data_2:
3030 case FK_Data_4:
31 case FK_Data_8:
32 case PPC::fixup_ppc_toc:
3133 return Value;
34 case PPC::fixup_ppc_lo14:
35 case PPC::fixup_ppc_toc16_ds:
36 return (Value & 0xffff) << 2;
3237 case PPC::fixup_ppc_brcond14:
33 return Value & 0x3ffc;
38 return Value & 0xfffc;
3439 case PPC::fixup_ppc_br24:
3540 return Value & 0x3fffffc;
3641 #if 0
4045 case PPC::fixup_ppc_ha16:
4146 return ((Value >> 16) + ((Value & 0x8000) ? 1 : 0)) & 0xffff;
4247 case PPC::fixup_ppc_lo16:
48 case PPC::fixup_ppc_toc16:
4349 return Value & 0xffff;
4450 }
4551 }
7177 { "fixup_ppc_brcond14", 16, 14, MCFixupKindInfo::FKF_IsPCRel },
7278 { "fixup_ppc_lo16", 16, 16, 0 },
7379 { "fixup_ppc_ha16", 16, 16, 0 },
74 { "fixup_ppc_lo14", 16, 14, 0 }
80 { "fixup_ppc_lo14", 16, 14, 0 },
81 { "fixup_ppc_toc", 0, 64, 0 },
82 { "fixup_ppc_toc16", 16, 16, 0 },
83 { "fixup_ppc_toc16_ds", 16, 14, 0 }
7584 };
7685
7786 if (Kind < FirstTargetFixupKind)
1010 #include "MCTargetDesc/PPCMCTargetDesc.h"
1111 #include "llvm/MC/MCELFObjectWriter.h"
1212 #include "llvm/Support/ErrorHandling.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCValue.h"
1315
1416 using namespace llvm;
1517
2022
2123 virtual ~PPCELFObjectWriter();
2224 protected:
25 virtual unsigned getRelocTypeInner(const MCValue &Target,
26 const MCFixup &Fixup,
27 bool IsPCRel) const;
2328 virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
2429 bool IsPCRel, bool IsRelocWithSymbol,
2530 int64_t Addend) const;
31 virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
32 const MCFixup &Fixup,
33 bool IsPCRel) const;
2634 virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset);
2735 };
2836 }
3543 PPCELFObjectWriter::~PPCELFObjectWriter() {
3644 }
3745
38 unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
39 const MCFixup &Fixup,
40 bool IsPCRel,
41 bool IsRelocWithSymbol,
42 int64_t Addend) const {
46 unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
47 const MCFixup &Fixup,
48 bool IsPCRel) const
49 {
50 MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
51 MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
52
4353 // determine the type of the relocation
4454 unsigned Type;
4555 if (IsPCRel) {
6070 Type = ELF::R_PPC_ADDR24;
6171 break;
6272 case PPC::fixup_ppc_brcond14:
63 Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_
73 Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
6474 break;
6575 case PPC::fixup_ppc_ha16:
6676 Type = ELF::R_PPC_ADDR16_HA;
7181 case PPC::fixup_ppc_lo14:
7282 Type = ELF::R_PPC_ADDR14;
7383 break;
84 case PPC::fixup_ppc_toc:
85 Type = ELF::R_PPC64_TOC;
86 break;
87 case PPC::fixup_ppc_toc16:
88 Type = ELF::R_PPC64_TOC16;
89 break;
90 case PPC::fixup_ppc_toc16_ds:
91 Type = ELF::R_PPC64_TOC16_DS;
92 break;
93 case FK_Data_8:
94 switch (Modifier) {
95 default: llvm_unreachable("Unsupported Modifier");
96 case MCSymbolRefExpr::VK_PPC_TOC:
97 Type = ELF::R_PPC64_TOC;
98 break;
99 case MCSymbolRefExpr::VK_None:
100 Type = ELF::R_PPC64_ADDR64;
101 break;
102 }
103 break;
74104 case FK_Data_4:
75105 Type = ELF::R_PPC_ADDR32;
76106 break;
80110 }
81111 }
82112 return Type;
113 }
114
115 unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
116 const MCFixup &Fixup,
117 bool IsPCRel,
118 bool IsRelocWithSymbol,
119 int64_t Addend) const {
120 return getRelocTypeInner(Target, Fixup, IsPCRel);
121 }
122
123 const MCSymbol *PPCELFObjectWriter::undefinedExplicitRelSym(const MCValue &Target,
124 const MCFixup &Fixup,
125 bool IsPCRel) const {
126 assert(Target.getSymA() && "SymA cannot be 0");
127 const MCSymbol &Symbol = Target.getSymA()->getSymbol().AliasedSymbol();
128
129 unsigned RelocType = getRelocTypeInner(Target, Fixup, IsPCRel);
130
131 // The .odp creation emits a relocation against the symbol ".TOC." which
132 // create a R_PPC64_TOC relocation. However the relocation symbol name
133 // in final object creation should be NULL, since the symbol does not
134 // really exist, it is just the reference to TOC base for the current
135 // object file.
136 bool EmitThisSym = RelocType != ELF::R_PPC64_TOC;
137
138 if (EmitThisSym && !Symbol.isTemporary())
139 return &Symbol;
140 return NULL;
83141 }
84142
85143 void PPCELFObjectWriter::
3333 /// fixup_ppc_lo14 - A 14-bit fixup corresponding to lo16(_foo) for instrs
3434 /// like 'std'.
3535 fixup_ppc_lo14,
36
37 /// fixup_ppc_toc - Insert value of TOC base (.TOC.).
38 fixup_ppc_toc,
39
40 /// fixup_ppc_toc16 - A 16-bit signed fixup relative to the TOC base.
41 fixup_ppc_toc16,
42
43 /// fixup_ppc_toc16_ds - A 14-bit signed fixup relative to the TOC base with
44 /// implied 2 zero bits
45 fixup_ppc_toc16_ds,
3646
3747 // Marker
3848 LastTargetFixupKind,
1414 #include "MCTargetDesc/PPCBaseInfo.h"
1515 #include "MCTargetDesc/PPCFixupKinds.h"
1616 #include "llvm/MC/MCCodeEmitter.h"
17 #include "llvm/MC/MCSubtargetInfo.h"
1718 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstrInfo.h"
1820 #include "llvm/ADT/Statistic.h"
1921 #include "llvm/Support/raw_ostream.h"
2022 #include "llvm/Support/ErrorHandling.h"
2729 PPCMCCodeEmitter(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION;
2830 void operator=(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION;
2931
32 const MCSubtargetInfo &STI;
33 Triple TT;
34
3035 public:
3136 PPCMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
32 MCContext &ctx) {
37 MCContext &ctx)
38 : STI(sti), TT(STI.getTargetTriple()) {
3339 }
3440
3541 ~PPCMCCodeEmitter() {}
42
43 bool is64BitMode() const {
44 return (STI.getFeatureBits() & PPC::Feature64Bit) != 0;
45 }
46
47 bool isSVR4ABI() const {
48 return TT.isMacOSX() == 0;
49 }
3650
3751 unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
3852 SmallVectorImpl &Fixups) const;
139153 return (getMachineOpValue(MI, MO, Fixups) & 0xFFFF) | RegBits;
140154
141155 // Add a fixup for the displacement field.
142 Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
143 (MCFixupKind)PPC::fixup_ppc_lo16));
156 if (isSVR4ABI() && is64BitMode())
157 Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
158 (MCFixupKind)PPC::fixup_ppc_toc16));
159 else
160 Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
161 (MCFixupKind)PPC::fixup_ppc_lo16));
144162 return RegBits;
145163 }
146164
157175 return (getMachineOpValue(MI, MO, Fixups) & 0x3FFF) | RegBits;
158176
159177 // Add a fixup for the branch target.
160 Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
161 (MCFixupKind)PPC::fixup_ppc_lo14));
178 if (isSVR4ABI() && is64BitMode())
179 Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
180 (MCFixupKind)PPC::fixup_ppc_toc16_ds));
181 else
182 Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
183 (MCFixupKind)PPC::fixup_ppc_lo14));
162184 return RegBits;
163185 }
164186
419419 OutStreamer.EmitValueToAlignment(8);
420420 MCSymbol *Symbol1 =
421421 OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
422 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.@tocbase"));
422 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
423 // entry point.
423424 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
424425 8/*size*/, 0/*addrspace*/);
425 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, OutContext),
426 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
427 // Generates a R_PPC64_TOC relocation for TOC base insertion.
428 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
429 MCSymbolRefExpr::VK_PPC_TOC, OutContext),
426430 8/*size*/, 0/*addrspace*/);
427431 // Emit a null environment pointer.
428432 OutStreamer.EmitIntValue(0, 8 /* size */, 0 /* addrspace */);
5353 CPUName = sys::getHostCPUName();
5454 #endif
5555
56 // Parse features string.
57 ParseSubtargetFeatures(CPUName, FS);
58
5956 // Initialize scheduling itinerary for the specified CPU.
6057 InstrItins = getInstrItineraryForCPU(CPUName);
58
59 // Make sure 64-bit features are available when CPUname is generic
60 std::string FullFS = FS;
6161
6262 // If we are generating code for ppc64, verify that options make sense.
6363 if (is64Bit) {
6464 Has64BitSupport = true;
6565 // Silently force 64-bit register use on ppc64.
6666 Use64BitRegs = true;
67 if (!FullFS.empty())
68 FullFS = "+64bit," + FullFS;
69 else
70 FullFS = "+64bit";
6771 }
72
73 // Parse features string.
74 ParseSubtargetFeatures(CPUName, FullFS);
6875
6976 // If the user requested use of 64-bit regs, but the cpu selected doesn't
7077 // support it, ignore.
0 config.suffixes = ['.ll', '.c', '.cpp', '.s']
1
2 targets = set(config.root.targets_to_build.split())
3 if not 'PowerPC' in targets:
4 config.unsupported = True
0 ;; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -O3 \
1 ;; RUN: -filetype=obj %s -o - | \
2 ;; RUN: elf-dump --dump-section-data | FileCheck %s
3
4 ;; FIXME: this file need to be in .s form, change when asm parse is done.
5
6 @number64 = global i64 10, align 8
7
8 define i64 @access_int64(i64 %a) nounwind readonly {
9 entry:
10 %0 = load i64* @number64, align 8
11 %cmp = icmp eq i64 %0, %a
12 %conv1 = zext i1 %cmp to i64
13 ret i64 %conv1
14 }
15
16 declare double @sin(double) nounwind
17
18 define double @test_branch24 (double %x) nounwind readonly {
19 entry:
20 %add = call double @sin(double %x) nounwind
21 ret double %add
22 }
23
24 ;; The relocations in .rela.text are the 'number64' load using a
25 ;; R_PPC64_TOC16_DS against the .toc and the 'sin' external function
26 ;; address using a R_PPC64_REL24
27 ;; CHECK: '.rela.text'
28 ;; CHECK: Relocation 0
29 ;; CHECK-NEXT: 'r_offset',
30 ;; CHECK-NEXT: 'r_sym', 0x00000006
31 ;; CHECK-NEXT: 'r_type', 0x0000003f
32 ;; CHECK: Relocation 1
33 ;; CHECK-NEXT: 'r_offset',
34 ;; CHECK-NEXT: 'r_sym', 0x0000000a
35 ;; CHECK-NEXT: 'r_type', 0x0000000a
36
37 ;; The .opd entry for the 'access_int64' function creates 2 relocations:
38 ;; 1. A R_PPC64_ADDR64 against the .text segment plus addend (the function
39 ; address itself);
40 ;; 2. And a R_PPC64_TOC against no symbol (the linker will replace for the
41 ;; module's TOC base).
42 ;; CHECK: '.rela.opd'
43 ;; CHECK: Relocation 0
44 ;; CHECK-NEXT: 'r_offset',
45 ;; CHECK-NEXT: 'r_sym', 0x00000002
46 ;; CHECK-NEXT: 'r_type', 0x00000026
47 ;; CHECK: Relocation 1
48 ;; CHECK-NEXT: 'r_offset',
49 ;; CHECK-NEXT: 'r_sym', 0x00000000
50 ;; CHECK-NEXT: 'r_type', 0x00000033
51
52 ;; Finally the TOC creates the relocation for the 'number64'.
53 ;; CHECK: '.rela.toc'
54 ;; CHECK: Relocation 0
55 ;; CHECK-NEXT: 'r_offset',
56 ;; CHECK-NEXT: 'r_sym', 0x00000008
57 ;; CHECK-NEXT: 'r_type', 0x00000026
58
59 ;; Check if the relocation references are for correct symbols.
60 ;; CHECK: Symbol 7
61 ;; CHECK-NEXT: 'access_int64'
62 ;; CHECK: Symbol 8
63 ;; CHECK-NEXT: 'number64'
64 ;; CHECK: Symbol 10
65 ;; CHECK-NEXT: 'sin'