LLVM API Documentation

X86ATTAsmPrinter.cpp

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