[AVX512] FMA support for the 231 variants
[oota-llvm.git] / lib / Target / PowerPC / MCTargetDesc / PPCELFObjectWriter.cpp
1 //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MCTargetDesc/PPCMCTargetDesc.h"
11 #include "MCTargetDesc/PPCFixupKinds.h"
12 #include "MCTargetDesc/PPCMCExpr.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/MC/MCELF.h"
15 #include "llvm/MC/MCELFObjectWriter.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCValue.h"
18 #include "llvm/Support/ErrorHandling.h"
19
20 using namespace llvm;
21
22 namespace {
23   class PPCELFObjectWriter : public MCELFObjectTargetWriter {
24   public:
25     PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
26
27   protected:
28     unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
29                           bool IsPCRel) const override;
30
31     bool needsRelocateWithSymbol(const MCSymbolData &SD,
32                                  unsigned Type) const override;
33   };
34 }
35
36 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
37   : MCELFObjectTargetWriter(Is64Bit, OSABI,
38                             Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
39                             /*HasRelocationAddend*/ true) {}
40
41 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
42                                                      const MCFixup &Fixup) {
43   const MCExpr *Expr = Fixup.getValue();
44
45   if (Expr->getKind() != MCExpr::Target)
46     return Target.getAccessVariant();
47
48   switch (cast<PPCMCExpr>(Expr)->getKind()) {
49   case PPCMCExpr::VK_PPC_None:
50     return MCSymbolRefExpr::VK_None;
51   case PPCMCExpr::VK_PPC_LO:
52     return MCSymbolRefExpr::VK_PPC_LO;
53   case PPCMCExpr::VK_PPC_HI:
54     return MCSymbolRefExpr::VK_PPC_HI;
55   case PPCMCExpr::VK_PPC_HA:
56     return MCSymbolRefExpr::VK_PPC_HA;
57   case PPCMCExpr::VK_PPC_HIGHERA:
58     return MCSymbolRefExpr::VK_PPC_HIGHERA;
59   case PPCMCExpr::VK_PPC_HIGHER:
60     return MCSymbolRefExpr::VK_PPC_HIGHER;
61   case PPCMCExpr::VK_PPC_HIGHEST:
62     return MCSymbolRefExpr::VK_PPC_HIGHEST;
63   case PPCMCExpr::VK_PPC_HIGHESTA:
64     return MCSymbolRefExpr::VK_PPC_HIGHESTA;
65   }
66   llvm_unreachable("unknown PPCMCExpr kind");
67 }
68
69 unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
70                                           const MCFixup &Fixup,
71                                           bool IsPCRel) const {
72   MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
73
74   // determine the type of the relocation
75   unsigned Type;
76   if (IsPCRel) {
77     switch ((unsigned)Fixup.getKind()) {
78     default:
79       llvm_unreachable("Unimplemented");
80     case PPC::fixup_ppc_br24:
81     case PPC::fixup_ppc_br24abs:
82       switch (Modifier) {
83       default: llvm_unreachable("Unsupported Modifier");
84       case MCSymbolRefExpr::VK_None:
85         Type = ELF::R_PPC_REL24;
86         break;
87       case MCSymbolRefExpr::VK_PLT:
88         Type = ELF::R_PPC_PLTREL24;
89         break;
90       }
91       break;
92     case PPC::fixup_ppc_brcond14:
93     case PPC::fixup_ppc_brcond14abs:
94       Type = ELF::R_PPC_REL14;
95       break;
96     case PPC::fixup_ppc_half16:
97       switch (Modifier) {
98       default: llvm_unreachable("Unsupported Modifier");
99       case MCSymbolRefExpr::VK_None:
100         Type = ELF::R_PPC_REL16;
101         break;
102       case MCSymbolRefExpr::VK_PPC_LO:
103         Type = ELF::R_PPC_REL16_LO;
104         break;
105       case MCSymbolRefExpr::VK_PPC_HI:
106         Type = ELF::R_PPC_REL16_HI;
107         break;
108       case MCSymbolRefExpr::VK_PPC_HA:
109         Type = ELF::R_PPC_REL16_HA;
110         break;
111       }
112       break;
113     case FK_Data_4:
114     case FK_PCRel_4:
115       Type = ELF::R_PPC_REL32;
116       break;
117     case FK_Data_8:
118     case FK_PCRel_8:
119       Type = ELF::R_PPC64_REL64;
120       break;
121     }
122   } else {
123     switch ((unsigned)Fixup.getKind()) {
124       default: llvm_unreachable("invalid fixup kind!");
125     case PPC::fixup_ppc_br24abs:
126       Type = ELF::R_PPC_ADDR24;
127       break;
128     case PPC::fixup_ppc_brcond14abs:
129       Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
130       break;
131     case PPC::fixup_ppc_half16:
132       switch (Modifier) {
133       default: llvm_unreachable("Unsupported Modifier");
134       case MCSymbolRefExpr::VK_None:
135         Type = ELF::R_PPC_ADDR16;
136         break;
137       case MCSymbolRefExpr::VK_PPC_LO:
138         Type = ELF::R_PPC_ADDR16_LO;
139         break;
140       case MCSymbolRefExpr::VK_PPC_HI:
141         Type = ELF::R_PPC_ADDR16_HI;
142         break;
143       case MCSymbolRefExpr::VK_PPC_HA:
144         Type = ELF::R_PPC_ADDR16_HA;
145         break;
146       case MCSymbolRefExpr::VK_PPC_HIGHER:
147         Type = ELF::R_PPC64_ADDR16_HIGHER;
148         break;
149       case MCSymbolRefExpr::VK_PPC_HIGHERA:
150         Type = ELF::R_PPC64_ADDR16_HIGHERA;
151         break;
152       case MCSymbolRefExpr::VK_PPC_HIGHEST:
153         Type = ELF::R_PPC64_ADDR16_HIGHEST;
154         break;
155       case MCSymbolRefExpr::VK_PPC_HIGHESTA:
156         Type = ELF::R_PPC64_ADDR16_HIGHESTA;
157         break;
158       case MCSymbolRefExpr::VK_GOT:
159         Type = ELF::R_PPC_GOT16;
160         break;
161       case MCSymbolRefExpr::VK_PPC_GOT_LO:
162         Type = ELF::R_PPC_GOT16_LO;
163         break;
164       case MCSymbolRefExpr::VK_PPC_GOT_HI:
165         Type = ELF::R_PPC_GOT16_HI;
166         break;
167       case MCSymbolRefExpr::VK_PPC_GOT_HA:
168         Type = ELF::R_PPC_GOT16_HA;
169         break;
170       case MCSymbolRefExpr::VK_PPC_TOC:
171         Type = ELF::R_PPC64_TOC16;
172         break;
173       case MCSymbolRefExpr::VK_PPC_TOC_LO:
174         Type = ELF::R_PPC64_TOC16_LO;
175         break;
176       case MCSymbolRefExpr::VK_PPC_TOC_HI:
177         Type = ELF::R_PPC64_TOC16_HI;
178         break;
179       case MCSymbolRefExpr::VK_PPC_TOC_HA:
180         Type = ELF::R_PPC64_TOC16_HA;
181         break;
182       case MCSymbolRefExpr::VK_PPC_TPREL:
183         Type = ELF::R_PPC_TPREL16;
184         break;
185       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
186         Type = ELF::R_PPC_TPREL16_LO;
187         break;
188       case MCSymbolRefExpr::VK_PPC_TPREL_HI:
189         Type = ELF::R_PPC_TPREL16_HI;
190         break;
191       case MCSymbolRefExpr::VK_PPC_TPREL_HA:
192         Type = ELF::R_PPC_TPREL16_HA;
193         break;
194       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
195         Type = ELF::R_PPC64_TPREL16_HIGHER;
196         break;
197       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
198         Type = ELF::R_PPC64_TPREL16_HIGHERA;
199         break;
200       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
201         Type = ELF::R_PPC64_TPREL16_HIGHEST;
202         break;
203       case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
204         Type = ELF::R_PPC64_TPREL16_HIGHESTA;
205         break;
206       case MCSymbolRefExpr::VK_PPC_DTPREL:
207         Type = ELF::R_PPC64_DTPREL16;
208         break;
209       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
210         Type = ELF::R_PPC64_DTPREL16_LO;
211         break;
212       case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
213         Type = ELF::R_PPC64_DTPREL16_HI;
214         break;
215       case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
216         Type = ELF::R_PPC64_DTPREL16_HA;
217         break;
218       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
219         Type = ELF::R_PPC64_DTPREL16_HIGHER;
220         break;
221       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
222         Type = ELF::R_PPC64_DTPREL16_HIGHERA;
223         break;
224       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
225         Type = ELF::R_PPC64_DTPREL16_HIGHEST;
226         break;
227       case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
228         Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
229         break;
230       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
231         if (is64Bit())
232           Type = ELF::R_PPC64_GOT_TLSGD16;
233         else
234           Type = ELF::R_PPC_GOT_TLSGD16;
235         break;
236       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
237         Type = ELF::R_PPC64_GOT_TLSGD16_LO;
238         break;
239       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
240         Type = ELF::R_PPC64_GOT_TLSGD16_HI;
241         break;
242       case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
243         Type = ELF::R_PPC64_GOT_TLSGD16_HA;
244         break;
245       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
246         if (is64Bit())
247           Type = ELF::R_PPC64_GOT_TLSLD16;
248         else
249           Type = ELF::R_PPC_GOT_TLSLD16;
250         break;
251       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
252         Type = ELF::R_PPC64_GOT_TLSLD16_LO;
253         break;
254       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
255         Type = ELF::R_PPC64_GOT_TLSLD16_HI;
256         break;
257       case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
258         Type = ELF::R_PPC64_GOT_TLSLD16_HA;
259         break;
260       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
261         /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
262            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
263         Type = ELF::R_PPC64_GOT_TPREL16_DS;
264         break;
265       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
266         /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
267            are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
268         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
269         break;
270       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
271         Type = ELF::R_PPC64_GOT_TPREL16_HI;
272         break;
273       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
274         /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
275            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
276         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
277         break;
278       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
279         /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
280            are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
281         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
282         break;
283       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
284         Type = ELF::R_PPC64_GOT_TPREL16_HA;
285         break;
286       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
287         Type = ELF::R_PPC64_GOT_DTPREL16_HI;
288         break;
289       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
290         Type = ELF::R_PPC64_GOT_DTPREL16_HA;
291         break;
292       }
293       break;
294     case PPC::fixup_ppc_half16ds:
295       switch (Modifier) {
296       default: llvm_unreachable("Unsupported Modifier");
297       case MCSymbolRefExpr::VK_None:
298         Type = ELF::R_PPC64_ADDR16_DS;
299         break;
300       case MCSymbolRefExpr::VK_PPC_LO:
301         Type = ELF::R_PPC64_ADDR16_LO_DS;
302         break;
303       case MCSymbolRefExpr::VK_GOT:
304         Type = ELF::R_PPC64_GOT16_DS;
305         break;
306       case MCSymbolRefExpr::VK_PPC_GOT_LO:
307         Type = ELF::R_PPC64_GOT16_LO_DS;
308         break;
309       case MCSymbolRefExpr::VK_PPC_TOC:
310         Type = ELF::R_PPC64_TOC16_DS;
311         break;
312       case MCSymbolRefExpr::VK_PPC_TOC_LO:
313         Type = ELF::R_PPC64_TOC16_LO_DS;
314         break;
315       case MCSymbolRefExpr::VK_PPC_TPREL:
316         Type = ELF::R_PPC64_TPREL16_DS;
317         break;
318       case MCSymbolRefExpr::VK_PPC_TPREL_LO:
319         Type = ELF::R_PPC64_TPREL16_LO_DS;
320         break;
321       case MCSymbolRefExpr::VK_PPC_DTPREL:
322         Type = ELF::R_PPC64_DTPREL16_DS;
323         break;
324       case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
325         Type = ELF::R_PPC64_DTPREL16_LO_DS;
326         break;
327       case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
328         Type = ELF::R_PPC64_GOT_TPREL16_DS;
329         break;
330       case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
331         Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
332         break;
333       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
334         Type = ELF::R_PPC64_GOT_DTPREL16_DS;
335         break;
336       case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
337         Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
338         break;
339       }
340       break;
341     case PPC::fixup_ppc_nofixup:
342       switch (Modifier) {
343       default: llvm_unreachable("Unsupported Modifier");
344       case MCSymbolRefExpr::VK_PPC_TLSGD:
345         if (is64Bit())
346           Type = ELF::R_PPC64_TLSGD;
347         else
348           Type = ELF::R_PPC_TLSGD;
349         break;
350       case MCSymbolRefExpr::VK_PPC_TLSLD:
351         if (is64Bit())
352           Type = ELF::R_PPC64_TLSLD;
353         else
354           Type = ELF::R_PPC_TLSLD;
355         break;
356       case MCSymbolRefExpr::VK_PPC_TLS:
357         if (is64Bit())
358           Type = ELF::R_PPC64_TLS;
359         else
360           Type = ELF::R_PPC_TLS;
361         break;
362       }
363       break;
364     case FK_Data_8:
365       switch (Modifier) {
366       default: llvm_unreachable("Unsupported Modifier");
367       case MCSymbolRefExpr::VK_PPC_TOCBASE:
368         Type = ELF::R_PPC64_TOC;
369         break;
370       case MCSymbolRefExpr::VK_None:
371         Type = ELF::R_PPC64_ADDR64;
372         break;
373       case MCSymbolRefExpr::VK_PPC_DTPMOD:
374         Type = ELF::R_PPC64_DTPMOD64;
375         break;
376       case MCSymbolRefExpr::VK_PPC_TPREL:
377         Type = ELF::R_PPC64_TPREL64;
378         break;
379       case MCSymbolRefExpr::VK_PPC_DTPREL:
380         Type = ELF::R_PPC64_DTPREL64;
381         break;
382       }
383       break;
384     case FK_Data_4:
385       Type = ELF::R_PPC_ADDR32;
386       break;
387     case FK_Data_2:
388       Type = ELF::R_PPC_ADDR16;
389       break;
390     }
391   }
392   return Type;
393 }
394
395 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
396                                                  unsigned Type) const {
397   switch (Type) {
398     default:
399       return false;
400
401     case ELF::R_PPC_REL24:
402       // If the target symbol has a local entry point, we must keep the
403       // target symbol to preserve that information for the linker.
404       // The "other" values are stored in the last 6 bits of the second byte.
405       // The traditional defines for STO values assume the full byte and thus
406       // the shift to pack it.
407       unsigned Other = MCELF::getOther(SD) << 2;
408       return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
409   }
410 }
411
412 MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,
413                                                bool Is64Bit,
414                                                bool IsLittleEndian,
415                                                uint8_t OSABI) {
416   MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI);
417   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
418 }