LLVM API Documentation
00001 //===-- X86ATTAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly ----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains a printer that converts from our internal representation 00011 // of machine-dependent LLVM code to AT&T format assembly 00012 // language. This printer is the output mechanism used by `llc'. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "X86ATTAsmPrinter.h" 00017 #include "X86.h" 00018 #include "X86TargetMachine.h" 00019 #include "llvm/Module.h" 00020 #include "llvm/Support/Mangler.h" 00021 #include "llvm/Target/TargetOptions.h" 00022 #include <iostream> 00023 using namespace llvm; 00024 00025 /// runOnMachineFunction - This uses the printMachineInstruction() 00026 /// method to print assembly for each instruction. 00027 /// 00028 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00029 if (Subtarget->isTargetDarwin()) { 00030 // Let PassManager know we need debug information and relay 00031 // the MachineDebugInfo address on to DwarfWriter. 00032 DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>()); 00033 } 00034 00035 SetupMachineFunction(MF); 00036 O << "\n\n"; 00037 00038 // Print out constants referenced by the function 00039 EmitConstantPool(MF.getConstantPool()); 00040 00041 // Print out jump tables referenced by the function 00042 EmitJumpTableInfo(MF.getJumpTableInfo()); 00043 00044 // Print out labels for the function. 00045 const Function *F = MF.getFunction(); 00046 switch (F->getLinkage()) { 00047 default: assert(0 && "Unknown linkage type!"); 00048 case Function::InternalLinkage: // Symbols default to internal. 00049 SwitchToTextSection(DefaultTextSection, F); 00050 EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. 00051 break; 00052 case Function::ExternalLinkage: 00053 SwitchToTextSection(DefaultTextSection, F); 00054 EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. 00055 O << "\t.globl\t" << CurrentFnName << "\n"; 00056 break; 00057 case Function::WeakLinkage: 00058 case Function::LinkOnceLinkage: 00059 if (Subtarget->isTargetDarwin()) { 00060 SwitchToTextSection( 00061 ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); 00062 O << "\t.globl\t" << CurrentFnName << "\n"; 00063 O << "\t.weak_definition\t" << CurrentFnName << "\n"; 00064 } else if (Subtarget->TargetType == X86Subtarget::isCygwin) { 00065 EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. 00066 O << "\t.section\t.llvm.linkonce.t." << CurrentFnName 00067 << ",\"ax\"\n"; 00068 SwitchToTextSection("", F); 00069 O << "\t.weak " << CurrentFnName << "\n"; 00070 } else { 00071 EmitAlignment(4, F); // FIXME: This should be parameterized somewhere. 00072 O << "\t.section\t.llvm.linkonce.t." << CurrentFnName 00073 << ",\"ax\",@progbits\n"; 00074 SwitchToTextSection("", F); 00075 O << "\t.weak " << CurrentFnName << "\n"; 00076 } 00077 break; 00078 } 00079 O << CurrentFnName << ":\n"; 00080 00081 if (Subtarget->isTargetDarwin()) { 00082 // Emit pre-function debug information. 00083 DW.BeginFunction(&MF); 00084 } 00085 00086 // Print out code for the function. 00087 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00088 I != E; ++I) { 00089 // Print a label for the basic block. 00090 if (I->pred_begin() != I->pred_end()) { 00091 printBasicBlockLabel(I, true); 00092 O << '\n'; 00093 } 00094 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 00095 II != E; ++II) { 00096 // Print the assembly for the instruction. 00097 O << "\t"; 00098 printMachineInstruction(II); 00099 } 00100 } 00101 if (HasDotTypeDotSizeDirective) 00102 O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n"; 00103 00104 if (Subtarget->isTargetDarwin()) { 00105 // Emit post-function debug information. 00106 DW.EndFunction(); 00107 } 00108 00109 // We didn't modify anything. 00110 return false; 00111 } 00112 00113 void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 00114 const char *Modifier) { 00115 const MachineOperand &MO = MI->getOperand(OpNo); 00116 const MRegisterInfo &RI = *TM.getRegisterInfo(); 00117 switch (MO.getType()) { 00118 case MachineOperand::MO_Register: { 00119 assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && 00120 "Virtual registers should not make it this far!"); 00121 O << '%'; 00122 unsigned Reg = MO.getReg(); 00123 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { 00124 MVT::ValueType VT = (strcmp(Modifier,"subreg16") == 0) 00125 ? MVT::i16 : MVT::i8; 00126 Reg = getX86SubSuperRegister(Reg, VT); 00127 } 00128 for (const char *Name = RI.get(Reg).Name; *Name; ++Name) 00129 O << (char)tolower(*Name); 00130 return; 00131 } 00132 00133 case MachineOperand::MO_Immediate: 00134 if (!Modifier || strcmp(Modifier, "debug") != 0) 00135 O << '$'; 00136 O << MO.getImmedValue(); 00137 return; 00138 case MachineOperand::MO_MachineBasicBlock: 00139 printBasicBlockLabel(MO.getMachineBasicBlock()); 00140 return; 00141 case MachineOperand::MO_JumpTableIndex: { 00142 bool isMemOp = Modifier && !strcmp(Modifier, "mem"); 00143 if (!isMemOp) O << '$'; 00144 O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << "_" 00145 << MO.getJumpTableIndex(); 00146 if (Subtarget->isTargetDarwin() && 00147 TM.getRelocationModel() == Reloc::PIC_) 00148 O << "-\"L" << getFunctionNumber() << "$pb\""; 00149 return; 00150 } 00151 case MachineOperand::MO_ConstantPoolIndex: { 00152 bool isMemOp = Modifier && !strcmp(Modifier, "mem"); 00153 if (!isMemOp) O << '$'; 00154 O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" 00155 << MO.getConstantPoolIndex(); 00156 if (Subtarget->isTargetDarwin() && 00157 TM.getRelocationModel() == Reloc::PIC_) 00158 O << "-\"L" << getFunctionNumber() << "$pb\""; 00159 int Offset = MO.getOffset(); 00160 if (Offset > 0) 00161 O << "+" << Offset; 00162 else if (Offset < 0) 00163 O << Offset; 00164 return; 00165 } 00166 case MachineOperand::MO_GlobalAddress: { 00167 bool isCallOp = Modifier && !strcmp(Modifier, "call"); 00168 bool isMemOp = Modifier && !strcmp(Modifier, "mem"); 00169 if (!isMemOp && !isCallOp) O << '$'; 00170 // Darwin block shameless ripped from PPCAsmPrinter.cpp 00171 if (Subtarget->isTargetDarwin() && 00172 TM.getRelocationModel() != Reloc::Static) { 00173 GlobalValue *GV = MO.getGlobal(); 00174 std::string Name = Mang->getValueName(GV); 00175 // Link-once, External, or Weakly-linked global variables need 00176 // non-lazily-resolved stubs 00177 if (GV->isExternal() || GV->hasWeakLinkage() || 00178 GV->hasLinkOnceLinkage()) { 00179 // Dynamically-resolved functions need a stub for the function. 00180 if (isCallOp && isa<Function>(GV) && cast<Function>(GV)->isExternal()) { 00181 FnStubs.insert(Name); 00182 O << "L" << Name << "$stub"; 00183 } else { 00184 GVStubs.insert(Name); 00185 O << "L" << Name << "$non_lazy_ptr"; 00186 } 00187 } else { 00188 O << Mang->getValueName(GV); 00189 } 00190 if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_) 00191 O << "-\"L" << getFunctionNumber() << "$pb\""; 00192 } else 00193 O << Mang->getValueName(MO.getGlobal()); 00194 int Offset = MO.getOffset(); 00195 if (Offset > 0) 00196 O << "+" << Offset; 00197 else if (Offset < 0) 00198 O << Offset; 00199 return; 00200 } 00201 case MachineOperand::MO_ExternalSymbol: { 00202 bool isCallOp = Modifier && !strcmp(Modifier, "call"); 00203 if (isCallOp && 00204 Subtarget->isTargetDarwin() && 00205 TM.getRelocationModel() != Reloc::Static) { 00206 std::string Name(GlobalPrefix); 00207 Name += MO.getSymbolName(); 00208 FnStubs.insert(Name); 00209 O << "L" << Name << "$stub"; 00210 return; 00211 } 00212 if (!isCallOp) O << '$'; 00213 O << GlobalPrefix << MO.getSymbolName(); 00214 return; 00215 } 00216 default: 00217 O << "<unknown operand type>"; return; 00218 } 00219 } 00220 00221 void X86ATTAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) { 00222 unsigned char value = MI->getOperand(Op).getImmedValue(); 00223 assert(value <= 7 && "Invalid ssecc argument!"); 00224 switch (value) { 00225 case 0: O << "eq"; break; 00226 case 1: O << "lt"; break; 00227 case 2: O << "le"; break; 00228 case 3: O << "unord"; break; 00229 case 4: O << "neq"; break; 00230 case 5: O << "nlt"; break; 00231 case 6: O << "nle"; break; 00232 case 7: O << "ord"; break; 00233 } 00234 } 00235 00236 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ 00237 assert(isMem(MI, Op) && "Invalid memory reference!"); 00238 00239 const MachineOperand &BaseReg = MI->getOperand(Op); 00240 int ScaleVal = MI->getOperand(Op+1).getImmedValue(); 00241 const MachineOperand &IndexReg = MI->getOperand(Op+2); 00242 const MachineOperand &DispSpec = MI->getOperand(Op+3); 00243 00244 if (BaseReg.isFrameIndex()) { 00245 O << "[frame slot #" << BaseReg.getFrameIndex(); 00246 if (DispSpec.getImmedValue()) 00247 O << " + " << DispSpec.getImmedValue(); 00248 O << "]"; 00249 return; 00250 } 00251 00252 if (DispSpec.isGlobalAddress() || DispSpec.isConstantPoolIndex()) { 00253 printOperand(MI, Op+3, "mem"); 00254 } else { 00255 int DispVal = DispSpec.getImmedValue(); 00256 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) 00257 O << DispVal; 00258 } 00259 00260 if (IndexReg.getReg() || BaseReg.getReg()) { 00261 O << "("; 00262 if (BaseReg.getReg()) 00263 printOperand(MI, Op); 00264 00265 if (IndexReg.getReg()) { 00266 O << ","; 00267 printOperand(MI, Op+2); 00268 if (ScaleVal != 1) 00269 O << "," << ScaleVal; 00270 } 00271 00272 O << ")"; 00273 } 00274 } 00275 00276 void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { 00277 O << "\"L" << getFunctionNumber() << "$pb\"\n"; 00278 O << "\"L" << getFunctionNumber() << "$pb\":"; 00279 } 00280 00281 00282 bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO, 00283 const char Mode) { 00284 const MRegisterInfo &RI = *TM.getRegisterInfo(); 00285 unsigned Reg = MO.getReg(); 00286 switch (Mode) { 00287 default: return true; // Unknown mode. 00288 case 'b': // Print QImode register 00289 Reg = getX86SubSuperRegister(Reg, MVT::i8); 00290 break; 00291 case 'h': // Print QImode high register 00292 Reg = getX86SubSuperRegister(Reg, MVT::i8, true); 00293 break; 00294 case 'w': // Print HImode register 00295 Reg = getX86SubSuperRegister(Reg, MVT::i16); 00296 break; 00297 case 'k': // Print SImode register 00298 Reg = getX86SubSuperRegister(Reg, MVT::i32); 00299 break; 00300 } 00301 00302 O << '%'; 00303 for (const char *Name = RI.get(Reg).Name; *Name; ++Name) 00304 O << (char)tolower(*Name); 00305 return false; 00306 } 00307 00308 /// PrintAsmOperand - Print out an operand for an inline asm expression. 00309 /// 00310 bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00311 unsigned AsmVariant, 00312 const char *ExtraCode) { 00313 // Does this asm operand have a single letter operand modifier? 00314 if (ExtraCode && ExtraCode[0]) { 00315 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00316 00317 switch (ExtraCode[0]) { 00318 default: return true; // Unknown modifier. 00319 case 'b': // Print QImode register 00320 case 'h': // Print QImode high register 00321 case 'w': // Print HImode register 00322 case 'k': // Print SImode register 00323 return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]); 00324 } 00325 } 00326 00327 printOperand(MI, OpNo); 00328 return false; 00329 } 00330 00331 bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00332 unsigned OpNo, 00333 unsigned AsmVariant, 00334 const char *ExtraCode) { 00335 if (ExtraCode && ExtraCode[0]) 00336 return true; // Unknown modifier. 00337 printMemReference(MI, OpNo); 00338 return false; 00339 } 00340 00341 /// printMachineInstruction -- Print out a single X86 LLVM instruction 00342 /// MI in Intel syntax to the current output stream. 00343 /// 00344 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 00345 ++EmittedInsts; 00346 // This works around some Darwin assembler bugs. 00347 if (Subtarget->isTargetDarwin()) { 00348 switch (MI->getOpcode()) { 00349 case X86::REP_MOVSB: 00350 O << "rep/movsb (%esi),(%edi)\n"; 00351 return; 00352 case X86::REP_MOVSD: 00353 O << "rep/movsl (%esi),(%edi)\n"; 00354 return; 00355 case X86::REP_MOVSW: 00356 O << "rep/movsw (%esi),(%edi)\n"; 00357 return; 00358 case X86::REP_STOSB: 00359 O << "rep/stosb\n"; 00360 return; 00361 case X86::REP_STOSD: 00362 O << "rep/stosl\n"; 00363 return; 00364 case X86::REP_STOSW: 00365 O << "rep/stosw\n"; 00366 return; 00367 default: 00368 break; 00369 } 00370 } 00371 00372 // See if a truncate instruction can be turned into a nop. 00373 switch (MI->getOpcode()) { 00374 default: break; 00375 case X86::TRUNC_GR32_GR16: 00376 case X86::TRUNC_GR32_GR8: 00377 case X86::TRUNC_GR16_GR8: { 00378 const MachineOperand &MO0 = MI->getOperand(0); 00379 const MachineOperand &MO1 = MI->getOperand(1); 00380 unsigned Reg0 = MO0.getReg(); 00381 unsigned Reg1 = MO1.getReg(); 00382 if (MI->getOpcode() == X86::TRUNC_GR32_GR16) 00383 Reg1 = getX86SubSuperRegister(Reg1, MVT::i16); 00384 else 00385 Reg1 = getX86SubSuperRegister(Reg1, MVT::i8); 00386 O << CommentString << " TRUNCATE "; 00387 if (Reg0 != Reg1) 00388 O << "\n\t"; 00389 break; 00390 } 00391 } 00392 00393 // Call the autogenerated instruction printer routines. 00394 printInstruction(MI); 00395 } 00396 00397 // Include the auto-generated portion of the assembly writer. 00398 #include "X86GenAsmWriter.inc" 00399