Home | History | Annotate | Download | only in MCTargetDesc
      1 //===-- MipsMCCodeEmitter.cpp - Convert Mips 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 MipsMCCodeEmitter class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 //
     14 
     15 #include "MipsMCCodeEmitter.h"
     16 #include "MCTargetDesc/MipsFixupKinds.h"
     17 #include "MCTargetDesc/MipsMCExpr.h"
     18 #include "MCTargetDesc/MipsMCTargetDesc.h"
     19 #include "llvm/ADT/APFloat.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 #include "llvm/MC/MCContext.h"
     22 #include "llvm/MC/MCExpr.h"
     23 #include "llvm/MC/MCInst.h"
     24 #include "llvm/MC/MCInstrInfo.h"
     25 #include "llvm/MC/MCFixup.h"
     26 #include "llvm/MC/MCSubtargetInfo.h"
     27 #include "llvm/Support/raw_ostream.h"
     28 
     29 #define DEBUG_TYPE "mccodeemitter"
     30 
     31 #define GET_INSTRMAP_INFO
     32 #include "MipsGenInstrInfo.inc"
     33 #undef GET_INSTRMAP_INFO
     34 
     35 namespace llvm {
     36 MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
     37                                          const MCRegisterInfo &MRI,
     38                                          const MCSubtargetInfo &STI,
     39                                          MCContext &Ctx) {
     40   return new MipsMCCodeEmitter(MCII, Ctx, false);
     41 }
     42 
     43 MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
     44                                          const MCRegisterInfo &MRI,
     45                                          const MCSubtargetInfo &STI,
     46                                          MCContext &Ctx) {
     47   return new MipsMCCodeEmitter(MCII, Ctx, true);
     48 }
     49 } // End of namespace llvm.
     50 
     51 // If the D<shift> instruction has a shift amount that is greater
     52 // than 31 (checked in calling routine), lower it to a D<shift>32 instruction
     53 static void LowerLargeShift(MCInst& Inst) {
     54 
     55   assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
     56   assert(Inst.getOperand(2).isImm());
     57 
     58   int64_t Shift = Inst.getOperand(2).getImm();
     59   if (Shift <= 31)
     60     return; // Do nothing
     61   Shift -= 32;
     62 
     63   // saminus32
     64   Inst.getOperand(2).setImm(Shift);
     65 
     66   switch (Inst.getOpcode()) {
     67   default:
     68     // Calling function is not synchronized
     69     llvm_unreachable("Unexpected shift instruction");
     70   case Mips::DSLL:
     71     Inst.setOpcode(Mips::DSLL32);
     72     return;
     73   case Mips::DSRL:
     74     Inst.setOpcode(Mips::DSRL32);
     75     return;
     76   case Mips::DSRA:
     77     Inst.setOpcode(Mips::DSRA32);
     78     return;
     79   case Mips::DROTR:
     80     Inst.setOpcode(Mips::DROTR32);
     81     return;
     82   }
     83 }
     84 
     85 // Pick a DEXT or DINS instruction variant based on the pos and size operands
     86 static void LowerDextDins(MCInst& InstIn) {
     87   int Opcode = InstIn.getOpcode();
     88 
     89   if (Opcode == Mips::DEXT)
     90     assert(InstIn.getNumOperands() == 4 &&
     91            "Invalid no. of machine operands for DEXT!");
     92   else // Only DEXT and DINS are possible
     93     assert(InstIn.getNumOperands() == 5 &&
     94            "Invalid no. of machine operands for DINS!");
     95 
     96   assert(InstIn.getOperand(2).isImm());
     97   int64_t pos = InstIn.getOperand(2).getImm();
     98   assert(InstIn.getOperand(3).isImm());
     99   int64_t size = InstIn.getOperand(3).getImm();
    100 
    101   if (size <= 32) {
    102     if (pos < 32)  // DEXT/DINS, do nothing
    103       return;
    104     // DEXTU/DINSU
    105     InstIn.getOperand(2).setImm(pos - 32);
    106     InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
    107     return;
    108   }
    109   // DEXTM/DINSM
    110   assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
    111   InstIn.getOperand(3).setImm(size - 32);
    112   InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
    113   return;
    114 }
    115 
    116 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
    117   return STI.getFeatureBits() & Mips::FeatureMicroMips;
    118 }
    119 
    120 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
    121   OS << (char)C;
    122 }
    123 
    124 void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
    125                                         const MCSubtargetInfo &STI,
    126                                         raw_ostream &OS) const {
    127   // Output the instruction encoding in little endian byte order.
    128   // Little-endian byte ordering:
    129   //   mips32r2:   4 | 3 | 2 | 1
    130   //   microMIPS:  2 | 1 | 4 | 3
    131   if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
    132     EmitInstruction(Val >> 16, 2, STI, OS);
    133     EmitInstruction(Val, 2, STI, OS);
    134   } else {
    135     for (unsigned i = 0; i < Size; ++i) {
    136       unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
    137       EmitByte((Val >> Shift) & 0xff, OS);
    138     }
    139   }
    140 }
    141 
    142 /// EncodeInstruction - Emit the instruction.
    143 /// Size the instruction with Desc.getSize().
    144 void MipsMCCodeEmitter::
    145 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
    146                   SmallVectorImpl<MCFixup> &Fixups,
    147                   const MCSubtargetInfo &STI) const
    148 {
    149 
    150   // Non-pseudo instructions that get changed for direct object
    151   // only based on operand values.
    152   // If this list of instructions get much longer we will move
    153   // the check to a function call. Until then, this is more efficient.
    154   MCInst TmpInst = MI;
    155   switch (MI.getOpcode()) {
    156   // If shift amount is >= 32 it the inst needs to be lowered further
    157   case Mips::DSLL:
    158   case Mips::DSRL:
    159   case Mips::DSRA:
    160   case Mips::DROTR:
    161     LowerLargeShift(TmpInst);
    162     break;
    163     // Double extract instruction is chosen by pos and size operands
    164   case Mips::DEXT:
    165   case Mips::DINS:
    166     LowerDextDins(TmpInst);
    167   }
    168 
    169   unsigned long N = Fixups.size();
    170   uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
    171 
    172   // Check for unimplemented opcodes.
    173   // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
    174   // so we have to special check for them.
    175   unsigned Opcode = TmpInst.getOpcode();
    176   if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
    177     llvm_unreachable("unimplemented opcode in EncodeInstruction()");
    178 
    179   if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
    180     int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips);
    181     if (NewOpcode != -1) {
    182       if (Fixups.size() > N)
    183         Fixups.pop_back();
    184       Opcode = NewOpcode;
    185       TmpInst.setOpcode (NewOpcode);
    186       Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
    187     }
    188   }
    189 
    190   const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
    191 
    192   // Get byte count of instruction
    193   unsigned Size = Desc.getSize();
    194   if (!Size)
    195     llvm_unreachable("Desc.getSize() returns 0");
    196 
    197   EmitInstruction(Binary, Size, STI, OS);
    198 }
    199 
    200 /// getBranchTargetOpValue - Return binary encoding of the branch
    201 /// target operand. If the machine operand requires relocation,
    202 /// record the relocation and return zero.
    203 unsigned MipsMCCodeEmitter::
    204 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
    205                        SmallVectorImpl<MCFixup> &Fixups,
    206                        const MCSubtargetInfo &STI) const {
    207 
    208   const MCOperand &MO = MI.getOperand(OpNo);
    209 
    210   // If the destination is an immediate, divide by 4.
    211   if (MO.isImm()) return MO.getImm() >> 2;
    212 
    213   assert(MO.isExpr() &&
    214          "getBranchTargetOpValue expects only expressions or immediates");
    215 
    216   const MCExpr *Expr = MO.getExpr();
    217   Fixups.push_back(MCFixup::Create(0, Expr,
    218                                    MCFixupKind(Mips::fixup_Mips_PC16)));
    219   return 0;
    220 }
    221 
    222 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
    223 /// target operand. If the machine operand requires relocation,
    224 /// record the relocation and return zero.
    225 unsigned MipsMCCodeEmitter::
    226 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
    227                          SmallVectorImpl<MCFixup> &Fixups,
    228                          const MCSubtargetInfo &STI) const {
    229 
    230   const MCOperand &MO = MI.getOperand(OpNo);
    231 
    232   // If the destination is an immediate, divide by 2.
    233   if (MO.isImm()) return MO.getImm() >> 1;
    234 
    235   assert(MO.isExpr() &&
    236          "getBranchTargetOpValueMM expects only expressions or immediates");
    237 
    238   const MCExpr *Expr = MO.getExpr();
    239   Fixups.push_back(MCFixup::Create(0, Expr,
    240                    MCFixupKind(Mips::
    241                                fixup_MICROMIPS_PC16_S1)));
    242   return 0;
    243 }
    244 
    245 /// getBranchTarget21OpValue - Return binary encoding of the branch
    246 /// target operand. If the machine operand requires relocation,
    247 /// record the relocation and return zero.
    248 unsigned MipsMCCodeEmitter::
    249 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
    250                          SmallVectorImpl<MCFixup> &Fixups,
    251                          const MCSubtargetInfo &STI) const {
    252 
    253   const MCOperand &MO = MI.getOperand(OpNo);
    254 
    255   // If the destination is an immediate, divide by 4.
    256   if (MO.isImm()) return MO.getImm() >> 2;
    257 
    258   assert(MO.isExpr() &&
    259          "getBranchTarget21OpValue expects only expressions or immediates");
    260 
    261   const MCExpr *Expr = MO.getExpr();
    262   Fixups.push_back(MCFixup::Create(0, Expr,
    263                                    MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
    264   return 0;
    265 }
    266 
    267 /// getBranchTarget26OpValue - Return binary encoding of the branch
    268 /// target operand. If the machine operand requires relocation,
    269 /// record the relocation and return zero.
    270 unsigned MipsMCCodeEmitter::
    271 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
    272                          SmallVectorImpl<MCFixup> &Fixups,
    273                          const MCSubtargetInfo &STI) const {
    274 
    275   const MCOperand &MO = MI.getOperand(OpNo);
    276 
    277   // If the destination is an immediate, divide by 4.
    278   if (MO.isImm()) return MO.getImm() >> 2;
    279 
    280   assert(MO.isExpr() &&
    281          "getBranchTarget26OpValue expects only expressions or immediates");
    282 
    283   const MCExpr *Expr = MO.getExpr();
    284   Fixups.push_back(MCFixup::Create(0, Expr,
    285                                    MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
    286   return 0;
    287 }
    288 
    289 /// getJumpOffset16OpValue - Return binary encoding of the jump
    290 /// target operand. If the machine operand requires relocation,
    291 /// record the relocation and return zero.
    292 unsigned MipsMCCodeEmitter::
    293 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
    294                        SmallVectorImpl<MCFixup> &Fixups,
    295                        const MCSubtargetInfo &STI) const {
    296 
    297   const MCOperand &MO = MI.getOperand(OpNo);
    298 
    299   if (MO.isImm()) return MO.getImm();
    300 
    301   assert(MO.isExpr() &&
    302          "getJumpOffset16OpValue expects only expressions or an immediate");
    303 
    304    // TODO: Push fixup.
    305    return 0;
    306 }
    307 
    308 /// getJumpTargetOpValue - Return binary encoding of the jump
    309 /// target operand. If the machine operand requires relocation,
    310 /// record the relocation and return zero.
    311 unsigned MipsMCCodeEmitter::
    312 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
    313                      SmallVectorImpl<MCFixup> &Fixups,
    314                      const MCSubtargetInfo &STI) const {
    315 
    316   const MCOperand &MO = MI.getOperand(OpNo);
    317   // If the destination is an immediate, divide by 4.
    318   if (MO.isImm()) return MO.getImm()>>2;
    319 
    320   assert(MO.isExpr() &&
    321          "getJumpTargetOpValue expects only expressions or an immediate");
    322 
    323   const MCExpr *Expr = MO.getExpr();
    324   Fixups.push_back(MCFixup::Create(0, Expr,
    325                                    MCFixupKind(Mips::fixup_Mips_26)));
    326   return 0;
    327 }
    328 
    329 unsigned MipsMCCodeEmitter::
    330 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
    331                        SmallVectorImpl<MCFixup> &Fixups,
    332                        const MCSubtargetInfo &STI) const {
    333 
    334   const MCOperand &MO = MI.getOperand(OpNo);
    335   // If the destination is an immediate, divide by 2.
    336   if (MO.isImm()) return MO.getImm() >> 1;
    337 
    338   assert(MO.isExpr() &&
    339          "getJumpTargetOpValueMM expects only expressions or an immediate");
    340 
    341   const MCExpr *Expr = MO.getExpr();
    342   Fixups.push_back(MCFixup::Create(0, Expr,
    343                                    MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
    344   return 0;
    345 }
    346 
    347 unsigned MipsMCCodeEmitter::
    348 getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups,
    349                const MCSubtargetInfo &STI) const {
    350   int64_t Res;
    351 
    352   if (Expr->EvaluateAsAbsolute(Res))
    353     return Res;
    354 
    355   MCExpr::ExprKind Kind = Expr->getKind();
    356   if (Kind == MCExpr::Constant) {
    357     return cast<MCConstantExpr>(Expr)->getValue();
    358   }
    359 
    360   if (Kind == MCExpr::Binary) {
    361     unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
    362     Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
    363     return Res;
    364   }
    365 
    366   if (Kind == MCExpr::Target) {
    367     const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
    368 
    369     Mips::Fixups FixupKind = Mips::Fixups(0);
    370     switch (MipsExpr->getKind()) {
    371     default: llvm_unreachable("Unsupported fixup kind for target expression!");
    372     case MipsMCExpr::VK_Mips_HIGHEST:
    373       FixupKind = Mips::fixup_Mips_HIGHEST;
    374       break;
    375     case MipsMCExpr::VK_Mips_HIGHER:
    376       FixupKind = Mips::fixup_Mips_HIGHER;
    377       break;
    378     case MipsMCExpr::VK_Mips_HI:
    379       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
    380                                    : Mips::fixup_Mips_HI16;
    381       break;
    382     case MipsMCExpr::VK_Mips_LO:
    383       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
    384                                    : Mips::fixup_Mips_LO16;
    385       break;
    386     }
    387     Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind)));
    388     return 0;
    389   }
    390 
    391   if (Kind == MCExpr::SymbolRef) {
    392     Mips::Fixups FixupKind = Mips::Fixups(0);
    393 
    394     switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
    395     default: llvm_unreachable("Unknown fixup kind!");
    396       break;
    397     case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
    398       FixupKind = Mips::fixup_Mips_GPOFF_HI;
    399       break;
    400     case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
    401       FixupKind = Mips::fixup_Mips_GPOFF_LO;
    402       break;
    403     case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
    404       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
    405                               : Mips::fixup_Mips_GOT_PAGE;
    406       break;
    407     case MCSymbolRefExpr::VK_Mips_GOT_OFST :
    408       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
    409                               : Mips::fixup_Mips_GOT_OFST;
    410       break;
    411     case MCSymbolRefExpr::VK_Mips_GOT_DISP :
    412       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
    413                               : Mips::fixup_Mips_GOT_DISP;
    414       break;
    415     case MCSymbolRefExpr::VK_Mips_GPREL:
    416       FixupKind = Mips::fixup_Mips_GPREL16;
    417       break;
    418     case MCSymbolRefExpr::VK_Mips_GOT_CALL:
    419       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
    420                               : Mips::fixup_Mips_CALL16;
    421       break;
    422     case MCSymbolRefExpr::VK_Mips_GOT16:
    423       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
    424                               : Mips::fixup_Mips_GOT_Global;
    425       break;
    426     case MCSymbolRefExpr::VK_Mips_GOT:
    427       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
    428                               : Mips::fixup_Mips_GOT_Local;
    429       break;
    430     case MCSymbolRefExpr::VK_Mips_ABS_HI:
    431       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
    432                               : Mips::fixup_Mips_HI16;
    433       break;
    434     case MCSymbolRefExpr::VK_Mips_ABS_LO:
    435       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
    436                               : Mips::fixup_Mips_LO16;
    437       break;
    438     case MCSymbolRefExpr::VK_Mips_TLSGD:
    439       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
    440                               : Mips::fixup_Mips_TLSGD;
    441       break;
    442     case MCSymbolRefExpr::VK_Mips_TLSLDM:
    443       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
    444                               : Mips::fixup_Mips_TLSLDM;
    445       break;
    446     case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
    447       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
    448                               : Mips::fixup_Mips_DTPREL_HI;
    449       break;
    450     case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
    451       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
    452                               : Mips::fixup_Mips_DTPREL_LO;
    453       break;
    454     case MCSymbolRefExpr::VK_Mips_GOTTPREL:
    455       FixupKind = Mips::fixup_Mips_GOTTPREL;
    456       break;
    457     case MCSymbolRefExpr::VK_Mips_TPREL_HI:
    458       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
    459                               : Mips::fixup_Mips_TPREL_HI;
    460       break;
    461     case MCSymbolRefExpr::VK_Mips_TPREL_LO:
    462       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
    463                               : Mips::fixup_Mips_TPREL_LO;
    464       break;
    465     case MCSymbolRefExpr::VK_Mips_HIGHER:
    466       FixupKind = Mips::fixup_Mips_HIGHER;
    467       break;
    468     case MCSymbolRefExpr::VK_Mips_HIGHEST:
    469       FixupKind = Mips::fixup_Mips_HIGHEST;
    470       break;
    471     case MCSymbolRefExpr::VK_Mips_GOT_HI16:
    472       FixupKind = Mips::fixup_Mips_GOT_HI16;
    473       break;
    474     case MCSymbolRefExpr::VK_Mips_GOT_LO16:
    475       FixupKind = Mips::fixup_Mips_GOT_LO16;
    476       break;
    477     case MCSymbolRefExpr::VK_Mips_CALL_HI16:
    478       FixupKind = Mips::fixup_Mips_CALL_HI16;
    479       break;
    480     case MCSymbolRefExpr::VK_Mips_CALL_LO16:
    481       FixupKind = Mips::fixup_Mips_CALL_LO16;
    482       break;
    483     case MCSymbolRefExpr::VK_Mips_PCREL_HI16:
    484       FixupKind = Mips::fixup_MIPS_PCHI16;
    485       break;
    486     case MCSymbolRefExpr::VK_Mips_PCREL_LO16:
    487       FixupKind = Mips::fixup_MIPS_PCLO16;
    488       break;
    489     } // switch
    490 
    491     Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
    492     return 0;
    493   }
    494   return 0;
    495 }
    496 
    497 /// getMachineOpValue - Return binary encoding of operand. If the machine
    498 /// operand requires relocation, record the relocation and return zero.
    499 unsigned MipsMCCodeEmitter::
    500 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
    501                   SmallVectorImpl<MCFixup> &Fixups,
    502                   const MCSubtargetInfo &STI) const {
    503   if (MO.isReg()) {
    504     unsigned Reg = MO.getReg();
    505     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
    506     return RegNo;
    507   } else if (MO.isImm()) {
    508     return static_cast<unsigned>(MO.getImm());
    509   } else if (MO.isFPImm()) {
    510     return static_cast<unsigned>(APFloat(MO.getFPImm())
    511         .bitcastToAPInt().getHiBits(32).getLimitedValue());
    512   }
    513   // MO must be an Expr.
    514   assert(MO.isExpr());
    515   return getExprOpValue(MO.getExpr(),Fixups, STI);
    516 }
    517 
    518 /// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST
    519 /// instructions.
    520 unsigned
    521 MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
    522                                      SmallVectorImpl<MCFixup> &Fixups,
    523                                      const MCSubtargetInfo &STI) const {
    524   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
    525   assert(MI.getOperand(OpNo).isReg());
    526   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
    527   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
    528 
    529   // The immediate field of an LD/ST instruction is scaled which means it must
    530   // be divided (when encoding) by the size (in bytes) of the instructions'
    531   // data format.
    532   // .b - 1 byte
    533   // .h - 2 bytes
    534   // .w - 4 bytes
    535   // .d - 8 bytes
    536   switch(MI.getOpcode())
    537   {
    538   default:
    539     assert (0 && "Unexpected instruction");
    540     break;
    541   case Mips::LD_B:
    542   case Mips::ST_B:
    543     // We don't need to scale the offset in this case
    544     break;
    545   case Mips::LD_H:
    546   case Mips::ST_H:
    547     OffBits >>= 1;
    548     break;
    549   case Mips::LD_W:
    550   case Mips::ST_W:
    551     OffBits >>= 2;
    552     break;
    553   case Mips::LD_D:
    554   case Mips::ST_D:
    555     OffBits >>= 3;
    556     break;
    557   }
    558 
    559   return (OffBits & 0xFFFF) | RegBits;
    560 }
    561 
    562 /// getMemEncoding - Return binary encoding of memory related operand.
    563 /// If the offset operand requires relocation, record the relocation.
    564 unsigned
    565 MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
    566                                   SmallVectorImpl<MCFixup> &Fixups,
    567                                   const MCSubtargetInfo &STI) const {
    568   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
    569   assert(MI.getOperand(OpNo).isReg());
    570   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
    571   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
    572 
    573   return (OffBits & 0xFFFF) | RegBits;
    574 }
    575 
    576 unsigned MipsMCCodeEmitter::
    577 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
    578                       SmallVectorImpl<MCFixup> &Fixups,
    579                       const MCSubtargetInfo &STI) const {
    580   // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
    581   assert(MI.getOperand(OpNo).isReg());
    582   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
    583   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
    584 
    585   return (OffBits & 0x0FFF) | RegBits;
    586 }
    587 
    588 unsigned
    589 MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
    590                                       SmallVectorImpl<MCFixup> &Fixups,
    591                                       const MCSubtargetInfo &STI) const {
    592   assert(MI.getOperand(OpNo).isImm());
    593   unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
    594   return SizeEncoding - 1;
    595 }
    596 
    597 // FIXME: should be called getMSBEncoding
    598 //
    599 unsigned
    600 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
    601                                       SmallVectorImpl<MCFixup> &Fixups,
    602                                       const MCSubtargetInfo &STI) const {
    603   assert(MI.getOperand(OpNo-1).isImm());
    604   assert(MI.getOperand(OpNo).isImm());
    605   unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
    606   unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
    607 
    608   return Position + Size - 1;
    609 }
    610 
    611 unsigned
    612 MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
    613                                      SmallVectorImpl<MCFixup> &Fixups,
    614                                      const MCSubtargetInfo &STI) const {
    615   assert(MI.getOperand(OpNo).isImm());
    616   // The immediate is encoded as 'immediate - 1'.
    617   return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1;
    618 }
    619 
    620 unsigned
    621 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
    622                                          SmallVectorImpl<MCFixup> &Fixups,
    623                                          const MCSubtargetInfo &STI) const {
    624   const MCOperand &MO = MI.getOperand(OpNo);
    625   if (MO.isImm()) {
    626     // The immediate is encoded as 'immediate << 2'.
    627     unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
    628     assert((Res & 3) == 0);
    629     return Res >> 2;
    630   }
    631 
    632   assert(MO.isExpr() &&
    633          "getSimm19Lsl2Encoding expects only expressions or an immediate");
    634 
    635   const MCExpr *Expr = MO.getExpr();
    636   Fixups.push_back(MCFixup::Create(0, Expr,
    637                                    MCFixupKind(Mips::fixup_MIPS_PC19_S2)));
    638   return 0;
    639 }
    640 
    641 unsigned
    642 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
    643                                          SmallVectorImpl<MCFixup> &Fixups,
    644                                          const MCSubtargetInfo &STI) const {
    645   const MCOperand &MO = MI.getOperand(OpNo);
    646   if (MO.isImm()) {
    647     // The immediate is encoded as 'immediate << 3'.
    648     unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
    649     assert((Res & 7) == 0);
    650     return Res >> 3;
    651   }
    652 
    653   assert(MO.isExpr() &&
    654          "getSimm18Lsl2Encoding expects only expressions or an immediate");
    655 
    656   const MCExpr *Expr = MO.getExpr();
    657   Fixups.push_back(MCFixup::Create(0, Expr,
    658                                    MCFixupKind(Mips::fixup_MIPS_PC18_S3)));
    659   return 0;
    660 }
    661 
    662 #include "MipsGenMCCodeEmitter.inc"
    663