LLVM API Documentation
00001 //===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the "Instituto Nokia de Tecnologia" and 00006 // is distributed under the University of Illinois Open Source 00007 // License. See LICENSE.TXT for details. 00008 // 00009 //===----------------------------------------------------------------------===// 00010 // 00011 // This file contains a printer that converts from our internal representation 00012 // of machine-dependent LLVM code to GAS-format ARM assembly language. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "ARM.h" 00017 #include "ARMInstrInfo.h" 00018 #include "llvm/Constants.h" 00019 #include "llvm/DerivedTypes.h" 00020 #include "llvm/Module.h" 00021 #include "llvm/Assembly/Writer.h" 00022 #include "llvm/CodeGen/AsmPrinter.h" 00023 #include "llvm/CodeGen/MachineFunctionPass.h" 00024 #include "llvm/CodeGen/MachineConstantPool.h" 00025 #include "llvm/CodeGen/MachineInstr.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 ARMAsmPrinter : public AsmPrinter { 00040 ARMAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { 00041 Data16bitsDirective = "\t.half\t"; 00042 Data32bitsDirective = "\t.word\t"; 00043 Data64bitsDirective = 0; 00044 ZeroDirective = "\t.skip\t"; 00045 CommentString = "!"; 00046 ConstantPoolSection = "\t.section \".rodata\",#alloc\n"; 00047 AlignmentIsInBytes = false; 00048 } 00049 00050 /// We name each basic block in a Function with a unique number, so 00051 /// that we can consistently refer to them later. This is cleared 00052 /// at the beginning of each call to runOnMachineFunction(). 00053 /// 00054 typedef std::map<const Value *, unsigned> ValueMapTy; 00055 ValueMapTy NumberForBB; 00056 00057 virtual const char *getPassName() const { 00058 return "ARM Assembly Printer"; 00059 } 00060 00061 void printMemRegImm(const MachineInstr *MI, unsigned OpNo) { 00062 printOperand(MI, OpNo + 1); 00063 O << ", "; 00064 printOperand(MI, OpNo); 00065 } 00066 00067 void printOperand(const MachineInstr *MI, int opNum); 00068 void printMemOperand(const MachineInstr *MI, int opNum, 00069 const char *Modifier = 0); 00070 void printCCOperand(const MachineInstr *MI, int opNum); 00071 00072 bool printInstruction(const MachineInstr *MI); // autogenerated. 00073 bool runOnMachineFunction(MachineFunction &F); 00074 bool doInitialization(Module &M); 00075 bool doFinalization(Module &M); 00076 }; 00077 } // end of anonymous namespace 00078 00079 #include "ARMGenAsmWriter.inc" 00080 00081 /// createARMCodePrinterPass - Returns a pass that prints the ARM 00082 /// assembly code for a MachineFunction to the given output stream, 00083 /// using the given target machine description. This should work 00084 /// regardless of whether the function is in SSA form. 00085 /// 00086 FunctionPass *llvm::createARMCodePrinterPass(std::ostream &o, 00087 TargetMachine &tm) { 00088 return new ARMAsmPrinter(o, tm); 00089 } 00090 00091 /// runOnMachineFunction - This uses the printMachineInstruction() 00092 /// method to print assembly for each instruction. 00093 /// 00094 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00095 SetupMachineFunction(MF); 00096 O << "\n\n"; 00097 00098 // Print out constants referenced by the function 00099 EmitConstantPool(MF.getConstantPool()); 00100 00101 // Print out jump tables referenced by the function 00102 EmitJumpTableInfo(MF.getJumpTableInfo()); 00103 00104 // Print out labels for the function. 00105 const Function *F = MF.getFunction(); 00106 switch (F->getLinkage()) { 00107 default: assert(0 && "Unknown linkage type!"); 00108 case Function::InternalLinkage: 00109 SwitchToTextSection("\t.text", F); 00110 break; 00111 case Function::ExternalLinkage: 00112 SwitchToTextSection("\t.text", F); 00113 O << "\t.globl\t" << CurrentFnName << "\n"; 00114 break; 00115 case Function::WeakLinkage: 00116 case Function::LinkOnceLinkage: 00117 assert(0 && "Not implemented"); 00118 break; 00119 } 00120 EmitAlignment(2, F); 00121 O << CurrentFnName << ":\n"; 00122 00123 // Print out code for the function. 00124 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00125 I != E; ++I) { 00126 // Print a label for the basic block. 00127 if (I != MF.begin()) { 00128 printBasicBlockLabel(I, true); 00129 O << '\n'; 00130 } 00131 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 00132 II != E; ++II) { 00133 // Print the assembly for the instruction. 00134 O << "\t"; 00135 printInstruction(II); 00136 } 00137 } 00138 00139 return false; 00140 } 00141 00142 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { 00143 const MachineOperand &MO = MI->getOperand (opNum); 00144 const MRegisterInfo &RI = *TM.getRegisterInfo(); 00145 switch (MO.getType()) { 00146 case MachineOperand::MO_Register: 00147 if (MRegisterInfo::isPhysicalRegister(MO.getReg())) 00148 O << LowercaseString (RI.get(MO.getReg()).Name); 00149 else 00150 assert(0 && "not implemented"); 00151 break; 00152 case MachineOperand::MO_Immediate: 00153 O << "#" << (int)MO.getImmedValue(); 00154 break; 00155 case MachineOperand::MO_MachineBasicBlock: 00156 assert(0 && "not implemented"); 00157 abort(); 00158 return; 00159 case MachineOperand::MO_GlobalAddress: { 00160 GlobalValue *GV = MO.getGlobal(); 00161 std::string Name = Mang->getValueName(GV); 00162 O << Name; 00163 } 00164 break; 00165 case MachineOperand::MO_ExternalSymbol: 00166 assert(0 && "not implemented"); 00167 abort(); 00168 break; 00169 case MachineOperand::MO_ConstantPoolIndex: 00170 assert(0 && "not implemented"); 00171 abort(); 00172 break; 00173 default: 00174 O << "<unknown operand type>"; abort (); break; 00175 } 00176 } 00177 00178 void ARMAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, 00179 const char *Modifier) { 00180 assert(0 && "not implemented"); 00181 } 00182 00183 void ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { 00184 assert(0 && "not implemented"); 00185 } 00186 00187 bool ARMAsmPrinter::doInitialization(Module &M) { 00188 Mang = new Mangler(M); 00189 return false; // success 00190 } 00191 00192 bool ARMAsmPrinter::doFinalization(Module &M) { 00193 AsmPrinter::doFinalization(M); 00194 return false; // success 00195 }