1 //===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===// 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 implements the SparcMCCodeEmitter class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define DEBUG_TYPE "mccodeemitter" 15 #include "SparcMCExpr.h" 16 #include "MCTargetDesc/SparcFixupKinds.h" 17 #include "SparcMCTargetDesc.h" 18 #include "llvm/ADT/Statistic.h" 19 #include "llvm/MC/MCCodeEmitter.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCExpr.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/MC/MCRegisterInfo.h" 24 #include "llvm/Support/raw_ostream.h" 25 26 using namespace llvm; 27 28 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 29 30 namespace { 31 class SparcMCCodeEmitter : public MCCodeEmitter { 32 SparcMCCodeEmitter(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION; 33 void operator=(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION; 34 MCContext &Ctx; 35 36 public: 37 SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {} 38 39 ~SparcMCCodeEmitter() {} 40 41 void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 42 SmallVectorImpl<MCFixup> &Fixups, 43 const MCSubtargetInfo &STI) const; 44 45 // getBinaryCodeForInstr - TableGen'erated function for getting the 46 // binary encoding for an instruction. 47 uint64_t getBinaryCodeForInstr(const MCInst &MI, 48 SmallVectorImpl<MCFixup> &Fixups, 49 const MCSubtargetInfo &STI) const; 50 51 /// getMachineOpValue - Return binary encoding of operand. If the machine 52 /// operand requires relocation, record the relocation and return zero. 53 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 54 SmallVectorImpl<MCFixup> &Fixups, 55 const MCSubtargetInfo &STI) const; 56 57 unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 58 SmallVectorImpl<MCFixup> &Fixups, 59 const MCSubtargetInfo &STI) const; 60 unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 61 SmallVectorImpl<MCFixup> &Fixups, 62 const MCSubtargetInfo &STI) const; 63 64 }; 65 } // end anonymous namespace 66 67 MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII, 68 const MCRegisterInfo &MRI, 69 const MCSubtargetInfo &STI, 70 MCContext &Ctx) { 71 return new SparcMCCodeEmitter(Ctx); 72 } 73 74 void SparcMCCodeEmitter:: 75 EncodeInstruction(const MCInst &MI, raw_ostream &OS, 76 SmallVectorImpl<MCFixup> &Fixups, 77 const MCSubtargetInfo &STI) const { 78 unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI); 79 80 // Output the constant in big endian byte order. 81 for (unsigned i = 0; i != 4; ++i) { 82 OS << (char)(Bits >> 24); 83 Bits <<= 8; 84 } 85 86 ++MCNumEmitted; // Keep track of the # of mi's emitted. 87 } 88 89 90 unsigned SparcMCCodeEmitter:: 91 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 92 SmallVectorImpl<MCFixup> &Fixups, 93 const MCSubtargetInfo &STI) const { 94 95 if (MO.isReg()) 96 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 97 98 if (MO.isImm()) 99 return MO.getImm(); 100 101 assert(MO.isExpr()); 102 const MCExpr *Expr = MO.getExpr(); 103 if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) { 104 switch(SExpr->getKind()) { 105 default: assert(0 && "Unhandled sparc expression!"); break; 106 case SparcMCExpr::VK_Sparc_LO: 107 Fixups.push_back(MCFixup::Create(0, Expr, 108 (MCFixupKind)Sparc::fixup_sparc_lo10)); 109 break; 110 case SparcMCExpr::VK_Sparc_HI: 111 Fixups.push_back(MCFixup::Create(0, Expr, 112 (MCFixupKind)Sparc::fixup_sparc_hi22)); 113 break; 114 case SparcMCExpr::VK_Sparc_H44: 115 Fixups.push_back(MCFixup::Create(0, Expr, 116 (MCFixupKind)Sparc::fixup_sparc_h44)); 117 break; 118 case SparcMCExpr::VK_Sparc_M44: 119 Fixups.push_back(MCFixup::Create(0, Expr, 120 (MCFixupKind)Sparc::fixup_sparc_m44)); 121 break; 122 case SparcMCExpr::VK_Sparc_L44: 123 Fixups.push_back(MCFixup::Create(0, Expr, 124 (MCFixupKind)Sparc::fixup_sparc_l44)); 125 break; 126 case SparcMCExpr::VK_Sparc_HH: 127 Fixups.push_back(MCFixup::Create(0, Expr, 128 (MCFixupKind)Sparc::fixup_sparc_hh)); 129 break; 130 case SparcMCExpr::VK_Sparc_HM: 131 Fixups.push_back(MCFixup::Create(0, Expr, 132 (MCFixupKind)Sparc::fixup_sparc_hm)); 133 break; 134 } 135 return 0; 136 } 137 138 int64_t Res; 139 if (Expr->EvaluateAsAbsolute(Res)) 140 return Res; 141 142 assert(0 && "Unhandled expression!"); 143 return 0; 144 } 145 146 unsigned SparcMCCodeEmitter:: 147 getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 148 SmallVectorImpl<MCFixup> &Fixups, 149 const MCSubtargetInfo &STI) const { 150 const MCOperand &MO = MI.getOperand(OpNo); 151 if (MO.isReg() || MO.isImm()) 152 return getMachineOpValue(MI, MO, Fixups, STI); 153 154 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 155 (MCFixupKind)Sparc::fixup_sparc_call30)); 156 return 0; 157 } 158 159 unsigned SparcMCCodeEmitter:: 160 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 161 SmallVectorImpl<MCFixup> &Fixups, 162 const MCSubtargetInfo &STI) const { 163 const MCOperand &MO = MI.getOperand(OpNo); 164 if (MO.isReg() || MO.isImm()) 165 return getMachineOpValue(MI, MO, Fixups, STI); 166 167 Sparc::Fixups fixup = Sparc::fixup_sparc_br22; 168 if (MI.getOpcode() == SP::BPXCC) 169 fixup = Sparc::fixup_sparc_br19; 170 171 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 172 (MCFixupKind)fixup)); 173 return 0; 174 } 175 176 #include "SparcGenMCCodeEmitter.inc" 177