MSP430AsmPrinter.cpp revision 36b6e533c1aac85452438161f7034a9f54bd1830
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 bool printInstruction(const MachineInstr *MI); // autogenerated. 55 void printMachineInstruction(const MachineInstr * MI); 56 bool runOnMachineFunction(MachineFunction &F); 57 bool doInitialization(Module &M); 58 bool doFinalization(Module &M); 59 60 void getAnalysisUsage(AnalysisUsage &AU) const { 61 AsmPrinter::getAnalysisUsage(AU); 62 AU.setPreservesAll(); 63 } 64 }; 65} // end of anonymous namespace 66 67#include "MSP430GenAsmWriter.inc" 68 69/// createMSP430CodePrinterPass - Returns a pass that prints the MSP430 70/// assembly code for a MachineFunction to the given output stream, 71/// using the given target machine description. This should work 72/// regardless of whether the function is in SSA form. 73/// 74FunctionPass *llvm::createMSP430CodePrinterPass(raw_ostream &o, 75 MSP430TargetMachine &tm, 76 bool fast, bool verbose) { 77 return new MSP430AsmPrinter(o, tm, tm.getTargetAsmInfo(), fast, verbose); 78} 79 80bool MSP430AsmPrinter::doInitialization(Module &M) { 81 Mang = new Mangler(M, "", TAI->getPrivateGlobalPrefix()); 82 return false; // success 83} 84 85 86bool MSP430AsmPrinter::doFinalization(Module &M) { 87 return AsmPrinter::doFinalization(M); 88} 89 90bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 91 // Print out code for the function. 92 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 93 I != E; ++I) { 94 // Print a label for the basic block. 95 if (I != MF.begin()) { 96 printBasicBlockLabel(I, true , true); 97 O << '\n'; 98 } 99 100 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 101 II != E; ++II) { 102 // Print the assembly for the instruction. 103 O << "\t"; 104 printMachineInstruction(II); 105 } 106 107 // Each Basic Block is separated by a newline 108 O << '\n'; 109 } 110 111 // We didn't modify anything 112 return false; 113} 114 115void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) { 116 ++EmittedInsts; 117 118 // Call the autogenerated instruction printer routines. 119 if (printInstruction(MI)) 120 return; 121 122 assert(0 && "Should not happen"); 123} 124 125void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 126 const char* Modifier) { 127 const MachineOperand &MO = MI->getOperand(OpNum); 128 switch (MO.getType()) { 129 case MachineOperand::MO_Register: 130 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) 131 O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; 132 else 133 assert(0 && "not implemented"); 134 break; 135 case MachineOperand::MO_Immediate: 136 if (!Modifier || strcmp(Modifier, "nohash")) 137 O << '#'; 138 O << MO.getImm(); 139 break; 140 case MachineOperand::MO_MachineBasicBlock: 141 printBasicBlockLabel(MO.getMBB()); 142 break; 143 default: 144 assert(0 && "Not implemented yet!"); 145 } 146} 147 148void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum, 149 const char* Modifier) { 150 const MachineOperand &Disp = MI->getOperand(OpNum); 151 assert(Disp.isImm() && "Displacement can be only immediate!"); 152 153 // Special case: 0(Reg) -> @Reg 154 if (Disp.getImm() == 0) { 155 O << "@"; 156 printOperand(MI, OpNum + 1); 157 } else { 158 printOperand(MI, OpNum, "nohash"); 159 O << '('; 160 printOperand(MI, OpNum + 1); 161 O << ')'; 162 } 163} 164 165