LLVM API Documentation

X86IntelAsmPrinter.cpp

Go to the documentation of this file.
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"