llvm.org GIT mirror llvm / aef4035
fix a layering problem by moving the x86 implementation of AsmPrinter and InstLowering into libx86 and out of the asmprinter subdirectory. Now X86/AsmPrinter just depends on MC stuff, not all of codegen and LLVM IR. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108782 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
8 changed file(s) with 1456 addition(s) and 1456 deletion(s). Raw diff Collapse all Expand all
+0
-684
lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp less more
None //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a printer that converts from our internal representation
10 // of machine-dependent LLVM code to X86 machine code.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "X86AsmPrinter.h"
15 #include "X86ATTInstPrinter.h"
16 #include "X86IntelInstPrinter.h"
17 #include "X86MCInstLower.h"
18 #include "X86.h"
19 #include "X86COFFMachineModuleInfo.h"
20 #include "X86MachineFunctionInfo.h"
21 #include "X86TargetMachine.h"
22 #include "llvm/CallingConv.h"
23 #include "llvm/DerivedTypes.h"
24 #include "llvm/Module.h"
25 #include "llvm/Type.h"
26 #include "llvm/Assembly/Writer.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/MC/MCContext.h"
29 #include "llvm/MC/MCExpr.h"
30 #include "llvm/MC/MCSectionMachO.h"
31 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/MC/MCSymbol.h"
33 #include "llvm/CodeGen/MachineJumpTableInfo.h"
34 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
35 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
36 #include "llvm/Support/COFF.h"
37 #include "llvm/Support/ErrorHandling.h"
38 #include "llvm/Target/Mangler.h"
39 #include "llvm/Target/TargetOptions.h"
40 #include "llvm/Target/TargetRegistry.h"
41 #include "llvm/ADT/SmallString.h"
42 using namespace llvm;
43
44 //===----------------------------------------------------------------------===//
45 // Primitive Helper Functions.
46 //===----------------------------------------------------------------------===//
47
48 void X86AsmPrinter::PrintPICBaseSymbol(raw_ostream &O) const {
49 const TargetLowering *TLI = TM.getTargetLowering();
50 O << *static_cast(TLI)->getPICBaseSymbol(MF,
51 OutContext);
52 }
53
54 /// runOnMachineFunction - Emit the function body.
55 ///
56 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
57 SetupMachineFunction(MF);
58
59 if (Subtarget->isTargetCOFF()) {
60 bool Intrn = MF.getFunction()->hasInternalLinkage();
61 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym);
62 OutStreamer.EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC
63 : COFF::IMAGE_SYM_CLASS_EXTERNAL);
64 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
65 << COFF::SCT_COMPLEX_TYPE_SHIFT);
66 OutStreamer.EndCOFFSymbolDef();
67 }
68
69 // Have common code print out the function header with linkage info etc.
70 EmitFunctionHeader();
71
72 // Emit the rest of the function body.
73 EmitFunctionBody();
74
75 // We didn't modify anything.
76 return false;
77 }
78
79 /// printSymbolOperand - Print a raw symbol reference operand. This handles
80 /// jump tables, constant pools, global address and external symbols, all of
81 /// which print to a label with various suffixes for relocation types etc.
82 void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO,
83 raw_ostream &O) {
84 switch (MO.getType()) {
85 default: llvm_unreachable("unknown symbol type!");
86 case MachineOperand::MO_JumpTableIndex:
87 O << *GetJTISymbol(MO.getIndex());
88 break;
89 case MachineOperand::MO_ConstantPoolIndex:
90 O << *GetCPISymbol(MO.getIndex());
91 printOffset(MO.getOffset(), O);
92 break;
93 case MachineOperand::MO_GlobalAddress: {
94 const GlobalValue *GV = MO.getGlobal();
95
96 MCSymbol *GVSym;
97 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
98 GVSym = GetSymbolWithGlobalValueBase(GV, "$stub");
99 else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
100 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
101 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
102 GVSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
103 else
104 GVSym = Mang->getSymbol(GV);
105
106 // Handle dllimport linkage.
107 if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
108 GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName());
109
110 if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
111 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
112 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
113 MachineModuleInfoImpl::StubValueTy &StubSym =
114 MMI->getObjFileInfo().getGVStubEntry(Sym);
115 if (StubSym.getPointer() == 0)
116 StubSym = MachineModuleInfoImpl::
117 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
118 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
119 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
120 MachineModuleInfoImpl::StubValueTy &StubSym =
121 MMI->getObjFileInfo().getHiddenGVStubEntry(Sym);
122 if (StubSym.getPointer() == 0)
123 StubSym = MachineModuleInfoImpl::
124 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
125 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
126 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
127 MachineModuleInfoImpl::StubValueTy &StubSym =
128 MMI->getObjFileInfo().getFnStubEntry(Sym);
129 if (StubSym.getPointer() == 0)
130 StubSym = MachineModuleInfoImpl::
131 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
132 }
133
134 // If the name begins with a dollar-sign, enclose it in parens. We do this
135 // to avoid having it look like an integer immediate to the assembler.
136 if (GVSym->getName()[0] != '$')
137 O << *GVSym;
138 else
139 O << '(' << *GVSym << ')';
140 printOffset(MO.getOffset(), O);
141 break;
142 }
143 case MachineOperand::MO_ExternalSymbol: {
144 const MCSymbol *SymToPrint;
145 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
146 SmallString<128> TempNameStr;
147 TempNameStr += StringRef(MO.getSymbolName());
148 TempNameStr += StringRef("$stub");
149
150 MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
151 MachineModuleInfoImpl::StubValueTy &StubSym =
152 MMI->getObjFileInfo().getFnStubEntry(Sym);
153 if (StubSym.getPointer() == 0) {
154 TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end());
155 StubSym = MachineModuleInfoImpl::
156 StubValueTy(OutContext.GetOrCreateSymbol(TempNameStr.str()),
157 true);
158 }
159 SymToPrint = StubSym.getPointer();
160 } else {
161 SymToPrint = GetExternalSymbolSymbol(MO.getSymbolName());
162 }
163
164 // If the name begins with a dollar-sign, enclose it in parens. We do this
165 // to avoid having it look like an integer immediate to the assembler.
166 if (SymToPrint->getName()[0] != '$')
167 O << *SymToPrint;
168 else
169 O << '(' << *SymToPrint << '(';
170 break;
171 }
172 }
173
174 switch (MO.getTargetFlags()) {
175 default:
176 llvm_unreachable("Unknown target flag on GV operand");
177 case X86II::MO_NO_FLAG: // No flag.
178 break;
179 case X86II::MO_DARWIN_NONLAZY:
180 case X86II::MO_DLLIMPORT:
181 case X86II::MO_DARWIN_STUB:
182 // These affect the name of the symbol, not any suffix.
183 break;
184 case X86II::MO_GOT_ABSOLUTE_ADDRESS:
185 O << " + [.-";
186 PrintPICBaseSymbol(O);
187 O << ']';
188 break;
189 case X86II::MO_PIC_BASE_OFFSET:
190 case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
191 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
192 O << '-';
193 PrintPICBaseSymbol(O);
194 break;
195 case X86II::MO_TLSGD: O << "@TLSGD"; break;
196 case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break;
197 case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
198 case X86II::MO_TPOFF: O << "@TPOFF"; break;
199 case X86II::MO_NTPOFF: O << "@NTPOFF"; break;
200 case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break;
201 case X86II::MO_GOT: O << "@GOT"; break;
202 case X86II::MO_GOTOFF: O << "@GOTOFF"; break;
203 case X86II::MO_PLT: O << "@PLT"; break;
204 case X86II::MO_TLVP: O << "@TLVP"; break;
205 case X86II::MO_TLVP_PIC_BASE:
206 O << "@TLVP" << '-';
207 PrintPICBaseSymbol(O);
208 break;
209 }
210 }
211
212 /// print_pcrel_imm - This is used to print an immediate value that ends up
213 /// being encoded as a pc-relative value. These print slightly differently, for
214 /// example, a $ is not emitted.
215 void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo,
216 raw_ostream &O) {
217 const MachineOperand &MO = MI->getOperand(OpNo);
218 switch (MO.getType()) {
219 default: llvm_unreachable("Unknown pcrel immediate operand");
220 case MachineOperand::MO_Register:
221 // pc-relativeness was handled when computing the value in the reg.
222 printOperand(MI, OpNo, O);
223 return;
224 case MachineOperand::MO_Immediate:
225 O << MO.getImm();
226 return;
227 case MachineOperand::MO_MachineBasicBlock:
228 O << *MO.getMBB()->getSymbol();
229 return;
230 case MachineOperand::MO_GlobalAddress:
231 case MachineOperand::MO_ExternalSymbol:
232 printSymbolOperand(MO, O);
233 return;
234 }
235 }
236
237
238 void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
239 raw_ostream &O, const char *Modifier) {
240 const MachineOperand &MO = MI->getOperand(OpNo);
241 switch (MO.getType()) {
242 default: llvm_unreachable("unknown operand type!");
243 case MachineOperand::MO_Register: {
244 O << '%';
245 unsigned Reg = MO.getReg();
246 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
247 EVT VT = (strcmp(Modifier+6,"64") == 0) ?
248 MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
249 ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
250 Reg = getX86SubSuperRegister(Reg, VT);
251 }
252 O << X86ATTInstPrinter::getRegisterName(Reg);
253 return;
254 }
255
256 case MachineOperand::MO_Immediate:
257 O << '$' << MO.getImm();
258 return;
259
260 case MachineOperand::MO_JumpTableIndex:
261 case MachineOperand::MO_ConstantPoolIndex:
262 case MachineOperand::MO_GlobalAddress:
263 case MachineOperand::MO_ExternalSymbol: {
264 O << '$';
265 printSymbolOperand(MO, O);
266 break;
267 }
268 }
269 }
270
271 void X86AsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op,
272 raw_ostream &O) {
273 unsigned char value = MI->getOperand(Op).getImm();
274 assert(value <= 7 && "Invalid ssecc argument!");
275 switch (value) {
276 case 0: O << "eq"; break;
277 case 1: O << "lt"; break;
278 case 2: O << "le"; break;
279 case 3: O << "unord"; break;
280 case 4: O << "neq"; break;
281 case 5: O << "nlt"; break;
282 case 6: O << "nle"; break;
283 case 7: O << "ord"; break;
284 }
285 }
286
287 void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
288 raw_ostream &O, const char *Modifier) {
289 const MachineOperand &BaseReg = MI->getOperand(Op);
290 const MachineOperand &IndexReg = MI->getOperand(Op+2);
291 const MachineOperand &DispSpec = MI->getOperand(Op+3);
292
293 // If we really don't want to print out (rip), don't.
294 bool HasBaseReg = BaseReg.getReg() != 0;
295 if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") &&
296 BaseReg.getReg() == X86::RIP)
297 HasBaseReg = false;
298
299 // HasParenPart - True if we will print out the () part of the mem ref.
300 bool HasParenPart = IndexReg.getReg() || HasBaseReg;
301
302 if (DispSpec.isImm()) {
303 int DispVal = DispSpec.getImm();
304 if (DispVal || !HasParenPart)
305 O << DispVal;
306 } else {
307 assert(DispSpec.isGlobal() || DispSpec.isCPI() ||
308 DispSpec.isJTI() || DispSpec.isSymbol());
309 printSymbolOperand(MI->getOperand(Op+3), O);
310 }
311
312 if (HasParenPart) {
313 assert(IndexReg.getReg() != X86::ESP &&
314 "X86 doesn't allow scaling by ESP");
315
316 O << '(';
317 if (HasBaseReg)
318 printOperand(MI, Op, O, Modifier);
319
320 if (IndexReg.getReg()) {
321 O << ',';
322 printOperand(MI, Op+2, O, Modifier);
323 unsigned ScaleVal = MI->getOperand(Op+1).getImm();
324 if (ScaleVal != 1)
325 O << ',' << ScaleVal;
326 }
327 O << ')';
328 }
329 }
330
331 void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
332 raw_ostream &O, const char *Modifier) {
333 assert(isMem(MI, Op) && "Invalid memory reference!");
334 const MachineOperand &Segment = MI->getOperand(Op+4);
335 if (Segment.getReg()) {
336 printOperand(MI, Op+4, O, Modifier);
337 O << ':';
338 }
339 printLeaMemReference(MI, Op, O, Modifier);
340 }
341
342 void X86AsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op,
343 raw_ostream &O) {
344 PrintPICBaseSymbol(O);
345 O << '\n';
346 PrintPICBaseSymbol(O);
347 O << ':';
348 }
349
350 bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode,
351 raw_ostream &O) {
352 unsigned Reg = MO.getReg();
353 switch (Mode) {
354 default: return true; // Unknown mode.
355 case 'b': // Print QImode register
356 Reg = getX86SubSuperRegister(Reg, MVT::i8);
357 break;
358 case 'h': // Print QImode high register
359 Reg = getX86SubSuperRegister(Reg, MVT::i8, true);
360 break;
361 case 'w': // Print HImode register
362 Reg = getX86SubSuperRegister(Reg, MVT::i16);
363 break;
364 case 'k': // Print SImode register
365 Reg = getX86SubSuperRegister(Reg, MVT::i32);
366 break;
367 case 'q': // Print DImode register
368 Reg = getX86SubSuperRegister(Reg, MVT::i64);
369 break;
370 }
371
372 O << '%' << X86ATTInstPrinter::getRegisterName(Reg);
373 return false;
374 }
375
376 /// PrintAsmOperand - Print out an operand for an inline asm expression.
377 ///
378 bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
379 unsigned AsmVariant,
380 const char *ExtraCode, raw_ostream &O) {
381 // Does this asm operand have a single letter operand modifier?
382 if (ExtraCode && ExtraCode[0]) {
383 if (ExtraCode[1] != 0) return true; // Unknown modifier.
384
385 const MachineOperand &MO = MI->getOperand(OpNo);
386
387 switch (ExtraCode[0]) {
388 default: return true; // Unknown modifier.
389 case 'a': // This is an address. Currently only 'i' and 'r' are expected.
390 if (MO.isImm()) {
391 O << MO.getImm();
392 return false;
393 }
394 if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) {
395 printSymbolOperand(MO, O);
396 if (Subtarget->isPICStyleRIPRel())
397 O << "(%rip)";
398 return false;
399 }
400 if (MO.isReg()) {
401 O << '(';
402 printOperand(MI, OpNo, O);
403 O << ')';
404 return false;
405 }
406 return true;
407
408 case 'c': // Don't print "$" before a global var name or constant.
409 if (MO.isImm())
410 O << MO.getImm();
411 else if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol())
412 printSymbolOperand(MO, O);
413 else
414 printOperand(MI, OpNo, O);
415 return false;
416
417 case 'A': // Print '*' before a register (it must be a register)
418 if (MO.isReg()) {
419 O << '*';
420 printOperand(MI, OpNo, O);
421 return false;
422 }
423 return true;
424
425 case 'b': // Print QImode register
426 case 'h': // Print QImode high register
427 case 'w': // Print HImode register
428 case 'k': // Print SImode register
429 case 'q': // Print DImode register
430 if (MO.isReg())
431 return printAsmMRegister(MO, ExtraCode[0], O);
432 printOperand(MI, OpNo, O);
433 return false;
434
435 case 'P': // This is the operand of a call, treat specially.
436 print_pcrel_imm(MI, OpNo, O);
437 return false;
438
439 case 'n': // Negate the immediate or print a '-' before the operand.
440 // Note: this is a temporary solution. It should be handled target
441 // independently as part of the 'MC' work.
442 if (MO.isImm()) {
443 O << -MO.getImm();
444 return false;
445 }
446 O << '-';
447 }
448 }
449
450 printOperand(MI, OpNo, O);
451 return false;
452 }
453
454 bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
455 unsigned OpNo, unsigned AsmVariant,
456 const char *ExtraCode,
457 raw_ostream &O) {
458 if (ExtraCode && ExtraCode[0]) {
459 if (ExtraCode[1] != 0) return true; // Unknown modifier.
460
461 switch (ExtraCode[0]) {
462 default: return true; // Unknown modifier.
463 case 'b': // Print QImode register
464 case 'h': // Print QImode high register
465 case 'w': // Print HImode register
466 case 'k': // Print SImode register
467 case 'q': // Print SImode register
468 // These only apply to registers, ignore on mem.
469 break;
470 case 'P': // Don't print @PLT, but do print as memory.
471 printMemReference(MI, OpNo, O, "no-rip");
472 return false;
473 }
474 }
475 printMemReference(MI, OpNo, O);
476 return false;
477 }
478
479 void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
480 if (Subtarget->isTargetDarwin())
481 OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
482 }
483
484
485 void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
486 if (Subtarget->isTargetDarwin()) {
487 // All darwin targets use mach-o.
488 MachineModuleInfoMachO &MMIMacho =
489 MMI->getObjFileInfo();
490
491 // Output stubs for dynamically-linked functions.
492 MachineModuleInfoMachO::SymbolListTy Stubs;
493
494 Stubs = MMIMacho.GetFnStubList();
495 if (!Stubs.empty()) {
496 const MCSection *TheSection =
497 OutContext.getMachOSection("__IMPORT", "__jump_table",
498 MCSectionMachO::S_SYMBOL_STUBS |
499 MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE |
500 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
501 5, SectionKind::getMetadata());
502 OutStreamer.SwitchSection(TheSection);
503
504 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
505 // L_foo$stub:
506 OutStreamer.EmitLabel(Stubs[i].first);
507 // .indirect_symbol _foo
508 OutStreamer.EmitSymbolAttribute(Stubs[i].second.getPointer(),
509 MCSA_IndirectSymbol);
510 // hlt; hlt; hlt; hlt; hlt hlt = 0xf4 = -12.
511 const char HltInsts[] = { -12, -12, -12, -12, -12 };
512 OutStreamer.EmitBytes(StringRef(HltInsts, 5), 0/*addrspace*/);
513 }
514
515 Stubs.clear();
516 OutStreamer.AddBlankLine();
517 }
518
519 // Output stubs for external and common global variables.
520 Stubs = MMIMacho.GetGVStubList();
521 if (!Stubs.empty()) {
522 const MCSection *TheSection =
523 OutContext.getMachOSection("__IMPORT", "__pointers",
524 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
525 SectionKind::getMetadata());
526 OutStreamer.SwitchSection(TheSection);
527
528 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
529 // L_foo$non_lazy_ptr:
530 OutStreamer.EmitLabel(Stubs[i].first);
531 // .indirect_symbol _foo
532 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
533 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),
534 MCSA_IndirectSymbol);
535 // .long 0
536 if (MCSym.getInt())
537 // External to current translation unit.
538 OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
539 else
540 // Internal to current translation unit.
541 //
542 // When we place the LSDA into the TEXT section, the type info
543 // pointers need to be indirect and pc-rel. We accomplish this by
544 // using NLPs. However, sometimes the types are local to the file. So
545 // we need to fill in the value for the NLP in those cases.
546 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
547 OutContext),
548 4/*size*/, 0/*addrspace*/);
549 }
550 Stubs.clear();
551 OutStreamer.AddBlankLine();
552 }
553
554 Stubs = MMIMacho.GetHiddenGVStubList();
555 if (!Stubs.empty()) {
556 OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
557 EmitAlignment(2);
558
559 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
560 // L_foo$non_lazy_ptr:
561 OutStreamer.EmitLabel(Stubs[i].first);
562 // .long _foo
563 OutStreamer.EmitValue(MCSymbolRefExpr::
564 Create(Stubs[i].second.getPointer(),
565 OutContext),
566 4/*size*/, 0/*addrspace*/);
567 }
568 Stubs.clear();
569 OutStreamer.AddBlankLine();
570 }
571
572 // Funny Darwin hack: This flag tells the linker that no global symbols
573 // contain code that falls through to other global symbols (e.g. the obvious
574 // implementation of multiple entry points). If this doesn't occur, the
575 // linker can safely perform dead code stripping. Since LLVM never
576 // generates code that does this, it is always safe to set.
577 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
578 }
579
580 if (Subtarget->isTargetCOFF()) {
581 X86COFFMachineModuleInfo &COFFMMI =
582 MMI->getObjFileInfo();
583
584 // Emit type information for external functions
585 typedef X86COFFMachineModuleInfo::externals_iterator externals_iterator;
586 for (externals_iterator I = COFFMMI.externals_begin(),
587 E = COFFMMI.externals_end();
588 I != E; ++I) {
589 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym);
590 OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL);
591 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
592 << COFF::SCT_COMPLEX_TYPE_SHIFT);
593 OutStreamer.EndCOFFSymbolDef();
594 }
595
596 // Necessary for dllexport support
597 std::vector DLLExportedFns, DLLExportedGlobals;
598
599 const TargetLoweringObjectFileCOFF &TLOFCOFF =
600 static_cast(getObjFileLowering());
601
602 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
603 if (I->hasDLLExportLinkage())
604 DLLExportedFns.push_back(Mang->getSymbol(I));
605
606 for (Module::const_global_iterator I = M.global_begin(),
607 E = M.global_end(); I != E; ++I)
608 if (I->hasDLLExportLinkage())
609 DLLExportedGlobals.push_back(Mang->getSymbol(I));
610
611 // Output linker support code for dllexported globals on windows.
612 if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
613 OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection());
614 SmallString<128> name;
615 for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) {
616 if (Subtarget->isTargetWindows())
617 name = " /EXPORT:";
618 else
619 name = " -export:";
620 name += DLLExportedGlobals[i]->getName();
621 if (Subtarget->isTargetWindows())
622 name += ",DATA";
623 else
624 name += ",data";
625 OutStreamer.EmitBytes(name, 0);
626 }
627
628 for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i) {
629 if (Subtarget->isTargetWindows())
630 name = " /EXPORT:";
631 else
632 name = " -export:";
633 name += DLLExportedFns[i]->getName();
634 OutStreamer.EmitBytes(name, 0);
635 }
636 }
637 }
638
639 if (Subtarget->isTargetELF()) {
640 const TargetLoweringObjectFileELF &TLOFELF =
641 static_cast(getObjFileLowering());
642
643 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo();
644
645 // Output stubs for external and common global variables.
646 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
647 if (!Stubs.empty()) {
648 OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
649 const TargetData *TD = TM.getTargetData();
650
651 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
652 OutStreamer.EmitLabel(Stubs[i].first);
653 OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
654 TD->getPointerSize(), 0);
655 }
656 Stubs.clear();
657 }
658 }
659 }
660
661
662 //===----------------------------------------------------------------------===//
663 // Target Registry Stuff
664 //===----------------------------------------------------------------------===//
665
666 static MCInstPrinter *createX86MCInstPrinter(const Target &T,
667 unsigned SyntaxVariant,
668 const MCAsmInfo &MAI) {
669 if (SyntaxVariant == 0)
670 return new X86ATTInstPrinter(MAI);
671 if (SyntaxVariant == 1)
672 return new X86IntelInstPrinter(MAI);
673 return 0;
674 }
675
676 // Force static initialization.
677 extern "C" void LLVMInitializeX86AsmPrinter() {
678 RegisterAsmPrinter X(TheX86_32Target);
679 RegisterAsmPrinter Y(TheX86_64Target);
680
681 TargetRegistry::RegisterMCInstPrinter(TheX86_32Target,createX86MCInstPrinter);
682 TargetRegistry::RegisterMCInstPrinter(TheX86_64Target,createX86MCInstPrinter);
683 }
+0
-89
lib/Target/X86/AsmPrinter/X86AsmPrinter.h less more
None //===-- X86AsmPrinter.h - Convert X86 LLVM code to assembly -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // AT&T assembly code printer class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef X86ASMPRINTER_H
14 #define X86ASMPRINTER_H
15
16 #include "../X86.h"
17 #include "../X86MachineFunctionInfo.h"
18 #include "../X86TargetMachine.h"
19 #include "llvm/ADT/StringSet.h"
20 #include "llvm/CodeGen/AsmPrinter.h"
21 #include "llvm/CodeGen/MachineModuleInfo.h"
22 #include "llvm/CodeGen/ValueTypes.h"
23 #include "llvm/Support/Compiler.h"
24
25 namespace llvm {
26
27 class MachineJumpTableInfo;
28 class MCContext;
29 class MCInst;
30 class MCStreamer;
31 class MCSymbol;
32
33 class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
34 const X86Subtarget *Subtarget;
35 public:
36 explicit X86AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
37 : AsmPrinter(TM, Streamer) {
38 Subtarget = &TM.getSubtarget();
39 }
40
41 virtual const char *getPassName() const {
42 return "X86 AT&T-Style Assembly Printer";
43 }
44
45 const X86Subtarget &getSubtarget() const { return *Subtarget; }
46
47 virtual void EmitStartOfAsmFile(Module &M);
48
49 virtual void EmitEndOfAsmFile(Module &M);
50
51 virtual void EmitInstruction(const MachineInstr *MI);
52
53 void printSymbolOperand(const MachineOperand &MO, raw_ostream &O);
54
55 // These methods are used by the tablegen'erated instruction printer.
56 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
57 const char *Modifier = 0);
58 void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
59
60 bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O);
61 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
62 unsigned AsmVariant, const char *ExtraCode,
63 raw_ostream &OS);
64 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
65 unsigned AsmVariant, const char *ExtraCode,
66 raw_ostream &OS);
67
68 void printMachineInstruction(const MachineInstr *MI);
69 void printSSECC(const MachineInstr *MI, unsigned Op, raw_ostream &O);
70 void printMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O,
71 const char *Modifier=NULL);
72 void printLeaMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O,
73 const char *Modifier=NULL);
74
75 void printPICLabel(const MachineInstr *MI, unsigned Op, raw_ostream &O);
76
77 void PrintPICBaseSymbol(raw_ostream &O) const;
78
79 bool runOnMachineFunction(MachineFunction &F);
80
81 void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
82
83 MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
84 };
85
86 } // end namespace llvm
87
88 #endif
+0
-632
lib/Target/X86/AsmPrinter/X86MCInstLower.cpp less more
None //===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains code to lower X86 MachineInstrs to their corresponding
10 // MCInst records.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "X86MCInstLower.h"
15 #include "X86AsmPrinter.h"
16 #include "X86COFFMachineModuleInfo.h"
17 #include "X86MCAsmInfo.h"
18 #include "llvm/Analysis/DebugInfo.h"
19 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/Target/Mangler.h"
26 #include "llvm/Support/FormattedStream.h"
27 #include "llvm/ADT/SmallString.h"
28 #include "llvm/Type.h"
29 using namespace llvm;
30
31
32 const X86Subtarget &X86MCInstLower::getSubtarget() const {
33 return AsmPrinter.getSubtarget();
34 }
35
36 MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
37 assert(getSubtarget().isTargetDarwin() &&"Can only get MachO info on darwin");
38 return AsmPrinter.MMI->getObjFileInfo();
39 }
40
41
42 MCSymbol *X86MCInstLower::GetPICBaseSymbol() const {
43 const TargetLowering *TLI = AsmPrinter.TM.getTargetLowering();
44 return static_cast(TLI)->
45 getPICBaseSymbol(AsmPrinter.MF, Ctx);
46 }
47
48 /// GetSymbolFromOperand - Lower an MO_GlobalAddress or MO_ExternalSymbol
49 /// operand to an MCSymbol.
50 MCSymbol *X86MCInstLower::
51 GetSymbolFromOperand(const MachineOperand &MO) const {
52 assert((MO.isGlobal() || MO.isSymbol()) && "Isn't a symbol reference");
53
54 SmallString<128> Name;
55
56 if (!MO.isGlobal()) {
57 assert(MO.isSymbol());
58 Name += AsmPrinter.MAI->getGlobalPrefix();
59 Name += MO.getSymbolName();
60 } else {
61 const GlobalValue *GV = MO.getGlobal();
62 bool isImplicitlyPrivate = false;
63 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB ||
64 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
65 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
66 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
67 isImplicitlyPrivate = true;
68
69 Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
70 }
71
72 // If the target flags on the operand changes the name of the symbol, do that
73 // before we return the symbol.
74 switch (MO.getTargetFlags()) {
75 default: break;
76 case X86II::MO_DLLIMPORT: {
77 // Handle dllimport linkage.
78 const char *Prefix = "__imp_";
79 Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix));
80 break;
81 }
82 case X86II::MO_DARWIN_NONLAZY:
83 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: {
84 Name += "$non_lazy_ptr";
85 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
86
87 MachineModuleInfoImpl::StubValueTy &StubSym =
88 getMachOMMI().getGVStubEntry(Sym);
89 if (StubSym.getPointer() == 0) {
90 assert(MO.isGlobal() && "Extern symbol not handled yet");
91 StubSym =
92 MachineModuleInfoImpl::
93 StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()),
94 !MO.getGlobal()->hasInternalLinkage());
95 }
96 return Sym;
97 }
98 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
99 Name += "$non_lazy_ptr";
100 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
101 MachineModuleInfoImpl::StubValueTy &StubSym =
102 getMachOMMI().getHiddenGVStubEntry(Sym);
103 if (StubSym.getPointer() == 0) {
104 assert(MO.isGlobal() && "Extern symbol not handled yet");
105 StubSym =
106 MachineModuleInfoImpl::
107 StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()),
108 !MO.getGlobal()->hasInternalLinkage());
109 }
110 return Sym;
111 }
112 case X86II::MO_DARWIN_STUB: {
113 Name += "$stub";
114 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
115 MachineModuleInfoImpl::StubValueTy &StubSym =
116 getMachOMMI().getFnStubEntry(Sym);
117 if (StubSym.getPointer())
118 return Sym;
119
120 if (MO.isGlobal()) {
121 StubSym =
122 MachineModuleInfoImpl::
123 StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()),
124 !MO.getGlobal()->hasInternalLinkage());
125 } else {
126 Name.erase(Name.end()-5, Name.end());
127 StubSym =
128 MachineModuleInfoImpl::
129 StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false);
130 }
131 return Sym;
132 }
133 }
134
135 return Ctx.GetOrCreateSymbol(Name.str());
136 }
137
138 MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
139 MCSymbol *Sym) const {
140 // FIXME: We would like an efficient form for this, so we don't have to do a
141 // lot of extra uniquing.
142 const MCExpr *Expr = 0;
143 MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
144
145 switch (MO.getTargetFlags()) {
146 default: llvm_unreachable("Unknown target flag on GV operand");
147 case X86II::MO_NO_FLAG: // No flag.
148 // These affect the name of the symbol, not any suffix.
149 case X86II::MO_DARWIN_NONLAZY:
150 case X86II::MO_DLLIMPORT:
151 case X86II::MO_DARWIN_STUB:
152 break;
153
154 case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break;
155 case X86II::MO_TLVP_PIC_BASE:
156 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
157 // Subtract the pic base.
158 Expr = MCBinaryExpr::CreateSub(Expr,
159 MCSymbolRefExpr::Create(GetPICBaseSymbol(),
160 Ctx),
161 Ctx);
162 break;
163 case X86II::MO_TLSGD: RefKind = MCSymbolRefExpr::VK_TLSGD; break;
164 case X86II::MO_GOTTPOFF: RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break;
165 case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break;
166 case X86II::MO_TPOFF: RefKind = MCSymbolRefExpr::VK_TPOFF; break;
167 case X86II::MO_NTPOFF: RefKind = MCSymbolRefExpr::VK_NTPOFF; break;
168 case X86II::MO_GOTPCREL: RefKind = MCSymbolRefExpr::VK_GOTPCREL; break;
169 case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break;
170 case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break;
171 case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break;
172 case X86II::MO_PIC_BASE_OFFSET:
173 case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
174 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
175 Expr = MCSymbolRefExpr::Create(Sym, Ctx);
176 // Subtract the pic base.
177 Expr = MCBinaryExpr::CreateSub(Expr,
178 MCSymbolRefExpr::Create(GetPICBaseSymbol(), Ctx),
179 Ctx);
180 if (MO.isJTI() && AsmPrinter.MAI->hasSetDirective()) {
181 // If .set directive is supported, use it to reduce the number of
182 // relocations the assembler will generate for differences between
183 // local labels. This is only safe when the symbols are in the same
184 // section so we are restricting it to jumptable references.
185 MCSymbol *Label = Ctx.CreateTempSymbol();
186 AsmPrinter.OutStreamer.EmitAssignment(Label, Expr);
187 Expr = MCSymbolRefExpr::Create(Label, Ctx);
188 }
189 break;
190 }
191
192 if (Expr == 0)
193 Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx);
194
195 if (!MO.isJTI() && MO.getOffset())
196 Expr = MCBinaryExpr::CreateAdd(Expr,
197 MCConstantExpr::Create(MO.getOffset(), Ctx),
198 Ctx);
199 return MCOperand::CreateExpr(Expr);
200 }
201
202
203
204 static void lower_subreg32(MCInst *MI, unsigned OpNo) {
205 // Convert registers in the addr mode according to subreg32.
206 unsigned Reg = MI->getOperand(OpNo).getReg();
207 if (Reg != 0)
208 MI->getOperand(OpNo).setReg(getX86SubSuperRegister(Reg, MVT::i32));
209 }
210
211 static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) {
212 // Convert registers in the addr mode according to subreg64.
213 for (unsigned i = 0; i != 4; ++i) {
214 if (!MI->getOperand(OpNo+i).isReg()) continue;
215
216 unsigned Reg = MI->getOperand(OpNo+i).getReg();
217 if (Reg == 0) continue;
218
219 MI->getOperand(OpNo+i).setReg(getX86SubSuperRegister(Reg, MVT::i64));
220 }
221 }
222
223 /// LowerSubReg32_Op0 - Things like MOVZX16rr8 -> MOVZX32rr8.
224 static void LowerSubReg32_Op0(MCInst &OutMI, unsigned NewOpc) {
225 OutMI.setOpcode(NewOpc);
226 lower_subreg32(&OutMI, 0);
227 }
228 /// LowerUnaryToTwoAddr - R = setb -> R = sbb R, R
229 static void LowerUnaryToTwoAddr(MCInst &OutMI, unsigned NewOpc) {
230 OutMI.setOpcode(NewOpc);
231 OutMI.addOperand(OutMI.getOperand(0));
232 OutMI.addOperand(OutMI.getOperand(0));
233 }
234
235 /// \brief Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with
236 /// a short fixed-register form.
237 static void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) {
238 unsigned ImmOp = Inst.getNumOperands() - 1;
239 assert(Inst.getOperand(0).isReg() && Inst.getOperand(ImmOp).isImm() &&
240 ((Inst.getNumOperands() == 3 && Inst.getOperand(1).isReg() &&
241 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) ||
242 Inst.getNumOperands() == 2) && "Unexpected instruction!");
243
244 // Check whether the destination register can be fixed.
245 unsigned Reg = Inst.getOperand(0).getReg();
246 if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
247 return;
248
249 // If so, rewrite the instruction.
250 MCOperand Saved = Inst.getOperand(ImmOp);
251 Inst = MCInst();
252 Inst.setOpcode(Opcode);
253 Inst.addOperand(Saved);
254 }
255
256 /// \brief Simplify things like MOV32rm to MOV32o32a.
257 static void SimplifyShortMoveForm(MCInst &Inst, unsigned Opcode) {
258 bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg();
259 unsigned AddrBase = IsStore;
260 unsigned RegOp = IsStore ? 0 : 5;
261 unsigned AddrOp = AddrBase + 3;
262 assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() &&
263 Inst.getOperand(AddrBase + 0).isReg() && // base
264 Inst.getOperand(AddrBase + 1).isImm() && // scale
265 Inst.getOperand(AddrBase + 2).isReg() && // index register
266 (Inst.getOperand(AddrOp).isExpr() || // address
267 Inst.getOperand(AddrOp).isImm())&&
268 Inst.getOperand(AddrBase + 4).isReg() && // segment
269 "Unexpected instruction!");
270
271 // Check whether the destination register can be fixed.
272 unsigned Reg = Inst.getOperand(RegOp).getReg();
273 if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
274 return;
275
276 // Check whether this is an absolute address.
277 // FIXME: We know TLVP symbol refs aren't, but there should be a better way
278 // to do this here.
279 bool Absolute = true;
280 if (Inst.getOperand(AddrOp).isExpr()) {
281 const MCExpr *MCE = Inst.getOperand(AddrOp).getExpr();
282 if (const MCSymbolRefExpr *SRE = dyn_cast(MCE))
283 if (SRE->getKind() == MCSymbolRefExpr::VK_TLVP)
284 Absolute = false;
285 }
286
287 if (Absolute &&
288 (Inst.getOperand(AddrBase + 0).getReg() != 0 ||
289 Inst.getOperand(AddrBase + 2).getReg() != 0 ||
290 Inst.getOperand(AddrBase + 4).getReg() != 0 ||
291 Inst.getOperand(AddrBase + 1).getImm() != 1))
292 return;
293
294 // If so, rewrite the instruction.
295 MCOperand Saved = Inst.getOperand(AddrOp);
296 Inst = MCInst();
297 Inst.setOpcode(Opcode);
298 Inst.addOperand(Saved);
299 }
300
301 void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
302 OutMI.setOpcode(MI->getOpcode());
303
304 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
305 const MachineOperand &MO = MI->getOperand(i);
306
307 MCOperand MCOp;
308 switch (MO.getType()) {
309 default:
310 MI->dump();
311 llvm_unreachable("unknown operand type");
312 case MachineOperand::MO_Register:
313 // Ignore all implicit register operands.
314 if (MO.isImplicit()) continue;
315 MCOp = MCOperand::CreateReg(MO.getReg());
316 break;
317 case MachineOperand::MO_Immediate:
318 MCOp = MCOperand::CreateImm(MO.getImm());
319 break;
320 case MachineOperand::MO_MachineBasicBlock:
321 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
322 MO.getMBB()->getSymbol(), Ctx));
323 break;
324 case MachineOperand::MO_GlobalAddress:
325 MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
326 break;
327 case MachineOperand::MO_ExternalSymbol:
328 MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
329 break;
330 case MachineOperand::MO_JumpTableIndex:
331 MCOp = LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));
332 break;
333 case MachineOperand::MO_ConstantPoolIndex:
334 MCOp = LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));
335 break;
336 case MachineOperand::MO_BlockAddress:
337 MCOp = LowerSymbolOperand(MO,
338 AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));
339 break;
340 }
341
342 OutMI.addOperand(MCOp);
343 }
344
345 // Handle a few special cases to eliminate operand modifiers.
346 switch (OutMI.getOpcode()) {
347 case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand.
348 lower_lea64_32mem(&OutMI, 1);
349 // FALL THROUGH.
350 case X86::LEA64r:
351 case X86::LEA16r:
352 case X86::LEA32r:
353 // LEA should have a segment register, but it must be empty.
354 assert(OutMI.getNumOperands() == 1+X86::AddrNumOperands &&
355 "Unexpected # of LEA operands");
356 assert(OutMI.getOperand(1+X86::AddrSegmentReg).getReg() == 0 &&
357 "LEA has segment specified!");
358 break;
359 case X86::MOVZX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break;
360 case X86::MOVZX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break;
361 case X86::MOVSX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rr8); break;
362 case X86::MOVSX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rm8); break;
363 case X86::MOVZX64rr32: LowerSubReg32_Op0(OutMI, X86::MOV32rr); break;
364 case X86::MOVZX64rm32: LowerSubReg32_Op0(OutMI, X86::MOV32rm); break;
365 case X86::MOV64ri64i32: LowerSubReg32_Op0(OutMI, X86::MOV32ri); break;
366 case X86::MOVZX64rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break;
367 case X86::MOVZX64rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break;
368 case X86::MOVZX64rr16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr16); break;
369 case X86::MOVZX64rm16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm16); break;
370 case X86::SETB_C8r: LowerUnaryToTwoAddr(OutMI, X86::SBB8rr); break;
371 case X86::SETB_C16r: LowerUnaryToTwoAddr(OutMI, X86::SBB16rr); break;
372 case X86::SETB_C32r: LowerUnaryToTwoAddr(OutMI, X86::SBB32rr); break;
373 case X86::SETB_C64r: LowerUnaryToTwoAddr(OutMI, X86::SBB64rr); break;
374 case X86::MOV8r0: LowerUnaryToTwoAddr(OutMI, X86::XOR8rr); break;
375 case X86::MOV32r0: LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); break;
376 case X86::MMX_V_SET0: LowerUnaryToTwoAddr(OutMI, X86::MMX_PXORrr); break;
377 case X86::MMX_V_SETALLONES:
378 LowerUnaryToTwoAddr(OutMI, X86::MMX_PCMPEQDrr); break;
379 case X86::FsFLD0SS: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break;
380 case X86::FsFLD0SD: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break;
381 case X86::V_SET0PS: LowerUnaryToTwoAddr(OutMI, X86::XORPSrr); break;
382 case X86::V_SET0PD: LowerUnaryToTwoAddr(OutMI, X86::XORPDrr); break;
383 case X86::V_SET0PI: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break;
384 case X86::V_SETALLONES: LowerUnaryToTwoAddr(OutMI, X86::PCMPEQDrr); break;
385
386 case X86::MOV16r0:
387 LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV16r0 -> MOV32r0
388 LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr
389 break;
390 case X86::MOV64r0:
391 LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV64r0 -> MOV32r0
392 LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr
393 break;
394
395 // TAILJMPr64, CALL64r, CALL64pcrel32 - These instructions have
396 // register inputs modeled as normal uses instead of implicit uses. As such,
397 // truncate off all but the first operand (the callee). FIXME: Change isel.
398 case X86::TAILJMPr64:
399 case X86::CALL64r:
400 case X86::CALL64pcrel32: {
401 unsigned Opcode = OutMI.getOpcode();
402 MCOperand Saved = OutMI.getOperand(0);
403 OutMI = MCInst();
404 OutMI.setOpcode(Opcode);
405 OutMI.addOperand(Saved);
406 break;
407 }
408
409 // TAILJMPd, TAILJMPd64 - Lower to the correct jump instructions.
410 case X86::TAILJMPr:
411 case X86::TAILJMPd:
412 case X86::TAILJMPd64: {
413 unsigned Opcode;
414 switch (OutMI.getOpcode()) {
415 default: assert(0 && "Invalid opcode");
416 case X86::TAILJMPr: Opcode = X86::JMP32r; break;
417 case X86::TAILJMPd:
418 case X86::TAILJMPd64: Opcode = X86::JMP_1; break;
419 }
420
421 MCOperand Saved = OutMI.getOperand(0);
422 OutMI = MCInst();
423 OutMI.setOpcode(Opcode);
424 OutMI.addOperand(Saved);
425 break;
426 }
427
428 // The assembler backend wants to see branches in their small form and relax
429 // them to their large form. The JIT can only handle the large form because
430 // it does not do relaxation. For now, translate the large form to the
431 // small one here.
432 case X86::JMP_4: OutMI.setOpcode(X86::JMP_1); break;
433 case X86::JO_4: OutMI.setOpcode(X86::JO_1); break;
434 case X86::JNO_4: OutMI.setOpcode(X86::JNO_1); break;
435 case X86::JB_4: OutMI.setOpcode(X86::JB_1); break;
436 case X86::JAE_4: OutMI.setOpcode(X86::JAE_1); break;
437 case X86::JE_4: OutMI.setOpcode(X86::JE_1); break;
438 case X86::JNE_4: OutMI.setOpcode(X86::JNE_1); break;
439 case X86::JBE_4: OutMI.setOpcode(X86::JBE_1); break;
440 case X86::JA_4: OutMI.setOpcode(X86::JA_1); break;
441 case X86::JS_4: OutMI.setOpcode(X86::JS_1); break;
442 case X86::JNS_4: OutMI.setOpcode(X86::JNS_1); break;
443 case X86::JP_4: OutMI.setOpcode(X86::JP_1); break;
444 case X86::JNP_4: OutMI.setOpcode(X86::JNP_1); break;
445 case X86::JL_4: OutMI.setOpcode(X86::JL_1); break;
446 case X86::JGE_4: OutMI.setOpcode(X86::JGE_1); break;
447 case X86::JLE_4: OutMI.setOpcode(X86::JLE_1); break;
448 case X86::JG_4: OutMI.setOpcode(X86::JG_1); break;
449
450 // We don't currently select the correct instruction form for instructions
451 // which have a short %eax, etc. form. Handle this by custom lowering, for
452 // now.
453 //
454 // Note, we are currently not handling the following instructions:
455 // MOV64ao8, MOV64o8a
456 // XCHG16ar, XCHG32ar, XCHG64ar
457 case X86::MOV8mr_NOREX:
458 case X86::MOV8mr: SimplifyShortMoveForm(OutMI, X86::MOV8ao8); break;
459 case X86::MOV8rm_NOREX:
460 case X86::MOV8rm: SimplifyShortMoveForm(OutMI, X86::MOV8o8a); break;
461 case X86::MOV16mr: SimplifyShortMoveForm(OutMI, X86::MOV16ao16); break;
462 case X86::MOV16rm: SimplifyShortMoveForm(OutMI, X86::MOV16o16a); break;
463 case X86::MOV32mr: SimplifyShortMoveForm(OutMI, X86::MOV32ao32); break;
464 case X86::MOV32rm: SimplifyShortMoveForm(OutMI, X86::MOV32o32a); break;
465 case X86::MOV64mr: SimplifyShortMoveForm(OutMI, X86::MOV64ao64); break;
466 case X86::MOV64rm: SimplifyShortMoveForm(OutMI, X86::MOV64o64a); break;
467
468 case X86::ADC8ri: SimplifyShortImmForm(OutMI, X86::ADC8i8); break;
469 case X86::ADC16ri: SimplifyShortImmForm(OutMI, X86::ADC16i16); break;
470 case X86::ADC32ri: SimplifyShortImmForm(OutMI, X86::ADC32i32); break;
471 case X86::ADC64ri32: SimplifyShortImmForm(OutMI, X86::ADC64i32); break;
472 case X86::ADD8ri: SimplifyShortImmForm(OutMI, X86::ADD8i8); break;
473 case X86::ADD16ri: SimplifyShortImmForm(OutMI, X86::ADD16i16); break;
474 case X86::ADD32ri: SimplifyShortImmForm(OutMI, X86::ADD32i32); break;
475 case X86::ADD64ri32: SimplifyShortImmForm(OutMI, X86::ADD64i32); break;
476 case X86::AND8ri: SimplifyShortImmForm(OutMI, X86::AND8i8); break;
477 case X86::AND16ri: SimplifyShortImmForm(OutMI, X86::AND16i16); break;
478 case X86::AND32ri: SimplifyShortImmForm(OutMI, X86::AND32i32); break;
479 case X86::AND64ri32: SimplifyShortImmForm(OutMI, X86::AND64i32); break;
480 case X86::CMP8ri: SimplifyShortImmForm(OutMI, X86::CMP8i8); break;
481 case X86::CMP16ri: SimplifyShortImmForm(OutMI, X86::CMP16i16); break;
482 case X86::CMP32ri: SimplifyShortImmForm(OutMI, X86::CMP32i32); break;
483 case X86::CMP64ri32: SimplifyShortImmForm(OutMI, X86::CMP64i32); break;
484 case X86::OR8ri: SimplifyShortImmForm(OutMI, X86::OR8i8); break;
485 case X86::OR16ri: SimplifyShortImmForm(OutMI, X86::OR16i16); break;
486 case X86::OR32ri: SimplifyShortImmForm(OutMI, X86::OR32i32); break;
487 case X86::OR64ri32: SimplifyShortImmForm(OutMI, X86::OR64i32); break;
488 case X86::SBB8ri: SimplifyShortImmForm(OutMI, X86::SBB8i8); break;
489 case X86::SBB16ri: SimplifyShortImmForm(OutMI, X86::SBB16i16); break;
490 case X86::SBB32ri: SimplifyShortImmForm(OutMI, X86::SBB32i32); break;
491 case X86::SBB64ri32: SimplifyShortImmForm(OutMI, X86::SBB64i32); break;
492 case X86::SUB8ri: SimplifyShortImmForm(OutMI, X86::SUB8i8); break;
493 case X86::SUB16ri: SimplifyShortImmForm(OutMI, X86::SUB16i16); break;
494 case X86::SUB32ri: SimplifyShortImmForm(OutMI, X86::SUB32i32); break;
495 case X86::SUB64ri32: SimplifyShortImmForm(OutMI, X86::SUB64i32); break;
496 case X86::TEST8ri: SimplifyShortImmForm(OutMI, X86::TEST8i8); break;
497 case X86::TEST16ri: SimplifyShortImmForm(OutMI, X86::TEST16i16); break;
498 case X86::TEST32ri: SimplifyShortImmForm(OutMI, X86::TEST32i32); break;
499 case X86::TEST64ri32: SimplifyShortImmForm(OutMI, X86::TEST64i32); break;
500 case X86::XOR8ri: SimplifyShortImmForm(OutMI, X86::XOR8i8); break;
501 case X86::XOR16ri: SimplifyShortImmForm(OutMI, X86::XOR16i16); break;
502 case X86::XOR32ri: SimplifyShortImmForm(OutMI, X86::XOR32i32); break;
503 case X86::XOR64ri32: SimplifyShortImmForm(OutMI, X86::XOR64i32); break;
504 }
505 }
506
507 void X86AsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
508 raw_ostream &O) {
509 // Only the target-dependent form of DBG_VALUE should get here.
510 // Referencing the offset and metadata as NOps-2 and NOps-1 is
511 // probably portable to other targets; frame pointer location is not.
512 unsigned NOps = MI->getNumOperands();
513 assert(NOps==7);
514 O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
515 // cast away const; DIetc do not take const operands for some reason.
516 DIVariable V(const_cast(MI->getOperand(NOps-1).getMetadata()));
517 if (V.getContext().isSubprogram())
518 O << DISubprogram(V.getContext()).getDisplayName() << ":";
519 O << V.getName();
520 O << " <- ";
521 // Frame address. Currently handles register +- offset only.
522 O << '[';
523 if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg())
524 printOperand(MI, 0, O);
525 else
526 O << "undef";
527 O << '+'; printOperand(MI, 3, O);
528 O << ']';
529 O << "+";
530 printOperand(MI, NOps-2, O);
531 }
532
533 MachineLocation
534 X86AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const {
535 MachineLocation Location;
536 assert (MI->getNumOperands() == 7 && "Invalid no. of machine operands!");
537 // Frame address. Currently handles register +- offset only.
538
539 if (MI->getOperand(0).isReg() && MI->getOperand(3).isImm())
540 Location.set(MI->getOperand(0).getReg(), MI->getOperand(3).getImm());
541 return Location;
542 }
543
544
545 void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
546 X86MCInstLower MCInstLowering(OutContext, Mang, *this);
547 switch (MI->getOpcode()) {
548 case TargetOpcode::DBG_VALUE:
549 if (isVerbose() && OutStreamer.hasRawTextSupport()) {
550 std::string TmpStr;
551 raw_string_ostream OS(TmpStr);
552 PrintDebugValueComment(MI, OS);
553 OutStreamer.EmitRawText(StringRef(OS.str()));
554 }
555 return;
556
557 case X86::TAILJMPr:
558 case X86::TAILJMPd:
559 case X86::TAILJMPd64:
560 // Lower these as normal, but add some comments.
561 OutStreamer.AddComment("TAILCALL");
562 break;
563
564 case X86::MOVPC32r: {
565 MCInst TmpInst;
566 // This is a pseudo op for a two instruction sequence with a label, which
567 // looks like:
568 // call "L1$pb"
569 // "L1$pb":
570 // popl %esi
571
572 // Emit the call.
573 MCSymbol *PICBase = MCInstLowering.GetPICBaseSymbol();
574 TmpInst.setOpcode(X86::CALLpcrel32);
575 // FIXME: We would like an efficient form for this, so we don't have to do a
576 // lot of extra uniquing.
577 TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase,
578 OutContext)));
579 OutStreamer.EmitInstruction(TmpInst);
580
581 // Emit the label.
582 OutStreamer.EmitLabel(PICBase);
583
584 // popl $reg
585 TmpInst.setOpcode(X86::POP32r);
586 TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg());
587 OutStreamer.EmitInstruction(TmpInst);
588 return;
589 }
590
591 case X86::ADD32ri: {
592 // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri.
593 if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS)
594 break;
595
596 // Okay, we have something like:
597 // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL)
598
599 // For this, we want to print something like:
600 // MYGLOBAL + (. - PICBASE)
601 // However, we can't generate a ".", so just emit a new label here and refer
602 // to it.
603 MCSymbol *DotSym = OutContext.CreateTempSymbol();
604 OutStreamer.EmitLabel(DotSym);
605
606 // Now that we have emitted the label, lower the complex operand expression.
607 MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2));
608
609 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
610 const MCExpr *PICBase =
611 MCSymbolRefExpr::Create(MCInstLowering.GetPICBaseSymbol(), OutContext);
612 DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext);
613
614 DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext),
615 DotExpr, OutContext);
616
617 MCInst TmpInst;
618 TmpInst.setOpcode(X86::ADD32ri);
619 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
620 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
621 TmpInst.addOperand(MCOperand::CreateExpr(DotExpr));
622 OutStreamer.EmitInstruction(TmpInst);
623 return;
624 }
625 }
626
627 MCInst TmpInst;
628 MCInstLowering.Lower(MI, TmpInst);
629 OutStreamer.EmitInstruction(TmpInst);
630 }
631
+0
-51
lib/Target/X86/AsmPrinter/X86MCInstLower.h less more
None //===-- X86MCInstLower.h - Lower MachineInstr to MCInst -------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef X86_MCINSTLOWER_H
10 #define X86_MCINSTLOWER_H
11
12 #include "llvm/Support/Compiler.h"
13
14 namespace llvm {
15 class MCContext;
16 class MCInst;
17 class MCOperand;
18 class MCSymbol;
19 class MachineInstr;
20 class MachineModuleInfoMachO;
21 class MachineOperand;
22 class Mangler;
23 class X86AsmPrinter;
24 class X86Subtarget;
25
26 /// X86MCInstLower - This class is used to lower an MachineInstr into an MCInst.
27 class LLVM_LIBRARY_VISIBILITY X86MCInstLower {
28 MCContext &Ctx;
29 Mangler *Mang;
30 X86AsmPrinter &AsmPrinter;
31
32 const X86Subtarget &getSubtarget() const;
33 public:
34 X86MCInstLower(MCContext &ctx, Mangler *mang, X86AsmPrinter &asmprinter)
35 : Ctx(ctx), Mang(mang), AsmPrinter(asmprinter) {}
36
37 void Lower(const MachineInstr *MI, MCInst &OutMI) const;
38
39 MCSymbol *GetPICBaseSymbol() const;
40
41 MCSymbol *GetSymbolFromOperand(const MachineOperand &MO) const;
42 MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
43
44 private:
45 MachineModuleInfoMachO &getMachOMMI() const;
46 };
47
48 }
49
50 #endif
0 //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a printer that converts from our internal representation
10 // of machine-dependent LLVM code to X86 machine code.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "X86AsmPrinter.h"
15 #include "AsmPrinter/X86ATTInstPrinter.h"
16 #include "AsmPrinter/X86IntelInstPrinter.h"
17 #include "X86MCInstLower.h"
18 #include "X86.h"
19 #include "X86COFFMachineModuleInfo.h"
20 #include "X86MachineFunctionInfo.h"
21 #include "X86TargetMachine.h"
22 #include "llvm/CallingConv.h"
23 #include "llvm/DerivedTypes.h"
24 #include "llvm/Module.h"
25 #include "llvm/Type.h"
26 #include "llvm/Assembly/Writer.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/MC/MCContext.h"
29 #include "llvm/MC/MCExpr.h"
30 #include "llvm/MC/MCSectionMachO.h"
31 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/MC/MCSymbol.h"
33 #include "llvm/CodeGen/MachineJumpTableInfo.h"
34 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
35 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
36 #include "llvm/Support/COFF.h"
37 #include "llvm/Support/ErrorHandling.h"
38 #include "llvm/Target/Mangler.h"
39 #include "llvm/Target/TargetOptions.h"
40 #include "llvm/Target/TargetRegistry.h"
41 #include "llvm/ADT/SmallString.h"
42 using namespace llvm;
43
44 //===----------------------------------------------------------------------===//
45 // Primitive Helper Functions.
46 //===----------------------------------------------------------------------===//
47
48 void X86AsmPrinter::PrintPICBaseSymbol(raw_ostream &O) const {
49 const TargetLowering *TLI = TM.getTargetLowering();
50 O << *static_cast(TLI)->getPICBaseSymbol(MF,
51 OutContext);
52 }
53
54 /// runOnMachineFunction - Emit the function body.
55 ///
56 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
57 SetupMachineFunction(MF);
58
59 if (Subtarget->isTargetCOFF()) {
60 bool Intrn = MF.getFunction()->hasInternalLinkage();
61 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym);
62 OutStreamer.EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC
63 : COFF::IMAGE_SYM_CLASS_EXTERNAL);
64 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
65 << COFF::SCT_COMPLEX_TYPE_SHIFT);
66 OutStreamer.EndCOFFSymbolDef();
67 }
68
69 // Have common code print out the function header with linkage info etc.
70 EmitFunctionHeader();
71
72 // Emit the rest of the function body.
73 EmitFunctionBody();
74
75 // We didn't modify anything.
76 return false;
77 }
78
79 /// printSymbolOperand - Print a raw symbol reference operand. This handles
80 /// jump tables, constant pools, global address and external symbols, all of
81 /// which print to a label with various suffixes for relocation types etc.
82 void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO,
83 raw_ostream &O) {
84 switch (MO.getType()) {
85 default: llvm_unreachable("unknown symbol type!");
86 case MachineOperand::MO_JumpTableIndex:
87 O << *GetJTISymbol(MO.getIndex());
88 break;
89 case MachineOperand::MO_ConstantPoolIndex:
90 O << *GetCPISymbol(MO.getIndex());
91 printOffset(MO.getOffset(), O);
92 break;
93 case MachineOperand::MO_GlobalAddress: {
94 const GlobalValue *GV = MO.getGlobal();
95
96 MCSymbol *GVSym;
97 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
98 GVSym = GetSymbolWithGlobalValueBase(GV, "$stub");
99 else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
100 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
101 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
102 GVSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
103 else
104 GVSym = Mang->getSymbol(GV);
105
106 // Handle dllimport linkage.
107 if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
108 GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName());
109
110 if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
111 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
112 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
113 MachineModuleInfoImpl::StubValueTy &StubSym =
114 MMI->getObjFileInfo().getGVStubEntry(Sym);
115 if (StubSym.getPointer() == 0)
116 StubSym = MachineModuleInfoImpl::
117 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
118 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
119 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
120 MachineModuleInfoImpl::StubValueTy &StubSym =
121 MMI->getObjFileInfo().getHiddenGVStubEntry(Sym);
122 if (StubSym.getPointer() == 0)
123 StubSym = MachineModuleInfoImpl::
124 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
125 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
126 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
127 MachineModuleInfoImpl::StubValueTy &StubSym =
128 MMI->getObjFileInfo().getFnStubEntry(Sym);
129 if (StubSym.getPointer() == 0)
130 StubSym = MachineModuleInfoImpl::
131 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
132 }
133
134 // If the name begins with a dollar-sign, enclose it in parens. We do this
135 // to avoid having it look like an integer immediate to the assembler.
136 if (GVSym->getName()[0] != '$')
137 O << *GVSym;
138 else
139 O << '(' << *GVSym << ')';
140 printOffset(MO.getOffset(), O);
141 break;
142 }
143 case MachineOperand::MO_ExternalSymbol: {
144 const MCSymbol *SymToPrint;
145 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
146 SmallString<128> TempNameStr;
147 TempNameStr += StringRef(MO.getSymbolName());
148 TempNameStr += StringRef("$stub");
149
150 MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
151 MachineModuleInfoImpl::StubValueTy &StubSym =
152 MMI->getObjFileInfo().getFnStubEntry(Sym);
153 if (StubSym.getPointer() == 0) {
154 TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end());
155 StubSym = MachineModuleInfoImpl::
156 StubValueTy(OutContext.GetOrCreateSymbol(TempNameStr.str()),
157 true);
158 }
159 SymToPrint = StubSym.getPointer();
160 } else {
161 SymToPrint = GetExternalSymbolSymbol(MO.getSymbolName());
162 }
163
164 // If the name begins with a dollar-sign, enclose it in parens. We do this
165 // to avoid having it look like an integer immediate to the assembler.
166 if (SymToPrint->getName()[0] != '$')
167 O << *SymToPrint;
168 else
169 O << '(' << *SymToPrint << '(';
170 break;
171 }
172 }
173
174 switch (MO.getTargetFlags()) {
175 default:
176 llvm_unreachable("Unknown target flag on GV operand");
177 case X86II::MO_NO_FLAG: // No flag.
178 break;
179 case X86II::MO_DARWIN_NONLAZY:
180 case X86II::MO_DLLIMPORT:
181 case X86II::MO_DARWIN_STUB:
182 // These affect the name of the symbol, not any suffix.
183 break;
184 case X86II::MO_GOT_ABSOLUTE_ADDRESS:
185 O << " + [.-";
186 PrintPICBaseSymbol(O);
187 O << ']';
188 break;
189 case X86II::MO_PIC_BASE_OFFSET:
190 case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
191 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
192 O << '-';
193 PrintPICBaseSymbol(O);
194 break;
195 case X86II::MO_TLSGD: O << "@TLSGD"; break;
196 case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break;
197 case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
198 case X86II::MO_TPOFF: O << "@TPOFF"; break;
199 case X86II::MO_NTPOFF: O << "@NTPOFF"; break;
200 case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break;
201 case X86II::MO_GOT: O << "@GOT"; break;
202 case X86II::MO_GOTOFF: O << "@GOTOFF"; break;
203 case X86II::MO_PLT: O << "@PLT"; break;
204 case X86II::MO_TLVP: O << "@TLVP"; break;
205 case X86II::MO_TLVP_PIC_BASE:
206 O << "@TLVP" << '-';
207 PrintPICBaseSymbol(O);
208 break;
209 }
210 }
211
212 /// print_pcrel_imm - This is used to print an immediate value that ends up
213 /// being encoded as a pc-relative value. These print slightly differently, for
214 /// example, a $ is not emitted.
215 void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo,
216 raw_ostream &O) {
217 const MachineOperand &MO = MI->getOperand(OpNo);
218 switch (MO.getType()) {
219 default: llvm_unreachable("Unknown pcrel immediate operand");
220 case MachineOperand::MO_Register:
221 // pc-relativeness was handled when computing the value in the reg.
222 printOperand(MI, OpNo, O);
223 return;
224 case MachineOperand::MO_Immediate:
225 O << MO.getImm();
226 return;
227 case MachineOperand::MO_MachineBasicBlock:
228 O << *MO.getMBB()->getSymbol();
229 return;
230 case MachineOperand::MO_GlobalAddress:
231 case MachineOperand::MO_ExternalSymbol:
232 printSymbolOperand(MO, O);
233 return;
234 }
235 }
236
237
238 void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
239 raw_ostream &O, const char *Modifier) {
240 const MachineOperand &MO = MI->getOperand(OpNo);
241 switch (MO.getType()) {
242 default: llvm_unreachable("unknown operand type!");
243 case MachineOperand::MO_Register: {
244 O << '%';
245 unsigned Reg = MO.getReg();
246 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
247 EVT VT = (strcmp(Modifier+6,"64") == 0) ?
248 MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
249 ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
250 Reg = getX86SubSuperRegister(Reg, VT);
251 }
252 O << X86ATTInstPrinter::getRegisterName(Reg);
253 return;
254 }
255
256 case MachineOperand::MO_Immediate:
257 O << '$' << MO.getImm();
258 return;
259
260 case MachineOperand::MO_JumpTableIndex:
261 case MachineOperand::MO_ConstantPoolIndex:
262 case MachineOperand::MO_GlobalAddress:
263 case MachineOperand::MO_ExternalSymbol: {
264 O << '$';
265 printSymbolOperand(MO, O);
266 break;
267 }
268 }
269 }
270
271 void X86AsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op,
272 raw_ostream &O) {
273 unsigned char value = MI->getOperand(Op).getImm();
274 assert(value <= 7 && "Invalid ssecc argument!");
275 switch (value) {
276 case 0: O << "eq"; break;
277 case 1: O << "lt"; break;
278 case 2: O << "le"; break;
279 case 3: O << "unord"; break;
280 case 4: O << "neq"; break;
281 case 5: O << "nlt"; break;
282 case 6: O << "nle"; break;
283 case 7: O << "ord"; break;
284 }
285 }
286
287 void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
288 raw_ostream &O, const char *Modifier) {
289 const MachineOperand &BaseReg = MI->getOperand(Op);
290 const MachineOperand &IndexReg = MI->getOperand(Op+2);
291 const MachineOperand &DispSpec = MI->getOperand(Op+3);
292
293 // If we really don't want to print out (rip), don't.
294 bool HasBaseReg = BaseReg.getReg() != 0;
295 if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") &&
296 BaseReg.getReg() == X86::RIP)
297 HasBaseReg = false;
298
299 // HasParenPart - True if we will print out the () part of the mem ref.
300 bool HasParenPart = IndexReg.getReg() || HasBaseReg;
301
302 if (DispSpec.isImm()) {
303 int DispVal = DispSpec.getImm();
304 if (DispVal || !HasParenPart)
305 O << DispVal;
306 } else {
307 assert(DispSpec.isGlobal() || DispSpec.isCPI() ||
308 DispSpec.isJTI() || DispSpec.isSymbol());
309 printSymbolOperand(MI->getOperand(Op+3), O);
310 }
311
312 if (HasParenPart) {
313 assert(IndexReg.getReg() != X86::ESP &&
314 "X86 doesn't allow scaling by ESP");
315
316 O << '(';
317 if (HasBaseReg)
318 printOperand(MI, Op, O, Modifier);
319
320 if (IndexReg.getReg()) {
321 O << ',';
322 printOperand(MI, Op+2, O, Modifier);
323 unsigned ScaleVal = MI->getOperand(Op+1).getImm();
324 if (ScaleVal != 1)
325 O << ',' << ScaleVal;
326 }
327 O << ')';
328 }
329 }
330
331 void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
332 raw_ostream &O, const char *Modifier) {
333 assert(isMem(MI, Op) && "Invalid memory reference!");
334 const MachineOperand &Segment = MI->getOperand(Op+4);
335 if (Segment.getReg()) {
336 printOperand(MI, Op+4, O, Modifier);
337 O << ':';
338 }
339 printLeaMemReference(MI, Op, O, Modifier);
340 }
341
342 void X86AsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op,
343 raw_ostream &O) {
344 PrintPICBaseSymbol(O);
345 O << '\n';
346 PrintPICBaseSymbol(O);
347 O << ':';
348 }
349
350 bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode,
351 raw_ostream &O) {
352 unsigned Reg = MO.getReg();
353 switch (Mode) {
354 default: return true; // Unknown mode.
355 case 'b': // Print QImode register
356 Reg = getX86SubSuperRegister(Reg, MVT::i8);
357 break;
358 case 'h': // Print QImode high register
359 Reg = getX86SubSuperRegister(Reg, MVT::i8, true);
360 break;
361 case 'w': // Print HImode register
362 Reg = getX86SubSuperRegister(Reg, MVT::i16);
363 break;
364 case 'k': // Print SImode register
365 Reg = getX86SubSuperRegister(Reg, MVT::i32);
366 break;
367 case 'q': // Print DImode register
368 Reg = getX86SubSuperRegister(Reg, MVT::i64);
369 break;
370 }
371
372 O << '%' << X86ATTInstPrinter::getRegisterName(Reg);
373 return false;
374 }
375
376 /// PrintAsmOperand - Print out an operand for an inline asm expression.
377 ///
378 bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
379 unsigned AsmVariant,
380 const char *ExtraCode, raw_ostream &O) {
381 // Does this asm operand have a single letter operand modifier?
382 if (ExtraCode && ExtraCode[0]) {
383 if (ExtraCode[1] != 0) return true; // Unknown modifier.
384
385 const MachineOperand &MO = MI->getOperand(OpNo);
386
387 switch (ExtraCode[0]) {
388 default: return true; // Unknown modifier.
389 case 'a': // This is an address. Currently only 'i' and 'r' are expected.
390 if (MO.isImm()) {
391 O << MO.getImm();
392 return false;
393 }
394 if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) {
395 printSymbolOperand(MO, O);
396 if (Subtarget->isPICStyleRIPRel())
397 O << "(%rip)";
398 return false;
399 }
400 if (MO.isReg()) {
401 O << '(';
402 printOperand(MI, OpNo, O);
403 O << ')';
404 return false;
405 }
406 return true;
407
408 case 'c': // Don't print "$" before a global var name or constant.
409 if (MO.isImm())
410 O << MO.getImm();
411 else if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol())
412 printSymbolOperand(MO, O);
413 else
414 printOperand(MI, OpNo, O);
415 return false;
416
417 case 'A': // Print '*' before a register (it must be a register)
418 if (MO.isReg()) {
419 O << '*';
420 printOperand(MI, OpNo, O);
421 return false;
422 }
423 return true;
424
425 case 'b': // Print QImode register
426 case 'h': // Print QImode high register
427 case 'w': // Print HImode register
428 case 'k': // Print SImode register
429 case 'q': // Print DImode register
430 if (MO.isReg())
431 return printAsmMRegister(MO, ExtraCode[0], O);
432 printOperand(MI, OpNo, O);
433 return false;
434
435 case 'P': // This is the operand of a call, treat specially.
436 print_pcrel_imm(MI, OpNo, O);
437 return false;
438
439 case 'n': // Negate the immediate or print a '-' before the operand.
440 // Note: this is a temporary solution. It should be handled target
441 // independently as part of the 'MC' work.
442 if (MO.isImm()) {
443 O << -MO.getImm();
444 return false;
445 }
446 O << '-';
447 }
448 }
449
450 printOperand(MI, OpNo, O);
451 return false;
452 }
453
454 bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
455 unsigned OpNo, unsigned AsmVariant,
456 const char *ExtraCode,
457 raw_ostream &O) {
458 if (ExtraCode && ExtraCode[0]) {
459 if (ExtraCode[1] != 0) return true; // Unknown modifier.
460
461 switch (ExtraCode[0]) {
462 default: return true; // Unknown modifier.
463 case 'b': // Print QImode register
464 case 'h': // Print QImode high register
465 case 'w': // Print HImode register
466 case 'k': // Print SImode register
467 case 'q': // Print SImode register
468 // These only apply to registers, ignore on mem.
469 break;
470 case 'P': // Don't print @PLT, but do print as memory.
471 printMemReference(MI, OpNo, O, "no-rip");
472 return false;
473 }
474 }
475 printMemReference(MI, OpNo, O);
476 return false;
477 }
478
479 void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
480 if (Subtarget->isTargetDarwin())
481 OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
482 }
483
484
485 void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
486 if (Subtarget->isTargetDarwin()) {
487 // All darwin targets use mach-o.
488 MachineModuleInfoMachO &MMIMacho =
489 MMI->getObjFileInfo();
490
491 // Output stubs for dynamically-linked functions.
492 MachineModuleInfoMachO::SymbolListTy Stubs;
493
494 Stubs = MMIMacho.GetFnStubList();
495 if (!Stubs.empty()) {
496 const MCSection *TheSection =
497 OutContext.getMachOSection("__IMPORT", "__jump_table",
498 MCSectionMachO::S_SYMBOL_STUBS |
499 MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE |
500 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
501 5, SectionKind::getMetadata());
502 OutStreamer.SwitchSection(TheSection);
503
504 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
505 // L_foo$stub:
506 OutStreamer.EmitLabel(Stubs[i].first);
507 // .indirect_symbol _foo
508 OutStreamer.EmitSymbolAttribute(Stubs[i].second.getPointer(),
509 MCSA_IndirectSymbol);
510 // hlt; hlt; hlt; hlt; hlt hlt = 0xf4 = -12.
511 const char HltInsts[] = { -12, -12, -12, -12, -12 };
512 OutStreamer.EmitBytes(StringRef(HltInsts, 5), 0/*addrspace*/);
513 }
514
515 Stubs.clear();
516 OutStreamer.AddBlankLine();
517 }
518
519 // Output stubs for external and common global variables.
520 Stubs = MMIMacho.GetGVStubList();
521 if (!Stubs.empty()) {
522 const MCSection *TheSection =
523 OutContext.getMachOSection("__IMPORT", "__pointers",
524 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
525 SectionKind::getMetadata());
526 OutStreamer.SwitchSection(TheSection);
527
528 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
529 // L_foo$non_lazy_ptr:
530 OutStreamer.EmitLabel(Stubs[i].first);
531 // .indirect_symbol _foo
532 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
533 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),
534 MCSA_IndirectSymbol);
535 // .long 0
536 if (MCSym.getInt())
537 // External to current translation unit.
538 OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
539 else
540 // Internal to current translation unit.
541 //
542 // When we place the LSDA into the TEXT section, the type info
543 // pointers need to be indirect and pc-rel. We accomplish this by
544 // using NLPs. However, sometimes the types are local to the file. So
545 // we need to fill in the value for the NLP in those cases.
546 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
547 OutContext),
548 4/*size*/, 0/*addrspace*/);
549 }
550 Stubs.clear();
551 OutStreamer.AddBlankLine();
552 }
553
554 Stubs = MMIMacho.GetHiddenGVStubList();
555 if (!Stubs.empty()) {
556 OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
557 EmitAlignment(2);
558
559 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
560 // L_foo$non_lazy_ptr:
561 OutStreamer.EmitLabel(Stubs[i].first);
562 // .long _foo
563 OutStreamer.EmitValue(MCSymbolRefExpr::
564 Create(Stubs[i].second.getPointer(),
565 OutContext),
566 4/*size*/, 0/*addrspace*/);
567 }
568 Stubs.clear();
569 OutStreamer.AddBlankLine();
570 }
571
572 // Funny Darwin hack: This flag tells the linker that no global symbols
573 // contain code that falls through to other global symbols (e.g. the obvious
574 // implementation of multiple entry points). If this doesn't occur, the
575 // linker can safely perform dead code stripping. Since LLVM never
576 // generates code that does this, it is always safe to set.
577 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
578 }
579
580 if (Subtarget->isTargetCOFF()) {
581 X86COFFMachineModuleInfo &COFFMMI =
582 MMI->getObjFileInfo();
583
584 // Emit type information for external functions
585 typedef X86COFFMachineModuleInfo::externals_iterator externals_iterator;
586 for (externals_iterator I = COFFMMI.externals_begin(),
587 E = COFFMMI.externals_end();
588 I != E; ++I) {
589 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym);
590 OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL);
591 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
592 << COFF::SCT_COMPLEX_TYPE_SHIFT);
593 OutStreamer.EndCOFFSymbolDef();
594 }
595
596 // Necessary for dllexport support
597 std::vector DLLExportedFns, DLLExportedGlobals;
598
599 const TargetLoweringObjectFileCOFF &TLOFCOFF =
600 static_cast(getObjFileLowering());
601
602 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
603 if (I->hasDLLExportLinkage())
604 DLLExportedFns.push_back(Mang->getSymbol(I));
605
606 for (Module::const_global_iterator I = M.global_begin(),
607 E = M.global_end(); I != E; ++I)
608 if (I->hasDLLExportLinkage())
609 DLLExportedGlobals.push_back(Mang->getSymbol(I));
610
611 // Output linker support code for dllexported globals on windows.
612 if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
613 OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection());
614 SmallString<128> name;
615 for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) {
616 if (Subtarget->isTargetWindows())
617 name = " /EXPORT:";
618 else
619 name = " -export:";
620 name += DLLExportedGlobals[i]->getName();
621 if (Subtarget->isTargetWindows())
622 name += ",DATA";
623 else
624 name += ",data";
625 OutStreamer.EmitBytes(name, 0);
626 }
627
628 for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i) {
629 if (Subtarget->isTargetWindows())
630 name = " /EXPORT:";
631 else
632 name = " -export:";
633 name += DLLExportedFns[i]->getName();
634 OutStreamer.EmitBytes(name, 0);
635 }
636 }
637 }
638
639 if (Subtarget->isTargetELF()) {
640 const TargetLoweringObjectFileELF &TLOFELF =
641 static_cast(getObjFileLowering());
642
643 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo();
644
645 // Output stubs for external and common global variables.
646 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
647 if (!Stubs.empty()) {
648 OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
649 const TargetData *TD = TM.getTargetData();
650
651 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
652 OutStreamer.EmitLabel(Stubs[i].first);
653 OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
654 TD->getPointerSize(), 0);
655 }
656 Stubs.clear();
657 }
658 }
659 }
660
661
662 //===----------------------------------------------------------------------===//
663 // Target Registry Stuff
664 //===----------------------------------------------------------------------===//
665
666 static MCInstPrinter *createX86MCInstPrinter(const Target &T,
667 unsigned SyntaxVariant,
668 const MCAsmInfo &MAI) {
669 if (SyntaxVariant == 0)
670 return new X86ATTInstPrinter(MAI);
671 if (SyntaxVariant == 1)
672 return new X86IntelInstPrinter(MAI);
673 return 0;
674 }
675
676 // Force static initialization.
677 extern "C" void LLVMInitializeX86AsmPrinter() {
678 RegisterAsmPrinter X(TheX86_32Target);
679 RegisterAsmPrinter Y(TheX86_64Target);
680
681 TargetRegistry::RegisterMCInstPrinter(TheX86_32Target,createX86MCInstPrinter);
682 TargetRegistry::RegisterMCInstPrinter(TheX86_64Target,createX86MCInstPrinter);
683 }
0 //===-- X86AsmPrinter.h - Convert X86 LLVM code to assembly -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // AT&T assembly code printer class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef X86ASMPRINTER_H
14 #define X86ASMPRINTER_H
15
16 #include "X86.h"
17 #include "X86MachineFunctionInfo.h"
18 #include "X86TargetMachine.h"
19 #include "llvm/ADT/StringSet.h"
20 #include "llvm/CodeGen/AsmPrinter.h"
21 #include "llvm/CodeGen/MachineModuleInfo.h"
22 #include "llvm/CodeGen/ValueTypes.h"
23 #include "llvm/Support/Compiler.h"
24
25 namespace llvm {
26
27 class MachineJumpTableInfo;
28 class MCContext;
29 class MCInst;
30 class MCStreamer;
31 class MCSymbol;
32
33 class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
34 const X86Subtarget *Subtarget;
35 public:
36 explicit X86AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
37 : AsmPrinter(TM, Streamer) {
38 Subtarget = &TM.getSubtarget();
39 }
40
41 virtual const char *getPassName() const {
42 return "X86 AT&T-Style Assembly Printer";
43 }
44
45 const X86Subtarget &getSubtarget() const { return *Subtarget; }
46
47 virtual void EmitStartOfAsmFile(Module &M);
48
49 virtual void EmitEndOfAsmFile(Module &M);
50
51 virtual void EmitInstruction(const MachineInstr *MI);
52
53 void printSymbolOperand(const MachineOperand &MO, raw_ostream &O);
54
55 // These methods are used by the tablegen'erated instruction printer.
56 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
57 const char *Modifier = 0);
58 void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
59
60 bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O);
61 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
62 unsigned AsmVariant, const char *ExtraCode,
63 raw_ostream &OS);
64 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
65 unsigned AsmVariant, const char *ExtraCode,
66 raw_ostream &OS);
67
68 void printMachineInstruction(const MachineInstr *MI);
69 void printSSECC(const MachineInstr *MI, unsigned Op, raw_ostream &O);
70 void printMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O,
71 const char *Modifier=NULL);
72 void printLeaMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O,
73 const char *Modifier=NULL);
74
75 void printPICLabel(const MachineInstr *MI, unsigned Op, raw_ostream &O);
76
77 void PrintPICBaseSymbol(raw_ostream &O) const;
78
79 bool runOnMachineFunction(MachineFunction &F);
80
81 void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
82
83 MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
84 };
85
86 } // end namespace llvm
87
88 #endif
0 //===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains code to lower X86 MachineInstrs to their corresponding
10 // MCInst records.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "X86MCInstLower.h"
15 #include "X86AsmPrinter.h"
16 #include "X86COFFMachineModuleInfo.h"
17 #include "X86MCAsmInfo.h"
18 #include "llvm/Analysis/DebugInfo.h"
19 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/Target/Mangler.h"
26 #include "llvm/Support/FormattedStream.h"
27 #include "llvm/ADT/SmallString.h"
28 #include "llvm/Type.h"
29 using namespace llvm;
30
31
32 const X86Subtarget &X86MCInstLower::getSubtarget() const {
33 return AsmPrinter.getSubtarget();
34 }
35
36 MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
37 assert(getSubtarget().isTargetDarwin() &&"Can only get MachO info on darwin");
38 return AsmPrinter.MMI->getObjFileInfo();
39 }
40
41
42 MCSymbol *X86MCInstLower::GetPICBaseSymbol() const {
43 const TargetLowering *TLI = AsmPrinter.TM.getTargetLowering();
44 return static_cast(TLI)->
45 getPICBaseSymbol(AsmPrinter.MF, Ctx);
46 }
47
48 /// GetSymbolFromOperand - Lower an MO_GlobalAddress or MO_ExternalSymbol
49 /// operand to an MCSymbol.
50 MCSymbol *X86MCInstLower::
51 GetSymbolFromOperand(const MachineOperand &MO) const {
52 assert((MO.isGlobal() || MO.isSymbol()) && "Isn't a symbol reference");
53
54 SmallString<128> Name;
55
56 if (!MO.isGlobal()) {
57 assert(MO.isSymbol());
58 Name += AsmPrinter.MAI->getGlobalPrefix();
59 Name += MO.getSymbolName();
60 } else {
61 const GlobalValue *GV = MO.getGlobal();
62 bool isImplicitlyPrivate = false;
63 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB ||
64 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
65 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
66 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
67 isImplicitlyPrivate = true;
68
69 Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
70 }
71
72 // If the target flags on the operand changes the name of the symbol, do that
73 // before we return the symbol.
74 switch (MO.getTargetFlags()) {
75 default: break;
76 case X86II::MO_DLLIMPORT: {
77 // Handle dllimport linkage.
78 const char *Prefix = "__imp_";
79 Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix));
80 break;
81 }
82 case X86II::MO_DARWIN_NONLAZY:
83 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: {
84 Name += "$non_lazy_ptr";
85 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
86
87 MachineModuleInfoImpl::StubValueTy &StubSym =
88 getMachOMMI().getGVStubEntry(Sym);
89 if (StubSym.getPointer() == 0) {
90 assert(MO.isGlobal() && "Extern symbol not handled yet");
91 StubSym =
92 MachineModuleInfoImpl::
93 StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()),
94 !MO.getGlobal()->hasInternalLinkage());
95 }
96 return Sym;
97 }
98 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
99 Name += "$non_lazy_ptr";
100 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
101 MachineModuleInfoImpl::StubValueTy &StubSym =
102 getMachOMMI().getHiddenGVStubEntry(Sym);
103 if (StubSym.getPointer() == 0) {
104 assert(MO.isGlobal() && "Extern symbol not handled yet");
105 StubSym =
106 MachineModuleInfoImpl::
107 StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()),
108 !MO.getGlobal()->hasInternalLinkage());
109 }
110 return Sym;
111 }
112 case X86II::MO_DARWIN_STUB: {
113 Name += "$stub";
114 MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
115 MachineModuleInfoImpl::StubValueTy &StubSym =
116 getMachOMMI().getFnStubEntry(Sym);
117 if (StubSym.getPointer())
118 return Sym;
119
120 if (MO.isGlobal()) {
121 StubSym =
122 MachineModuleInfoImpl::
123 StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()),
124 !MO.getGlobal()->hasInternalLinkage());
125 } else {
126 Name.erase(Name.end()-5, Name.end());
127 StubSym =
128 MachineModuleInfoImpl::
129 StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false);
130 }
131 return Sym;
132 }
133 }
134
135 return Ctx.GetOrCreateSymbol(Name.str());
136 }
137
138 MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
139 MCSymbol *Sym) const {
140 // FIXME: We would like an efficient form for this, so we don't have to do a
141 // lot of extra uniquing.
142 const MCExpr *Expr = 0;
143 MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
144
145 switch (MO.getTargetFlags()) {
146 default: llvm_unreachable("Unknown target flag on GV operand");
147 case X86II::MO_NO_FLAG: // No flag.
148 // These affect the name of the symbol, not any suffix.
149 case X86II::MO_DARWIN_NONLAZY:
150 case X86II::MO_DLLIMPORT:
151 case X86II::MO_DARWIN_STUB:
152 break;
153
154 case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break;
155 case X86II::MO_TLVP_PIC_BASE:
156 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
157 // Subtract the pic base.
158 Expr = MCBinaryExpr::CreateSub(Expr,
159 MCSymbolRefExpr::Create(GetPICBaseSymbol(),
160 Ctx),
161 Ctx);
162 break;
163 case X86II::MO_TLSGD: RefKind = MCSymbolRefExpr::VK_TLSGD; break;
164 case X86II::MO_GOTTPOFF: RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break;
165 case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break;
166 case X86II::MO_TPOFF: RefKind = MCSymbolRefExpr::VK_TPOFF; break;
167 case X86II::MO_NTPOFF: RefKind = MCSymbolRefExpr::VK_NTPOFF; break;
168 case X86II::MO_GOTPCREL: RefKind = MCSymbolRefExpr::VK_GOTPCREL; break;
169 case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break;
170 case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break;
171 case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break;
172 case X86II::MO_PIC_BASE_OFFSET:
173 case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
174 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
175 Expr = MCSymbolRefExpr::Create(Sym, Ctx);
176 // Subtract the pic base.
177 Expr = MCBinaryExpr::CreateSub(Expr,
178 MCSymbolRefExpr::Create(GetPICBaseSymbol(), Ctx),
179 Ctx);
180 if (MO.isJTI() && AsmPrinter.MAI->hasSetDirective()) {
181 // If .set directive is supported, use it to reduce the number of
182 // relocations the assembler will generate for differences between
183 // local labels. This is only safe when the symbols are in the same
184 // section so we are restricting it to jumptable references.
185 MCSymbol *Label = Ctx.CreateTempSymbol();
186 AsmPrinter.OutStreamer.EmitAssignment(Label, Expr);
187 Expr = MCSymbolRefExpr::Create(Label, Ctx);
188 }
189 break;
190 }
191
192 if (Expr == 0)
193 Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx);
194
195 if (!MO.isJTI() && MO.getOffset())
196 Expr = MCBinaryExpr::CreateAdd(Expr,
197 MCConstantExpr::Create(MO.getOffset(), Ctx),
198 Ctx);
199 return MCOperand::CreateExpr(Expr);
200 }
201
202
203
204 static void lower_subreg32(MCInst *MI, unsigned OpNo) {
205 // Convert registers in the addr mode according to subreg32.
206 unsigned Reg = MI->getOperand(OpNo).getReg();
207 if (Reg != 0)
208 MI->getOperand(OpNo).setReg(getX86SubSuperRegister(Reg, MVT::i32));
209 }
210
211 static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) {
212 // Convert registers in the addr mode according to subreg64.
213 for (unsigned i = 0; i != 4; ++i) {
214 if (!MI->getOperand(OpNo+i).isReg()) continue;
215
216 unsigned Reg = MI->getOperand(OpNo+i).getReg();
217 if (Reg == 0) continue;
218
219 MI->getOperand(OpNo+i).setReg(getX86SubSuperRegister(Reg, MVT::i64));
220 }
221 }
222
223 /// LowerSubReg32_Op0 - Things like MOVZX16rr8 -> MOVZX32rr8.
224 static void LowerSubReg32_Op0(MCInst &OutMI, unsigned NewOpc) {
225 OutMI.setOpcode(NewOpc);
226 lower_subreg32(&OutMI, 0);
227 }
228 /// LowerUnaryToTwoAddr - R = setb -> R = sbb R, R
229 static void LowerUnaryToTwoAddr(MCInst &OutMI, unsigned NewOpc) {
230 OutMI.setOpcode(NewOpc);
231 OutMI.addOperand(OutMI.getOperand(0));
232 OutMI.addOperand(OutMI.getOperand(0));
233 }
234
235 /// \brief Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with
236 /// a short fixed-register form.
237 static void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) {
238 unsigned ImmOp = Inst.getNumOperands() - 1;
239 assert(Inst.getOperand(0).isReg() && Inst.getOperand(ImmOp).isImm() &&
240 ((Inst.getNumOperands() == 3 && Inst.getOperand(1).isReg() &&
241 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) ||
242 Inst.getNumOperands() == 2) && "Unexpected instruction!");
243
244 // Check whether the destination register can be fixed.
245 unsigned Reg = Inst.getOperand(0).getReg();
246 if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
247 return;
248
249 // If so, rewrite the instruction.
250 MCOperand Saved = Inst.getOperand(ImmOp);
251 Inst = MCInst();
252 Inst.setOpcode(Opcode);
253 Inst.addOperand(Saved);
254 }
255
256 /// \brief Simplify things like MOV32rm to MOV32o32a.
257 static void SimplifyShortMoveForm(MCInst &Inst, unsigned Opcode) {
258 bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg();
259 unsigned AddrBase = IsStore;
260 unsigned RegOp = IsStore ? 0 : 5;
261 unsigned AddrOp = AddrBase + 3;
262 assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() &&
263 Inst.getOperand(AddrBase + 0).isReg() && // base
264 Inst.getOperand(AddrBase + 1).isImm() && // scale
265 Inst.getOperand(AddrBase + 2).isReg() && // index register
266 (Inst.getOperand(AddrOp).isExpr() || // address
267 Inst.getOperand(AddrOp).isImm())&&
268 Inst.getOperand(AddrBase + 4).isReg() && // segment
269 "Unexpected instruction!");
270
271 // Check whether the destination register can be fixed.
272 unsigned Reg = Inst.getOperand(RegOp).getReg();
273 if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
274 return;
275
276 // Check whether this is an absolute address.
277 // FIXME: We know TLVP symbol refs aren't, but there should be a better way
278 // to do this here.
279 bool Absolute = true;
280 if (Inst.getOperand(AddrOp).isExpr()) {
281 const MCExpr *MCE = Inst.getOperand(AddrOp).getExpr();
282 if (const MCSymbolRefExpr *SRE = dyn_cast(MCE))
283 if (SRE->getKind() == MCSymbolRefExpr::VK_TLVP)
284 Absolute = false;
285 }
286
287 if (Absolute &&
288 (Inst.getOperand(AddrBase + 0).getReg() != 0 ||
289 Inst.getOperand(AddrBase + 2).getReg() != 0 ||
290 Inst.getOperand(AddrBase + 4).getReg() != 0 ||
291 Inst.getOperand(AddrBase + 1).getImm() != 1))
292 return;
293
294 // If so, rewrite the instruction.
295 MCOperand Saved = Inst.getOperand(AddrOp);
296 Inst = MCInst();
297 Inst.setOpcode(Opcode);
298 Inst.addOperand(Saved);
299 }
300
301 void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
302 OutMI.setOpcode(MI->getOpcode());
303
304 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
305 const MachineOperand &MO = MI->getOperand(i);
306
307 MCOperand MCOp;
308 switch (MO.getType()) {
309 default:
310 MI->dump();
311 llvm_unreachable("unknown operand type");
312 case MachineOperand::MO_Register:
313 // Ignore all implicit register operands.
314 if (MO.isImplicit()) continue;
315 MCOp = MCOperand::CreateReg(MO.getReg());
316 break;
317 case MachineOperand::MO_Immediate:
318 MCOp = MCOperand::CreateImm(MO.getImm());
319 break;
320 case MachineOperand::MO_MachineBasicBlock:
321 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
322 MO.getMBB()->getSymbol(), Ctx));
323 break;
324 case MachineOperand::MO_GlobalAddress:
325 MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
326 break;
327 case MachineOperand::MO_ExternalSymbol:
328 MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
329 break;
330 case MachineOperand::MO_JumpTableIndex:
331 MCOp = LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));
332 break;
333 case MachineOperand::MO_ConstantPoolIndex:
334 MCOp = LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));
335 break;
336 case MachineOperand::MO_BlockAddress:
337 MCOp = LowerSymbolOperand(MO,
338 AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));
339 break;
340 }
341
342 OutMI.addOperand(MCOp);
343 }
344
345 // Handle a few special cases to eliminate operand modifiers.
346 switch (OutMI.getOpcode()) {
347 case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand.
348 lower_lea64_32mem(&OutMI, 1);
349 // FALL THROUGH.
350 case X86::LEA64r:
351 case X86::LEA16r:
352 case X86::LEA32r:
353 // LEA should have a segment register, but it must be empty.
354 assert(OutMI.getNumOperands() == 1+X86::AddrNumOperands &&
355 "Unexpected # of LEA operands");
356 assert(OutMI.getOperand(1+X86::AddrSegmentReg).getReg() == 0 &&
357 "LEA has segment specified!");
358 break;
359 case X86::MOVZX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break;
360 case X86::MOVZX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break;
361 case X86::MOVSX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rr8); break;
362 case X86::MOVSX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rm8); break;
363 case X86::MOVZX64rr32: LowerSubReg32_Op0(OutMI, X86::MOV32rr); break;
364 case X86::MOVZX64rm32: LowerSubReg32_Op0(OutMI, X86::MOV32rm); break;
365 case X86::MOV64ri64i32: LowerSubReg32_Op0(OutMI, X86::MOV32ri); break;
366 case X86::MOVZX64rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break;
367 case X86::MOVZX64rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break;
368 case X86::MOVZX64rr16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr16); break;
369 case X86::MOVZX64rm16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm16); break;
370 case X86::SETB_C8r: LowerUnaryToTwoAddr(OutMI, X86::SBB8rr); break;
371 case X86::SETB_C16r: LowerUnaryToTwoAddr(OutMI, X86::SBB16rr); break;
372 case X86::SETB_C32r: LowerUnaryToTwoAddr(OutMI, X86::SBB32rr); break;
373 case X86::SETB_C64r: LowerUnaryToTwoAddr(OutMI, X86::SBB64rr); break;
374 case X86::MOV8r0: LowerUnaryToTwoAddr(OutMI, X86::XOR8rr); break;
375 case X86::MOV32r0: LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); break;
376 case X86::MMX_V_SET0: LowerUnaryToTwoAddr(OutMI, X86::MMX_PXORrr); break;
377 case X86::MMX_V_SETALLONES:
378 LowerUnaryToTwoAddr(OutMI, X86::MMX_PCMPEQDrr); break;
379 case X86::FsFLD0SS: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break;
380 case X86::FsFLD0SD: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break;
381 case X86::V_SET0PS: LowerUnaryToTwoAddr(OutMI, X86::XORPSrr); break;
382 case X86::V_SET0PD: LowerUnaryToTwoAddr(OutMI, X86::XORPDrr); break;
383 case X86::V_SET0PI: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break;
384 case X86::V_SETALLONES: LowerUnaryToTwoAddr(OutMI, X86::PCMPEQDrr); break;
385
386 case X86::MOV16r0:
387 LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV16r0 -> MOV32r0
388 LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr
389 break;
390 case X86::MOV64r0:
391 LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV64r0 -> MOV32r0
392 LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr
393 break;
394
395 // TAILJMPr64, CALL64r, CALL64pcrel32 - These instructions have
396 // register inputs modeled as normal uses instead of implicit uses. As such,
397 // truncate off all but the first operand (the callee). FIXME: Change isel.
398 case X86::TAILJMPr64:
399 case X86::CALL64r:
400 case X86::CALL64pcrel32: {
401 unsigned Opcode = OutMI.getOpcode();
402 MCOperand Saved = OutMI.getOperand(0);
403 OutMI = MCInst();
404 OutMI.setOpcode(Opcode);
405 OutMI.addOperand(Saved);
406 break;
407 }
408
409 // TAILJMPd, TAILJMPd64 - Lower to the correct jump instructions.
410 case X86::TAILJMPr:
411 case X86::TAILJMPd:
412 case X86::TAILJMPd64: {
413 unsigned Opcode;
414 switch (OutMI.getOpcode()) {
415 default: assert(0 && "Invalid opcode");
416 case X86::TAILJMPr: Opcode = X86::JMP32r; break;
417 case X86::TAILJMPd:
418 case X86::TAILJMPd64: Opcode = X86::JMP_1; break;
419 }
420
421 MCOperand Saved = OutMI.getOperand(0);
422 OutMI = MCInst();
423 OutMI.setOpcode(Opcode);
424 OutMI.addOperand(Saved);
425 break;
426 }
427
428 // The assembler backend wants to see branches in their small form and relax
429 // them to their large form. The JIT can only handle the large form because
430 // it does not do relaxation. For now, translate the large form to the
431 // small one here.
432 case X86::JMP_4: OutMI.setOpcode(X86::JMP_1); break;
433 case X86::JO_4: OutMI.setOpcode(X86::JO_1); break;
434 case X86::JNO_4: OutMI.setOpcode(X86::JNO_1); break;
435 case X86::JB_4: OutMI.setOpcode(X86::JB_1); break;
436 case X86::JAE_4: OutMI.setOpcode(X86::JAE_1); break;
437 case X86::JE_4: OutMI.setOpcode(X86::JE_1); break;
438 case X86::JNE_4: OutMI.setOpcode(X86::JNE_1); break;
439 case X86::JBE_4: OutMI.setOpcode(X86::JBE_1); break;
440 case X86::JA_4: OutMI.setOpcode(X86::JA_1); break;
441 case X86::JS_4: OutMI.setOpcode(X86::JS_1); break;
442 case X86::JNS_4: OutMI.setOpcode(X86::JNS_1); break;
443 case X86::JP_4: OutMI.setOpcode(X86::JP_1); break;
444 case X86::JNP_4: OutMI.setOpcode(X86::JNP_1); break;
445 case X86::JL_4: OutMI.setOpcode(X86::JL_1); break;
446 case X86::JGE_4: OutMI.setOpcode(X86::JGE_1); break;
447 case X86::JLE_4: OutMI.setOpcode(X86::JLE_1); break;
448 case X86::JG_4: OutMI.setOpcode(X86::JG_1); break;
449
450 // We don't currently select the correct instruction form for instructions
451 // which have a short %eax, etc. form. Handle this by custom lowering, for
452 // now.
453 //
454 // Note, we are currently not handling the following instructions:
455 // MOV64ao8, MOV64o8a
456 // XCHG16ar, XCHG32ar, XCHG64ar
457 case X86::MOV8mr_NOREX:
458 case X86::MOV8mr: SimplifyShortMoveForm(OutMI, X86::MOV8ao8); break;
459 case X86::MOV8rm_NOREX:
460 case X86::MOV8rm: SimplifyShortMoveForm(OutMI, X86::MOV8o8a); break;
461 case X86::MOV16mr: SimplifyShortMoveForm(OutMI, X86::MOV16ao16); break;
462 case X86::MOV16rm: SimplifyShortMoveForm(OutMI, X86::MOV16o16a); break;
463 case X86::MOV32mr: SimplifyShortMoveForm(OutMI, X86::MOV32ao32); break;
464 case X86::MOV32rm: SimplifyShortMoveForm(OutMI, X86::MOV32o32a); break;
465 case X86::MOV64mr: SimplifyShortMoveForm(OutMI, X86::MOV64ao64); break;
466 case X86::MOV64rm: SimplifyShortMoveForm(OutMI, X86::MOV64o64a); break;
467
468 case X86::ADC8ri: SimplifyShortImmForm(OutMI, X86::ADC8i8); break;
469 case X86::ADC16ri: SimplifyShortImmForm(OutMI, X86::ADC16i16); break;
470 case X86::ADC32ri: SimplifyShortImmForm(OutMI, X86::ADC32i32); break;
471 case X86::ADC64ri32: SimplifyShortImmForm(OutMI, X86::ADC64i32); break;
472 case X86::ADD8ri: SimplifyShortImmForm(OutMI, X86::ADD8i8); break;
473 case X86::ADD16ri: SimplifyShortImmForm(OutMI, X86::ADD16i16); break;
474 case X86::ADD32ri: SimplifyShortImmForm(OutMI, X86::ADD32i32); break;
475 case X86::ADD64ri32: SimplifyShortImmForm(OutMI, X86::ADD64i32); break;
476 case X86::AND8ri: SimplifyShortImmForm(OutMI, X86::AND8i8); break;
477 case X86::AND16ri: SimplifyShortImmForm(OutMI, X86::AND16i16); break;
478 case X86::AND32ri: SimplifyShortImmForm(OutMI, X86::AND32i32); break;
479 case X86::AND64ri32: SimplifyShortImmForm(OutMI, X86::AND64i32); break;
480 case X86::CMP8ri: SimplifyShortImmForm(OutMI, X86::CMP8i8); break;
481 case X86::CMP16ri: SimplifyShortImmForm(OutMI, X86::CMP16i16); break;
482 case X86::CMP32ri: SimplifyShortImmForm(OutMI, X86::CMP32i32); break;
483 case X86::CMP64ri32: SimplifyShortImmForm(OutMI, X86::CMP64i32); break;
484 case X86::OR8ri: SimplifyShortImmForm(OutMI, X86::OR8i8); break;
485 case X86::OR16ri: SimplifyShortImmForm(OutMI, X86::OR16i16); break;
486 case X86::OR32ri: SimplifyShortImmForm(OutMI, X86::OR32i32); break;
487 case X86::OR64ri32: SimplifyShortImmForm(OutMI, X86::OR64i32); break;
488 case X86::SBB8ri: SimplifyShortImmForm(OutMI, X86::SBB8i8); break;
489 case X86::SBB16ri: SimplifyShortImmForm(OutMI, X86::SBB16i16); break;
490 case X86::SBB32ri: SimplifyShortImmForm(OutMI, X86::SBB32i32); break;
491 case X86::SBB64ri32: SimplifyShortImmForm(OutMI, X86::SBB64i32); break;
492 case X86::SUB8ri: SimplifyShortImmForm(OutMI, X86::SUB8i8); break;
493 case X86::SUB16ri: SimplifyShortImmForm(OutMI, X86::SUB16i16); break;
494 case X86::SUB32ri: SimplifyShortImmForm(OutMI, X86::SUB32i32); break;
495 case X86::SUB64ri32: SimplifyShortImmForm(OutMI, X86::SUB64i32); break;
496 case X86::TEST8ri: SimplifyShortImmForm(OutMI, X86::TEST8i8); break;
497 case X86::TEST16ri: SimplifyShortImmForm(OutMI, X86::TEST16i16); break;
498 case X86::TEST32ri: SimplifyShortImmForm(OutMI, X86::TEST32i32); break;
499 case X86::TEST64ri32: SimplifyShortImmForm(OutMI, X86::TEST64i32); break;
500 case X86::XOR8ri: SimplifyShortImmForm(OutMI, X86::XOR8i8); break;
501 case X86::XOR16ri: SimplifyShortImmForm(OutMI, X86::XOR16i16); break;
502 case X86::XOR32ri: SimplifyShortImmForm(OutMI, X86::XOR32i32); break;
503 case X86::XOR64ri32: SimplifyShortImmForm(OutMI, X86::XOR64i32); break;
504 }
505 }
506
507 void X86AsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
508 raw_ostream &O) {
509 // Only the target-dependent form of DBG_VALUE should get here.
510 // Referencing the offset and metadata as NOps-2 and NOps-1 is
511 // probably portable to other targets; frame pointer location is not.
512 unsigned NOps = MI->getNumOperands();
513 assert(NOps==7);
514 O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
515 // cast away const; DIetc do not take const operands for some reason.
516 DIVariable V(const_cast(MI->getOperand(NOps-1).getMetadata()));
517 if (V.getContext().isSubprogram())
518 O << DISubprogram(V.getContext()).getDisplayName() << ":";
519 O << V.getName();
520 O << " <- ";
521 // Frame address. Currently handles register +- offset only.
522 O << '[';
523 if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg())
524 printOperand(MI, 0, O);
525 else
526 O << "undef";
527 O << '+'; printOperand(MI, 3, O);
528 O << ']';
529 O << "+";
530 printOperand(MI, NOps-2, O);
531 }
532
533 MachineLocation
534 X86AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const {
535 MachineLocation Location;
536 assert (MI->getNumOperands() == 7 && "Invalid no. of machine operands!");
537 // Frame address. Currently handles register +- offset only.
538
539 if (MI->getOperand(0).isReg() && MI->getOperand(3).isImm())
540 Location.set(MI->getOperand(0).getReg(), MI->getOperand(3).getImm());
541 return Location;
542 }
543
544
545 void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
546 X86MCInstLower MCInstLowering(OutContext, Mang, *this);
547 switch (MI->getOpcode()) {
548 case TargetOpcode::DBG_VALUE:
549 if (isVerbose() && OutStreamer.hasRawTextSupport()) {
550 std::string TmpStr;
551 raw_string_ostream OS(TmpStr);
552 PrintDebugValueComment(MI, OS);
553 OutStreamer.EmitRawText(StringRef(OS.str()));
554 }
555 return;
556
557 case X86::TAILJMPr:
558 case X86::TAILJMPd:
559 case X86::TAILJMPd64:
560 // Lower these as normal, but add some comments.
561 OutStreamer.AddComment("TAILCALL");
562 break;
563
564 case X86::MOVPC32r: {
565 MCInst TmpInst;
566 // This is a pseudo op for a two instruction sequence with a label, which
567 // looks like:
568 // call "L1$pb"
569 // "L1$pb":
570 // popl %esi
571
572 // Emit the call.
573 MCSymbol *PICBase = MCInstLowering.GetPICBaseSymbol();
574 TmpInst.setOpcode(X86::CALLpcrel32);
575 // FIXME: We would like an efficient form for this, so we don't have to do a
576 // lot of extra uniquing.
577 TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase,
578 OutContext)));
579 OutStreamer.EmitInstruction(TmpInst);
580
581 // Emit the label.
582 OutStreamer.EmitLabel(PICBase);
583
584 // popl $reg
585 TmpInst.setOpcode(X86::POP32r);
586 TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg());
587 OutStreamer.EmitInstruction(TmpInst);
588 return;
589 }
590
591 case X86::ADD32ri: {
592 // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri.
593 if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS)
594 break;
595
596 // Okay, we have something like:
597 // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL)
598
599 // For this, we want to print something like:
600 // MYGLOBAL + (. - PICBASE)
601 // However, we can't generate a ".", so just emit a new label here and refer
602 // to it.
603 MCSymbol *DotSym = OutContext.CreateTempSymbol();
604 OutStreamer.EmitLabel(DotSym);
605
606 // Now that we have emitted the label, lower the complex operand expression.
607 MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2));
608
609 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
610 const MCExpr *PICBase =
611 MCSymbolRefExpr::Create(MCInstLowering.GetPICBaseSymbol(), OutContext);
612 DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext);
613
614 DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext),
615 DotExpr, OutContext);
616
617 MCInst TmpInst;
618 TmpInst.setOpcode(X86::ADD32ri);
619 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
620 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
621 TmpInst.addOperand(MCOperand::CreateExpr(DotExpr));
622 OutStreamer.EmitInstruction(TmpInst);
623 return;
624 }
625 }
626
627 MCInst TmpInst;
628 MCInstLowering.Lower(MI, TmpInst);
629 OutStreamer.EmitInstruction(TmpInst);
630 }
631
0 //===-- X86MCInstLower.h - Lower MachineInstr to MCInst -------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef X86_MCINSTLOWER_H
10 #define X86_MCINSTLOWER_H
11
12 #include "llvm/Support/Compiler.h"
13
14 namespace llvm {
15 class MCContext;
16 class MCInst;
17 class MCOperand;
18 class MCSymbol;
19 class MachineInstr;
20 class MachineModuleInfoMachO;
21 class MachineOperand;
22 class Mangler;
23 class X86AsmPrinter;
24 class X86Subtarget;
25
26 /// X86MCInstLower - This class is used to lower an MachineInstr into an MCInst.
27 class LLVM_LIBRARY_VISIBILITY X86MCInstLower {
28 MCContext &Ctx;
29 Mangler *Mang;
30 X86AsmPrinter &AsmPrinter;
31
32 const X86Subtarget &getSubtarget() const;
33 public:
34 X86MCInstLower(MCContext &ctx, Mangler *mang, X86AsmPrinter &asmprinter)
35 : Ctx(ctx), Mang(mang), AsmPrinter(asmprinter) {}
36
37 void Lower(const MachineInstr *MI, MCInst &OutMI) const;
38
39 MCSymbol *GetPICBaseSymbol() const;
40
41 MCSymbol *GetSymbolFromOperand(const MachineOperand &MO) const;
42 MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
43
44 private:
45 MachineModuleInfoMachO &getMachOMMI() const;
46 };
47
48 }
49
50 #endif