LLVM API Documentation
00001 //===-- SparcAsmPrinter.cpp - Sparc 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 SPARC assembly language. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #define DEBUG_TYPE "asm-printer" 00016 #include "Sparc.h" 00017 #include "SparcInstrInfo.h" 00018 #include "llvm/Constants.h" 00019 #include "llvm/DerivedTypes.h" 00020 #include "llvm/Module.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/TargetAsmInfo.h" 00026 #include "llvm/Target/TargetData.h" 00027 #include "llvm/Target/TargetMachine.h" 00028 #include "llvm/Support/Mangler.h" 00029 #include "llvm/Support/raw_ostream.h" 00030 #include "llvm/ADT/Statistic.h" 00031 #include "llvm/ADT/StringExtras.h" 00032 #include "llvm/Support/CommandLine.h" 00033 #include "llvm/Support/MathExtras.h" 00034 #include <cctype> 00035 #include <cstring> 00036 #include <map> 00037 using namespace llvm; 00038 00039 STATISTIC(EmittedInsts, "Number of machine instrs printed"); 00040 00041 namespace { 00042 struct VISIBILITY_HIDDEN SparcAsmPrinter : public AsmPrinter { 00043 SparcAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T) 00044 : AsmPrinter(O, TM, T) { 00045 } 00046 00047 /// We name each basic block in a Function with a unique number, so 00048 /// that we can consistently refer to them later. This is cleared 00049 /// at the beginning of each call to runOnMachineFunction(). 00050 /// 00051 typedef std::map<const Value *, unsigned> ValueMapTy; 00052 ValueMapTy NumberForBB; 00053 00054 virtual const char *getPassName() const { 00055 return "Sparc Assembly Printer"; 00056 } 00057 00058 void printModuleLevelGV(const GlobalVariable* GVar); 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 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00069 unsigned AsmVariant, const char *ExtraCode); 00070 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 00071 unsigned AsmVariant, const char *ExtraCode); 00072 }; 00073 } // end of anonymous namespace 00074 00075 #include "SparcGenAsmWriter.inc" 00076 00077 /// createSparcCodePrinterPass - Returns a pass that prints the SPARC 00078 /// assembly code for a MachineFunction to the given output stream, 00079 /// using the given target machine description. This should work 00080 /// regardless of whether the function is in SSA form. 00081 /// 00082 FunctionPass *llvm::createSparcCodePrinterPass(raw_ostream &o, 00083 TargetMachine &tm) { 00084 return new SparcAsmPrinter(o, tm, tm.getTargetAsmInfo()); 00085 } 00086 00087 /// runOnMachineFunction - This uses the printInstruction() 00088 /// method to print assembly for each instruction. 00089 /// 00090 bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00091 SetupMachineFunction(MF); 00092 00093 // Print out constants referenced by the function 00094 EmitConstantPool(MF.getConstantPool()); 00095 00096 // BBNumber is used here so that a given Printer will never give two 00097 // BBs the same name. (If you have a better way, please let me know!) 00098 static unsigned BBNumber = 0; 00099 00100 O << "\n\n"; 00101 00102 // Print out the label for the function. 00103 const Function *F = MF.getFunction(); 00104 SwitchToSection(TAI->SectionForGlobal(F)); 00105 EmitAlignment(4, F); 00106 O << "\t.globl\t" << CurrentFnName << '\n'; 00107 00108 printVisibility(CurrentFnName, F->getVisibility()); 00109 00110 O << "\t.type\t" << CurrentFnName << ", #function\n"; 00111 O << CurrentFnName << ":\n"; 00112 00113 // Number each basic block so that we can consistently refer to them 00114 // in PC-relative references. 00115 // FIXME: Why not use the MBB numbers? 00116 NumberForBB.clear(); 00117 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00118 I != E; ++I) { 00119 NumberForBB[I->getBasicBlock()] = BBNumber++; 00120 } 00121 00122 // Print out code for the function. 00123 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00124 I != E; ++I) { 00125 // Print a label for the basic block. 00126 if (I != MF.begin()) { 00127 printBasicBlockLabel(I, true, true); 00128 O << '\n'; 00129 } 00130 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 00131 II != E; ++II) { 00132 // Print the assembly for the instruction. 00133 printInstruction(II); 00134 ++EmittedInsts; 00135 } 00136 } 00137 00138 // We didn't modify anything. 00139 return false; 00140 } 00141 00142 void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { 00143 const MachineOperand &MO = MI->getOperand (opNum); 00144 const TargetRegisterInfo &RI = *TM.getRegisterInfo(); 00145 bool CloseParen = false; 00146 if (MI->getOpcode() == SP::SETHIi && !MO.isReg() && !MO.isImm()) { 00147 O << "%hi("; 00148 CloseParen = true; 00149 } else if ((MI->getOpcode() == SP::ORri || MI->getOpcode() == SP::ADDri) && 00150 !MO.isReg() && !MO.isImm()) { 00151 O << "%lo("; 00152 CloseParen = true; 00153 } 00154 switch (MO.getType()) { 00155 case MachineOperand::MO_Register: 00156 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) 00157 O << "%" << LowercaseString (RI.get(MO.getReg()).AsmName); 00158 else 00159 O << "%reg" << MO.getReg(); 00160 break; 00161 00162 case MachineOperand::MO_Immediate: 00163 O << (int)MO.getImm(); 00164 break; 00165 case MachineOperand::MO_MachineBasicBlock: 00166 printBasicBlockLabel(MO.getMBB()); 00167 return; 00168 case MachineOperand::MO_GlobalAddress: 00169 { 00170 const GlobalValue *GV = MO.getGlobal(); 00171 O << Mang->getValueName(GV); 00172 } 00173 break; 00174 case MachineOperand::MO_ExternalSymbol: 00175 O << MO.getSymbolName(); 00176 break; 00177 case MachineOperand::MO_ConstantPoolIndex: 00178 O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" 00179 << MO.getIndex(); 00180 break; 00181 default: 00182 O << "<unknown operand type>"; abort (); break; 00183 } 00184 if (CloseParen) O << ")"; 00185 } 00186 00187 void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, 00188 const char *Modifier) { 00189 printOperand(MI, opNum); 00190 00191 // If this is an ADD operand, emit it like normal operands. 00192 if (Modifier && !strcmp(Modifier, "arith")) { 00193 O << ", "; 00194 printOperand(MI, opNum+1); 00195 return; 00196 } 00197 00198 if (MI->getOperand(opNum+1).isReg() && 00199 MI->getOperand(opNum+1).getReg() == SP::G0) 00200 return; // don't print "+%g0" 00201 if (MI->getOperand(opNum+1).isImm() && 00202 MI->getOperand(opNum+1).getImm() == 0) 00203 return; // don't print "+0" 00204 00205 O << "+"; 00206 if (MI->getOperand(opNum+1).isGlobal() || 00207 MI->getOperand(opNum+1).isCPI()) { 00208 O << "%lo("; 00209 printOperand(MI, opNum+1); 00210 O << ")"; 00211 } else { 00212 printOperand(MI, opNum+1); 00213 } 00214 } 00215 00216 void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { 00217 int CC = (int)MI->getOperand(opNum).getImm(); 00218 O << SPARCCondCodeToString((SPCC::CondCodes)CC); 00219 } 00220 00221 bool SparcAsmPrinter::doInitialization(Module &M) { 00222 Mang = new Mangler(M, "", TAI->getPrivateGlobalPrefix()); 00223 return false; // success 00224 } 00225 00226 bool SparcAsmPrinter::doFinalization(Module &M) { 00227 // Print out module-level global variables here. 00228 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 00229 I != E; ++I) 00230 printModuleLevelGV(I); 00231 00232 O << '\n'; 00233 00234 return AsmPrinter::doFinalization(M); 00235 } 00236 00237 void SparcAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { 00238 const TargetData *TD = TM.getTargetData(); 00239 00240 if (!GVar->hasInitializer()) 00241 return; // External global require no code 00242 00243 // Check to see if this is a special global used by LLVM, if so, emit it. 00244 if (EmitSpecialLLVMGlobal(GVar)) 00245 return; 00246 00247 O << "\n\n"; 00248 std::string name = Mang->getValueName(GVar); 00249 Constant *C = GVar->getInitializer(); 00250 unsigned Size = TD->getTypePaddedSize(C->getType()); 00251 unsigned Align = TD->getPreferredAlignment(GVar); 00252 00253 printVisibility(name, GVar->getVisibility()); 00254 00255 SwitchToSection(TAI->SectionForGlobal(GVar)); 00256 00257 if (C->isNullValue() && !GVar->hasSection()) { 00258 if (!GVar->isThreadLocal() && 00259 (GVar->hasLocalLinkage() || GVar->mayBeOverridden())) { 00260 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 00261 00262 if (GVar->hasLocalLinkage()) 00263 O << "\t.local " << name << '\n'; 00264 00265 O << TAI->getCOMMDirective() << name << ',' << Size; 00266 if (TAI->getCOMMDirectiveTakesAlignment()) 00267 O << ',' << (1 << Align); 00268 00269 O << '\n'; 00270 return; 00271 } 00272 } 00273 00274 switch (GVar->getLinkage()) { 00275 case GlobalValue::CommonLinkage: 00276 case GlobalValue::LinkOnceLinkage: 00277 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. 00278 // Nonnull linkonce -> weak 00279 O << "\t.weak " << name << '\n'; 00280 break; 00281 case GlobalValue::AppendingLinkage: 00282 // FIXME: appending linkage variables should go into a section of 00283 // their name or something. For now, just emit them as external. 00284 case GlobalValue::ExternalLinkage: 00285 // If external or appending, declare as a global symbol 00286 O << TAI->getGlobalDirective() << name << '\n'; 00287 // FALL THROUGH 00288 case GlobalValue::PrivateLinkage: 00289 case GlobalValue::InternalLinkage: 00290 break; 00291 case GlobalValue::GhostLinkage: 00292 cerr << "Should not have any unmaterialized functions!\n"; 00293 abort(); 00294 case GlobalValue::DLLImportLinkage: 00295 cerr << "DLLImport linkage is not supported by this target!\n"; 00296 abort(); 00297 case GlobalValue::DLLExportLinkage: 00298 cerr << "DLLExport linkage is not supported by this target!\n"; 00299 abort(); 00300 default: 00301 assert(0 && "Unknown linkage type!"); 00302 } 00303 00304 EmitAlignment(Align, GVar); 00305 00306 if (TAI->hasDotTypeDotSizeDirective()) { 00307 O << "\t.type " << name << ",#object\n"; 00308 O << "\t.size " << name << ',' << Size << '\n'; 00309 } 00310 00311 O << name << ":\n"; 00312 EmitGlobalConstant(C); 00313 } 00314 00315 /// PrintAsmOperand - Print out an operand for an inline asm expression. 00316 /// 00317 bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00318 unsigned AsmVariant, 00319 const char *ExtraCode) { 00320 if (ExtraCode && ExtraCode[0]) { 00321 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00322 00323 switch (ExtraCode[0]) { 00324 default: return true; // Unknown modifier. 00325 case 'r': 00326 break; 00327 } 00328 } 00329 00330 printOperand(MI, OpNo); 00331 00332 return false; 00333 } 00334 00335 bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00336 unsigned OpNo, 00337 unsigned AsmVariant, 00338 const char *ExtraCode) { 00339 if (ExtraCode && ExtraCode[0]) 00340 return true; // Unknown modifier 00341 00342 O << '['; 00343 printMemOperand(MI, OpNo); 00344 O << ']'; 00345 00346 return false; 00347 }