MipsMCCodeEmitter.cpp revision 5c042162beb3c2dd556e00aab84c4278a69cd5b1
1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//
3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//                     The LLVM Compiler Infrastructure
4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//
5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// This file is distributed under the University of Illinois Open Source
6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// License. See LICENSE.TXT for details.
7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//
8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//===----------------------------------------------------------------------===//
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// This file implements the MipsMCCodeEmitter class.
11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//
12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//===----------------------------------------------------------------------===//
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#define DEBUG_TYPE "mccodeemitter"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "MCTargetDesc/MipsBaseInfo.h"
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "MCTargetDesc/MipsFixupKinds.h"
17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "MCTargetDesc/MipsMCTargetDesc.h"
18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/ADT/APFloat.h"
19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/ADT/Statistic.h"
20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCCodeEmitter.h"
21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCContext.h"
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCExpr.h"
23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCInst.h"
24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCInstrInfo.h"
25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCRegisterInfo.h"
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "llvm/MC/MCSubtargetInfo.h"
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "llvm/Support/raw_ostream.h"
28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define GET_INSTRMAP_INFO
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "MipsGenInstrInfo.inc"
31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing namespace llvm;
33ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace {
35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass MipsMCCodeEmitter : public MCCodeEmitter {
36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MipsMCCodeEmitter(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void operator=(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const MCInstrInfo &MCII;
39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MCContext &Ctx;
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const MCSubtargetInfo &STI;
41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool IsLittleEndian;
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool IsMicroMips;
43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)public:
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_,
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    const MCSubtargetInfo &sti, bool IsLittle) :
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MCII(mcii), Ctx(Ctx_), STI (sti), IsLittleEndian(IsLittle) {
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ~MipsMCCodeEmitter() {}
52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void EmitByte(unsigned char C, raw_ostream &OS) const {
54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    OS << (char)C;
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void EmitInstruction(uint64_t Val, unsigned Size, raw_ostream &OS) const {
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Output the instruction encoding in little endian byte order.
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Little-endian byte ordering:
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    //   mips32r2:   4 | 3 | 2 | 1
61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    //   microMIPS:  2 | 1 | 4 | 3
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (IsLittleEndian && Size == 4 && IsMicroMips) {
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      EmitInstruction(Val>>16, 2, OS);
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      EmitInstruction(Val, 2, OS);
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    } else {
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      for (unsigned i = 0; i < Size; ++i) {
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        EmitByte((Val >> Shift) & 0xff, OS);
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         SmallVectorImpl<MCFixup> &Fixups) const;
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // getBinaryCodeForInstr - TableGen'erated function for getting the
77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // binary encoding for an instruction.
78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  uint64_t getBinaryCodeForInstr(const MCInst &MI,
79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 SmallVectorImpl<MCFixup> &Fixups) const;
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
81  // getBranchJumpOpValue - Return binary encoding of the jump
82  // target operand. If the machine operand requires relocation,
83  // record the relocation and return zero.
84   unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
85                                 SmallVectorImpl<MCFixup> &Fixups) const;
86
87  // getBranchJumpOpValueMM - Return binary encoding of the microMIPS jump
88  // target operand. If the machine operand requires relocation,
89  // record the relocation and return zero.
90  unsigned getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
91                                  SmallVectorImpl<MCFixup> &Fixups) const;
92
93   // getBranchTargetOpValue - Return binary encoding of the branch
94   // target operand. If the machine operand requires relocation,
95   // record the relocation and return zero.
96  unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
97                                  SmallVectorImpl<MCFixup> &Fixups) const;
98
99  // getBranchTargetOpValue - Return binary encoding of the microMIPS branch
100  // target operand. If the machine operand requires relocation,
101  // record the relocation and return zero.
102  unsigned getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
103                                    SmallVectorImpl<MCFixup> &Fixups) const;
104
105   // getMachineOpValue - Return binary encoding of operand. If the machin
106   // operand requires relocation, record the relocation and return zero.
107  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
108                             SmallVectorImpl<MCFixup> &Fixups) const;
109
110  unsigned getMemEncoding(const MCInst &MI, unsigned OpNo,
111                          SmallVectorImpl<MCFixup> &Fixups) const;
112  unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
113                                 SmallVectorImpl<MCFixup> &Fixups) const;
114  unsigned getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
115                              SmallVectorImpl<MCFixup> &Fixups) const;
116  unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
117                              SmallVectorImpl<MCFixup> &Fixups) const;
118
119  unsigned
120  getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const;
121
122}; // class MipsMCCodeEmitter
123}  // namespace
124
125MCCodeEmitter *llvm::createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
126                                               const MCRegisterInfo &MRI,
127                                               const MCSubtargetInfo &STI,
128                                               MCContext &Ctx)
129{
130  return new MipsMCCodeEmitter(MCII, Ctx, STI, false);
131}
132
133MCCodeEmitter *llvm::createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
134                                               const MCRegisterInfo &MRI,
135                                               const MCSubtargetInfo &STI,
136                                               MCContext &Ctx)
137{
138  return new MipsMCCodeEmitter(MCII, Ctx, STI, true);
139}
140
141
142// If the D<shift> instruction has a shift amount that is greater
143// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
144static void LowerLargeShift(MCInst& Inst) {
145
146  assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
147  assert(Inst.getOperand(2).isImm());
148
149  int64_t Shift = Inst.getOperand(2).getImm();
150  if (Shift <= 31)
151    return; // Do nothing
152  Shift -= 32;
153
154  // saminus32
155  Inst.getOperand(2).setImm(Shift);
156
157  switch (Inst.getOpcode()) {
158  default:
159    // Calling function is not synchronized
160    llvm_unreachable("Unexpected shift instruction");
161  case Mips::DSLL:
162    Inst.setOpcode(Mips::DSLL32);
163    return;
164  case Mips::DSRL:
165    Inst.setOpcode(Mips::DSRL32);
166    return;
167  case Mips::DSRA:
168    Inst.setOpcode(Mips::DSRA32);
169    return;
170  case Mips::DROTR:
171    Inst.setOpcode(Mips::DROTR32);
172    return;
173  }
174}
175
176// Pick a DEXT or DINS instruction variant based on the pos and size operands
177static void LowerDextDins(MCInst& InstIn) {
178  int Opcode = InstIn.getOpcode();
179
180  if (Opcode == Mips::DEXT)
181    assert(InstIn.getNumOperands() == 4 &&
182           "Invalid no. of machine operands for DEXT!");
183  else // Only DEXT and DINS are possible
184    assert(InstIn.getNumOperands() == 5 &&
185           "Invalid no. of machine operands for DINS!");
186
187  assert(InstIn.getOperand(2).isImm());
188  int64_t pos = InstIn.getOperand(2).getImm();
189  assert(InstIn.getOperand(3).isImm());
190  int64_t size = InstIn.getOperand(3).getImm();
191
192  if (size <= 32) {
193    if (pos < 32)  // DEXT/DINS, do nothing
194      return;
195    // DEXTU/DINSU
196    InstIn.getOperand(2).setImm(pos - 32);
197    InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
198    return;
199  }
200  // DEXTM/DINSM
201  assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
202  InstIn.getOperand(3).setImm(size - 32);
203  InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
204  return;
205}
206
207/// EncodeInstruction - Emit the instruction.
208/// Size the instruction with Desc.getSize().
209void MipsMCCodeEmitter::
210EncodeInstruction(const MCInst &MI, raw_ostream &OS,
211                  SmallVectorImpl<MCFixup> &Fixups) const
212{
213
214  // Non-pseudo instructions that get changed for direct object
215  // only based on operand values.
216  // If this list of instructions get much longer we will move
217  // the check to a function call. Until then, this is more efficient.
218  MCInst TmpInst = MI;
219  switch (MI.getOpcode()) {
220  // If shift amount is >= 32 it the inst needs to be lowered further
221  case Mips::DSLL:
222  case Mips::DSRL:
223  case Mips::DSRA:
224  case Mips::DROTR:
225    LowerLargeShift(TmpInst);
226    break;
227    // Double extract instruction is chosen by pos and size operands
228  case Mips::DEXT:
229  case Mips::DINS:
230    LowerDextDins(TmpInst);
231  }
232
233  unsigned long N = Fixups.size();
234  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups);
235
236  // Check for unimplemented opcodes.
237  // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
238  // so we have to special check for them.
239  unsigned Opcode = TmpInst.getOpcode();
240  if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
241    llvm_unreachable("unimplemented opcode in EncodeInstruction()");
242
243  if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
244    int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips);
245    if (NewOpcode != -1) {
246      if (Fixups.size() > N)
247        Fixups.pop_back();
248      Opcode = NewOpcode;
249      TmpInst.setOpcode (NewOpcode);
250      Binary = getBinaryCodeForInstr(TmpInst, Fixups);
251    }
252  }
253
254  const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
255
256  // Get byte count of instruction
257  unsigned Size = Desc.getSize();
258  if (!Size)
259    llvm_unreachable("Desc.getSize() returns 0");
260
261  EmitInstruction(Binary, Size, OS);
262}
263
264/// getBranchTargetOpValue - Return binary encoding of the branch
265/// target operand. If the machine operand requires relocation,
266/// record the relocation and return zero.
267unsigned MipsMCCodeEmitter::
268getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
269                       SmallVectorImpl<MCFixup> &Fixups) const {
270
271  const MCOperand &MO = MI.getOperand(OpNo);
272
273  // If the destination is an immediate, divide by 4.
274  if (MO.isImm()) return MO.getImm() >> 2;
275
276  assert(MO.isExpr() &&
277         "getBranchTargetOpValue expects only expressions or immediates");
278
279  const MCExpr *Expr = MO.getExpr();
280  Fixups.push_back(MCFixup::Create(0, Expr,
281                                   MCFixupKind(Mips::fixup_Mips_PC16)));
282  return 0;
283}
284
285/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
286/// target operand. If the machine operand requires relocation,
287/// record the relocation and return zero.
288unsigned MipsMCCodeEmitter::
289getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
290                         SmallVectorImpl<MCFixup> &Fixups) const {
291
292  const MCOperand &MO = MI.getOperand(OpNo);
293
294  // If the destination is an immediate, divide by 2.
295  if (MO.isImm()) return MO.getImm() >> 1;
296
297  assert(MO.isExpr() &&
298         "getBranchTargetOpValueMM expects only expressions or immediates");
299
300  const MCExpr *Expr = MO.getExpr();
301  Fixups.push_back(MCFixup::Create(0, Expr,
302                   MCFixupKind(Mips::
303                               fixup_MICROMIPS_PC16_S1)));
304  return 0;
305}
306
307/// getJumpTargetOpValue - Return binary encoding of the jump
308/// target operand. If the machine operand requires relocation,
309/// record the relocation and return zero.
310unsigned MipsMCCodeEmitter::
311getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
312                     SmallVectorImpl<MCFixup> &Fixups) const {
313
314  const MCOperand &MO = MI.getOperand(OpNo);
315  // If the destination is an immediate, divide by 4.
316  if (MO.isImm()) return MO.getImm()>>2;
317
318  assert(MO.isExpr() &&
319         "getJumpTargetOpValue expects only expressions or an immediate");
320
321  const MCExpr *Expr = MO.getExpr();
322  Fixups.push_back(MCFixup::Create(0, Expr,
323                                   MCFixupKind(Mips::fixup_Mips_26)));
324  return 0;
325}
326
327unsigned MipsMCCodeEmitter::
328getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
329                       SmallVectorImpl<MCFixup> &Fixups) const {
330
331  const MCOperand &MO = MI.getOperand(OpNo);
332  // If the destination is an immediate, divide by 2.
333  if (MO.isImm()) return MO.getImm() >> 1;
334
335  assert(MO.isExpr() &&
336         "getJumpTargetOpValueMM expects only expressions or an immediate");
337
338  const MCExpr *Expr = MO.getExpr();
339  Fixups.push_back(MCFixup::Create(0, Expr,
340                                   MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
341  return 0;
342}
343
344unsigned MipsMCCodeEmitter::
345getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const {
346  int64_t Res;
347
348  if (Expr->EvaluateAsAbsolute(Res))
349    return Res;
350
351  MCExpr::ExprKind Kind = Expr->getKind();
352  if (Kind == MCExpr::Constant) {
353    return cast<MCConstantExpr>(Expr)->getValue();
354  }
355
356  if (Kind == MCExpr::Binary) {
357    unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups);
358    Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups);
359    return Res;
360  }
361  if (Kind == MCExpr::SymbolRef) {
362  Mips::Fixups FixupKind = Mips::Fixups(0);
363
364  switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
365  default: llvm_unreachable("Unknown fixup kind!");
366    break;
367  case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
368    FixupKind = Mips::fixup_Mips_GPOFF_HI;
369    break;
370  case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
371    FixupKind = Mips::fixup_Mips_GPOFF_LO;
372    break;
373  case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
374    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_PAGE
375                            : Mips::fixup_Mips_GOT_PAGE;
376    break;
377  case MCSymbolRefExpr::VK_Mips_GOT_OFST :
378    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_OFST
379                            : Mips::fixup_Mips_GOT_OFST;
380    break;
381  case MCSymbolRefExpr::VK_Mips_GOT_DISP :
382    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_DISP
383                            : Mips::fixup_Mips_GOT_DISP;
384    break;
385  case MCSymbolRefExpr::VK_Mips_GPREL:
386    FixupKind = Mips::fixup_Mips_GPREL16;
387    break;
388  case MCSymbolRefExpr::VK_Mips_GOT_CALL:
389    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_CALL16
390                            : Mips::fixup_Mips_CALL16;
391    break;
392  case MCSymbolRefExpr::VK_Mips_GOT16:
393    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16
394                            : Mips::fixup_Mips_GOT_Global;
395    break;
396  case MCSymbolRefExpr::VK_Mips_GOT:
397    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16
398                            : Mips::fixup_Mips_GOT_Local;
399    break;
400  case MCSymbolRefExpr::VK_Mips_ABS_HI:
401    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_HI16
402                            : Mips::fixup_Mips_HI16;
403    break;
404  case MCSymbolRefExpr::VK_Mips_ABS_LO:
405    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_LO16
406                            : Mips::fixup_Mips_LO16;
407    break;
408  case MCSymbolRefExpr::VK_Mips_TLSGD:
409    FixupKind = Mips::fixup_Mips_TLSGD;
410    break;
411  case MCSymbolRefExpr::VK_Mips_TLSLDM:
412    FixupKind = Mips::fixup_Mips_TLSLDM;
413    break;
414  case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
415    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
416                            : Mips::fixup_Mips_DTPREL_HI;
417    break;
418  case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
419    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
420                            : Mips::fixup_Mips_DTPREL_LO;
421    break;
422  case MCSymbolRefExpr::VK_Mips_GOTTPREL:
423    FixupKind = Mips::fixup_Mips_GOTTPREL;
424    break;
425  case MCSymbolRefExpr::VK_Mips_TPREL_HI:
426    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
427                            : Mips::fixup_Mips_TPREL_HI;
428    break;
429  case MCSymbolRefExpr::VK_Mips_TPREL_LO:
430    FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
431                            : Mips::fixup_Mips_TPREL_LO;
432    break;
433  case MCSymbolRefExpr::VK_Mips_HIGHER:
434    FixupKind = Mips::fixup_Mips_HIGHER;
435    break;
436  case MCSymbolRefExpr::VK_Mips_HIGHEST:
437    FixupKind = Mips::fixup_Mips_HIGHEST;
438    break;
439  case MCSymbolRefExpr::VK_Mips_GOT_HI16:
440    FixupKind = Mips::fixup_Mips_GOT_HI16;
441    break;
442  case MCSymbolRefExpr::VK_Mips_GOT_LO16:
443    FixupKind = Mips::fixup_Mips_GOT_LO16;
444    break;
445  case MCSymbolRefExpr::VK_Mips_CALL_HI16:
446    FixupKind = Mips::fixup_Mips_CALL_HI16;
447    break;
448  case MCSymbolRefExpr::VK_Mips_CALL_LO16:
449    FixupKind = Mips::fixup_Mips_CALL_LO16;
450    break;
451  } // switch
452
453    Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
454    return 0;
455  }
456  return 0;
457}
458
459/// getMachineOpValue - Return binary encoding of operand. If the machine
460/// operand requires relocation, record the relocation and return zero.
461unsigned MipsMCCodeEmitter::
462getMachineOpValue(const MCInst &MI, const MCOperand &MO,
463                  SmallVectorImpl<MCFixup> &Fixups) const {
464  if (MO.isReg()) {
465    unsigned Reg = MO.getReg();
466    unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
467    return RegNo;
468  } else if (MO.isImm()) {
469    return static_cast<unsigned>(MO.getImm());
470  } else if (MO.isFPImm()) {
471    return static_cast<unsigned>(APFloat(MO.getFPImm())
472        .bitcastToAPInt().getHiBits(32).getLimitedValue());
473  }
474  // MO must be an Expr.
475  assert(MO.isExpr());
476  return getExprOpValue(MO.getExpr(),Fixups);
477}
478
479/// getMemEncoding - Return binary encoding of memory related operand.
480/// If the offset operand requires relocation, record the relocation.
481unsigned
482MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
483                                  SmallVectorImpl<MCFixup> &Fixups) const {
484  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
485  assert(MI.getOperand(OpNo).isReg());
486  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups) << 16;
487  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
488
489  return (OffBits & 0xFFFF) | RegBits;
490}
491
492unsigned MipsMCCodeEmitter::
493getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
494                      SmallVectorImpl<MCFixup> &Fixups) const {
495  // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
496  assert(MI.getOperand(OpNo).isReg());
497  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) << 16;
498  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
499
500  return (OffBits & 0x0FFF) | RegBits;
501}
502
503unsigned
504MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
505                                      SmallVectorImpl<MCFixup> &Fixups) const {
506  assert(MI.getOperand(OpNo).isImm());
507  unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
508  return SizeEncoding - 1;
509}
510
511// FIXME: should be called getMSBEncoding
512//
513unsigned
514MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
515                                      SmallVectorImpl<MCFixup> &Fixups) const {
516  assert(MI.getOperand(OpNo-1).isImm());
517  assert(MI.getOperand(OpNo).isImm());
518  unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups);
519  unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
520
521  return Position + Size - 1;
522}
523
524#include "MipsGenMCCodeEmitter.inc"
525
526