19f610119SJia Liu //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
2750ecec7SAkira Hatanaka //
3750ecec7SAkira Hatanaka //                     The LLVM Compiler Infrastructure
4750ecec7SAkira Hatanaka //
5750ecec7SAkira Hatanaka // This file is distributed under the University of Illinois Open Source
6750ecec7SAkira Hatanaka // License. See LICENSE.TXT for details.
7750ecec7SAkira Hatanaka //
8750ecec7SAkira Hatanaka //===----------------------------------------------------------------------===//
9750ecec7SAkira Hatanaka //
10750ecec7SAkira Hatanaka // This file implements the MipsMCCodeEmitter class.
11750ecec7SAkira Hatanaka //
12750ecec7SAkira Hatanaka //===----------------------------------------------------------------------===//
139e1450bcSMatheus Almeida 
14c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsFixupKinds.h"
15a5da588bSPetar Jovanovic #include "MCTargetDesc/MipsMCExpr.h"
16c85e3ff3SBruno Cardoso Lopes #include "MCTargetDesc/MipsMCTargetDesc.h"
17926883e1SEugene Zelenko #include "MipsMCCodeEmitter.h"
18c85e3ff3SBruno Cardoso Lopes #include "llvm/ADT/APFloat.h"
19926883e1SEugene Zelenko #include "llvm/ADT/APInt.h"
209e1450bcSMatheus Almeida #include "llvm/ADT/SmallVector.h"
215d6faed1SAkira Hatanaka #include "llvm/MC/MCContext.h"
22750ecec7SAkira Hatanaka #include "llvm/MC/MCExpr.h"
23d9903888SChandler Carruth #include "llvm/MC/MCFixup.h"
24750ecec7SAkira Hatanaka #include "llvm/MC/MCInst.h"
25926883e1SEugene Zelenko #include "llvm/MC/MCInstrDesc.h"
26750ecec7SAkira Hatanaka #include "llvm/MC/MCInstrInfo.h"
273de83e40SPete Cooper #include "llvm/MC/MCRegisterInfo.h"
28750ecec7SAkira Hatanaka #include "llvm/MC/MCSubtargetInfo.h"
29926883e1SEugene Zelenko #include "llvm/Support/Casting.h"
30926883e1SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
31750ecec7SAkira Hatanaka #include "llvm/Support/raw_ostream.h"
32926883e1SEugene Zelenko #include <cassert>
33926883e1SEugene Zelenko #include <cstdint>
34926883e1SEugene Zelenko 
35926883e1SEugene Zelenko using namespace llvm;
36750ecec7SAkira Hatanaka 
3784e68b29SChandler Carruth #define DEBUG_TYPE "mccodeemitter"
3884e68b29SChandler Carruth 
39be6a818fSAkira Hatanaka #define GET_INSTRMAP_INFO
40be6a818fSAkira Hatanaka #include "MipsGenInstrInfo.inc"
419e1450bcSMatheus Almeida #undef GET_INSTRMAP_INFO
42be6a818fSAkira Hatanaka 
439e1450bcSMatheus Almeida namespace llvm {
44926883e1SEugene Zelenko 
459e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
46c3b04279SJim Grosbach                                          const MCRegisterInfo &MRI,
479e1450bcSMatheus Almeida                                          MCContext &Ctx) {
48d2cca113SDavid Woodhouse   return new MipsMCCodeEmitter(MCII, Ctx, false);
491ee768dbSAkira Hatanaka }
501ee768dbSAkira Hatanaka 
519e1450bcSMatheus Almeida MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
52c3b04279SJim Grosbach                                          const MCRegisterInfo &MRI,
539e1450bcSMatheus Almeida                                          MCContext &Ctx) {
54d2cca113SDavid Woodhouse   return new MipsMCCodeEmitter(MCII, Ctx, true);
55750ecec7SAkira Hatanaka }
56926883e1SEugene Zelenko 
57926883e1SEugene Zelenko } // end namespace llvm
58f30f2cceSRafael Espindola 
59f30f2cceSRafael Espindola // If the D<shift> instruction has a shift amount that is greater
60f30f2cceSRafael Espindola // than 31 (checked in calling routine), lower it to a D<shift>32 instruction
61f30f2cceSRafael Espindola static void LowerLargeShift(MCInst& Inst) {
62f30f2cceSRafael Espindola   assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
63f30f2cceSRafael Espindola   assert(Inst.getOperand(2).isImm());
64f30f2cceSRafael Espindola 
65f30f2cceSRafael Espindola   int64_t Shift = Inst.getOperand(2).getImm();
66f30f2cceSRafael Espindola   if (Shift <= 31)
67f30f2cceSRafael Espindola     return; // Do nothing
68f30f2cceSRafael Espindola   Shift -= 32;
69f30f2cceSRafael Espindola 
70f30f2cceSRafael Espindola   // saminus32
71f30f2cceSRafael Espindola   Inst.getOperand(2).setImm(Shift);
72f30f2cceSRafael Espindola 
73f30f2cceSRafael Espindola   switch (Inst.getOpcode()) {
74f30f2cceSRafael Espindola   default:
75f30f2cceSRafael Espindola     // Calling function is not synchronized
76f30f2cceSRafael Espindola     llvm_unreachable("Unexpected shift instruction");
77f30f2cceSRafael Espindola   case Mips::DSLL:
78f30f2cceSRafael Espindola     Inst.setOpcode(Mips::DSLL32);
79f30f2cceSRafael Espindola     return;
80f30f2cceSRafael Espindola   case Mips::DSRL:
81f30f2cceSRafael Espindola     Inst.setOpcode(Mips::DSRL32);
82f30f2cceSRafael Espindola     return;
83f30f2cceSRafael Espindola   case Mips::DSRA:
84f30f2cceSRafael Espindola     Inst.setOpcode(Mips::DSRA32);
85f30f2cceSRafael Espindola     return;
866a3fe574SAkira Hatanaka   case Mips::DROTR:
876a3fe574SAkira Hatanaka     Inst.setOpcode(Mips::DROTR32);
886a3fe574SAkira Hatanaka     return;
89f1e0a03dSHrvoje Varga   case Mips::DSLL_MM64R6:
90f1e0a03dSHrvoje Varga     Inst.setOpcode(Mips::DSLL32_MM64R6);
91f1e0a03dSHrvoje Varga     return;
9224b975dcSHrvoje Varga   case Mips::DSRL_MM64R6:
9324b975dcSHrvoje Varga     Inst.setOpcode(Mips::DSRL32_MM64R6);
9424b975dcSHrvoje Varga     return;
95f1e0a03dSHrvoje Varga   case Mips::DSRA_MM64R6:
96f1e0a03dSHrvoje Varga     Inst.setOpcode(Mips::DSRA32_MM64R6);
97f1e0a03dSHrvoje Varga     return;
98f1e0a03dSHrvoje Varga   case Mips::DROTR_MM64R6:
99f1e0a03dSHrvoje Varga     Inst.setOpcode(Mips::DROTR32_MM64R6);
100f1e0a03dSHrvoje Varga     return;
101f30f2cceSRafael Espindola   }
102f30f2cceSRafael Espindola }
103f30f2cceSRafael Espindola 
104611eb829SDaniel Sanders // Pick a DINS instruction variant based on the pos and size operands
105611eb829SDaniel Sanders static void LowerDins(MCInst& InstIn) {
106f30f2cceSRafael Espindola   assert(InstIn.getNumOperands() == 5 &&
107f30f2cceSRafael Espindola          "Invalid no. of machine operands for DINS!");
108f30f2cceSRafael Espindola 
109f30f2cceSRafael Espindola   assert(InstIn.getOperand(2).isImm());
110f30f2cceSRafael Espindola   int64_t pos = InstIn.getOperand(2).getImm();
111f30f2cceSRafael Espindola   assert(InstIn.getOperand(3).isImm());
112f30f2cceSRafael Espindola   int64_t size = InstIn.getOperand(3).getImm();
113f30f2cceSRafael Espindola 
114f9fa62e5SStrahinja Petrovic   assert((pos + size) <= 64 &&
115f9fa62e5SStrahinja Petrovic          "DINS cannot have position plus size over 64");
116f9fa62e5SStrahinja Petrovic   if (pos < 32) {
117f9fa62e5SStrahinja Petrovic     if ((pos + size) > 0 && (pos + size) <= 32)
118f9fa62e5SStrahinja Petrovic       return; // DINS, do nothing
119f9fa62e5SStrahinja Petrovic     else if ((pos + size) > 32) {
120f9fa62e5SStrahinja Petrovic       //DINSM
121f9fa62e5SStrahinja Petrovic       InstIn.getOperand(3).setImm(size - 32);
122f9fa62e5SStrahinja Petrovic       InstIn.setOpcode(Mips::DINSM);
123f9fa62e5SStrahinja Petrovic     }
124f9fa62e5SStrahinja Petrovic   } else if ((pos + size) > 32 && (pos + size) <= 64) {
125611eb829SDaniel Sanders     // DINSU
126f30f2cceSRafael Espindola     InstIn.getOperand(2).setImm(pos - 32);
127611eb829SDaniel Sanders     InstIn.setOpcode(Mips::DINSU);
128f30f2cceSRafael Espindola   }
129f30f2cceSRafael Espindola }
130f30f2cceSRafael Espindola 
131669d8dd8SSimon Dardis // Fix a bad compact branch encoding for beqc/bnec.
132669d8dd8SSimon Dardis void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const {
133669d8dd8SSimon Dardis   // Encoding may be illegal !(rs < rt), but this situation is
134669d8dd8SSimon Dardis   // easily fixed.
135669d8dd8SSimon Dardis   unsigned RegOp0 = Inst.getOperand(0).getReg();
136669d8dd8SSimon Dardis   unsigned RegOp1 = Inst.getOperand(1).getReg();
137669d8dd8SSimon Dardis 
138669d8dd8SSimon Dardis   unsigned Reg0 =  Ctx.getRegisterInfo()->getEncodingValue(RegOp0);
139669d8dd8SSimon Dardis   unsigned Reg1 =  Ctx.getRegisterInfo()->getEncodingValue(RegOp1);
140669d8dd8SSimon Dardis 
14168a204ddSSimon Dardis   if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC ||
14268a204ddSSimon Dardis       Inst.getOpcode() == Mips::BNEC64 || Inst.getOpcode() == Mips::BEQC64) {
143669d8dd8SSimon Dardis     assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!");
144669d8dd8SSimon Dardis     if (Reg0 < Reg1)
145669d8dd8SSimon Dardis       return;
146b60833c0SSimon Dardis   } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) {
147b60833c0SSimon Dardis     if (Reg0 >= Reg1)
148b60833c0SSimon Dardis       return;
149c962c493SHrvoje Varga   } else if (Inst.getOpcode() == Mips::BNVC_MMR6 ||
150c962c493SHrvoje Varga              Inst.getOpcode() == Mips::BOVC_MMR6) {
151c962c493SHrvoje Varga     if (Reg1 >= Reg0)
152c962c493SHrvoje Varga       return;
153b60833c0SSimon Dardis   } else
154b60833c0SSimon Dardis     llvm_unreachable("Cannot rewrite unknown branch!");
155669d8dd8SSimon Dardis 
156669d8dd8SSimon Dardis   Inst.getOperand(0).setReg(RegOp1);
157669d8dd8SSimon Dardis   Inst.getOperand(1).setReg(RegOp0);
158669d8dd8SSimon Dardis }
159669d8dd8SSimon Dardis 
1609e1450bcSMatheus Almeida bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
161db0712f9SMichael Kuperstein   return STI.getFeatureBits()[Mips::FeatureMicroMips];
1629e1450bcSMatheus Almeida }
1639e1450bcSMatheus Almeida 
164c22555d9SJozef Kolek bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const {
165db0712f9SMichael Kuperstein   return STI.getFeatureBits()[Mips::FeatureMips32r6];
166c22555d9SJozef Kolek }
167c22555d9SJozef Kolek 
1689e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
1699e1450bcSMatheus Almeida   OS << (char)C;
1709e1450bcSMatheus Almeida }
1719e1450bcSMatheus Almeida 
1729e1450bcSMatheus Almeida void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
1739e1450bcSMatheus Almeida                                         const MCSubtargetInfo &STI,
1749e1450bcSMatheus Almeida                                         raw_ostream &OS) const {
1759e1450bcSMatheus Almeida   // Output the instruction encoding in little endian byte order.
1769e1450bcSMatheus Almeida   // Little-endian byte ordering:
1779e1450bcSMatheus Almeida   //   mips32r2:   4 | 3 | 2 | 1
1789e1450bcSMatheus Almeida   //   microMIPS:  2 | 1 | 4 | 3
1799e1450bcSMatheus Almeida   if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
1809e1450bcSMatheus Almeida     EmitInstruction(Val >> 16, 2, STI, OS);
1819e1450bcSMatheus Almeida     EmitInstruction(Val, 2, STI, OS);
1829e1450bcSMatheus Almeida   } else {
1839e1450bcSMatheus Almeida     for (unsigned i = 0; i < Size; ++i) {
1849e1450bcSMatheus Almeida       unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
1859e1450bcSMatheus Almeida       EmitByte((Val >> Shift) & 0xff, OS);
1869e1450bcSMatheus Almeida     }
1879e1450bcSMatheus Almeida   }
1889e1450bcSMatheus Almeida }
1899e1450bcSMatheus Almeida 
19091df21f7SJim Grosbach /// encodeInstruction - Emit the instruction.
1914e07b95dSJack Carter /// Size the instruction with Desc.getSize().
192c85e3ff3SBruno Cardoso Lopes void MipsMCCodeEmitter::
19391df21f7SJim Grosbach encodeInstruction(const MCInst &MI, raw_ostream &OS,
1949784cef3SDavid Woodhouse                   SmallVectorImpl<MCFixup> &Fixups,
1959784cef3SDavid Woodhouse                   const MCSubtargetInfo &STI) const
196c85e3ff3SBruno Cardoso Lopes {
197aa7aeaa0SJack Carter   // Non-pseudo instructions that get changed for direct object
198aa7aeaa0SJack Carter   // only based on operand values.
199aa7aeaa0SJack Carter   // If this list of instructions get much longer we will move
200aa7aeaa0SJack Carter   // the check to a function call. Until then, this is more efficient.
201aa7aeaa0SJack Carter   MCInst TmpInst = MI;
202aa7aeaa0SJack Carter   switch (MI.getOpcode()) {
203aa7aeaa0SJack Carter   // If shift amount is >= 32 it the inst needs to be lowered further
204aa7aeaa0SJack Carter   case Mips::DSLL:
205aa7aeaa0SJack Carter   case Mips::DSRL:
206aa7aeaa0SJack Carter   case Mips::DSRA:
2076a3fe574SAkira Hatanaka   case Mips::DROTR:
208f1e0a03dSHrvoje Varga   case Mips::DSLL_MM64R6:
20924b975dcSHrvoje Varga   case Mips::DSRL_MM64R6:
210f1e0a03dSHrvoje Varga   case Mips::DSRA_MM64R6:
211f1e0a03dSHrvoje Varga   case Mips::DROTR_MM64R6:
212f30f2cceSRafael Espindola     LowerLargeShift(TmpInst);
213aa7aeaa0SJack Carter     break;
214aa7aeaa0SJack Carter     // Double extract instruction is chosen by pos and size operands
215aa7aeaa0SJack Carter   case Mips::DINS:
216611eb829SDaniel Sanders     LowerDins(TmpInst);
217669d8dd8SSimon Dardis     break;
218b60833c0SSimon Dardis   // Compact branches, enforce encoding restrictions.
219669d8dd8SSimon Dardis   case Mips::BEQC:
220669d8dd8SSimon Dardis   case Mips::BNEC:
22168a204ddSSimon Dardis   case Mips::BEQC64:
22268a204ddSSimon Dardis   case Mips::BNEC64:
223b60833c0SSimon Dardis   case Mips::BOVC:
224c962c493SHrvoje Varga   case Mips::BOVC_MMR6:
225b60833c0SSimon Dardis   case Mips::BNVC:
226c962c493SHrvoje Varga   case Mips::BNVC_MMR6:
227669d8dd8SSimon Dardis     LowerCompactBranch(TmpInst);
228aa7aeaa0SJack Carter   }
229aa7aeaa0SJack Carter 
23097700977SJack Carter   unsigned long N = Fixups.size();
2313fa98a65SDavid Woodhouse   uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
232c85e3ff3SBruno Cardoso Lopes 
233c85e3ff3SBruno Cardoso Lopes   // Check for unimplemented opcodes.
234aa7aeaa0SJack Carter   // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
235c85e3ff3SBruno Cardoso Lopes   // so we have to special check for them.
236aa7aeaa0SJack Carter   unsigned Opcode = TmpInst.getOpcode();
237c7e220f6SJozef Kolek   if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) &&
238c7e220f6SJozef Kolek       (Opcode != Mips::SLL_MM) && !Binary)
23991df21f7SJim Grosbach     llvm_unreachable("unimplemented opcode in encodeInstruction()");
240c85e3ff3SBruno Cardoso Lopes 
241b59a5419SZoran Jovanovic   int NewOpcode = -1;
2426ca13eafSJozef Kolek   if (isMicroMips(STI)) {
243b59a5419SZoran Jovanovic     if (isMips32r6(STI)) {
244b59a5419SZoran Jovanovic       NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
245b59a5419SZoran Jovanovic       if (NewOpcode == -1)
246b59a5419SZoran Jovanovic         NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
247b59a5419SZoran Jovanovic     }
248b59a5419SZoran Jovanovic     else
249b59a5419SZoran Jovanovic       NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips);
250b59a5419SZoran Jovanovic 
2512e386d3dSZoran Jovanovic     // Check whether it is Dsp instruction.
2522e386d3dSZoran Jovanovic     if (NewOpcode == -1)
2532e386d3dSZoran Jovanovic       NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp);
2542e386d3dSZoran Jovanovic 
255be6a818fSAkira Hatanaka     if (NewOpcode != -1) {
25697700977SJack Carter       if (Fixups.size() > N)
25797700977SJack Carter         Fixups.pop_back();
258b59a5419SZoran Jovanovic 
259be6a818fSAkira Hatanaka       Opcode = NewOpcode;
260be6a818fSAkira Hatanaka       TmpInst.setOpcode (NewOpcode);
2613fa98a65SDavid Woodhouse       Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
262be6a818fSAkira Hatanaka     }
263be6a818fSAkira Hatanaka   }
264be6a818fSAkira Hatanaka 
265aa7aeaa0SJack Carter   const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
266c85e3ff3SBruno Cardoso Lopes 
2675b5559d3SJack Carter   // Get byte count of instruction
2685b5559d3SJack Carter   unsigned Size = Desc.getSize();
2695b5559d3SJack Carter   if (!Size)
2705b5559d3SJack Carter     llvm_unreachable("Desc.getSize() returns 0");
271c85e3ff3SBruno Cardoso Lopes 
272d2cca113SDavid Woodhouse   EmitInstruction(Binary, Size, STI, OS);
273c85e3ff3SBruno Cardoso Lopes }
274c85e3ff3SBruno Cardoso Lopes 
275c85e3ff3SBruno Cardoso Lopes /// getBranchTargetOpValue - Return binary encoding of the branch
276c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation,
277c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero.
278c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter::
279c85e3ff3SBruno Cardoso Lopes getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
2803fa98a65SDavid Woodhouse                        SmallVectorImpl<MCFixup> &Fixups,
2813fa98a65SDavid Woodhouse                        const MCSubtargetInfo &STI) const {
282c85e3ff3SBruno Cardoso Lopes   const MCOperand &MO = MI.getOperand(OpNo);
28371e6a749SJack Carter 
2844f69a0f2SJack Carter   // If the destination is an immediate, divide by 4.
2854f69a0f2SJack Carter   if (MO.isImm()) return MO.getImm() >> 2;
2864f69a0f2SJack Carter 
28771e6a749SJack Carter   assert(MO.isExpr() &&
28871e6a749SJack Carter          "getBranchTargetOpValue expects only expressions or immediates");
289c85e3ff3SBruno Cardoso Lopes 
290b7915a1fSPetar Jovanovic   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
291b7915a1fSPetar Jovanovic       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
292b7915a1fSPetar Jovanovic   Fixups.push_back(MCFixup::create(0, FixupExpression,
293c85e3ff3SBruno Cardoso Lopes                                    MCFixupKind(Mips::fixup_Mips_PC16)));
294c85e3ff3SBruno Cardoso Lopes   return 0;
295c85e3ff3SBruno Cardoso Lopes }
296c85e3ff3SBruno Cardoso Lopes 
2976f09cdfdSHrvoje Varga /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch
2986f09cdfdSHrvoje Varga /// target operand. If the machine operand requires relocation,
2996f09cdfdSHrvoje Varga /// record the relocation and return zero.
3006f09cdfdSHrvoje Varga unsigned MipsMCCodeEmitter::
3016f09cdfdSHrvoje Varga getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo,
3026f09cdfdSHrvoje Varga                               SmallVectorImpl<MCFixup> &Fixups,
3036f09cdfdSHrvoje Varga                               const MCSubtargetInfo &STI) const {
3046f09cdfdSHrvoje Varga   const MCOperand &MO = MI.getOperand(OpNo);
3056f09cdfdSHrvoje Varga 
3066f09cdfdSHrvoje Varga   // If the destination is an immediate, divide by 2.
3076f09cdfdSHrvoje Varga   if (MO.isImm()) return MO.getImm() >> 1;
3086f09cdfdSHrvoje Varga 
3096f09cdfdSHrvoje Varga   assert(MO.isExpr() &&
3106f09cdfdSHrvoje Varga          "getBranchTargetOpValue expects only expressions or immediates");
3116f09cdfdSHrvoje Varga 
3126f09cdfdSHrvoje Varga   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
3136f09cdfdSHrvoje Varga       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
3146f09cdfdSHrvoje Varga   Fixups.push_back(MCFixup::create(0, FixupExpression,
3156f09cdfdSHrvoje Varga                                    MCFixupKind(Mips::fixup_Mips_PC16)));
3166f09cdfdSHrvoje Varga   return 0;
3176f09cdfdSHrvoje Varga }
3186f09cdfdSHrvoje Varga 
319c962c493SHrvoje Varga /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch
320c962c493SHrvoje Varga /// target operand. If the machine operand requires relocation,
321c962c493SHrvoje Varga /// record the relocation and return zero.
322c962c493SHrvoje Varga unsigned MipsMCCodeEmitter::
323c962c493SHrvoje Varga getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo,
324c962c493SHrvoje Varga                            SmallVectorImpl<MCFixup> &Fixups,
325c962c493SHrvoje Varga                            const MCSubtargetInfo &STI) const {
326c962c493SHrvoje Varga   const MCOperand &MO = MI.getOperand(OpNo);
327c962c493SHrvoje Varga 
328c962c493SHrvoje Varga   // If the destination is an immediate, divide by 2.
329c962c493SHrvoje Varga   if (MO.isImm())
330c962c493SHrvoje Varga     return MO.getImm() >> 1;
331c962c493SHrvoje Varga 
332c962c493SHrvoje Varga   assert(MO.isExpr() &&
333c962c493SHrvoje Varga          "getBranchTargetOpValueMMR6 expects only expressions or immediates");
334c962c493SHrvoje Varga 
335c962c493SHrvoje Varga   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
336c962c493SHrvoje Varga       MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx);
337c962c493SHrvoje Varga   Fixups.push_back(MCFixup::create(0, FixupExpression,
338c962c493SHrvoje Varga                                    MCFixupKind(Mips::fixup_Mips_PC16)));
339c962c493SHrvoje Varga   return 0;
340c962c493SHrvoje Varga }
341c962c493SHrvoje Varga 
342f0ed16eaSHrvoje Varga /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch
343f0ed16eaSHrvoje Varga /// target operand. If the machine operand requires relocation,
344f0ed16eaSHrvoje Varga /// record the relocation and return zero.
345f0ed16eaSHrvoje Varga unsigned MipsMCCodeEmitter::
346f0ed16eaSHrvoje Varga getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo,
347f0ed16eaSHrvoje Varga                                SmallVectorImpl<MCFixup> &Fixups,
348f0ed16eaSHrvoje Varga                                const MCSubtargetInfo &STI) const {
349f0ed16eaSHrvoje Varga   const MCOperand &MO = MI.getOperand(OpNo);
350f0ed16eaSHrvoje Varga 
351f0ed16eaSHrvoje Varga   // If the destination is an immediate, divide by 4.
352f0ed16eaSHrvoje Varga   if (MO.isImm())
353f0ed16eaSHrvoje Varga     return MO.getImm() >> 2;
354f0ed16eaSHrvoje Varga 
355f0ed16eaSHrvoje Varga   assert(MO.isExpr() &&
356f0ed16eaSHrvoje Varga          "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates");
357f0ed16eaSHrvoje Varga 
358f0ed16eaSHrvoje Varga   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
359f0ed16eaSHrvoje Varga       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
360f0ed16eaSHrvoje Varga   Fixups.push_back(MCFixup::create(0, FixupExpression,
361f0ed16eaSHrvoje Varga                                    MCFixupKind(Mips::fixup_Mips_PC16)));
362f0ed16eaSHrvoje Varga   return 0;
363f0ed16eaSHrvoje Varga }
364f0ed16eaSHrvoje Varga 
3659761e96bSJozef Kolek /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
3669761e96bSJozef Kolek /// target operand. If the machine operand requires relocation,
3679761e96bSJozef Kolek /// record the relocation and return zero.
3689761e96bSJozef Kolek unsigned MipsMCCodeEmitter::
3699761e96bSJozef Kolek getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
3709761e96bSJozef Kolek                           SmallVectorImpl<MCFixup> &Fixups,
3719761e96bSJozef Kolek                           const MCSubtargetInfo &STI) const {
3729761e96bSJozef Kolek   const MCOperand &MO = MI.getOperand(OpNo);
3739761e96bSJozef Kolek 
3749761e96bSJozef Kolek   // If the destination is an immediate, divide by 2.
3759761e96bSJozef Kolek   if (MO.isImm()) return MO.getImm() >> 1;
3769761e96bSJozef Kolek 
3779761e96bSJozef Kolek   assert(MO.isExpr() &&
3789761e96bSJozef Kolek          "getBranchTargetOpValueMM expects only expressions or immediates");
3799761e96bSJozef Kolek 
3809761e96bSJozef Kolek   const MCExpr *Expr = MO.getExpr();
38163661f8dSJim Grosbach   Fixups.push_back(MCFixup::create(0, Expr,
3829761e96bSJozef Kolek                                    MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
3839761e96bSJozef Kolek   return 0;
3849761e96bSJozef Kolek }
3859761e96bSJozef Kolek 
3865cfebddeSJozef Kolek /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
3875cfebddeSJozef Kolek /// 10-bit branch target operand. If the machine operand requires relocation,
3885cfebddeSJozef Kolek /// record the relocation and return zero.
3895cfebddeSJozef Kolek unsigned MipsMCCodeEmitter::
3905cfebddeSJozef Kolek getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
3915cfebddeSJozef Kolek                              SmallVectorImpl<MCFixup> &Fixups,
3925cfebddeSJozef Kolek                              const MCSubtargetInfo &STI) const {
3935cfebddeSJozef Kolek   const MCOperand &MO = MI.getOperand(OpNo);
3945cfebddeSJozef Kolek 
3955cfebddeSJozef Kolek   // If the destination is an immediate, divide by 2.
3965cfebddeSJozef Kolek   if (MO.isImm()) return MO.getImm() >> 1;
3975cfebddeSJozef Kolek 
3985cfebddeSJozef Kolek   assert(MO.isExpr() &&
3995cfebddeSJozef Kolek          "getBranchTargetOpValuePC10 expects only expressions or immediates");
4005cfebddeSJozef Kolek 
4015cfebddeSJozef Kolek   const MCExpr *Expr = MO.getExpr();
40263661f8dSJim Grosbach   Fixups.push_back(MCFixup::create(0, Expr,
4035cfebddeSJozef Kolek                    MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
4045cfebddeSJozef Kolek   return 0;
4055cfebddeSJozef Kolek }
4065cfebddeSJozef Kolek 
4078a80aa76SZoran Jovanovic /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
4088a80aa76SZoran Jovanovic /// target operand. If the machine operand requires relocation,
4098a80aa76SZoran Jovanovic /// record the relocation and return zero.
4108a80aa76SZoran Jovanovic unsigned MipsMCCodeEmitter::
4118a80aa76SZoran Jovanovic getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
4123fa98a65SDavid Woodhouse                          SmallVectorImpl<MCFixup> &Fixups,
4133fa98a65SDavid Woodhouse                          const MCSubtargetInfo &STI) const {
4148a80aa76SZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
4158a80aa76SZoran Jovanovic 
4168a80aa76SZoran Jovanovic   // If the destination is an immediate, divide by 2.
4178a80aa76SZoran Jovanovic   if (MO.isImm()) return MO.getImm() >> 1;
4188a80aa76SZoran Jovanovic 
4198a80aa76SZoran Jovanovic   assert(MO.isExpr() &&
4208a80aa76SZoran Jovanovic          "getBranchTargetOpValueMM expects only expressions or immediates");
4218a80aa76SZoran Jovanovic 
4228a80aa76SZoran Jovanovic   const MCExpr *Expr = MO.getExpr();
42363661f8dSJim Grosbach   Fixups.push_back(MCFixup::create(0, Expr,
4248a80aa76SZoran Jovanovic                    MCFixupKind(Mips::
4258a80aa76SZoran Jovanovic                                fixup_MICROMIPS_PC16_S1)));
4268a80aa76SZoran Jovanovic   return 0;
4278a80aa76SZoran Jovanovic }
4288a80aa76SZoran Jovanovic 
4293c8869dcSZoran Jovanovic /// getBranchTarget21OpValue - Return binary encoding of the branch
4303c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation,
4313c8869dcSZoran Jovanovic /// record the relocation and return zero.
4323c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter::
4333c8869dcSZoran Jovanovic getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
4343c8869dcSZoran Jovanovic                          SmallVectorImpl<MCFixup> &Fixups,
4353c8869dcSZoran Jovanovic                          const MCSubtargetInfo &STI) const {
4363c8869dcSZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
4373c8869dcSZoran Jovanovic 
4383c8869dcSZoran Jovanovic   // If the destination is an immediate, divide by 4.
4393c8869dcSZoran Jovanovic   if (MO.isImm()) return MO.getImm() >> 2;
4403c8869dcSZoran Jovanovic 
4413c8869dcSZoran Jovanovic   assert(MO.isExpr() &&
4423c8869dcSZoran Jovanovic          "getBranchTarget21OpValue expects only expressions or immediates");
4433c8869dcSZoran Jovanovic 
444b7915a1fSPetar Jovanovic   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
445b7915a1fSPetar Jovanovic       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
446b7915a1fSPetar Jovanovic   Fixups.push_back(MCFixup::create(0, FixupExpression,
44710e06da0SZoran Jovanovic                                    MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
4483c8869dcSZoran Jovanovic   return 0;
4493c8869dcSZoran Jovanovic }
4503c8869dcSZoran Jovanovic 
45184e4d59eSZoran Jovanovic /// getBranchTarget21OpValueMM - Return binary encoding of the branch
45284e4d59eSZoran Jovanovic /// target operand for microMIPS. If the machine operand requires
45384e4d59eSZoran Jovanovic /// relocation, record the relocation and return zero.
45484e4d59eSZoran Jovanovic unsigned MipsMCCodeEmitter::
45584e4d59eSZoran Jovanovic getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo,
45684e4d59eSZoran Jovanovic                            SmallVectorImpl<MCFixup> &Fixups,
45784e4d59eSZoran Jovanovic                            const MCSubtargetInfo &STI) const {
45884e4d59eSZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
45984e4d59eSZoran Jovanovic 
460f0ed16eaSHrvoje Varga   // If the destination is an immediate, divide by 4.
461f0ed16eaSHrvoje Varga   if (MO.isImm()) return MO.getImm() >> 2;
46284e4d59eSZoran Jovanovic 
46384e4d59eSZoran Jovanovic   assert(MO.isExpr() &&
46484e4d59eSZoran Jovanovic     "getBranchTarget21OpValueMM expects only expressions or immediates");
46584e4d59eSZoran Jovanovic 
4665f94cedeSZoran Jovanovic   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
4675f94cedeSZoran Jovanovic       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
4685f94cedeSZoran Jovanovic   Fixups.push_back(MCFixup::create(0, FixupExpression,
4695f94cedeSZoran Jovanovic                                    MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1)));
47084e4d59eSZoran Jovanovic   return 0;
47184e4d59eSZoran Jovanovic }
47284e4d59eSZoran Jovanovic 
4733c8869dcSZoran Jovanovic /// getBranchTarget26OpValue - Return binary encoding of the branch
4743c8869dcSZoran Jovanovic /// target operand. If the machine operand requires relocation,
4753c8869dcSZoran Jovanovic /// record the relocation and return zero.
4763c8869dcSZoran Jovanovic unsigned MipsMCCodeEmitter::
4773c8869dcSZoran Jovanovic getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
4783c8869dcSZoran Jovanovic                          SmallVectorImpl<MCFixup> &Fixups,
4793c8869dcSZoran Jovanovic                          const MCSubtargetInfo &STI) const {
4803c8869dcSZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
4813c8869dcSZoran Jovanovic 
4823c8869dcSZoran Jovanovic   // If the destination is an immediate, divide by 4.
4833c8869dcSZoran Jovanovic   if (MO.isImm()) return MO.getImm() >> 2;
4843c8869dcSZoran Jovanovic 
4853c8869dcSZoran Jovanovic   assert(MO.isExpr() &&
4863c8869dcSZoran Jovanovic          "getBranchTarget26OpValue expects only expressions or immediates");
4873c8869dcSZoran Jovanovic 
488b7915a1fSPetar Jovanovic   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
489b7915a1fSPetar Jovanovic       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
490b7915a1fSPetar Jovanovic   Fixups.push_back(MCFixup::create(0, FixupExpression,
49110e06da0SZoran Jovanovic                                    MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
4923c8869dcSZoran Jovanovic   return 0;
4933c8869dcSZoran Jovanovic }
4943c8869dcSZoran Jovanovic 
495a887b361SZoran Jovanovic /// getBranchTarget26OpValueMM - Return binary encoding of the branch
496a887b361SZoran Jovanovic /// target operand. If the machine operand requires relocation,
497a887b361SZoran Jovanovic /// record the relocation and return zero.
498a887b361SZoran Jovanovic unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM(
499a887b361SZoran Jovanovic     const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
500a887b361SZoran Jovanovic     const MCSubtargetInfo &STI) const {
501a887b361SZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
502a887b361SZoran Jovanovic 
503a887b361SZoran Jovanovic   // If the destination is an immediate, divide by 2.
504a887b361SZoran Jovanovic   if (MO.isImm())
505a887b361SZoran Jovanovic     return MO.getImm() >> 1;
506a887b361SZoran Jovanovic 
50702b70030SZoran Jovanovic   assert(MO.isExpr() &&
50802b70030SZoran Jovanovic          "getBranchTarget26OpValueMM expects only expressions or immediates");
50902b70030SZoran Jovanovic 
51002b70030SZoran Jovanovic   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
51102b70030SZoran Jovanovic       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
51202b70030SZoran Jovanovic   Fixups.push_back(MCFixup::create(0, FixupExpression,
51302b70030SZoran Jovanovic                                    MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1)));
514a887b361SZoran Jovanovic   return 0;
515a887b361SZoran Jovanovic }
516a887b361SZoran Jovanovic 
51752c56b93SZoran Jovanovic /// getJumpOffset16OpValue - Return binary encoding of the jump
51852c56b93SZoran Jovanovic /// target operand. If the machine operand requires relocation,
51952c56b93SZoran Jovanovic /// record the relocation and return zero.
52052c56b93SZoran Jovanovic unsigned MipsMCCodeEmitter::
52152c56b93SZoran Jovanovic getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
52252c56b93SZoran Jovanovic                        SmallVectorImpl<MCFixup> &Fixups,
52352c56b93SZoran Jovanovic                        const MCSubtargetInfo &STI) const {
52452c56b93SZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
52552c56b93SZoran Jovanovic 
52652c56b93SZoran Jovanovic   if (MO.isImm()) return MO.getImm();
52752c56b93SZoran Jovanovic 
52852c56b93SZoran Jovanovic   assert(MO.isExpr() &&
52952c56b93SZoran Jovanovic          "getJumpOffset16OpValue expects only expressions or an immediate");
53052c56b93SZoran Jovanovic 
53152c56b93SZoran Jovanovic    // TODO: Push fixup.
53252c56b93SZoran Jovanovic    return 0;
53352c56b93SZoran Jovanovic }
53452c56b93SZoran Jovanovic 
535c85e3ff3SBruno Cardoso Lopes /// getJumpTargetOpValue - Return binary encoding of the jump
536c85e3ff3SBruno Cardoso Lopes /// target operand. If the machine operand requires relocation,
537c85e3ff3SBruno Cardoso Lopes /// record the relocation and return zero.
538c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter::
539c85e3ff3SBruno Cardoso Lopes getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
5403fa98a65SDavid Woodhouse                      SmallVectorImpl<MCFixup> &Fixups,
5413fa98a65SDavid Woodhouse                      const MCSubtargetInfo &STI) const {
542c85e3ff3SBruno Cardoso Lopes   const MCOperand &MO = MI.getOperand(OpNo);
5434f69a0f2SJack Carter   // If the destination is an immediate, divide by 4.
5444f69a0f2SJack Carter   if (MO.isImm()) return MO.getImm()>>2;
5454f69a0f2SJack Carter 
54671e6a749SJack Carter   assert(MO.isExpr() &&
54771e6a749SJack Carter          "getJumpTargetOpValue expects only expressions or an immediate");
548c85e3ff3SBruno Cardoso Lopes 
549c85e3ff3SBruno Cardoso Lopes   const MCExpr *Expr = MO.getExpr();
55063661f8dSJim Grosbach   Fixups.push_back(MCFixup::create(0, Expr,
551c85e3ff3SBruno Cardoso Lopes                                    MCFixupKind(Mips::fixup_Mips_26)));
552c85e3ff3SBruno Cardoso Lopes   return 0;
553c85e3ff3SBruno Cardoso Lopes }
554c85e3ff3SBruno Cardoso Lopes 
555c85e3ff3SBruno Cardoso Lopes unsigned MipsMCCodeEmitter::
556507e084aSZoran Jovanovic getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
5573fa98a65SDavid Woodhouse                        SmallVectorImpl<MCFixup> &Fixups,
5583fa98a65SDavid Woodhouse                        const MCSubtargetInfo &STI) const {
559507e084aSZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
560507e084aSZoran Jovanovic   // If the destination is an immediate, divide by 2.
561507e084aSZoran Jovanovic   if (MO.isImm()) return MO.getImm() >> 1;
562507e084aSZoran Jovanovic 
563507e084aSZoran Jovanovic   assert(MO.isExpr() &&
564507e084aSZoran Jovanovic          "getJumpTargetOpValueMM expects only expressions or an immediate");
565507e084aSZoran Jovanovic 
566507e084aSZoran Jovanovic   const MCExpr *Expr = MO.getExpr();
56763661f8dSJim Grosbach   Fixups.push_back(MCFixup::create(0, Expr,
568507e084aSZoran Jovanovic                                    MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
569507e084aSZoran Jovanovic   return 0;
570507e084aSZoran Jovanovic }
571507e084aSZoran Jovanovic 
572507e084aSZoran Jovanovic unsigned MipsMCCodeEmitter::
573c74e3eb9SZoran Jovanovic getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
574c74e3eb9SZoran Jovanovic                      SmallVectorImpl<MCFixup> &Fixups,
575c74e3eb9SZoran Jovanovic                      const MCSubtargetInfo &STI) const {
576c74e3eb9SZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
577c74e3eb9SZoran Jovanovic   if (MO.isImm()) {
578c74e3eb9SZoran Jovanovic     // The immediate is encoded as 'immediate << 2'.
579c74e3eb9SZoran Jovanovic     unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
580c74e3eb9SZoran Jovanovic     assert((Res & 3) == 0);
581c74e3eb9SZoran Jovanovic     return Res >> 2;
582c74e3eb9SZoran Jovanovic   }
583c74e3eb9SZoran Jovanovic 
584c74e3eb9SZoran Jovanovic   assert(MO.isExpr() &&
585c74e3eb9SZoran Jovanovic          "getUImm5Lsl2Encoding expects only expressions or an immediate");
586c74e3eb9SZoran Jovanovic 
587c74e3eb9SZoran Jovanovic   return 0;
588c74e3eb9SZoran Jovanovic }
589c74e3eb9SZoran Jovanovic 
590c74e3eb9SZoran Jovanovic unsigned MipsMCCodeEmitter::
591bac3619bSZoran Jovanovic getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo,
592bac3619bSZoran Jovanovic                   SmallVectorImpl<MCFixup> &Fixups,
593bac3619bSZoran Jovanovic                   const MCSubtargetInfo &STI) const {
594bac3619bSZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
595bac3619bSZoran Jovanovic   if (MO.isImm()) {
596bac3619bSZoran Jovanovic     int Value = MO.getImm();
597bac3619bSZoran Jovanovic     return Value >> 2;
598bac3619bSZoran Jovanovic   }
599bac3619bSZoran Jovanovic 
600bac3619bSZoran Jovanovic   return 0;
601bac3619bSZoran Jovanovic }
602bac3619bSZoran Jovanovic 
603bac3619bSZoran Jovanovic unsigned MipsMCCodeEmitter::
60442b84443SZoran Jovanovic getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
60542b84443SZoran Jovanovic                      SmallVectorImpl<MCFixup> &Fixups,
60642b84443SZoran Jovanovic                      const MCSubtargetInfo &STI) const {
60742b84443SZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
60842b84443SZoran Jovanovic   if (MO.isImm()) {
60942b84443SZoran Jovanovic     unsigned Value = MO.getImm();
61042b84443SZoran Jovanovic     return Value >> 2;
61142b84443SZoran Jovanovic   }
61242b84443SZoran Jovanovic 
61342b84443SZoran Jovanovic   return 0;
61442b84443SZoran Jovanovic }
61542b84443SZoran Jovanovic 
61642b84443SZoran Jovanovic unsigned MipsMCCodeEmitter::
61798bd58caSZoran Jovanovic getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
61898bd58caSZoran Jovanovic                      SmallVectorImpl<MCFixup> &Fixups,
61998bd58caSZoran Jovanovic                      const MCSubtargetInfo &STI) const {
62098bd58caSZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
62198bd58caSZoran Jovanovic   if (MO.isImm()) {
62298bd58caSZoran Jovanovic     unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff;
62398bd58caSZoran Jovanovic     return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
62498bd58caSZoran Jovanovic   }
62598bd58caSZoran Jovanovic 
62698bd58caSZoran Jovanovic   return 0;
62798bd58caSZoran Jovanovic }
62898bd58caSZoran Jovanovic 
62998bd58caSZoran Jovanovic unsigned MipsMCCodeEmitter::
6303fa98a65SDavid Woodhouse getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
6313fa98a65SDavid Woodhouse                const MCSubtargetInfo &STI) const {
632b5cf5909SJack Carter   int64_t Res;
633049e9e4dSAkira Hatanaka 
63413760bd1SJim Grosbach   if (Expr->evaluateAsAbsolute(Res))
635b5cf5909SJack Carter     return Res;
636fe384a2cSAkira Hatanaka 
637fe384a2cSAkira Hatanaka   MCExpr::ExprKind Kind = Expr->getKind();
638b5cf5909SJack Carter   if (Kind == MCExpr::Constant) {
639b5cf5909SJack Carter     return cast<MCConstantExpr>(Expr)->getValue();
640b5cf5909SJack Carter   }
641fe384a2cSAkira Hatanaka 
642fe384a2cSAkira Hatanaka   if (Kind == MCExpr::Binary) {
6433fa98a65SDavid Woodhouse     unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
6443fa98a65SDavid Woodhouse     Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
645b5cf5909SJack Carter     return Res;
646fe384a2cSAkira Hatanaka   }
647a5da588bSPetar Jovanovic 
648a5da588bSPetar Jovanovic   if (Kind == MCExpr::Target) {
649a5da588bSPetar Jovanovic     const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
650a5da588bSPetar Jovanovic 
651a5da588bSPetar Jovanovic     Mips::Fixups FixupKind = Mips::Fixups(0);
652a5da588bSPetar Jovanovic     switch (MipsExpr->getKind()) {
653fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_None:
654fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_Special:
655fe98b2f5SDaniel Sanders       llvm_unreachable("Unhandled fixup kind!");
656fe98b2f5SDaniel Sanders       break;
657fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_CALL_HI16:
658fe98b2f5SDaniel Sanders       FixupKind = Mips::fixup_Mips_CALL_HI16;
659fe98b2f5SDaniel Sanders       break;
660fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_CALL_LO16:
661fe98b2f5SDaniel Sanders       FixupKind = Mips::fixup_Mips_CALL_LO16;
662fe98b2f5SDaniel Sanders       break;
663fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_DTPREL_HI:
664fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
665fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_DTPREL_HI;
666fe98b2f5SDaniel Sanders       break;
667fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_DTPREL_LO:
668fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
669fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_DTPREL_LO;
670fe98b2f5SDaniel Sanders       break;
671fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_GOTTPREL:
672*3979f438SSimon Atanasyan       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL
673*3979f438SSimon Atanasyan                                    : Mips::fixup_Mips_GOTTPREL;
674fe98b2f5SDaniel Sanders       break;
675fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_GOT:
676fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
677fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_GOT;
678fe98b2f5SDaniel Sanders       break;
679fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_GOT_CALL:
680fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
681fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_CALL16;
682fe98b2f5SDaniel Sanders       break;
683fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_GOT_DISP:
684fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
685fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_GOT_DISP;
686fe98b2f5SDaniel Sanders       break;
687fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_GOT_HI16:
688fe98b2f5SDaniel Sanders       FixupKind = Mips::fixup_Mips_GOT_HI16;
689fe98b2f5SDaniel Sanders       break;
690fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_GOT_LO16:
691fe98b2f5SDaniel Sanders       FixupKind = Mips::fixup_Mips_GOT_LO16;
692fe98b2f5SDaniel Sanders       break;
693fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_GOT_PAGE:
694fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
695fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_GOT_PAGE;
696fe98b2f5SDaniel Sanders       break;
697fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_GOT_OFST:
698fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
699fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_GOT_OFST;
700fe98b2f5SDaniel Sanders       break;
701fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_GPREL:
702fe98b2f5SDaniel Sanders       FixupKind = Mips::fixup_Mips_GPREL16;
703fe98b2f5SDaniel Sanders       break;
704926883e1SEugene Zelenko     case MipsMCExpr::MEK_LO:
705fe98b2f5SDaniel Sanders       // Check for %lo(%neg(%gp_rel(X)))
706fe98b2f5SDaniel Sanders       if (MipsExpr->isGpOff()) {
707fe98b2f5SDaniel Sanders         FixupKind = Mips::fixup_Mips_GPOFF_LO;
708fe98b2f5SDaniel Sanders         break;
709fe98b2f5SDaniel Sanders       }
710fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
711fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_LO16;
712fe98b2f5SDaniel Sanders       break;
713fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_HIGHEST:
71406c47803SSasa Stankovic       FixupKind = Mips::fixup_Mips_HIGHEST;
71506c47803SSasa Stankovic       break;
716fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_HIGHER:
71706c47803SSasa Stankovic       FixupKind = Mips::fixup_Mips_HIGHER;
71806c47803SSasa Stankovic       break;
719fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_HI:
720fe98b2f5SDaniel Sanders       // Check for %hi(%neg(%gp_rel(X)))
721fe98b2f5SDaniel Sanders       if (MipsExpr->isGpOff()) {
722fe98b2f5SDaniel Sanders         FixupKind = Mips::fixup_Mips_GPOFF_HI;
723fe98b2f5SDaniel Sanders         break;
724fe98b2f5SDaniel Sanders       }
725a5da588bSPetar Jovanovic       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
726a5da588bSPetar Jovanovic                                    : Mips::fixup_Mips_HI16;
727a5da588bSPetar Jovanovic       break;
728fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_PCREL_HI16:
729fe98b2f5SDaniel Sanders       FixupKind = Mips::fixup_MIPS_PCHI16;
730fe98b2f5SDaniel Sanders       break;
731fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_PCREL_LO16:
732fe98b2f5SDaniel Sanders       FixupKind = Mips::fixup_MIPS_PCLO16;
733fe98b2f5SDaniel Sanders       break;
734fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_TLSGD:
735fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
736fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_TLSGD;
737fe98b2f5SDaniel Sanders       break;
738fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_TLSLDM:
739fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
740fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_TLSLDM;
741fe98b2f5SDaniel Sanders       break;
742fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_TPREL_HI:
743fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
744fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_TPREL_HI;
745fe98b2f5SDaniel Sanders       break;
746fe98b2f5SDaniel Sanders     case MipsMCExpr::MEK_TPREL_LO:
747fe98b2f5SDaniel Sanders       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
748fe98b2f5SDaniel Sanders                                    : Mips::fixup_Mips_TPREL_LO;
749a5da588bSPetar Jovanovic       break;
7503feeb9c8SDaniel Sanders     case MipsMCExpr::MEK_NEG:
7513feeb9c8SDaniel Sanders       FixupKind =
7523feeb9c8SDaniel Sanders           isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB;
7533feeb9c8SDaniel Sanders       break;
754a5da588bSPetar Jovanovic     }
75563661f8dSJim Grosbach     Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind)));
756a5da588bSPetar Jovanovic     return 0;
757a5da588bSPetar Jovanovic   }
758a5da588bSPetar Jovanovic 
759b5cf5909SJack Carter   if (Kind == MCExpr::SymbolRef) {
760f9774c32SBill Wendling     Mips::Fixups FixupKind = Mips::Fixups(0);
761e2eed964SAkira Hatanaka 
762049e9e4dSAkira Hatanaka     switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
763b9f9de93SJack Carter     default: llvm_unreachable("Unknown fixup kind!");
76460f1db05SDaniel Sanders       break;
76560f1db05SDaniel Sanders     case MCSymbolRefExpr::VK_None:
76660f1db05SDaniel Sanders       FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
767b9f9de93SJack Carter       break;
768c85e3ff3SBruno Cardoso Lopes     } // switch
769fe384a2cSAkira Hatanaka 
77063661f8dSJim Grosbach     Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
771fe384a2cSAkira Hatanaka     return 0;
772c85e3ff3SBruno Cardoso Lopes   }
773b5cf5909SJack Carter   return 0;
774b5cf5909SJack Carter }
775b5cf5909SJack Carter 
776b5cf5909SJack Carter /// getMachineOpValue - Return binary encoding of operand. If the machine
777b5cf5909SJack Carter /// operand requires relocation, record the relocation and return zero.
778b5cf5909SJack Carter unsigned MipsMCCodeEmitter::
779b5cf5909SJack Carter getMachineOpValue(const MCInst &MI, const MCOperand &MO,
7803fa98a65SDavid Woodhouse                   SmallVectorImpl<MCFixup> &Fixups,
7813fa98a65SDavid Woodhouse                   const MCSubtargetInfo &STI) const {
782b5cf5909SJack Carter   if (MO.isReg()) {
783b5cf5909SJack Carter     unsigned Reg = MO.getReg();
784bc07a890SBill Wendling     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
785b5cf5909SJack Carter     return RegNo;
786b5cf5909SJack Carter   } else if (MO.isImm()) {
787b5cf5909SJack Carter     return static_cast<unsigned>(MO.getImm());
788b5cf5909SJack Carter   } else if (MO.isFPImm()) {
789b5cf5909SJack Carter     return static_cast<unsigned>(APFloat(MO.getFPImm())
790b5cf5909SJack Carter         .bitcastToAPInt().getHiBits(32).getLimitedValue());
791b5cf5909SJack Carter   }
792b5cf5909SJack Carter   // MO must be an Expr.
793b5cf5909SJack Carter   assert(MO.isExpr());
7943fa98a65SDavid Woodhouse   return getExprOpValue(MO.getExpr(),Fixups, STI);
795b5cf5909SJack Carter }
796c85e3ff3SBruno Cardoso Lopes 
797dc0602a2SDaniel Sanders /// Return binary encoding of memory related operand.
798c85e3ff3SBruno Cardoso Lopes /// If the offset operand requires relocation, record the relocation.
799dc0602a2SDaniel Sanders template <unsigned ShiftAmount>
800dc0602a2SDaniel Sanders unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
8013fa98a65SDavid Woodhouse                                            SmallVectorImpl<MCFixup> &Fixups,
8023fa98a65SDavid Woodhouse                                            const MCSubtargetInfo &STI) const {
803c85e3ff3SBruno Cardoso Lopes   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
804c85e3ff3SBruno Cardoso Lopes   assert(MI.getOperand(OpNo).isReg());
8053fa98a65SDavid Woodhouse   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
8063fa98a65SDavid Woodhouse   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
807c85e3ff3SBruno Cardoso Lopes 
808dc0602a2SDaniel Sanders   // Apply the scale factor if there is one.
809dc0602a2SDaniel Sanders   OffBits >>= ShiftAmount;
810dc0602a2SDaniel Sanders 
811c85e3ff3SBruno Cardoso Lopes   return (OffBits & 0xFFFF) | RegBits;
812c85e3ff3SBruno Cardoso Lopes }
813c85e3ff3SBruno Cardoso Lopes 
81497700977SJack Carter unsigned MipsMCCodeEmitter::
815e8c9d1eaSJozef Kolek getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
816e8c9d1eaSJozef Kolek                      SmallVectorImpl<MCFixup> &Fixups,
817e8c9d1eaSJozef Kolek                      const MCSubtargetInfo &STI) const {
818e8c9d1eaSJozef Kolek   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
819e8c9d1eaSJozef Kolek   assert(MI.getOperand(OpNo).isReg());
820e8c9d1eaSJozef Kolek   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
821e8c9d1eaSJozef Kolek                                        Fixups, STI) << 4;
822e8c9d1eaSJozef Kolek   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
823e8c9d1eaSJozef Kolek                                        Fixups, STI);
824e8c9d1eaSJozef Kolek 
825e8c9d1eaSJozef Kolek   return (OffBits & 0xF) | RegBits;
826e8c9d1eaSJozef Kolek }
827e8c9d1eaSJozef Kolek 
828e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter::
829e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
830e8c9d1eaSJozef Kolek                          SmallVectorImpl<MCFixup> &Fixups,
831e8c9d1eaSJozef Kolek                          const MCSubtargetInfo &STI) const {
832e8c9d1eaSJozef Kolek   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
833e8c9d1eaSJozef Kolek   assert(MI.getOperand(OpNo).isReg());
834e8c9d1eaSJozef Kolek   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
835e8c9d1eaSJozef Kolek                                        Fixups, STI) << 4;
836e8c9d1eaSJozef Kolek   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
837e8c9d1eaSJozef Kolek                                        Fixups, STI) >> 1;
838e8c9d1eaSJozef Kolek 
839e8c9d1eaSJozef Kolek   return (OffBits & 0xF) | RegBits;
840e8c9d1eaSJozef Kolek }
841e8c9d1eaSJozef Kolek 
842e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter::
843e8c9d1eaSJozef Kolek getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
844e8c9d1eaSJozef Kolek                          SmallVectorImpl<MCFixup> &Fixups,
845e8c9d1eaSJozef Kolek                          const MCSubtargetInfo &STI) const {
846e8c9d1eaSJozef Kolek   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
847e8c9d1eaSJozef Kolek   assert(MI.getOperand(OpNo).isReg());
848e8c9d1eaSJozef Kolek   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
849e8c9d1eaSJozef Kolek                                        Fixups, STI) << 4;
850e8c9d1eaSJozef Kolek   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
851e8c9d1eaSJozef Kolek                                        Fixups, STI) >> 2;
852e8c9d1eaSJozef Kolek 
853e8c9d1eaSJozef Kolek   return (OffBits & 0xF) | RegBits;
854e8c9d1eaSJozef Kolek }
855e8c9d1eaSJozef Kolek 
856e8c9d1eaSJozef Kolek unsigned MipsMCCodeEmitter::
85712c6982bSJozef Kolek getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
85812c6982bSJozef Kolek                            SmallVectorImpl<MCFixup> &Fixups,
85912c6982bSJozef Kolek                            const MCSubtargetInfo &STI) const {
86012c6982bSJozef Kolek   // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
86112c6982bSJozef Kolek   assert(MI.getOperand(OpNo).isReg() &&
86268be5f21SZoran Jovanovic          (MI.getOperand(OpNo).getReg() == Mips::SP ||
86368be5f21SZoran Jovanovic          MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
86412c6982bSJozef Kolek          "Unexpected base register!");
86512c6982bSJozef Kolek   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
86612c6982bSJozef Kolek                                        Fixups, STI) >> 2;
86712c6982bSJozef Kolek 
86812c6982bSJozef Kolek   return OffBits & 0x1F;
86912c6982bSJozef Kolek }
87012c6982bSJozef Kolek 
87112c6982bSJozef Kolek unsigned MipsMCCodeEmitter::
872e10a02ecSJozef Kolek getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
873e10a02ecSJozef Kolek                            SmallVectorImpl<MCFixup> &Fixups,
874e10a02ecSJozef Kolek                            const MCSubtargetInfo &STI) const {
875e10a02ecSJozef Kolek   // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
876e10a02ecSJozef Kolek   assert(MI.getOperand(OpNo).isReg() &&
877e10a02ecSJozef Kolek          MI.getOperand(OpNo).getReg() == Mips::GP &&
878e10a02ecSJozef Kolek          "Unexpected base register!");
879e10a02ecSJozef Kolek 
880e10a02ecSJozef Kolek   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
881e10a02ecSJozef Kolek                                        Fixups, STI) >> 2;
882e10a02ecSJozef Kolek 
883e10a02ecSJozef Kolek   return OffBits & 0x7F;
884e10a02ecSJozef Kolek }
885e10a02ecSJozef Kolek 
8869eaa30d2SZoran Jovanovic unsigned MipsMCCodeEmitter::
8879eaa30d2SZoran Jovanovic getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
8889eaa30d2SZoran Jovanovic                      SmallVectorImpl<MCFixup> &Fixups,
8899eaa30d2SZoran Jovanovic                      const MCSubtargetInfo &STI) const {
8909eaa30d2SZoran Jovanovic   // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
8919eaa30d2SZoran Jovanovic   assert(MI.getOperand(OpNo).isReg());
8929eaa30d2SZoran Jovanovic   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
8939eaa30d2SZoran Jovanovic                                        STI) << 16;
8949eaa30d2SZoran Jovanovic   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
8959eaa30d2SZoran Jovanovic 
8969eaa30d2SZoran Jovanovic   return (OffBits & 0x1FF) | RegBits;
8979eaa30d2SZoran Jovanovic }
8989eaa30d2SZoran Jovanovic 
899e10a02ecSJozef Kolek unsigned MipsMCCodeEmitter::
900cba9f80bSZlatko Buljan getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo,
901cba9f80bSZlatko Buljan                       SmallVectorImpl<MCFixup> &Fixups,
902cba9f80bSZlatko Buljan                       const MCSubtargetInfo &STI) const {
903cba9f80bSZlatko Buljan   // Base register is encoded in bits 20-16, offset is encoded in bits 10-0.
904cba9f80bSZlatko Buljan   assert(MI.getOperand(OpNo).isReg());
905cba9f80bSZlatko Buljan   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
906cba9f80bSZlatko Buljan                                        STI) << 16;
907cba9f80bSZlatko Buljan   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
908cba9f80bSZlatko Buljan 
909cba9f80bSZlatko Buljan   return (OffBits & 0x07FF) | RegBits;
910cba9f80bSZlatko Buljan }
911cba9f80bSZlatko Buljan 
912cba9f80bSZlatko Buljan unsigned MipsMCCodeEmitter::
91397700977SJack Carter getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
9143fa98a65SDavid Woodhouse                       SmallVectorImpl<MCFixup> &Fixups,
9153fa98a65SDavid Woodhouse                       const MCSubtargetInfo &STI) const {
916a4c4b5fcSZoran Jovanovic   // opNum can be invalid if instruction had reglist as operand.
917a4c4b5fcSZoran Jovanovic   // MemOperand is always last operand of instruction (base + offset).
918a4c4b5fcSZoran Jovanovic   switch (MI.getOpcode()) {
919a4c4b5fcSZoran Jovanovic   default:
920a4c4b5fcSZoran Jovanovic     break;
921a4c4b5fcSZoran Jovanovic   case Mips::SWM32_MM:
922a4c4b5fcSZoran Jovanovic   case Mips::LWM32_MM:
923a4c4b5fcSZoran Jovanovic     OpNo = MI.getNumOperands() - 2;
924a4c4b5fcSZoran Jovanovic     break;
925a4c4b5fcSZoran Jovanovic   }
926a4c4b5fcSZoran Jovanovic 
92797700977SJack Carter   // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
92897700977SJack Carter   assert(MI.getOperand(OpNo).isReg());
9293fa98a65SDavid Woodhouse   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
9303fa98a65SDavid Woodhouse   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
93197700977SJack Carter 
93297700977SJack Carter   return (OffBits & 0x0FFF) | RegBits;
9333c88fbd3SHrvoje Varga }
9343c88fbd3SHrvoje Varga 
9353c88fbd3SHrvoje Varga unsigned MipsMCCodeEmitter::
9363c88fbd3SHrvoje Varga getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
9373c88fbd3SHrvoje Varga                       SmallVectorImpl<MCFixup> &Fixups,
9383c88fbd3SHrvoje Varga                       const MCSubtargetInfo &STI) const {
9393c88fbd3SHrvoje Varga   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
9403c88fbd3SHrvoje Varga   assert(MI.getOperand(OpNo).isReg());
9413c88fbd3SHrvoje Varga   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
9423c88fbd3SHrvoje Varga                                        STI) << 16;
9433c88fbd3SHrvoje Varga   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
9443c88fbd3SHrvoje Varga 
9453c88fbd3SHrvoje Varga   return (OffBits & 0xFFFF) | RegBits;
94697700977SJack Carter }
94797700977SJack Carter 
948f9a02500SZoran Jovanovic unsigned MipsMCCodeEmitter::
949f9a02500SZoran Jovanovic getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
950f9a02500SZoran Jovanovic                        SmallVectorImpl<MCFixup> &Fixups,
951f9a02500SZoran Jovanovic                        const MCSubtargetInfo &STI) const {
952f9a02500SZoran Jovanovic   // opNum can be invalid if instruction had reglist as operand
953f9a02500SZoran Jovanovic   // MemOperand is always last operand of instruction (base + offset)
954f9a02500SZoran Jovanovic   switch (MI.getOpcode()) {
955f9a02500SZoran Jovanovic   default:
956f9a02500SZoran Jovanovic     break;
957f9a02500SZoran Jovanovic   case Mips::SWM16_MM:
958797c2aecSZlatko Buljan   case Mips::SWM16_MMR6:
959f9a02500SZoran Jovanovic   case Mips::LWM16_MM:
960797c2aecSZlatko Buljan   case Mips::LWM16_MMR6:
961f9a02500SZoran Jovanovic     OpNo = MI.getNumOperands() - 2;
962f9a02500SZoran Jovanovic     break;
963f9a02500SZoran Jovanovic   }
964f9a02500SZoran Jovanovic 
965f9a02500SZoran Jovanovic   // Offset is encoded in bits 4-0.
966f9a02500SZoran Jovanovic   assert(MI.getOperand(OpNo).isReg());
967f9a02500SZoran Jovanovic   // Base register is always SP - thus it is not encoded.
968f9a02500SZoran Jovanovic   assert(MI.getOperand(OpNo+1).isImm());
969f9a02500SZoran Jovanovic   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
970f9a02500SZoran Jovanovic 
971f9a02500SZoran Jovanovic   return ((OffBits >> 2) & 0x0F);
972f9a02500SZoran Jovanovic }
973f9a02500SZoran Jovanovic 
974049e9e4dSAkira Hatanaka // FIXME: should be called getMSBEncoding
975049e9e4dSAkira Hatanaka //
976c85e3ff3SBruno Cardoso Lopes unsigned
977c85e3ff3SBruno Cardoso Lopes MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
9783fa98a65SDavid Woodhouse                                       SmallVectorImpl<MCFixup> &Fixups,
9793fa98a65SDavid Woodhouse                                       const MCSubtargetInfo &STI) const {
980049e9e4dSAkira Hatanaka   assert(MI.getOperand(OpNo-1).isImm());
981049e9e4dSAkira Hatanaka   assert(MI.getOperand(OpNo).isImm());
9823fa98a65SDavid Woodhouse   unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
9833fa98a65SDavid Woodhouse   unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
984049e9e4dSAkira Hatanaka 
98556b70de0SBruno Cardoso Lopes   return Position + Size - 1;
986c85e3ff3SBruno Cardoso Lopes }
987c85e3ff3SBruno Cardoso Lopes 
988ea4f653dSDaniel Sanders template <unsigned Bits, int Offset>
989779c5937SMatheus Almeida unsigned
990ea4f653dSDaniel Sanders MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
9913fa98a65SDavid Woodhouse                                              SmallVectorImpl<MCFixup> &Fixups,
9923fa98a65SDavid Woodhouse                                              const MCSubtargetInfo &STI) const {
993779c5937SMatheus Almeida   assert(MI.getOperand(OpNo).isImm());
994ea4f653dSDaniel Sanders   unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
995ea4f653dSDaniel Sanders   Value -= Offset;
996ea4f653dSDaniel Sanders   return Value;
997779c5937SMatheus Almeida }
998779c5937SMatheus Almeida 
999b59e1a41SDaniel Sanders unsigned
1000b59e1a41SDaniel Sanders MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
1001b59e1a41SDaniel Sanders                                          SmallVectorImpl<MCFixup> &Fixups,
1002b59e1a41SDaniel Sanders                                          const MCSubtargetInfo &STI) const {
1003b9c07f3bSZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
1004b9c07f3bSZoran Jovanovic   if (MO.isImm()) {
1005b59e1a41SDaniel Sanders     // The immediate is encoded as 'immediate << 2'.
1006b9c07f3bSZoran Jovanovic     unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
1007b59e1a41SDaniel Sanders     assert((Res & 3) == 0);
1008b59e1a41SDaniel Sanders     return Res >> 2;
1009b59e1a41SDaniel Sanders   }
1010c85e3ff3SBruno Cardoso Lopes 
1011b9c07f3bSZoran Jovanovic   assert(MO.isExpr() &&
1012b9c07f3bSZoran Jovanovic          "getSimm19Lsl2Encoding expects only expressions or an immediate");
1013b9c07f3bSZoran Jovanovic 
1014b9c07f3bSZoran Jovanovic   const MCExpr *Expr = MO.getExpr();
10156764fa78SZoran Jovanovic   Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2
10166764fa78SZoran Jovanovic                                             : Mips::fixup_MIPS_PC19_S2;
10176764fa78SZoran Jovanovic   Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
1018b9c07f3bSZoran Jovanovic   return 0;
1019b9c07f3bSZoran Jovanovic }
1020b9c07f3bSZoran Jovanovic 
10212855142aSZoran Jovanovic unsigned
10222855142aSZoran Jovanovic MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
10232855142aSZoran Jovanovic                                          SmallVectorImpl<MCFixup> &Fixups,
10242855142aSZoran Jovanovic                                          const MCSubtargetInfo &STI) const {
1025a5acdcf9SZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
1026a5acdcf9SZoran Jovanovic   if (MO.isImm()) {
10272855142aSZoran Jovanovic     // The immediate is encoded as 'immediate << 3'.
10282855142aSZoran Jovanovic     unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
10292855142aSZoran Jovanovic     assert((Res & 7) == 0);
10302855142aSZoran Jovanovic     return Res >> 3;
10312855142aSZoran Jovanovic   }
10322855142aSZoran Jovanovic 
1033a5acdcf9SZoran Jovanovic   assert(MO.isExpr() &&
1034a5acdcf9SZoran Jovanovic          "getSimm18Lsl2Encoding expects only expressions or an immediate");
1035a5acdcf9SZoran Jovanovic 
1036a5acdcf9SZoran Jovanovic   const MCExpr *Expr = MO.getExpr();
10378e366822SZoran Jovanovic   Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3
10388e366822SZoran Jovanovic                                             : Mips::fixup_MIPS_PC18_S3;
10398e366822SZoran Jovanovic   Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
1040a5acdcf9SZoran Jovanovic   return 0;
1041a5acdcf9SZoran Jovanovic }
1042a5acdcf9SZoran Jovanovic 
10434a00fdc2SZoran Jovanovic unsigned
10444a00fdc2SZoran Jovanovic MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
10454a00fdc2SZoran Jovanovic                                         SmallVectorImpl<MCFixup> &Fixups,
10464a00fdc2SZoran Jovanovic                                         const MCSubtargetInfo &STI) const {
10474a00fdc2SZoran Jovanovic   assert(MI.getOperand(OpNo).isImm());
10484a00fdc2SZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
10494a00fdc2SZoran Jovanovic   return MO.getImm() % 8;
10504a00fdc2SZoran Jovanovic }
10514a00fdc2SZoran Jovanovic 
10528853171bSZoran Jovanovic unsigned
10538853171bSZoran Jovanovic MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
10548853171bSZoran Jovanovic                                     SmallVectorImpl<MCFixup> &Fixups,
10558853171bSZoran Jovanovic                                     const MCSubtargetInfo &STI) const {
10568853171bSZoran Jovanovic   assert(MI.getOperand(OpNo).isImm());
10578853171bSZoran Jovanovic   const MCOperand &MO = MI.getOperand(OpNo);
10588853171bSZoran Jovanovic   unsigned Value = MO.getImm();
10598853171bSZoran Jovanovic   switch (Value) {
10608853171bSZoran Jovanovic     case 128:   return 0x0;
10618853171bSZoran Jovanovic     case 1:     return 0x1;
10628853171bSZoran Jovanovic     case 2:     return 0x2;
10638853171bSZoran Jovanovic     case 3:     return 0x3;
10648853171bSZoran Jovanovic     case 4:     return 0x4;
10658853171bSZoran Jovanovic     case 7:     return 0x5;
10668853171bSZoran Jovanovic     case 8:     return 0x6;
10678853171bSZoran Jovanovic     case 15:    return 0x7;
10688853171bSZoran Jovanovic     case 16:    return 0x8;
10698853171bSZoran Jovanovic     case 31:    return 0x9;
10708853171bSZoran Jovanovic     case 32:    return 0xa;
10718853171bSZoran Jovanovic     case 63:    return 0xb;
10728853171bSZoran Jovanovic     case 64:    return 0xc;
10738853171bSZoran Jovanovic     case 255:   return 0xd;
10748853171bSZoran Jovanovic     case 32768: return 0xe;
10758853171bSZoran Jovanovic     case 65535: return 0xf;
10768853171bSZoran Jovanovic   }
10778853171bSZoran Jovanovic   llvm_unreachable("Unexpected value");
10788853171bSZoran Jovanovic }
10798853171bSZoran Jovanovic 
1080a4c4b5fcSZoran Jovanovic unsigned
1081a4c4b5fcSZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
1082a4c4b5fcSZoran Jovanovic                                           SmallVectorImpl<MCFixup> &Fixups,
1083a4c4b5fcSZoran Jovanovic                                           const MCSubtargetInfo &STI) const {
1084a4c4b5fcSZoran Jovanovic   unsigned res = 0;
1085a4c4b5fcSZoran Jovanovic 
1086a4c4b5fcSZoran Jovanovic   // Register list operand is always first operand of instruction and it is
1087a4c4b5fcSZoran Jovanovic   // placed before memory operand (register + imm).
1088a4c4b5fcSZoran Jovanovic 
1089a4c4b5fcSZoran Jovanovic   for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
1090a4c4b5fcSZoran Jovanovic     unsigned Reg = MI.getOperand(I).getReg();
1091a4c4b5fcSZoran Jovanovic     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
1092a4c4b5fcSZoran Jovanovic     if (RegNo != 31)
1093a4c4b5fcSZoran Jovanovic       res++;
1094a4c4b5fcSZoran Jovanovic     else
1095a4c4b5fcSZoran Jovanovic       res |= 0x10;
1096a4c4b5fcSZoran Jovanovic   }
1097a4c4b5fcSZoran Jovanovic   return res;
1098a4c4b5fcSZoran Jovanovic }
1099a4c4b5fcSZoran Jovanovic 
1100f9a02500SZoran Jovanovic unsigned
1101f9a02500SZoran Jovanovic MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
1102f9a02500SZoran Jovanovic                                             SmallVectorImpl<MCFixup> &Fixups,
1103f9a02500SZoran Jovanovic                                             const MCSubtargetInfo &STI) const {
1104f9a02500SZoran Jovanovic   return (MI.getNumOperands() - 4);
1105f9a02500SZoran Jovanovic }
1106f9a02500SZoran Jovanovic 
11072deca348SZoran Jovanovic unsigned
11082deca348SZoran Jovanovic MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
11092deca348SZoran Jovanovic                                           SmallVectorImpl<MCFixup> &Fixups,
11102deca348SZoran Jovanovic                                           const MCSubtargetInfo &STI) const {
11112deca348SZoran Jovanovic   return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
11122deca348SZoran Jovanovic }
11132deca348SZoran Jovanovic 
11142c6d7320SJozef Kolek unsigned
111541688679SZoran Jovanovic MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
111641688679SZoran Jovanovic                                           SmallVectorImpl<MCFixup> &Fixups,
111741688679SZoran Jovanovic                                           const MCSubtargetInfo &STI) const {
111841688679SZoran Jovanovic   unsigned res = 0;
111941688679SZoran Jovanovic 
112041688679SZoran Jovanovic   if (MI.getOperand(0).getReg() == Mips::A1 &&
112141688679SZoran Jovanovic       MI.getOperand(1).getReg() == Mips::A2)
112241688679SZoran Jovanovic     res = 0;
112341688679SZoran Jovanovic   else if (MI.getOperand(0).getReg() == Mips::A1 &&
112441688679SZoran Jovanovic            MI.getOperand(1).getReg() == Mips::A3)
112541688679SZoran Jovanovic     res = 1;
112641688679SZoran Jovanovic   else if (MI.getOperand(0).getReg() == Mips::A2 &&
112741688679SZoran Jovanovic            MI.getOperand(1).getReg() == Mips::A3)
112841688679SZoran Jovanovic     res = 2;
112941688679SZoran Jovanovic   else if (MI.getOperand(0).getReg() == Mips::A0 &&
113041688679SZoran Jovanovic            MI.getOperand(1).getReg() == Mips::S5)
113141688679SZoran Jovanovic     res = 3;
113241688679SZoran Jovanovic   else if (MI.getOperand(0).getReg() == Mips::A0 &&
113341688679SZoran Jovanovic            MI.getOperand(1).getReg() == Mips::S6)
113441688679SZoran Jovanovic     res = 4;
113541688679SZoran Jovanovic   else if (MI.getOperand(0).getReg() == Mips::A0 &&
113641688679SZoran Jovanovic            MI.getOperand(1).getReg() == Mips::A1)
113741688679SZoran Jovanovic     res = 5;
113841688679SZoran Jovanovic   else if (MI.getOperand(0).getReg() == Mips::A0 &&
113941688679SZoran Jovanovic            MI.getOperand(1).getReg() == Mips::A2)
114041688679SZoran Jovanovic     res = 6;
114141688679SZoran Jovanovic   else if (MI.getOperand(0).getReg() == Mips::A0 &&
114241688679SZoran Jovanovic            MI.getOperand(1).getReg() == Mips::A3)
114341688679SZoran Jovanovic     res = 7;
114441688679SZoran Jovanovic 
114541688679SZoran Jovanovic   return res;
114641688679SZoran Jovanovic }
114741688679SZoran Jovanovic 
114841688679SZoran Jovanovic unsigned
11492c6d7320SJozef Kolek MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
11502c6d7320SJozef Kolek                                          SmallVectorImpl<MCFixup> &Fixups,
11512c6d7320SJozef Kolek                                          const MCSubtargetInfo &STI) const {
11522c6d7320SJozef Kolek   const MCOperand &MO = MI.getOperand(OpNo);
11532c6d7320SJozef Kolek   assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
11542c6d7320SJozef Kolek   // The immediate is encoded as 'immediate >> 2'.
11552c6d7320SJozef Kolek   unsigned Res = static_cast<unsigned>(MO.getImm());
11562c6d7320SJozef Kolek   assert((Res & 3) == 0);
11572c6d7320SJozef Kolek   return Res >> 2;
11582c6d7320SJozef Kolek }
11592c6d7320SJozef Kolek 
1160b59e1a41SDaniel Sanders #include "MipsGenMCCodeEmitter.inc"
1161