LLVM API Documentation

SparcAsmPrinter.cpp

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