LLVM API Documentation

SparcMCCodeEmitter.cpp
Go to the documentation of this file.
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"