MipsMCCodeEmitter.cpp revision d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739
14520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka//===-- 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"
1647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MCTargetDesc/MipsFixupKinds.h"
1747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MCTargetDesc/MipsMCTargetDesc.h"
1847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "llvm/ADT/APFloat.h"
1947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "llvm/ADT/Statistic.h"
204520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCCodeEmitter.h"
214520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCExpr.h"
224520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCInst.h"
234520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCInstrInfo.h"
244520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCRegisterInfo.h"
254520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/MC/MCSubtargetInfo.h"
264520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka#include "llvm/Support/raw_ostream.h"
274520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
284520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanakausing namespace llvm;
294520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
304520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanakanamespace {
314520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanakaclass MipsMCCodeEmitter : public MCCodeEmitter {
324520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  MipsMCCodeEmitter(const MipsMCCodeEmitter &); // DO NOT IMPLEMENT
334520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  void operator=(const MipsMCCodeEmitter &); // DO NOT IMPLEMENT
344520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  const MCInstrInfo &MCII;
354520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  const MCSubtargetInfo &STI;
3647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  MCContext &Ctx;
374520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
384520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanakapublic:
394520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  MipsMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
4047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                    MCContext &ctx) : MCII(mcii), STI(sti) , Ctx(ctx) {}
414520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
424520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  ~MipsMCCodeEmitter() {}
434520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
4447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  void EmitByte(unsigned char C, raw_ostream &OS) const {
4547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    OS << (char)C;
4647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  }
4747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
4847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  void EmitInstruction(uint64_t Val, unsigned Size, raw_ostream &OS) const {
4947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // Output the instruction encoding in little endian byte order.
5047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    for (unsigned i = 0; i != Size; ++i) {
5147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      EmitByte(Val & 255, OS);
5247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      Val >>= 8;
5347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    }
544520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  }
5547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
5647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
5747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                         SmallVectorImpl<MCFixup> &Fixups) const;
5847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
5947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // getBinaryCodeForInstr - TableGen'erated function for getting the
6047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // binary encoding for an instruction.
6147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getBinaryCodeForInstr(const MCInst &MI,
6247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                 SmallVectorImpl<MCFixup> &Fixups) const;
6347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
6447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // getBranchJumpOpValue - Return binary encoding of the jump
6547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // target operand. If the machine operand requires relocation,
6647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // record the relocation and return zero.
6747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
6847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                 SmallVectorImpl<MCFixup> &Fixups) const;
6947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
7047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // getBranchTargetOpValue - Return binary encoding of the branch
7147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // target operand. If the machine operand requires relocation,
7247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // record the relocation and return zero.
7347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
7447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                  SmallVectorImpl<MCFixup> &Fixups) const;
7547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
7647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // getMachineOpValue - Return binary encoding of operand. If the machin
7747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes   // operand requires relocation, record the relocation and return zero.
7847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
7947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                             SmallVectorImpl<MCFixup> &Fixups) const;
8047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
8147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getMemEncoding(const MCInst &MI, unsigned OpNo,
8247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                          SmallVectorImpl<MCFixup> &Fixups) const;
8347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
8447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                              SmallVectorImpl<MCFixup> &Fixups) const;
8547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
8647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                              SmallVectorImpl<MCFixup> &Fixups) const;
8747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
884520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka}; // class MipsMCCodeEmitter
894520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka}  // namespace
904520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka
914520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira HatanakaMCCodeEmitter *llvm::createMipsMCCodeEmitter(const MCInstrInfo &MCII,
924520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka                                             const MCSubtargetInfo &STI,
9347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                             MCContext &Ctx)
9447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes{
954520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka  return new MipsMCCodeEmitter(MCII, STI, Ctx);
964520a10fdbaabf1c0cd98b43a61469c5f0e76f38Akira Hatanaka}
9747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
9847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// EncodeInstruction - Emit the instruction.
9947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// Size the instruction (currently only 4 bytes
10047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesvoid MipsMCCodeEmitter::
10147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesEncodeInstruction(const MCInst &MI, raw_ostream &OS,
10247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                  SmallVectorImpl<MCFixup> &Fixups) const
10347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes{
10447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
10547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
10647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // Check for unimplemented opcodes.
10747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // Unfortunately in MIPS both NOT and SLL will come in with Binary == 0
10847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // so we have to special check for them.
10947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned Opcode = MI.getOpcode();
11047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
11147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    llvm_unreachable("unimplemented opcode in EncodeInstruction()");
11247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
11347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
11447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  uint64_t TSFlags = Desc.TSFlags;
11547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
11647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // Pseudo instructions don't get encoded and shouldn't be here
11747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // in the first place!
11847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  if ((TSFlags & MipsII::FormMask) == MipsII::Pseudo)
11947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    llvm_unreachable("Pseudo opcode found in EncodeInstruction()");
12047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
12147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // For now all instructions are 4 bytes
12247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  int Size = 4; // FIXME: Have Desc.getSize() return the correct value!
12347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
12447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  EmitInstruction(Binary, Size, OS);
12547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
12647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
12747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// getBranchTargetOpValue - Return binary encoding of the branch
12847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// target operand. If the machine operand requires relocation,
12947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// record the relocation and return zero.
13047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned MipsMCCodeEmitter::
13147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesgetBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
13247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                       SmallVectorImpl<MCFixup> &Fixups) const {
13347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
13447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  const MCOperand &MO = MI.getOperand(OpNo);
13547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  assert(MO.isExpr() && "getBranchTargetOpValue expects only expressions");
13647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
13747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  const MCExpr *Expr = MO.getExpr();
13847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  Fixups.push_back(MCFixup::Create(0, Expr,
13947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                   MCFixupKind(Mips::fixup_Mips_PC16)));
14047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  return 0;
14147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
14247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
14347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// getJumpTargetOpValue - Return binary encoding of the jump
14447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// target operand. If the machine operand requires relocation,
14547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// record the relocation and return zero.
14647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned MipsMCCodeEmitter::
14747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesgetJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
14847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                     SmallVectorImpl<MCFixup> &Fixups) const {
14947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
15047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  const MCOperand &MO = MI.getOperand(OpNo);
15147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  assert(MO.isExpr() && "getJumpTargetOpValue expects only expressions");
15247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
15347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  const MCExpr *Expr = MO.getExpr();
15447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  Fixups.push_back(MCFixup::Create(0, Expr,
15547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                   MCFixupKind(Mips::fixup_Mips_26)));
15647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  return 0;
15747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
15847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
15947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// getMachineOpValue - Return binary encoding of operand. If the machine
16047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// operand requires relocation, record the relocation and return zero.
16147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned MipsMCCodeEmitter::
16247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesgetMachineOpValue(const MCInst &MI, const MCOperand &MO,
16347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                  SmallVectorImpl<MCFixup> &Fixups) const {
16447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  if (MO.isReg()) {
16547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    unsigned Reg = MO.getReg();
16647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    unsigned RegNo = getMipsRegisterNumbering(Reg);
16747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    return RegNo;
16847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  } else if (MO.isImm()) {
16947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    return static_cast<unsigned>(MO.getImm());
17047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  } else if (MO.isFPImm()) {
17147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    return static_cast<unsigned>(APFloat(MO.getFPImm())
17247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        .bitcastToAPInt().getHiBits(32).getLimitedValue());
17347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  } else if (MO.isExpr()) {
17447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    const MCExpr *Expr = MO.getExpr();
17547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    MCExpr::ExprKind Kind = Expr->getKind();
176421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka    unsigned Ret = 0;
177421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka
178421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka    if (Kind == MCExpr::Binary) {
179421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka      const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Expr);
180421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka      Expr = BE->getLHS();
181421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka      Kind = Expr->getKind();
182421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(BE->getRHS());
183421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka      assert((Kind == MCExpr::SymbolRef) && CE &&
184421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka             "Binary expression must be sym+const.");
185421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka      Ret = CE->getValue();
186421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka    }
187421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka
18847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    if (Kind == MCExpr::SymbolRef) {
189421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka      Mips::Fixups FixupKind;
190421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka      switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
19147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_GPREL:
19247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_GPREL16;
19347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        break;
19447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_GOT_CALL:
19547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_CALL16;
19647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        break;
197e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_GOT16:
198e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_GOT_Global;
199e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes        break;
20047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_GOT:
201e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_GOT_Local;
20247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        break;
20347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_ABS_HI:
20447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_HI16;
20547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        break;
20647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_ABS_LO:
20747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_LO16;
20847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        break;
20947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_TLSGD:
21047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_TLSGD;
21147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        break;
21247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_GOTTPREL:
21347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_GOTTPREL;
21447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        break;
21547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_TPREL_HI:
21647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_TPREL_HI;
21747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        break;
21847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      case MCSymbolRefExpr::VK_Mips_TPREL_LO:
21947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        FixupKind = Mips::fixup_Mips_TPREL_LO;
22047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes        break;
22147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      default:
222421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka        return Ret;
22347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      } // switch
22447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes      Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
22547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    } // if SymbolRef
22647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes    // All of the information is in the fixup.
227421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka    return Ret;
22847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  }
22947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  llvm_unreachable("Unable to encode MCOperand!");
23047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // Not reached
23147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  return 0;
23247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
23347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
23447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// getMemEncoding - Return binary encoding of memory related operand.
23547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes/// If the offset operand requires relocation, record the relocation.
23647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned
23747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesMipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
23847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                  SmallVectorImpl<MCFixup> &Fixups) const {
23947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
24047b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  assert(MI.getOperand(OpNo).isReg());
24147b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups) << 16;
24247b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
24347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
24447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes  return (OffBits & 0xFFFF) | RegBits;
24547b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
24647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
24747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned
24847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesMipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
24947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                      SmallVectorImpl<MCFixup> &Fixups) const {
250421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka  assert(MI.getOperand(OpNo).isImm());
251d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
252d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  return SizeEncoding - 1;
25347b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
25447b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
255421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka// FIXME: should be called getMSBEncoding
256421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka//
25747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopesunsigned
25847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso LopesMipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
25947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes                                      SmallVectorImpl<MCFixup> &Fixups) const {
260421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka  assert(MI.getOperand(OpNo-1).isImm());
261421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka  assert(MI.getOperand(OpNo).isImm());
262d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups);
263d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
264421455f1ea081e2e1767e782ac0d57ca55976e9bAkira Hatanaka
265d1bcf0dbc18f39e51fd3b5bf3b90d737f9965739Bruno Cardoso Lopes  return Position + Size - 1;
26647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes}
26747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
26847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MipsGenMCCodeEmitter.inc"
26947b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes
270