LLVM API Documentation
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 }