aaa5845d66e872098e80788151633528fb01bb53
[oota-llvm.git] / lib / Target / X86 / X86AsmBackend.cpp
1 //===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===//
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 "llvm/Target/TargetAsmBackend.h"
11 #include "X86.h"
12 #include "X86FixupKinds.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCObjectWriter.h"
17 #include "llvm/MC/MCSectionELF.h"
18 #include "llvm/MC/MCSectionMachO.h"
19 #include "llvm/MC/MachObjectWriter.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include "llvm/Target/TargetRegistry.h"
23 #include "llvm/Target/TargetAsmBackend.h"
24 using namespace llvm;
25
26 namespace {
27
28 static unsigned getFixupKindLog2Size(unsigned Kind) {
29   switch (Kind) {
30   default: assert(0 && "invalid fixup kind!");
31   case X86::reloc_pcrel_1byte:
32   case FK_Data_1: return 0;
33   case FK_Data_2: return 1;
34   case X86::reloc_pcrel_4byte:
35   case X86::reloc_riprel_4byte:
36   case X86::reloc_riprel_4byte_movq_load:
37   case FK_Data_4: return 2;
38   case FK_Data_8: return 3;
39   }
40 }
41
42 class X86AsmBackend : public TargetAsmBackend {
43 public:
44   X86AsmBackend(const Target &T)
45     : TargetAsmBackend(T) {}
46
47   void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
48                   uint64_t Value) const {
49     unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind());
50
51     assert(Fixup.getOffset() + Size <= DF.getContents().size() &&
52            "Invalid fixup offset!");
53     for (unsigned i = 0; i != Size; ++i)
54       DF.getContents()[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8));
55   }
56
57   bool MayNeedRelaxation(const MCInst &Inst,
58                          const SmallVectorImpl<MCFixup> &Fixups) const;
59
60   void RelaxInstruction(const MCInstFragment *IF, MCInst &Res) const;
61
62   bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const;
63 };
64
65 static unsigned getRelaxedOpcode(unsigned Op) {
66   switch (Op) {
67   default:
68     return Op;
69
70   case X86::JAE_1: return X86::JAE_4;
71   case X86::JA_1:  return X86::JA_4;
72   case X86::JBE_1: return X86::JBE_4;
73   case X86::JB_1:  return X86::JB_4;
74   case X86::JE_1:  return X86::JE_4;
75   case X86::JGE_1: return X86::JGE_4;
76   case X86::JG_1:  return X86::JG_4;
77   case X86::JLE_1: return X86::JLE_4;
78   case X86::JL_1:  return X86::JL_4;
79   case X86::TAILJMP_1:
80   case X86::JMP_1: return X86::JMP_4;
81   case X86::JNE_1: return X86::JNE_4;
82   case X86::JNO_1: return X86::JNO_4;
83   case X86::JNP_1: return X86::JNP_4;
84   case X86::JNS_1: return X86::JNS_4;
85   case X86::JO_1:  return X86::JO_4;
86   case X86::JP_1:  return X86::JP_4;
87   case X86::JS_1:  return X86::JS_4;
88   }
89 }
90
91 bool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst,
92                               const SmallVectorImpl<MCFixup> &Fixups) const {
93   for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
94     const MCFixup &F = Fixups[i];
95
96     // We don't support relaxing anything else currently. Make sure we error out
97     // if we see a non-constant 1 or 2 byte fixup.
98     //
99     // FIXME: We should need to check this here, this is better checked in the
100     // object writer which should be verifying that any final relocations match
101     // the expected fixup. However, that code is more complicated and hasn't
102     // been written yet. See the FIXMEs in MachObjectWriter.cpp.
103     if ((F.getKind() == FK_Data_1 || F.getKind() == FK_Data_2) &&
104         !isa<MCConstantExpr>(F.getValue()))
105       report_fatal_error("unexpected small fixup with a non-constant operand!");
106
107     // Check for a 1byte pcrel fixup, and enforce that we would know how to
108     // relax this instruction.
109     if (unsigned(F.getKind()) == X86::reloc_pcrel_1byte) {
110       assert(getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode());
111       return true;
112     }
113   }
114
115   return false;
116 }
117
118 // FIXME: Can tblgen help at all here to verify there aren't other instructions
119 // we can relax?
120 void X86AsmBackend::RelaxInstruction(const MCInstFragment *IF,
121                                      MCInst &Res) const {
122   // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel.
123   unsigned RelaxedOp = getRelaxedOpcode(IF->getInst().getOpcode());
124
125   if (RelaxedOp == IF->getInst().getOpcode()) {
126     SmallString<256> Tmp;
127     raw_svector_ostream OS(Tmp);
128     IF->getInst().dump_pretty(OS);
129     OS << "\n";
130     report_fatal_error("unexpected instruction to relax: " + OS.str());
131   }
132
133   Res = IF->getInst();
134   Res.setOpcode(RelaxedOp);
135 }
136
137 /// WriteNopData - Write optimal nops to the output file for the \arg Count
138 /// bytes.  This returns the number of bytes written.  It may return 0 if
139 /// the \arg Count is more than the maximum optimal nops.
140 ///
141 /// FIXME this is X86 32-bit specific and should move to a better place.
142 bool X86AsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
143   static const uint8_t Nops[16][16] = {
144     // nop
145     {0x90},
146     // xchg %ax,%ax
147     {0x66, 0x90},
148     // nopl (%[re]ax)
149     {0x0f, 0x1f, 0x00},
150     // nopl 0(%[re]ax)
151     {0x0f, 0x1f, 0x40, 0x00},
152     // nopl 0(%[re]ax,%[re]ax,1)
153     {0x0f, 0x1f, 0x44, 0x00, 0x00},
154     // nopw 0(%[re]ax,%[re]ax,1)
155     {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
156     // nopl 0L(%[re]ax)
157     {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
158     // nopl 0L(%[re]ax,%[re]ax,1)
159     {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
160     // nopw 0L(%[re]ax,%[re]ax,1)
161     {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
162     // nopw %cs:0L(%[re]ax,%[re]ax,1)
163     {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
164     // nopl 0(%[re]ax,%[re]ax,1)
165     // nopw 0(%[re]ax,%[re]ax,1)
166     {0x0f, 0x1f, 0x44, 0x00, 0x00,
167      0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
168     // nopw 0(%[re]ax,%[re]ax,1)
169     // nopw 0(%[re]ax,%[re]ax,1)
170     {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
171      0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
172     // nopw 0(%[re]ax,%[re]ax,1)
173     // nopl 0L(%[re]ax) */
174     {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
175      0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
176     // nopl 0L(%[re]ax)
177     // nopl 0L(%[re]ax)
178     {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
179      0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
180     // nopl 0L(%[re]ax)
181     // nopl 0L(%[re]ax,%[re]ax,1)
182     {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
183      0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}
184   };
185
186   // Write an optimal sequence for the first 15 bytes.
187   uint64_t OptimalCount = (Count < 16) ? Count : 15;
188   for (uint64_t i = 0, e = OptimalCount; i != e; i++)
189     OW->Write8(Nops[OptimalCount - 1][i]);
190
191   // Finish with single byte nops.
192   for (uint64_t i = OptimalCount, e = Count; i != e; ++i)
193    OW->Write8(0x90);
194
195   return true;
196 }
197
198 /* *** */
199
200 class ELFX86AsmBackend : public X86AsmBackend {
201 public:
202   ELFX86AsmBackend(const Target &T)
203     : X86AsmBackend(T) {
204     HasAbsolutizedSet = true;
205     HasScatteredSymbols = true;
206   }
207
208   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
209     return 0;
210   }
211
212   bool isVirtualSection(const MCSection &Section) const {
213     const MCSectionELF &SE = static_cast<const MCSectionELF&>(Section);
214     return SE.getType() == MCSectionELF::SHT_NOBITS;;
215   }
216 };
217
218 class ELFX86_32AsmBackend : public ELFX86AsmBackend {
219 public:
220   ELFX86_32AsmBackend(const Target &T)
221     : ELFX86AsmBackend(T) {}
222 };
223
224 class ELFX86_64AsmBackend : public ELFX86AsmBackend {
225 public:
226   ELFX86_64AsmBackend(const Target &T)
227     : ELFX86AsmBackend(T) {}
228 };
229
230 class DarwinX86AsmBackend : public X86AsmBackend {
231 public:
232   DarwinX86AsmBackend(const Target &T)
233     : X86AsmBackend(T) {
234     HasAbsolutizedSet = true;
235     HasScatteredSymbols = true;
236   }
237
238   bool isVirtualSection(const MCSection &Section) const {
239     const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
240     return (SMO.getType() == MCSectionMachO::S_ZEROFILL ||
241             SMO.getType() == MCSectionMachO::S_GB_ZEROFILL ||
242             SMO.getType() == MCSectionMachO::S_THREAD_LOCAL_ZEROFILL);
243   }
244 };
245
246 class DarwinX86_32AsmBackend : public DarwinX86AsmBackend {
247 public:
248   DarwinX86_32AsmBackend(const Target &T)
249     : DarwinX86AsmBackend(T) {}
250
251   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
252     return new MachObjectWriter(OS, /*Is64Bit=*/false);
253   }
254 };
255
256 class DarwinX86_64AsmBackend : public DarwinX86AsmBackend {
257 public:
258   DarwinX86_64AsmBackend(const Target &T)
259     : DarwinX86AsmBackend(T) {
260     HasReliableSymbolDifference = true;
261   }
262
263   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
264     return new MachObjectWriter(OS, /*Is64Bit=*/true);
265   }
266
267   virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
268     // Temporary labels in the string literals sections require symbols. The
269     // issue is that the x86_64 relocation format does not allow symbol +
270     // offset, and so the linker does not have enough information to resolve the
271     // access to the appropriate atom unless an external relocation is used. For
272     // non-cstring sections, we expect the compiler to use a non-temporary label
273     // for anything that could have an addend pointing outside the symbol.
274     //
275     // See <rdar://problem/4765733>.
276     const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
277     return SMO.getType() == MCSectionMachO::S_CSTRING_LITERALS;
278   }
279
280   virtual bool isSectionAtomizable(const MCSection &Section) const {
281     const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
282     // Fixed sized data sections are uniqued, they cannot be diced into atoms.
283     switch (SMO.getType()) {
284     default:
285       return true;
286
287     case MCSectionMachO::S_4BYTE_LITERALS:
288     case MCSectionMachO::S_8BYTE_LITERALS:
289     case MCSectionMachO::S_16BYTE_LITERALS:
290     case MCSectionMachO::S_LITERAL_POINTERS:
291     case MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS:
292     case MCSectionMachO::S_LAZY_SYMBOL_POINTERS:
293     case MCSectionMachO::S_MOD_INIT_FUNC_POINTERS:
294     case MCSectionMachO::S_MOD_TERM_FUNC_POINTERS:
295     case MCSectionMachO::S_INTERPOSING:
296       return false;
297     }
298   }
299 };
300
301 }
302
303 TargetAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
304                                                const std::string &TT) {
305   switch (Triple(TT).getOS()) {
306   case Triple::Darwin:
307     return new DarwinX86_32AsmBackend(T);
308   default:
309     return new ELFX86_32AsmBackend(T);
310   }
311 }
312
313 TargetAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
314                                                const std::string &TT) {
315   switch (Triple(TT).getOS()) {
316   case Triple::Darwin:
317     return new DarwinX86_64AsmBackend(T);
318   default:
319     return new ELFX86_64AsmBackend(T);
320   }
321 }