LLVM API Documentation
00001 //===-- X86IntelAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly --===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // 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 Intel format assembly language. 00012 // This printer is the output mechanism used by `llc'. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #define DEBUG_TYPE "asm-printer" 00017 #include "X86IntelAsmPrinter.h" 00018 #include "X86InstrInfo.h" 00019 #include "X86TargetAsmInfo.h" 00020 #include "X86.h" 00021 #include "llvm/CallingConv.h" 00022 #include "llvm/Constants.h" 00023 #include "llvm/DerivedTypes.h" 00024 #include "llvm/Module.h" 00025 #include "llvm/ADT/Statistic.h" 00026 #include "llvm/ADT/StringExtras.h" 00027 #include "llvm/Assembly/Writer.h" 00028 #include "llvm/Support/Mangler.h" 00029 #include "llvm/Target/TargetAsmInfo.h" 00030 #include "llvm/Target/TargetOptions.h" 00031 using namespace llvm; 00032 00033 STATISTIC(EmittedInsts, "Number of machine instrs printed"); 00034 00035 static X86MachineFunctionInfo calculateFunctionInfo(const Function *F, 00036 const TargetData *TD) { 00037 X86MachineFunctionInfo Info; 00038 uint64_t Size = 0; 00039 00040 switch (F->getCallingConv()) { 00041 case CallingConv::X86_StdCall: 00042 Info.setDecorationStyle(StdCall); 00043 break; 00044 case CallingConv::X86_FastCall: 00045 Info.setDecorationStyle(FastCall); 00046 break; 00047 default: 00048 return Info; 00049 } 00050 00051 unsigned argNum = 1; 00052 for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); 00053 AI != AE; ++AI, ++argNum) { 00054 const Type* Ty = AI->getType(); 00055 00056 // 'Dereference' type in case of byval parameter attribute 00057 if (F->paramHasAttr(argNum, Attribute::ByVal)) 00058 Ty = cast<PointerType>(Ty)->getElementType(); 00059 00060 // Size should be aligned to DWORD boundary 00061 Size += ((TD->getTypePaddedSize(Ty) + 3)/4)*4; 00062 } 00063 00064 // We're not supporting tooooo huge arguments :) 00065 Info.setBytesToPopOnReturn((unsigned int)Size); 00066 return Info; 00067 } 00068 00069 00070 /// decorateName - Query FunctionInfoMap and use this information for various 00071 /// name decoration. 00072 void X86IntelAsmPrinter::decorateName(std::string &Name, 00073 const GlobalValue *GV) { 00074 const Function *F = dyn_cast<Function>(GV); 00075 if (!F) return; 00076 00077 // We don't want to decorate non-stdcall or non-fastcall functions right now 00078 unsigned CC = F->getCallingConv(); 00079 if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall) 00080 return; 00081 00082 FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F); 00083 00084 const X86MachineFunctionInfo *Info; 00085 if (info_item == FunctionInfoMap.end()) { 00086 // Calculate apropriate function info and populate map 00087 FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData()); 00088 Info = &FunctionInfoMap[F]; 00089 } else { 00090 Info = &info_item->second; 00091 } 00092 00093 const FunctionType *FT = F->getFunctionType(); 00094 switch (Info->getDecorationStyle()) { 00095 case None: 00096 break; 00097 case StdCall: 00098 // "Pure" variadic functions do not receive @0 suffix. 00099 if (!FT->isVarArg() || (FT->getNumParams() == 0) || 00100 (FT->getNumParams() == 1 && F->hasStructRetAttr())) 00101 Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); 00102 break; 00103 case FastCall: 00104 // "Pure" variadic functions do not receive @0 suffix. 00105 if (!FT->isVarArg() || (FT->getNumParams() == 0) || 00106 (FT->getNumParams() == 1 && F->hasStructRetAttr())) 00107 Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); 00108 00109 if (Name[0] == '_') 00110 Name[0] = '@'; 00111 else 00112 Name = '@' + Name; 00113 00114 break; 00115 default: 00116 assert(0 && "Unsupported DecorationStyle"); 00117 } 00118 } 00119 00120 /// runOnMachineFunction - This uses the printMachineInstruction() 00121 /// method to print assembly for each instruction. 00122 /// 00123 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00124 SetupMachineFunction(MF); 00125 O << "\n\n"; 00126 00127 // Print out constants referenced by the function 00128 EmitConstantPool(MF.getConstantPool()); 00129 00130 // Print out labels for the function. 00131 const Function *F = MF.getFunction(); 00132 unsigned CC = F->getCallingConv(); 00133 00134 // Populate function information map. Actually, We don't want to populate 00135 // non-stdcall or non-fastcall functions' information right now. 00136 if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall) 00137 FunctionInfoMap[F] = *MF.getInfo<X86MachineFunctionInfo>(); 00138 00139 decorateName(CurrentFnName, F); 00140 00141 SwitchToTextSection("_text", F); 00142 00143 unsigned FnAlign = 4; 00144 if (F->hasFnAttr(Attribute::OptimizeForSize)) 00145 FnAlign = 1; 00146 switch (F->getLinkage()) { 00147 default: assert(0 && "Unsupported linkage type!"); 00148 case Function::PrivateLinkage: 00149 case Function::InternalLinkage: 00150 EmitAlignment(FnAlign); 00151 break; 00152 case Function::DLLExportLinkage: 00153 DLLExportedFns.insert(CurrentFnName); 00154 //FALLS THROUGH 00155 case Function::ExternalLinkage: 00156 O << "\tpublic " << CurrentFnName << "\n"; 00157 EmitAlignment(FnAlign); 00158 break; 00159 } 00160 00161 O << CurrentFnName << "\tproc near\n"; 00162 00163 // Print out code for the function. 00164 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00165 I != E; ++I) { 00166 // Print a label for the basic block if there are any predecessors. 00167 if (!I->pred_empty()) { 00168 printBasicBlockLabel(I, true, true); 00169 O << '\n'; 00170 } 00171 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 00172 II != E; ++II) { 00173 // Print the assembly for the instruction. 00174 printMachineInstruction(II); 00175 } 00176 } 00177 00178 // Print out jump tables referenced by the function. 00179 EmitJumpTableInfo(MF.getJumpTableInfo(), MF); 00180 00181 O << CurrentFnName << "\tendp\n"; 00182 00183 O.flush(); 00184 00185 // We didn't modify anything. 00186 return false; 00187 } 00188 00189 void X86IntelAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) { 00190 unsigned char value = MI->getOperand(Op).getImm(); 00191 assert(value <= 7 && "Invalid ssecc argument!"); 00192 switch (value) { 00193 case 0: O << "eq"; break; 00194 case 1: O << "lt"; break; 00195 case 2: O << "le"; break; 00196 case 3: O << "unord"; break; 00197 case 4: O << "neq"; break; 00198 case 5: O << "nlt"; break; 00199 case 6: O << "nle"; break; 00200 case 7: O << "ord"; break; 00201 } 00202 } 00203 00204 void X86IntelAsmPrinter::printOp(const MachineOperand &MO, 00205 const char *Modifier) { 00206 switch (MO.getType()) { 00207 case MachineOperand::MO_Register: { 00208 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) { 00209 unsigned Reg = MO.getReg(); 00210 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { 00211 MVT VT = (strcmp(Modifier,"subreg64") == 0) ? 00212 MVT::i64 : ((strcmp(Modifier, "subreg32") == 0) ? MVT::i32 : 00213 ((strcmp(Modifier,"subreg16") == 0) ? MVT::i16 :MVT::i8)); 00214 Reg = getX86SubSuperRegister(Reg, VT); 00215 } 00216 O << TRI->getName(Reg); 00217 } else 00218 O << "reg" << MO.getReg(); 00219 return; 00220 } 00221 case MachineOperand::MO_Immediate: 00222 O << MO.getImm(); 00223 return; 00224 case MachineOperand::MO_MachineBasicBlock: 00225 printBasicBlockLabel(MO.getMBB()); 00226 return; 00227 case MachineOperand::MO_JumpTableIndex: { 00228 bool isMemOp = Modifier && !strcmp(Modifier, "mem"); 00229 if (!isMemOp) O << "OFFSET "; 00230 O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 00231 << "_" << MO.getIndex(); 00232 return; 00233 } 00234 case MachineOperand::MO_ConstantPoolIndex: { 00235 bool isMemOp = Modifier && !strcmp(Modifier, "mem"); 00236 if (!isMemOp) O << "OFFSET "; 00237 O << "[" << TAI->getPrivateGlobalPrefix() << "CPI" 00238 << getFunctionNumber() << "_" << MO.getIndex(); 00239 printOffset(MO.getOffset()); 00240 O << "]"; 00241 return; 00242 } 00243 case MachineOperand::MO_GlobalAddress: { 00244 bool isCallOp = Modifier && !strcmp(Modifier, "call"); 00245 bool isMemOp = Modifier && !strcmp(Modifier, "mem"); 00246 GlobalValue *GV = MO.getGlobal(); 00247 std::string Name = Mang->getValueName(GV); 00248 00249 decorateName(Name, GV); 00250 00251 if (!isMemOp && !isCallOp) O << "OFFSET "; 00252 if (GV->hasDLLImportLinkage()) { 00253 // FIXME: This should be fixed with full support of stdcall & fastcall 00254 // CC's 00255 O << "__imp_"; 00256 } 00257 O << Name; 00258 printOffset(MO.getOffset()); 00259 return; 00260 } 00261 case MachineOperand::MO_ExternalSymbol: { 00262 bool isCallOp = Modifier && !strcmp(Modifier, "call"); 00263 if (!isCallOp) O << "OFFSET "; 00264 O << TAI->getGlobalPrefix() << MO.getSymbolName(); 00265 return; 00266 } 00267 default: 00268 O << "<unknown operand type>"; return; 00269 } 00270 } 00271 00272 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, 00273 const char *Modifier) { 00274 assert(isMem(MI, Op) && "Invalid memory reference!"); 00275 00276 const MachineOperand &BaseReg = MI->getOperand(Op); 00277 int ScaleVal = MI->getOperand(Op+1).getImm(); 00278 const MachineOperand &IndexReg = MI->getOperand(Op+2); 00279 const MachineOperand &DispSpec = MI->getOperand(Op+3); 00280 00281 O << "["; 00282 bool NeedPlus = false; 00283 if (BaseReg.getReg()) { 00284 printOp(BaseReg, Modifier); 00285 NeedPlus = true; 00286 } 00287 00288 if (IndexReg.getReg()) { 00289 if (NeedPlus) O << " + "; 00290 if (ScaleVal != 1) 00291 O << ScaleVal << "*"; 00292 printOp(IndexReg, Modifier); 00293 NeedPlus = true; 00294 } 00295 00296 if (DispSpec.isGlobal() || DispSpec.isCPI() || 00297 DispSpec.isJTI()) { 00298 if (NeedPlus) 00299 O << " + "; 00300 printOp(DispSpec, "mem"); 00301 } else { 00302 int DispVal = DispSpec.getImm(); 00303 if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) { 00304 if (NeedPlus) { 00305 if (DispVal > 0) 00306 O << " + "; 00307 else { 00308 O << " - "; 00309 DispVal = -DispVal; 00310 } 00311 } 00312 O << DispVal; 00313 } 00314 } 00315 O << "]"; 00316 } 00317 00318 void X86IntelAsmPrinter::printPICJumpTableSetLabel(unsigned uid, 00319 const MachineBasicBlock *MBB) const { 00320 if (!TAI->getSetDirective()) 00321 return; 00322 00323 O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() 00324 << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; 00325 printBasicBlockLabel(MBB, false, false, false); 00326 O << '-' << "\"L" << getFunctionNumber() << "$pb\"'\n"; 00327 } 00328 00329 void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { 00330 O << "\"L" << getFunctionNumber() << "$pb\"\n"; 00331 O << "\"L" << getFunctionNumber() << "$pb\":"; 00332 } 00333 00334 bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, 00335 const char Mode) { 00336 unsigned Reg = MO.getReg(); 00337 switch (Mode) { 00338 default: return true; // Unknown mode. 00339 case 'b': // Print QImode register 00340 Reg = getX86SubSuperRegister(Reg, MVT::i8); 00341 break; 00342 case 'h': // Print QImode high register 00343 Reg = getX86SubSuperRegister(Reg, MVT::i8, true); 00344 break; 00345 case 'w': // Print HImode register 00346 Reg = getX86SubSuperRegister(Reg, MVT::i16); 00347 break; 00348 case 'k': // Print SImode register 00349 Reg = getX86SubSuperRegister(Reg, MVT::i32); 00350 break; 00351 } 00352 00353 O << '%' << TRI->getName(Reg); 00354 return false; 00355 } 00356 00357 /// PrintAsmOperand - Print out an operand for an inline asm expression. 00358 /// 00359 bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00360 unsigned AsmVariant, 00361 const char *ExtraCode) { 00362 // Does this asm operand have a single letter operand modifier? 00363 if (ExtraCode && ExtraCode[0]) { 00364 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00365 00366 switch (ExtraCode[0]) { 00367 default: return true; // Unknown modifier. 00368 case 'b': // Print QImode register 00369 case 'h': // Print QImode high register 00370 case 'w': // Print HImode register 00371 case 'k': // Print SImode register 00372 return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]); 00373 } 00374 } 00375 00376 printOperand(MI, OpNo); 00377 return false; 00378 } 00379 00380 bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00381 unsigned OpNo, 00382 unsigned AsmVariant, 00383 const char *ExtraCode) { 00384 if (ExtraCode && ExtraCode[0]) 00385 return true; // Unknown modifier. 00386 printMemReference(MI, OpNo); 00387 return false; 00388 } 00389 00390 /// printMachineInstruction -- Print out a single X86 LLVM instruction 00391 /// MI in Intel syntax to the current output stream. 00392 /// 00393 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 00394 ++EmittedInsts; 00395 00396 // Call the autogenerated instruction printer routines. 00397 printInstruction(MI); 00398 } 00399 00400 bool X86IntelAsmPrinter::doInitialization(Module &M) { 00401 bool Result = AsmPrinter::doInitialization(M); 00402 00403 Mang->markCharUnacceptable('.'); 00404 00405 O << "\t.686\n\t.model flat\n\n"; 00406 00407 // Emit declarations for external functions. 00408 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 00409 if (I->isDeclaration()) { 00410 std::string Name = Mang->getValueName(I); 00411 decorateName(Name, I); 00412 00413 O << "\textern " ; 00414 if (I->hasDLLImportLinkage()) { 00415 O << "__imp_"; 00416 } 00417 O << Name << ":near\n"; 00418 } 00419 00420 // Emit declarations for external globals. Note that VC++ always declares 00421 // external globals to have type byte, and if that's good enough for VC++... 00422 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 00423 I != E; ++I) { 00424 if (I->isDeclaration()) { 00425 std::string Name = Mang->getValueName(I); 00426 00427 O << "\textern " ; 00428 if (I->hasDLLImportLinkage()) { 00429 O << "__imp_"; 00430 } 00431 O << Name << ":byte\n"; 00432 } 00433 } 00434 00435 return Result; 00436 } 00437 00438 bool X86IntelAsmPrinter::doFinalization(Module &M) { 00439 const TargetData *TD = TM.getTargetData(); 00440 00441 // Print out module-level global variables here. 00442 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 00443 I != E; ++I) { 00444 if (I->isDeclaration()) continue; // External global require no code 00445 00446 // Check to see if this is a special global used by LLVM, if so, emit it. 00447 if (EmitSpecialLLVMGlobal(I)) 00448 continue; 00449 00450 std::string name = Mang->getValueName(I); 00451 Constant *C = I->getInitializer(); 00452 unsigned Align = TD->getPreferredAlignmentLog(I); 00453 bool bCustomSegment = false; 00454 00455 switch (I->getLinkage()) { 00456 case GlobalValue::CommonLinkage: 00457 case GlobalValue::LinkOnceLinkage: 00458 case GlobalValue::WeakLinkage: 00459 SwitchToDataSection(""); 00460 O << name << "?\tsegment common 'COMMON'\n"; 00461 bCustomSegment = true; 00462 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 00463 // are also available. 00464 break; 00465 case GlobalValue::AppendingLinkage: 00466 SwitchToDataSection(""); 00467 O << name << "?\tsegment public 'DATA'\n"; 00468 bCustomSegment = true; 00469 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 00470 // are also available. 00471 break; 00472 case GlobalValue::DLLExportLinkage: 00473 DLLExportedGVs.insert(name); 00474 // FALL THROUGH 00475 case GlobalValue::ExternalLinkage: 00476 O << "\tpublic " << name << "\n"; 00477 // FALL THROUGH 00478 case GlobalValue::InternalLinkage: 00479 SwitchToSection(TAI->getDataSection()); 00480 break; 00481 default: 00482 assert(0 && "Unknown linkage type!"); 00483 } 00484 00485 if (!bCustomSegment) 00486 EmitAlignment(Align, I); 00487 00488 O << name << ":\t\t\t\t" << TAI->getCommentString() 00489 << " " << I->getName() << '\n'; 00490 00491 EmitGlobalConstant(C); 00492 00493 if (bCustomSegment) 00494 O << name << "?\tends\n"; 00495 } 00496 00497 // Output linker support code for dllexported globals 00498 if (!DLLExportedGVs.empty() || !DLLExportedFns.empty()) { 00499 SwitchToDataSection(""); 00500 O << "; WARNING: The following code is valid only with MASM v8.x" 00501 << "and (possible) higher\n" 00502 << "; This version of MASM is usually shipped with Microsoft " 00503 << "Visual Studio 2005\n" 00504 << "; or (possible) further versions. Unfortunately, there is no " 00505 << "way to support\n" 00506 << "; dllexported symbols in the earlier versions of MASM in fully " 00507 << "automatic way\n\n"; 00508 O << "_drectve\t segment info alias('.drectve')\n"; 00509 } 00510 00511 for (StringSet<>::iterator i = DLLExportedGVs.begin(), 00512 e = DLLExportedGVs.end(); 00513 i != e; ++i) 00514 O << "\t db ' /EXPORT:" << i->getKeyData() << ",data'\n"; 00515 00516 for (StringSet<>::iterator i = DLLExportedFns.begin(), 00517 e = DLLExportedFns.end(); 00518 i != e; ++i) 00519 O << "\t db ' /EXPORT:" << i->getKeyData() << "'\n"; 00520 00521 if (!DLLExportedGVs.empty() || !DLLExportedFns.empty()) 00522 O << "_drectve\t ends\n"; 00523 00524 // Bypass X86SharedAsmPrinter::doFinalization(). 00525 bool Result = AsmPrinter::doFinalization(M); 00526 SwitchToDataSection(""); 00527 O << "\tend\n"; 00528 return Result; 00529 } 00530 00531 void X86IntelAsmPrinter::EmitString(const ConstantArray *CVA) const { 00532 unsigned NumElts = CVA->getNumOperands(); 00533 if (NumElts) { 00534 // ML does not have escape sequences except '' for '. It also has a maximum 00535 // string length of 255. 00536 unsigned len = 0; 00537 bool inString = false; 00538 for (unsigned i = 0; i < NumElts; i++) { 00539 int n = cast<ConstantInt>(CVA->getOperand(i))->getZExtValue() & 255; 00540 if (len == 0) 00541 O << "\tdb "; 00542 00543 if (n >= 32 && n <= 127) { 00544 if (!inString) { 00545 if (len > 0) { 00546 O << ",'"; 00547 len += 2; 00548 } else { 00549 O << "'"; 00550 len++; 00551 } 00552 inString = true; 00553 } 00554 if (n == '\'') { 00555 O << "'"; 00556 len++; 00557 } 00558 O << char(n); 00559 } else { 00560 if (inString) { 00561 O << "'"; 00562 len++; 00563 inString = false; 00564 } 00565 if (len > 0) { 00566 O << ","; 00567 len++; 00568 } 00569 O << n; 00570 len += 1 + (n > 9) + (n > 99); 00571 } 00572 00573 if (len > 60) { 00574 if (inString) { 00575 O << "'"; 00576 inString = false; 00577 } 00578 O << "\n"; 00579 len = 0; 00580 } 00581 } 00582 00583 if (len > 0) { 00584 if (inString) 00585 O << "'"; 00586 O << "\n"; 00587 } 00588 } 00589 } 00590 00591 // Include the auto-generated portion of the assembly writer. 00592 #include "X86GenAsmWriter1.inc"