LLVM API Documentation

MipsAsmPrinter.cpp

Go to the documentation of this file.
00001 //===-- MipsAsmPrinter.cpp - Mips LLVM assembly writer --------------------===//
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 GAS-format MIPS assembly language.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #define DEBUG_TYPE "mips-asm-printer"
00016 
00017 #include "Mips.h"
00018 #include "MipsSubtarget.h"
00019 #include "MipsInstrInfo.h"
00020 #include "MipsTargetMachine.h"
00021 #include "MipsMachineFunction.h"
00022 #include "llvm/Constants.h"
00023 #include "llvm/DerivedTypes.h"
00024 #include "llvm/Module.h"
00025 #include "llvm/CodeGen/AsmPrinter.h"
00026 #include "llvm/CodeGen/MachineFunctionPass.h"
00027 #include "llvm/CodeGen/MachineConstantPool.h"
00028 #include "llvm/CodeGen/MachineFrameInfo.h"
00029 #include "llvm/CodeGen/MachineInstr.h"
00030 #include "llvm/Target/TargetAsmInfo.h"
00031 #include "llvm/Target/TargetData.h"
00032 #include "llvm/Target/TargetMachine.h"
00033 #include "llvm/Target/TargetOptions.h"
00034 #include "llvm/Support/Mangler.h"
00035 #include "llvm/ADT/Statistic.h"
00036 #include "llvm/ADT/StringExtras.h"
00037 #include "llvm/Support/Debug.h"
00038 #include "llvm/Support/CommandLine.h"
00039 #include "llvm/Support/MathExtras.h"
00040 #include "llvm/Support/raw_ostream.h"
00041 #include <cctype>
00042 
00043 using namespace llvm;
00044 
00045 STATISTIC(EmittedInsts, "Number of machine instrs printed");
00046 
00047 namespace {
00048   struct VISIBILITY_HIDDEN MipsAsmPrinter : public AsmPrinter {
00049 
00050     const MipsSubtarget *Subtarget;
00051 
00052     MipsAsmPrinter(raw_ostream &O, MipsTargetMachine &TM, 
00053                    const TargetAsmInfo *T): 
00054                    AsmPrinter(O, TM, T) {
00055       Subtarget = &TM.getSubtarget<MipsSubtarget>();
00056     }
00057 
00058     virtual const char *getPassName() const {
00059       return "Mips Assembly Printer";
00060     }
00061 
00062     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 
00063                          unsigned AsmVariant, const char *ExtraCode);
00064     void printOperand(const MachineInstr *MI, int opNum);
00065     void printUnsignedImm(const MachineInstr *MI, int opNum);
00066     void printMemOperand(const MachineInstr *MI, int opNum, 
00067                          const char *Modifier = 0);
00068     void printFCCOperand(const MachineInstr *MI, int opNum, 
00069                          const char *Modifier = 0);
00070     void printModuleLevelGV(const GlobalVariable* GVar);
00071     void printSavedRegsBitmask(MachineFunction &MF);
00072     void printHex32(unsigned int Value);
00073 
00074     const char *emitCurrentABIString(void);
00075     void emitFunctionStart(MachineFunction &MF);
00076     void emitFunctionEnd(MachineFunction &MF);
00077     void emitFrameDirective(MachineFunction &MF);
00078 
00079     bool printInstruction(const MachineInstr *MI);  // autogenerated.
00080     bool runOnMachineFunction(MachineFunction &F);
00081     bool doInitialization(Module &M);
00082     bool doFinalization(Module &M);
00083   };
00084 } // end of anonymous namespace
00085 
00086 #include "MipsGenAsmWriter.inc"
00087 
00088 /// createMipsCodePrinterPass - Returns a pass that prints the MIPS
00089 /// assembly code for a MachineFunction to the given output stream,
00090 /// using the given target machine description.  This should work
00091 /// regardless of whether the function is in SSA form.
00092 FunctionPass *llvm::createMipsCodePrinterPass(raw_ostream &o,
00093                                               MipsTargetMachine &tm) 
00094 {
00095   return new MipsAsmPrinter(o, tm, tm.getTargetAsmInfo());
00096 }
00097 
00098 //===----------------------------------------------------------------------===//
00099 //
00100 //  Mips Asm Directives
00101 //
00102 //  -- Frame directive "frame Stackpointer, Stacksize, RARegister"
00103 //  Describe the stack frame.
00104 //
00105 //  -- Mask directives "(f)mask  bitmask, offset" 
00106 //  Tells the assembler which registers are saved and where.
00107 //  bitmask - contain a little endian bitset indicating which registers are 
00108 //            saved on function prologue (e.g. with a 0x80000000 mask, the 
00109 //            assembler knows the register 31 (RA) is saved at prologue.
00110 //  offset  - the position before stack pointer subtraction indicating where 
00111 //            the first saved register on prologue is located. (e.g. with a
00112 //
00113 //  Consider the following function prologue:
00114 //
00115 //    .frame  $fp,48,$ra
00116 //    .mask   0xc0000000,-8
00117 //       addiu $sp, $sp, -48
00118 //       sw $ra, 40($sp)
00119 //       sw $fp, 36($sp)
00120 //
00121 //    With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 
00122 //    30 (FP) are saved at prologue. As the save order on prologue is from 
00123 //    left to right, RA is saved first. A -8 offset means that after the 
00124 //    stack pointer subtration, the first register in the mask (RA) will be
00125 //    saved at address 48-8=40.
00126 //
00127 //===----------------------------------------------------------------------===//
00128 
00129 //===----------------------------------------------------------------------===//
00130 // Mask directives
00131 //===----------------------------------------------------------------------===//
00132 
00133 // Create a bitmask with all callee saved registers for CPU or Floating Point 
00134 // registers. For CPU registers consider RA, GP and FP for saving if necessary.
00135 void MipsAsmPrinter::
00136 printSavedRegsBitmask(MachineFunction &MF)
00137 {
00138   const TargetRegisterInfo &RI = *TM.getRegisterInfo();
00139   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
00140              
00141   // CPU and FPU Saved Registers Bitmasks
00142   unsigned int CPUBitmask = 0;
00143   unsigned int FPUBitmask = 0;
00144 
00145   // Set the CPU and FPU Bitmasks
00146   MachineFrameInfo *MFI = MF.getFrameInfo();
00147   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
00148   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
00149     unsigned RegNum = MipsRegisterInfo::getRegisterNumbering(CSI[i].getReg());
00150     if (CSI[i].getRegClass() == Mips::CPURegsRegisterClass)
00151       CPUBitmask |= (1 << RegNum);
00152     else
00153       FPUBitmask |= (1 << RegNum);
00154   }
00155 
00156   // Return Address and Frame registers must also be set in CPUBitmask.
00157   if (RI.hasFP(MF)) 
00158     CPUBitmask |= (1 << MipsRegisterInfo::
00159                 getRegisterNumbering(RI.getFrameRegister(MF)));
00160   
00161   if (MF.getFrameInfo()->hasCalls()) 
00162     CPUBitmask |= (1 << MipsRegisterInfo::
00163                 getRegisterNumbering(RI.getRARegister()));
00164 
00165   // Print CPUBitmask
00166   O << "\t.mask \t"; printHex32(CPUBitmask); O << ','
00167     << MipsFI->getCPUTopSavedRegOff() << '\n';
00168 
00169   // Print FPUBitmask
00170   O << "\t.fmask\t"; printHex32(FPUBitmask); O << ","
00171     << MipsFI->getFPUTopSavedRegOff() << '\n';
00172 }
00173 
00174 // Print a 32 bit hex number with all numbers.
00175 void MipsAsmPrinter::
00176 printHex32(unsigned int Value) 
00177 {
00178   O << "0x";
00179   for (int i = 7; i >= 0; i--) 
00180     O << utohexstr( (Value & (0xF << (i*4))) >> (i*4) );
00181 }
00182 
00183 //===----------------------------------------------------------------------===//
00184 // Frame and Set directives
00185 //===----------------------------------------------------------------------===//
00186 
00187 /// Frame Directive
00188 void MipsAsmPrinter::
00189 emitFrameDirective(MachineFunction &MF)
00190 {
00191   const TargetRegisterInfo &RI = *TM.getRegisterInfo();
00192 
00193   unsigned stackReg  = RI.getFrameRegister(MF);
00194   unsigned returnReg = RI.getRARegister();
00195   unsigned stackSize = MF.getFrameInfo()->getStackSize();
00196 
00197 
00198   O << "\t.frame\t" << '$' << LowercaseString(RI.get(stackReg).AsmName)
00199                     << ',' << stackSize << ','
00200                     << '$' << LowercaseString(RI.get(returnReg).AsmName)
00201                     << '\n';
00202 }
00203 
00204 /// Emit Set directives.
00205 const char * MipsAsmPrinter::
00206 emitCurrentABIString(void) 
00207 {  
00208   switch(Subtarget->getTargetABI()) {
00209     case MipsSubtarget::O32:  return "abi32";  
00210     case MipsSubtarget::O64:  return "abiO64";
00211     case MipsSubtarget::N32:  return "abiN32";
00212     case MipsSubtarget::N64:  return "abi64";
00213     case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
00214     default: break;
00215   }
00216 
00217   assert(0 && "Unknown Mips ABI");
00218   return NULL;
00219 }  
00220 
00221 /// Emit the directives used by GAS on the start of functions
00222 void MipsAsmPrinter::
00223 emitFunctionStart(MachineFunction &MF)
00224 {
00225   // Print out the label for the function.
00226   const Function *F = MF.getFunction();
00227   SwitchToSection(TAI->SectionForGlobal(F));
00228 
00229   // 2 bits aligned
00230   EmitAlignment(2, F);
00231 
00232   O << "\t.globl\t"  << CurrentFnName << '\n';
00233   O << "\t.ent\t"    << CurrentFnName << '\n';
00234 
00235   printVisibility(CurrentFnName, F->getVisibility());
00236 
00237   if ((TAI->hasDotTypeDotSizeDirective()) && Subtarget->isLinux())
00238     O << "\t.type\t"   << CurrentFnName << ", @function\n";
00239 
00240   O << CurrentFnName << ":\n";
00241 
00242   emitFrameDirective(MF);
00243   printSavedRegsBitmask(MF);
00244 
00245   O << '\n';
00246 }
00247 
00248 /// Emit the directives used by GAS on the end of functions
00249 void MipsAsmPrinter::
00250 emitFunctionEnd(MachineFunction &MF) 
00251 {
00252   // There are instruction for this macros, but they must
00253   // always be at the function end, and we can't emit and
00254   // break with BB logic. 
00255   O << "\t.set\tmacro\n"; 
00256   O << "\t.set\treorder\n"; 
00257 
00258   O << "\t.end\t" << CurrentFnName << '\n';
00259   if (TAI->hasDotTypeDotSizeDirective() && !Subtarget->isLinux())
00260     O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
00261 }
00262 
00263 /// runOnMachineFunction - This uses the printMachineInstruction()
00264 /// method to print assembly for each instruction.
00265 bool MipsAsmPrinter::
00266 runOnMachineFunction(MachineFunction &MF) 
00267 {
00268   SetupMachineFunction(MF);
00269 
00270   // Print out constants referenced by the function
00271   EmitConstantPool(MF.getConstantPool());
00272 
00273   // Print out jump tables referenced by the function
00274   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
00275 
00276   O << "\n\n";
00277 
00278   // Emit the function start directives
00279   emitFunctionStart(MF);
00280 
00281   // Print out code for the function.
00282   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
00283        I != E; ++I) {
00284 
00285     // Print a label for the basic block.
00286     if (I != MF.begin()) {
00287       printBasicBlockLabel(I, true, true);
00288       O << '\n';
00289     }
00290 
00291     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
00292          II != E; ++II) {
00293       // Print the assembly for the instruction.
00294       printInstruction(II);
00295       ++EmittedInsts;
00296     }
00297 
00298     // Each Basic Block is separated by a newline
00299     O << '\n';
00300   }
00301 
00302   // Emit function end directives
00303   emitFunctionEnd(MF);
00304 
00305   // We didn't modify anything.
00306   return false;
00307 }
00308 
00309 // Print out an operand for an inline asm expression.
00310 bool MipsAsmPrinter::
00311 PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 
00312                 unsigned AsmVariant, const char *ExtraCode) 
00313 {
00314   // Does this asm operand have a single letter operand modifier?
00315   if (ExtraCode && ExtraCode[0]) 
00316     return true; // Unknown modifier.
00317 
00318   printOperand(MI, OpNo);
00319   return false;
00320 }
00321 
00322 void MipsAsmPrinter::
00323 printOperand(const MachineInstr *MI, int opNum) 
00324 {
00325   const MachineOperand &MO = MI->getOperand(opNum);
00326   const TargetRegisterInfo  &RI = *TM.getRegisterInfo();
00327   bool closeP = false;
00328   bool isPIC = (TM.getRelocationModel() == Reloc::PIC_);
00329   bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
00330 
00331   // %hi and %lo used on mips gas to load global addresses on
00332   // static code. %got is used to load global addresses when 
00333   // using PIC_. %call16 is used to load direct call targets
00334   // on PIC_ and small code size. %call_lo and %call_hi load 
00335   // direct call targets on PIC_ and large code size.
00336   if (MI->getOpcode() == Mips::LUi && !MO.isReg() && !MO.isImm()) {
00337     if ((isPIC) && (isCodeLarge))
00338       O << "%call_hi(";
00339     else
00340       O << "%hi(";
00341     closeP = true;
00342   } else if ((MI->getOpcode() == Mips::ADDiu) && !MO.isReg() && !MO.isImm()) {
00343     const MachineOperand &firstMO = MI->getOperand(opNum-1);
00344     if (firstMO.getReg() == Mips::GP)
00345       O << "%gp_rel(";
00346     else
00347       O << "%lo(";
00348     closeP = true;
00349   } else if ((isPIC) && (MI->getOpcode() == Mips::LW) &&
00350              (!MO.isReg()) && (!MO.isImm())) {
00351     const MachineOperand &firstMO = MI->getOperand(opNum-1);
00352     const MachineOperand &lastMO  = MI->getOperand(opNum+1);
00353     if ((firstMO.isReg()) && (lastMO.isReg())) {
00354       if ((firstMO.getReg() == Mips::T9) && (lastMO.getReg() == Mips::GP) 
00355           && (!isCodeLarge))
00356         O << "%call16(";
00357       else if ((firstMO.getReg() != Mips::T9) && (lastMO.getReg() == Mips::GP))
00358         O << "%got(";
00359       else if ((firstMO.getReg() == Mips::T9) && (lastMO.getReg() != Mips::GP) 
00360                && (isCodeLarge))
00361         O << "%call_lo(";
00362       closeP = true;
00363     }
00364   }
00365  
00366   switch (MO.getType()) 
00367   {
00368     case MachineOperand::MO_Register:
00369       if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
00370         O << '$' << LowercaseString (RI.get(MO.getReg()).AsmName);
00371       else
00372         O << '$' << MO.getReg();
00373       break;
00374 
00375     case MachineOperand::MO_Immediate:
00376       O << (short int)MO.getImm();
00377       break;
00378 
00379     case MachineOperand::MO_MachineBasicBlock:
00380       printBasicBlockLabel(MO.getMBB());
00381       return;
00382 
00383     case MachineOperand::MO_GlobalAddress:
00384       {
00385         const GlobalValue *GV = MO.getGlobal();
00386         O << Mang->getValueName(GV);
00387       }
00388       break;
00389 
00390     case MachineOperand::MO_ExternalSymbol:
00391       O << MO.getSymbolName();
00392       break;
00393 
00394     case MachineOperand::MO_JumpTableIndex:
00395       O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
00396       << '_' << MO.getIndex();
00397       break;
00398 
00399     case MachineOperand::MO_ConstantPoolIndex:
00400       O << TAI->getPrivateGlobalPrefix() << "CPI"
00401         << getFunctionNumber() << "_" << MO.getIndex();
00402       break;
00403   
00404     default:
00405       O << "<unknown operand type>"; abort (); break;
00406   }
00407 
00408   if (closeP) O << ")";
00409 }
00410 
00411 void MipsAsmPrinter::
00412 printUnsignedImm(const MachineInstr *MI, int opNum) 
00413 {
00414   const MachineOperand &MO = MI->getOperand(opNum);
00415   if (MO.getType() == MachineOperand::MO_Immediate)
00416     O << (unsigned short int)MO.getImm();
00417   else 
00418     printOperand(MI, opNum);
00419 }
00420 
00421 void MipsAsmPrinter::
00422 printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier) 
00423 {
00424   // when using stack locations for not load/store instructions
00425   // print the same way as all normal 3 operand instructions.
00426   if (Modifier && !strcmp(Modifier, "stackloc")) {
00427     printOperand(MI, opNum+1);
00428     O << ", ";
00429     printOperand(MI, opNum);
00430     return;
00431   }
00432 
00433   // Load/Store memory operands -- imm($reg) 
00434   // If PIC target the target is loaded as the 
00435   // pattern lw $25,%call16($28)
00436   printOperand(MI, opNum);
00437   O << "(";
00438   printOperand(MI, opNum+1);
00439   O << ")";
00440 }
00441 
00442 void MipsAsmPrinter::
00443 printFCCOperand(const MachineInstr *MI, int opNum, const char *Modifier) 
00444 {
00445   const MachineOperand& MO = MI->getOperand(opNum);
00446   O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 
00447 }
00448 
00449 bool MipsAsmPrinter::
00450 doInitialization(Module &M) 
00451 {
00452   Mang = new Mangler(M, "", TAI->getPrivateGlobalPrefix());
00453 
00454   // Tell the assembler which ABI we are using
00455   O << "\t.section .mdebug." << emitCurrentABIString() << '\n';
00456 
00457   // TODO: handle O64 ABI
00458   if (Subtarget->isABI_EABI())
00459     O << "\t.section .gcc_compiled_long" << 
00460       (Subtarget->isGP32bit() ? "32" : "64") << '\n';
00461 
00462   // return to previous section
00463   O << "\t.previous" << '\n'; 
00464 
00465   return false; // success
00466 }
00467 
00468 void MipsAsmPrinter::
00469 printModuleLevelGV(const GlobalVariable* GVar) {
00470   const TargetData *TD = TM.getTargetData();
00471 
00472   if (!GVar->hasInitializer())
00473     return;   // External global require no code
00474 
00475   // Check to see if this is a special global used by LLVM, if so, emit it.
00476   if (EmitSpecialLLVMGlobal(GVar))
00477     return;
00478 
00479   O << "\n\n";
00480   std::string name = Mang->getValueName(GVar);
00481   Constant *C = GVar->getInitializer();
00482   const Type *CTy = C->getType();
00483   unsigned Size = TD->getTypePaddedSize(CTy);
00484   const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
00485   bool printSizeAndType = true;
00486 
00487   // A data structure or array is aligned in memory to the largest
00488   // alignment boundary required by any data type inside it (this matches
00489   // the Preferred Type Alignment). For integral types, the alignment is
00490   // the type size.
00491   unsigned Align;
00492   if (CTy->getTypeID() == Type::IntegerTyID ||
00493       CTy->getTypeID() == Type::VoidTyID) {
00494     assert(!(Size & (Size-1)) && "Alignment is not a power of two!");
00495     Align = Log2_32(Size);
00496   } else
00497     Align = TD->getPreferredTypeAlignmentShift(CTy);
00498 
00499   printVisibility(name, GVar->getVisibility());
00500 
00501   SwitchToSection(TAI->SectionForGlobal(GVar));
00502 
00503   if (C->isNullValue() && !GVar->hasSection()) {
00504     if (!GVar->isThreadLocal() &&
00505         (GVar->hasLocalLinkage() || GVar->mayBeOverridden())) {
00506       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
00507 
00508       if (GVar->hasLocalLinkage())
00509         O << "\t.local\t" << name << '\n';
00510 
00511       O << TAI->getCOMMDirective() << name << ',' << Size;
00512       if (TAI->getCOMMDirectiveTakesAlignment())
00513         O << ',' << (1 << Align);
00514 
00515       O << '\n';
00516       return;
00517     }
00518   }
00519   switch (GVar->getLinkage()) {
00520    case GlobalValue::LinkOnceLinkage:
00521    case GlobalValue::CommonLinkage:
00522    case GlobalValue::WeakLinkage:
00523     // FIXME: Verify correct for weak.
00524     // Nonnull linkonce -> weak
00525     O << "\t.weak " << name << '\n';
00526     break;
00527    case GlobalValue::AppendingLinkage:
00528     // FIXME: appending linkage variables should go into a section of their name
00529     // or something.  For now, just emit them as external.
00530    case GlobalValue::ExternalLinkage:
00531     // If external or appending, declare as a global symbol
00532     O << TAI->getGlobalDirective() << name << '\n';
00533     // Fall Through
00534    case GlobalValue::PrivateLinkage:
00535    case GlobalValue::InternalLinkage:
00536     if (CVA && CVA->isCString())
00537       printSizeAndType = false;
00538     break;
00539    case GlobalValue::GhostLinkage:
00540     cerr << "Should not have any unmaterialized functions!\n";
00541     abort();
00542    case GlobalValue::DLLImportLinkage:
00543     cerr << "DLLImport linkage is not supported by this target!\n";
00544     abort();
00545    case GlobalValue::DLLExportLinkage:
00546     cerr << "DLLExport linkage is not supported by this target!\n";
00547     abort();
00548    default:
00549     assert(0 && "Unknown linkage type!");
00550   }
00551 
00552   EmitAlignment(Align, GVar);
00553 
00554   if (TAI->hasDotTypeDotSizeDirective() && printSizeAndType) {
00555     O << "\t.type " << name << ",@object\n";
00556     O << "\t.size " << name << ',' << Size << '\n';
00557   }
00558 
00559   O << name << ":\n";
00560   EmitGlobalConstant(C);
00561 }
00562 
00563 bool MipsAsmPrinter::
00564 doFinalization(Module &M)
00565 {
00566   // Print out module-level global variables here.
00567   for (Module::const_global_iterator I = M.global_begin(),
00568          E = M.global_end(); I != E; ++I)
00569     printModuleLevelGV(I);
00570 
00571   O << '\n';
00572 
00573   return AsmPrinter::doFinalization(M);
00574 }