LLVM API Documentation
00001 //===-- SparcAsmPrinter.cpp - Sparc LLVM assembly writer ------------------===// 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 GAS-format SPARC assembly language. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "Sparc.h" 00016 #include "SparcInstrInfo.h" 00017 #include "llvm/Constants.h" 00018 #include "llvm/DerivedTypes.h" 00019 #include "llvm/Module.h" 00020 #include "llvm/Assembly/Writer.h" 00021 #include "llvm/CodeGen/AsmPrinter.h" 00022 #include "llvm/CodeGen/MachineFunctionPass.h" 00023 #include "llvm/CodeGen/MachineConstantPool.h" 00024 #include "llvm/CodeGen/MachineInstr.h" 00025 #include "llvm/Target/TargetMachine.h" 00026 #include "llvm/Support/Mangler.h" 00027 #include "llvm/ADT/Statistic.h" 00028 #include "llvm/ADT/StringExtras.h" 00029 #include "llvm/Support/CommandLine.h" 00030 #include "llvm/Support/MathExtras.h" 00031 #include <cctype> 00032 #include <iostream> 00033 using namespace llvm; 00034 00035 namespace { 00036 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); 00037 00038 struct SparcAsmPrinter : public AsmPrinter { 00039 SparcAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { 00040 Data16bitsDirective = "\t.half\t"; 00041 Data32bitsDirective = "\t.word\t"; 00042 Data64bitsDirective = 0; // .xword is only supported by V9. 00043 ZeroDirective = "\t.skip\t"; 00044 CommentString = "!"; 00045 ConstantPoolSection = "\t.section \".rodata\",#alloc\n"; 00046 } 00047 00048 /// We name each basic block in a Function with a unique number, so 00049 /// that we can consistently refer to them later. This is cleared 00050 /// at the beginning of each call to runOnMachineFunction(). 00051 /// 00052 typedef std::map<const Value *, unsigned> ValueMapTy; 00053 ValueMapTy NumberForBB; 00054 00055 virtual const char *getPassName() const { 00056 return "Sparc Assembly Printer"; 00057 } 00058 00059 void printOperand(const MachineInstr *MI, int opNum); 00060 void printMemOperand(const MachineInstr *MI, int opNum, 00061 const char *Modifier = 0); 00062 void printCCOperand(const MachineInstr *MI, int opNum); 00063 00064 bool printInstruction(const MachineInstr *MI); // autogenerated. 00065 bool runOnMachineFunction(MachineFunction &F); 00066 bool doInitialization(Module &M); 00067 bool doFinalization(Module &M); 00068 }; 00069 } // end of anonymous namespace 00070 00071 #include "SparcGenAsmWriter.inc" 00072 00073 /// createSparcCodePrinterPass - Returns a pass that prints the SPARC 00074 /// assembly code for a MachineFunction to the given output stream, 00075 /// using the given target machine description. This should work 00076 /// regardless of whether the function is in SSA form. 00077 /// 00078 FunctionPass *llvm::createSparcCodePrinterPass(std::ostream &o, 00079 TargetMachine &tm) { 00080 return new SparcAsmPrinter(o, tm); 00081 } 00082 00083 /// runOnMachineFunction - This uses the printMachineInstruction() 00084 /// method to print assembly for each instruction. 00085 /// 00086 bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00087 SetupMachineFunction(MF); 00088 00089 // Print out constants referenced by the function 00090 EmitConstantPool(MF.getConstantPool()); 00091 00092 // BBNumber is used here so that a given Printer will never give two 00093 // BBs the same name. (If you have a better way, please let me know!) 00094 static unsigned BBNumber = 0; 00095 00096 O << "\n\n"; 00097 // What's my mangled name? 00098 CurrentFnName = Mang->getValueName(MF.getFunction()); 00099 00100 // Print out labels for the function. 00101 O << "\t.text\n"; 00102 O << "\t.align 16\n"; 00103 O << "\t.globl\t" << CurrentFnName << "\n"; 00104 O << "\t.type\t" << CurrentFnName << ", #function\n"; 00105 O << CurrentFnName << ":\n"; 00106 00107 // Number each basic block so that we can consistently refer to them 00108 // in PC-relative references. 00109 NumberForBB.clear(); 00110 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00111 I != E; ++I) { 00112 NumberForBB[I->getBasicBlock()] = BBNumber++; 00113 } 00114 00115 // Print out code for the function. 00116 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00117 I != E; ++I) { 00118 // Print a label for the basic block. 00119 if (I != MF.begin()) 00120 O << ".LBB" << Mang->getValueName(MF.getFunction ()) 00121 << "_" << I->getNumber () << ":\t! " 00122 << I->getBasicBlock ()->getName () << "\n"; 00123 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 00124 II != E; ++II) { 00125 // Print the assembly for the instruction. 00126 O << "\t"; 00127 printInstruction(II); 00128 ++EmittedInsts; 00129 } 00130 } 00131 00132 // We didn't modify anything. 00133 return false; 00134 } 00135 00136 void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { 00137 const MachineOperand &MO = MI->getOperand (opNum); 00138 const MRegisterInfo &RI = *TM.getRegisterInfo(); 00139 bool CloseParen = false; 00140 if (MI->getOpcode() == SP::SETHIi && !MO.isRegister() && !MO.isImmediate()) { 00141 O << "%hi("; 00142 CloseParen = true; 00143 } else if ((MI->getOpcode() == SP::ORri || MI->getOpcode() == SP::ADDri) 00144 && !MO.isRegister() && !MO.isImmediate()) { 00145 O << "%lo("; 00146 CloseParen = true; 00147 } 00148 switch (MO.getType()) { 00149 case MachineOperand::MO_VirtualRegister: 00150 if (Value *V = MO.getVRegValueOrNull()) { 00151 O << "<" << V->getName() << ">"; 00152 break; 00153 } 00154 // FALLTHROUGH 00155 case MachineOperand::MO_MachineRegister: 00156 if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 00157 O << "%" << LowercaseString (RI.get(MO.getReg()).Name); 00158 else 00159 O << "%reg" << MO.getReg(); 00160 break; 00161 00162 case MachineOperand::MO_SignExtendedImmed: 00163 case MachineOperand::MO_UnextendedImmed: 00164 O << (int)MO.getImmedValue(); 00165 break; 00166 case MachineOperand::MO_MachineBasicBlock: { 00167 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 00168 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 00169 << "_" << MBBOp->getNumber () << "\t! " 00170 << MBBOp->getBasicBlock ()->getName (); 00171 return; 00172 } 00173 case MachineOperand::MO_PCRelativeDisp: 00174 std::cerr << "Shouldn't use addPCDisp() when building Sparc MachineInstrs"; 00175 abort (); 00176 return; 00177 case MachineOperand::MO_GlobalAddress: 00178 O << Mang->getValueName(MO.getGlobal()); 00179 break; 00180 case MachineOperand::MO_ExternalSymbol: 00181 O << MO.getSymbolName(); 00182 break; 00183 case MachineOperand::MO_ConstantPoolIndex: 00184 O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" 00185 << MO.getConstantPoolIndex(); 00186 break; 00187 default: 00188 O << "<unknown operand type>"; abort (); break; 00189 } 00190 if (CloseParen) O << ")"; 00191 } 00192 00193 void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, 00194 const char *Modifier) { 00195 printOperand(MI, opNum); 00196 00197 // If this is an ADD operand, emit it like normal operands. 00198 if (Modifier && !strcmp(Modifier, "arith")) { 00199 O << ", "; 00200 printOperand(MI, opNum+1); 00201 return; 00202 } 00203 00204 MachineOperand::MachineOperandType OpTy = MI->getOperand(opNum+1).getType(); 00205 00206 if ((OpTy == MachineOperand::MO_VirtualRegister || 00207 OpTy == MachineOperand::MO_MachineRegister) && 00208 MI->getOperand(opNum+1).getReg() == SP::G0) 00209 return; // don't print "+%g0" 00210 if ((OpTy == MachineOperand::MO_SignExtendedImmed || 00211 OpTy == MachineOperand::MO_UnextendedImmed) && 00212 MI->getOperand(opNum+1).getImmedValue() == 0) 00213 return; // don't print "+0" 00214 00215 O << "+"; 00216 if (OpTy == MachineOperand::MO_GlobalAddress || 00217 OpTy == MachineOperand::MO_ConstantPoolIndex) { 00218 O << "%lo("; 00219 printOperand(MI, opNum+1); 00220 O << ")"; 00221 } else { 00222 printOperand(MI, opNum+1); 00223 } 00224 } 00225 00226 void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { 00227 int CC = (int)MI->getOperand(opNum).getImmedValue(); 00228 O << SPARCCondCodeToString((SPCC::CondCodes)CC); 00229 } 00230 00231 00232 00233 bool SparcAsmPrinter::doInitialization(Module &M) { 00234 Mang = new Mangler(M); 00235 return false; // success 00236 } 00237 00238 bool SparcAsmPrinter::doFinalization(Module &M) { 00239 const TargetData &TD = TM.getTargetData(); 00240 00241 // Print out module-level global variables here. 00242 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 00243 I != E; ++I) 00244 if (I->hasInitializer()) { // External global require no code 00245 // Check to see if this is a special global used by LLVM, if so, emit it. 00246 if (EmitSpecialLLVMGlobal(I)) 00247 continue; 00248 00249 O << "\n\n"; 00250 std::string name = Mang->getValueName(I); 00251 Constant *C = I->getInitializer(); 00252 unsigned Size = TD.getTypeSize(C->getType()); 00253 unsigned Align = TD.getTypeAlignment(C->getType()); 00254 00255 if (C->isNullValue() && 00256 (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || 00257 I->hasWeakLinkage() /* FIXME: Verify correct */)) { 00258 SwitchSection(".data", I); 00259 if (I->hasInternalLinkage()) 00260 O << "\t.local " << name << "\n"; 00261 00262 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) 00263 << "," << (unsigned)TD.getTypeAlignment(C->getType()); 00264 O << "\t\t! "; 00265 WriteAsOperand(O, I, true, true, &M); 00266 O << "\n"; 00267 } else { 00268 switch (I->getLinkage()) { 00269 case GlobalValue::LinkOnceLinkage: 00270 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. 00271 // Nonnull linkonce -> weak 00272 O << "\t.weak " << name << "\n"; 00273 SwitchSection("", I); 00274 O << "\t.section\t\".llvm.linkonce.d." << name 00275 << "\",\"aw\",@progbits\n"; 00276 break; 00277 00278 case GlobalValue::AppendingLinkage: 00279 // FIXME: appending linkage variables should go into a section of 00280 // their name or something. For now, just emit them as external. 00281 case GlobalValue::ExternalLinkage: 00282 // If external or appending, declare as a global symbol 00283 O << "\t.globl " << name << "\n"; 00284 // FALL THROUGH 00285 case GlobalValue::InternalLinkage: 00286 if (C->isNullValue()) 00287 SwitchSection(".bss", I); 00288 else 00289 SwitchSection(".data", I); 00290 break; 00291 case GlobalValue::GhostLinkage: 00292 std::cerr << "Should not have any unmaterialized functions!\n"; 00293 abort(); 00294 } 00295 00296 O << "\t.align " << Align << "\n"; 00297 O << "\t.type " << name << ",#object\n"; 00298 O << "\t.size " << name << "," << Size << "\n"; 00299 O << name << ":\t\t\t\t! "; 00300 WriteAsOperand(O, I, true, true, &M); 00301 O << "\n"; 00302 EmitGlobalConstant(C); 00303 } 00304 } 00305 00306 AsmPrinter::doFinalization(M); 00307 return false; // success 00308 }