]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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 "MCTargetDesc/X86BaseInfo.h" | |
11 | #include "MCTargetDesc/X86FixupKinds.h" | |
1a4d82fc | 12 | #include "llvm/ADT/StringSwitch.h" |
223e47cc | 13 | #include "llvm/MC/MCAsmBackend.h" |
223e47cc LB |
14 | #include "llvm/MC/MCELFObjectWriter.h" |
15 | #include "llvm/MC/MCExpr.h" | |
16 | #include "llvm/MC/MCFixupKindInfo.h" | |
17 | #include "llvm/MC/MCMachObjectWriter.h" | |
18 | #include "llvm/MC/MCObjectWriter.h" | |
19 | #include "llvm/MC/MCSectionCOFF.h" | |
20 | #include "llvm/MC/MCSectionELF.h" | |
21 | #include "llvm/MC/MCSectionMachO.h" | |
223e47cc LB |
22 | #include "llvm/Support/CommandLine.h" |
23 | #include "llvm/Support/ELF.h" | |
24 | #include "llvm/Support/ErrorHandling.h" | |
1a4d82fc | 25 | #include "llvm/Support/MachO.h" |
223e47cc LB |
26 | #include "llvm/Support/TargetRegistry.h" |
27 | #include "llvm/Support/raw_ostream.h" | |
28 | using namespace llvm; | |
29 | ||
30 | // Option to allow disabling arithmetic relaxation to workaround PR9807, which | |
31 | // is useful when running bitwise comparison experiments on Darwin. We should be | |
32 | // able to remove this once PR9807 is resolved. | |
33 | static cl::opt<bool> | |
34 | MCDisableArithRelaxation("mc-x86-disable-arith-relaxation", | |
35 | cl::desc("Disable relaxation of arithmetic instruction for X86")); | |
36 | ||
37 | static unsigned getFixupKindLog2Size(unsigned Kind) { | |
38 | switch (Kind) { | |
1a4d82fc JJ |
39 | default: |
40 | llvm_unreachable("invalid fixup kind!"); | |
223e47cc LB |
41 | case FK_PCRel_1: |
42 | case FK_SecRel_1: | |
1a4d82fc JJ |
43 | case FK_Data_1: |
44 | return 0; | |
223e47cc LB |
45 | case FK_PCRel_2: |
46 | case FK_SecRel_2: | |
1a4d82fc JJ |
47 | case FK_Data_2: |
48 | return 1; | |
223e47cc LB |
49 | case FK_PCRel_4: |
50 | case X86::reloc_riprel_4byte: | |
51 | case X86::reloc_riprel_4byte_movq_load: | |
52 | case X86::reloc_signed_4byte: | |
53 | case X86::reloc_global_offset_table: | |
54 | case FK_SecRel_4: | |
1a4d82fc JJ |
55 | case FK_Data_4: |
56 | return 2; | |
223e47cc LB |
57 | case FK_PCRel_8: |
58 | case FK_SecRel_8: | |
1a4d82fc JJ |
59 | case FK_Data_8: |
60 | case X86::reloc_global_offset_table8: | |
61 | return 3; | |
223e47cc LB |
62 | } |
63 | } | |
64 | ||
65 | namespace { | |
66 | ||
67 | class X86ELFObjectWriter : public MCELFObjectTargetWriter { | |
68 | public: | |
69 | X86ELFObjectWriter(bool is64Bit, uint8_t OSABI, uint16_t EMachine, | |
70 | bool HasRelocationAddend, bool foobar) | |
71 | : MCELFObjectTargetWriter(is64Bit, OSABI, EMachine, HasRelocationAddend) {} | |
72 | }; | |
73 | ||
74 | class X86AsmBackend : public MCAsmBackend { | |
1a4d82fc JJ |
75 | const StringRef CPU; |
76 | bool HasNopl; | |
77 | const uint64_t MaxNopLength; | |
223e47cc LB |
78 | public: |
79 | X86AsmBackend(const Target &T, StringRef _CPU) | |
1a4d82fc JJ |
80 | : MCAsmBackend(), CPU(_CPU), MaxNopLength(_CPU == "slm" ? 7 : 15) { |
81 | HasNopl = CPU != "generic" && CPU != "i386" && CPU != "i486" && | |
82 | CPU != "i586" && CPU != "pentium" && CPU != "pentium-mmx" && | |
83 | CPU != "i686" && CPU != "k6" && CPU != "k6-2" && CPU != "k6-3" && | |
84 | CPU != "geode" && CPU != "winchip-c6" && CPU != "winchip2" && | |
85 | CPU != "c3" && CPU != "c3-2"; | |
86 | } | |
223e47cc | 87 | |
1a4d82fc | 88 | unsigned getNumFixupKinds() const override { |
223e47cc LB |
89 | return X86::NumTargetFixupKinds; |
90 | } | |
91 | ||
1a4d82fc | 92 | const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { |
223e47cc LB |
93 | const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = { |
94 | { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, | |
95 | { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel}, | |
96 | { "reloc_signed_4byte", 0, 4 * 8, 0}, | |
97 | { "reloc_global_offset_table", 0, 4 * 8, 0} | |
98 | }; | |
99 | ||
100 | if (Kind < FirstTargetFixupKind) | |
101 | return MCAsmBackend::getFixupKindInfo(Kind); | |
102 | ||
103 | assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && | |
104 | "Invalid kind!"); | |
105 | return Infos[Kind - FirstTargetFixupKind]; | |
106 | } | |
107 | ||
108 | void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, | |
1a4d82fc | 109 | uint64_t Value, bool IsPCRel) const override { |
223e47cc LB |
110 | unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); |
111 | ||
112 | assert(Fixup.getOffset() + Size <= DataSize && | |
113 | "Invalid fixup offset!"); | |
114 | ||
115 | // Check that uppper bits are either all zeros or all ones. | |
116 | // Specifically ignore overflow/underflow as long as the leakage is | |
117 | // limited to the lower bits. This is to remain compatible with | |
118 | // other assemblers. | |
119 | assert(isIntN(Size * 8 + 1, Value) && | |
120 | "Value does not fit in the Fixup field"); | |
121 | ||
122 | for (unsigned i = 0; i != Size; ++i) | |
123 | Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); | |
124 | } | |
125 | ||
1a4d82fc | 126 | bool mayNeedRelaxation(const MCInst &Inst) const override; |
223e47cc | 127 | |
1a4d82fc | 128 | bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, |
970d7e83 | 129 | const MCRelaxableFragment *DF, |
1a4d82fc | 130 | const MCAsmLayout &Layout) const override; |
223e47cc | 131 | |
1a4d82fc | 132 | void relaxInstruction(const MCInst &Inst, MCInst &Res) const override; |
223e47cc | 133 | |
1a4d82fc | 134 | bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; |
223e47cc LB |
135 | }; |
136 | } // end anonymous namespace | |
137 | ||
138 | static unsigned getRelaxedOpcodeBranch(unsigned Op) { | |
139 | switch (Op) { | |
140 | default: | |
141 | return Op; | |
142 | ||
143 | case X86::JAE_1: return X86::JAE_4; | |
144 | case X86::JA_1: return X86::JA_4; | |
145 | case X86::JBE_1: return X86::JBE_4; | |
146 | case X86::JB_1: return X86::JB_4; | |
147 | case X86::JE_1: return X86::JE_4; | |
148 | case X86::JGE_1: return X86::JGE_4; | |
149 | case X86::JG_1: return X86::JG_4; | |
150 | case X86::JLE_1: return X86::JLE_4; | |
151 | case X86::JL_1: return X86::JL_4; | |
152 | case X86::JMP_1: return X86::JMP_4; | |
153 | case X86::JNE_1: return X86::JNE_4; | |
154 | case X86::JNO_1: return X86::JNO_4; | |
155 | case X86::JNP_1: return X86::JNP_4; | |
156 | case X86::JNS_1: return X86::JNS_4; | |
157 | case X86::JO_1: return X86::JO_4; | |
158 | case X86::JP_1: return X86::JP_4; | |
159 | case X86::JS_1: return X86::JS_4; | |
160 | } | |
161 | } | |
162 | ||
163 | static unsigned getRelaxedOpcodeArith(unsigned Op) { | |
164 | switch (Op) { | |
165 | default: | |
166 | return Op; | |
167 | ||
168 | // IMUL | |
169 | case X86::IMUL16rri8: return X86::IMUL16rri; | |
170 | case X86::IMUL16rmi8: return X86::IMUL16rmi; | |
171 | case X86::IMUL32rri8: return X86::IMUL32rri; | |
172 | case X86::IMUL32rmi8: return X86::IMUL32rmi; | |
173 | case X86::IMUL64rri8: return X86::IMUL64rri32; | |
174 | case X86::IMUL64rmi8: return X86::IMUL64rmi32; | |
175 | ||
176 | // AND | |
177 | case X86::AND16ri8: return X86::AND16ri; | |
178 | case X86::AND16mi8: return X86::AND16mi; | |
179 | case X86::AND32ri8: return X86::AND32ri; | |
180 | case X86::AND32mi8: return X86::AND32mi; | |
181 | case X86::AND64ri8: return X86::AND64ri32; | |
182 | case X86::AND64mi8: return X86::AND64mi32; | |
183 | ||
184 | // OR | |
185 | case X86::OR16ri8: return X86::OR16ri; | |
186 | case X86::OR16mi8: return X86::OR16mi; | |
187 | case X86::OR32ri8: return X86::OR32ri; | |
188 | case X86::OR32mi8: return X86::OR32mi; | |
189 | case X86::OR64ri8: return X86::OR64ri32; | |
190 | case X86::OR64mi8: return X86::OR64mi32; | |
191 | ||
192 | // XOR | |
193 | case X86::XOR16ri8: return X86::XOR16ri; | |
194 | case X86::XOR16mi8: return X86::XOR16mi; | |
195 | case X86::XOR32ri8: return X86::XOR32ri; | |
196 | case X86::XOR32mi8: return X86::XOR32mi; | |
197 | case X86::XOR64ri8: return X86::XOR64ri32; | |
198 | case X86::XOR64mi8: return X86::XOR64mi32; | |
199 | ||
200 | // ADD | |
201 | case X86::ADD16ri8: return X86::ADD16ri; | |
202 | case X86::ADD16mi8: return X86::ADD16mi; | |
203 | case X86::ADD32ri8: return X86::ADD32ri; | |
204 | case X86::ADD32mi8: return X86::ADD32mi; | |
205 | case X86::ADD64ri8: return X86::ADD64ri32; | |
206 | case X86::ADD64mi8: return X86::ADD64mi32; | |
207 | ||
208 | // SUB | |
209 | case X86::SUB16ri8: return X86::SUB16ri; | |
210 | case X86::SUB16mi8: return X86::SUB16mi; | |
211 | case X86::SUB32ri8: return X86::SUB32ri; | |
212 | case X86::SUB32mi8: return X86::SUB32mi; | |
213 | case X86::SUB64ri8: return X86::SUB64ri32; | |
214 | case X86::SUB64mi8: return X86::SUB64mi32; | |
215 | ||
216 | // CMP | |
217 | case X86::CMP16ri8: return X86::CMP16ri; | |
218 | case X86::CMP16mi8: return X86::CMP16mi; | |
219 | case X86::CMP32ri8: return X86::CMP32ri; | |
220 | case X86::CMP32mi8: return X86::CMP32mi; | |
221 | case X86::CMP64ri8: return X86::CMP64ri32; | |
222 | case X86::CMP64mi8: return X86::CMP64mi32; | |
223 | ||
224 | // PUSH | |
1a4d82fc JJ |
225 | case X86::PUSH32i8: return X86::PUSHi32; |
226 | case X86::PUSH16i8: return X86::PUSHi16; | |
227 | case X86::PUSH64i8: return X86::PUSH64i32; | |
223e47cc LB |
228 | case X86::PUSH64i16: return X86::PUSH64i32; |
229 | } | |
230 | } | |
231 | ||
232 | static unsigned getRelaxedOpcode(unsigned Op) { | |
233 | unsigned R = getRelaxedOpcodeArith(Op); | |
234 | if (R != Op) | |
235 | return R; | |
236 | return getRelaxedOpcodeBranch(Op); | |
237 | } | |
238 | ||
239 | bool X86AsmBackend::mayNeedRelaxation(const MCInst &Inst) const { | |
240 | // Branches can always be relaxed. | |
241 | if (getRelaxedOpcodeBranch(Inst.getOpcode()) != Inst.getOpcode()) | |
242 | return true; | |
243 | ||
244 | if (MCDisableArithRelaxation) | |
245 | return false; | |
246 | ||
247 | // Check if this instruction is ever relaxable. | |
248 | if (getRelaxedOpcodeArith(Inst.getOpcode()) == Inst.getOpcode()) | |
249 | return false; | |
250 | ||
251 | ||
252 | // Check if it has an expression and is not RIP relative. | |
253 | bool hasExp = false; | |
254 | bool hasRIP = false; | |
255 | for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { | |
256 | const MCOperand &Op = Inst.getOperand(i); | |
257 | if (Op.isExpr()) | |
258 | hasExp = true; | |
259 | ||
260 | if (Op.isReg() && Op.getReg() == X86::RIP) | |
261 | hasRIP = true; | |
262 | } | |
263 | ||
264 | // FIXME: Why exactly do we need the !hasRIP? Is it just a limitation on | |
265 | // how we do relaxations? | |
266 | return hasExp && !hasRIP; | |
267 | } | |
268 | ||
269 | bool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, | |
270 | uint64_t Value, | |
970d7e83 | 271 | const MCRelaxableFragment *DF, |
223e47cc LB |
272 | const MCAsmLayout &Layout) const { |
273 | // Relax if the value is too big for a (signed) i8. | |
274 | return int64_t(Value) != int64_t(int8_t(Value)); | |
275 | } | |
276 | ||
277 | // FIXME: Can tblgen help at all here to verify there aren't other instructions | |
278 | // we can relax? | |
279 | void X86AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { | |
280 | // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel. | |
281 | unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); | |
282 | ||
283 | if (RelaxedOp == Inst.getOpcode()) { | |
284 | SmallString<256> Tmp; | |
285 | raw_svector_ostream OS(Tmp); | |
286 | Inst.dump_pretty(OS); | |
287 | OS << "\n"; | |
288 | report_fatal_error("unexpected instruction to relax: " + OS.str()); | |
289 | } | |
290 | ||
291 | Res = Inst; | |
292 | Res.setOpcode(RelaxedOp); | |
293 | } | |
294 | ||
970d7e83 LB |
295 | /// \brief Write a sequence of optimal nops to the output, covering \p Count |
296 | /// bytes. | |
297 | /// \return - true on success, false on failure | |
223e47cc LB |
298 | bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { |
299 | static const uint8_t Nops[10][10] = { | |
300 | // nop | |
301 | {0x90}, | |
302 | // xchg %ax,%ax | |
303 | {0x66, 0x90}, | |
304 | // nopl (%[re]ax) | |
305 | {0x0f, 0x1f, 0x00}, | |
306 | // nopl 0(%[re]ax) | |
307 | {0x0f, 0x1f, 0x40, 0x00}, | |
308 | // nopl 0(%[re]ax,%[re]ax,1) | |
309 | {0x0f, 0x1f, 0x44, 0x00, 0x00}, | |
310 | // nopw 0(%[re]ax,%[re]ax,1) | |
311 | {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, | |
312 | // nopl 0L(%[re]ax) | |
313 | {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, | |
314 | // nopl 0L(%[re]ax,%[re]ax,1) | |
315 | {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
316 | // nopw 0L(%[re]ax,%[re]ax,1) | |
317 | {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
318 | // nopw %cs:0L(%[re]ax,%[re]ax,1) | |
319 | {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, | |
320 | }; | |
321 | ||
1a4d82fc | 322 | // This CPU doesn't support long nops. If needed add more. |
970d7e83 | 323 | // FIXME: Can we get this from the subtarget somehow? |
1a4d82fc JJ |
324 | // FIXME: We could generated something better than plain 0x90. |
325 | if (!HasNopl) { | |
223e47cc LB |
326 | for (uint64_t i = 0; i < Count; ++i) |
327 | OW->Write8(0x90); | |
328 | return true; | |
329 | } | |
330 | ||
970d7e83 LB |
331 | // 15 is the longest single nop instruction. Emit as many 15-byte nops as |
332 | // needed, then emit a nop of the remaining length. | |
333 | do { | |
1a4d82fc | 334 | const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength); |
970d7e83 LB |
335 | const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10; |
336 | for (uint8_t i = 0; i < Prefixes; i++) | |
337 | OW->Write8(0x66); | |
338 | const uint8_t Rest = ThisNopLength - Prefixes; | |
339 | for (uint8_t i = 0; i < Rest; i++) | |
340 | OW->Write8(Nops[Rest - 1][i]); | |
341 | Count -= ThisNopLength; | |
342 | } while (Count != 0); | |
223e47cc LB |
343 | |
344 | return true; | |
345 | } | |
346 | ||
347 | /* *** */ | |
348 | ||
349 | namespace { | |
1a4d82fc | 350 | |
223e47cc LB |
351 | class ELFX86AsmBackend : public X86AsmBackend { |
352 | public: | |
353 | uint8_t OSABI; | |
354 | ELFX86AsmBackend(const Target &T, uint8_t _OSABI, StringRef CPU) | |
1a4d82fc | 355 | : X86AsmBackend(T, CPU), OSABI(_OSABI) {} |
223e47cc LB |
356 | }; |
357 | ||
358 | class ELFX86_32AsmBackend : public ELFX86AsmBackend { | |
359 | public: | |
360 | ELFX86_32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) | |
361 | : ELFX86AsmBackend(T, OSABI, CPU) {} | |
362 | ||
1a4d82fc | 363 | MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { |
970d7e83 | 364 | return createX86ELFObjectWriter(OS, /*IsELF64*/ false, OSABI, ELF::EM_386); |
223e47cc LB |
365 | } |
366 | }; | |
367 | ||
1a4d82fc JJ |
368 | class ELFX86_X32AsmBackend : public ELFX86AsmBackend { |
369 | public: | |
370 | ELFX86_X32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) | |
371 | : ELFX86AsmBackend(T, OSABI, CPU) {} | |
372 | ||
373 | MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { | |
374 | return createX86ELFObjectWriter(OS, /*IsELF64*/ false, OSABI, | |
375 | ELF::EM_X86_64); | |
376 | } | |
377 | }; | |
378 | ||
223e47cc LB |
379 | class ELFX86_64AsmBackend : public ELFX86AsmBackend { |
380 | public: | |
381 | ELFX86_64AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) | |
382 | : ELFX86AsmBackend(T, OSABI, CPU) {} | |
383 | ||
1a4d82fc | 384 | MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { |
970d7e83 | 385 | return createX86ELFObjectWriter(OS, /*IsELF64*/ true, OSABI, ELF::EM_X86_64); |
223e47cc LB |
386 | } |
387 | }; | |
388 | ||
389 | class WindowsX86AsmBackend : public X86AsmBackend { | |
390 | bool Is64Bit; | |
391 | ||
392 | public: | |
393 | WindowsX86AsmBackend(const Target &T, bool is64Bit, StringRef CPU) | |
394 | : X86AsmBackend(T, CPU) | |
395 | , Is64Bit(is64Bit) { | |
396 | } | |
397 | ||
1a4d82fc | 398 | MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { |
223e47cc LB |
399 | return createX86WinCOFFObjectWriter(OS, Is64Bit); |
400 | } | |
401 | }; | |
402 | ||
1a4d82fc JJ |
403 | namespace CU { |
404 | ||
405 | /// Compact unwind encoding values. | |
406 | enum CompactUnwindEncodings { | |
407 | /// [RE]BP based frame where [RE]BP is pused on the stack immediately after | |
408 | /// the return address, then [RE]SP is moved to [RE]BP. | |
409 | UNWIND_MODE_BP_FRAME = 0x01000000, | |
410 | ||
411 | /// A frameless function with a small constant stack size. | |
412 | UNWIND_MODE_STACK_IMMD = 0x02000000, | |
413 | ||
414 | /// A frameless function with a large constant stack size. | |
415 | UNWIND_MODE_STACK_IND = 0x03000000, | |
416 | ||
417 | /// No compact unwind encoding is available. | |
418 | UNWIND_MODE_DWARF = 0x04000000, | |
419 | ||
420 | /// Mask for encoding the frame registers. | |
421 | UNWIND_BP_FRAME_REGISTERS = 0x00007FFF, | |
422 | ||
423 | /// Mask for encoding the frameless registers. | |
424 | UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF | |
425 | }; | |
426 | ||
427 | } // end CU namespace | |
428 | ||
223e47cc | 429 | class DarwinX86AsmBackend : public X86AsmBackend { |
1a4d82fc JJ |
430 | const MCRegisterInfo &MRI; |
431 | ||
432 | /// \brief Number of registers that can be saved in a compact unwind encoding. | |
433 | enum { CU_NUM_SAVED_REGS = 6 }; | |
434 | ||
435 | mutable unsigned SavedRegs[CU_NUM_SAVED_REGS]; | |
436 | bool Is64Bit; | |
437 | ||
438 | unsigned OffsetSize; ///< Offset of a "push" instruction. | |
439 | unsigned MoveInstrSize; ///< Size of a "move" instruction. | |
440 | unsigned StackDivide; ///< Amount to adjust stack size by. | |
441 | protected: | |
442 | /// \brief Size of a "push" instruction for the given register. | |
443 | unsigned PushInstrSize(unsigned Reg) const { | |
444 | switch (Reg) { | |
445 | case X86::EBX: | |
446 | case X86::ECX: | |
447 | case X86::EDX: | |
448 | case X86::EDI: | |
449 | case X86::ESI: | |
450 | case X86::EBP: | |
451 | case X86::RBX: | |
452 | case X86::RBP: | |
453 | return 1; | |
454 | case X86::R12: | |
455 | case X86::R13: | |
456 | case X86::R14: | |
457 | case X86::R15: | |
458 | return 2; | |
459 | } | |
460 | return 1; | |
461 | } | |
462 | ||
463 | /// \brief Implementation of algorithm to generate the compact unwind encoding | |
464 | /// for the CFI instructions. | |
465 | uint32_t | |
466 | generateCompactUnwindEncodingImpl(ArrayRef<MCCFIInstruction> Instrs) const { | |
467 | if (Instrs.empty()) return 0; | |
468 | ||
469 | // Reset the saved registers. | |
470 | unsigned SavedRegIdx = 0; | |
471 | memset(SavedRegs, 0, sizeof(SavedRegs)); | |
472 | ||
473 | bool HasFP = false; | |
474 | ||
475 | // Encode that we are using EBP/RBP as the frame pointer. | |
476 | uint32_t CompactUnwindEncoding = 0; | |
477 | ||
478 | unsigned SubtractInstrIdx = Is64Bit ? 3 : 2; | |
479 | unsigned InstrOffset = 0; | |
480 | unsigned StackAdjust = 0; | |
481 | unsigned StackSize = 0; | |
482 | unsigned PrevStackSize = 0; | |
483 | unsigned NumDefCFAOffsets = 0; | |
484 | ||
485 | for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { | |
486 | const MCCFIInstruction &Inst = Instrs[i]; | |
487 | ||
488 | switch (Inst.getOperation()) { | |
489 | default: | |
490 | // Any other CFI directives indicate a frame that we aren't prepared | |
491 | // to represent via compact unwind, so just bail out. | |
492 | return 0; | |
493 | case MCCFIInstruction::OpDefCfaRegister: { | |
494 | // Defines a frame pointer. E.g. | |
495 | // | |
496 | // movq %rsp, %rbp | |
497 | // L0: | |
498 | // .cfi_def_cfa_register %rbp | |
499 | // | |
500 | HasFP = true; | |
501 | assert(MRI.getLLVMRegNum(Inst.getRegister(), true) == | |
502 | (Is64Bit ? X86::RBP : X86::EBP) && "Invalid frame pointer!"); | |
503 | ||
504 | // Reset the counts. | |
505 | memset(SavedRegs, 0, sizeof(SavedRegs)); | |
506 | StackAdjust = 0; | |
507 | SavedRegIdx = 0; | |
508 | InstrOffset += MoveInstrSize; | |
509 | break; | |
510 | } | |
511 | case MCCFIInstruction::OpDefCfaOffset: { | |
512 | // Defines a new offset for the CFA. E.g. | |
513 | // | |
514 | // With frame: | |
85aaf69f | 515 | // |
1a4d82fc JJ |
516 | // pushq %rbp |
517 | // L0: | |
518 | // .cfi_def_cfa_offset 16 | |
519 | // | |
520 | // Without frame: | |
521 | // | |
522 | // subq $72, %rsp | |
523 | // L0: | |
524 | // .cfi_def_cfa_offset 80 | |
525 | // | |
526 | PrevStackSize = StackSize; | |
527 | StackSize = std::abs(Inst.getOffset()) / StackDivide; | |
528 | ++NumDefCFAOffsets; | |
529 | break; | |
530 | } | |
531 | case MCCFIInstruction::OpOffset: { | |
532 | // Defines a "push" of a callee-saved register. E.g. | |
533 | // | |
534 | // pushq %r15 | |
535 | // pushq %r14 | |
536 | // pushq %rbx | |
537 | // L0: | |
538 | // subq $120, %rsp | |
539 | // L1: | |
540 | // .cfi_offset %rbx, -40 | |
541 | // .cfi_offset %r14, -32 | |
542 | // .cfi_offset %r15, -24 | |
543 | // | |
544 | if (SavedRegIdx == CU_NUM_SAVED_REGS) | |
545 | // If there are too many saved registers, we cannot use a compact | |
546 | // unwind encoding. | |
547 | return CU::UNWIND_MODE_DWARF; | |
548 | ||
549 | unsigned Reg = MRI.getLLVMRegNum(Inst.getRegister(), true); | |
550 | SavedRegs[SavedRegIdx++] = Reg; | |
551 | StackAdjust += OffsetSize; | |
552 | InstrOffset += PushInstrSize(Reg); | |
553 | break; | |
554 | } | |
555 | } | |
556 | } | |
557 | ||
558 | StackAdjust /= StackDivide; | |
559 | ||
560 | if (HasFP) { | |
561 | if ((StackAdjust & 0xFF) != StackAdjust) | |
562 | // Offset was too big for a compact unwind encoding. | |
563 | return CU::UNWIND_MODE_DWARF; | |
564 | ||
565 | // Get the encoding of the saved registers when we have a frame pointer. | |
566 | uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame(); | |
567 | if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF; | |
568 | ||
569 | CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME; | |
570 | CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16; | |
571 | CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS; | |
572 | } else { | |
573 | // If the amount of the stack allocation is the size of a register, then | |
574 | // we "push" the RAX/EAX register onto the stack instead of adjusting the | |
575 | // stack pointer with a SUB instruction. We don't support the push of the | |
576 | // RAX/EAX register with compact unwind. So we check for that situation | |
577 | // here. | |
578 | if ((NumDefCFAOffsets == SavedRegIdx + 1 && | |
579 | StackSize - PrevStackSize == 1) || | |
580 | (Instrs.size() == 1 && NumDefCFAOffsets == 1 && StackSize == 2)) | |
581 | return CU::UNWIND_MODE_DWARF; | |
582 | ||
583 | SubtractInstrIdx += InstrOffset; | |
584 | ++StackAdjust; | |
585 | ||
586 | if ((StackSize & 0xFF) == StackSize) { | |
587 | // Frameless stack with a small stack size. | |
588 | CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD; | |
589 | ||
590 | // Encode the stack size. | |
591 | CompactUnwindEncoding |= (StackSize & 0xFF) << 16; | |
592 | } else { | |
593 | if ((StackAdjust & 0x7) != StackAdjust) | |
594 | // The extra stack adjustments are too big for us to handle. | |
595 | return CU::UNWIND_MODE_DWARF; | |
596 | ||
597 | // Frameless stack with an offset too large for us to encode compactly. | |
598 | CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND; | |
599 | ||
600 | // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP' | |
601 | // instruction. | |
602 | CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16; | |
603 | ||
604 | // Encode any extra stack stack adjustments (done via push | |
605 | // instructions). | |
606 | CompactUnwindEncoding |= (StackAdjust & 0x7) << 13; | |
607 | } | |
608 | ||
609 | // Encode the number of registers saved. (Reverse the list first.) | |
610 | std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]); | |
611 | CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10; | |
612 | ||
613 | // Get the encoding of the saved registers when we don't have a frame | |
614 | // pointer. | |
615 | uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx); | |
616 | if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF; | |
617 | ||
618 | // Encode the register encoding. | |
619 | CompactUnwindEncoding |= | |
620 | RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION; | |
621 | } | |
622 | ||
623 | return CompactUnwindEncoding; | |
624 | } | |
625 | ||
626 | private: | |
627 | /// \brief Get the compact unwind number for a given register. The number | |
628 | /// corresponds to the enum lists in compact_unwind_encoding.h. | |
629 | int getCompactUnwindRegNum(unsigned Reg) const { | |
630 | static const uint16_t CU32BitRegs[7] = { | |
631 | X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 | |
632 | }; | |
633 | static const uint16_t CU64BitRegs[] = { | |
634 | X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 | |
635 | }; | |
636 | const uint16_t *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs; | |
637 | for (int Idx = 1; *CURegs; ++CURegs, ++Idx) | |
638 | if (*CURegs == Reg) | |
639 | return Idx; | |
640 | ||
641 | return -1; | |
642 | } | |
643 | ||
644 | /// \brief Return the registers encoded for a compact encoding with a frame | |
645 | /// pointer. | |
646 | uint32_t encodeCompactUnwindRegistersWithFrame() const { | |
647 | // Encode the registers in the order they were saved --- 3-bits per | |
648 | // register. The list of saved registers is assumed to be in reverse | |
649 | // order. The registers are numbered from 1 to CU_NUM_SAVED_REGS. | |
650 | uint32_t RegEnc = 0; | |
651 | for (int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) { | |
652 | unsigned Reg = SavedRegs[i]; | |
653 | if (Reg == 0) break; | |
654 | ||
655 | int CURegNum = getCompactUnwindRegNum(Reg); | |
656 | if (CURegNum == -1) return ~0U; | |
657 | ||
658 | // Encode the 3-bit register number in order, skipping over 3-bits for | |
659 | // each register. | |
660 | RegEnc |= (CURegNum & 0x7) << (Idx++ * 3); | |
661 | } | |
662 | ||
663 | assert((RegEnc & 0x3FFFF) == RegEnc && | |
664 | "Invalid compact register encoding!"); | |
665 | return RegEnc; | |
666 | } | |
667 | ||
668 | /// \brief Create the permutation encoding used with frameless stacks. It is | |
669 | /// passed the number of registers to be saved and an array of the registers | |
670 | /// saved. | |
671 | uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned RegCount) const { | |
672 | // The saved registers are numbered from 1 to 6. In order to encode the | |
673 | // order in which they were saved, we re-number them according to their | |
674 | // place in the register order. The re-numbering is relative to the last | |
675 | // re-numbered register. E.g., if we have registers {6, 2, 4, 5} saved in | |
676 | // that order: | |
677 | // | |
678 | // Orig Re-Num | |
679 | // ---- ------ | |
680 | // 6 6 | |
681 | // 2 2 | |
682 | // 4 3 | |
683 | // 5 3 | |
684 | // | |
85aaf69f | 685 | for (unsigned i = 0; i < RegCount; ++i) { |
1a4d82fc JJ |
686 | int CUReg = getCompactUnwindRegNum(SavedRegs[i]); |
687 | if (CUReg == -1) return ~0U; | |
688 | SavedRegs[i] = CUReg; | |
689 | } | |
690 | ||
691 | // Reverse the list. | |
692 | std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]); | |
693 | ||
694 | uint32_t RenumRegs[CU_NUM_SAVED_REGS]; | |
695 | for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){ | |
696 | unsigned Countless = 0; | |
697 | for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j) | |
698 | if (SavedRegs[j] < SavedRegs[i]) | |
699 | ++Countless; | |
700 | ||
701 | RenumRegs[i] = SavedRegs[i] - Countless - 1; | |
702 | } | |
703 | ||
704 | // Take the renumbered values and encode them into a 10-bit number. | |
705 | uint32_t permutationEncoding = 0; | |
706 | switch (RegCount) { | |
707 | case 6: | |
708 | permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] | |
709 | + 6 * RenumRegs[2] + 2 * RenumRegs[3] | |
710 | + RenumRegs[4]; | |
711 | break; | |
712 | case 5: | |
713 | permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2] | |
714 | + 6 * RenumRegs[3] + 2 * RenumRegs[4] | |
715 | + RenumRegs[5]; | |
716 | break; | |
717 | case 4: | |
718 | permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3] | |
719 | + 3 * RenumRegs[4] + RenumRegs[5]; | |
720 | break; | |
721 | case 3: | |
722 | permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4] | |
723 | + RenumRegs[5]; | |
724 | break; | |
725 | case 2: | |
726 | permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5]; | |
727 | break; | |
728 | case 1: | |
729 | permutationEncoding |= RenumRegs[5]; | |
730 | break; | |
731 | } | |
732 | ||
733 | assert((permutationEncoding & 0x3FF) == permutationEncoding && | |
734 | "Invalid compact register encoding!"); | |
735 | return permutationEncoding; | |
736 | } | |
737 | ||
223e47cc | 738 | public: |
1a4d82fc JJ |
739 | DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI, StringRef CPU, |
740 | bool Is64Bit) | |
741 | : X86AsmBackend(T, CPU), MRI(MRI), Is64Bit(Is64Bit) { | |
742 | memset(SavedRegs, 0, sizeof(SavedRegs)); | |
743 | OffsetSize = Is64Bit ? 8 : 4; | |
744 | MoveInstrSize = Is64Bit ? 3 : 2; | |
745 | StackDivide = Is64Bit ? 8 : 4; | |
746 | } | |
223e47cc LB |
747 | }; |
748 | ||
749 | class DarwinX86_32AsmBackend : public DarwinX86AsmBackend { | |
750 | public: | |
1a4d82fc JJ |
751 | DarwinX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI, |
752 | StringRef CPU) | |
753 | : DarwinX86AsmBackend(T, MRI, CPU, false) {} | |
223e47cc | 754 | |
1a4d82fc | 755 | MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { |
223e47cc | 756 | return createX86MachObjectWriter(OS, /*Is64Bit=*/false, |
1a4d82fc JJ |
757 | MachO::CPU_TYPE_I386, |
758 | MachO::CPU_SUBTYPE_I386_ALL); | |
759 | } | |
760 | ||
761 | /// \brief Generate the compact unwind encoding for the CFI instructions. | |
762 | uint32_t generateCompactUnwindEncoding( | |
763 | ArrayRef<MCCFIInstruction> Instrs) const override { | |
764 | return generateCompactUnwindEncodingImpl(Instrs); | |
223e47cc LB |
765 | } |
766 | }; | |
767 | ||
768 | class DarwinX86_64AsmBackend : public DarwinX86AsmBackend { | |
1a4d82fc | 769 | const MachO::CPUSubTypeX86 Subtype; |
223e47cc | 770 | public: |
1a4d82fc JJ |
771 | DarwinX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI, |
772 | StringRef CPU, MachO::CPUSubTypeX86 st) | |
773 | : DarwinX86AsmBackend(T, MRI, CPU, true), Subtype(st) {} | |
223e47cc | 774 | |
1a4d82fc | 775 | MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { |
223e47cc | 776 | return createX86MachObjectWriter(OS, /*Is64Bit=*/true, |
1a4d82fc | 777 | MachO::CPU_TYPE_X86_64, Subtype); |
223e47cc LB |
778 | } |
779 | ||
1a4d82fc | 780 | bool doesSectionRequireSymbols(const MCSection &Section) const override { |
223e47cc LB |
781 | // Temporary labels in the string literals sections require symbols. The |
782 | // issue is that the x86_64 relocation format does not allow symbol + | |
783 | // offset, and so the linker does not have enough information to resolve the | |
784 | // access to the appropriate atom unless an external relocation is used. For | |
785 | // non-cstring sections, we expect the compiler to use a non-temporary label | |
786 | // for anything that could have an addend pointing outside the symbol. | |
787 | // | |
788 | // See <rdar://problem/4765733>. | |
789 | const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); | |
1a4d82fc | 790 | return SMO.getType() == MachO::S_CSTRING_LITERALS; |
223e47cc LB |
791 | } |
792 | ||
1a4d82fc JJ |
793 | /// \brief Generate the compact unwind encoding for the CFI instructions. |
794 | uint32_t generateCompactUnwindEncoding( | |
795 | ArrayRef<MCCFIInstruction> Instrs) const override { | |
796 | return generateCompactUnwindEncodingImpl(Instrs); | |
797 | } | |
223e47cc LB |
798 | }; |
799 | ||
800 | } // end anonymous namespace | |
801 | ||
1a4d82fc JJ |
802 | MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, |
803 | const MCRegisterInfo &MRI, | |
804 | StringRef TT, | |
805 | StringRef CPU) { | |
223e47cc LB |
806 | Triple TheTriple(TT); |
807 | ||
1a4d82fc JJ |
808 | if (TheTriple.isOSBinFormatMachO()) |
809 | return new DarwinX86_32AsmBackend(T, MRI, CPU); | |
223e47cc | 810 | |
1a4d82fc | 811 | if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) |
223e47cc LB |
812 | return new WindowsX86AsmBackend(T, false, CPU); |
813 | ||
814 | uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); | |
815 | return new ELFX86_32AsmBackend(T, OSABI, CPU); | |
816 | } | |
817 | ||
1a4d82fc JJ |
818 | MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, |
819 | const MCRegisterInfo &MRI, | |
820 | StringRef TT, | |
821 | StringRef CPU) { | |
223e47cc LB |
822 | Triple TheTriple(TT); |
823 | ||
1a4d82fc JJ |
824 | if (TheTriple.isOSBinFormatMachO()) { |
825 | MachO::CPUSubTypeX86 CS = | |
826 | StringSwitch<MachO::CPUSubTypeX86>(TheTriple.getArchName()) | |
827 | .Case("x86_64h", MachO::CPU_SUBTYPE_X86_64_H) | |
828 | .Default(MachO::CPU_SUBTYPE_X86_64_ALL); | |
829 | return new DarwinX86_64AsmBackend(T, MRI, CPU, CS); | |
830 | } | |
223e47cc | 831 | |
1a4d82fc | 832 | if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) |
223e47cc LB |
833 | return new WindowsX86AsmBackend(T, true, CPU); |
834 | ||
835 | uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); | |
1a4d82fc JJ |
836 | |
837 | if (TheTriple.getEnvironment() == Triple::GNUX32) | |
838 | return new ELFX86_X32AsmBackend(T, OSABI, CPU); | |
223e47cc LB |
839 | return new ELFX86_64AsmBackend(T, OSABI, CPU); |
840 | } |