blob: bc1e5fa1346e99abedcc2b45e0ee17c61bc0a440 [file] [log] [blame]
Jia Liu9f610112012-02-17 08:55:11 +00001//===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
Akira Hatanaka750ecec2011-09-30 20:40:03 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the MipsMCCodeEmitter class.
11//
12//===----------------------------------------------------------------------===//
13//
Matheus Almeida9e1450b2014-03-20 09:29:54 +000014
Matheus Almeida9e1450b2014-03-20 09:29:54 +000015#include "MipsMCCodeEmitter.h"
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +000016#include "MCTargetDesc/MipsFixupKinds.h"
Petar Jovanovica5da5882014-02-04 18:41:57 +000017#include "MCTargetDesc/MipsMCExpr.h"
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +000018#include "MCTargetDesc/MipsMCTargetDesc.h"
19#include "llvm/ADT/APFloat.h"
Matheus Almeida9e1450b2014-03-20 09:29:54 +000020#include "llvm/ADT/SmallVector.h"
Akira Hatanaka5d6faed2012-12-10 20:04:40 +000021#include "llvm/MC/MCContext.h"
Akira Hatanaka750ecec2011-09-30 20:40:03 +000022#include "llvm/MC/MCExpr.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000023#include "llvm/MC/MCFixup.h"
Akira Hatanaka750ecec2011-09-30 20:40:03 +000024#include "llvm/MC/MCInst.h"
25#include "llvm/MC/MCInstrInfo.h"
Akira Hatanaka750ecec2011-09-30 20:40:03 +000026#include "llvm/MC/MCSubtargetInfo.h"
Akira Hatanaka750ecec2011-09-30 20:40:03 +000027#include "llvm/Support/raw_ostream.h"
Akira Hatanaka750ecec2011-09-30 20:40:03 +000028
Chandler Carruth84e68b22014-04-22 02:41:26 +000029#define DEBUG_TYPE "mccodeemitter"
30
Akira Hatanakabe6a8182013-04-19 19:03:11 +000031#define GET_INSTRMAP_INFO
32#include "MipsGenInstrInfo.inc"
Matheus Almeida9e1450b2014-03-20 09:29:54 +000033#undef GET_INSTRMAP_INFO
Akira Hatanakabe6a8182013-04-19 19:03:11 +000034
Matheus Almeida9e1450b2014-03-20 09:29:54 +000035namespace llvm {
36MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
37 const MCRegisterInfo &MRI,
Matheus Almeida9e1450b2014-03-20 09:29:54 +000038 MCContext &Ctx) {
David Woodhoused2cca112014-01-28 23:13:25 +000039 return new MipsMCCodeEmitter(MCII, Ctx, false);
Akira Hatanaka1ee768d2012-03-01 01:53:15 +000040}
41
Matheus Almeida9e1450b2014-03-20 09:29:54 +000042MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
43 const MCRegisterInfo &MRI,
Matheus Almeida9e1450b2014-03-20 09:29:54 +000044 MCContext &Ctx) {
David Woodhoused2cca112014-01-28 23:13:25 +000045 return new MipsMCCodeEmitter(MCII, Ctx, true);
Akira Hatanaka750ecec2011-09-30 20:40:03 +000046}
Matheus Almeida9e1450b2014-03-20 09:29:54 +000047} // End of namespace llvm.
Rafael Espindolaf30f2cc2013-05-27 22:34:59 +000048
49// If the D<shift> instruction has a shift amount that is greater
50// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
51static void LowerLargeShift(MCInst& Inst) {
52
53 assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
54 assert(Inst.getOperand(2).isImm());
55
56 int64_t Shift = Inst.getOperand(2).getImm();
57 if (Shift <= 31)
58 return; // Do nothing
59 Shift -= 32;
60
61 // saminus32
62 Inst.getOperand(2).setImm(Shift);
63
64 switch (Inst.getOpcode()) {
65 default:
66 // Calling function is not synchronized
67 llvm_unreachable("Unexpected shift instruction");
68 case Mips::DSLL:
69 Inst.setOpcode(Mips::DSLL32);
70 return;
71 case Mips::DSRL:
72 Inst.setOpcode(Mips::DSRL32);
73 return;
74 case Mips::DSRA:
75 Inst.setOpcode(Mips::DSRA32);
76 return;
Akira Hatanaka6a3fe572013-09-07 00:18:01 +000077 case Mips::DROTR:
78 Inst.setOpcode(Mips::DROTR32);
79 return;
Rafael Espindolaf30f2cc2013-05-27 22:34:59 +000080 }
81}
82
83// Pick a DEXT or DINS instruction variant based on the pos and size operands
84static void LowerDextDins(MCInst& InstIn) {
85 int Opcode = InstIn.getOpcode();
86
87 if (Opcode == Mips::DEXT)
88 assert(InstIn.getNumOperands() == 4 &&
89 "Invalid no. of machine operands for DEXT!");
90 else // Only DEXT and DINS are possible
91 assert(InstIn.getNumOperands() == 5 &&
92 "Invalid no. of machine operands for DINS!");
93
94 assert(InstIn.getOperand(2).isImm());
95 int64_t pos = InstIn.getOperand(2).getImm();
96 assert(InstIn.getOperand(3).isImm());
97 int64_t size = InstIn.getOperand(3).getImm();
98
99 if (size <= 32) {
100 if (pos < 32) // DEXT/DINS, do nothing
101 return;
102 // DEXTU/DINSU
103 InstIn.getOperand(2).setImm(pos - 32);
104 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
105 return;
106 }
107 // DEXTM/DINSM
108 assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
109 InstIn.getOperand(3).setImm(size - 32);
110 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
111 return;
112}
113
Matheus Almeida9e1450b2014-03-20 09:29:54 +0000114bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
Michael Kuperstein29704e72015-03-24 12:56:59 +0000115 return STI.getFeatureBits() & Mips::FeatureMicroMips;
Matheus Almeida9e1450b2014-03-20 09:29:54 +0000116}
117
Jozef Kolekc22555d2015-04-20 12:23:06 +0000118bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const {
119 return STI.getFeatureBits() & Mips::FeatureMips32r6;
120}
121
Matheus Almeida9e1450b2014-03-20 09:29:54 +0000122void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
123 OS << (char)C;
124}
125
126void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
127 const MCSubtargetInfo &STI,
128 raw_ostream &OS) const {
129 // Output the instruction encoding in little endian byte order.
130 // Little-endian byte ordering:
131 // mips32r2: 4 | 3 | 2 | 1
132 // microMIPS: 2 | 1 | 4 | 3
133 if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
134 EmitInstruction(Val >> 16, 2, STI, OS);
135 EmitInstruction(Val, 2, STI, OS);
136 } else {
137 for (unsigned i = 0; i < Size; ++i) {
138 unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
139 EmitByte((Val >> Shift) & 0xff, OS);
140 }
141 }
142}
143
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000144/// EncodeInstruction - Emit the instruction.
Jack Carter4e07b95d2013-08-27 19:45:28 +0000145/// Size the instruction with Desc.getSize().
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000146void MipsMCCodeEmitter::
147EncodeInstruction(const MCInst &MI, raw_ostream &OS,
David Woodhouse9784cef2014-01-28 23:13:07 +0000148 SmallVectorImpl<MCFixup> &Fixups,
149 const MCSubtargetInfo &STI) const
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000150{
Jack Carteraa7aeaa2012-10-02 23:09:40 +0000151
152 // Non-pseudo instructions that get changed for direct object
153 // only based on operand values.
154 // If this list of instructions get much longer we will move
155 // the check to a function call. Until then, this is more efficient.
156 MCInst TmpInst = MI;
157 switch (MI.getOpcode()) {
158 // If shift amount is >= 32 it the inst needs to be lowered further
159 case Mips::DSLL:
160 case Mips::DSRL:
161 case Mips::DSRA:
Akira Hatanaka6a3fe572013-09-07 00:18:01 +0000162 case Mips::DROTR:
Rafael Espindolaf30f2cc2013-05-27 22:34:59 +0000163 LowerLargeShift(TmpInst);
Jack Carteraa7aeaa2012-10-02 23:09:40 +0000164 break;
165 // Double extract instruction is chosen by pos and size operands
166 case Mips::DEXT:
167 case Mips::DINS:
Rafael Espindolaf30f2cc2013-05-27 22:34:59 +0000168 LowerDextDins(TmpInst);
Jack Carteraa7aeaa2012-10-02 23:09:40 +0000169 }
170
Jack Carter97700972013-08-13 20:19:16 +0000171 unsigned long N = Fixups.size();
David Woodhouse3fa98a62014-01-28 23:13:18 +0000172 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000173
174 // Check for unimplemented opcodes.
Jack Carteraa7aeaa2012-10-02 23:09:40 +0000175 // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000176 // so we have to special check for them.
Jack Carteraa7aeaa2012-10-02 23:09:40 +0000177 unsigned Opcode = TmpInst.getOpcode();
Jozef Kolekc7e220f2014-11-29 13:29:24 +0000178 if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) &&
179 (Opcode != Mips::SLL_MM) && !Binary)
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000180 llvm_unreachable("unimplemented opcode in EncodeInstruction()");
181
Michael Kuperstein29704e72015-03-24 12:56:59 +0000182 if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
Akira Hatanakabe6a8182013-04-19 19:03:11 +0000183 int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips);
184 if (NewOpcode != -1) {
Jack Carter97700972013-08-13 20:19:16 +0000185 if (Fixups.size() > N)
186 Fixups.pop_back();
Akira Hatanakabe6a8182013-04-19 19:03:11 +0000187 Opcode = NewOpcode;
188 TmpInst.setOpcode (NewOpcode);
David Woodhouse3fa98a62014-01-28 23:13:18 +0000189 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
Akira Hatanakabe6a8182013-04-19 19:03:11 +0000190 }
191 }
192
Jack Carteraa7aeaa2012-10-02 23:09:40 +0000193 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000194
Jack Carter5b5559d2012-10-03 21:58:54 +0000195 // Get byte count of instruction
196 unsigned Size = Desc.getSize();
197 if (!Size)
198 llvm_unreachable("Desc.getSize() returns 0");
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000199
David Woodhoused2cca112014-01-28 23:13:25 +0000200 EmitInstruction(Binary, Size, STI, OS);
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000201}
202
203/// getBranchTargetOpValue - Return binary encoding of the branch
204/// target operand. If the machine operand requires relocation,
205/// record the relocation and return zero.
206unsigned MipsMCCodeEmitter::
207getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000208 SmallVectorImpl<MCFixup> &Fixups,
209 const MCSubtargetInfo &STI) const {
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000210
211 const MCOperand &MO = MI.getOperand(OpNo);
Jack Carter71e6a742012-09-06 00:43:26 +0000212
Jack Carter4f69a0f2013-03-22 00:29:10 +0000213 // If the destination is an immediate, divide by 4.
214 if (MO.isImm()) return MO.getImm() >> 2;
215
Jack Carter71e6a742012-09-06 00:43:26 +0000216 assert(MO.isExpr() &&
217 "getBranchTargetOpValue expects only expressions or immediates");
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000218
219 const MCExpr *Expr = MO.getExpr();
220 Fixups.push_back(MCFixup::Create(0, Expr,
221 MCFixupKind(Mips::fixup_Mips_PC16)));
222 return 0;
223}
224
Jozef Kolek9761e962015-01-12 12:03:34 +0000225/// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
226/// target operand. If the machine operand requires relocation,
227/// record the relocation and return zero.
228unsigned MipsMCCodeEmitter::
229getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
230 SmallVectorImpl<MCFixup> &Fixups,
231 const MCSubtargetInfo &STI) const {
232
233 const MCOperand &MO = MI.getOperand(OpNo);
234
235 // If the destination is an immediate, divide by 2.
236 if (MO.isImm()) return MO.getImm() >> 1;
237
238 assert(MO.isExpr() &&
239 "getBranchTargetOpValueMM expects only expressions or immediates");
240
241 const MCExpr *Expr = MO.getExpr();
242 Fixups.push_back(MCFixup::Create(0, Expr,
243 MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
244 return 0;
245}
246
Jozef Kolek5cfebdd2015-01-21 12:39:30 +0000247/// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
248/// 10-bit branch target operand. If the machine operand requires relocation,
249/// record the relocation and return zero.
250unsigned MipsMCCodeEmitter::
251getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
252 SmallVectorImpl<MCFixup> &Fixups,
253 const MCSubtargetInfo &STI) const {
254
255 const MCOperand &MO = MI.getOperand(OpNo);
256
257 // If the destination is an immediate, divide by 2.
258 if (MO.isImm()) return MO.getImm() >> 1;
259
260 assert(MO.isExpr() &&
261 "getBranchTargetOpValuePC10 expects only expressions or immediates");
262
263 const MCExpr *Expr = MO.getExpr();
264 Fixups.push_back(MCFixup::Create(0, Expr,
265 MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
266 return 0;
267}
268
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000269/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
270/// target operand. If the machine operand requires relocation,
271/// record the relocation and return zero.
272unsigned MipsMCCodeEmitter::
273getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000274 SmallVectorImpl<MCFixup> &Fixups,
275 const MCSubtargetInfo &STI) const {
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000276
277 const MCOperand &MO = MI.getOperand(OpNo);
278
279 // If the destination is an immediate, divide by 2.
280 if (MO.isImm()) return MO.getImm() >> 1;
281
282 assert(MO.isExpr() &&
283 "getBranchTargetOpValueMM expects only expressions or immediates");
284
285 const MCExpr *Expr = MO.getExpr();
286 Fixups.push_back(MCFixup::Create(0, Expr,
287 MCFixupKind(Mips::
288 fixup_MICROMIPS_PC16_S1)));
289 return 0;
290}
291
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000292/// getBranchTarget21OpValue - Return binary encoding of the branch
293/// target operand. If the machine operand requires relocation,
294/// record the relocation and return zero.
295unsigned MipsMCCodeEmitter::
296getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
297 SmallVectorImpl<MCFixup> &Fixups,
298 const MCSubtargetInfo &STI) const {
299
300 const MCOperand &MO = MI.getOperand(OpNo);
301
302 // If the destination is an immediate, divide by 4.
303 if (MO.isImm()) return MO.getImm() >> 2;
304
305 assert(MO.isExpr() &&
306 "getBranchTarget21OpValue expects only expressions or immediates");
307
Zoran Jovanovic10e06da2014-05-27 12:55:40 +0000308 const MCExpr *Expr = MO.getExpr();
309 Fixups.push_back(MCFixup::Create(0, Expr,
310 MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000311 return 0;
312}
313
314/// getBranchTarget26OpValue - Return binary encoding of the branch
315/// target operand. If the machine operand requires relocation,
316/// record the relocation and return zero.
317unsigned MipsMCCodeEmitter::
318getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
319 SmallVectorImpl<MCFixup> &Fixups,
320 const MCSubtargetInfo &STI) const {
321
322 const MCOperand &MO = MI.getOperand(OpNo);
323
324 // If the destination is an immediate, divide by 4.
325 if (MO.isImm()) return MO.getImm() >> 2;
326
327 assert(MO.isExpr() &&
328 "getBranchTarget26OpValue expects only expressions or immediates");
329
Zoran Jovanovic10e06da2014-05-27 12:55:40 +0000330 const MCExpr *Expr = MO.getExpr();
331 Fixups.push_back(MCFixup::Create(0, Expr,
332 MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000333 return 0;
334}
335
Zoran Jovanovic52c56b92014-05-16 13:19:46 +0000336/// getJumpOffset16OpValue - Return binary encoding of the jump
337/// target operand. If the machine operand requires relocation,
338/// record the relocation and return zero.
339unsigned MipsMCCodeEmitter::
340getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
341 SmallVectorImpl<MCFixup> &Fixups,
342 const MCSubtargetInfo &STI) const {
343
344 const MCOperand &MO = MI.getOperand(OpNo);
345
346 if (MO.isImm()) return MO.getImm();
347
348 assert(MO.isExpr() &&
349 "getJumpOffset16OpValue expects only expressions or an immediate");
350
351 // TODO: Push fixup.
352 return 0;
353}
354
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000355/// getJumpTargetOpValue - Return binary encoding of the jump
356/// target operand. If the machine operand requires relocation,
357/// record the relocation and return zero.
358unsigned MipsMCCodeEmitter::
359getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000360 SmallVectorImpl<MCFixup> &Fixups,
361 const MCSubtargetInfo &STI) const {
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000362
363 const MCOperand &MO = MI.getOperand(OpNo);
Jack Carter4f69a0f2013-03-22 00:29:10 +0000364 // If the destination is an immediate, divide by 4.
365 if (MO.isImm()) return MO.getImm()>>2;
366
Jack Carter71e6a742012-09-06 00:43:26 +0000367 assert(MO.isExpr() &&
368 "getJumpTargetOpValue expects only expressions or an immediate");
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000369
370 const MCExpr *Expr = MO.getExpr();
371 Fixups.push_back(MCFixup::Create(0, Expr,
372 MCFixupKind(Mips::fixup_Mips_26)));
373 return 0;
374}
375
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000376unsigned MipsMCCodeEmitter::
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000377getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000378 SmallVectorImpl<MCFixup> &Fixups,
379 const MCSubtargetInfo &STI) const {
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000380
381 const MCOperand &MO = MI.getOperand(OpNo);
382 // If the destination is an immediate, divide by 2.
383 if (MO.isImm()) return MO.getImm() >> 1;
384
385 assert(MO.isExpr() &&
386 "getJumpTargetOpValueMM expects only expressions or an immediate");
387
388 const MCExpr *Expr = MO.getExpr();
389 Fixups.push_back(MCFixup::Create(0, Expr,
390 MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
391 return 0;
392}
393
394unsigned MipsMCCodeEmitter::
Zoran Jovanovicc74e3eb92014-09-12 14:29:54 +0000395getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
396 SmallVectorImpl<MCFixup> &Fixups,
397 const MCSubtargetInfo &STI) const {
398
399 const MCOperand &MO = MI.getOperand(OpNo);
400 if (MO.isImm()) {
401 // The immediate is encoded as 'immediate << 2'.
402 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
403 assert((Res & 3) == 0);
404 return Res >> 2;
405 }
406
407 assert(MO.isExpr() &&
408 "getUImm5Lsl2Encoding expects only expressions or an immediate");
409
410 return 0;
411}
412
413unsigned MipsMCCodeEmitter::
Zoran Jovanovicbac36192014-10-23 11:06:34 +0000414getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo,
415 SmallVectorImpl<MCFixup> &Fixups,
416 const MCSubtargetInfo &STI) const {
417
418 const MCOperand &MO = MI.getOperand(OpNo);
419 if (MO.isImm()) {
420 int Value = MO.getImm();
421 return Value >> 2;
422 }
423
424 return 0;
425}
426
427unsigned MipsMCCodeEmitter::
Zoran Jovanovic42b84442014-10-23 11:13:59 +0000428getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
429 SmallVectorImpl<MCFixup> &Fixups,
430 const MCSubtargetInfo &STI) const {
431
432 const MCOperand &MO = MI.getOperand(OpNo);
433 if (MO.isImm()) {
434 unsigned Value = MO.getImm();
435 return Value >> 2;
436 }
437
438 return 0;
439}
440
441unsigned MipsMCCodeEmitter::
Zoran Jovanovic98bd58c2014-10-10 14:37:30 +0000442getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
443 SmallVectorImpl<MCFixup> &Fixups,
444 const MCSubtargetInfo &STI) const {
445
446 const MCOperand &MO = MI.getOperand(OpNo);
447 if (MO.isImm()) {
448 unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff;
449 return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
450 }
451
452 return 0;
453}
454
455unsigned MipsMCCodeEmitter::
Daniel Sanders60f1db02015-03-13 12:45:09 +0000456getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000457 const MCSubtargetInfo &STI) const {
Jack Carterb5cf5902013-04-17 00:18:04 +0000458 int64_t Res;
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000459
Jack Carterb5cf5902013-04-17 00:18:04 +0000460 if (Expr->EvaluateAsAbsolute(Res))
461 return Res;
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000462
Akira Hatanakafe384a22012-03-27 02:33:05 +0000463 MCExpr::ExprKind Kind = Expr->getKind();
Jack Carterb5cf5902013-04-17 00:18:04 +0000464 if (Kind == MCExpr::Constant) {
465 return cast<MCConstantExpr>(Expr)->getValue();
466 }
Akira Hatanakae2eed962011-12-22 01:05:17 +0000467
Akira Hatanakafe384a22012-03-27 02:33:05 +0000468 if (Kind == MCExpr::Binary) {
David Woodhouse3fa98a62014-01-28 23:13:18 +0000469 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
470 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
Jack Carterb5cf5902013-04-17 00:18:04 +0000471 return Res;
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000472 }
Petar Jovanovica5da5882014-02-04 18:41:57 +0000473
474 if (Kind == MCExpr::Target) {
475 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
476
477 Mips::Fixups FixupKind = Mips::Fixups(0);
478 switch (MipsExpr->getKind()) {
479 default: llvm_unreachable("Unsupported fixup kind for target expression!");
Sasa Stankovic06c47802014-04-03 10:37:45 +0000480 case MipsMCExpr::VK_Mips_HIGHEST:
481 FixupKind = Mips::fixup_Mips_HIGHEST;
482 break;
483 case MipsMCExpr::VK_Mips_HIGHER:
484 FixupKind = Mips::fixup_Mips_HIGHER;
485 break;
486 case MipsMCExpr::VK_Mips_HI:
Petar Jovanovica5da5882014-02-04 18:41:57 +0000487 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
488 : Mips::fixup_Mips_HI16;
489 break;
Sasa Stankovic06c47802014-04-03 10:37:45 +0000490 case MipsMCExpr::VK_Mips_LO:
Petar Jovanovica5da5882014-02-04 18:41:57 +0000491 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
492 : Mips::fixup_Mips_LO16;
493 break;
494 }
495 Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind)));
496 return 0;
497 }
498
Jack Carterb5cf5902013-04-17 00:18:04 +0000499 if (Kind == MCExpr::SymbolRef) {
Mark Seabornc3bd1772013-12-31 13:05:15 +0000500 Mips::Fixups FixupKind = Mips::Fixups(0);
Akira Hatanakafe384a22012-03-27 02:33:05 +0000501
Mark Seabornc3bd1772013-12-31 13:05:15 +0000502 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
503 default: llvm_unreachable("Unknown fixup kind!");
504 break;
Daniel Sanders60f1db02015-03-13 12:45:09 +0000505 case MCSymbolRefExpr::VK_None:
506 FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
507 break;
Mark Seabornc3bd1772013-12-31 13:05:15 +0000508 case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
509 FixupKind = Mips::fixup_Mips_GPOFF_HI;
510 break;
511 case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
512 FixupKind = Mips::fixup_Mips_GPOFF_LO;
513 break;
514 case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
David Woodhoused2cca112014-01-28 23:13:25 +0000515 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
Mark Seabornc3bd1772013-12-31 13:05:15 +0000516 : Mips::fixup_Mips_GOT_PAGE;
517 break;
518 case MCSymbolRefExpr::VK_Mips_GOT_OFST :
David Woodhoused2cca112014-01-28 23:13:25 +0000519 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
Mark Seabornc3bd1772013-12-31 13:05:15 +0000520 : Mips::fixup_Mips_GOT_OFST;
521 break;
522 case MCSymbolRefExpr::VK_Mips_GOT_DISP :
David Woodhoused2cca112014-01-28 23:13:25 +0000523 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
Mark Seabornc3bd1772013-12-31 13:05:15 +0000524 : Mips::fixup_Mips_GOT_DISP;
525 break;
526 case MCSymbolRefExpr::VK_Mips_GPREL:
527 FixupKind = Mips::fixup_Mips_GPREL16;
528 break;
529 case MCSymbolRefExpr::VK_Mips_GOT_CALL:
David Woodhoused2cca112014-01-28 23:13:25 +0000530 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000531 : Mips::fixup_Mips_CALL16;
532 break;
533 case MCSymbolRefExpr::VK_Mips_GOT16:
David Woodhoused2cca112014-01-28 23:13:25 +0000534 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000535 : Mips::fixup_Mips_GOT_Global;
536 break;
537 case MCSymbolRefExpr::VK_Mips_GOT:
David Woodhoused2cca112014-01-28 23:13:25 +0000538 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000539 : Mips::fixup_Mips_GOT_Local;
540 break;
541 case MCSymbolRefExpr::VK_Mips_ABS_HI:
David Woodhoused2cca112014-01-28 23:13:25 +0000542 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000543 : Mips::fixup_Mips_HI16;
544 break;
545 case MCSymbolRefExpr::VK_Mips_ABS_LO:
David Woodhoused2cca112014-01-28 23:13:25 +0000546 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000547 : Mips::fixup_Mips_LO16;
548 break;
549 case MCSymbolRefExpr::VK_Mips_TLSGD:
David Woodhoused2cca112014-01-28 23:13:25 +0000550 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
Mark Seabornc3bd1772013-12-31 13:05:15 +0000551 : Mips::fixup_Mips_TLSGD;
552 break;
553 case MCSymbolRefExpr::VK_Mips_TLSLDM:
David Woodhoused2cca112014-01-28 23:13:25 +0000554 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
Mark Seabornc3bd1772013-12-31 13:05:15 +0000555 : Mips::fixup_Mips_TLSLDM;
556 break;
557 case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
David Woodhoused2cca112014-01-28 23:13:25 +0000558 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000559 : Mips::fixup_Mips_DTPREL_HI;
560 break;
561 case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
David Woodhoused2cca112014-01-28 23:13:25 +0000562 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000563 : Mips::fixup_Mips_DTPREL_LO;
564 break;
565 case MCSymbolRefExpr::VK_Mips_GOTTPREL:
566 FixupKind = Mips::fixup_Mips_GOTTPREL;
567 break;
568 case MCSymbolRefExpr::VK_Mips_TPREL_HI:
David Woodhoused2cca112014-01-28 23:13:25 +0000569 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000570 : Mips::fixup_Mips_TPREL_HI;
571 break;
572 case MCSymbolRefExpr::VK_Mips_TPREL_LO:
David Woodhoused2cca112014-01-28 23:13:25 +0000573 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000574 : Mips::fixup_Mips_TPREL_LO;
575 break;
576 case MCSymbolRefExpr::VK_Mips_HIGHER:
577 FixupKind = Mips::fixup_Mips_HIGHER;
578 break;
579 case MCSymbolRefExpr::VK_Mips_HIGHEST:
580 FixupKind = Mips::fixup_Mips_HIGHEST;
581 break;
582 case MCSymbolRefExpr::VK_Mips_GOT_HI16:
583 FixupKind = Mips::fixup_Mips_GOT_HI16;
584 break;
585 case MCSymbolRefExpr::VK_Mips_GOT_LO16:
586 FixupKind = Mips::fixup_Mips_GOT_LO16;
587 break;
588 case MCSymbolRefExpr::VK_Mips_CALL_HI16:
589 FixupKind = Mips::fixup_Mips_CALL_HI16;
590 break;
591 case MCSymbolRefExpr::VK_Mips_CALL_LO16:
592 FixupKind = Mips::fixup_Mips_CALL_LO16;
593 break;
Zoran Jovanovicb355e8f2014-05-27 14:58:51 +0000594 case MCSymbolRefExpr::VK_Mips_PCREL_HI16:
595 FixupKind = Mips::fixup_MIPS_PCHI16;
596 break;
597 case MCSymbolRefExpr::VK_Mips_PCREL_LO16:
598 FixupKind = Mips::fixup_MIPS_PCLO16;
599 break;
Mark Seabornc3bd1772013-12-31 13:05:15 +0000600 } // switch
Akira Hatanakafe384a22012-03-27 02:33:05 +0000601
Jack Carterb5cf5902013-04-17 00:18:04 +0000602 Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
603 return 0;
604 }
Akira Hatanakafe384a22012-03-27 02:33:05 +0000605 return 0;
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000606}
607
Jack Carterb5cf5902013-04-17 00:18:04 +0000608/// getMachineOpValue - Return binary encoding of operand. If the machine
609/// operand requires relocation, record the relocation and return zero.
610unsigned MipsMCCodeEmitter::
611getMachineOpValue(const MCInst &MI, const MCOperand &MO,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000612 SmallVectorImpl<MCFixup> &Fixups,
613 const MCSubtargetInfo &STI) const {
Jack Carterb5cf5902013-04-17 00:18:04 +0000614 if (MO.isReg()) {
615 unsigned Reg = MO.getReg();
Bill Wendlingbc07a892013-06-18 07:20:20 +0000616 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
Jack Carterb5cf5902013-04-17 00:18:04 +0000617 return RegNo;
618 } else if (MO.isImm()) {
619 return static_cast<unsigned>(MO.getImm());
620 } else if (MO.isFPImm()) {
621 return static_cast<unsigned>(APFloat(MO.getFPImm())
622 .bitcastToAPInt().getHiBits(32).getLimitedValue());
623 }
624 // MO must be an Expr.
625 assert(MO.isExpr());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000626 return getExprOpValue(MO.getExpr(),Fixups, STI);
Jack Carterb5cf5902013-04-17 00:18:04 +0000627}
628
Matheus Almeida6b59c442013-12-05 11:06:22 +0000629/// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST
630/// instructions.
631unsigned
632MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000633 SmallVectorImpl<MCFixup> &Fixups,
634 const MCSubtargetInfo &STI) const {
Matheus Almeida6b59c442013-12-05 11:06:22 +0000635 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
636 assert(MI.getOperand(OpNo).isReg());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000637 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
638 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
Matheus Almeida6b59c442013-12-05 11:06:22 +0000639
640 // The immediate field of an LD/ST instruction is scaled which means it must
641 // be divided (when encoding) by the size (in bytes) of the instructions'
642 // data format.
643 // .b - 1 byte
644 // .h - 2 bytes
645 // .w - 4 bytes
646 // .d - 8 bytes
647 switch(MI.getOpcode())
648 {
649 default:
650 assert (0 && "Unexpected instruction");
651 break;
652 case Mips::LD_B:
653 case Mips::ST_B:
654 // We don't need to scale the offset in this case
655 break;
656 case Mips::LD_H:
657 case Mips::ST_H:
658 OffBits >>= 1;
659 break;
660 case Mips::LD_W:
661 case Mips::ST_W:
662 OffBits >>= 2;
663 break;
664 case Mips::LD_D:
665 case Mips::ST_D:
666 OffBits >>= 3;
667 break;
668 }
669
670 return (OffBits & 0xFFFF) | RegBits;
671}
672
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000673/// getMemEncoding - Return binary encoding of memory related operand.
674/// If the offset operand requires relocation, record the relocation.
675unsigned
676MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000677 SmallVectorImpl<MCFixup> &Fixups,
678 const MCSubtargetInfo &STI) const {
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000679 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
680 assert(MI.getOperand(OpNo).isReg());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000681 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
682 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000683
684 return (OffBits & 0xFFFF) | RegBits;
685}
686
Jack Carter97700972013-08-13 20:19:16 +0000687unsigned MipsMCCodeEmitter::
Jozef Koleke8c9d1e2014-11-24 14:39:13 +0000688getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
689 SmallVectorImpl<MCFixup> &Fixups,
690 const MCSubtargetInfo &STI) const {
691 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
692 assert(MI.getOperand(OpNo).isReg());
693 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
694 Fixups, STI) << 4;
695 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
696 Fixups, STI);
697
698 return (OffBits & 0xF) | RegBits;
699}
700
701unsigned MipsMCCodeEmitter::
702getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
703 SmallVectorImpl<MCFixup> &Fixups,
704 const MCSubtargetInfo &STI) const {
705 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
706 assert(MI.getOperand(OpNo).isReg());
707 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
708 Fixups, STI) << 4;
709 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
710 Fixups, STI) >> 1;
711
712 return (OffBits & 0xF) | RegBits;
713}
714
715unsigned MipsMCCodeEmitter::
716getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
717 SmallVectorImpl<MCFixup> &Fixups,
718 const MCSubtargetInfo &STI) const {
719 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
720 assert(MI.getOperand(OpNo).isReg());
721 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
722 Fixups, STI) << 4;
723 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
724 Fixups, STI) >> 2;
725
726 return (OffBits & 0xF) | RegBits;
727}
728
729unsigned MipsMCCodeEmitter::
Jozef Kolek12c69822014-12-23 16:16:33 +0000730getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
731 SmallVectorImpl<MCFixup> &Fixups,
732 const MCSubtargetInfo &STI) const {
733 // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
734 assert(MI.getOperand(OpNo).isReg() &&
735 MI.getOperand(OpNo).getReg() == Mips::SP &&
736 "Unexpected base register!");
737 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
738 Fixups, STI) >> 2;
739
740 return OffBits & 0x1F;
741}
742
743unsigned MipsMCCodeEmitter::
Jozef Koleke10a02e2015-01-28 17:27:26 +0000744getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
745 SmallVectorImpl<MCFixup> &Fixups,
746 const MCSubtargetInfo &STI) const {
747 // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
748 assert(MI.getOperand(OpNo).isReg() &&
749 MI.getOperand(OpNo).getReg() == Mips::GP &&
750 "Unexpected base register!");
751
752 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
753 Fixups, STI) >> 2;
754
755 return OffBits & 0x7F;
756}
757
758unsigned MipsMCCodeEmitter::
Jack Carter97700972013-08-13 20:19:16 +0000759getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000760 SmallVectorImpl<MCFixup> &Fixups,
761 const MCSubtargetInfo &STI) const {
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000762 // opNum can be invalid if instruction had reglist as operand.
763 // MemOperand is always last operand of instruction (base + offset).
764 switch (MI.getOpcode()) {
765 default:
766 break;
767 case Mips::SWM32_MM:
768 case Mips::LWM32_MM:
769 OpNo = MI.getNumOperands() - 2;
770 break;
771 }
772
Jack Carter97700972013-08-13 20:19:16 +0000773 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
774 assert(MI.getOperand(OpNo).isReg());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000775 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
776 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
Jack Carter97700972013-08-13 20:19:16 +0000777
778 return (OffBits & 0x0FFF) | RegBits;
779}
780
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000781unsigned MipsMCCodeEmitter::
782getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
783 SmallVectorImpl<MCFixup> &Fixups,
784 const MCSubtargetInfo &STI) const {
785 // opNum can be invalid if instruction had reglist as operand
786 // MemOperand is always last operand of instruction (base + offset)
787 switch (MI.getOpcode()) {
788 default:
789 break;
790 case Mips::SWM16_MM:
791 case Mips::LWM16_MM:
792 OpNo = MI.getNumOperands() - 2;
793 break;
794 }
795
796 // Offset is encoded in bits 4-0.
797 assert(MI.getOperand(OpNo).isReg());
798 // Base register is always SP - thus it is not encoded.
799 assert(MI.getOperand(OpNo+1).isImm());
800 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
801
802 return ((OffBits >> 2) & 0x0F);
803}
804
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000805unsigned
806MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000807 SmallVectorImpl<MCFixup> &Fixups,
808 const MCSubtargetInfo &STI) const {
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000809 assert(MI.getOperand(OpNo).isImm());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000810 unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
Bruno Cardoso Lopes56b70de2011-12-07 22:35:30 +0000811 return SizeEncoding - 1;
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000812}
813
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000814// FIXME: should be called getMSBEncoding
815//
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000816unsigned
817MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000818 SmallVectorImpl<MCFixup> &Fixups,
819 const MCSubtargetInfo &STI) const {
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000820 assert(MI.getOperand(OpNo-1).isImm());
821 assert(MI.getOperand(OpNo).isImm());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000822 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
823 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000824
Bruno Cardoso Lopes56b70de2011-12-07 22:35:30 +0000825 return Position + Size - 1;
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000826}
827
Matheus Almeida779c5932013-11-18 12:32:49 +0000828unsigned
829MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000830 SmallVectorImpl<MCFixup> &Fixups,
831 const MCSubtargetInfo &STI) const {
Matheus Almeida779c5932013-11-18 12:32:49 +0000832 assert(MI.getOperand(OpNo).isImm());
833 // The immediate is encoded as 'immediate - 1'.
David Woodhouse3fa98a62014-01-28 23:13:18 +0000834 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1;
Matheus Almeida779c5932013-11-18 12:32:49 +0000835}
836
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000837unsigned
838MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
839 SmallVectorImpl<MCFixup> &Fixups,
840 const MCSubtargetInfo &STI) const {
Zoran Jovanovicb9c07f32014-06-12 12:40:00 +0000841 const MCOperand &MO = MI.getOperand(OpNo);
842 if (MO.isImm()) {
843 // The immediate is encoded as 'immediate << 2'.
844 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
845 assert((Res & 3) == 0);
846 return Res >> 2;
847 }
848
849 assert(MO.isExpr() &&
850 "getSimm19Lsl2Encoding expects only expressions or an immediate");
851
852 const MCExpr *Expr = MO.getExpr();
853 Fixups.push_back(MCFixup::Create(0, Expr,
854 MCFixupKind(Mips::fixup_MIPS_PC19_S2)));
855 return 0;
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000856}
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000857
Zoran Jovanovic28551422014-06-09 09:49:51 +0000858unsigned
859MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
860 SmallVectorImpl<MCFixup> &Fixups,
861 const MCSubtargetInfo &STI) const {
Zoran Jovanovica5acdcf2014-06-13 14:26:47 +0000862 const MCOperand &MO = MI.getOperand(OpNo);
863 if (MO.isImm()) {
864 // The immediate is encoded as 'immediate << 3'.
865 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
866 assert((Res & 7) == 0);
867 return Res >> 3;
868 }
869
870 assert(MO.isExpr() &&
871 "getSimm18Lsl2Encoding expects only expressions or an immediate");
872
873 const MCExpr *Expr = MO.getExpr();
874 Fixups.push_back(MCFixup::Create(0, Expr,
875 MCFixupKind(Mips::fixup_MIPS_PC18_S3)));
876 return 0;
Zoran Jovanovic28551422014-06-09 09:49:51 +0000877}
878
Zoran Jovanovic4a00fdc2014-10-23 10:42:01 +0000879unsigned
880MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
881 SmallVectorImpl<MCFixup> &Fixups,
882 const MCSubtargetInfo &STI) const {
883 assert(MI.getOperand(OpNo).isImm());
884 const MCOperand &MO = MI.getOperand(OpNo);
885 return MO.getImm() % 8;
886}
887
Zoran Jovanovic88531712014-11-05 17:31:00 +0000888unsigned
889MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
890 SmallVectorImpl<MCFixup> &Fixups,
891 const MCSubtargetInfo &STI) const {
892 assert(MI.getOperand(OpNo).isImm());
893 const MCOperand &MO = MI.getOperand(OpNo);
894 unsigned Value = MO.getImm();
895 switch (Value) {
896 case 128: return 0x0;
897 case 1: return 0x1;
898 case 2: return 0x2;
899 case 3: return 0x3;
900 case 4: return 0x4;
901 case 7: return 0x5;
902 case 8: return 0x6;
903 case 15: return 0x7;
904 case 16: return 0x8;
905 case 31: return 0x9;
906 case 32: return 0xa;
907 case 63: return 0xb;
908 case 64: return 0xc;
909 case 255: return 0xd;
910 case 32768: return 0xe;
911 case 65535: return 0xf;
912 }
913 llvm_unreachable("Unexpected value");
914}
915
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000916unsigned
917MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
918 SmallVectorImpl<MCFixup> &Fixups,
919 const MCSubtargetInfo &STI) const {
920 unsigned res = 0;
921
922 // Register list operand is always first operand of instruction and it is
923 // placed before memory operand (register + imm).
924
925 for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
926 unsigned Reg = MI.getOperand(I).getReg();
927 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
928 if (RegNo != 31)
929 res++;
930 else
931 res |= 0x10;
932 }
933 return res;
934}
935
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000936unsigned
937MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
938 SmallVectorImpl<MCFixup> &Fixups,
939 const MCSubtargetInfo &STI) const {
940 return (MI.getNumOperands() - 4);
941}
942
Zoran Jovanovic2deca342014-12-16 14:59:10 +0000943unsigned
944MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
945 SmallVectorImpl<MCFixup> &Fixups,
946 const MCSubtargetInfo &STI) const {
947 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
948}
949
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000950unsigned
Zoran Jovanovic41688672015-02-10 16:36:20 +0000951MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
952 SmallVectorImpl<MCFixup> &Fixups,
953 const MCSubtargetInfo &STI) const {
954 unsigned res = 0;
955
956 if (MI.getOperand(0).getReg() == Mips::A1 &&
957 MI.getOperand(1).getReg() == Mips::A2)
958 res = 0;
959 else if (MI.getOperand(0).getReg() == Mips::A1 &&
960 MI.getOperand(1).getReg() == Mips::A3)
961 res = 1;
962 else if (MI.getOperand(0).getReg() == Mips::A2 &&
963 MI.getOperand(1).getReg() == Mips::A3)
964 res = 2;
965 else if (MI.getOperand(0).getReg() == Mips::A0 &&
966 MI.getOperand(1).getReg() == Mips::S5)
967 res = 3;
968 else if (MI.getOperand(0).getReg() == Mips::A0 &&
969 MI.getOperand(1).getReg() == Mips::S6)
970 res = 4;
971 else if (MI.getOperand(0).getReg() == Mips::A0 &&
972 MI.getOperand(1).getReg() == Mips::A1)
973 res = 5;
974 else if (MI.getOperand(0).getReg() == Mips::A0 &&
975 MI.getOperand(1).getReg() == Mips::A2)
976 res = 6;
977 else if (MI.getOperand(0).getReg() == Mips::A0 &&
978 MI.getOperand(1).getReg() == Mips::A3)
979 res = 7;
980
981 return res;
982}
983
984unsigned
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000985MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
986 SmallVectorImpl<MCFixup> &Fixups,
987 const MCSubtargetInfo &STI) const {
988 const MCOperand &MO = MI.getOperand(OpNo);
989 assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
990 // The immediate is encoded as 'immediate >> 2'.
991 unsigned Res = static_cast<unsigned>(MO.getImm());
992 assert((Res & 3) == 0);
993 return Res >> 2;
994}
995
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000996#include "MipsGenMCCodeEmitter.inc"