1 //===-- X86IntelAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly --===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to Intel format assembly language.
12 // This printer is the output mechanism used by `llc'.
14 //===----------------------------------------------------------------------===//
16 #include "X86IntelAsmPrinter.h"
18 #include "llvm/Constants.h"
19 #include "llvm/Module.h"
20 #include "llvm/Assembly/Writer.h"
21 #include "llvm/Support/Mangler.h"
22 #include "llvm/Target/TargetOptions.h"
25 X86IntelAsmPrinter::X86IntelAsmPrinter(std::ostream &O, X86TargetMachine &TM)
26 : X86SharedAsmPrinter(O, TM) {
29 /// runOnMachineFunction - This uses the printMachineInstruction()
30 /// method to print assembly for each instruction.
32 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
33 SetupMachineFunction(MF);
36 // Print out constants referenced by the function
37 EmitConstantPool(MF.getConstantPool());
39 // Print out labels for the function.
40 SwitchSection(".code", MF.getFunction());
42 if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage)
43 O << "\tpublic " << CurrentFnName << "\n";
44 O << CurrentFnName << "\tproc near\n";
46 // Print out code for the function.
47 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
49 // Print a label for the basic block if there are any predecessors.
50 if (I->pred_begin() != I->pred_end()) {
51 printBasicBlockLabel(I, true);
54 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
56 // Print the assembly for the instruction.
58 printMachineInstruction(II);
62 O << CurrentFnName << "\tendp\n";
64 // We didn't modify anything.
68 void X86IntelAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
69 unsigned char value = MI->getOperand(Op).getImmedValue();
70 assert(value <= 7 && "Invalid ssecc argument!");
72 case 0: O << "eq"; break;
73 case 1: O << "lt"; break;
74 case 2: O << "le"; break;
75 case 3: O << "unord"; break;
76 case 4: O << "neq"; break;
77 case 5: O << "nlt"; break;
78 case 6: O << "nle"; break;
79 case 7: O << "ord"; break;
83 void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
84 const char *Modifier) {
85 const MRegisterInfo &RI = *TM.getRegisterInfo();
86 switch (MO.getType()) {
87 case MachineOperand::MO_Register:
88 if (MRegisterInfo::isPhysicalRegister(MO.getReg())) {
89 unsigned Reg = MO.getReg();
90 if (Modifier && strncmp(Modifier, "trunc", strlen("trunc")) == 0) {
91 MVT::ValueType VT = (strcmp(Modifier,"trunc16") == 0)
93 Reg = getX86SubSuperRegister(Reg, VT);
95 O << RI.get(Reg).Name;
97 O << "reg" << MO.getReg();
100 case MachineOperand::MO_Immediate:
101 O << (int)MO.getImmedValue();
103 case MachineOperand::MO_MachineBasicBlock:
104 printBasicBlockLabel(MO.getMachineBasicBlock());
106 case MachineOperand::MO_ConstantPoolIndex: {
107 bool isMemOp = Modifier && !strcmp(Modifier, "mem");
108 if (!isMemOp) O << "OFFSET ";
109 O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
110 << MO.getConstantPoolIndex();
111 int Offset = MO.getOffset();
113 O << " + " << Offset;
119 case MachineOperand::MO_GlobalAddress: {
120 bool isCallOp = Modifier && !strcmp(Modifier, "call");
121 bool isMemOp = Modifier && !strcmp(Modifier, "mem");
122 if (!isMemOp && !isCallOp) O << "OFFSET ";
123 O << Mang->getValueName(MO.getGlobal());
124 int Offset = MO.getOffset();
126 O << " + " << Offset;
131 case MachineOperand::MO_ExternalSymbol: {
132 bool isCallOp = Modifier && !strcmp(Modifier, "call");
133 if (!isCallOp) O << "OFFSET ";
134 O << GlobalPrefix << MO.getSymbolName();
138 O << "<unknown operand type>"; return;
142 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
143 assert(isMem(MI, Op) && "Invalid memory reference!");
145 const MachineOperand &BaseReg = MI->getOperand(Op);
146 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
147 const MachineOperand &IndexReg = MI->getOperand(Op+2);
148 const MachineOperand &DispSpec = MI->getOperand(Op+3);
150 if (BaseReg.isFrameIndex()) {
151 O << "[frame slot #" << BaseReg.getFrameIndex();
152 if (DispSpec.getImmedValue())
153 O << " + " << DispSpec.getImmedValue();
159 bool NeedPlus = false;
160 if (BaseReg.getReg()) {
161 printOp(BaseReg, "mem");
165 if (IndexReg.getReg()) {
166 if (NeedPlus) O << " + ";
168 O << ScaleVal << "*";
173 if (DispSpec.isGlobalAddress() || DispSpec.isConstantPoolIndex()) {
176 printOp(DispSpec, "mem");
178 int DispVal = DispSpec.getImmedValue();
179 if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) {
193 void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
194 O << "\"L" << getFunctionNumber() << "$pb\"\n";
195 O << "\"L" << getFunctionNumber() << "$pb\":";
198 bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO,
200 const MRegisterInfo &RI = *TM.getRegisterInfo();
201 unsigned Reg = MO.getReg();
203 default: return true; // Unknown mode.
204 case 'b': // Print QImode register
205 Reg = getX86SubSuperRegister(Reg, MVT::i8);
207 case 'h': // Print QImode high register
208 Reg = getX86SubSuperRegister(Reg, MVT::i8, true);
210 case 'w': // Print HImode register
211 Reg = getX86SubSuperRegister(Reg, MVT::i16);
213 case 'k': // Print SImode register
214 Reg = getX86SubSuperRegister(Reg, MVT::i32);
218 O << '%' << RI.get(Reg).Name;
222 /// PrintAsmOperand - Print out an operand for an inline asm expression.
224 bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
226 const char *ExtraCode) {
227 // Does this asm operand have a single letter operand modifier?
228 if (ExtraCode && ExtraCode[0]) {
229 if (ExtraCode[1] != 0) return true; // Unknown modifier.
231 switch (ExtraCode[0]) {
232 default: return true; // Unknown modifier.
233 case 'b': // Print QImode register
234 case 'h': // Print QImode high register
235 case 'w': // Print HImode register
236 case 'k': // Print SImode register
237 return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]);
241 printOperand(MI, OpNo);
245 bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
248 const char *ExtraCode) {
249 if (ExtraCode && ExtraCode[0])
250 return true; // Unknown modifier.
251 printMemReference(MI, OpNo);
255 /// printMachineInstruction -- Print out a single X86 LLVM instruction
256 /// MI in Intel syntax to the current output stream.
258 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
261 // See if a truncate instruction can be turned into a nop.
262 switch (MI->getOpcode()) {
264 case X86::TRUNC_R32_R16:
265 case X86::TRUNC_R32_R8:
266 case X86::TRUNC_R16_R8: {
267 const MachineOperand &MO0 = MI->getOperand(0);
268 const MachineOperand &MO1 = MI->getOperand(1);
269 unsigned Reg0 = MO0.getReg();
270 unsigned Reg1 = MO1.getReg();
271 if (MI->getOpcode() == X86::TRUNC_R32_R16)
272 Reg1 = getX86SubSuperRegister(Reg1, MVT::i16);
274 Reg1 = getX86SubSuperRegister(Reg1, MVT::i8);
275 O << CommentString << " TRUNCATE ";
282 // Call the autogenerated instruction printer routines.
283 printInstruction(MI);
286 bool X86IntelAsmPrinter::doInitialization(Module &M) {
291 X86SharedAsmPrinter::doInitialization(M);
293 PrivateGlobalPrefix = "$";
294 AlignDirective = "\talign\t";
295 ZeroDirective = "\tdb\t";
296 ZeroDirectiveSuffix = " dup(0)";
297 AsciiDirective = "\tdb\t";
299 Data8bitsDirective = "\tdb\t";
300 Data16bitsDirective = "\tdw\t";
301 Data32bitsDirective = "\tdd\t";
302 Data64bitsDirective = "\tdq\t";
303 HasDotTypeDotSizeDirective = false;
304 Mang->markCharUnacceptable('.');
306 O << "\t.686\n\t.model flat\n\n";
308 // Emit declarations for external functions.
309 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
311 O << "\textern " << Mang->getValueName(I) << ":near\n";
313 // Emit declarations for external globals. Note that VC++ always declares
314 // external globals to have type byte, and if that's good enough for VC++...
315 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
318 O << "\textern " << Mang->getValueName(I) << ":byte\n";
324 bool X86IntelAsmPrinter::doFinalization(Module &M) {
325 const TargetData *TD = TM.getTargetData();
327 // Print out module-level global variables here.
328 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
330 if (I->isExternal()) continue; // External global require no code
332 // Check to see if this is a special global used by LLVM, if so, emit it.
333 if (EmitSpecialLLVMGlobal(I))
336 std::string name = Mang->getValueName(I);
337 Constant *C = I->getInitializer();
338 unsigned Size = TD->getTypeSize(C->getType());
339 unsigned Align = getPreferredAlignmentLog(I);
340 bool bCustomSegment = false;
342 switch (I->getLinkage()) {
343 case GlobalValue::LinkOnceLinkage:
344 case GlobalValue::WeakLinkage:
345 SwitchSection("", 0);
346 O << name << "?\tsegment common 'COMMON'\n";
347 bCustomSegment = true;
348 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
349 // are also available.
351 case GlobalValue::AppendingLinkage:
352 SwitchSection("", 0);
353 O << name << "?\tsegment public 'DATA'\n";
354 bCustomSegment = true;
355 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
356 // are also available.
358 case GlobalValue::ExternalLinkage:
359 O << "\tpublic " << name << "\n";
361 case GlobalValue::InternalLinkage:
362 SwitchSection(".data", I);
365 assert(0 && "Unknown linkage type!");
369 EmitAlignment(Align, I);
371 O << name << ":\t\t\t\t" << CommentString << " " << I->getName() << '\n';
373 EmitGlobalConstant(C);
376 O << name << "?\tends\n";
379 // Bypass X86SharedAsmPrinter::doFinalization().
380 AsmPrinter::doFinalization(M);
381 SwitchSection("", 0);
383 return false; // success
386 void X86IntelAsmPrinter::EmitString(const ConstantArray *CVA) const {
387 unsigned NumElts = CVA->getNumOperands();
389 // ML does not have escape sequences except '' for '. It also has a maximum
390 // string length of 255.
392 bool inString = false;
393 for (unsigned i = 0; i < NumElts; i++) {
394 int n = cast<ConstantInt>(CVA->getOperand(i))->getRawValue() & 255;
398 if (n >= 32 && n <= 127) {
425 len += 1 + (n > 9) + (n > 99);
446 // Include the auto-generated portion of the assembly writer.
447 #include "X86GenAsmWriter1.inc"