blob: 9c2508ff9839a5c3ef98c42a60ebce58e4999e3b [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
Jozef Kolek6ca13ea2015-04-20 12:42:08 +0000182 if (isMicroMips(STI)) {
183 int NewOpcode = isMips32r6(STI) ?
184 Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6) :
185 Mips::Std2MicroMips(Opcode, Mips::Arch_micromips);
Akira Hatanakabe6a8182013-04-19 19:03:11 +0000186 if (NewOpcode != -1) {
Jack Carter97700972013-08-13 20:19:16 +0000187 if (Fixups.size() > N)
188 Fixups.pop_back();
Akira Hatanakabe6a8182013-04-19 19:03:11 +0000189 Opcode = NewOpcode;
190 TmpInst.setOpcode (NewOpcode);
David Woodhouse3fa98a62014-01-28 23:13:18 +0000191 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
Akira Hatanakabe6a8182013-04-19 19:03:11 +0000192 }
193 }
194
Jack Carteraa7aeaa2012-10-02 23:09:40 +0000195 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000196
Jack Carter5b5559d2012-10-03 21:58:54 +0000197 // Get byte count of instruction
198 unsigned Size = Desc.getSize();
199 if (!Size)
200 llvm_unreachable("Desc.getSize() returns 0");
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000201
David Woodhoused2cca112014-01-28 23:13:25 +0000202 EmitInstruction(Binary, Size, STI, OS);
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000203}
204
205/// getBranchTargetOpValue - Return binary encoding of the branch
206/// target operand. If the machine operand requires relocation,
207/// record the relocation and return zero.
208unsigned MipsMCCodeEmitter::
209getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000210 SmallVectorImpl<MCFixup> &Fixups,
211 const MCSubtargetInfo &STI) const {
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000212
213 const MCOperand &MO = MI.getOperand(OpNo);
Jack Carter71e6a742012-09-06 00:43:26 +0000214
Jack Carter4f69a0f2013-03-22 00:29:10 +0000215 // If the destination is an immediate, divide by 4.
216 if (MO.isImm()) return MO.getImm() >> 2;
217
Jack Carter71e6a742012-09-06 00:43:26 +0000218 assert(MO.isExpr() &&
219 "getBranchTargetOpValue expects only expressions or immediates");
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000220
221 const MCExpr *Expr = MO.getExpr();
222 Fixups.push_back(MCFixup::Create(0, Expr,
223 MCFixupKind(Mips::fixup_Mips_PC16)));
224 return 0;
225}
226
Jozef Kolek9761e962015-01-12 12:03:34 +0000227/// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
228/// target operand. If the machine operand requires relocation,
229/// record the relocation and return zero.
230unsigned MipsMCCodeEmitter::
231getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
232 SmallVectorImpl<MCFixup> &Fixups,
233 const MCSubtargetInfo &STI) const {
234
235 const MCOperand &MO = MI.getOperand(OpNo);
236
237 // If the destination is an immediate, divide by 2.
238 if (MO.isImm()) return MO.getImm() >> 1;
239
240 assert(MO.isExpr() &&
241 "getBranchTargetOpValueMM expects only expressions or immediates");
242
243 const MCExpr *Expr = MO.getExpr();
244 Fixups.push_back(MCFixup::Create(0, Expr,
245 MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
246 return 0;
247}
248
Jozef Kolek5cfebdd2015-01-21 12:39:30 +0000249/// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
250/// 10-bit branch target operand. If the machine operand requires relocation,
251/// record the relocation and return zero.
252unsigned MipsMCCodeEmitter::
253getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
254 SmallVectorImpl<MCFixup> &Fixups,
255 const MCSubtargetInfo &STI) const {
256
257 const MCOperand &MO = MI.getOperand(OpNo);
258
259 // If the destination is an immediate, divide by 2.
260 if (MO.isImm()) return MO.getImm() >> 1;
261
262 assert(MO.isExpr() &&
263 "getBranchTargetOpValuePC10 expects only expressions or immediates");
264
265 const MCExpr *Expr = MO.getExpr();
266 Fixups.push_back(MCFixup::Create(0, Expr,
267 MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
268 return 0;
269}
270
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000271/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
272/// target operand. If the machine operand requires relocation,
273/// record the relocation and return zero.
274unsigned MipsMCCodeEmitter::
275getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000276 SmallVectorImpl<MCFixup> &Fixups,
277 const MCSubtargetInfo &STI) const {
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000278
279 const MCOperand &MO = MI.getOperand(OpNo);
280
281 // If the destination is an immediate, divide by 2.
282 if (MO.isImm()) return MO.getImm() >> 1;
283
284 assert(MO.isExpr() &&
285 "getBranchTargetOpValueMM expects only expressions or immediates");
286
287 const MCExpr *Expr = MO.getExpr();
288 Fixups.push_back(MCFixup::Create(0, Expr,
289 MCFixupKind(Mips::
290 fixup_MICROMIPS_PC16_S1)));
291 return 0;
292}
293
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000294/// getBranchTarget21OpValue - Return binary encoding of the branch
295/// target operand. If the machine operand requires relocation,
296/// record the relocation and return zero.
297unsigned MipsMCCodeEmitter::
298getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
299 SmallVectorImpl<MCFixup> &Fixups,
300 const MCSubtargetInfo &STI) const {
301
302 const MCOperand &MO = MI.getOperand(OpNo);
303
304 // If the destination is an immediate, divide by 4.
305 if (MO.isImm()) return MO.getImm() >> 2;
306
307 assert(MO.isExpr() &&
308 "getBranchTarget21OpValue expects only expressions or immediates");
309
Zoran Jovanovic10e06da2014-05-27 12:55:40 +0000310 const MCExpr *Expr = MO.getExpr();
311 Fixups.push_back(MCFixup::Create(0, Expr,
312 MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000313 return 0;
314}
315
316/// getBranchTarget26OpValue - Return binary encoding of the branch
317/// target operand. If the machine operand requires relocation,
318/// record the relocation and return zero.
319unsigned MipsMCCodeEmitter::
320getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
321 SmallVectorImpl<MCFixup> &Fixups,
322 const MCSubtargetInfo &STI) const {
323
324 const MCOperand &MO = MI.getOperand(OpNo);
325
326 // If the destination is an immediate, divide by 4.
327 if (MO.isImm()) return MO.getImm() >> 2;
328
329 assert(MO.isExpr() &&
330 "getBranchTarget26OpValue expects only expressions or immediates");
331
Zoran Jovanovic10e06da2014-05-27 12:55:40 +0000332 const MCExpr *Expr = MO.getExpr();
333 Fixups.push_back(MCFixup::Create(0, Expr,
334 MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000335 return 0;
336}
337
Zoran Jovanovic52c56b92014-05-16 13:19:46 +0000338/// getJumpOffset16OpValue - Return binary encoding of the jump
339/// target operand. If the machine operand requires relocation,
340/// record the relocation and return zero.
341unsigned MipsMCCodeEmitter::
342getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
343 SmallVectorImpl<MCFixup> &Fixups,
344 const MCSubtargetInfo &STI) const {
345
346 const MCOperand &MO = MI.getOperand(OpNo);
347
348 if (MO.isImm()) return MO.getImm();
349
350 assert(MO.isExpr() &&
351 "getJumpOffset16OpValue expects only expressions or an immediate");
352
353 // TODO: Push fixup.
354 return 0;
355}
356
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000357/// getJumpTargetOpValue - Return binary encoding of the jump
358/// target operand. If the machine operand requires relocation,
359/// record the relocation and return zero.
360unsigned MipsMCCodeEmitter::
361getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000362 SmallVectorImpl<MCFixup> &Fixups,
363 const MCSubtargetInfo &STI) const {
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000364
365 const MCOperand &MO = MI.getOperand(OpNo);
Jack Carter4f69a0f2013-03-22 00:29:10 +0000366 // If the destination is an immediate, divide by 4.
367 if (MO.isImm()) return MO.getImm()>>2;
368
Jack Carter71e6a742012-09-06 00:43:26 +0000369 assert(MO.isExpr() &&
370 "getJumpTargetOpValue expects only expressions or an immediate");
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000371
372 const MCExpr *Expr = MO.getExpr();
373 Fixups.push_back(MCFixup::Create(0, Expr,
374 MCFixupKind(Mips::fixup_Mips_26)));
375 return 0;
376}
377
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000378unsigned MipsMCCodeEmitter::
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000379getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000380 SmallVectorImpl<MCFixup> &Fixups,
381 const MCSubtargetInfo &STI) const {
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000382
383 const MCOperand &MO = MI.getOperand(OpNo);
384 // If the destination is an immediate, divide by 2.
385 if (MO.isImm()) return MO.getImm() >> 1;
386
387 assert(MO.isExpr() &&
388 "getJumpTargetOpValueMM expects only expressions or an immediate");
389
390 const MCExpr *Expr = MO.getExpr();
391 Fixups.push_back(MCFixup::Create(0, Expr,
392 MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
393 return 0;
394}
395
396unsigned MipsMCCodeEmitter::
Zoran Jovanovicc74e3eb92014-09-12 14:29:54 +0000397getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
398 SmallVectorImpl<MCFixup> &Fixups,
399 const MCSubtargetInfo &STI) const {
400
401 const MCOperand &MO = MI.getOperand(OpNo);
402 if (MO.isImm()) {
403 // The immediate is encoded as 'immediate << 2'.
404 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
405 assert((Res & 3) == 0);
406 return Res >> 2;
407 }
408
409 assert(MO.isExpr() &&
410 "getUImm5Lsl2Encoding expects only expressions or an immediate");
411
412 return 0;
413}
414
415unsigned MipsMCCodeEmitter::
Zoran Jovanovicbac36192014-10-23 11:06:34 +0000416getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo,
417 SmallVectorImpl<MCFixup> &Fixups,
418 const MCSubtargetInfo &STI) const {
419
420 const MCOperand &MO = MI.getOperand(OpNo);
421 if (MO.isImm()) {
422 int Value = MO.getImm();
423 return Value >> 2;
424 }
425
426 return 0;
427}
428
429unsigned MipsMCCodeEmitter::
Zoran Jovanovic42b84442014-10-23 11:13:59 +0000430getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
431 SmallVectorImpl<MCFixup> &Fixups,
432 const MCSubtargetInfo &STI) const {
433
434 const MCOperand &MO = MI.getOperand(OpNo);
435 if (MO.isImm()) {
436 unsigned Value = MO.getImm();
437 return Value >> 2;
438 }
439
440 return 0;
441}
442
443unsigned MipsMCCodeEmitter::
Zoran Jovanovic98bd58c2014-10-10 14:37:30 +0000444getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
445 SmallVectorImpl<MCFixup> &Fixups,
446 const MCSubtargetInfo &STI) const {
447
448 const MCOperand &MO = MI.getOperand(OpNo);
449 if (MO.isImm()) {
450 unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff;
451 return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
452 }
453
454 return 0;
455}
456
457unsigned MipsMCCodeEmitter::
Daniel Sanders60f1db02015-03-13 12:45:09 +0000458getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000459 const MCSubtargetInfo &STI) const {
Jack Carterb5cf5902013-04-17 00:18:04 +0000460 int64_t Res;
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000461
Jack Carterb5cf5902013-04-17 00:18:04 +0000462 if (Expr->EvaluateAsAbsolute(Res))
463 return Res;
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000464
Akira Hatanakafe384a22012-03-27 02:33:05 +0000465 MCExpr::ExprKind Kind = Expr->getKind();
Jack Carterb5cf5902013-04-17 00:18:04 +0000466 if (Kind == MCExpr::Constant) {
467 return cast<MCConstantExpr>(Expr)->getValue();
468 }
Akira Hatanakae2eed962011-12-22 01:05:17 +0000469
Akira Hatanakafe384a22012-03-27 02:33:05 +0000470 if (Kind == MCExpr::Binary) {
David Woodhouse3fa98a62014-01-28 23:13:18 +0000471 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
472 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
Jack Carterb5cf5902013-04-17 00:18:04 +0000473 return Res;
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000474 }
Petar Jovanovica5da5882014-02-04 18:41:57 +0000475
476 if (Kind == MCExpr::Target) {
477 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
478
479 Mips::Fixups FixupKind = Mips::Fixups(0);
480 switch (MipsExpr->getKind()) {
481 default: llvm_unreachable("Unsupported fixup kind for target expression!");
Sasa Stankovic06c47802014-04-03 10:37:45 +0000482 case MipsMCExpr::VK_Mips_HIGHEST:
483 FixupKind = Mips::fixup_Mips_HIGHEST;
484 break;
485 case MipsMCExpr::VK_Mips_HIGHER:
486 FixupKind = Mips::fixup_Mips_HIGHER;
487 break;
488 case MipsMCExpr::VK_Mips_HI:
Petar Jovanovica5da5882014-02-04 18:41:57 +0000489 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
490 : Mips::fixup_Mips_HI16;
491 break;
Sasa Stankovic06c47802014-04-03 10:37:45 +0000492 case MipsMCExpr::VK_Mips_LO:
Petar Jovanovica5da5882014-02-04 18:41:57 +0000493 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
494 : Mips::fixup_Mips_LO16;
495 break;
496 }
497 Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind)));
498 return 0;
499 }
500
Jack Carterb5cf5902013-04-17 00:18:04 +0000501 if (Kind == MCExpr::SymbolRef) {
Mark Seabornc3bd1772013-12-31 13:05:15 +0000502 Mips::Fixups FixupKind = Mips::Fixups(0);
Akira Hatanakafe384a22012-03-27 02:33:05 +0000503
Mark Seabornc3bd1772013-12-31 13:05:15 +0000504 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
505 default: llvm_unreachable("Unknown fixup kind!");
506 break;
Daniel Sanders60f1db02015-03-13 12:45:09 +0000507 case MCSymbolRefExpr::VK_None:
508 FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
509 break;
Mark Seabornc3bd1772013-12-31 13:05:15 +0000510 case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
511 FixupKind = Mips::fixup_Mips_GPOFF_HI;
512 break;
513 case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
514 FixupKind = Mips::fixup_Mips_GPOFF_LO;
515 break;
516 case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
David Woodhoused2cca112014-01-28 23:13:25 +0000517 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
Mark Seabornc3bd1772013-12-31 13:05:15 +0000518 : Mips::fixup_Mips_GOT_PAGE;
519 break;
520 case MCSymbolRefExpr::VK_Mips_GOT_OFST :
David Woodhoused2cca112014-01-28 23:13:25 +0000521 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
Mark Seabornc3bd1772013-12-31 13:05:15 +0000522 : Mips::fixup_Mips_GOT_OFST;
523 break;
524 case MCSymbolRefExpr::VK_Mips_GOT_DISP :
David Woodhoused2cca112014-01-28 23:13:25 +0000525 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
Mark Seabornc3bd1772013-12-31 13:05:15 +0000526 : Mips::fixup_Mips_GOT_DISP;
527 break;
528 case MCSymbolRefExpr::VK_Mips_GPREL:
529 FixupKind = Mips::fixup_Mips_GPREL16;
530 break;
531 case MCSymbolRefExpr::VK_Mips_GOT_CALL:
David Woodhoused2cca112014-01-28 23:13:25 +0000532 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000533 : Mips::fixup_Mips_CALL16;
534 break;
535 case MCSymbolRefExpr::VK_Mips_GOT16:
David Woodhoused2cca112014-01-28 23:13:25 +0000536 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000537 : Mips::fixup_Mips_GOT_Global;
538 break;
539 case MCSymbolRefExpr::VK_Mips_GOT:
David Woodhoused2cca112014-01-28 23:13:25 +0000540 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000541 : Mips::fixup_Mips_GOT_Local;
542 break;
543 case MCSymbolRefExpr::VK_Mips_ABS_HI:
David Woodhoused2cca112014-01-28 23:13:25 +0000544 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000545 : Mips::fixup_Mips_HI16;
546 break;
547 case MCSymbolRefExpr::VK_Mips_ABS_LO:
David Woodhoused2cca112014-01-28 23:13:25 +0000548 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000549 : Mips::fixup_Mips_LO16;
550 break;
551 case MCSymbolRefExpr::VK_Mips_TLSGD:
David Woodhoused2cca112014-01-28 23:13:25 +0000552 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
Mark Seabornc3bd1772013-12-31 13:05:15 +0000553 : Mips::fixup_Mips_TLSGD;
554 break;
555 case MCSymbolRefExpr::VK_Mips_TLSLDM:
David Woodhoused2cca112014-01-28 23:13:25 +0000556 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
Mark Seabornc3bd1772013-12-31 13:05:15 +0000557 : Mips::fixup_Mips_TLSLDM;
558 break;
559 case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
David Woodhoused2cca112014-01-28 23:13:25 +0000560 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000561 : Mips::fixup_Mips_DTPREL_HI;
562 break;
563 case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
David Woodhoused2cca112014-01-28 23:13:25 +0000564 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000565 : Mips::fixup_Mips_DTPREL_LO;
566 break;
567 case MCSymbolRefExpr::VK_Mips_GOTTPREL:
568 FixupKind = Mips::fixup_Mips_GOTTPREL;
569 break;
570 case MCSymbolRefExpr::VK_Mips_TPREL_HI:
David Woodhoused2cca112014-01-28 23:13:25 +0000571 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000572 : Mips::fixup_Mips_TPREL_HI;
573 break;
574 case MCSymbolRefExpr::VK_Mips_TPREL_LO:
David Woodhoused2cca112014-01-28 23:13:25 +0000575 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
Mark Seabornc3bd1772013-12-31 13:05:15 +0000576 : Mips::fixup_Mips_TPREL_LO;
577 break;
578 case MCSymbolRefExpr::VK_Mips_HIGHER:
579 FixupKind = Mips::fixup_Mips_HIGHER;
580 break;
581 case MCSymbolRefExpr::VK_Mips_HIGHEST:
582 FixupKind = Mips::fixup_Mips_HIGHEST;
583 break;
584 case MCSymbolRefExpr::VK_Mips_GOT_HI16:
585 FixupKind = Mips::fixup_Mips_GOT_HI16;
586 break;
587 case MCSymbolRefExpr::VK_Mips_GOT_LO16:
588 FixupKind = Mips::fixup_Mips_GOT_LO16;
589 break;
590 case MCSymbolRefExpr::VK_Mips_CALL_HI16:
591 FixupKind = Mips::fixup_Mips_CALL_HI16;
592 break;
593 case MCSymbolRefExpr::VK_Mips_CALL_LO16:
594 FixupKind = Mips::fixup_Mips_CALL_LO16;
595 break;
Zoran Jovanovicb355e8f2014-05-27 14:58:51 +0000596 case MCSymbolRefExpr::VK_Mips_PCREL_HI16:
597 FixupKind = Mips::fixup_MIPS_PCHI16;
598 break;
599 case MCSymbolRefExpr::VK_Mips_PCREL_LO16:
600 FixupKind = Mips::fixup_MIPS_PCLO16;
601 break;
Mark Seabornc3bd1772013-12-31 13:05:15 +0000602 } // switch
Akira Hatanakafe384a22012-03-27 02:33:05 +0000603
Jack Carterb5cf5902013-04-17 00:18:04 +0000604 Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
605 return 0;
606 }
Akira Hatanakafe384a22012-03-27 02:33:05 +0000607 return 0;
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000608}
609
Jack Carterb5cf5902013-04-17 00:18:04 +0000610/// getMachineOpValue - Return binary encoding of operand. If the machine
611/// operand requires relocation, record the relocation and return zero.
612unsigned MipsMCCodeEmitter::
613getMachineOpValue(const MCInst &MI, const MCOperand &MO,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000614 SmallVectorImpl<MCFixup> &Fixups,
615 const MCSubtargetInfo &STI) const {
Jack Carterb5cf5902013-04-17 00:18:04 +0000616 if (MO.isReg()) {
617 unsigned Reg = MO.getReg();
Bill Wendlingbc07a892013-06-18 07:20:20 +0000618 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
Jack Carterb5cf5902013-04-17 00:18:04 +0000619 return RegNo;
620 } else if (MO.isImm()) {
621 return static_cast<unsigned>(MO.getImm());
622 } else if (MO.isFPImm()) {
623 return static_cast<unsigned>(APFloat(MO.getFPImm())
624 .bitcastToAPInt().getHiBits(32).getLimitedValue());
625 }
626 // MO must be an Expr.
627 assert(MO.isExpr());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000628 return getExprOpValue(MO.getExpr(),Fixups, STI);
Jack Carterb5cf5902013-04-17 00:18:04 +0000629}
630
Matheus Almeida6b59c442013-12-05 11:06:22 +0000631/// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST
632/// instructions.
633unsigned
634MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000635 SmallVectorImpl<MCFixup> &Fixups,
636 const MCSubtargetInfo &STI) const {
Matheus Almeida6b59c442013-12-05 11:06:22 +0000637 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
638 assert(MI.getOperand(OpNo).isReg());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000639 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
640 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
Matheus Almeida6b59c442013-12-05 11:06:22 +0000641
642 // The immediate field of an LD/ST instruction is scaled which means it must
643 // be divided (when encoding) by the size (in bytes) of the instructions'
644 // data format.
645 // .b - 1 byte
646 // .h - 2 bytes
647 // .w - 4 bytes
648 // .d - 8 bytes
649 switch(MI.getOpcode())
650 {
651 default:
652 assert (0 && "Unexpected instruction");
653 break;
654 case Mips::LD_B:
655 case Mips::ST_B:
656 // We don't need to scale the offset in this case
657 break;
658 case Mips::LD_H:
659 case Mips::ST_H:
660 OffBits >>= 1;
661 break;
662 case Mips::LD_W:
663 case Mips::ST_W:
664 OffBits >>= 2;
665 break;
666 case Mips::LD_D:
667 case Mips::ST_D:
668 OffBits >>= 3;
669 break;
670 }
671
672 return (OffBits & 0xFFFF) | RegBits;
673}
674
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000675/// getMemEncoding - Return binary encoding of memory related operand.
676/// If the offset operand requires relocation, record the relocation.
677unsigned
678MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000679 SmallVectorImpl<MCFixup> &Fixups,
680 const MCSubtargetInfo &STI) const {
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000681 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
682 assert(MI.getOperand(OpNo).isReg());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000683 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
684 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000685
686 return (OffBits & 0xFFFF) | RegBits;
687}
688
Jack Carter97700972013-08-13 20:19:16 +0000689unsigned MipsMCCodeEmitter::
Jozef Koleke8c9d1e2014-11-24 14:39:13 +0000690getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
691 SmallVectorImpl<MCFixup> &Fixups,
692 const MCSubtargetInfo &STI) const {
693 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
694 assert(MI.getOperand(OpNo).isReg());
695 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
696 Fixups, STI) << 4;
697 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
698 Fixups, STI);
699
700 return (OffBits & 0xF) | RegBits;
701}
702
703unsigned MipsMCCodeEmitter::
704getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
705 SmallVectorImpl<MCFixup> &Fixups,
706 const MCSubtargetInfo &STI) const {
707 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
708 assert(MI.getOperand(OpNo).isReg());
709 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
710 Fixups, STI) << 4;
711 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
712 Fixups, STI) >> 1;
713
714 return (OffBits & 0xF) | RegBits;
715}
716
717unsigned MipsMCCodeEmitter::
718getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
719 SmallVectorImpl<MCFixup> &Fixups,
720 const MCSubtargetInfo &STI) const {
721 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
722 assert(MI.getOperand(OpNo).isReg());
723 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
724 Fixups, STI) << 4;
725 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
726 Fixups, STI) >> 2;
727
728 return (OffBits & 0xF) | RegBits;
729}
730
731unsigned MipsMCCodeEmitter::
Jozef Kolek12c69822014-12-23 16:16:33 +0000732getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
733 SmallVectorImpl<MCFixup> &Fixups,
734 const MCSubtargetInfo &STI) const {
735 // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
736 assert(MI.getOperand(OpNo).isReg() &&
737 MI.getOperand(OpNo).getReg() == Mips::SP &&
738 "Unexpected base register!");
739 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
740 Fixups, STI) >> 2;
741
742 return OffBits & 0x1F;
743}
744
745unsigned MipsMCCodeEmitter::
Jozef Koleke10a02e2015-01-28 17:27:26 +0000746getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
747 SmallVectorImpl<MCFixup> &Fixups,
748 const MCSubtargetInfo &STI) const {
749 // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
750 assert(MI.getOperand(OpNo).isReg() &&
751 MI.getOperand(OpNo).getReg() == Mips::GP &&
752 "Unexpected base register!");
753
754 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
755 Fixups, STI) >> 2;
756
757 return OffBits & 0x7F;
758}
759
760unsigned MipsMCCodeEmitter::
Jack Carter97700972013-08-13 20:19:16 +0000761getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000762 SmallVectorImpl<MCFixup> &Fixups,
763 const MCSubtargetInfo &STI) const {
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000764 // opNum can be invalid if instruction had reglist as operand.
765 // MemOperand is always last operand of instruction (base + offset).
766 switch (MI.getOpcode()) {
767 default:
768 break;
769 case Mips::SWM32_MM:
770 case Mips::LWM32_MM:
771 OpNo = MI.getNumOperands() - 2;
772 break;
773 }
774
Jack Carter97700972013-08-13 20:19:16 +0000775 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
776 assert(MI.getOperand(OpNo).isReg());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000777 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
778 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
Jack Carter97700972013-08-13 20:19:16 +0000779
780 return (OffBits & 0x0FFF) | RegBits;
781}
782
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000783unsigned MipsMCCodeEmitter::
784getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
785 SmallVectorImpl<MCFixup> &Fixups,
786 const MCSubtargetInfo &STI) const {
787 // opNum can be invalid if instruction had reglist as operand
788 // MemOperand is always last operand of instruction (base + offset)
789 switch (MI.getOpcode()) {
790 default:
791 break;
792 case Mips::SWM16_MM:
793 case Mips::LWM16_MM:
794 OpNo = MI.getNumOperands() - 2;
795 break;
796 }
797
798 // Offset is encoded in bits 4-0.
799 assert(MI.getOperand(OpNo).isReg());
800 // Base register is always SP - thus it is not encoded.
801 assert(MI.getOperand(OpNo+1).isImm());
802 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
803
804 return ((OffBits >> 2) & 0x0F);
805}
806
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000807unsigned
808MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000809 SmallVectorImpl<MCFixup> &Fixups,
810 const MCSubtargetInfo &STI) const {
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000811 assert(MI.getOperand(OpNo).isImm());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000812 unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
Bruno Cardoso Lopes56b70de2011-12-07 22:35:30 +0000813 return SizeEncoding - 1;
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000814}
815
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000816// FIXME: should be called getMSBEncoding
817//
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000818unsigned
819MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000820 SmallVectorImpl<MCFixup> &Fixups,
821 const MCSubtargetInfo &STI) const {
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000822 assert(MI.getOperand(OpNo-1).isImm());
823 assert(MI.getOperand(OpNo).isImm());
David Woodhouse3fa98a62014-01-28 23:13:18 +0000824 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
825 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
Akira Hatanaka049e9e42011-11-23 22:19:28 +0000826
Bruno Cardoso Lopes56b70de2011-12-07 22:35:30 +0000827 return Position + Size - 1;
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000828}
829
Matheus Almeida779c5932013-11-18 12:32:49 +0000830unsigned
831MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000832 SmallVectorImpl<MCFixup> &Fixups,
833 const MCSubtargetInfo &STI) const {
Matheus Almeida779c5932013-11-18 12:32:49 +0000834 assert(MI.getOperand(OpNo).isImm());
835 // The immediate is encoded as 'immediate - 1'.
David Woodhouse3fa98a62014-01-28 23:13:18 +0000836 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1;
Matheus Almeida779c5932013-11-18 12:32:49 +0000837}
838
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000839unsigned
840MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
841 SmallVectorImpl<MCFixup> &Fixups,
842 const MCSubtargetInfo &STI) const {
Zoran Jovanovicb9c07f32014-06-12 12:40:00 +0000843 const MCOperand &MO = MI.getOperand(OpNo);
844 if (MO.isImm()) {
845 // The immediate is encoded as 'immediate << 2'.
846 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
847 assert((Res & 3) == 0);
848 return Res >> 2;
849 }
850
851 assert(MO.isExpr() &&
852 "getSimm19Lsl2Encoding expects only expressions or an immediate");
853
854 const MCExpr *Expr = MO.getExpr();
855 Fixups.push_back(MCFixup::Create(0, Expr,
856 MCFixupKind(Mips::fixup_MIPS_PC19_S2)));
857 return 0;
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000858}
Bruno Cardoso Lopesc85e3ff2011-11-11 22:58:42 +0000859
Zoran Jovanovic28551422014-06-09 09:49:51 +0000860unsigned
861MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
862 SmallVectorImpl<MCFixup> &Fixups,
863 const MCSubtargetInfo &STI) const {
Zoran Jovanovica5acdcf2014-06-13 14:26:47 +0000864 const MCOperand &MO = MI.getOperand(OpNo);
865 if (MO.isImm()) {
866 // The immediate is encoded as 'immediate << 3'.
867 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
868 assert((Res & 7) == 0);
869 return Res >> 3;
870 }
871
872 assert(MO.isExpr() &&
873 "getSimm18Lsl2Encoding expects only expressions or an immediate");
874
875 const MCExpr *Expr = MO.getExpr();
876 Fixups.push_back(MCFixup::Create(0, Expr,
877 MCFixupKind(Mips::fixup_MIPS_PC18_S3)));
878 return 0;
Zoran Jovanovic28551422014-06-09 09:49:51 +0000879}
880
Zoran Jovanovic4a00fdc2014-10-23 10:42:01 +0000881unsigned
882MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
883 SmallVectorImpl<MCFixup> &Fixups,
884 const MCSubtargetInfo &STI) const {
885 assert(MI.getOperand(OpNo).isImm());
886 const MCOperand &MO = MI.getOperand(OpNo);
887 return MO.getImm() % 8;
888}
889
Zoran Jovanovic88531712014-11-05 17:31:00 +0000890unsigned
891MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
892 SmallVectorImpl<MCFixup> &Fixups,
893 const MCSubtargetInfo &STI) const {
894 assert(MI.getOperand(OpNo).isImm());
895 const MCOperand &MO = MI.getOperand(OpNo);
896 unsigned Value = MO.getImm();
897 switch (Value) {
898 case 128: return 0x0;
899 case 1: return 0x1;
900 case 2: return 0x2;
901 case 3: return 0x3;
902 case 4: return 0x4;
903 case 7: return 0x5;
904 case 8: return 0x6;
905 case 15: return 0x7;
906 case 16: return 0x8;
907 case 31: return 0x9;
908 case 32: return 0xa;
909 case 63: return 0xb;
910 case 64: return 0xc;
911 case 255: return 0xd;
912 case 32768: return 0xe;
913 case 65535: return 0xf;
914 }
915 llvm_unreachable("Unexpected value");
916}
917
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000918unsigned
919MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
920 SmallVectorImpl<MCFixup> &Fixups,
921 const MCSubtargetInfo &STI) const {
922 unsigned res = 0;
923
924 // Register list operand is always first operand of instruction and it is
925 // placed before memory operand (register + imm).
926
927 for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
928 unsigned Reg = MI.getOperand(I).getReg();
929 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
930 if (RegNo != 31)
931 res++;
932 else
933 res |= 0x10;
934 }
935 return res;
936}
937
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000938unsigned
939MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
940 SmallVectorImpl<MCFixup> &Fixups,
941 const MCSubtargetInfo &STI) const {
942 return (MI.getNumOperands() - 4);
943}
944
Zoran Jovanovic2deca342014-12-16 14:59:10 +0000945unsigned
946MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
947 SmallVectorImpl<MCFixup> &Fixups,
948 const MCSubtargetInfo &STI) const {
949 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
950}
951
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000952unsigned
Zoran Jovanovic41688672015-02-10 16:36:20 +0000953MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
954 SmallVectorImpl<MCFixup> &Fixups,
955 const MCSubtargetInfo &STI) const {
956 unsigned res = 0;
957
958 if (MI.getOperand(0).getReg() == Mips::A1 &&
959 MI.getOperand(1).getReg() == Mips::A2)
960 res = 0;
961 else if (MI.getOperand(0).getReg() == Mips::A1 &&
962 MI.getOperand(1).getReg() == Mips::A3)
963 res = 1;
964 else if (MI.getOperand(0).getReg() == Mips::A2 &&
965 MI.getOperand(1).getReg() == Mips::A3)
966 res = 2;
967 else if (MI.getOperand(0).getReg() == Mips::A0 &&
968 MI.getOperand(1).getReg() == Mips::S5)
969 res = 3;
970 else if (MI.getOperand(0).getReg() == Mips::A0 &&
971 MI.getOperand(1).getReg() == Mips::S6)
972 res = 4;
973 else if (MI.getOperand(0).getReg() == Mips::A0 &&
974 MI.getOperand(1).getReg() == Mips::A1)
975 res = 5;
976 else if (MI.getOperand(0).getReg() == Mips::A0 &&
977 MI.getOperand(1).getReg() == Mips::A2)
978 res = 6;
979 else if (MI.getOperand(0).getReg() == Mips::A0 &&
980 MI.getOperand(1).getReg() == Mips::A3)
981 res = 7;
982
983 return res;
984}
985
986unsigned
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000987MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
988 SmallVectorImpl<MCFixup> &Fixups,
989 const MCSubtargetInfo &STI) const {
990 const MCOperand &MO = MI.getOperand(OpNo);
991 assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
992 // The immediate is encoded as 'immediate >> 2'.
993 unsigned Res = static_cast<unsigned>(MO.getImm());
994 assert((Res & 3) == 0);
995 return Res >> 2;
996}
997
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000998#include "MipsGenMCCodeEmitter.inc"