LLVM API Documentation

MipsMCCodeEmitter.cpp
Go to the documentation of this file.
00001 //===-- MipsMCCodeEmitter.cpp - Convert Mips 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 MipsMCCodeEmitter class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 //
00014 
00015 #include "MipsMCCodeEmitter.h"
00016 #include "MCTargetDesc/MipsFixupKinds.h"
00017 #include "MCTargetDesc/MipsMCExpr.h"
00018 #include "MCTargetDesc/MipsMCTargetDesc.h"
00019 #include "llvm/ADT/APFloat.h"
00020 #include "llvm/ADT/SmallVector.h"
00021 #include "llvm/MC/MCContext.h"
00022 #include "llvm/MC/MCExpr.h"
00023 #include "llvm/MC/MCInst.h"
00024 #include "llvm/MC/MCInstrInfo.h"
00025 #include "llvm/MC/MCFixup.h"
00026 #include "llvm/MC/MCSubtargetInfo.h"
00027 #include "llvm/Support/raw_ostream.h"
00028 
00029 #define DEBUG_TYPE "mccodeemitter"
00030 
00031 #define GET_INSTRMAP_INFO
00032 #include "MipsGenInstrInfo.inc"
00033 #undef GET_INSTRMAP_INFO
00034 
00035 namespace llvm {
00036 MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
00037                                          const MCRegisterInfo &MRI,
00038                                          const MCSubtargetInfo &STI,
00039                                          MCContext &Ctx) {
00040   return new MipsMCCodeEmitter(MCII, Ctx, false);
00041 }
00042 
00043 MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
00044                                          const MCRegisterInfo &MRI,
00045                                          const MCSubtargetInfo &STI,
00046                                          MCContext &Ctx) {
00047   return new MipsMCCodeEmitter(MCII, Ctx, true);
00048 }
00049 } // End of namespace llvm.
00050 
00051 // If the D<shift> instruction has a shift amount that is greater
00052 // than 31 (checked in calling routine), lower it to a D<shift>32 instruction
00053 static void LowerLargeShift(MCInst& Inst) {
00054 
00055   assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
00056   assert(Inst.getOperand(2).isImm());
00057 
00058   int64_t Shift = Inst.getOperand(2).getImm();
00059   if (Shift <= 31)
00060     return; // Do nothing
00061   Shift -= 32;
00062 
00063   // saminus32
00064   Inst.getOperand(2).setImm(Shift);
00065 
00066   switch (Inst.getOpcode()) {
00067   default:
00068     // Calling function is not synchronized
00069     llvm_unreachable("Unexpected shift instruction");
00070   case Mips::DSLL:
00071     Inst.setOpcode(Mips::DSLL32);
00072     return;
00073   case Mips::DSRL:
00074     Inst.setOpcode(Mips::DSRL32);
00075     return;
00076   case Mips::DSRA:
00077     Inst.setOpcode(Mips::DSRA32);
00078     return;
00079   case Mips::DROTR:
00080     Inst.setOpcode(Mips::DROTR32);
00081     return;
00082   }
00083 }
00084 
00085 // Pick a DEXT or DINS instruction variant based on the pos and size operands
00086 static void LowerDextDins(MCInst& InstIn) {
00087   int Opcode = InstIn.getOpcode();
00088 
00089   if (Opcode == Mips::DEXT)
00090     assert(InstIn.getNumOperands() == 4 &&
00091            "Invalid no. of machine operands for DEXT!");
00092   else // Only DEXT and DINS are possible
00093     assert(InstIn.getNumOperands() == 5 &&
00094            "Invalid no. of machine operands for DINS!");
00095 
00096   assert(InstIn.getOperand(2).isImm());
00097   int64_t pos = InstIn.getOperand(2).getImm();
00098   assert(InstIn.getOperand(3).isImm());
00099   int64_t size = InstIn.getOperand(3).getImm();
00100 
00101   if (size <= 32) {
00102     if (pos < 32)  // DEXT/DINS, do nothing
00103       return;
00104     // DEXTU/DINSU
00105     InstIn.getOperand(2).setImm(pos - 32);
00106     InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
00107     return;
00108   }
00109   // DEXTM/DINSM
00110   assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
00111   InstIn.getOperand(3).setImm(size - 32);
00112   InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
00113   return;
00114 }
00115 
00116 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
00117   return STI.getFeatureBits() & Mips::FeatureMicroMips;
00118 }
00119 
00120 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
00121   OS << (char)C;
00122 }
00123 
00124 void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
00125                                         const MCSubtargetInfo &STI,
00126                                         raw_ostream &OS) const {
00127   // Output the instruction encoding in little endian byte order.
00128   // Little-endian byte ordering:
00129   //   mips32r2:   4 | 3 | 2 | 1
00130   //   microMIPS:  2 | 1 | 4 | 3
00131   if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
00132     EmitInstruction(Val >> 16, 2, STI, OS);
00133     EmitInstruction(Val, 2, STI, OS);
00134   } else {
00135     for (unsigned i = 0; i < Size; ++i) {
00136       unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
00137       EmitByte((Val >> Shift) & 0xff, OS);
00138     }
00139   }
00140 }
00141 
00142 /// EncodeInstruction - Emit the instruction.
00143 /// Size the instruction with Desc.getSize().
00144 void MipsMCCodeEmitter::
00145 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
00146                   SmallVectorImpl<MCFixup> &Fixups,
00147                   const MCSubtargetInfo &STI) const
00148 {
00149 
00150   // Non-pseudo instructions that get changed for direct object
00151   // only based on operand values.
00152   // If this list of instructions get much longer we will move
00153   // the check to a function call. Until then, this is more efficient.
00154   MCInst TmpInst = MI;
00155   switch (MI.getOpcode()) {
00156   // If shift amount is >= 32 it the inst needs to be lowered further
00157   case Mips::DSLL:
00158   case Mips::DSRL:
00159   case Mips::DSRA:
00160   case Mips::DROTR:
00161     LowerLargeShift(TmpInst);
00162     break;
00163     // Double extract instruction is chosen by pos and size operands
00164   case Mips::DEXT:
00165   case Mips::DINS:
00166     LowerDextDins(TmpInst);
00167   }
00168 
00169   unsigned long N = Fixups.size();
00170   uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
00171 
00172   // Check for unimplemented opcodes.
00173   // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
00174   // so we have to special check for them.
00175   unsigned Opcode = TmpInst.getOpcode();
00176   if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
00177     llvm_unreachable("unimplemented opcode in EncodeInstruction()");
00178 
00179   if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
00180     int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips);
00181     if (NewOpcode != -1) {
00182       if (Fixups.size() > N)
00183         Fixups.pop_back();
00184       Opcode = NewOpcode;
00185       TmpInst.setOpcode (NewOpcode);
00186       Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
00187     }
00188   }
00189 
00190   const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
00191 
00192   // Get byte count of instruction
00193   unsigned Size = Desc.getSize();
00194   if (!Size)
00195     llvm_unreachable("Desc.getSize() returns 0");
00196 
00197   EmitInstruction(Binary, Size, STI, OS);
00198 }
00199 
00200 /// getBranchTargetOpValue - Return binary encoding of the branch
00201 /// target operand. If the machine operand requires relocation,
00202 /// record the relocation and return zero.
00203 unsigned MipsMCCodeEmitter::
00204 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
00205                        SmallVectorImpl<MCFixup> &Fixups,
00206                        const MCSubtargetInfo &STI) const {
00207 
00208   const MCOperand &MO = MI.getOperand(OpNo);
00209 
00210   // If the destination is an immediate, divide by 4.
00211   if (MO.isImm()) return MO.getImm() >> 2;
00212 
00213   assert(MO.isExpr() &&
00214          "getBranchTargetOpValue expects only expressions or immediates");
00215 
00216   const MCExpr *Expr = MO.getExpr();
00217   Fixups.push_back(MCFixup::Create(0, Expr,
00218                                    MCFixupKind(Mips::fixup_Mips_PC16)));
00219   return 0;
00220 }
00221 
00222 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
00223 /// target operand. If the machine operand requires relocation,
00224 /// record the relocation and return zero.
00225 unsigned MipsMCCodeEmitter::
00226 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
00227                          SmallVectorImpl<MCFixup> &Fixups,
00228                          const MCSubtargetInfo &STI) const {
00229 
00230   const MCOperand &MO = MI.getOperand(OpNo);
00231 
00232   // If the destination is an immediate, divide by 2.
00233   if (MO.isImm()) return MO.getImm() >> 1;
00234 
00235   assert(MO.isExpr() &&
00236          "getBranchTargetOpValueMM expects only expressions or immediates");
00237 
00238   const MCExpr *Expr = MO.getExpr();
00239   Fixups.push_back(MCFixup::Create(0, Expr,
00240                    MCFixupKind(Mips::
00241                                fixup_MICROMIPS_PC16_S1)));
00242   return 0;
00243 }
00244 
00245 /// getBranchTarget21OpValue - Return binary encoding of the branch
00246 /// target operand. If the machine operand requires relocation,
00247 /// record the relocation and return zero.
00248 unsigned MipsMCCodeEmitter::
00249 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
00250                          SmallVectorImpl<MCFixup> &Fixups,
00251                          const MCSubtargetInfo &STI) const {
00252 
00253   const MCOperand &MO = MI.getOperand(OpNo);
00254 
00255   // If the destination is an immediate, divide by 4.
00256   if (MO.isImm()) return MO.getImm() >> 2;
00257 
00258   assert(MO.isExpr() &&
00259          "getBranchTarget21OpValue expects only expressions or immediates");
00260 
00261   const MCExpr *Expr = MO.getExpr();
00262   Fixups.push_back(MCFixup::Create(0, Expr,
00263                                    MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
00264   return 0;
00265 }
00266 
00267 /// getBranchTarget26OpValue - Return binary encoding of the branch
00268 /// target operand. If the machine operand requires relocation,
00269 /// record the relocation and return zero.
00270 unsigned MipsMCCodeEmitter::
00271 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
00272                          SmallVectorImpl<MCFixup> &Fixups,
00273                          const MCSubtargetInfo &STI) const {
00274 
00275   const MCOperand &MO = MI.getOperand(OpNo);
00276 
00277   // If the destination is an immediate, divide by 4.
00278   if (MO.isImm()) return MO.getImm() >> 2;
00279 
00280   assert(MO.isExpr() &&
00281          "getBranchTarget26OpValue expects only expressions or immediates");
00282 
00283   const MCExpr *Expr = MO.getExpr();
00284   Fixups.push_back(MCFixup::Create(0, Expr,
00285                                    MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
00286   return 0;
00287 }
00288 
00289 /// getJumpOffset16OpValue - Return binary encoding of the jump
00290 /// target operand. If the machine operand requires relocation,
00291 /// record the relocation and return zero.
00292 unsigned MipsMCCodeEmitter::
00293 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
00294                        SmallVectorImpl<MCFixup> &Fixups,
00295                        const MCSubtargetInfo &STI) const {
00296 
00297   const MCOperand &MO = MI.getOperand(OpNo);
00298 
00299   if (MO.isImm()) return MO.getImm();
00300 
00301   assert(MO.isExpr() &&
00302          "getJumpOffset16OpValue expects only expressions or an immediate");
00303 
00304    // TODO: Push fixup.
00305    return 0;
00306 }
00307 
00308 /// getJumpTargetOpValue - Return binary encoding of the jump
00309 /// target operand. If the machine operand requires relocation,
00310 /// record the relocation and return zero.
00311 unsigned MipsMCCodeEmitter::
00312 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
00313                      SmallVectorImpl<MCFixup> &Fixups,
00314                      const MCSubtargetInfo &STI) const {
00315 
00316   const MCOperand &MO = MI.getOperand(OpNo);
00317   // If the destination is an immediate, divide by 4.
00318   if (MO.isImm()) return MO.getImm()>>2;
00319 
00320   assert(MO.isExpr() &&
00321          "getJumpTargetOpValue expects only expressions or an immediate");
00322 
00323   const MCExpr *Expr = MO.getExpr();
00324   Fixups.push_back(MCFixup::Create(0, Expr,
00325                                    MCFixupKind(Mips::fixup_Mips_26)));
00326   return 0;
00327 }
00328 
00329 unsigned MipsMCCodeEmitter::
00330 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
00331                        SmallVectorImpl<MCFixup> &Fixups,
00332                        const MCSubtargetInfo &STI) const {
00333 
00334   const MCOperand &MO = MI.getOperand(OpNo);
00335   // If the destination is an immediate, divide by 2.
00336   if (MO.isImm()) return MO.getImm() >> 1;
00337 
00338   assert(MO.isExpr() &&
00339          "getJumpTargetOpValueMM expects only expressions or an immediate");
00340 
00341   const MCExpr *Expr = MO.getExpr();
00342   Fixups.push_back(MCFixup::Create(0, Expr,
00343                                    MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
00344   return 0;
00345 }
00346 
00347 unsigned MipsMCCodeEmitter::
00348 getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
00349                      SmallVectorImpl<MCFixup> &Fixups,
00350                      const MCSubtargetInfo &STI) const {
00351 
00352   const MCOperand &MO = MI.getOperand(OpNo);
00353   if (MO.isImm()) {
00354     // The immediate is encoded as 'immediate << 2'.
00355     unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
00356     assert((Res & 3) == 0);
00357     return Res >> 2;
00358   }
00359 
00360   assert(MO.isExpr() &&
00361          "getUImm5Lsl2Encoding expects only expressions or an immediate");
00362 
00363   return 0;
00364 }
00365 
00366 unsigned MipsMCCodeEmitter::
00367 getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups,
00368                const MCSubtargetInfo &STI) const {
00369   int64_t Res;
00370 
00371   if (Expr->EvaluateAsAbsolute(Res))
00372     return Res;
00373 
00374   MCExpr::ExprKind Kind = Expr->getKind();
00375   if (Kind == MCExpr::Constant) {
00376     return cast<MCConstantExpr>(Expr)->getValue();
00377   }
00378 
00379   if (Kind == MCExpr::Binary) {
00380     unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
00381     Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
00382     return Res;
00383   }
00384 
00385   if (Kind == MCExpr::Target) {
00386     const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
00387 
00388     Mips::Fixups FixupKind = Mips::Fixups(0);
00389     switch (MipsExpr->getKind()) {
00390     default: llvm_unreachable("Unsupported fixup kind for target expression!");
00391     case MipsMCExpr::VK_Mips_HIGHEST:
00392       FixupKind = Mips::fixup_Mips_HIGHEST;
00393       break;
00394     case MipsMCExpr::VK_Mips_HIGHER:
00395       FixupKind = Mips::fixup_Mips_HIGHER;
00396       break;
00397     case MipsMCExpr::VK_Mips_HI:
00398       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
00399                                    : Mips::fixup_Mips_HI16;
00400       break;
00401     case MipsMCExpr::VK_Mips_LO:
00402       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
00403                                    : Mips::fixup_Mips_LO16;
00404       break;
00405     }
00406     Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind)));
00407     return 0;
00408   }
00409 
00410   if (Kind == MCExpr::SymbolRef) {
00411     Mips::Fixups FixupKind = Mips::Fixups(0);
00412 
00413     switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
00414     default: llvm_unreachable("Unknown fixup kind!");
00415       break;
00416     case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
00417       FixupKind = Mips::fixup_Mips_GPOFF_HI;
00418       break;
00419     case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
00420       FixupKind = Mips::fixup_Mips_GPOFF_LO;
00421       break;
00422     case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
00423       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
00424                               : Mips::fixup_Mips_GOT_PAGE;
00425       break;
00426     case MCSymbolRefExpr::VK_Mips_GOT_OFST :
00427       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
00428                               : Mips::fixup_Mips_GOT_OFST;
00429       break;
00430     case MCSymbolRefExpr::VK_Mips_GOT_DISP :
00431       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
00432                               : Mips::fixup_Mips_GOT_DISP;
00433       break;
00434     case MCSymbolRefExpr::VK_Mips_GPREL:
00435       FixupKind = Mips::fixup_Mips_GPREL16;
00436       break;
00437     case MCSymbolRefExpr::VK_Mips_GOT_CALL:
00438       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
00439                               : Mips::fixup_Mips_CALL16;
00440       break;
00441     case MCSymbolRefExpr::VK_Mips_GOT16:
00442       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
00443                               : Mips::fixup_Mips_GOT_Global;
00444       break;
00445     case MCSymbolRefExpr::VK_Mips_GOT:
00446       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
00447                               : Mips::fixup_Mips_GOT_Local;
00448       break;
00449     case MCSymbolRefExpr::VK_Mips_ABS_HI:
00450       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
00451                               : Mips::fixup_Mips_HI16;
00452       break;
00453     case MCSymbolRefExpr::VK_Mips_ABS_LO:
00454       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
00455                               : Mips::fixup_Mips_LO16;
00456       break;
00457     case MCSymbolRefExpr::VK_Mips_TLSGD:
00458       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
00459                               : Mips::fixup_Mips_TLSGD;
00460       break;
00461     case MCSymbolRefExpr::VK_Mips_TLSLDM:
00462       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
00463                               : Mips::fixup_Mips_TLSLDM;
00464       break;
00465     case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
00466       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
00467                               : Mips::fixup_Mips_DTPREL_HI;
00468       break;
00469     case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
00470       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
00471                               : Mips::fixup_Mips_DTPREL_LO;
00472       break;
00473     case MCSymbolRefExpr::VK_Mips_GOTTPREL:
00474       FixupKind = Mips::fixup_Mips_GOTTPREL;
00475       break;
00476     case MCSymbolRefExpr::VK_Mips_TPREL_HI:
00477       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
00478                               : Mips::fixup_Mips_TPREL_HI;
00479       break;
00480     case MCSymbolRefExpr::VK_Mips_TPREL_LO:
00481       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
00482                               : Mips::fixup_Mips_TPREL_LO;
00483       break;
00484     case MCSymbolRefExpr::VK_Mips_HIGHER:
00485       FixupKind = Mips::fixup_Mips_HIGHER;
00486       break;
00487     case MCSymbolRefExpr::VK_Mips_HIGHEST:
00488       FixupKind = Mips::fixup_Mips_HIGHEST;
00489       break;
00490     case MCSymbolRefExpr::VK_Mips_GOT_HI16:
00491       FixupKind = Mips::fixup_Mips_GOT_HI16;
00492       break;
00493     case MCSymbolRefExpr::VK_Mips_GOT_LO16:
00494       FixupKind = Mips::fixup_Mips_GOT_LO16;
00495       break;
00496     case MCSymbolRefExpr::VK_Mips_CALL_HI16:
00497       FixupKind = Mips::fixup_Mips_CALL_HI16;
00498       break;
00499     case MCSymbolRefExpr::VK_Mips_CALL_LO16:
00500       FixupKind = Mips::fixup_Mips_CALL_LO16;
00501       break;
00502     case MCSymbolRefExpr::VK_Mips_PCREL_HI16:
00503       FixupKind = Mips::fixup_MIPS_PCHI16;
00504       break;
00505     case MCSymbolRefExpr::VK_Mips_PCREL_LO16:
00506       FixupKind = Mips::fixup_MIPS_PCLO16;
00507       break;
00508     } // switch
00509 
00510     Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
00511     return 0;
00512   }
00513   return 0;
00514 }
00515 
00516 /// getMachineOpValue - Return binary encoding of operand. If the machine
00517 /// operand requires relocation, record the relocation and return zero.
00518 unsigned MipsMCCodeEmitter::
00519 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
00520                   SmallVectorImpl<MCFixup> &Fixups,
00521                   const MCSubtargetInfo &STI) const {
00522   if (MO.isReg()) {
00523     unsigned Reg = MO.getReg();
00524     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
00525     return RegNo;
00526   } else if (MO.isImm()) {
00527     return static_cast<unsigned>(MO.getImm());
00528   } else if (MO.isFPImm()) {
00529     return static_cast<unsigned>(APFloat(MO.getFPImm())
00530         .bitcastToAPInt().getHiBits(32).getLimitedValue());
00531   }
00532   // MO must be an Expr.
00533   assert(MO.isExpr());
00534   return getExprOpValue(MO.getExpr(),Fixups, STI);
00535 }
00536 
00537 /// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST
00538 /// instructions.
00539 unsigned
00540 MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
00541                                      SmallVectorImpl<MCFixup> &Fixups,
00542                                      const MCSubtargetInfo &STI) const {
00543   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
00544   assert(MI.getOperand(OpNo).isReg());
00545   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
00546   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
00547 
00548   // The immediate field of an LD/ST instruction is scaled which means it must
00549   // be divided (when encoding) by the size (in bytes) of the instructions'
00550   // data format.
00551   // .b - 1 byte
00552   // .h - 2 bytes
00553   // .w - 4 bytes
00554   // .d - 8 bytes
00555   switch(MI.getOpcode())
00556   {
00557   default:
00558     assert (0 && "Unexpected instruction");
00559     break;
00560   case Mips::LD_B:
00561   case Mips::ST_B:
00562     // We don't need to scale the offset in this case
00563     break;
00564   case Mips::LD_H:
00565   case Mips::ST_H:
00566     OffBits >>= 1;
00567     break;
00568   case Mips::LD_W:
00569   case Mips::ST_W:
00570     OffBits >>= 2;
00571     break;
00572   case Mips::LD_D:
00573   case Mips::ST_D:
00574     OffBits >>= 3;
00575     break;
00576   }
00577 
00578   return (OffBits & 0xFFFF) | RegBits;
00579 }
00580 
00581 /// getMemEncoding - Return binary encoding of memory related operand.
00582 /// If the offset operand requires relocation, record the relocation.
00583 unsigned
00584 MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
00585                                   SmallVectorImpl<MCFixup> &Fixups,
00586                                   const MCSubtargetInfo &STI) const {
00587   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
00588   assert(MI.getOperand(OpNo).isReg());
00589   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
00590   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
00591 
00592   return (OffBits & 0xFFFF) | RegBits;
00593 }
00594 
00595 unsigned MipsMCCodeEmitter::
00596 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
00597                       SmallVectorImpl<MCFixup> &Fixups,
00598                       const MCSubtargetInfo &STI) const {
00599   // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
00600   assert(MI.getOperand(OpNo).isReg());
00601   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
00602   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
00603 
00604   return (OffBits & 0x0FFF) | RegBits;
00605 }
00606 
00607 unsigned
00608 MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
00609                                       SmallVectorImpl<MCFixup> &Fixups,
00610                                       const MCSubtargetInfo &STI) const {
00611   assert(MI.getOperand(OpNo).isImm());
00612   unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
00613   return SizeEncoding - 1;
00614 }
00615 
00616 // FIXME: should be called getMSBEncoding
00617 //
00618 unsigned
00619 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
00620                                       SmallVectorImpl<MCFixup> &Fixups,
00621                                       const MCSubtargetInfo &STI) const {
00622   assert(MI.getOperand(OpNo-1).isImm());
00623   assert(MI.getOperand(OpNo).isImm());
00624   unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
00625   unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
00626 
00627   return Position + Size - 1;
00628 }
00629 
00630 unsigned
00631 MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
00632                                      SmallVectorImpl<MCFixup> &Fixups,
00633                                      const MCSubtargetInfo &STI) const {
00634   assert(MI.getOperand(OpNo).isImm());
00635   // The immediate is encoded as 'immediate - 1'.
00636   return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1;
00637 }
00638 
00639 unsigned
00640 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
00641                                          SmallVectorImpl<MCFixup> &Fixups,
00642                                          const MCSubtargetInfo &STI) const {
00643   const MCOperand &MO = MI.getOperand(OpNo);
00644   if (MO.isImm()) {
00645     // The immediate is encoded as 'immediate << 2'.
00646     unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
00647     assert((Res & 3) == 0);
00648     return Res >> 2;
00649   }
00650 
00651   assert(MO.isExpr() &&
00652          "getSimm19Lsl2Encoding expects only expressions or an immediate");
00653 
00654   const MCExpr *Expr = MO.getExpr();
00655   Fixups.push_back(MCFixup::Create(0, Expr,
00656                                    MCFixupKind(Mips::fixup_MIPS_PC19_S2)));
00657   return 0;
00658 }
00659 
00660 unsigned
00661 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
00662                                          SmallVectorImpl<MCFixup> &Fixups,
00663                                          const MCSubtargetInfo &STI) const {
00664   const MCOperand &MO = MI.getOperand(OpNo);
00665   if (MO.isImm()) {
00666     // The immediate is encoded as 'immediate << 3'.
00667     unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
00668     assert((Res & 7) == 0);
00669     return Res >> 3;
00670   }
00671 
00672   assert(MO.isExpr() &&
00673          "getSimm18Lsl2Encoding expects only expressions or an immediate");
00674 
00675   const MCExpr *Expr = MO.getExpr();
00676   Fixups.push_back(MCFixup::Create(0, Expr,
00677                                    MCFixupKind(Mips::fixup_MIPS_PC18_S3)));
00678   return 0;
00679 }
00680 
00681 #include "MipsGenMCCodeEmitter.inc"