LLVM API Documentation
00001 //===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the SparcMCCodeEmitter class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "SparcMCExpr.h" 00015 #include "MCTargetDesc/SparcFixupKinds.h" 00016 #include "SparcMCTargetDesc.h" 00017 #include "llvm/ADT/Statistic.h" 00018 #include "llvm/MC/MCCodeEmitter.h" 00019 #include "llvm/MC/MCContext.h" 00020 #include "llvm/MC/MCExpr.h" 00021 #include "llvm/MC/MCInst.h" 00022 #include "llvm/MC/MCRegisterInfo.h" 00023 #include "llvm/MC/MCSymbol.h" 00024 #include "llvm/Support/raw_ostream.h" 00025 00026 using namespace llvm; 00027 00028 #define DEBUG_TYPE "mccodeemitter" 00029 00030 STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); 00031 00032 namespace { 00033 class SparcMCCodeEmitter : public MCCodeEmitter { 00034 SparcMCCodeEmitter(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION; 00035 void operator=(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION; 00036 MCContext &Ctx; 00037 00038 public: 00039 SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {} 00040 00041 ~SparcMCCodeEmitter() {} 00042 00043 void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 00044 SmallVectorImpl<MCFixup> &Fixups, 00045 const MCSubtargetInfo &STI) const override; 00046 00047 // getBinaryCodeForInstr - TableGen'erated function for getting the 00048 // binary encoding for an instruction. 00049 uint64_t getBinaryCodeForInstr(const MCInst &MI, 00050 SmallVectorImpl<MCFixup> &Fixups, 00051 const MCSubtargetInfo &STI) const; 00052 00053 /// getMachineOpValue - Return binary encoding of operand. If the machine 00054 /// operand requires relocation, record the relocation and return zero. 00055 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 00056 SmallVectorImpl<MCFixup> &Fixups, 00057 const MCSubtargetInfo &STI) const; 00058 00059 unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 00060 SmallVectorImpl<MCFixup> &Fixups, 00061 const MCSubtargetInfo &STI) const; 00062 unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 00063 SmallVectorImpl<MCFixup> &Fixups, 00064 const MCSubtargetInfo &STI) const; 00065 unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, 00066 SmallVectorImpl<MCFixup> &Fixups, 00067 const MCSubtargetInfo &STI) const; 00068 unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, 00069 SmallVectorImpl<MCFixup> &Fixups, 00070 const MCSubtargetInfo &STI) const; 00071 00072 }; 00073 } // end anonymous namespace 00074 00075 MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII, 00076 const MCRegisterInfo &MRI, 00077 const MCSubtargetInfo &STI, 00078 MCContext &Ctx) { 00079 return new SparcMCCodeEmitter(Ctx); 00080 } 00081 00082 void SparcMCCodeEmitter:: 00083 EncodeInstruction(const MCInst &MI, raw_ostream &OS, 00084 SmallVectorImpl<MCFixup> &Fixups, 00085 const MCSubtargetInfo &STI) const { 00086 unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI); 00087 00088 // Output the constant in big endian byte order. 00089 for (unsigned i = 0; i != 4; ++i) { 00090 OS << (char)(Bits >> 24); 00091 Bits <<= 8; 00092 } 00093 unsigned tlsOpNo = 0; 00094 switch (MI.getOpcode()) { 00095 default: break; 00096 case SP::TLS_CALL: tlsOpNo = 1; break; 00097 case SP::TLS_ADDrr: 00098 case SP::TLS_ADDXrr: 00099 case SP::TLS_LDrr: 00100 case SP::TLS_LDXrr: tlsOpNo = 3; break; 00101 } 00102 if (tlsOpNo != 0) { 00103 const MCOperand &MO = MI.getOperand(tlsOpNo); 00104 uint64_t op = getMachineOpValue(MI, MO, Fixups, STI); 00105 assert(op == 0 && "Unexpected operand value!"); 00106 (void)op; // suppress warning. 00107 } 00108 00109 ++MCNumEmitted; // Keep track of the # of mi's emitted. 00110 } 00111 00112 00113 unsigned SparcMCCodeEmitter:: 00114 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 00115 SmallVectorImpl<MCFixup> &Fixups, 00116 const MCSubtargetInfo &STI) const { 00117 00118 if (MO.isReg()) 00119 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 00120 00121 if (MO.isImm()) 00122 return MO.getImm(); 00123 00124 assert(MO.isExpr()); 00125 const MCExpr *Expr = MO.getExpr(); 00126 if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) { 00127 MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind(); 00128 Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 00129 return 0; 00130 } 00131 00132 int64_t Res; 00133 if (Expr->EvaluateAsAbsolute(Res)) 00134 return Res; 00135 00136 llvm_unreachable("Unhandled expression!"); 00137 return 0; 00138 } 00139 00140 unsigned SparcMCCodeEmitter:: 00141 getCallTargetOpValue(const MCInst &MI, unsigned OpNo, 00142 SmallVectorImpl<MCFixup> &Fixups, 00143 const MCSubtargetInfo &STI) const { 00144 const MCOperand &MO = MI.getOperand(OpNo); 00145 if (MO.isReg() || MO.isImm()) 00146 return getMachineOpValue(MI, MO, Fixups, STI); 00147 00148 if (MI.getOpcode() == SP::TLS_CALL) { 00149 // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in 00150 // EncodeInstruction. 00151 #ifndef NDEBUG 00152 // Verify that the callee is actually __tls_get_addr. 00153 const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr()); 00154 assert(SExpr && SExpr->getSubExpr()->getKind() == MCExpr::SymbolRef && 00155 "Unexpected expression in TLS_CALL"); 00156 const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(SExpr->getSubExpr()); 00157 assert(SymExpr->getSymbol().getName() == "__tls_get_addr" && 00158 "Unexpected function for TLS_CALL"); 00159 #endif 00160 return 0; 00161 } 00162 00163 MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30; 00164 00165 if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) { 00166 if (SExpr->getKind() == SparcMCExpr::VK_Sparc_WPLT30) 00167 fixupKind = (MCFixupKind)Sparc::fixup_sparc_wplt30; 00168 } 00169 00170 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), fixupKind)); 00171 00172 return 0; 00173 } 00174 00175 unsigned SparcMCCodeEmitter:: 00176 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 00177 SmallVectorImpl<MCFixup> &Fixups, 00178 const MCSubtargetInfo &STI) const { 00179 const MCOperand &MO = MI.getOperand(OpNo); 00180 if (MO.isReg() || MO.isImm()) 00181 return getMachineOpValue(MI, MO, Fixups, STI); 00182 00183 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 00184 (MCFixupKind)Sparc::fixup_sparc_br22)); 00185 return 0; 00186 } 00187 00188 unsigned SparcMCCodeEmitter:: 00189 getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo, 00190 SmallVectorImpl<MCFixup> &Fixups, 00191 const MCSubtargetInfo &STI) const { 00192 const MCOperand &MO = MI.getOperand(OpNo); 00193 if (MO.isReg() || MO.isImm()) 00194 return getMachineOpValue(MI, MO, Fixups, STI); 00195 00196 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 00197 (MCFixupKind)Sparc::fixup_sparc_br19)); 00198 return 0; 00199 } 00200 unsigned SparcMCCodeEmitter:: 00201 getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo, 00202 SmallVectorImpl<MCFixup> &Fixups, 00203 const MCSubtargetInfo &STI) const { 00204 const MCOperand &MO = MI.getOperand(OpNo); 00205 if (MO.isReg() || MO.isImm()) 00206 return getMachineOpValue(MI, MO, Fixups, STI); 00207 00208 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 00209 (MCFixupKind)Sparc::fixup_sparc_br16_2)); 00210 Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 00211 (MCFixupKind)Sparc::fixup_sparc_br16_14)); 00212 00213 return 0; 00214 } 00215 00216 00217 00218 #include "SparcGenMCCodeEmitter.inc"