1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
24520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//
34520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//                     The LLVM Compiler Infrastructure
44520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//
54520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka// This file is distributed under the University of Illinois Open Source
64520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka// License. See LICENSE.TXT for details.
74520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//
84520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//===----------------------------------------------------------------------===//
94520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//
104520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka// This file implements the MipsMCCodeEmitter class.
114520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//
124520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//===----------------------------------------------------------------------===//
134520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//
144520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#define DEBUG_TYPE "mccodeemitter"
1547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MCTargetDesc/MipsBaseInfo.h"
168e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter#include "MCTargetDesc/MipsDirectObjLower.h"
1747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MCTargetDesc/MipsFixupKinds.h"
1847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MCTargetDesc/MipsMCTargetDesc.h"
1947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "llvm/ADT/APFloat.h"
2047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "llvm/ADT/Statistic.h"
214520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCCodeEmitter.h"
22e8068692f924a1577075bd2d7b72b44820e0ffb2Akira Hatanaka#include "llvm/MC/MCContext.h"
234520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCExpr.h"
244520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCInst.h"
254520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCInstrInfo.h"
264520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCRegisterInfo.h"
274520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCSubtargetInfo.h"
284520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/Support/raw_ostream.h"
294520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
304520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanakausing namespace llvm;
314520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
324520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanakanamespace {
334520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanakaclass MipsMCCodeEmitter : public MCCodeEmitter {
34dd100d831bb8062b64e7037d2bbc21bf20be4f45Craig Topper  MipsMCCodeEmitter(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
35dd100d831bb8062b64e7037d2bbc21bf20be4f45Craig Topper  void operator=(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
364520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  const MCInstrInfo &MCII;
37e8068692f924a1577075bd2d7b72b44820e0ffb2Akira Hatanaka  MCContext &Ctx;
38e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka  bool IsLittleEndian;
394520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
404520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanakapublic:
41ccb3c9c2702f548fd0a7d60a622e6f4fdf0940e7Jack Carter  MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_,
42ccb3c9c2702f548fd0a7d60a622e6f4fdf0940e7Jack Carter                    const MCSubtargetInfo &sti, bool IsLittle) :
435f645953555cee528cd1c0d6faa16d9b89ebba48David Blaikie    MCII(mcii), Ctx(Ctx_), IsLittleEndian(IsLittle) {}
444520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
454520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  ~MipsMCCodeEmitter() {}
464520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
4747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  void EmitByte(unsigned char C, raw_ostream &OS) const {
4847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    OS << (char)C;
4947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  }
5047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
5147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  void EmitInstruction(uint64_t Val, unsigned Size, raw_ostream &OS) const {
5247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // Output the instruction encoding in little endian byte order.
53fb54afbcb8f460c5c4cafa605259ba0dd77504dcAkira Hatanaka    for (unsigned i = 0; i < Size; ++i) {
54fb54afbcb8f460c5c4cafa605259ba0dd77504dcAkira Hatanaka      unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
55fb54afbcb8f460c5c4cafa605259ba0dd77504dcAkira Hatanaka      EmitByte((Val >> Shift) & 0xff, OS);
5647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    }
574520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  }
5847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
5947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
6047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                         SmallVectorImpl<MCFixup> &Fixups) const;
6147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
6247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // getBinaryCodeForInstr - TableGen'erated function for getting the
6347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // binary encoding for an instruction.
644f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson  uint64_t getBinaryCodeForInstr(const MCInst &MI,
6547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                 SmallVectorImpl<MCFixup> &Fixups) const;
6647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
6747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // getBranchJumpOpValue - Return binary encoding of the jump
6847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // target operand. If the machine operand requires relocation,
6947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // record the relocation and return zero.
7047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
7147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                 SmallVectorImpl<MCFixup> &Fixups) const;
7247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
7347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // getBranchTargetOpValue - Return binary encoding of the branch
7447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // target operand. If the machine operand requires relocation,
7547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // record the relocation and return zero.
7647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
7747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                  SmallVectorImpl<MCFixup> &Fixups) const;
7847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
7947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // getMachineOpValue - Return binary encoding of operand. If the machin
8047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // operand requires relocation, record the relocation and return zero.
8147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
8247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                             SmallVectorImpl<MCFixup> &Fixups) const;
8347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
8447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getMemEncoding(const MCInst &MI, unsigned OpNo,
8547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                          SmallVectorImpl<MCFixup> &Fixups) const;
8647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
8747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                              SmallVectorImpl<MCFixup> &Fixups) const;
8847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
8947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                              SmallVectorImpl<MCFixup> &Fixups) const;
9047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
914520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka}; // class MipsMCCodeEmitter
924520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka}  // namespace
934520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
94e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira HatanakaMCCodeEmitter *llvm::createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
95918f55fe239f00651e396be841f2b3b6e242f98dJim Grosbach                                               const MCRegisterInfo &MRI,
96e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka                                               const MCSubtargetInfo &STI,
97e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka                                               MCContext &Ctx)
9847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes{
99ccb3c9c2702f548fd0a7d60a622e6f4fdf0940e7Jack Carter  return new MipsMCCodeEmitter(MCII, Ctx, STI, false);
100e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka}
101e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka
102e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira HatanakaMCCodeEmitter *llvm::createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
103918f55fe239f00651e396be841f2b3b6e242f98dJim Grosbach                                               const MCRegisterInfo &MRI,
104e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka                                               const MCSubtargetInfo &STI,
105e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka                                               MCContext &Ctx)
106e9e520f23ec3e5dc26e0801ac0d8b9e6899e2626Akira Hatanaka{
107ccb3c9c2702f548fd0a7d60a622e6f4fdf0940e7Jack Carter  return new MipsMCCodeEmitter(MCII, Ctx, STI, true);
1084520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka}
10947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
11047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// EncodeInstruction - Emit the instruction.
11147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// Size the instruction (currently only 4 bytes
11247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesvoid MipsMCCodeEmitter::
11347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesEncodeInstruction(const MCInst &MI, raw_ostream &OS,
11447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                  SmallVectorImpl<MCFixup> &Fixups) const
11547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes{
1168e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter
1178e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  // Non-pseudo instructions that get changed for direct object
1188e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  // only based on operand values.
1198e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  // If this list of instructions get much longer we will move
1208e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  // the check to a function call. Until then, this is more efficient.
1218e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  MCInst TmpInst = MI;
1228e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  switch (MI.getOpcode()) {
1238e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  // If shift amount is >= 32 it the inst needs to be lowered further
1248e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  case Mips::DSLL:
1258e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  case Mips::DSRL:
1268e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  case Mips::DSRA:
1278e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter    Mips::LowerLargeShift(TmpInst);
1288e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter    break;
1298e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter    // Double extract instruction is chosen by pos and size operands
1308e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  case Mips::DEXT:
1318e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  case Mips::DINS:
1328e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter    Mips::LowerDextDins(TmpInst);
1338e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  }
1348e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter
1358e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups);
13647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
13747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // Check for unimplemented opcodes.
1388e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
13947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // so we have to special check for them.
1408e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  unsigned Opcode = TmpInst.getOpcode();
14147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
14247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    llvm_unreachable("unimplemented opcode in EncodeInstruction()");
14347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
1448e71e617c9b1e42737ffd00984a5025ec90c734cJack Carter  const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
14547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
14642faefc11da326f10a4a52d72953318921d9e43dJack Carter  // Get byte count of instruction
14742faefc11da326f10a4a52d72953318921d9e43dJack Carter  unsigned Size = Desc.getSize();
14842faefc11da326f10a4a52d72953318921d9e43dJack Carter  if (!Size)
14942faefc11da326f10a4a52d72953318921d9e43dJack Carter    llvm_unreachable("Desc.getSize() returns 0");
15047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
15147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  EmitInstruction(Binary, Size, OS);
15247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
15347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
15447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// getBranchTargetOpValue - Return binary encoding of the branch
15547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// target operand. If the machine operand requires relocation,
15647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// record the relocation and return zero.
15747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned MipsMCCodeEmitter::
15847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesgetBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
15947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                       SmallVectorImpl<MCFixup> &Fixups) const {
16047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
16147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  const MCOperand &MO = MI.getOperand(OpNo);
162ad51a4a5984a365d671ddfe9eaa23d2e12ee4281Jack Carter
163ad51a4a5984a365d671ddfe9eaa23d2e12ee4281Jack Carter  // If the destination is an immediate, we have nothing to do.
164ad51a4a5984a365d671ddfe9eaa23d2e12ee4281Jack Carter  if (MO.isImm()) return MO.getImm();
165ad51a4a5984a365d671ddfe9eaa23d2e12ee4281Jack Carter  assert(MO.isExpr() &&
166ad51a4a5984a365d671ddfe9eaa23d2e12ee4281Jack Carter         "getBranchTargetOpValue expects only expressions or immediates");
16747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
16847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  const MCExpr *Expr = MO.getExpr();
16947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  Fixups.push_back(MCFixup::Create(0, Expr,
17047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                   MCFixupKind(Mips::fixup_Mips_PC16)));
17147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  return 0;
17247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
17347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
17447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// getJumpTargetOpValue - Return binary encoding of the jump
17547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// target operand. If the machine operand requires relocation,
17647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// record the relocation and return zero.
17747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned MipsMCCodeEmitter::
17847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesgetJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
17947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                     SmallVectorImpl<MCFixup> &Fixups) const {
18047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
18147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  const MCOperand &MO = MI.getOperand(OpNo);
182ad51a4a5984a365d671ddfe9eaa23d2e12ee4281Jack Carter  // If the destination is an immediate, we have nothing to do.
183ad51a4a5984a365d671ddfe9eaa23d2e12ee4281Jack Carter  if (MO.isImm()) return MO.getImm();
184ad51a4a5984a365d671ddfe9eaa23d2e12ee4281Jack Carter  assert(MO.isExpr() &&
185ad51a4a5984a365d671ddfe9eaa23d2e12ee4281Jack Carter         "getJumpTargetOpValue expects only expressions or an immediate");
18647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
18747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  const MCExpr *Expr = MO.getExpr();
18847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  Fixups.push_back(MCFixup::Create(0, Expr,
18947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                   MCFixupKind(Mips::fixup_Mips_26)));
19047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  return 0;
19147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
19247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
19347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// getMachineOpValue - Return binary encoding of operand. If the machine
19447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// operand requires relocation, record the relocation and return zero.
19547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned MipsMCCodeEmitter::
19647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesgetMachineOpValue(const MCInst &MI, const MCOperand &MO,
19747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                  SmallVectorImpl<MCFixup> &Fixups) const {
19847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  if (MO.isReg()) {
19947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    unsigned Reg = MO.getReg();
200e8068692f924a1577075bd2d7b72b44820e0ffb2Akira Hatanaka    unsigned RegNo = Ctx.getRegisterInfo().getEncodingValue(Reg);
20147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    return RegNo;
20247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  } else if (MO.isImm()) {
20347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    return static_cast<unsigned>(MO.getImm());
20447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  } else if (MO.isFPImm()) {
20547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    return static_cast<unsigned>(APFloat(MO.getFPImm())
20647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        .bitcastToAPInt().getHiBits(32).getLimitedValue());
207864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka  }
20859182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka
20959182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  // MO must be an Expr.
21059182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  assert(MO.isExpr());
21159182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka
21259182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  const MCExpr *Expr = MO.getExpr();
21359182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  MCExpr::ExprKind Kind = Expr->getKind();
214421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka
21559182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  if (Kind == MCExpr::Binary) {
21659182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    Expr = static_cast<const MCBinaryExpr*>(Expr)->getLHS();
21759182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    Kind = Expr->getKind();
21847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  }
21959182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka
22059182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  assert (Kind == MCExpr::SymbolRef);
221864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka
222eb23f9e92e607990ffe986735e10a8dec713909aBill Wendling  Mips::Fixups FixupKind = Mips::Fixups(0);
22359182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka
22459182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
2250140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  default: llvm_unreachable("Unknown fixup kind!");
2260140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    break;
2270140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
2280140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    FixupKind = Mips::fixup_Mips_GPOFF_HI;
2290140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    break;
2300140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
2310140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    FixupKind = Mips::fixup_Mips_GPOFF_LO;
2320140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    break;
2330140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
2340140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    FixupKind = Mips::fixup_Mips_GOT_PAGE;
2350140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    break;
2360140e55393c4403ab240c386501cdc5e438dcc0eJack Carter  case MCSymbolRefExpr::VK_Mips_GOT_OFST :
2370140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    FixupKind = Mips::fixup_Mips_GOT_OFST;
2380140e55393c4403ab240c386501cdc5e438dcc0eJack Carter    break;
239fd506efec628819f7e6fad8016a9dbb5d8612b8bJack Carter  case MCSymbolRefExpr::VK_Mips_GOT_DISP :
240fd506efec628819f7e6fad8016a9dbb5d8612b8bJack Carter    FixupKind = Mips::fixup_Mips_GOT_DISP;
241fd506efec628819f7e6fad8016a9dbb5d8612b8bJack Carter    break;
24259182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_GPREL:
24359182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_GPREL16;
24459182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
24559182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_GOT_CALL:
24659182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_CALL16;
24759182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
24859182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_GOT16:
24959182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_GOT_Global;
25059182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
25159182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_GOT:
25259182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_GOT_Local;
25359182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
25459182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_ABS_HI:
25559182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_HI16;
25659182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
25759182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_ABS_LO:
25859182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_LO16;
25959182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
26059182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_TLSGD:
26159182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_TLSGD;
26259182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
26359182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_TLSLDM:
26459182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_TLSLDM;
26559182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
26659182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
26759182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_DTPREL_HI;
26859182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
26959182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
27059182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_DTPREL_LO;
27159182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
27259182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_GOTTPREL:
27359182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_GOTTPREL;
27459182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
27559182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_TPREL_HI:
27659182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_TPREL_HI;
27759182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
27859182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  case MCSymbolRefExpr::VK_Mips_TPREL_LO:
27959182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    FixupKind = Mips::fixup_Mips_TPREL_LO;
28059182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka    break;
281fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter  case MCSymbolRefExpr::VK_Mips_HIGHER:
282fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    FixupKind = Mips::fixup_Mips_HIGHER;
283fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    break;
284fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter  case MCSymbolRefExpr::VK_Mips_HIGHEST:
285fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    FixupKind = Mips::fixup_Mips_HIGHEST;
286fc54d9e47a1276650f14f38e7d037c9b58c8dc2dJack Carter    break;
287198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case MCSymbolRefExpr::VK_Mips_GOT_HI16:
288198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    FixupKind = Mips::fixup_Mips_GOT_HI16;
289198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    break;
290198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case MCSymbolRefExpr::VK_Mips_GOT_LO16:
291198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    FixupKind = Mips::fixup_Mips_GOT_LO16;
292198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    break;
293198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case MCSymbolRefExpr::VK_Mips_CALL_HI16:
294198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    FixupKind = Mips::fixup_Mips_CALL_HI16;
295198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    break;
296198ad916d736047f8a439f19dee25cee917df8a9Jack Carter  case MCSymbolRefExpr::VK_Mips_CALL_LO16:
297198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    FixupKind = Mips::fixup_Mips_CALL_LO16;
298198ad916d736047f8a439f19dee25cee917df8a9Jack Carter    break;
29959182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  } // switch
30059182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka
30159182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  Fixups.push_back(MCFixup::Create(0, MO.getExpr(), MCFixupKind(FixupKind)));
30259182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka
30359182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  // All of the information is in the fixup.
30459182f9425dba2d5e0035155bd2b0a04c6ababb3Akira Hatanaka  return 0;
30547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
30647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
30747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// getMemEncoding - Return binary encoding of memory related operand.
30847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// If the offset operand requires relocation, record the relocation.
30947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned
31047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesMipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
31147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                  SmallVectorImpl<MCFixup> &Fixups) const {
31247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
31347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  assert(MI.getOperand(OpNo).isReg());
31447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups) << 16;
31547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
31647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
31747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  return (OffBits & 0xFFFF) | RegBits;
31847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
31947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
32047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned
32147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesMipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
32247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                      SmallVectorImpl<MCFixup> &Fixups) const {
323421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka  assert(MI.getOperand(OpNo).isImm());
324d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
325d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  return SizeEncoding - 1;
32647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
32747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
328421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka// FIXME: should be called getMSBEncoding
329421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka//
33047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned
33147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesMipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
33247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                      SmallVectorImpl<MCFixup> &Fixups) const {
333421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka  assert(MI.getOperand(OpNo-1).isImm());
334421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka  assert(MI.getOperand(OpNo).isImm());
335d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups);
336d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
337421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka
338d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  return Position + Size - 1;
33947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
34047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
34147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MipsGenMCCodeEmitter.inc"
34247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
343