blob: 5d72005b2a6bd1aece096cce785d06b71ecba1dc [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
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +080014/* Capstone Disassembly Engine */
15/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080016
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +080017#ifdef CAPSTONE_HAS_MIPS
18
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080019#include <stdio.h>
20#include <string.h>
21
Yegor Derevenetsced9d242014-09-21 17:27:11 +020022#include "../../inttypes.h"
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080023
Nguyen Anh Quynhc7404072014-01-05 11:35:47 +080024#include "../../utils.h"
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080025
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080026#include "../../MCInst.h"
27#include "../../MCRegisterInfo.h"
28#include "../../SStream.h"
29
30#include "../../MathExtras.h"
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080031
32//#include "Mips.h"
33//#include "MipsRegisterInfo.h"
34//#include "MipsSubtarget.h"
35#include "../../MCFixedLenDisassembler.h"
36#include "../../MCInst.h"
37//#include "llvm/MC/MCSubtargetInfo.h"
38#include "../../MCRegisterInfo.h"
39#include "../../MCDisassembler.h"
40
41// Forward declare these because the autogenerated code will reference them.
42// Definitions are further down.
43static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst,
44 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
45
46static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst *Inst,
47 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
48
49static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst,
50 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
51
52static DecodeStatus DecodePtrRegisterClass(MCInst *Inst,
53 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
54
55static DecodeStatus DecodeDSPRRegisterClass(MCInst *Inst,
56 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
57
58static DecodeStatus DecodeFGR64RegisterClass(MCInst *Inst,
59 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
60
61static DecodeStatus DecodeFGR32RegisterClass(MCInst *Inst,
62 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
63
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080064static DecodeStatus DecodeCCRRegisterClass(MCInst *Inst,
65 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
66
67static DecodeStatus DecodeFCCRegisterClass(MCInst *Inst,
68 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
69
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +080070static DecodeStatus DecodeCCRegisterClass(MCInst *Inst,
71 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
72
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +080073static DecodeStatus DecodeFGRCCRegisterClass(MCInst *Inst,
74 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
75
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080076static DecodeStatus DecodeHWRegsRegisterClass(MCInst *Inst,
77 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
78
79static DecodeStatus DecodeAFGR64RegisterClass(MCInst *Inst,
80 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
81
82static DecodeStatus DecodeACC64DSPRegisterClass(MCInst *Inst,
83 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
84
85static DecodeStatus DecodeHI32DSPRegisterClass(MCInst *Inst,
86 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
87
88static DecodeStatus DecodeLO32DSPRegisterClass(MCInst *Inst,
89 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
90
91static DecodeStatus DecodeMSA128BRegisterClass(MCInst *Inst,
92 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
93
94static DecodeStatus DecodeMSA128HRegisterClass(MCInst *Inst,
95 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
96
97static DecodeStatus DecodeMSA128WRegisterClass(MCInst *Inst,
98 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
99
100static DecodeStatus DecodeMSA128DRegisterClass(MCInst *Inst,
101 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
102
103static DecodeStatus DecodeMSACtrlRegisterClass(MCInst *Inst,
104 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
105
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800106static DecodeStatus DecodeCOP2RegisterClass(MCInst *Inst,
107 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder);
108
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800109static DecodeStatus DecodeBranchTarget(MCInst *Inst,
110 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder);
111
112static DecodeStatus DecodeJumpTarget(MCInst *Inst,
113 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
114
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800115static DecodeStatus DecodeBranchTarget21(MCInst *Inst,
116 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder);
117
118static DecodeStatus DecodeBranchTarget26(MCInst *Inst,
119 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder);
120
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800121// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
122// shifted left by 1 bit.
123static DecodeStatus DecodeBranchTargetMM(MCInst *Inst,
124 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder);
125
126// DecodeJumpTargetMM - Decode microMIPS jump target, which is
127// shifted left by 1 bit.
128static DecodeStatus DecodeJumpTargetMM(MCInst *Inst,
129 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
130
131static DecodeStatus DecodeMem(MCInst *Inst,
132 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
133
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800134static DecodeStatus DecodeCachePref(MCInst *Inst,
135 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
136
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800137static DecodeStatus DecodeMSA128Mem(MCInst *Inst,
138 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
139
140static DecodeStatus DecodeMemMMImm12(MCInst *Inst,
141 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
142
143static DecodeStatus DecodeMemMMImm16(MCInst *Inst,
144 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
145
146static DecodeStatus DecodeFMem(MCInst *Inst, unsigned Insn,
147 uint64_t Address, MCRegisterInfo *Decoder);
148
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800149static DecodeStatus DecodeCOP2Mem(MCInst *Inst, unsigned Insn,
150 uint64_t Address, MCRegisterInfo *Decoder);
151
152static DecodeStatus DecodeCOP3Mem(MCInst *Inst, unsigned Insn,
153 uint64_t Address, MCRegisterInfo *Decoder);
154
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800155static DecodeStatus DecodeSpecial3LlSc(MCInst *Inst,
156 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
157
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800158static DecodeStatus DecodeSimm16(MCInst *Inst,
159 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
160
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800161// Decode the immediate field of an LSA instruction which
162// is off by one.
163static DecodeStatus DecodeLSAImm(MCInst *Inst,
164 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
165
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800166static DecodeStatus DecodeInsSize(MCInst *Inst,
167 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
168
169static DecodeStatus DecodeExtSize(MCInst *Inst,
170 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
171
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800172static DecodeStatus DecodeSimm19Lsl2(MCInst *Inst,
173 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
174
175static DecodeStatus DecodeSimm18Lsl3(MCInst *Inst,
176 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder);
177
178/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
179/// handle.
180static DecodeStatus DecodeINSVE_DF_4(MCInst *MI,
181 uint32_t insn, uint64_t Address, MCRegisterInfo *Decoder);
182
183static DecodeStatus DecodeAddiGroupBranch_4(MCInst *MI,
184 uint32_t insn, uint64_t Address, MCRegisterInfo *Decoder);
185
186static DecodeStatus DecodeDaddiGroupBranch_4(MCInst *MI,
187 uint32_t insn, uint64_t Address, MCRegisterInfo *Decoder);
188
189static DecodeStatus DecodeBlezlGroupBranch_4(MCInst *MI,
190 uint32_t insn, uint64_t Address, MCRegisterInfo *Decoder);
191
192static DecodeStatus DecodeBgtzlGroupBranch_4(MCInst *MI,
193 uint32_t insn, uint64_t Address, MCRegisterInfo *Decoder);
194
195static DecodeStatus DecodeBgtzGroupBranch_4(MCInst *MI,
196 uint32_t insn, uint64_t Address, MCRegisterInfo *Decoder);
197
198static DecodeStatus DecodeBlezGroupBranch_4(MCInst *MI,
199 uint32_t insn, uint64_t Address, MCRegisterInfo *Decoder);
200
201
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800202#define GET_SUBTARGETINFO_ENUM
203#include "MipsGenSubtargetInfo.inc"
204
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800205// Hacky: enable all features for disassembler
Nguyen Anh Quynh04ac9c32013-12-31 18:15:12 +0800206static uint64_t getFeatureBits(int mode)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800207{
Alex Ionescu46018db2014-01-22 09:45:00 -0800208 uint64_t Bits = (uint64_t)-1; // include every features by default
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800209
210 // ref: MipsGenDisassemblerTables.inc::checkDecoderPredicate()
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800211 // some features are mutually execlusive
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800212 if (mode & CS_MODE_16) {
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800213 //Bits &= ~Mips_FeatureMips32r2;
214 //Bits &= ~Mips_FeatureMips32;
215 //Bits &= ~Mips_FeatureFPIdx;
216 //Bits &= ~Mips_FeatureBitCount;
217 //Bits &= ~Mips_FeatureSwap;
218 //Bits &= ~Mips_FeatureSEInReg;
219 //Bits &= ~Mips_FeatureMips64r2;
220 //Bits &= ~Mips_FeatureFP64Bit;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800221 } else if (mode & CS_MODE_32) {
Nguyen Anh Quynha1fbd4a2013-12-11 17:48:48 +0800222 Bits &= ~Mips_FeatureMips16;
223 Bits &= ~Mips_FeatureFP64Bit;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800224 Bits &= ~Mips_FeatureMips32r6;
225 Bits &= ~Mips_FeatureMips64r6;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800226 } else if (mode & CS_MODE_64) {
Nguyen Anh Quynha1fbd4a2013-12-11 17:48:48 +0800227 Bits &= ~Mips_FeatureMips16;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800228 Bits &= ~Mips_FeatureMips64r6;
229 Bits &= ~Mips_FeatureMips64r6;
Nguyen Anh Quynh05bd2942014-11-10 15:20:49 +0800230 Bits &= ~Mips_FeatureMips32r6;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800231 }
232
Nguyen Anh Quynh248519e2014-11-09 14:07:07 +0800233 if (mode & CS_MODE_MIPS32R6) {
234 Bits |= Mips_FeatureMips32r6;
235 }
236
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800237 if (mode & CS_MODE_MICRO) {
Nguyen Anh Quynha1fbd4a2013-12-11 17:48:48 +0800238 Bits |= Mips_FeatureMicroMips;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800239 Bits &= ~Mips_FeatureMips4_32r2;
240 Bits &= ~Mips_FeatureMips2;
241 } else {
Nguyen Anh Quynh748a70a2013-12-15 00:16:32 +0800242 Bits &= ~Mips_FeatureMicroMips;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800243 }
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800244
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800245 return Bits;
246}
247
248#include "MipsGenDisassemblerTables.inc"
249
250#define GET_REGINFO_ENUM
251#include "MipsGenRegisterInfo.inc"
252
253#define GET_REGINFO_MC_DESC
254#include "MipsGenRegisterInfo.inc"
255
256#define GET_INSTRINFO_ENUM
257#include "MipsGenInstrInfo.inc"
258
259void Mips_init(MCRegisterInfo *MRI)
260{
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800261 // InitMCRegisterInfo(MipsRegDesc, 394, RA, PC,
262 // MipsMCRegisterClasses, 48,
263 // MipsRegUnitRoots,
264 // 273,
265 // MipsRegDiffLists,
266 // MipsRegStrings,
267 // MipsSubRegIdxLists,
268 // 12,
269 // MipsSubRegIdxRanges,
270 // MipsRegEncodingTable);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800271
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800272 MCRegisterInfo_InitMCRegisterInfo(MRI, MipsRegDesc, 394,
Jay Oster79e253c2014-10-12 16:03:12 -0700273 0, 0,
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800274 MipsMCRegisterClasses, 48,
Jay Oster79e253c2014-10-12 16:03:12 -0700275 0, 0,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800276 MipsRegDiffLists,
Jay Oster79e253c2014-10-12 16:03:12 -0700277 0,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800278 MipsSubRegIdxLists, 12,
279 0);
280}
281
282/// readInstruction - read four bytes from the MemoryObject
283/// and return 32 bit word sorted according to the given endianess
284static DecodeStatus readInstruction32(unsigned char *code, uint32_t *insn, bool isBigEndian, bool isMicroMips)
285{
286 // We want to read exactly 4 Bytes of data.
287 if (isBigEndian) {
288 // Encoded as a big-endian 32-bit word in the stream.
289 *insn = (code[3] << 0) |
290 (code[2] << 8) |
291 (code[1] << 16) |
292 (code[0] << 24);
293 } else {
294 // Encoded as a small-endian 32-bit word in the stream.
295 // Little-endian byte ordering:
296 // mips32r2: 4 | 3 | 2 | 1
297 // microMIPS: 2 | 1 | 4 | 3
298 if (isMicroMips) {
299 *insn = (code[2] << 0) |
300 (code[3] << 8) |
301 (code[0] << 16) |
302 (code[1] << 24);
303 } else {
304 *insn = (code[0] << 0) |
305 (code[1] << 8) |
306 (code[2] << 16) |
307 (code[3] << 24);
308 }
309 }
310
311 return MCDisassembler_Success;
312}
313
314static DecodeStatus MipsDisassembler_getInstruction(int mode, MCInst *instr,
pancakef0e4eed2013-12-11 22:14:42 +0100315 const uint8_t *code, size_t code_len,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800316 uint16_t *Size,
Nguyen Anh Quynh778ec162013-12-11 18:25:56 +0800317 uint64_t Address, bool isBigEndian, MCRegisterInfo *MRI)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800318{
319 uint32_t Insn;
Nguyen Anh Quynha82a0892014-01-23 23:42:40 +0800320 DecodeStatus Result;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800321
322 if (code_len < 4)
323 // not enough data
324 return MCDisassembler_Fail;
325
Nguyen Anh Quynh0c07cc92014-08-27 22:31:54 +0800326 if (instr->flat_insn->detail) {
327 memset(instr->flat_insn->detail, 0, sizeof(cs_detail));
328 }
Nguyen Anh Quynh69582d72014-06-09 17:50:01 +0700329
Alex Ionescu46018db2014-01-22 09:45:00 -0800330 Result = readInstruction32((unsigned char*)code, &Insn, isBigEndian,
Nguyen Anh Quynh1f449282013-12-15 14:04:59 +0800331 mode & CS_MODE_MICRO);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800332 if (Result == MCDisassembler_Fail)
333 return MCDisassembler_Fail;
334
Nguyen Anh Quynh1f449282013-12-15 14:04:59 +0800335 if (mode & CS_MODE_MICRO) {
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800336 // Calling the auto-generated decoder function.
337 Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address, MRI, mode);
338 if (Result != MCDisassembler_Fail) {
339 *Size = 4;
340 return Result;
341 }
342 return MCDisassembler_Fail;
343 }
344
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800345 if (((mode & CS_MODE_32) == 0) && ((mode & CS_MODE_MIPS3) == 0)) { // COP3
346 // DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
347 Result = decodeInstruction(DecoderTableCOP3_32, instr, Insn, Address, MRI, mode);
348 if (Result != MCDisassembler_Fail) {
349 *Size = 4;
350 return Result;
351 }
352 }
353
354 if (((mode & CS_MODE_MIPS32R6) != 0) && ((mode & CS_MODE_MIPSGP64) != 0)) {
355 // DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
356 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, instr, Insn,
357 Address, MRI, mode);
358 if (Result != MCDisassembler_Fail) {
359 *Size = 4;
360 return Result;
361 }
362 }
363
364 if ((mode & CS_MODE_MIPS32R6) != 0) {
365 // DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
366 Result = decodeInstruction(DecoderTableMips32r6_64r632, instr, Insn,
367 Address, MRI, mode);
368 if (Result != MCDisassembler_Fail) {
369 *Size = 4;
370 return Result;
371 }
372 }
373
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800374 // Calling the auto-generated decoder function.
375 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, MRI, mode);
376 if (Result != MCDisassembler_Fail) {
377 *Size = 4;
378 return Result;
379 }
380
381 return MCDisassembler_Fail;
382}
383
Nguyen Anh Quynha5ffdc32014-05-07 08:25:24 +0800384bool Mips_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,
pancakec04f8732013-12-03 02:51:46 +0100385 uint16_t *size, uint64_t address, void *info)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800386{
387 cs_struct *handle = (cs_struct *)(uintptr_t)ud;
388
389 DecodeStatus status = MipsDisassembler_getInstruction(handle->mode, instr,
390 code, code_len,
391 size,
Nguyen Anh Quynh778ec162013-12-11 18:25:56 +0800392 address, handle->big_endian, (MCRegisterInfo *)info);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800393
394 return status == MCDisassembler_Success;
395}
396
397static DecodeStatus Mips64Disassembler_getInstruction(int mode, MCInst *instr,
Nguyen Anh Quynh2cff6f62014-04-28 11:19:44 +0800398 const uint8_t *code, size_t code_len,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800399 uint16_t *Size,
Nguyen Anh Quynh9cf170b2013-12-03 15:17:41 +0800400 uint64_t Address, bool isBigEndian, MCRegisterInfo *MRI)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800401{
402 uint32_t Insn;
403
404 DecodeStatus Result = readInstruction32((unsigned char*)code, &Insn, isBigEndian, false);
405 if (Result == MCDisassembler_Fail)
406 return MCDisassembler_Fail;
407
Nguyen Anh Quynh0c07cc92014-08-27 22:31:54 +0800408 if (instr->flat_insn->detail) {
409 memset(instr->flat_insn->detail, 0, sizeof(cs_detail));
410 }
Nguyen Anh Quynh69582d72014-06-09 17:50:01 +0700411
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800412 // Calling the auto-generated decoder function.
413 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address, MRI, mode);
414 if (Result != MCDisassembler_Fail) {
415 *Size = 4;
416 return Result;
417 }
Nguyen Anh Quynh05bd2942014-11-10 15:20:49 +0800418
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800419 // If we fail to decode in Mips64 decoder space we can try in Mips32
420 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, MRI, mode);
421 if (Result != MCDisassembler_Fail) {
422 *Size = 4;
423 return Result;
424 }
425
426 return MCDisassembler_Fail;
427}
428
Nguyen Anh Quynha5ffdc32014-05-07 08:25:24 +0800429bool Mips64_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,
Nguyen Anh Quynh9cf170b2013-12-03 15:17:41 +0800430 uint16_t *size, uint64_t address, void *info)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800431{
432 cs_struct *handle = (cs_struct *)(uintptr_t)ud;
433
434 DecodeStatus status = Mips64Disassembler_getInstruction(handle->mode, instr,
435 code, code_len,
436 size,
437 address, handle->big_endian, (MCRegisterInfo *)info);
438
439 return status == MCDisassembler_Success;
440}
441
442static unsigned getReg(MCRegisterInfo *MRI, unsigned RC, unsigned RegNo)
443{
444 //MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
445 //return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
446 MCRegisterClass *rc = MCRegisterInfo_getRegClass(MRI, RC);
447 return rc->RegsBegin[RegNo];
448}
449
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800450static DecodeStatus DecodeINSVE_DF_4(MCInst *MI, uint32_t insn,
451 uint64_t Address, MCRegisterInfo *Decoder)
452{
453 typedef DecodeStatus (*DecodeFN)(MCInst *, unsigned, uint64_t, MCRegisterInfo *);
454 // The size of the n field depends on the element size
455 // The register class also depends on this.
456 uint32_t tmp = fieldFromInstruction(insn, 17, 5);
457 unsigned NSize = 0;
Nguyen Anh Quynh9d545442014-10-01 14:16:07 +0800458 DecodeFN RegDecoder = NULL;
459
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800460 if ((tmp & 0x18) == 0x00) { // INSVE_B
461 NSize = 4;
462 RegDecoder = DecodeMSA128BRegisterClass;
463 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
464 NSize = 3;
465 RegDecoder = DecodeMSA128HRegisterClass;
466 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
467 NSize = 2;
468 RegDecoder = DecodeMSA128WRegisterClass;
469 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
470 NSize = 1;
471 RegDecoder = DecodeMSA128DRegisterClass;
472 } //else llvm_unreachable("Invalid encoding");
473
474 //assert(NSize != 0 && RegDecoder != nullptr);
475
Nguyen Anh Quynh9d545442014-10-01 14:16:07 +0800476 if (RegDecoder == NULL)
Nguyen Anh Quynhc96f1b02014-10-01 14:35:29 +0800477 return MCDisassembler_Fail;
Nguyen Anh Quynh9d545442014-10-01 14:16:07 +0800478
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800479 // $wd
480 tmp = fieldFromInstruction(insn, 6, 5);
481 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler_Fail)
482 return MCDisassembler_Fail;
Nguyen Anh Quynh9d545442014-10-01 14:16:07 +0800483
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800484 // $wd_in
485 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler_Fail)
486 return MCDisassembler_Fail;
Nguyen Anh Quynh9d545442014-10-01 14:16:07 +0800487
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800488 // $n
489 tmp = fieldFromInstruction(insn, 16, NSize);
490 MCOperand_CreateImm0(MI, tmp);
Nguyen Anh Quynh9d545442014-10-01 14:16:07 +0800491
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800492 // $ws
493 tmp = fieldFromInstruction(insn, 11, 5);
494 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler_Fail)
495 return MCDisassembler_Fail;
Nguyen Anh Quynh9d545442014-10-01 14:16:07 +0800496
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800497 // $n2
498 MCOperand_CreateImm0(MI, 0);
499
500 return MCDisassembler_Success;
501}
502
503static DecodeStatus DecodeAddiGroupBranch_4(MCInst *MI, uint32_t insn,
504 uint64_t Address, MCRegisterInfo *Decoder)
505{
506 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
507 // (otherwise we would have matched the ADDI instruction from the earlier
508 // ISA's instead).
509 //
510 // We have:
511 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
512 // BOVC if rs >= rt
513 // BEQZALC if rs == 0 && rt != 0
514 // BEQC if rs < rt && rs != 0
515
516 uint32_t Rs = fieldFromInstruction(insn, 21, 5);
517 uint32_t Rt = fieldFromInstruction(insn, 16, 5);
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800518 uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800519 bool HasRs = false;
520
521 if (Rs >= Rt) {
522 MCInst_setOpcode(MI, Mips_BOVC);
523 HasRs = true;
524 } else if (Rs != 0 && Rs < Rt) {
525 MCInst_setOpcode(MI, Mips_BEQC);
526 HasRs = true;
527 } else
528 MCInst_setOpcode(MI, Mips_BEQZALC);
529
530 if (HasRs)
531 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs));
532
533 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt));
534 MCOperand_CreateImm0(MI, Imm);
535
536 return MCDisassembler_Success;
537}
538
539static DecodeStatus DecodeDaddiGroupBranch_4(MCInst *MI, uint32_t insn,
540 uint64_t Address, MCRegisterInfo *Decoder)
541{
542 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
543 // (otherwise we would have matched the ADDI instruction from the earlier
544 // ISA's instead).
545 //
546 // We have:
547 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
548 // BNVC if rs >= rt
549 // BNEZALC if rs == 0 && rt != 0
550 // BNEC if rs < rt && rs != 0
551
552 uint32_t Rs = fieldFromInstruction(insn, 21, 5);
553 uint32_t Rt = fieldFromInstruction(insn, 16, 5);
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800554 uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800555 bool HasRs = false;
556
557 if (Rs >= Rt) {
558 MCInst_setOpcode(MI, Mips_BNVC);
559 HasRs = true;
560 } else if (Rs != 0 && Rs < Rt) {
561 MCInst_setOpcode(MI, Mips_BNEC);
562 HasRs = true;
563 } else
564 MCInst_setOpcode(MI, Mips_BNEZALC);
565
566 if (HasRs)
567 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs));
568
569 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt));
570 MCOperand_CreateImm0(MI, Imm);
571
572 return MCDisassembler_Success;
573}
574
575static DecodeStatus DecodeBlezlGroupBranch_4(MCInst *MI, uint32_t insn,
576 uint64_t Address, MCRegisterInfo *Decoder)
577{
578 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
579 // (otherwise we would have matched the BLEZL instruction from the earlier
580 // ISA's instead).
581 //
582 // We have:
583 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
584 // Invalid if rs == 0
585 // BLEZC if rs == 0 && rt != 0
586 // BGEZC if rs == rt && rt != 0
587 // BGEC if rs != rt && rs != 0 && rt != 0
588
589 uint32_t Rs = fieldFromInstruction(insn, 21, 5);
590 uint32_t Rt = fieldFromInstruction(insn, 16, 5);
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800591 uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800592 bool HasRs = false;
593
594 if (Rt == 0)
595 return MCDisassembler_Fail;
596 else if (Rs == 0)
597 MCInst_setOpcode(MI, Mips_BLEZC);
598 else if (Rs == Rt)
599 MCInst_setOpcode(MI, Mips_BGEZC);
600 else {
601 HasRs = true;
602 MCInst_setOpcode(MI, Mips_BGEC);
603 }
604
605 if (HasRs)
606 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs));
607
608 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt));
609
610 MCOperand_CreateImm0(MI, Imm);
611
612 return MCDisassembler_Success;
613}
614
615static DecodeStatus DecodeBgtzlGroupBranch_4(MCInst *MI, uint32_t insn,
616 uint64_t Address, MCRegisterInfo *Decoder)
617{
618 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
619 // (otherwise we would have matched the BGTZL instruction from the earlier
620 // ISA's instead).
621 //
622 // We have:
623 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
624 // Invalid if rs == 0
625 // BGTZC if rs == 0 && rt != 0
626 // BLTZC if rs == rt && rt != 0
627 // BLTC if rs != rt && rs != 0 && rt != 0
628
629 bool HasRs = false;
630
631 uint32_t Rs = fieldFromInstruction(insn, 21, 5);
632 uint32_t Rt = fieldFromInstruction(insn, 16, 5);
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800633 uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800634
635 if (Rt == 0)
636 return MCDisassembler_Fail;
637 else if (Rs == 0)
638 MCInst_setOpcode(MI, Mips_BGTZC);
639 else if (Rs == Rt)
640 MCInst_setOpcode(MI, Mips_BLTZC);
641 else {
642 MCInst_setOpcode(MI, Mips_BLTC);
643 HasRs = true;
644 }
645
646 if (HasRs)
647 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs));
648
649 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt));
650 MCOperand_CreateImm0(MI, Imm);
651
652 return MCDisassembler_Success;
653}
654
655static DecodeStatus DecodeBgtzGroupBranch_4(MCInst *MI, uint32_t insn,
656 uint64_t Address, MCRegisterInfo *Decoder)
657{
658 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
659 // (otherwise we would have matched the BGTZ instruction from the earlier
660 // ISA's instead).
661 //
662 // We have:
663 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
664 // BGTZ if rt == 0
665 // BGTZALC if rs == 0 && rt != 0
666 // BLTZALC if rs != 0 && rs == rt
667 // BLTUC if rs != 0 && rs != rt
668
669 uint32_t Rs = fieldFromInstruction(insn, 21, 5);
670 uint32_t Rt = fieldFromInstruction(insn, 16, 5);
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800671 uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800672 bool HasRs = false;
673 bool HasRt = false;
674
675 if (Rt == 0) {
676 MCInst_setOpcode(MI, Mips_BGTZ);
677 HasRs = true;
678 } else if (Rs == 0) {
679 MCInst_setOpcode(MI, Mips_BGTZALC);
680 HasRt = true;
681 } else if (Rs == Rt) {
682 MCInst_setOpcode(MI, Mips_BLTZALC);
683 HasRs = true;
684 } else {
685 MCInst_setOpcode(MI, Mips_BLTUC);
686 HasRs = true;
687 HasRt = true;
688 }
689
690 if (HasRs)
691 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs));
692
693 if (HasRt)
694 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt));
695
696 MCOperand_CreateImm0(MI, Imm);
697
698 return MCDisassembler_Success;
699}
700
701static DecodeStatus DecodeBlezGroupBranch_4(MCInst *MI, uint32_t insn,
702 uint64_t Address, MCRegisterInfo *Decoder)
703{
704 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
705 // (otherwise we would have matched the BLEZL instruction from the earlier
706 // ISA's instead).
707 //
708 // We have:
709 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
710 // Invalid if rs == 0
711 // BLEZALC if rs == 0 && rt != 0
712 // BGEZALC if rs == rt && rt != 0
713 // BGEUC if rs != rt && rs != 0 && rt != 0
714
715 uint32_t Rs = fieldFromInstruction(insn, 21, 5);
716 uint32_t Rt = fieldFromInstruction(insn, 16, 5);
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800717 uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800718 bool HasRs = false;
719
720 if (Rt == 0)
721 return MCDisassembler_Fail;
722 else if (Rs == 0)
723 MCInst_setOpcode(MI, Mips_BLEZALC);
724 else if (Rs == Rt)
725 MCInst_setOpcode(MI, Mips_BGEZALC);
726 else {
727 HasRs = true;
728 MCInst_setOpcode(MI, Mips_BGEUC);
729 }
730
731 if (HasRs)
732 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs));
733
734 MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt));
735
736 MCOperand_CreateImm0(MI, Imm);
737
738 return MCDisassembler_Success;
739}
740
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800741static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst *Inst,
742 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
743{
744 return MCDisassembler_Fail;
745}
746
747static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst,
748 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
749{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800750 unsigned Reg;
751
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800752 if (RegNo > 31)
753 return MCDisassembler_Fail;
754
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100755 Reg = getReg(Decoder, Mips_GPR64RegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800756 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800757 return MCDisassembler_Success;
758}
759
760static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst,
761 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
762{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800763 unsigned Reg;
764
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800765 if (RegNo > 31)
766 return MCDisassembler_Fail;
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800767
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100768 Reg = getReg(Decoder, Mips_GPR32RegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800769 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800770 return MCDisassembler_Success;
771}
772
773static DecodeStatus DecodePtrRegisterClass(MCInst *Inst,
774 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
775{
Jay Oster79e253c2014-10-12 16:03:12 -0700776 if (Inst->csh->mode & CS_MODE_64)
Nguyen Anh Quynh778ec162013-12-11 18:25:56 +0800777 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
778
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800779 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
780}
781
782static DecodeStatus DecodeDSPRRegisterClass(MCInst *Inst,
783 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
784{
785 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
786}
787
788static DecodeStatus DecodeFGR64RegisterClass(MCInst *Inst,
789 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
790{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800791 unsigned Reg;
792
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800793 if (RegNo > 31)
794 return MCDisassembler_Fail;
795
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100796 Reg = getReg(Decoder, Mips_FGR64RegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800797 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800798 return MCDisassembler_Success;
799}
800
801static DecodeStatus DecodeFGR32RegisterClass(MCInst *Inst,
802 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
803{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800804 unsigned Reg;
805
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800806 if (RegNo > 31)
807 return MCDisassembler_Fail;
808
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100809 Reg = getReg(Decoder, Mips_FGR32RegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800810 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800811 return MCDisassembler_Success;
812}
813
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800814static DecodeStatus DecodeCCRRegisterClass(MCInst *Inst,
815 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
816{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800817 unsigned Reg;
818
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800819 if (RegNo > 31)
820 return MCDisassembler_Fail;
821
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100822 Reg = getReg(Decoder, Mips_CCRRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800823 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800824 return MCDisassembler_Success;
825}
826
827static DecodeStatus DecodeFCCRegisterClass(MCInst *Inst,
828 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
829{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800830 unsigned Reg;
831
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800832 if (RegNo > 7)
833 return MCDisassembler_Fail;
834
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100835 Reg = getReg(Decoder, Mips_FCCRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800836 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800837 return MCDisassembler_Success;
838}
839
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800840static DecodeStatus DecodeCCRegisterClass(MCInst *Inst,
841 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
842{
843 unsigned Reg;
844
845 if (RegNo > 7)
846 return MCDisassembler_Fail;
847
848 Reg = getReg(Decoder, Mips_CCRegClassID, RegNo);
849 MCOperand_CreateReg0(Inst, Reg);
850 return MCDisassembler_Success;
851}
852
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800853static DecodeStatus DecodeFGRCCRegisterClass(MCInst *Inst,
854 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
855{
856 unsigned Reg;
857
858 if (RegNo > 31)
859 return MCDisassembler_Fail;
860
861 Reg = getReg(Decoder, Mips_FGRCCRegClassID, RegNo);
862 MCOperand_CreateReg0(Inst, Reg);
863 return MCDisassembler_Success;
864}
865
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800866static DecodeStatus DecodeMem(MCInst *Inst,
867 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
868{
869 int Offset = SignExtend32(Insn & 0xffff, 16);
870 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
871 unsigned Base = fieldFromInstruction(Insn, 21, 5);
872
873 Reg = getReg(Decoder, Mips_GPR32RegClassID, Reg);
874 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
875
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800876 if (MCInst_getOpcode(Inst) == Mips_SC){
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800877 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800878 }
879
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800880 MCOperand_CreateReg0(Inst, Reg);
881 MCOperand_CreateReg0(Inst, Base);
882 MCOperand_CreateImm0(Inst, Offset);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800883
884 return MCDisassembler_Success;
885}
886
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800887static DecodeStatus DecodeCachePref(MCInst *Inst,
888 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
889{
890 int Offset = SignExtend32(Insn & 0xffff, 16);
891 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
892 unsigned Base = fieldFromInstruction(Insn, 21, 5);
893
894 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
895
896 MCOperand_CreateReg0(Inst, Base);
897 MCOperand_CreateImm0(Inst, Offset);
898 MCOperand_CreateImm0(Inst, Hint);
899
900 return MCDisassembler_Success;
901}
902
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800903static DecodeStatus DecodeMSA128Mem(MCInst *Inst, unsigned Insn,
904 uint64_t Address, MCRegisterInfo *Decoder)
905{
906 int Offset = SignExtend32(fieldFromInstruction(Insn, 16, 10), 10);
907 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
908 unsigned Base = fieldFromInstruction(Insn, 11, 5);
909
910 Reg = getReg(Decoder, Mips_MSA128BRegClassID, Reg);
911 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
912
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800913 MCOperand_CreateReg0(Inst, Reg);
914 MCOperand_CreateReg0(Inst, Base);
915 // MCOperand_CreateImm0(Inst, Offset);
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800916
917 // The immediate field of an LD/ST instruction is scaled which means it must
918 // be multiplied (when decoding) by the size (in bytes) of the instructions'
919 // data format.
920 // .b - 1 byte
921 // .h - 2 bytes
922 // .w - 4 bytes
923 // .d - 8 bytes
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800924 switch(MCInst_getOpcode(Inst)) {
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800925 default:
926 //assert (0 && "Unexpected instruction");
927 return MCDisassembler_Fail;
928 break;
929 case Mips_LD_B:
930 case Mips_ST_B:
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800931 MCOperand_CreateImm0(Inst, Offset);
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800932 break;
933 case Mips_LD_H:
934 case Mips_ST_H:
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800935 MCOperand_CreateImm0(Inst, Offset * 2);
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800936 break;
937 case Mips_LD_W:
938 case Mips_ST_W:
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800939 MCOperand_CreateImm0(Inst, Offset * 4);
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800940 break;
941 case Mips_LD_D:
942 case Mips_ST_D:
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +0800943 MCOperand_CreateImm0(Inst, Offset * 8);
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +0800944 break;
945 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800946
947 return MCDisassembler_Success;
948}
949
950static DecodeStatus DecodeMemMMImm12(MCInst *Inst,
951 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
952{
953 int Offset = SignExtend32(Insn & 0x0fff, 12);
954 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
955 unsigned Base = fieldFromInstruction(Insn, 16, 5);
956
957 Reg = getReg(Decoder, Mips_GPR32RegClassID, Reg);
958 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
959
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +0800960 if (MCInst_getOpcode(Inst) == Mips_SC_MM)
961 MCOperand_CreateReg0(Inst, Reg);
962
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800963 MCOperand_CreateReg0(Inst, Reg);
964 MCOperand_CreateReg0(Inst, Base);
965 MCOperand_CreateImm0(Inst, Offset);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800966
967 return MCDisassembler_Success;
968}
969
970static DecodeStatus DecodeMemMMImm16(MCInst *Inst,
971 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
972{
973 int Offset = SignExtend32(Insn & 0xffff, 16);
974 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
975 unsigned Base = fieldFromInstruction(Insn, 16, 5);
976
977 Reg = getReg(Decoder, Mips_GPR32RegClassID, Reg);
978 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
979
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800980 MCOperand_CreateReg0(Inst, Reg);
981 MCOperand_CreateReg0(Inst, Base);
982 MCOperand_CreateImm0(Inst, Offset);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800983
984 return MCDisassembler_Success;
985}
986
987static DecodeStatus DecodeFMem(MCInst *Inst,
988 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
989{
990 int Offset = SignExtend32(Insn & 0xffff, 16);
991 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
992 unsigned Base = fieldFromInstruction(Insn, 21, 5);
993
994 Reg = getReg(Decoder, Mips_FGR64RegClassID, Reg);
995 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
996
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +0800997 MCOperand_CreateReg0(Inst, Reg);
998 MCOperand_CreateReg0(Inst, Base);
999 MCOperand_CreateImm0(Inst, Offset);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001000
1001 return MCDisassembler_Success;
1002}
1003
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +08001004static DecodeStatus DecodeCOP2Mem(MCInst *Inst,
1005 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1006{
1007 int Offset = SignExtend32(Insn & 0xffff, 16);
1008 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1009 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1010
1011 Reg = getReg(Decoder, Mips_COP2RegClassID, Reg);
1012 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
1013
1014 MCOperand_CreateReg0(Inst, Reg);
1015 MCOperand_CreateReg0(Inst, Base);
1016 MCOperand_CreateImm0(Inst, Offset);
1017
1018 return MCDisassembler_Success;
1019}
1020
1021static DecodeStatus DecodeCOP3Mem(MCInst *Inst,
1022 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1023{
1024 int Offset = SignExtend32(Insn & 0xffff, 16);
1025 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1026 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1027
1028 Reg = getReg(Decoder, Mips_COP3RegClassID, Reg);
1029 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
1030
1031 MCOperand_CreateReg0(Inst, Reg);
1032 MCOperand_CreateReg0(Inst, Base);
1033 MCOperand_CreateImm0(Inst, Offset);
1034
1035 return MCDisassembler_Success;
1036}
1037
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001038static DecodeStatus DecodeSpecial3LlSc(MCInst *Inst,
1039 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1040{
1041 int64_t Offset = SignExtend64((Insn >> 7) & 0x1ff, 9);
1042 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1043 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1044
1045 Rt = getReg(Decoder, Mips_GPR32RegClassID, Rt);
1046 Base = getReg(Decoder, Mips_GPR32RegClassID, Base);
1047
1048 if (MCInst_getOpcode(Inst) == Mips_SC_R6 ||
1049 MCInst_getOpcode(Inst) == Mips_SCD_R6) {
1050 MCOperand_CreateReg0(Inst, Rt);
1051 }
1052
1053 MCOperand_CreateReg0(Inst, Rt);
1054 MCOperand_CreateReg0(Inst, Base);
1055 MCOperand_CreateImm0(Inst, Offset);
1056
1057 return MCDisassembler_Success;
1058}
1059
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001060static DecodeStatus DecodeHWRegsRegisterClass(MCInst *Inst,
1061 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1062{
1063 // Currently only hardware register 29 is supported.
1064 if (RegNo != 29)
1065 return MCDisassembler_Fail;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001066
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001067 MCOperand_CreateReg0(Inst, Mips_HWR29);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001068
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001069 return MCDisassembler_Success;
1070}
1071
1072static DecodeStatus DecodeAFGR64RegisterClass(MCInst *Inst,
1073 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1074{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001075 unsigned Reg;
1076
1077 if (RegNo > 30 || RegNo % 2)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001078 return MCDisassembler_Fail;
1079
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001080 Reg = getReg(Decoder, Mips_AFGR64RegClassID, RegNo /2);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001081 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001082
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001083 return MCDisassembler_Success;
1084}
1085
1086static DecodeStatus DecodeACC64DSPRegisterClass(MCInst *Inst,
1087 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1088{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001089 unsigned Reg;
1090
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001091 if (RegNo >= 4)
1092 return MCDisassembler_Fail;
1093
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001094 Reg = getReg(Decoder, Mips_ACC64DSPRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001095 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001096 return MCDisassembler_Success;
1097}
1098
1099static DecodeStatus DecodeHI32DSPRegisterClass(MCInst *Inst,
1100 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1101{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001102 unsigned Reg;
1103
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001104 if (RegNo >= 4)
1105 return MCDisassembler_Fail;
1106
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001107 Reg = getReg(Decoder, Mips_HI32DSPRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001108 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001109
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001110 return MCDisassembler_Success;
1111}
1112
1113static DecodeStatus DecodeLO32DSPRegisterClass(MCInst *Inst,
1114 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1115{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001116 unsigned Reg;
1117
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001118 if (RegNo >= 4)
1119 return MCDisassembler_Fail;
1120
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001121 Reg = getReg(Decoder, Mips_LO32DSPRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001122 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001123
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001124 return MCDisassembler_Success;
1125}
1126
1127static DecodeStatus DecodeMSA128BRegisterClass(MCInst *Inst,
1128 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1129{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001130 unsigned Reg;
1131
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001132 if (RegNo > 31)
1133 return MCDisassembler_Fail;
1134
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001135 Reg = getReg(Decoder, Mips_MSA128BRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001136 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001137
1138 return MCDisassembler_Success;
1139}
1140
1141static DecodeStatus DecodeMSA128HRegisterClass(MCInst *Inst,
1142 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1143{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001144 unsigned Reg;
1145
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001146 if (RegNo > 31)
1147 return MCDisassembler_Fail;
1148
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001149 Reg = getReg(Decoder, Mips_MSA128HRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001150 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001151
1152 return MCDisassembler_Success;
1153}
1154
1155static DecodeStatus DecodeMSA128WRegisterClass(MCInst *Inst,
1156 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1157{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001158 unsigned Reg;
1159
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001160 if (RegNo > 31)
1161 return MCDisassembler_Fail;
1162
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001163 Reg = getReg(Decoder, Mips_MSA128WRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001164 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001165
1166 return MCDisassembler_Success;
1167}
1168
1169static DecodeStatus DecodeMSA128DRegisterClass(MCInst *Inst,
1170 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1171{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001172 unsigned Reg;
1173
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001174 if (RegNo > 31)
1175 return MCDisassembler_Fail;
1176
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001177 Reg = getReg(Decoder, Mips_MSA128DRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001178 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001179
1180 return MCDisassembler_Success;
1181}
1182
1183static DecodeStatus DecodeMSACtrlRegisterClass(MCInst *Inst,
1184 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1185{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001186 unsigned Reg;
1187
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001188 if (RegNo > 7)
1189 return MCDisassembler_Fail;
1190
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001191 Reg = getReg(Decoder, Mips_MSACtrlRegClassID, RegNo);
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001192 MCOperand_CreateReg0(Inst, Reg);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001193
1194 return MCDisassembler_Success;
1195}
1196
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001197static DecodeStatus DecodeCOP2RegisterClass(MCInst *Inst,
1198 unsigned RegNo, uint64_t Address, MCRegisterInfo *Decoder)
1199{
1200 unsigned Reg;
1201
1202 if (RegNo > 31)
1203 return MCDisassembler_Fail;
1204
1205 Reg = getReg(Decoder, Mips_COP2RegClassID, RegNo);
1206 MCOperand_CreateReg0(Inst, Reg);
1207
1208 return MCDisassembler_Success;
1209}
1210
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001211static DecodeStatus DecodeBranchTarget(MCInst *Inst,
1212 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder)
1213{
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +08001214 int32_t BranchOffset = (SignExtend32(Offset, 16) * 4) + 4;
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001215 MCOperand_CreateImm0(Inst, BranchOffset);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001216
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001217 return MCDisassembler_Success;
1218}
1219
1220static DecodeStatus DecodeJumpTarget(MCInst *Inst,
1221 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1222{
1223 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001224 MCOperand_CreateImm0(Inst, JumpOffset);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001225
1226 return MCDisassembler_Success;
1227}
1228
1229static DecodeStatus DecodeBranchTarget21(MCInst *Inst,
1230 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder)
1231{
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +08001232 int32_t BranchOffset = SignExtend32(Offset, 21) * 4;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001233
1234 MCOperand_CreateImm0(Inst, BranchOffset);
1235
1236 return MCDisassembler_Success;
1237}
1238
1239static DecodeStatus DecodeBranchTarget26(MCInst *Inst,
1240 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder)
1241{
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +08001242 int32_t BranchOffset = SignExtend32(Offset, 26) * 4;
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001243
1244 MCOperand_CreateImm0(Inst, BranchOffset);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001245 return MCDisassembler_Success;
1246}
1247
1248static DecodeStatus DecodeBranchTargetMM(MCInst *Inst,
1249 unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder)
1250{
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +08001251 int32_t BranchOffset = SignExtend32(Offset, 16) * 2;
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001252 MCOperand_CreateImm0(Inst, BranchOffset);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001253
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001254 return MCDisassembler_Success;
1255}
1256
1257static DecodeStatus DecodeJumpTargetMM(MCInst *Inst,
1258 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1259{
1260 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001261 MCOperand_CreateImm0(Inst, JumpOffset);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001262
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001263 return MCDisassembler_Success;
1264}
1265
1266static DecodeStatus DecodeSimm16(MCInst *Inst,
1267 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1268{
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001269 MCOperand_CreateImm0(Inst, SignExtend32(Insn, 16));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001270 return MCDisassembler_Success;
1271}
1272
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +08001273static DecodeStatus DecodeLSAImm(MCInst *Inst,
1274 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1275{
Nguyen Anh Quynha82a0892014-01-23 23:42:40 +08001276 // We add one to the immediate field as it was encoded as 'imm - 1'.
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001277 MCOperand_CreateImm0(Inst, Insn + 1);
Nguyen Anh Quynha82a0892014-01-23 23:42:40 +08001278 return MCDisassembler_Success;
Nguyen Anh Quynh162409e2013-12-08 20:17:28 +08001279}
1280
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001281static DecodeStatus DecodeInsSize(MCInst *Inst,
1282 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1283{
1284 // First we need to grab the pos(lsb) from MCInst.
Alex Ionescu46018db2014-01-22 09:45:00 -08001285 int Pos = (int)MCOperand_getImm(MCInst_getOperand(Inst, 2));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001286 int Size = (int) Insn - Pos + 1;
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001287 MCOperand_CreateImm0(Inst, SignExtend32(Size, 16));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001288 return MCDisassembler_Success;
1289}
1290
1291static DecodeStatus DecodeExtSize(MCInst *Inst,
1292 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1293{
1294 int Size = (int) Insn + 1;
Nguyen Anh Quynhf08b83d2014-06-16 12:04:25 +08001295 MCOperand_CreateImm0(Inst, SignExtend32(Size, 16));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001296 return MCDisassembler_Success;
1297}
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +08001298
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001299static DecodeStatus DecodeSimm19Lsl2(MCInst *Inst,
1300 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1301{
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +08001302 MCOperand_CreateImm0(Inst, SignExtend32(Insn, 19) * 4);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001303 return MCDisassembler_Success;
1304}
1305
1306static DecodeStatus DecodeSimm18Lsl3(MCInst *Inst,
1307 unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder)
1308{
Nguyen Anh Quynh5691dd42014-09-24 18:03:47 +08001309 MCOperand_CreateImm0(Inst, SignExtend32(Insn, 18) * 8);
Nguyen Anh Quynh0f0eb982014-08-14 18:26:39 +08001310 return MCDisassembler_Success;
1311}
1312
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +08001313#endif