blob: 6fa91adf1872d42100dc55e5709be168fda02389 [file] [log] [blame]
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001//===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
2//
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 is part of the Mips Disassembler.
11//
12//===----------------------------------------------------------------------===//
13
14/* Capstone Disassembler Engine */
15/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
16
17#include <stdio.h>
18#include <string.h>
19
20#include <stdbool.h>
21
22#include <inttypes.h>
23
24#include "../../cs_priv.h"
25
26#include "../../SubtargetFeature.h"
27#include "../../MCInst.h"
28#include "../../MCRegisterInfo.h"
29#include "../../SStream.h"
30
31#include "../../MathExtras.h"
32#include "../../utils.h"
33
34//#include "Mips.h"
35//#include "MipsRegisterInfo.h"
36//#include "MipsSubtarget.h"
37#include "../../MCFixedLenDisassembler.h"
38#include "../../MCInst.h"
39//#include "llvm/MC/MCSubtargetInfo.h"
40#include "../../MCRegisterInfo.h"
41#include "../../MCDisassembler.h"
42
43// Forward declare these because the autogenerated code will reference them.
44// Definitions are further down.
45static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst,
46 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
47
48static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst *Inst,
49 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
50
51static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst,
52 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
53
54static DecodeStatus DecodePtrRegisterClass(MCInst *Inst,
55 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
56
57static DecodeStatus DecodeDSPRRegisterClass(MCInst *Inst,
58 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
59
60static DecodeStatus DecodeFGR64RegisterClass(MCInst *Inst,
61 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
62
63static DecodeStatus DecodeFGR32RegisterClass(MCInst *Inst,
64 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
65
66static DecodeStatus DecodeFGRH32RegisterClass(MCInst *Inst,
67 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
68
69static DecodeStatus DecodeCCRRegisterClass(MCInst *Inst,
70 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
71
72static DecodeStatus DecodeFCCRegisterClass(MCInst *Inst,
73 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
74
75static DecodeStatus DecodeHWRegsRegisterClass(MCInst *Inst,
76 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
77
78static DecodeStatus DecodeAFGR64RegisterClass(MCInst *Inst,
79 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
80
81static DecodeStatus DecodeACC64DSPRegisterClass(MCInst *Inst,
82 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
83
84static DecodeStatus DecodeHI32DSPRegisterClass(MCInst *Inst,
85 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
86
87static DecodeStatus DecodeLO32DSPRegisterClass(MCInst *Inst,
88 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
89
90static DecodeStatus DecodeMSA128BRegisterClass(MCInst *Inst,
91 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
92
93static DecodeStatus DecodeMSA128HRegisterClass(MCInst *Inst,
94 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
95
96static DecodeStatus DecodeMSA128WRegisterClass(MCInst *Inst,
97 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
98
99static DecodeStatus DecodeMSA128DRegisterClass(MCInst *Inst,
100 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
101
102static DecodeStatus DecodeMSACtrlRegisterClass(MCInst *Inst,
103 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
104
105static DecodeStatus DecodeBranchTarget(MCInst *Inst,
106 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder);
107
108static DecodeStatus DecodeJumpTarget(MCInst *Inst,
109 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
110
111// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
112// shifted left by 1 bit.
113static DecodeStatus DecodeBranchTargetMM(MCInst *Inst,
114 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder);
115
116// DecodeJumpTargetMM - Decode microMIPS jump target, which is
117// shifted left by 1 bit.
118static DecodeStatus DecodeJumpTargetMM(MCInst *Inst,
119 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
120
121static DecodeStatus DecodeMem(MCInst *Inst,
122 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
123
124static DecodeStatus DecodeMSA128Mem(MCInst *Inst,
125 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
126
127static DecodeStatus DecodeMemMMImm12(MCInst *Inst,
128 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
129
130static DecodeStatus DecodeMemMMImm16(MCInst *Inst,
131 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
132
133static DecodeStatus DecodeFMem(MCInst *Inst, unsigned Insn,
134 uint64_t Address, MCRegisterInfo *Decoder);
135
136static DecodeStatus DecodeSimm16(MCInst *Inst,
137 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
138
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800139// Decode the immediate field of an LSA instruction which
140// is off by one.
141static DecodeStatus DecodeLSAImm(MCInst *Inst,
142 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
143
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800144static DecodeStatus DecodeInsSize(MCInst *Inst,
145 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
146
147static DecodeStatus DecodeExtSize(MCInst *Inst,
148 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
149
150#define GET_SUBTARGETINFO_ENUM
151#include "MipsGenSubtargetInfo.inc"
152
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800153// Hacky: enable all features for disassembler
154static uint64_t Mips_getFeatureBits(int mode)
155{
Nguyen Anh Quynha1fbd4a2013-12-11 17:48:48 +0800156 uint64_t Bits = -1; // include every features by default
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800157
158 // ref: MipsGenDisassemblerTables.inc::checkDecoderPredicate()
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800159 // some features are mutually execlusive
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800160 if (mode & CS_MODE_16) {
Nguyen Anh Quynha1fbd4a2013-12-11 17:48:48 +0800161 Bits &= ~Mips_FeatureMips32r2;
162 Bits &= ~Mips_FeatureMips32;
163 Bits &= ~Mips_FeatureFPIdx;
164 Bits &= ~Mips_FeatureBitCount;
165 Bits &= ~Mips_FeatureSwap;
166 Bits &= ~Mips_FeatureSEInReg;
167 Bits &= ~Mips_FeatureMips64r2;
168 Bits &= ~Mips_FeatureFP64Bit;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800169 } else if (mode & CS_MODE_32) {
Nguyen Anh Quynha1fbd4a2013-12-11 17:48:48 +0800170 Bits &= ~Mips_FeatureMips16;
171 Bits &= ~Mips_FeatureFP64Bit;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800172 } else if (mode & CS_MODE_64) {
Nguyen Anh Quynha1fbd4a2013-12-11 17:48:48 +0800173 Bits &= ~Mips_FeatureMips16;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800174 }
175
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800176 if (mode & CS_MODE_MICRO)
Nguyen Anh Quynha1fbd4a2013-12-11 17:48:48 +0800177 Bits |= Mips_FeatureMicroMips;
Nguyen Anh Quynh748a70a2013-12-15 00:16:32 +0800178 else
179 Bits &= ~Mips_FeatureMicroMips;
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800180
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800181 return Bits;
182}
183
184#include "MipsGenDisassemblerTables.inc"
185
186#define GET_REGINFO_ENUM
187#include "MipsGenRegisterInfo.inc"
188
189#define GET_REGINFO_MC_DESC
190#include "MipsGenRegisterInfo.inc"
191
192#define GET_INSTRINFO_ENUM
193#include "MipsGenInstrInfo.inc"
194
195void Mips_init(MCRegisterInfo *MRI)
196{
197 // InitMCRegisterInfo(MipsRegDesc, 317,
198 // RA, PC,
199 // MipsMCRegisterClasses, 34,
200 // MipsRegUnitRoots, 196,
201 // MipsRegDiffLists,
202 // MipsRegStrings,
203 // MipsSubRegIdxLists, 12,
204 // MipsSubRegIdxRanges, MipsRegEncodingTable);
205 MCRegisterInfo_InitMCRegisterInfo(MRI, MipsRegDesc, 317,
206 0, 0,
207 MipsMCRegisterClasses, 34,
208 0, 0,
209 MipsRegDiffLists,
210 0,
211 MipsSubRegIdxLists, 12,
212 0);
213}
214
215/// readInstruction - read four bytes from the MemoryObject
216/// and return 32 bit word sorted according to the given endianess
217static DecodeStatus readInstruction32(unsigned char *code, uint32_t *insn, bool isBigEndian, bool isMicroMips)
218{
219 // We want to read exactly 4 Bytes of data.
220 if (isBigEndian) {
221 // Encoded as a big-endian 32-bit word in the stream.
222 *insn = (code[3] << 0) |
223 (code[2] << 8) |
224 (code[1] << 16) |
225 (code[0] << 24);
226 } else {
227 // Encoded as a small-endian 32-bit word in the stream.
228 // Little-endian byte ordering:
229 // mips32r2: 4 | 3 | 2 | 1
230 // microMIPS: 2 | 1 | 4 | 3
231 if (isMicroMips) {
232 *insn = (code[2] << 0) |
233 (code[3] << 8) |
234 (code[0] << 16) |
235 (code[1] << 24);
236 } else {
237 *insn = (code[0] << 0) |
238 (code[1] << 8) |
239 (code[2] << 16) |
240 (code[3] << 24);
241 }
242 }
243
244 return MCDisassembler_Success;
245}
246
247static DecodeStatus MipsDisassembler_getInstruction(int mode, MCInst *instr,
pancakef0e4eed2013-12-11 22:14:42 +0100248 const uint8_t *code, size_t code_len,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800249 uint16_t *Size,
Nguyen Anh Quynh778ec162013-12-11 18:25:56 +0800250 uint64_t Address, bool isBigEndian, MCRegisterInfo *MRI)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800251{
252 uint32_t Insn;
253
254 if (code_len < 4)
255 // not enough data
256 return MCDisassembler_Fail;
257
258 DecodeStatus Result = readInstruction32((unsigned char*)code, &Insn, isBigEndian,
Nguyen Anh Quynh1f449282013-12-15 14:04:59 +0800259 mode & CS_MODE_MICRO);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800260 if (Result == MCDisassembler_Fail)
261 return MCDisassembler_Fail;
262
Nguyen Anh Quynh1f449282013-12-15 14:04:59 +0800263 if (mode & CS_MODE_MICRO) {
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800264 // Calling the auto-generated decoder function.
265 Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address, MRI, mode);
266 if (Result != MCDisassembler_Fail) {
267 *Size = 4;
268 return Result;
269 }
270 return MCDisassembler_Fail;
271 }
272
273 // Calling the auto-generated decoder function.
274 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, MRI, mode);
275 if (Result != MCDisassembler_Fail) {
276 *Size = 4;
277 return Result;
278 }
279
280 return MCDisassembler_Fail;
281}
282
pancakef0e4eed2013-12-11 22:14:42 +0100283bool Mips_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,
pancakec04f8732013-12-03 02:51:46 +0100284 uint16_t *size, uint64_t address, void *info)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800285{
286 cs_struct *handle = (cs_struct *)(uintptr_t)ud;
287
288 DecodeStatus status = MipsDisassembler_getInstruction(handle->mode, instr,
289 code, code_len,
290 size,
Nguyen Anh Quynh778ec162013-12-11 18:25:56 +0800291 address, handle->big_endian, (MCRegisterInfo *)info);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800292
293 return status == MCDisassembler_Success;
294}
295
296static DecodeStatus Mips64Disassembler_getInstruction(int mode, MCInst *instr,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +0800297 unsigned char *code, size_t code_len,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800298 uint16_t *Size,
Nguyen Anh Quynh9cf170b2013-12-03 15:17:41 +0800299 uint64_t Address, bool isBigEndian, MCRegisterInfo *MRI)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800300{
301 uint32_t Insn;
302
303 DecodeStatus Result = readInstruction32((unsigned char*)code, &Insn, isBigEndian, false);
304 if (Result == MCDisassembler_Fail)
305 return MCDisassembler_Fail;
306
307 // Calling the auto-generated decoder function.
308 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address, MRI, mode);
309 if (Result != MCDisassembler_Fail) {
310 *Size = 4;
311 return Result;
312 }
313 // If we fail to decode in Mips64 decoder space we can try in Mips32
314 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, MRI, mode);
315 if (Result != MCDisassembler_Fail) {
316 *Size = 4;
317 return Result;
318 }
319
320 return MCDisassembler_Fail;
321}
322
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +0800323bool Mips64_getInstruction(csh ud, unsigned char *code, size_t code_len, MCInst *instr,
Nguyen Anh Quynh9cf170b2013-12-03 15:17:41 +0800324 uint16_t *size, uint64_t address, void *info)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800325{
326 cs_struct *handle = (cs_struct *)(uintptr_t)ud;
327
328 DecodeStatus status = Mips64Disassembler_getInstruction(handle->mode, instr,
329 code, code_len,
330 size,
331 address, handle->big_endian, (MCRegisterInfo *)info);
332
333 return status == MCDisassembler_Success;
334}
335
336static unsigned getReg(MCRegisterInfo *MRI, unsigned RC, unsigned RegNo)
337{
338 //MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
339 //return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
340 MCRegisterClass *rc = MCRegisterInfo_getRegClass(MRI, RC);
341 return rc->RegsBegin[RegNo];
342}
343
344static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst *Inst,
345 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
346{
347 return MCDisassembler_Fail;
348}
349
350static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst,
351 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
352{
353 if (RegNo > 31)
354 return MCDisassembler_Fail;
355
356 unsigned Reg = getReg(Decoder, Mips_GPR64RegClassID, RegNo);
357 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
358 return MCDisassembler_Success;
359}
360
361static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst,
362 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
363{
364 if (RegNo > 31)
365 return MCDisassembler_Fail;
366 unsigned Reg = getReg(Decoder, Mips_GPR32RegClassID, RegNo);
367 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
368 return MCDisassembler_Success;
369}
370
371static DecodeStatus DecodePtrRegisterClass(MCInst *Inst,
372 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
373{
Nguyen Anh Quynh778ec162013-12-11 18:25:56 +0800374 if (Inst->mode & CS_MODE_N64)
375 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
376
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800377 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
378}
379
380static DecodeStatus DecodeDSPRRegisterClass(MCInst *Inst,
381 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
382{
383 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
384}
385
386static DecodeStatus DecodeFGR64RegisterClass(MCInst *Inst,
387 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
388{
389 if (RegNo > 31)
390 return MCDisassembler_Fail;
391
392 unsigned Reg = getReg(Decoder, Mips_FGR64RegClassID, RegNo);
393 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
394 return MCDisassembler_Success;
395}
396
397static DecodeStatus DecodeFGR32RegisterClass(MCInst *Inst,
398 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
399{
400 if (RegNo > 31)
401 return MCDisassembler_Fail;
402
403 unsigned Reg = getReg(Decoder, Mips_FGR32RegClassID, RegNo);
404 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
405 return MCDisassembler_Success;
406}
407
408static DecodeStatus DecodeFGRH32RegisterClass(MCInst *Inst,
409 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
410{
411 if (RegNo > 31)
412 return MCDisassembler_Fail;
413
414 unsigned Reg = getReg(Decoder, Mips_FGRH32RegClassID, RegNo);
415 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
416 return MCDisassembler_Success;
417}
418
419static DecodeStatus DecodeCCRRegisterClass(MCInst *Inst,
420 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
421{
422 if (RegNo > 31)
423 return MCDisassembler_Fail;
424
425 unsigned Reg = getReg(Decoder, Mips_CCRRegClassID, RegNo);
426 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
427 return MCDisassembler_Success;
428}
429
430static DecodeStatus DecodeFCCRegisterClass(MCInst *Inst,
431 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
432{
433 if (RegNo > 7)
434 return MCDisassembler_Fail;
435
436 unsigned Reg = getReg(Decoder, Mips_FCCRegClassID, RegNo);
437 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
438 return MCDisassembler_Success;
439}
440
441static DecodeStatus DecodeMem(MCInst *Inst,
442 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
443{
444 int Offset = SignExtend32(Insn & 0xffff, 16);
445 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
446 unsigned Base = fieldFromInstruction(Insn, 21, 5);
447
448 Reg = getReg(Decoder, Mips_GPR32RegClassID, Reg);
449 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
450
451 if(MCInst_getOpcode(Inst) == Mips_SC){
452 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
453 }
454
455 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
456 MCInst_addOperand(Inst, MCOperand_CreateReg(Base));
457 MCInst_addOperand(Inst, MCOperand_CreateImm(Offset));
458
459 return MCDisassembler_Success;
460}
461
462static DecodeStatus DecodeMSA128Mem(MCInst *Inst, unsigned Insn,
463 uint64_t Address, MCRegisterInfo *Decoder)
464{
465 int Offset = SignExtend32(fieldFromInstruction(Insn, 16, 10), 10);
466 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
467 unsigned Base = fieldFromInstruction(Insn, 11, 5);
468
469 Reg = getReg(Decoder, Mips_MSA128BRegClassID, Reg);
470 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
471
472 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
473 MCInst_addOperand(Inst, MCOperand_CreateReg(Base));
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800474 // MCInst_addOperand(Inst, MCOperand_CreateImm(Offset));
475
476 // The immediate field of an LD/ST instruction is scaled which means it must
477 // be multiplied (when decoding) by the size (in bytes) of the instructions'
478 // data format.
479 // .b - 1 byte
480 // .h - 2 bytes
481 // .w - 4 bytes
482 // .d - 8 bytes
483 switch(MCInst_getOpcode(Inst))
484 {
485 default:
486 //assert (0 && "Unexpected instruction");
487 return MCDisassembler_Fail;
488 break;
489 case Mips_LD_B:
490 case Mips_ST_B:
491 MCInst_addOperand(Inst, MCOperand_CreateImm(Offset));
492 break;
493 case Mips_LD_H:
494 case Mips_ST_H:
495 MCInst_addOperand(Inst, MCOperand_CreateImm(Offset << 1));
496 break;
497 case Mips_LD_W:
498 case Mips_ST_W:
499 MCInst_addOperand(Inst, MCOperand_CreateImm(Offset << 2));
500 break;
501 case Mips_LD_D:
502 case Mips_ST_D:
503 MCInst_addOperand(Inst, MCOperand_CreateImm(Offset << 3));
504 break;
505 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800506
507 return MCDisassembler_Success;
508}
509
510static DecodeStatus DecodeMemMMImm12(MCInst *Inst,
511 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
512{
513 int Offset = SignExtend32(Insn & 0x0fff, 12);
514 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
515 unsigned Base = fieldFromInstruction(Insn, 16, 5);
516
517 Reg = getReg(Decoder, Mips_GPR32RegClassID, Reg);
518 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
519
520 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
521 MCInst_addOperand(Inst, MCOperand_CreateReg(Base));
522 MCInst_addOperand(Inst, MCOperand_CreateImm(Offset));
523
524 return MCDisassembler_Success;
525}
526
527static DecodeStatus DecodeMemMMImm16(MCInst *Inst,
528 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
529{
530 int Offset = SignExtend32(Insn & 0xffff, 16);
531 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
532 unsigned Base = fieldFromInstruction(Insn, 16, 5);
533
534 Reg = getReg(Decoder, Mips_GPR32RegClassID, Reg);
535 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
536
537 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
538 MCInst_addOperand(Inst, MCOperand_CreateReg(Base));
539 MCInst_addOperand(Inst, MCOperand_CreateImm(Offset));
540
541 return MCDisassembler_Success;
542}
543
544static DecodeStatus DecodeFMem(MCInst *Inst,
545 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
546{
547 int Offset = SignExtend32(Insn & 0xffff, 16);
548 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
549 unsigned Base = fieldFromInstruction(Insn, 21, 5);
550
551 Reg = getReg(Decoder, Mips_FGR64RegClassID, Reg);
552 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
553
554 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
555 MCInst_addOperand(Inst, MCOperand_CreateReg(Base));
556 MCInst_addOperand(Inst, MCOperand_CreateImm(Offset));
557
558 return MCDisassembler_Success;
559}
560
561static DecodeStatus DecodeHWRegsRegisterClass(MCInst *Inst,
562 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
563{
564 // Currently only hardware register 29 is supported.
565 if (RegNo != 29)
566 return MCDisassembler_Fail;
567 MCInst_addOperand(Inst, MCOperand_CreateReg(Mips_HWR29));
568 return MCDisassembler_Success;
569}
570
571static DecodeStatus DecodeAFGR64RegisterClass(MCInst *Inst,
572 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
573{
574 if (RegNo > 30 || RegNo %2)
575 return MCDisassembler_Fail;
576
577 unsigned Reg = getReg(Decoder, Mips_AFGR64RegClassID, RegNo /2);
578 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
579 return MCDisassembler_Success;
580}
581
582static DecodeStatus DecodeACC64DSPRegisterClass(MCInst *Inst,
583 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
584{
585 if (RegNo >= 4)
586 return MCDisassembler_Fail;
587
588 unsigned Reg = getReg(Decoder, Mips_ACC64DSPRegClassID, RegNo);
589 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
590 return MCDisassembler_Success;
591}
592
593static DecodeStatus DecodeHI32DSPRegisterClass(MCInst *Inst,
594 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
595{
596 if (RegNo >= 4)
597 return MCDisassembler_Fail;
598
599 unsigned Reg = getReg(Decoder, Mips_HI32DSPRegClassID, RegNo);
600 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
601 return MCDisassembler_Success;
602}
603
604static DecodeStatus DecodeLO32DSPRegisterClass(MCInst *Inst,
605 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
606{
607 if (RegNo >= 4)
608 return MCDisassembler_Fail;
609
610 unsigned Reg = getReg(Decoder, Mips_LO32DSPRegClassID, RegNo);
611 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
612 return MCDisassembler_Success;
613}
614
615static DecodeStatus DecodeMSA128BRegisterClass(MCInst *Inst,
616 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
617{
618 if (RegNo > 31)
619 return MCDisassembler_Fail;
620
621 unsigned Reg = getReg(Decoder, Mips_MSA128BRegClassID, RegNo);
622 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
623
624 return MCDisassembler_Success;
625}
626
627static DecodeStatus DecodeMSA128HRegisterClass(MCInst *Inst,
628 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
629{
630 if (RegNo > 31)
631 return MCDisassembler_Fail;
632
633 unsigned Reg = getReg(Decoder, Mips_MSA128HRegClassID, RegNo);
634 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
635
636 return MCDisassembler_Success;
637}
638
639static DecodeStatus DecodeMSA128WRegisterClass(MCInst *Inst,
640 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
641{
642 if (RegNo > 31)
643 return MCDisassembler_Fail;
644
645 unsigned Reg = getReg(Decoder, Mips_MSA128WRegClassID, RegNo);
646 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
647
648 return MCDisassembler_Success;
649}
650
651static DecodeStatus DecodeMSA128DRegisterClass(MCInst *Inst,
652 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
653{
654 if (RegNo > 31)
655 return MCDisassembler_Fail;
656
657 unsigned Reg = getReg(Decoder, Mips_MSA128DRegClassID, RegNo);
658 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
659
660 return MCDisassembler_Success;
661}
662
663static DecodeStatus DecodeMSACtrlRegisterClass(MCInst *Inst,
664 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
665{
666 if (RegNo > 7)
667 return MCDisassembler_Fail;
668
669 unsigned Reg = getReg(Decoder, Mips_MSACtrlRegClassID, RegNo);
670 MCInst_addOperand(Inst, MCOperand_CreateReg(Reg));
671
672 return MCDisassembler_Success;
673}
674
675static DecodeStatus DecodeBranchTarget(MCInst *Inst,
676 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder)
677{
678 unsigned BranchOffset = Offset & 0xffff;
679 BranchOffset = SignExtend32(BranchOffset << 2, 18) + 4;
680 MCInst_addOperand(Inst, MCOperand_CreateImm(BranchOffset));
681 return MCDisassembler_Success;
682}
683
684static DecodeStatus DecodeJumpTarget(MCInst *Inst,
685 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
686{
687 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
688 MCInst_addOperand(Inst, MCOperand_CreateImm(JumpOffset));
689 return MCDisassembler_Success;
690}
691
692static DecodeStatus DecodeBranchTargetMM(MCInst *Inst,
693 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder)
694{
695 unsigned BranchOffset = Offset & 0xffff;
696 BranchOffset = SignExtend32(BranchOffset << 1, 18);
697 MCInst_addOperand(Inst, MCOperand_CreateImm(BranchOffset));
698 return MCDisassembler_Success;
699}
700
701static DecodeStatus DecodeJumpTargetMM(MCInst *Inst,
702 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
703{
704 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
705 MCInst_addOperand(Inst, MCOperand_CreateImm(JumpOffset));
706 return MCDisassembler_Success;
707}
708
709static DecodeStatus DecodeSimm16(MCInst *Inst,
710 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
711{
712 MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Insn, 16)));
713 return MCDisassembler_Success;
714}
715
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800716static DecodeStatus DecodeLSAImm(MCInst *Inst,
717 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
718{
719 // We add one to the immediate field as it was encoded as 'imm - 1'.
720 MCInst_addOperand(Inst, MCOperand_CreateImm(Insn + 1));
721 return MCDisassembler_Success;
722}
723
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800724static DecodeStatus DecodeInsSize(MCInst *Inst,
725 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
726{
727 // First we need to grab the pos(lsb) from MCInst.
728 int Pos = MCOperand_getImm(MCInst_getOperand(Inst, 2));
729 int Size = (int) Insn - Pos + 1;
730 MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Size, 16)));
731 return MCDisassembler_Success;
732}
733
734static DecodeStatus DecodeExtSize(MCInst *Inst,
735 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
736{
737 int Size = (int) Insn + 1;
738 MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Size, 16)));
739 return MCDisassembler_Success;
740}