blob: 9124d87286d37ba0fce6596cf6405c4f1f966547 [file] [log] [blame]
Akira Hatanaka71928e62012-04-17 18:03:21 +00001//===- 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#include "Mips.h"
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000015#include "MipsRegisterInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "MipsSubtarget.h"
Lang Hamesa1bc0f52014-04-15 04:40:56 +000017#include "llvm/MC/MCContext.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000018#include "llvm/MC/MCDisassembler/MCDisassembler.h"
Jim Grosbachecaef492012-08-14 19:06:05 +000019#include "llvm/MC/MCFixedLenDisassembler.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/Support/MathExtras.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000023#include "llvm/Support/TargetRegistry.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000024
Akira Hatanaka71928e62012-04-17 18:03:21 +000025using namespace llvm;
26
Chandler Carruthe96dd892014-04-21 22:55:11 +000027#define DEBUG_TYPE "mips-disassembler"
28
Akira Hatanaka71928e62012-04-17 18:03:21 +000029typedef MCDisassembler::DecodeStatus DecodeStatus;
30
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000031namespace {
32
Daniel Sandersa19216c2015-02-11 11:28:56 +000033class MipsDisassembler : public MCDisassembler {
Vladimir Medicdde3d582013-09-06 12:30:36 +000034 bool IsMicroMips;
Daniel Sandersa19216c2015-02-11 11:28:56 +000035 bool IsBigEndian;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000036public:
Daniel Sandersa19216c2015-02-11 11:28:56 +000037 MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
38 : MCDisassembler(STI, Ctx),
Michael Kupersteindb0712f2015-05-26 10:47:10 +000039 IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
Daniel Sandersa19216c2015-02-11 11:28:56 +000040 IsBigEndian(IsBigEndian) {}
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000041
Simon Dardis4fbf76f2016-06-14 11:29:28 +000042 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
Michael Kupersteindb0712f2015-05-26 10:47:10 +000043 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
44 bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
Daniel Sandersc171f652014-06-13 13:15:59 +000045 bool hasMips32r6() const {
Michael Kupersteindb0712f2015-05-26 10:47:10 +000046 return STI.getFeatureBits()[Mips::FeatureMips32r6];
Daniel Sanders5c582b22014-05-22 11:23:21 +000047 }
Zlatko Buljan6221be82016-03-31 08:51:24 +000048 bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
Daniel Sanders5c582b22014-05-22 11:23:21 +000049
Michael Kupersteindb0712f2015-05-26 10:47:10 +000050 bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
Daniel Sanders0fa60412014-06-12 13:39:06 +000051
Simon Dardis4fbf76f2016-06-14 11:29:28 +000052 bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }
53
Kai Nacke3adf9b82015-05-28 16:23:16 +000054 bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
55
Daniel Sandersc171f652014-06-13 13:15:59 +000056 bool hasCOP3() const {
57 // Only present in MIPS-I and MIPS-II
58 return !hasMips32() && !hasMips3();
59 }
60
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000061 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000062 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000063 raw_ostream &VStream,
64 raw_ostream &CStream) const override;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000065};
66
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000067} // end anonymous namespace
68
Akira Hatanaka71928e62012-04-17 18:03:21 +000069// Forward declare these because the autogenerated code will reference them.
70// Definitions are further down.
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000071static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
72 unsigned RegNo,
73 uint64_t Address,
74 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +000075
Reed Kotlerec8a5492013-02-14 03:05:25 +000076static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
77 unsigned RegNo,
78 uint64_t Address,
79 const void *Decoder);
80
Zoran Jovanovicb0852e52014-10-21 08:23:11 +000081static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
82 unsigned RegNo,
83 uint64_t Address,
84 const void *Decoder);
85
Jozef Kolek1904fa22014-11-24 14:25:53 +000086static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
87 unsigned RegNo,
88 uint64_t Address,
89 const void *Decoder);
90
Zoran Jovanovic41688672015-02-10 16:36:20 +000091static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
92 unsigned RegNo,
93 uint64_t Address,
94 const void *Decoder);
95
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000096static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
97 unsigned RegNo,
98 uint64_t Address,
99 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000100
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000101static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
102 unsigned Insn,
103 uint64_t Address,
104 const void *Decoder);
105
Akira Hatanaka654655f2013-08-14 00:53:38 +0000106static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
107 unsigned RegNo,
108 uint64_t Address,
109 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000110
Akira Hatanaka71928e62012-04-17 18:03:21 +0000111static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
112 unsigned RegNo,
113 uint64_t Address,
114 const void *Decoder);
115
116static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
117 unsigned RegNo,
118 uint64_t Address,
119 const void *Decoder);
120
121static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
122 unsigned RegNo,
123 uint64_t Address,
124 const void *Decoder);
125
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000126static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
127 unsigned RegNo,
128 uint64_t Address,
129 const void *Decoder);
130
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +0000131static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
132 uint64_t Address,
133 const void *Decoder);
Daniel Sanders0fa60412014-06-12 13:39:06 +0000134
Akira Hatanaka71928e62012-04-17 18:03:21 +0000135static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
136 unsigned Insn,
137 uint64_t Address,
138 const void *Decoder);
139
140static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
141 unsigned RegNo,
142 uint64_t Address,
143 const void *Decoder);
144
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000145static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
146 unsigned RegNo,
147 uint64_t Address,
148 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000149
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000150static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
151 unsigned RegNo,
152 uint64_t Address,
153 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000154
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000155static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
156 unsigned RegNo,
157 uint64_t Address,
158 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000159
Jack Carter3eb663b2013-09-26 00:09:46 +0000160static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
161 unsigned RegNo,
162 uint64_t Address,
163 const void *Decoder);
164
Jack Carter5dc8ac92013-09-25 23:50:44 +0000165static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
166 unsigned RegNo,
167 uint64_t Address,
168 const void *Decoder);
169
170static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
171 unsigned RegNo,
172 uint64_t Address,
173 const void *Decoder);
174
175static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
176 unsigned RegNo,
177 uint64_t Address,
178 const void *Decoder);
179
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000180static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
181 unsigned RegNo,
182 uint64_t Address,
183 const void *Decoder);
184
Daniel Sandersa3134fa2015-06-27 15:39:19 +0000185static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
186 unsigned RegNo,
187 uint64_t Address,
188 const void *Decoder);
189
Daniel Sanders2a83d682014-05-21 12:56:39 +0000190static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
191 unsigned RegNo,
192 uint64_t Address,
193 const void *Decoder);
194
Akira Hatanaka71928e62012-04-17 18:03:21 +0000195static DecodeStatus DecodeBranchTarget(MCInst &Inst,
196 unsigned Offset,
197 uint64_t Address,
198 const void *Decoder);
199
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +0000200static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
201 unsigned Offset,
202 uint64_t Address,
203 const void *Decoder);
204
Akira Hatanaka71928e62012-04-17 18:03:21 +0000205static DecodeStatus DecodeJumpTarget(MCInst &Inst,
206 unsigned Insn,
207 uint64_t Address,
208 const void *Decoder);
209
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000210static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
211 unsigned Offset,
212 uint64_t Address,
213 const void *Decoder);
214
Zoran Jovanovic84e4d592016-05-17 11:10:15 +0000215static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
216 unsigned Offset,
217 uint64_t Address,
218 const void *Decoder);
219
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000220static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
221 unsigned Offset,
222 uint64_t Address,
223 const void *Decoder);
224
Jozef Kolek9761e962015-01-12 12:03:34 +0000225// DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
226// shifted left by 1 bit.
227static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
228 unsigned Offset,
229 uint64_t Address,
230 const void *Decoder);
231
Jozef Kolek5cfebdd2015-01-21 12:39:30 +0000232// DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
233// shifted left by 1 bit.
234static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
235 unsigned Offset,
236 uint64_t Address,
237 const void *Decoder);
238
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000239// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
240// shifted left by 1 bit.
241static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
242 unsigned Offset,
243 uint64_t Address,
244 const void *Decoder);
245
Zoran Jovanovica887b362015-11-30 12:56:18 +0000246// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
247// shifted left by 1 bit.
248static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
249 unsigned Offset,
250 uint64_t Address,
251 const void *Decoder);
252
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000253// DecodeJumpTargetMM - Decode microMIPS jump target, which is
254// shifted left by 1 bit.
255static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
256 unsigned Insn,
257 uint64_t Address,
258 const void *Decoder);
259
Akira Hatanaka71928e62012-04-17 18:03:21 +0000260static DecodeStatus DecodeMem(MCInst &Inst,
261 unsigned Insn,
262 uint64_t Address,
263 const void *Decoder);
264
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000265static DecodeStatus DecodeMemEVA(MCInst &Inst,
266 unsigned Insn,
267 uint64_t Address,
268 const void *Decoder);
269
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +0000270static DecodeStatus DecodeLoadByte9(MCInst &Inst,
271 unsigned Insn,
272 uint64_t Address,
273 const void *Decoder);
274
275static DecodeStatus DecodeLoadByte15(MCInst &Inst,
276 unsigned Insn,
277 uint64_t Address,
278 const void *Decoder);
279
Daniel Sanders92db6b72014-10-01 08:26:55 +0000280static DecodeStatus DecodeCacheOp(MCInst &Inst,
281 unsigned Insn,
282 uint64_t Address,
283 const void *Decoder);
284
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000285static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
286 unsigned Insn,
287 uint64_t Address,
288 const void *Decoder);
Vladimir Medicdf464ae2015-01-29 11:33:41 +0000289
Jozef Kolekab6d1cc2014-12-23 19:55:34 +0000290static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
291 unsigned Insn,
292 uint64_t Address,
293 const void *Decoder);
294
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +0000295static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
296 unsigned Insn,
297 uint64_t Address,
298 const void *Decoder);
299
Zoran Jovanovicd9790792015-09-09 09:10:46 +0000300static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
301 unsigned Insn,
302 uint64_t Address,
303 const void *Decoder);
304
Daniel Sandersb4484d62014-11-27 17:28:10 +0000305static DecodeStatus DecodeSyncI(MCInst &Inst,
306 unsigned Insn,
307 uint64_t Address,
308 const void *Decoder);
309
Hrvoje Varga18148672015-10-28 11:04:29 +0000310static DecodeStatus DecodeSynciR6(MCInst &Inst,
311 unsigned Insn,
312 uint64_t Address,
313 const void *Decoder);
314
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000315static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
316 uint64_t Address, const void *Decoder);
317
Jozef Kolek315e7ec2014-11-26 18:56:38 +0000318static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
319 unsigned Insn,
320 uint64_t Address,
321 const void *Decoder);
322
Jozef Kolek12c69822014-12-23 16:16:33 +0000323static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
324 unsigned Insn,
325 uint64_t Address,
326 const void *Decoder);
327
Jozef Koleke10a02e2015-01-28 17:27:26 +0000328static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
329 unsigned Insn,
330 uint64_t Address,
331 const void *Decoder);
332
Jozef Kolekd68d424a2015-02-10 12:41:13 +0000333static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
334 unsigned Insn,
335 uint64_t Address,
336 const void *Decoder);
337
Zoran Jovanovica6593ff2015-08-18 12:53:08 +0000338static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
339 unsigned Insn,
340 uint64_t Address,
341 const void *Decoder);
342
Vladimir Medicdde3d582013-09-06 12:30:36 +0000343static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
344 unsigned Insn,
345 uint64_t Address,
346 const void *Decoder);
347
348static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
349 unsigned Insn,
350 uint64_t Address,
351 const void *Decoder);
352
Akira Hatanaka71928e62012-04-17 18:03:21 +0000353static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
354 uint64_t Address,
355 const void *Decoder);
356
Daniel Sanders92db6b72014-10-01 08:26:55 +0000357static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
358 uint64_t Address,
359 const void *Decoder);
360
361static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
362 uint64_t Address,
363 const void *Decoder);
364
Vladimir Medic435cf8a2015-01-21 10:47:36 +0000365static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
366 uint64_t Address,
367 const void *Decoder);
368
Daniel Sanders6a803f62014-06-16 13:13:03 +0000369static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
370 unsigned Insn,
371 uint64_t Address,
372 const void *Decoder);
373
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000374static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
375 unsigned Value,
376 uint64_t Address,
377 const void *Decoder);
378
Daniel Sanders97297772016-03-22 14:40:00 +0000379static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000380 unsigned Value,
381 uint64_t Address,
382 const void *Decoder);
383
Zoran Jovanovic6b28f092015-09-09 13:55:45 +0000384static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
385 unsigned Value,
386 uint64_t Address,
387 const void *Decoder);
388
Daniel Sanders19b7f762016-03-14 11:16:56 +0000389template <unsigned Bits, int Offset, int Scale>
390static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
391 uint64_t Address,
392 const void *Decoder);
393
Daniel Sandersea4f6532015-11-06 12:22:31 +0000394template <unsigned Bits, int Offset>
395static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
Daniel Sanders19b7f762016-03-14 11:16:56 +0000396 uint64_t Address,
397 const void *Decoder) {
398 return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
399 Decoder);
400}
Matheus Almeida779c5932013-11-18 12:32:49 +0000401
Daniel Sanders97297772016-03-22 14:40:00 +0000402template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
403static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
404 uint64_t Address,
405 const void *Decoder);
Daniel Sanders78e89022016-03-11 11:37:50 +0000406
Akira Hatanaka71928e62012-04-17 18:03:21 +0000407static DecodeStatus DecodeInsSize(MCInst &Inst,
408 unsigned Insn,
409 uint64_t Address,
410 const void *Decoder);
411
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000412static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
413 uint64_t Address, const void *Decoder);
414
Zoran Jovanovic28551422014-06-09 09:49:51 +0000415static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
416 uint64_t Address, const void *Decoder);
417
Vladimir Medicb682ddf2014-12-01 11:12:04 +0000418static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
419 uint64_t Address, const void *Decoder);
420
421static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
422 uint64_t Address, const void *Decoder);
423
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000424static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
425 uint64_t Address, const void *Decoder);
426
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000427/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
428/// handle.
429template <typename InsnType>
430static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
431 const void *Decoder);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000432
433template <typename InsnType>
434static DecodeStatus
435DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
436 const void *Decoder);
437
438template <typename InsnType>
439static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000440DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
441 const void *Decoder);
442
443template <typename InsnType>
444static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000445DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
446 const void *Decoder);
447
448template <typename InsnType>
449static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000450DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
451 const void *Decoder);
452
453template <typename InsnType>
454static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000455DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
456 const void *Decoder);
457
458template <typename InsnType>
459static DecodeStatus
460DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
461 const void *Decoder);
462
463template <typename InsnType>
464static DecodeStatus
465DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
466 const void *Decoder);
467
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000468template <typename InsnType>
469static DecodeStatus
470DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
471 const void *Decoder);
472
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +0000473template <typename InsnType>
474static DecodeStatus
475DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
476 const void *Decoder);
477
478template <typename InsnType>
479static DecodeStatus
480DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
481 const void *Decoder);
482
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000483static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
484 uint64_t Address,
485 const void *Decoder);
486
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000487static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
488 uint64_t Address,
489 const void *Decoder);
490
Zoran Jovanovic41688672015-02-10 16:36:20 +0000491static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
492 uint64_t Address,
493 const void *Decoder);
494
Akira Hatanaka71928e62012-04-17 18:03:21 +0000495namespace llvm {
496extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
497 TheMips64elTarget;
498}
499
500static MCDisassembler *createMipsDisassembler(
501 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000502 const MCSubtargetInfo &STI,
503 MCContext &Ctx) {
504 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000505}
506
507static MCDisassembler *createMipselDisassembler(
508 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000509 const MCSubtargetInfo &STI,
510 MCContext &Ctx) {
511 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000512}
513
Akira Hatanaka71928e62012-04-17 18:03:21 +0000514extern "C" void LLVMInitializeMipsDisassembler() {
515 // Register the disassembler.
516 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
517 createMipsDisassembler);
518 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
519 createMipselDisassembler);
520 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000521 createMipsDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000522 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000523 createMipselDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000524}
525
Akira Hatanaka71928e62012-04-17 18:03:21 +0000526#include "MipsGenDisassemblerTables.inc"
527
Daniel Sanders5c582b22014-05-22 11:23:21 +0000528static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
Daniel Sandersa19216c2015-02-11 11:28:56 +0000529 const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000530 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
531 return *(RegInfo->getRegClass(RC).begin() + RegNo);
532}
533
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000534template <typename InsnType>
535static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
536 const void *Decoder) {
537 typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
538 // The size of the n field depends on the element size
539 // The register class also depends on this.
540 InsnType tmp = fieldFromInstruction(insn, 17, 5);
541 unsigned NSize = 0;
542 DecodeFN RegDecoder = nullptr;
543 if ((tmp & 0x18) == 0x00) { // INSVE_B
544 NSize = 4;
545 RegDecoder = DecodeMSA128BRegisterClass;
546 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
547 NSize = 3;
548 RegDecoder = DecodeMSA128HRegisterClass;
549 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
550 NSize = 2;
551 RegDecoder = DecodeMSA128WRegisterClass;
552 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
553 NSize = 1;
554 RegDecoder = DecodeMSA128DRegisterClass;
555 } else
556 llvm_unreachable("Invalid encoding");
557
558 assert(NSize != 0 && RegDecoder != nullptr);
559
560 // $wd
561 tmp = fieldFromInstruction(insn, 6, 5);
562 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
563 return MCDisassembler::Fail;
564 // $wd_in
565 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
566 return MCDisassembler::Fail;
567 // $n
568 tmp = fieldFromInstruction(insn, 16, NSize);
Jim Grosbache9119e42015-05-13 18:37:00 +0000569 MI.addOperand(MCOperand::createImm(tmp));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000570 // $ws
571 tmp = fieldFromInstruction(insn, 11, 5);
572 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
573 return MCDisassembler::Fail;
574 // $n2
Jim Grosbache9119e42015-05-13 18:37:00 +0000575 MI.addOperand(MCOperand::createImm(0));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000576
577 return MCDisassembler::Success;
578}
579
Daniel Sanders5c582b22014-05-22 11:23:21 +0000580template <typename InsnType>
581static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
582 uint64_t Address,
583 const void *Decoder) {
584 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
585 // (otherwise we would have matched the ADDI instruction from the earlier
586 // ISA's instead).
587 //
588 // We have:
589 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
590 // BOVC if rs >= rt
591 // BEQZALC if rs == 0 && rt != 0
592 // BEQC if rs < rt && rs != 0
593
594 InsnType Rs = fieldFromInstruction(insn, 21, 5);
595 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000596 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000597 bool HasRs = false;
598
599 if (Rs >= Rt) {
600 MI.setOpcode(Mips::BOVC);
601 HasRs = true;
602 } else if (Rs != 0 && Rs < Rt) {
603 MI.setOpcode(Mips::BEQC);
604 HasRs = true;
605 } else
606 MI.setOpcode(Mips::BEQZALC);
607
608 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000609 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000610 Rs)));
611
Jim Grosbache9119e42015-05-13 18:37:00 +0000612 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000613 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000614 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000615
616 return MCDisassembler::Success;
617}
618
619template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000620static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
621 uint64_t Address,
622 const void *Decoder) {
623 InsnType Rt = fieldFromInstruction(insn, 21, 5);
624 InsnType Rs = fieldFromInstruction(insn, 16, 5);
625 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
626
627 if (Rs >= Rt) {
628 MI.setOpcode(Mips::BOVC_MMR6);
629 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
630 Rt)));
631 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
632 Rs)));
633 } else if (Rs != 0 && Rs < Rt) {
634 MI.setOpcode(Mips::BEQC_MMR6);
635 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
636 Rs)));
637 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
638 Rt)));
639 } else {
640 MI.setOpcode(Mips::BEQZALC_MMR6);
641 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
642 Rt)));
643 }
644
645 MI.addOperand(MCOperand::createImm(Imm));
646
647 return MCDisassembler::Success;
648}
649
650template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000651static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
652 uint64_t Address,
653 const void *Decoder) {
654 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
655 // (otherwise we would have matched the ADDI instruction from the earlier
656 // ISA's instead).
657 //
658 // We have:
659 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
660 // BNVC if rs >= rt
661 // BNEZALC if rs == 0 && rt != 0
662 // BNEC if rs < rt && rs != 0
663
664 InsnType Rs = fieldFromInstruction(insn, 21, 5);
665 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000666 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000667 bool HasRs = false;
668
669 if (Rs >= Rt) {
670 MI.setOpcode(Mips::BNVC);
671 HasRs = true;
672 } else if (Rs != 0 && Rs < Rt) {
673 MI.setOpcode(Mips::BNEC);
674 HasRs = true;
675 } else
676 MI.setOpcode(Mips::BNEZALC);
677
678 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000679 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000680 Rs)));
681
Jim Grosbache9119e42015-05-13 18:37:00 +0000682 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000683 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000684 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000685
686 return MCDisassembler::Success;
687}
688
689template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000690static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
691 uint64_t Address,
692 const void *Decoder) {
693 InsnType Rt = fieldFromInstruction(insn, 21, 5);
694 InsnType Rs = fieldFromInstruction(insn, 16, 5);
695 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
696
697 if (Rs >= Rt) {
698 MI.setOpcode(Mips::BNVC_MMR6);
699 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
700 Rt)));
701 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
702 Rs)));
703 } else if (Rs != 0 && Rs < Rt) {
704 MI.setOpcode(Mips::BNEC_MMR6);
705 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
706 Rs)));
707 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
708 Rt)));
709 } else {
710 MI.setOpcode(Mips::BNEZALC_MMR6);
711 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
712 Rt)));
713 }
714
715 MI.addOperand(MCOperand::createImm(Imm));
716
717 return MCDisassembler::Success;
718}
719
720template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000721static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
722 uint64_t Address,
723 const void *Decoder) {
724 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
725 // (otherwise we would have matched the BLEZL instruction from the earlier
726 // ISA's instead).
727 //
728 // We have:
729 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
730 // Invalid if rs == 0
731 // BLEZC if rs == 0 && rt != 0
732 // BGEZC if rs == rt && rt != 0
733 // BGEC if rs != rt && rs != 0 && rt != 0
734
735 InsnType Rs = fieldFromInstruction(insn, 21, 5);
736 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000737 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000738 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000739
740 if (Rt == 0)
741 return MCDisassembler::Fail;
742 else if (Rs == 0)
743 MI.setOpcode(Mips::BLEZC);
744 else if (Rs == Rt)
745 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000746 else {
747 HasRs = true;
748 MI.setOpcode(Mips::BGEC);
749 }
750
751 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000752 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000753 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000754
Jim Grosbache9119e42015-05-13 18:37:00 +0000755 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000756 Rt)));
757
Jim Grosbache9119e42015-05-13 18:37:00 +0000758 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000759
760 return MCDisassembler::Success;
761}
762
763template <typename InsnType>
764static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
765 uint64_t Address,
766 const void *Decoder) {
767 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
768 // (otherwise we would have matched the BGTZL instruction from the earlier
769 // ISA's instead).
770 //
771 // We have:
772 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
773 // Invalid if rs == 0
774 // BGTZC if rs == 0 && rt != 0
775 // BLTZC if rs == rt && rt != 0
776 // BLTC if rs != rt && rs != 0 && rt != 0
777
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000778 bool HasRs = false;
779
Daniel Sanders5c582b22014-05-22 11:23:21 +0000780 InsnType Rs = fieldFromInstruction(insn, 21, 5);
781 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000782 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000783
784 if (Rt == 0)
785 return MCDisassembler::Fail;
786 else if (Rs == 0)
787 MI.setOpcode(Mips::BGTZC);
788 else if (Rs == Rt)
789 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000790 else {
791 MI.setOpcode(Mips::BLTC);
792 HasRs = true;
793 }
794
795 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000796 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000797 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000798
Jim Grosbache9119e42015-05-13 18:37:00 +0000799 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000800 Rt)));
801
Jim Grosbache9119e42015-05-13 18:37:00 +0000802 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000803
804 return MCDisassembler::Success;
805}
806
807template <typename InsnType>
808static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
809 uint64_t Address,
810 const void *Decoder) {
811 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
812 // (otherwise we would have matched the BGTZ instruction from the earlier
813 // ISA's instead).
814 //
815 // We have:
816 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
817 // BGTZ if rt == 0
818 // BGTZALC if rs == 0 && rt != 0
819 // BLTZALC if rs != 0 && rs == rt
820 // BLTUC if rs != 0 && rs != rt
821
822 InsnType Rs = fieldFromInstruction(insn, 21, 5);
823 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000824 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000825 bool HasRs = false;
826 bool HasRt = false;
827
828 if (Rt == 0) {
829 MI.setOpcode(Mips::BGTZ);
830 HasRs = true;
831 } else if (Rs == 0) {
832 MI.setOpcode(Mips::BGTZALC);
833 HasRt = true;
834 } else if (Rs == Rt) {
835 MI.setOpcode(Mips::BLTZALC);
836 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000837 } else {
838 MI.setOpcode(Mips::BLTUC);
839 HasRs = true;
840 HasRt = true;
841 }
Daniel Sanders5c582b22014-05-22 11:23:21 +0000842
843 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000844 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000845 Rs)));
846
847 if (HasRt)
Jim Grosbache9119e42015-05-13 18:37:00 +0000848 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000849 Rt)));
850
Jim Grosbache9119e42015-05-13 18:37:00 +0000851 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000852
853 return MCDisassembler::Success;
854}
855
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000856template <typename InsnType>
857static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
858 uint64_t Address,
859 const void *Decoder) {
860 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
861 // (otherwise we would have matched the BLEZL instruction from the earlier
862 // ISA's instead).
863 //
864 // We have:
865 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
866 // Invalid if rs == 0
867 // BLEZALC if rs == 0 && rt != 0
868 // BGEZALC if rs == rt && rt != 0
869 // BGEUC if rs != rt && rs != 0 && rt != 0
870
871 InsnType Rs = fieldFromInstruction(insn, 21, 5);
872 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000873 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000874 bool HasRs = false;
875
876 if (Rt == 0)
877 return MCDisassembler::Fail;
878 else if (Rs == 0)
879 MI.setOpcode(Mips::BLEZALC);
880 else if (Rs == Rt)
881 MI.setOpcode(Mips::BGEZALC);
882 else {
883 HasRs = true;
884 MI.setOpcode(Mips::BGEUC);
885 }
886
887 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000888 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000889 Rs)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000890 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000891 Rt)));
892
Jim Grosbache9119e42015-05-13 18:37:00 +0000893 MI.addOperand(MCOperand::createImm(Imm));
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000894
895 return MCDisassembler::Success;
896}
897
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000898/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
899/// according to the given endianess.
900static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
901 uint64_t &Size, uint32_t &Insn,
902 bool IsBigEndian) {
903 // We want to read exactly 2 Bytes of data.
904 if (Bytes.size() < 2) {
905 Size = 0;
906 return MCDisassembler::Fail;
907 }
908
909 if (IsBigEndian) {
910 Insn = (Bytes[0] << 8) | Bytes[1];
911 } else {
912 Insn = (Bytes[1] << 8) | Bytes[0];
913 }
914
915 return MCDisassembler::Success;
916}
917
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000918/// Read four bytes from the ArrayRef and return 32 bit word sorted
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000919/// according to the given endianess
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000920static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
921 uint64_t &Size, uint32_t &Insn,
922 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000923 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000924 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000925 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000926 return MCDisassembler::Fail;
927 }
928
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000929 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
930 // always precede the low 16 bits in the instruction stream (that is, they
931 // are placed at lower addresses in the instruction stream).
932 //
933 // microMIPS byte ordering:
934 // Big-endian: 0 | 1 | 2 | 3
935 // Little-endian: 1 | 0 | 3 | 2
936
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000937 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000938 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000939 Insn =
940 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
941 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +0000942 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000943 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000944 (Bytes[1] << 24);
945 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000946 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000947 (Bytes[3] << 24);
948 }
Akira Hatanaka71928e62012-04-17 18:03:21 +0000949 }
950
951 return MCDisassembler::Success;
952}
953
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000954DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000955 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000956 uint64_t Address,
957 raw_ostream &VStream,
958 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000959 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000960 DecodeStatus Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000961
Vladimir Medicdde3d582013-09-06 12:30:36 +0000962 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000963 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
Reid Klecknerebee6122015-11-19 21:51:55 +0000964 if (Result == MCDisassembler::Fail)
965 return MCDisassembler::Fail;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000966
Zoran Jovanovicada70912015-09-07 11:56:37 +0000967 if (hasMips32r6()) {
968 DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
969 // Calling the auto-generated decoder function for microMIPS32R6
970 // (and microMIPS64R6) 16-bit instructions.
971 Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
972 Address, this, STI);
973 if (Result != MCDisassembler::Fail) {
974 Size = 2;
975 return Result;
976 }
977 }
978
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000979 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
Zoran Jovanovicada70912015-09-07 11:56:37 +0000980 // Calling the auto-generated decoder function for microMIPS 16-bit
981 // instructions.
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000982 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
983 this, STI);
984 if (Result != MCDisassembler::Fail) {
985 Size = 2;
986 return Result;
987 }
988
989 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
990 if (Result == MCDisassembler::Fail)
991 return MCDisassembler::Fail;
992
Jozef Kolek676d6012015-04-20 14:40:38 +0000993 if (hasMips32r6()) {
994 DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
995 // Calling the auto-generated decoder function.
Zoran Jovanovic366783e2015-08-12 12:45:16 +0000996 Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
Jozef Kolek676d6012015-04-20 14:40:38 +0000997 this, STI);
Zoran Jovanovicada70912015-09-07 11:56:37 +0000998 if (Result != MCDisassembler::Fail) {
999 Size = 4;
1000 return Result;
1001 }
Jozef Kolek676d6012015-04-20 14:40:38 +00001002 }
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001003
Zoran Jovanovicada70912015-09-07 11:56:37 +00001004 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1005 // Calling the auto-generated decoder function.
1006 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1007 this, STI);
Vladimir Medicdde3d582013-09-06 12:30:36 +00001008 if (Result != MCDisassembler::Fail) {
1009 Size = 4;
1010 return Result;
1011 }
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001012
Zlatko Buljan6221be82016-03-31 08:51:24 +00001013 if (hasMips32r6() && isFP64()) {
1014 DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
1015 Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001016 Address, this, STI);
1017 if (Result != MCDisassembler::Fail) {
1018 Size = 4;
1019 return Result;
1020 }
1021 }
1022
Reid Klecknerebee6122015-11-19 21:51:55 +00001023 // This is an invalid instruction. Let the disassembler move forward by the
1024 // minimum instruction size.
1025 Size = 2;
Vladimir Medicdde3d582013-09-06 12:30:36 +00001026 return MCDisassembler::Fail;
1027 }
1028
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001029 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Reid Klecknerebee6122015-11-19 21:51:55 +00001030 if (Result == MCDisassembler::Fail) {
1031 Size = 4;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001032 return MCDisassembler::Fail;
Reid Klecknerebee6122015-11-19 21:51:55 +00001033 }
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001034
Daniel Sandersc171f652014-06-13 13:15:59 +00001035 if (hasCOP3()) {
1036 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1037 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001038 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Daniel Sandersc171f652014-06-13 13:15:59 +00001039 if (Result != MCDisassembler::Fail) {
1040 Size = 4;
1041 return Result;
1042 }
1043 }
1044
1045 if (hasMips32r6() && isGP64()) {
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001046 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
1047 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
1048 Address, this, STI);
Daniel Sanders0fa60412014-06-12 13:39:06 +00001049 if (Result != MCDisassembler::Fail) {
1050 Size = 4;
1051 return Result;
1052 }
1053 }
1054
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001055 if (hasMips32r6() && isPTR64()) {
1056 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1057 Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
1058 Address, this, STI);
1059 if (Result != MCDisassembler::Fail) {
1060 Size = 4;
1061 return Result;
1062 }
1063 }
1064
Daniel Sandersc171f652014-06-13 13:15:59 +00001065 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001066 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001067 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +00001068 Address, this, STI);
1069 if (Result != MCDisassembler::Fail) {
1070 Size = 4;
1071 return Result;
1072 }
1073 }
1074
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001075 if (hasMips2() && isPTR64()) {
1076 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1077 Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
1078 Address, this, STI);
1079 if (Result != MCDisassembler::Fail) {
1080 Size = 4;
1081 return Result;
1082 }
1083 }
1084
Kai Nacke3adf9b82015-05-28 16:23:16 +00001085 if (hasCnMips()) {
1086 DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
1087 Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
1088 Address, this, STI);
1089 if (Result != MCDisassembler::Fail) {
1090 Size = 4;
1091 return Result;
1092 }
1093 }
1094
Daniel Sandersa19216c2015-02-11 11:28:56 +00001095 if (isGP64()) {
1096 DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1097 Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1098 Address, this, STI);
1099 if (Result != MCDisassembler::Fail) {
1100 Size = 4;
1101 return Result;
1102 }
1103 }
1104
Daniel Sanders0fa60412014-06-12 13:39:06 +00001105 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +00001106 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001107 Result =
1108 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001109 if (Result != MCDisassembler::Fail) {
1110 Size = 4;
1111 return Result;
1112 }
1113
Reid Klecknerebee6122015-11-19 21:51:55 +00001114 Size = 4;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001115 return MCDisassembler::Fail;
1116}
1117
Reed Kotlerec8a5492013-02-14 03:05:25 +00001118static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1119 unsigned RegNo,
1120 uint64_t Address,
1121 const void *Decoder) {
1122
1123 return MCDisassembler::Fail;
1124
1125}
1126
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001127static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1128 unsigned RegNo,
1129 uint64_t Address,
1130 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001131
1132 if (RegNo > 31)
1133 return MCDisassembler::Fail;
1134
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001135 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001136 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001137 return MCDisassembler::Success;
1138}
1139
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001140static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1141 unsigned RegNo,
1142 uint64_t Address,
1143 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001144 if (RegNo > 7)
1145 return MCDisassembler::Fail;
1146 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001147 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001148 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001149}
1150
Jozef Kolek1904fa22014-11-24 14:25:53 +00001151static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1152 unsigned RegNo,
1153 uint64_t Address,
1154 const void *Decoder) {
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001155 if (RegNo > 7)
1156 return MCDisassembler::Fail;
1157 unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001158 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001159 return MCDisassembler::Success;
Jozef Kolek1904fa22014-11-24 14:25:53 +00001160}
1161
Zoran Jovanovic41688672015-02-10 16:36:20 +00001162static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1163 unsigned RegNo,
1164 uint64_t Address,
1165 const void *Decoder) {
1166 if (RegNo > 7)
1167 return MCDisassembler::Fail;
1168 unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001169 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic41688672015-02-10 16:36:20 +00001170 return MCDisassembler::Success;
1171}
1172
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001173static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1174 unsigned RegNo,
1175 uint64_t Address,
1176 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001177 if (RegNo > 31)
1178 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001179 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001180 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001181 return MCDisassembler::Success;
1182}
1183
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001184static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1185 unsigned RegNo,
1186 uint64_t Address,
1187 const void *Decoder) {
Daniel Sandersa19216c2015-02-11 11:28:56 +00001188 if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001189 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1190
1191 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1192}
1193
Akira Hatanaka654655f2013-08-14 00:53:38 +00001194static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1195 unsigned RegNo,
1196 uint64_t Address,
1197 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001198 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001199}
1200
Akira Hatanaka71928e62012-04-17 18:03:21 +00001201static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1202 unsigned RegNo,
1203 uint64_t Address,
1204 const void *Decoder) {
1205 if (RegNo > 31)
1206 return MCDisassembler::Fail;
1207
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001208 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001209 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001210 return MCDisassembler::Success;
1211}
1212
1213static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1214 unsigned RegNo,
1215 uint64_t Address,
1216 const void *Decoder) {
1217 if (RegNo > 31)
1218 return MCDisassembler::Fail;
1219
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001220 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001221 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001222 return MCDisassembler::Success;
1223}
1224
1225static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1226 unsigned RegNo,
1227 uint64_t Address,
1228 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +00001229 if (RegNo > 31)
1230 return MCDisassembler::Fail;
1231 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001232 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001233 return MCDisassembler::Success;
1234}
1235
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001236static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1237 unsigned RegNo,
1238 uint64_t Address,
1239 const void *Decoder) {
1240 if (RegNo > 7)
1241 return MCDisassembler::Fail;
1242 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001243 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001244 return MCDisassembler::Success;
1245}
1246
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001247static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1248 uint64_t Address,
1249 const void *Decoder) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001250 if (RegNo > 31)
1251 return MCDisassembler::Fail;
1252
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001253 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001254 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders0fa60412014-06-12 13:39:06 +00001255 return MCDisassembler::Success;
1256}
1257
Akira Hatanaka71928e62012-04-17 18:03:21 +00001258static DecodeStatus DecodeMem(MCInst &Inst,
1259 unsigned Insn,
1260 uint64_t Address,
1261 const void *Decoder) {
1262 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001263 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1264 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001265
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001266 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1267 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001268
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001269 if (Inst.getOpcode() == Mips::SC ||
1270 Inst.getOpcode() == Mips::SCD)
Jim Grosbache9119e42015-05-13 18:37:00 +00001271 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001272
1273 Inst.addOperand(MCOperand::createReg(Reg));
1274 Inst.addOperand(MCOperand::createReg(Base));
1275 Inst.addOperand(MCOperand::createImm(Offset));
1276
1277 return MCDisassembler::Success;
1278}
1279
1280static DecodeStatus DecodeMemEVA(MCInst &Inst,
1281 unsigned Insn,
1282 uint64_t Address,
1283 const void *Decoder) {
1284 int Offset = SignExtend32<9>(Insn >> 7);
1285 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1286 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1287
1288 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1289 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1290
1291 if (Inst.getOpcode() == Mips::SCE)
1292 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001293
Jim Grosbache9119e42015-05-13 18:37:00 +00001294 Inst.addOperand(MCOperand::createReg(Reg));
1295 Inst.addOperand(MCOperand::createReg(Base));
1296 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001297
1298 return MCDisassembler::Success;
1299}
1300
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +00001301static DecodeStatus DecodeLoadByte9(MCInst &Inst,
1302 unsigned Insn,
1303 uint64_t Address,
1304 const void *Decoder) {
1305 int Offset = SignExtend32<9>(Insn & 0x1ff);
1306 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1307 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1308
1309 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1310 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1311
1312 Inst.addOperand(MCOperand::createReg(Reg));
1313 Inst.addOperand(MCOperand::createReg(Base));
1314 Inst.addOperand(MCOperand::createImm(Offset));
1315
1316 return MCDisassembler::Success;
1317}
1318
1319static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1320 unsigned Insn,
1321 uint64_t Address,
1322 const void *Decoder) {
1323 int Offset = SignExtend32<16>(Insn & 0xffff);
1324 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1325 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1326
1327 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1328 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1329
1330 Inst.addOperand(MCOperand::createReg(Reg));
1331 Inst.addOperand(MCOperand::createReg(Base));
1332 Inst.addOperand(MCOperand::createImm(Offset));
1333
1334 return MCDisassembler::Success;
1335}
1336
Daniel Sanders92db6b72014-10-01 08:26:55 +00001337static DecodeStatus DecodeCacheOp(MCInst &Inst,
1338 unsigned Insn,
1339 uint64_t Address,
1340 const void *Decoder) {
1341 int Offset = SignExtend32<16>(Insn & 0xffff);
1342 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1343 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1344
1345 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1346
Jim Grosbache9119e42015-05-13 18:37:00 +00001347 Inst.addOperand(MCOperand::createReg(Base));
1348 Inst.addOperand(MCOperand::createImm(Offset));
1349 Inst.addOperand(MCOperand::createImm(Hint));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001350
1351 return MCDisassembler::Success;
1352}
1353
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001354static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1355 unsigned Insn,
1356 uint64_t Address,
1357 const void *Decoder) {
1358 int Offset = SignExtend32<12>(Insn & 0xfff);
1359 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1360 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1361
1362 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1363
Jim Grosbache9119e42015-05-13 18:37:00 +00001364 Inst.addOperand(MCOperand::createReg(Base));
1365 Inst.addOperand(MCOperand::createImm(Offset));
1366 Inst.addOperand(MCOperand::createImm(Hint));
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001367
1368 return MCDisassembler::Success;
1369}
1370
Zoran Jovanovicd9790792015-09-09 09:10:46 +00001371static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1372 unsigned Insn,
1373 uint64_t Address,
1374 const void *Decoder) {
1375 int Offset = SignExtend32<9>(Insn & 0x1ff);
1376 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1377 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1378
1379 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1380
1381 Inst.addOperand(MCOperand::createReg(Base));
1382 Inst.addOperand(MCOperand::createImm(Offset));
1383 Inst.addOperand(MCOperand::createImm(Hint));
1384
1385 return MCDisassembler::Success;
1386}
1387
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001388static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1389 unsigned Insn,
1390 uint64_t Address,
1391 const void *Decoder) {
1392 int Offset = SignExtend32<9>(Insn >> 7);
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001393 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1394 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1395
1396 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1397
Jim Grosbache9119e42015-05-13 18:37:00 +00001398 Inst.addOperand(MCOperand::createReg(Base));
1399 Inst.addOperand(MCOperand::createImm(Offset));
1400 Inst.addOperand(MCOperand::createImm(Hint));
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001401
1402 return MCDisassembler::Success;
1403}
1404
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +00001405static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
1406 unsigned Insn,
1407 uint64_t Address,
1408 const void *Decoder) {
1409 int Offset = SignExtend32<9>(Insn & 0x1ff);
1410 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1411 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1412
1413 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1414 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1415
1416 Inst.addOperand(MCOperand::createReg(Reg));
1417 Inst.addOperand(MCOperand::createReg(Base));
1418 Inst.addOperand(MCOperand::createImm(Offset));
1419
1420 return MCDisassembler::Success;
1421}
1422
Daniel Sandersb4484d62014-11-27 17:28:10 +00001423static DecodeStatus DecodeSyncI(MCInst &Inst,
1424 unsigned Insn,
1425 uint64_t Address,
1426 const void *Decoder) {
1427 int Offset = SignExtend32<16>(Insn & 0xffff);
1428 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1429
1430 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1431
Jim Grosbache9119e42015-05-13 18:37:00 +00001432 Inst.addOperand(MCOperand::createReg(Base));
1433 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sandersb4484d62014-11-27 17:28:10 +00001434
1435 return MCDisassembler::Success;
1436}
1437
Hrvoje Varga18148672015-10-28 11:04:29 +00001438static DecodeStatus DecodeSynciR6(MCInst &Inst,
1439 unsigned Insn,
1440 uint64_t Address,
1441 const void *Decoder) {
1442 int Immediate = SignExtend32<16>(Insn & 0xffff);
1443 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1444
1445 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1446
1447 Inst.addOperand(MCOperand::createReg(Base));
1448 Inst.addOperand(MCOperand::createImm(Immediate));
1449
1450 return MCDisassembler::Success;
1451}
1452
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001453static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1454 uint64_t Address, const void *Decoder) {
1455 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1456 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1457 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1458
1459 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1460 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1461
Jim Grosbache9119e42015-05-13 18:37:00 +00001462 Inst.addOperand(MCOperand::createReg(Reg));
1463 Inst.addOperand(MCOperand::createReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001464
1465 // The immediate field of an LD/ST instruction is scaled which means it must
1466 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1467 // data format.
1468 // .b - 1 byte
1469 // .h - 2 bytes
1470 // .w - 4 bytes
1471 // .d - 8 bytes
1472 switch(Inst.getOpcode())
1473 {
1474 default:
1475 assert (0 && "Unexpected instruction");
1476 return MCDisassembler::Fail;
1477 break;
1478 case Mips::LD_B:
1479 case Mips::ST_B:
Jim Grosbache9119e42015-05-13 18:37:00 +00001480 Inst.addOperand(MCOperand::createImm(Offset));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001481 break;
1482 case Mips::LD_H:
1483 case Mips::ST_H:
Jim Grosbache9119e42015-05-13 18:37:00 +00001484 Inst.addOperand(MCOperand::createImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001485 break;
1486 case Mips::LD_W:
1487 case Mips::ST_W:
Jim Grosbache9119e42015-05-13 18:37:00 +00001488 Inst.addOperand(MCOperand::createImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001489 break;
1490 case Mips::LD_D:
1491 case Mips::ST_D:
Jim Grosbache9119e42015-05-13 18:37:00 +00001492 Inst.addOperand(MCOperand::createImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001493 break;
1494 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001495
1496 return MCDisassembler::Success;
1497}
1498
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001499static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1500 unsigned Insn,
1501 uint64_t Address,
1502 const void *Decoder) {
1503 unsigned Offset = Insn & 0xf;
1504 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1505 unsigned Base = fieldFromInstruction(Insn, 4, 3);
1506
1507 switch (Inst.getOpcode()) {
1508 case Mips::LBU16_MM:
1509 case Mips::LHU16_MM:
1510 case Mips::LW16_MM:
1511 if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1512 == MCDisassembler::Fail)
1513 return MCDisassembler::Fail;
1514 break;
1515 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001516 case Mips::SB16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001517 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001518 case Mips::SH16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001519 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001520 case Mips::SW16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001521 if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1522 == MCDisassembler::Fail)
1523 return MCDisassembler::Fail;
1524 break;
1525 }
1526
1527 if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1528 == MCDisassembler::Fail)
1529 return MCDisassembler::Fail;
1530
1531 switch (Inst.getOpcode()) {
1532 case Mips::LBU16_MM:
1533 if (Offset == 0xf)
Jim Grosbache9119e42015-05-13 18:37:00 +00001534 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001535 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001536 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001537 break;
1538 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001539 case Mips::SB16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001540 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001541 break;
1542 case Mips::LHU16_MM:
1543 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001544 case Mips::SH16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001545 Inst.addOperand(MCOperand::createImm(Offset << 1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001546 break;
1547 case Mips::LW16_MM:
1548 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001549 case Mips::SW16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001550 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001551 break;
1552 }
1553
1554 return MCDisassembler::Success;
1555}
1556
Jozef Kolek12c69822014-12-23 16:16:33 +00001557static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1558 unsigned Insn,
1559 uint64_t Address,
1560 const void *Decoder) {
1561 unsigned Offset = Insn & 0x1F;
1562 unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1563
1564 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1565
Jim Grosbache9119e42015-05-13 18:37:00 +00001566 Inst.addOperand(MCOperand::createReg(Reg));
1567 Inst.addOperand(MCOperand::createReg(Mips::SP));
1568 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek12c69822014-12-23 16:16:33 +00001569
1570 return MCDisassembler::Success;
1571}
1572
Jozef Koleke10a02e2015-01-28 17:27:26 +00001573static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1574 unsigned Insn,
1575 uint64_t Address,
1576 const void *Decoder) {
1577 unsigned Offset = Insn & 0x7F;
1578 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1579
1580 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1581
Jim Grosbache9119e42015-05-13 18:37:00 +00001582 Inst.addOperand(MCOperand::createReg(Reg));
1583 Inst.addOperand(MCOperand::createReg(Mips::GP));
1584 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Koleke10a02e2015-01-28 17:27:26 +00001585
1586 return MCDisassembler::Success;
1587}
1588
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001589static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1590 unsigned Insn,
1591 uint64_t Address,
1592 const void *Decoder) {
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001593 int Offset;
1594 switch (Inst.getOpcode()) {
1595 case Mips::LWM16_MMR6:
1596 case Mips::SWM16_MMR6:
1597 Offset = fieldFromInstruction(Insn, 4, 4);
1598 break;
1599 default:
1600 Offset = SignExtend32<4>(Insn & 0xf);
1601 break;
1602 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001603
1604 if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1605 == MCDisassembler::Fail)
1606 return MCDisassembler::Fail;
1607
Jim Grosbache9119e42015-05-13 18:37:00 +00001608 Inst.addOperand(MCOperand::createReg(Mips::SP));
1609 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001610
1611 return MCDisassembler::Success;
1612}
1613
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001614static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1615 unsigned Insn,
1616 uint64_t Address,
1617 const void *Decoder) {
1618 int Offset = SignExtend32<9>(Insn & 0x1ff);
1619 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1620 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1621
1622 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1623 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1624
Hrvoje Varga3ef4dd72015-10-15 08:11:50 +00001625 if (Inst.getOpcode() == Mips::SCE_MM)
1626 Inst.addOperand(MCOperand::createReg(Reg));
1627
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001628 Inst.addOperand(MCOperand::createReg(Reg));
1629 Inst.addOperand(MCOperand::createReg(Base));
1630 Inst.addOperand(MCOperand::createImm(Offset));
1631
1632 return MCDisassembler::Success;
1633}
1634
Vladimir Medicdde3d582013-09-06 12:30:36 +00001635static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1636 unsigned Insn,
1637 uint64_t Address,
1638 const void *Decoder) {
1639 int Offset = SignExtend32<12>(Insn & 0x0fff);
1640 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1641 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1642
1643 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1644 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1645
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001646 switch (Inst.getOpcode()) {
1647 case Mips::SWM32_MM:
1648 case Mips::LWM32_MM:
1649 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1650 == MCDisassembler::Fail)
1651 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001652 Inst.addOperand(MCOperand::createReg(Base));
1653 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001654 break;
1655 case Mips::SC_MM:
Jim Grosbache9119e42015-05-13 18:37:00 +00001656 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001657 // fallthrough
1658 default:
Jim Grosbache9119e42015-05-13 18:37:00 +00001659 Inst.addOperand(MCOperand::createReg(Reg));
Zlatko Buljanba553a62016-05-09 08:07:28 +00001660 if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1661 Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
Jim Grosbache9119e42015-05-13 18:37:00 +00001662 Inst.addOperand(MCOperand::createReg(Reg+1));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001663
Jim Grosbache9119e42015-05-13 18:37:00 +00001664 Inst.addOperand(MCOperand::createReg(Base));
1665 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001666 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001667
1668 return MCDisassembler::Success;
1669}
1670
1671static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1672 unsigned Insn,
1673 uint64_t Address,
1674 const void *Decoder) {
1675 int Offset = SignExtend32<16>(Insn & 0xffff);
1676 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1677 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1678
1679 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1680 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1681
Jim Grosbache9119e42015-05-13 18:37:00 +00001682 Inst.addOperand(MCOperand::createReg(Reg));
1683 Inst.addOperand(MCOperand::createReg(Base));
1684 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medicdde3d582013-09-06 12:30:36 +00001685
1686 return MCDisassembler::Success;
1687}
1688
Akira Hatanaka71928e62012-04-17 18:03:21 +00001689static DecodeStatus DecodeFMem(MCInst &Inst,
1690 unsigned Insn,
1691 uint64_t Address,
1692 const void *Decoder) {
1693 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001694 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1695 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001696
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001697 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001698 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001699
Jim Grosbache9119e42015-05-13 18:37:00 +00001700 Inst.addOperand(MCOperand::createReg(Reg));
1701 Inst.addOperand(MCOperand::createReg(Base));
1702 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001703
1704 return MCDisassembler::Success;
1705}
1706
Daniel Sanders92db6b72014-10-01 08:26:55 +00001707static DecodeStatus DecodeFMem2(MCInst &Inst,
1708 unsigned Insn,
1709 uint64_t Address,
1710 const void *Decoder) {
1711 int Offset = SignExtend32<16>(Insn & 0xffff);
1712 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1713 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1714
1715 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1716 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1717
Jim Grosbache9119e42015-05-13 18:37:00 +00001718 Inst.addOperand(MCOperand::createReg(Reg));
1719 Inst.addOperand(MCOperand::createReg(Base));
1720 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001721
1722 return MCDisassembler::Success;
1723}
1724
1725static DecodeStatus DecodeFMem3(MCInst &Inst,
1726 unsigned Insn,
1727 uint64_t Address,
1728 const void *Decoder) {
1729 int Offset = SignExtend32<16>(Insn & 0xffff);
1730 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1731 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1732
1733 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1734 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1735
Jim Grosbache9119e42015-05-13 18:37:00 +00001736 Inst.addOperand(MCOperand::createReg(Reg));
1737 Inst.addOperand(MCOperand::createReg(Base));
1738 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001739
1740 return MCDisassembler::Success;
1741}
1742
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001743static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1744 unsigned Insn,
1745 uint64_t Address,
1746 const void *Decoder) {
1747 int Offset = SignExtend32<11>(Insn & 0x07ff);
1748 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1749 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1750
1751 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1752 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1753
Jim Grosbache9119e42015-05-13 18:37:00 +00001754 Inst.addOperand(MCOperand::createReg(Reg));
1755 Inst.addOperand(MCOperand::createReg(Base));
1756 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001757
1758 return MCDisassembler::Success;
1759}
Daniel Sanders6a803f62014-06-16 13:13:03 +00001760static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1761 unsigned Insn,
1762 uint64_t Address,
1763 const void *Decoder) {
1764 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1765 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1766 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1767
1768 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1769 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1770
1771 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
Jim Grosbache9119e42015-05-13 18:37:00 +00001772 Inst.addOperand(MCOperand::createReg(Rt));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001773 }
1774
Jim Grosbache9119e42015-05-13 18:37:00 +00001775 Inst.addOperand(MCOperand::createReg(Rt));
1776 Inst.addOperand(MCOperand::createReg(Base));
1777 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001778
1779 return MCDisassembler::Success;
1780}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001781
1782static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1783 unsigned RegNo,
1784 uint64_t Address,
1785 const void *Decoder) {
1786 // Currently only hardware register 29 is supported.
1787 if (RegNo != 29)
1788 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001789 Inst.addOperand(MCOperand::createReg(Mips::HWR29));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001790 return MCDisassembler::Success;
1791}
1792
Akira Hatanaka71928e62012-04-17 18:03:21 +00001793static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1794 unsigned RegNo,
1795 uint64_t Address,
1796 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001797 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001798 return MCDisassembler::Fail;
1799
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001800 ;
1801 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
Jim Grosbache9119e42015-05-13 18:37:00 +00001802 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001803 return MCDisassembler::Success;
1804}
1805
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001806static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1807 unsigned RegNo,
1808 uint64_t Address,
1809 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001810 if (RegNo >= 4)
1811 return MCDisassembler::Fail;
1812
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001813 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001814 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001815 return MCDisassembler::Success;
1816}
1817
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001818static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1819 unsigned RegNo,
1820 uint64_t Address,
1821 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001822 if (RegNo >= 4)
1823 return MCDisassembler::Fail;
1824
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001825 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001826 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001827 return MCDisassembler::Success;
1828}
1829
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001830static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
1831 unsigned RegNo,
1832 uint64_t Address,
1833 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001834 if (RegNo >= 4)
1835 return MCDisassembler::Fail;
1836
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001837 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001838 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001839 return MCDisassembler::Success;
1840}
1841
Jack Carter3eb663b2013-09-26 00:09:46 +00001842static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1843 unsigned RegNo,
1844 uint64_t Address,
1845 const void *Decoder) {
1846 if (RegNo > 31)
1847 return MCDisassembler::Fail;
1848
1849 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001850 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter3eb663b2013-09-26 00:09:46 +00001851 return MCDisassembler::Success;
1852}
1853
Jack Carter5dc8ac92013-09-25 23:50:44 +00001854static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1855 unsigned RegNo,
1856 uint64_t Address,
1857 const void *Decoder) {
1858 if (RegNo > 31)
1859 return MCDisassembler::Fail;
1860
1861 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001862 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001863 return MCDisassembler::Success;
1864}
1865
1866static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1867 unsigned RegNo,
1868 uint64_t Address,
1869 const void *Decoder) {
1870 if (RegNo > 31)
1871 return MCDisassembler::Fail;
1872
1873 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001874 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001875 return MCDisassembler::Success;
1876}
1877
1878static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1879 unsigned RegNo,
1880 uint64_t Address,
1881 const void *Decoder) {
1882 if (RegNo > 31)
1883 return MCDisassembler::Fail;
1884
1885 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001886 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001887 return MCDisassembler::Success;
1888}
1889
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001890static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1891 unsigned RegNo,
1892 uint64_t Address,
1893 const void *Decoder) {
1894 if (RegNo > 7)
1895 return MCDisassembler::Fail;
1896
1897 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001898 Inst.addOperand(MCOperand::createReg(Reg));
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001899 return MCDisassembler::Success;
1900}
1901
Daniel Sandersa3134fa2015-06-27 15:39:19 +00001902static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1903 unsigned RegNo,
1904 uint64_t Address,
1905 const void *Decoder) {
1906 if (RegNo > 31)
1907 return MCDisassembler::Fail;
1908
1909 unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1910 Inst.addOperand(MCOperand::createReg(Reg));
1911 return MCDisassembler::Success;
1912}
1913
Daniel Sanders2a83d682014-05-21 12:56:39 +00001914static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1915 unsigned RegNo,
1916 uint64_t Address,
1917 const void *Decoder) {
1918 if (RegNo > 31)
1919 return MCDisassembler::Fail;
1920
1921 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001922 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders2a83d682014-05-21 12:56:39 +00001923 return MCDisassembler::Success;
1924}
1925
Akira Hatanaka71928e62012-04-17 18:03:21 +00001926static DecodeStatus DecodeBranchTarget(MCInst &Inst,
1927 unsigned Offset,
1928 uint64_t Address,
1929 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001930 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00001931 Inst.addOperand(MCOperand::createImm(BranchOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001932 return MCDisassembler::Success;
1933}
1934
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +00001935static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
1936 unsigned Offset,
1937 uint64_t Address,
1938 const void *Decoder) {
1939 int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
1940 Inst.addOperand(MCOperand::createImm(BranchOffset));
1941 return MCDisassembler::Success;
1942}
1943
Akira Hatanaka71928e62012-04-17 18:03:21 +00001944static DecodeStatus DecodeJumpTarget(MCInst &Inst,
1945 unsigned Insn,
1946 uint64_t Address,
1947 const void *Decoder) {
1948
Jim Grosbachecaef492012-08-14 19:06:05 +00001949 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00001950 Inst.addOperand(MCOperand::createImm(JumpOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001951 return MCDisassembler::Success;
1952}
1953
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001954static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
1955 unsigned Offset,
1956 uint64_t Address,
1957 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00001958 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001959
Jim Grosbache9119e42015-05-13 18:37:00 +00001960 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001961 return MCDisassembler::Success;
1962}
1963
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00001964static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
1965 unsigned Offset,
1966 uint64_t Address,
1967 const void *Decoder) {
1968 int32_t BranchOffset = SignExtend32<21>(Offset) << 1;
1969
1970 Inst.addOperand(MCOperand::createImm(BranchOffset));
1971 return MCDisassembler::Success;
1972}
1973
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001974static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
1975 unsigned Offset,
1976 uint64_t Address,
1977 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00001978 int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001979
Jim Grosbache9119e42015-05-13 18:37:00 +00001980 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001981 return MCDisassembler::Success;
1982}
1983
Jozef Kolek9761e962015-01-12 12:03:34 +00001984static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
1985 unsigned Offset,
1986 uint64_t Address,
1987 const void *Decoder) {
1988 int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001989 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek9761e962015-01-12 12:03:34 +00001990 return MCDisassembler::Success;
1991}
1992
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00001993static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
1994 unsigned Offset,
1995 uint64_t Address,
1996 const void *Decoder) {
1997 int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001998 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00001999 return MCDisassembler::Success;
2000}
2001
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002002static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2003 unsigned Offset,
2004 uint64_t Address,
2005 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00002006 int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00002007 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002008 return MCDisassembler::Success;
2009}
2010
Zoran Jovanovica887b362015-11-30 12:56:18 +00002011static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2012 unsigned Offset,
2013 uint64_t Address,
2014 const void *Decoder) {
2015 int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
2016
2017 Inst.addOperand(MCOperand::createImm(BranchOffset));
2018 return MCDisassembler::Success;
2019}
2020
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002021static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2022 unsigned Insn,
2023 uint64_t Address,
2024 const void *Decoder) {
2025 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002026 Inst.addOperand(MCOperand::createImm(JumpOffset));
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002027 return MCDisassembler::Success;
2028}
Akira Hatanaka71928e62012-04-17 18:03:21 +00002029
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002030static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2031 unsigned Value,
2032 uint64_t Address,
2033 const void *Decoder) {
2034 if (Value == 0)
Jim Grosbache9119e42015-05-13 18:37:00 +00002035 Inst.addOperand(MCOperand::createImm(1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002036 else if (Value == 0x7)
Jim Grosbache9119e42015-05-13 18:37:00 +00002037 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002038 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002039 Inst.addOperand(MCOperand::createImm(Value << 2));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002040 return MCDisassembler::Success;
2041}
2042
Daniel Sanders97297772016-03-22 14:40:00 +00002043static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002044 unsigned Value,
2045 uint64_t Address,
2046 const void *Decoder) {
2047 if (Value == 0x7F)
Jim Grosbache9119e42015-05-13 18:37:00 +00002048 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002049 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002050 Inst.addOperand(MCOperand::createImm(Value));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002051 return MCDisassembler::Success;
2052}
2053
Zoran Jovanovic6b28f092015-09-09 13:55:45 +00002054static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
2055 unsigned Value,
2056 uint64_t Address,
2057 const void *Decoder) {
2058 Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
2059 return MCDisassembler::Success;
2060}
2061
Daniel Sanders19b7f762016-03-14 11:16:56 +00002062template <unsigned Bits, int Offset, int Scale>
2063static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2064 uint64_t Address,
2065 const void *Decoder) {
Daniel Sandersea4f6532015-11-06 12:22:31 +00002066 Value &= ((1 << Bits) - 1);
Daniel Sanders19b7f762016-03-14 11:16:56 +00002067 Value *= Scale;
Daniel Sandersea4f6532015-11-06 12:22:31 +00002068 Inst.addOperand(MCOperand::createImm(Value + Offset));
Matheus Almeida779c5932013-11-18 12:32:49 +00002069 return MCDisassembler::Success;
2070}
2071
Daniel Sanders97297772016-03-22 14:40:00 +00002072template <unsigned Bits, int Offset, int ScaleBy>
2073static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2074 uint64_t Address,
2075 const void *Decoder) {
2076 int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
Daniel Sanders78e89022016-03-11 11:37:50 +00002077 Inst.addOperand(MCOperand::createImm(Imm + Offset));
2078 return MCDisassembler::Success;
2079}
2080
Akira Hatanaka71928e62012-04-17 18:03:21 +00002081static DecodeStatus DecodeInsSize(MCInst &Inst,
2082 unsigned Insn,
2083 uint64_t Address,
2084 const void *Decoder) {
2085 // First we need to grab the pos(lsb) from MCInst.
2086 int Pos = Inst.getOperand(2).getImm();
2087 int Size = (int) Insn - Pos + 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002088 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002089 return MCDisassembler::Success;
2090}
2091
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002092static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2093 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002094 Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002095 return MCDisassembler::Success;
2096}
Zoran Jovanovic28551422014-06-09 09:49:51 +00002097
2098static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2099 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002100 Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00002101 return MCDisassembler::Success;
2102}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002103
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002104static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2105 uint64_t Address, const void *Decoder) {
2106 int32_t DecodedValue;
2107 switch (Insn) {
2108 case 0: DecodedValue = 256; break;
2109 case 1: DecodedValue = 257; break;
2110 case 510: DecodedValue = -258; break;
2111 case 511: DecodedValue = -257; break;
2112 default: DecodedValue = SignExtend32<9>(Insn); break;
2113 }
Jim Grosbache9119e42015-05-13 18:37:00 +00002114 Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002115 return MCDisassembler::Success;
2116}
2117
2118static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2119 uint64_t Address, const void *Decoder) {
2120 // Insn must be >= 0, since it is unsigned that condition is always true.
2121 assert(Insn < 16);
2122 int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2123 255, 32768, 65535};
Jim Grosbache9119e42015-05-13 18:37:00 +00002124 Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002125 return MCDisassembler::Success;
2126}
2127
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002128static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2129 unsigned Insn,
2130 uint64_t Address,
2131 const void *Decoder) {
2132 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
Zoran Jovanovicdc4b8c22015-09-15 15:21:27 +00002133 Mips::S6, Mips::S7, Mips::FP};
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002134 unsigned RegNum;
2135
2136 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002137
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002138 // Empty register lists are not allowed.
2139 if (RegLst == 0)
2140 return MCDisassembler::Fail;
2141
2142 RegNum = RegLst & 0xf;
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002143
2144 // RegLst values 10-15, and 26-31 are reserved.
2145 if (RegNum > 9)
2146 return MCDisassembler::Fail;
2147
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002148 for (unsigned i = 0; i < RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002149 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002150
2151 if (RegLst & 0x10)
Jim Grosbache9119e42015-05-13 18:37:00 +00002152 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002153
2154 return MCDisassembler::Success;
2155}
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002156
2157static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2158 uint64_t Address,
2159 const void *Decoder) {
2160 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00002161 unsigned RegLst;
2162 switch(Inst.getOpcode()) {
2163 default:
2164 RegLst = fieldFromInstruction(Insn, 4, 2);
2165 break;
2166 case Mips::LWM16_MMR6:
2167 case Mips::SWM16_MMR6:
2168 RegLst = fieldFromInstruction(Insn, 8, 2);
2169 break;
2170 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002171 unsigned RegNum = RegLst & 0x3;
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002172
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002173 for (unsigned i = 0; i <= RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002174 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002175
Jim Grosbache9119e42015-05-13 18:37:00 +00002176 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002177
2178 return MCDisassembler::Success;
2179}
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002180
Zoran Jovanovic41688672015-02-10 16:36:20 +00002181static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
2182 uint64_t Address, const void *Decoder) {
2183
2184 unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2185
2186 switch (RegPair) {
2187 default:
2188 return MCDisassembler::Fail;
2189 case 0:
Jim Grosbache9119e42015-05-13 18:37:00 +00002190 Inst.addOperand(MCOperand::createReg(Mips::A1));
2191 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002192 break;
2193 case 1:
Jim Grosbache9119e42015-05-13 18:37:00 +00002194 Inst.addOperand(MCOperand::createReg(Mips::A1));
2195 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002196 break;
2197 case 2:
Jim Grosbache9119e42015-05-13 18:37:00 +00002198 Inst.addOperand(MCOperand::createReg(Mips::A2));
2199 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002200 break;
2201 case 3:
Jim Grosbache9119e42015-05-13 18:37:00 +00002202 Inst.addOperand(MCOperand::createReg(Mips::A0));
2203 Inst.addOperand(MCOperand::createReg(Mips::S5));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002204 break;
2205 case 4:
Jim Grosbache9119e42015-05-13 18:37:00 +00002206 Inst.addOperand(MCOperand::createReg(Mips::A0));
2207 Inst.addOperand(MCOperand::createReg(Mips::S6));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002208 break;
2209 case 5:
Jim Grosbache9119e42015-05-13 18:37:00 +00002210 Inst.addOperand(MCOperand::createReg(Mips::A0));
2211 Inst.addOperand(MCOperand::createReg(Mips::A1));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002212 break;
2213 case 6:
Jim Grosbache9119e42015-05-13 18:37:00 +00002214 Inst.addOperand(MCOperand::createReg(Mips::A0));
2215 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002216 break;
2217 case 7:
Jim Grosbache9119e42015-05-13 18:37:00 +00002218 Inst.addOperand(MCOperand::createReg(Mips::A0));
2219 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002220 break;
2221 }
2222
2223 return MCDisassembler::Success;
2224}
2225
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002226static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2227 uint64_t Address, const void *Decoder) {
Justin Bogner6499b5f2015-06-23 07:28:57 +00002228 Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002229 return MCDisassembler::Success;
2230}
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002231
2232template <typename InsnType>
2233static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2234 uint64_t Address,
2235 const void *Decoder) {
2236 // We have:
2237 // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
2238 // Invalid if rt == 0
2239 // BGTZALC_MMR6 if rs == 0 && rt != 0
2240 // BLTZALC_MMR6 if rs != 0 && rs == rt
2241 // BLTUC_MMR6 if rs != 0 && rs != rt
2242
2243 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2244 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2245 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2246 bool HasRs = false;
2247 bool HasRt = false;
2248
2249 if (Rt == 0)
2250 return MCDisassembler::Fail;
2251 else if (Rs == 0) {
2252 MI.setOpcode(Mips::BGTZALC_MMR6);
2253 HasRt = true;
2254 }
2255 else if (Rs == Rt) {
2256 MI.setOpcode(Mips::BLTZALC_MMR6);
2257 HasRs = true;
2258 }
2259 else {
2260 MI.setOpcode(Mips::BLTUC_MMR6);
2261 HasRs = true;
2262 HasRt = true;
2263 }
2264
2265 if (HasRs)
2266 MI.addOperand(
2267 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2268
2269 if (HasRt)
2270 MI.addOperand(
2271 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2272
2273 MI.addOperand(MCOperand::createImm(Imm));
2274
2275 return MCDisassembler::Success;
2276}
2277
2278template <typename InsnType>
2279static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2280 uint64_t Address,
2281 const void *Decoder) {
2282 // We have:
2283 // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
2284 // Invalid if rs == 0
2285 // BLEZALC_MMR6 if rs == 0 && rt != 0
2286 // BGEZALC_MMR6 if rs == rt && rt != 0
2287 // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
2288
2289 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2290 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2291 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2292 bool HasRs = false;
2293
2294 if (Rt == 0)
2295 return MCDisassembler::Fail;
2296 else if (Rs == 0)
2297 MI.setOpcode(Mips::BLEZALC_MMR6);
2298 else if (Rs == Rt)
2299 MI.setOpcode(Mips::BGEZALC_MMR6);
2300 else {
2301 HasRs = true;
2302 MI.setOpcode(Mips::BGEUC_MMR6);
2303 }
2304
2305 if (HasRs)
2306 MI.addOperand(
2307 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2308 MI.addOperand(
2309 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2310
2311 MI.addOperand(MCOperand::createImm(Imm));
2312
2313 return MCDisassembler::Success;
2314}