MipsMCCodeEmitter.cpp revision 1aaf43c2a2ec0fd4c8dbfe56558237219c5f8af7
18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file implements the MipsMCCodeEmitter class.
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#define DEBUG_TYPE "mccodeemitter"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "MCTargetDesc/MipsBaseInfo.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "MCTargetDesc/MipsFixupKinds.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "MCTargetDesc/MipsMCTargetDesc.h"
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/ADT/APFloat.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/Statistic.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/MC/MCCodeEmitter.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCContext.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/MC/MCExpr.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/MC/MCInst.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "llvm/MC/MCInstrInfo.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/MC/MCRegisterInfo.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "llvm/MC/MCSubtargetInfo.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "llvm/Support/raw_ostream.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#define GET_INSTRMAP_INFO
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "MipsGenInstrInfo.inc"
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace llvm;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass MipsMCCodeEmitter : public MCCodeEmitter {
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MipsMCCodeEmitter(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void operator=(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const MCInstrInfo &MCII;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MCContext &Ctx;
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const MCSubtargetInfo &STI;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsLittleEndian;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsMicroMips;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_,
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    const MCSubtargetInfo &sti, bool IsLittle) :
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MCII(mcii), Ctx(Ctx_), STI (sti), IsLittleEndian(IsLittle) {
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ~MipsMCCodeEmitter() {}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EmitByte(unsigned char C, raw_ostream &OS) const {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OS << (char)C;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EmitInstruction(uint64_t Val, unsigned Size, raw_ostream &OS) const {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Output the instruction encoding in little endian byte order.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Little-endian byte ordering:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   mips32r2:   4 | 3 | 2 | 1
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   microMIPS:  2 | 1 | 4 | 3
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsLittleEndian && Size == 4 && IsMicroMips) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EmitInstruction(Val>>16, 2, OS);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EmitInstruction(Val, 2, OS);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (unsigned i = 0; i < Size; ++i) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EmitByte((Val >> Shift) & 0xff, OS);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         SmallVectorImpl<MCFixup> &Fixups) const;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // getBinaryCodeForInstr - TableGen'erated function for getting the
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // binary encoding for an instruction.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64_t getBinaryCodeForInstr(const MCInst &MI,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 SmallVectorImpl<MCFixup> &Fixups) const;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // getBranchJumpOpValue - Return binary encoding of the jump
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // target operand. If the machine operand requires relocation,
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // record the relocation and return zero.
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 SmallVectorImpl<MCFixup> &Fixups) const;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // getBranchJumpOpValueMM - Return binary encoding of the microMIPS jump
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // target operand. If the machine operand requires relocation,
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // record the relocation and return zero.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  SmallVectorImpl<MCFixup> &Fixups) const;
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   // getBranchTargetOpValue - Return binary encoding of the branch
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   // target operand. If the machine operand requires relocation,
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   // record the relocation and return zero.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  SmallVectorImpl<MCFixup> &Fixups) const;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   // getMachineOpValue - Return binary encoding of operand. If the machin
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   // operand requires relocation, record the relocation and return zero.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             SmallVectorImpl<MCFixup> &Fixups) const;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned getMemEncoding(const MCInst &MI, unsigned OpNo,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          SmallVectorImpl<MCFixup> &Fixups) const;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                 SmallVectorImpl<MCFixup> &Fixups) const;
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  unsigned getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SmallVectorImpl<MCFixup> &Fixups) const;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SmallVectorImpl<MCFixup> &Fixups) const;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; // class MipsMCCodeEmitter
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MCCodeEmitter *llvm::createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const MCRegisterInfo &MRI,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const MCSubtargetInfo &STI,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               MCContext &Ctx)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new MipsMCCodeEmitter(MCII, Ctx, STI, false);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MCCodeEmitter *llvm::createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                               const MCRegisterInfo &MRI,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const MCSubtargetInfo &STI,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               MCContext &Ctx)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new MipsMCCodeEmitter(MCII, Ctx, STI, true);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// If the D<shift> instruction has a shift amount that is greater
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void LowerLargeShift(MCInst& Inst) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(Inst.getOperand(2).isImm());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64_t Shift = Inst.getOperand(2).getImm();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (Shift <= 31)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return; // Do nothing
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shift -= 32;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // saminus32
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Inst.getOperand(2).setImm(Shift);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (Inst.getOpcode()) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Calling function is not synchronized
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    llvm_unreachable("Unexpected shift instruction");
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DSLL:
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Inst.setOpcode(Mips::DSLL32);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DSRL:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Inst.setOpcode(Mips::DSRL32);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DSRA:
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Inst.setOpcode(Mips::DSRA32);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DROTR:
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Inst.setOpcode(Mips::DROTR32);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pick a DEXT or DINS instruction variant based on the pos and size operands
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void LowerDextDins(MCInst& InstIn) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Opcode = InstIn.getOpcode();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (Opcode == Mips::DEXT)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert(InstIn.getNumOperands() == 4 &&
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           "Invalid no. of machine operands for DEXT!");
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else // Only DEXT and DINS are possible
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert(InstIn.getNumOperands() == 5 &&
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)           "Invalid no. of machine operands for DINS!");
18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(InstIn.getOperand(2).isImm());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64_t pos = InstIn.getOperand(2).getImm();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(InstIn.getOperand(3).isImm());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64_t size = InstIn.getOperand(3).getImm();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size <= 32) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pos < 32)  // DEXT/DINS, do nothing
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // DEXTU/DINSU
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstIn.getOperand(2).setImm(pos - 32);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DEXTM/DINSM
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstIn.getOperand(3).setImm(size - 32);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// EncodeInstruction - Emit the instruction.
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// Size the instruction with Desc.getSize().
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MipsMCCodeEmitter::
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EncodeInstruction(const MCInst &MI, raw_ostream &OS,
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  SmallVectorImpl<MCFixup> &Fixups) const
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-pseudo instructions that get changed for direct object
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // only based on operand values.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this list of instructions get much longer we will move
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the check to a function call. Until then, this is more efficient.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MCInst TmpInst = MI;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (MI.getOpcode()) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If shift amount is >= 32 it the inst needs to be lowered further
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DSLL:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DSRL:
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DSRA:
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DROTR:
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LowerLargeShift(TmpInst);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    break;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Double extract instruction is chosen by pos and size operands
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DEXT:
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case Mips::DINS:
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LowerDextDins(TmpInst);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned long N = Fixups.size();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups);
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for unimplemented opcodes.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we have to special check for them.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned Opcode = TmpInst.getOpcode();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    llvm_unreachable("unimplemented opcode in EncodeInstruction()");
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NewOpcode != -1) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (Fixups.size() > N)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Fixups.pop_back();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Opcode = NewOpcode;
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TmpInst.setOpcode (NewOpcode);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Binary = getBinaryCodeForInstr(TmpInst, Fixups);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get byte count of instruction
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned Size = Desc.getSize();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Size)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    llvm_unreachable("Desc.getSize() returns 0");
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EmitInstruction(Binary, Size, OS);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// getBranchTargetOpValue - Return binary encoding of the branch
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// target operand. If the machine operand requires relocation,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// record the relocation and return zero.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned MipsMCCodeEmitter::
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       SmallVectorImpl<MCFixup> &Fixups) const {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MCOperand &MO = MI.getOperand(OpNo);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the destination is an immediate, divide by 4.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MO.isImm()) return MO.getImm() >> 2;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  assert(MO.isExpr() &&
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)         "getBranchTargetOpValue expects only expressions or immediates");
27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const MCExpr *Expr = MO.getExpr();
27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  Fixups.push_back(MCFixup::Create(0, Expr,
27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                   MCFixupKind(Mips::fixup_Mips_PC16)));
27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return 0;
27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)/// getJumpTargetOpValue - Return binary encoding of the jump
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)/// target operand. If the machine operand requires relocation,
2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)/// record the relocation and return zero.
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)unsigned MipsMCCodeEmitter::
28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     SmallVectorImpl<MCFixup> &Fixups) const {
28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const MCOperand &MO = MI.getOperand(OpNo);
28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // If the destination is an immediate, divide by 4.
28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (MO.isImm()) return MO.getImm()>>2;
28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  assert(MO.isExpr() &&
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)         "getJumpTargetOpValue expects only expressions or an immediate");
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const MCExpr *Expr = MO.getExpr();
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  Fixups.push_back(MCFixup::Create(0, Expr,
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                   MCFixupKind(Mips::fixup_Mips_26)));
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return 0;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)unsigned MipsMCCodeEmitter::
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       SmallVectorImpl<MCFixup> &Fixups) const {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MCOperand &MO = MI.getOperand(OpNo);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the destination is an immediate, divide by 2.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MO.isImm()) return MO.getImm() >> 1;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  assert(MO.isExpr() &&
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         "getJumpTargetOpValueMM expects only expressions or an immediate");
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MCExpr *Expr = MO.getExpr();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fixups.push_back(MCFixup::Create(0, Expr,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned MipsMCCodeEmitter::
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const {
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int64_t Res;
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (Expr->EvaluateAsAbsolute(Res))
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return Res;
322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MCExpr::ExprKind Kind = Expr->getKind();
324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (Kind == MCExpr::Constant) {
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return cast<MCConstantExpr>(Expr)->getValue();
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (Kind == MCExpr::Binary) {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Res;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (Kind == MCExpr::SymbolRef) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mips::Fixups FixupKind = Mips::Fixups(0);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default: llvm_unreachable("Unknown fixup kind!");
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    break;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FixupKind = Mips::fixup_Mips_GPOFF_HI;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    break;
3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FixupKind = Mips::fixup_Mips_GPOFF_LO;
3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    break;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_PAGE
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            : Mips::fixup_Mips_GOT_PAGE;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    break;
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GOT_OFST :
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_OFST
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            : Mips::fixup_Mips_GOT_OFST;
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    break;
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GOT_DISP :
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_DISP
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            : Mips::fixup_Mips_GOT_DISP;
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    break;
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GPREL:
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FixupKind = Mips::fixup_Mips_GPREL16;
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    break;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GOT_CALL:
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_CALL16
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            : Mips::fixup_Mips_CALL16;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    break;
364010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GOT16:
365010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            : Mips::fixup_Mips_GOT_Global;
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GOT:
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            : Mips::fixup_Mips_GOT_Local;
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_ABS_HI:
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_HI16
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            : Mips::fixup_Mips_HI16;
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_ABS_LO:
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_LO16
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            : Mips::fixup_Mips_LO16;
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_TLSGD:
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = Mips::fixup_Mips_TLSGD;
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_TLSLDM:
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = Mips::fixup_Mips_TLSLDM;
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            : Mips::fixup_Mips_DTPREL_HI;
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            : Mips::fixup_Mips_DTPREL_LO;
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GOTTPREL:
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = Mips::fixup_Mips_GOTTPREL;
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_TPREL_HI:
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            : Mips::fixup_Mips_TPREL_HI;
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_TPREL_LO:
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            : Mips::fixup_Mips_TPREL_LO;
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_HIGHER:
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = Mips::fixup_Mips_HIGHER;
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_HIGHEST:
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = Mips::fixup_Mips_HIGHEST;
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GOT_HI16:
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = Mips::fixup_Mips_GOT_HI16;
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_GOT_LO16:
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = Mips::fixup_Mips_GOT_LO16;
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_CALL_HI16:
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = Mips::fixup_Mips_CALL_HI16;
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case MCSymbolRefExpr::VK_Mips_CALL_LO16:
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FixupKind = Mips::fixup_Mips_CALL_LO16;
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } // switch
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return 0;
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 0;
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// getMachineOpValue - Return binary encoding of operand. If the machine
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// operand requires relocation, record the relocation and return zero.
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned MipsMCCodeEmitter::
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)getMachineOpValue(const MCInst &MI, const MCOperand &MO,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  SmallVectorImpl<MCFixup> &Fixups) const {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MO.isReg()) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned Reg = MO.getReg();
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return RegNo;
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (MO.isImm()) {
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return static_cast<unsigned>(MO.getImm());
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (MO.isFPImm()) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<unsigned>(APFloat(MO.getFPImm())
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .bitcastToAPInt().getHiBits(32).getLimitedValue());
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // MO must be an Expr.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(MO.isExpr());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return getExprOpValue(MO.getExpr(),Fixups);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// getMemEncoding - Return binary encoding of memory related operand.
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// If the offset operand requires relocation, record the relocation.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  SmallVectorImpl<MCFixup> &Fixups) const {
4568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  assert(MI.getOperand(OpNo).isReg());
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups) << 16;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return (OffBits & 0xFFFF) | RegBits;
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned MipsMCCodeEmitter::
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      SmallVectorImpl<MCFixup> &Fixups) const {
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(MI.getOperand(OpNo).isReg());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) << 16;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (OffBits & 0x0FFF) | RegBits;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      SmallVectorImpl<MCFixup> &Fixups) const {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(MI.getOperand(OpNo).isImm());
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return SizeEncoding - 1;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// FIXME: should be called getMSBEncoding
4848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//
4858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)unsigned
4868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      SmallVectorImpl<MCFixup> &Fixups) const {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(MI.getOperand(OpNo-1).isImm());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(MI.getOperand(OpNo).isImm());
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Position + Size - 1;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "MipsGenMCCodeEmitter.inc"
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)