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