1 //===-- HexagonAsmPrinter.h - Print machine code to an Hexagon .s file ----===// 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 // Hexagon Assembly printer class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef HEXAGONASMPRINTER_H 15 #define HEXAGONASMPRINTER_H 16 17 #include "Hexagon.h" 18 #include "HexagonTargetMachine.h" 19 #include "llvm/CodeGen/AsmPrinter.h" 20 #include "llvm/Support/Compiler.h" 21 #include "llvm/Support/raw_ostream.h" 22 23 namespace llvm { 24 class HexagonAsmPrinter : public AsmPrinter { 25 const HexagonSubtarget *Subtarget; 26 27 public: 28 explicit HexagonAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 29 : AsmPrinter(TM, Streamer) { 30 Subtarget = &TM.getSubtarget<HexagonSubtarget>(); 31 } 32 33 virtual const char *getPassName() const { 34 return "Hexagon Assembly Printer"; 35 } 36 37 bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; 38 39 virtual void EmitInstruction(const MachineInstr *MI); 40 virtual void EmitAlignment(unsigned NumBits, 41 const GlobalValue *GV = 0) const; 42 43 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); 44 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 45 unsigned AsmVariant, const char *ExtraCode, 46 raw_ostream &OS); 47 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 48 unsigned AsmVariant, const char *ExtraCode, 49 raw_ostream &OS); 50 51 /// printInstruction - This method is automatically generated by tablegen 52 /// from the instruction set description. This method returns true if the 53 /// machine instruction was sufficiently described to print it, otherwise it 54 /// returns false. 55 void printInstruction(const MachineInstr *MI, raw_ostream &O); 56 57 // void printMachineInstruction(const MachineInstr *MI); 58 void printOp(const MachineOperand &MO, raw_ostream &O); 59 60 /// printRegister - Print register according to target requirements. 61 /// 62 void printRegister(const MachineOperand &MO, bool R0AsZero, 63 raw_ostream &O) { 64 unsigned RegNo = MO.getReg(); 65 assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??"); 66 O << getRegisterName(RegNo); 67 } 68 69 void printImmOperand(const MachineInstr *MI, unsigned OpNo, 70 raw_ostream &O) { 71 int value = MI->getOperand(OpNo).getImm(); 72 O << value; 73 } 74 75 void printNegImmOperand(const MachineInstr *MI, unsigned OpNo, 76 raw_ostream &O) { 77 int value = MI->getOperand(OpNo).getImm(); 78 O << -value; 79 } 80 81 void printMEMriOperand(const MachineInstr *MI, unsigned OpNo, 82 raw_ostream &O) { 83 const MachineOperand &MO1 = MI->getOperand(OpNo); 84 const MachineOperand &MO2 = MI->getOperand(OpNo+1); 85 86 O << getRegisterName(MO1.getReg()) 87 << " + #" 88 << (int) MO2.getImm(); 89 } 90 91 void printFrameIndexOperand(const MachineInstr *MI, unsigned OpNo, 92 raw_ostream &O) { 93 const MachineOperand &MO1 = MI->getOperand(OpNo); 94 const MachineOperand &MO2 = MI->getOperand(OpNo+1); 95 96 O << getRegisterName(MO1.getReg()) 97 << ", #" 98 << MO2.getImm(); 99 } 100 101 void printBranchOperand(const MachineInstr *MI, unsigned OpNo, 102 raw_ostream &O) { 103 // Branches can take an immediate operand. This is used by the branch 104 // selection pass to print $+8, an eight byte displacement from the PC. 105 if (MI->getOperand(OpNo).isImm()) { 106 O << "$+" << MI->getOperand(OpNo).getImm()*4; 107 } else { 108 printOp(MI->getOperand(OpNo), O); 109 } 110 } 111 112 void printCallOperand(const MachineInstr *MI, unsigned OpNo, 113 raw_ostream &O) { 114 } 115 116 void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo, 117 raw_ostream &O) { 118 } 119 120 void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 121 O << "#HI("; 122 if (MI->getOperand(OpNo).isImm()) { 123 printImmOperand(MI, OpNo, O); 124 } 125 else { 126 printOp(MI->getOperand(OpNo), O); 127 } 128 O << ")"; 129 } 130 131 void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 132 O << "#HI("; 133 if (MI->getOperand(OpNo).isImm()) { 134 printImmOperand(MI, OpNo, O); 135 } 136 else { 137 printOp(MI->getOperand(OpNo), O); 138 } 139 O << ")"; 140 } 141 142 void printPredicateOperand(const MachineInstr *MI, unsigned OpNo, 143 raw_ostream &O); 144 145 #if 0 146 void printModuleLevelGV(const GlobalVariable* GVar, raw_ostream &O); 147 #endif 148 149 void printAddrModeBasePlusOffset(const MachineInstr *MI, int OpNo, 150 raw_ostream &O); 151 152 void printGlobalOperand(const MachineInstr *MI, int OpNo, raw_ostream &O); 153 void printJumpTable(const MachineInstr *MI, int OpNo, raw_ostream &O); 154 void printConstantPool(const MachineInstr *MI, int OpNo, raw_ostream &O); 155 156 static const char *getRegisterName(unsigned RegNo); 157 158 #if 0 159 void EmitStartOfAsmFile(Module &M); 160 #endif 161 }; 162 163 } // end of llvm namespace 164 165 #endif 166