MSP430AsmPrinter.cpp revision 8b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9
1//===-- MSP430AsmPrinter.cpp - MSP430 LLVM assembly writer ------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains a printer that converts from our internal representation 11// of machine-dependent LLVM code to the MSP430 assembly language. 12// 13//===----------------------------------------------------------------------===// 14 15#define DEBUG_TYPE "asm-printer" 16#include "MSP430.h" 17#include "MSP430InstrInfo.h" 18#include "MSP430TargetMachine.h" 19#include "llvm/Constants.h" 20#include "llvm/DerivedTypes.h" 21#include "llvm/Module.h" 22#include "llvm/CodeGen/AsmPrinter.h" 23#include "llvm/CodeGen/DwarfWriter.h" 24#include "llvm/CodeGen/MachineModuleInfo.h" 25#include "llvm/CodeGen/MachineFunctionPass.h" 26#include "llvm/CodeGen/MachineConstantPool.h" 27#include "llvm/CodeGen/MachineInstr.h" 28#include "llvm/Target/TargetAsmInfo.h" 29#include "llvm/Target/TargetData.h" 30#include "llvm/ADT/Statistic.h" 31#include "llvm/Support/Compiler.h" 32#include "llvm/Support/Mangler.h" 33#include "llvm/Support/raw_ostream.h" 34 35using namespace llvm; 36 37STATISTIC(EmittedInsts, "Number of machine instrs printed"); 38 39namespace { 40 class VISIBILITY_HIDDEN MSP430AsmPrinter : public AsmPrinter { 41 public: 42 MSP430AsmPrinter(raw_ostream &O, MSP430TargetMachine &TM, 43 const TargetAsmInfo *TAI, bool Fast, bool Verbose) 44 : AsmPrinter(O, TM, TAI, Fast, Verbose) {} 45 46 virtual const char *getPassName() const { 47 return "MSP430 Assembly Printer"; 48 } 49 50 void printOperand(const MachineInstr *MI, int OpNum, 51 const char* Modifier = 0); 52 void printSrcMemOperand(const MachineInstr *MI, int OpNum, 53 const char* Modifier = 0); 54 void printCCOperand(const MachineInstr *MI, int OpNum); 55 bool printInstruction(const MachineInstr *MI); // autogenerated. 56 void printMachineInstruction(const MachineInstr * MI); 57 bool runOnMachineFunction(MachineFunction &F); 58 bool doInitialization(Module &M); 59 bool doFinalization(Module &M); 60 61 void getAnalysisUsage(AnalysisUsage &AU) const { 62 AsmPrinter::getAnalysisUsage(AU); 63 AU.setPreservesAll(); 64 } 65 }; 66} // end of anonymous namespace 67 68#include "MSP430GenAsmWriter.inc" 69 70/// createMSP430CodePrinterPass - Returns a pass that prints the MSP430 71/// assembly code for a MachineFunction to the given output stream, 72/// using the given target machine description. This should work 73/// regardless of whether the function is in SSA form. 74/// 75FunctionPass *llvm::createMSP430CodePrinterPass(raw_ostream &o, 76 MSP430TargetMachine &tm, 77 bool fast, bool verbose) { 78 return new MSP430AsmPrinter(o, tm, tm.getTargetAsmInfo(), fast, verbose); 79} 80 81bool MSP430AsmPrinter::doInitialization(Module &M) { 82 Mang = new Mangler(M, "", TAI->getPrivateGlobalPrefix()); 83 return false; // success 84} 85 86 87bool MSP430AsmPrinter::doFinalization(Module &M) { 88 return AsmPrinter::doFinalization(M); 89} 90 91bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 92 // Print out code for the function. 93 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 94 I != E; ++I) { 95 // Print a label for the basic block. 96 if (I != MF.begin()) { 97 printBasicBlockLabel(I, true , true); 98 O << '\n'; 99 } 100 101 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 102 II != E; ++II) { 103 // Print the assembly for the instruction. 104 O << "\t"; 105 printMachineInstruction(II); 106 } 107 108 // Each Basic Block is separated by a newline 109 O << '\n'; 110 } 111 112 // We didn't modify anything 113 return false; 114} 115 116void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) { 117 ++EmittedInsts; 118 119 // Call the autogenerated instruction printer routines. 120 if (printInstruction(MI)) 121 return; 122 123 assert(0 && "Should not happen"); 124} 125 126void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 127 const char* Modifier) { 128 const MachineOperand &MO = MI->getOperand(OpNum); 129 switch (MO.getType()) { 130 case MachineOperand::MO_Register: 131 assert (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && 132 "Virtual registers should be already mapped!"); 133 O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; 134 return; 135 case MachineOperand::MO_Immediate: 136 if (!Modifier || strcmp(Modifier, "nohash")) 137 O << '#'; 138 O << MO.getImm(); 139 return; 140 case MachineOperand::MO_MachineBasicBlock: 141 printBasicBlockLabel(MO.getMBB()); 142 return; 143 case MachineOperand::MO_GlobalAddress: { 144 bool isMemOp = Modifier && !strcmp(Modifier, "mem"); 145 bool isCallOp = Modifier && !strcmp(Modifier, "call"); 146 std::string Name = Mang->getValueName(MO.getGlobal()); 147 assert(MO.getOffset() == 0 && "No offsets allowed!"); 148 149 if (isCallOp) 150 O << '#'; 151 else if (isMemOp) 152 O << '&'; 153 154 O << Name; 155 156 return; 157 } 158 default: 159 assert(0 && "Not implemented yet!"); 160 } 161} 162 163void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum, 164 const char* Modifier) { 165 const MachineOperand &Base = MI->getOperand(OpNum); 166 const MachineOperand &Disp = MI->getOperand(OpNum+1); 167 168 if (Base.isGlobal()) 169 printOperand(MI, OpNum, "mem"); 170 else if (Disp.isImm() && !Base.getReg()) 171 printOperand(MI, OpNum); 172 else if (Base.getReg()) { 173 if (Disp.getImm()) { 174 printOperand(MI, OpNum + 1, "nohash"); 175 O << '('; 176 printOperand(MI, OpNum); 177 O << ')'; 178 } else { 179 O << '@'; 180 printOperand(MI, OpNum); 181 } 182 } else 183 assert(0 && "Unsupported memory operand"); 184} 185 186void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) { 187 unsigned CC = MI->getOperand(OpNum).getImm(); 188 189 switch (CC) { 190 default: 191 assert(0 && "Unsupported CC code"); 192 break; 193 case MSP430::COND_E: 194 O << 'e'; 195 break; 196 case MSP430::COND_NE: 197 O << "ne"; 198 break; 199 case MSP430::COND_HS: 200 O << "hs"; 201 break; 202 case MSP430::COND_LO: 203 O << "lo"; 204 break; 205 case MSP430::COND_GE: 206 O << "ge"; 207 break; 208 case MSP430::COND_L: 209 O << 'l'; 210 break; 211 } 212} 213