blob: aebb4ef419d183a458d6d418f09b84695590792f [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
Zlatko Buljancba9f802016-07-11 07:41:56 +0000357static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
358 uint64_t Address,
359 const void *Decoder);
360
Daniel Sanders92db6b72014-10-01 08:26:55 +0000361static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
362 uint64_t Address,
363 const void *Decoder);
364
365static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
366 uint64_t Address,
367 const void *Decoder);
368
Vladimir Medic435cf8a2015-01-21 10:47:36 +0000369static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
370 uint64_t Address,
371 const void *Decoder);
372
Zlatko Buljancba9f802016-07-11 07:41:56 +0000373static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
374 uint64_t Address,
375 const void *Decoder);
376
Daniel Sanders6a803f62014-06-16 13:13:03 +0000377static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
378 unsigned Insn,
379 uint64_t Address,
380 const void *Decoder);
381
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000382static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
383 unsigned Value,
384 uint64_t Address,
385 const void *Decoder);
386
Daniel Sanders97297772016-03-22 14:40:00 +0000387static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000388 unsigned Value,
389 uint64_t Address,
390 const void *Decoder);
391
Zoran Jovanovic6b28f092015-09-09 13:55:45 +0000392static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
393 unsigned Value,
394 uint64_t Address,
395 const void *Decoder);
396
Daniel Sanders19b7f762016-03-14 11:16:56 +0000397template <unsigned Bits, int Offset, int Scale>
398static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
399 uint64_t Address,
400 const void *Decoder);
401
Daniel Sandersea4f6532015-11-06 12:22:31 +0000402template <unsigned Bits, int Offset>
403static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
Daniel Sanders19b7f762016-03-14 11:16:56 +0000404 uint64_t Address,
405 const void *Decoder) {
406 return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
407 Decoder);
408}
Matheus Almeida779c5932013-11-18 12:32:49 +0000409
Daniel Sanders97297772016-03-22 14:40:00 +0000410template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
411static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
412 uint64_t Address,
413 const void *Decoder);
Daniel Sanders78e89022016-03-11 11:37:50 +0000414
Akira Hatanaka71928e62012-04-17 18:03:21 +0000415static DecodeStatus DecodeInsSize(MCInst &Inst,
416 unsigned Insn,
417 uint64_t Address,
418 const void *Decoder);
419
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000420static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
421 uint64_t Address, const void *Decoder);
422
Zoran Jovanovic28551422014-06-09 09:49:51 +0000423static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
424 uint64_t Address, const void *Decoder);
425
Vladimir Medicb682ddf2014-12-01 11:12:04 +0000426static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
427 uint64_t Address, const void *Decoder);
428
429static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
430 uint64_t Address, const void *Decoder);
431
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000432static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
433 uint64_t Address, const void *Decoder);
434
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000435/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
436/// handle.
437template <typename InsnType>
438static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
439 const void *Decoder);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000440
441template <typename InsnType>
442static DecodeStatus
443DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
444 const void *Decoder);
445
446template <typename InsnType>
447static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000448DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
449 const void *Decoder);
450
451template <typename InsnType>
452static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000453DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
454 const void *Decoder);
455
456template <typename InsnType>
457static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000458DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
459 const void *Decoder);
460
461template <typename InsnType>
462static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000463DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
464 const void *Decoder);
465
466template <typename InsnType>
467static DecodeStatus
468DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
469 const void *Decoder);
470
471template <typename InsnType>
472static DecodeStatus
473DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
474 const void *Decoder);
475
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000476template <typename InsnType>
477static DecodeStatus
478DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
479 const void *Decoder);
480
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +0000481template <typename InsnType>
482static DecodeStatus
483DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
484 const void *Decoder);
485
486template <typename InsnType>
487static DecodeStatus
488DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
489 const void *Decoder);
490
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000491static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
492 uint64_t Address,
493 const void *Decoder);
494
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000495static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
496 uint64_t Address,
497 const void *Decoder);
498
Zoran Jovanovic41688672015-02-10 16:36:20 +0000499static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
500 uint64_t Address,
501 const void *Decoder);
502
Akira Hatanaka71928e62012-04-17 18:03:21 +0000503namespace llvm {
504extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
505 TheMips64elTarget;
506}
507
508static MCDisassembler *createMipsDisassembler(
509 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000510 const MCSubtargetInfo &STI,
511 MCContext &Ctx) {
512 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000513}
514
515static MCDisassembler *createMipselDisassembler(
516 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000517 const MCSubtargetInfo &STI,
518 MCContext &Ctx) {
519 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000520}
521
Akira Hatanaka71928e62012-04-17 18:03:21 +0000522extern "C" void LLVMInitializeMipsDisassembler() {
523 // Register the disassembler.
524 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
525 createMipsDisassembler);
526 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
527 createMipselDisassembler);
528 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000529 createMipsDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000530 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000531 createMipselDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000532}
533
Akira Hatanaka71928e62012-04-17 18:03:21 +0000534#include "MipsGenDisassemblerTables.inc"
535
Daniel Sanders5c582b22014-05-22 11:23:21 +0000536static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
Daniel Sandersa19216c2015-02-11 11:28:56 +0000537 const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000538 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
539 return *(RegInfo->getRegClass(RC).begin() + RegNo);
540}
541
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000542template <typename InsnType>
543static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
544 const void *Decoder) {
545 typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
546 // The size of the n field depends on the element size
547 // The register class also depends on this.
548 InsnType tmp = fieldFromInstruction(insn, 17, 5);
549 unsigned NSize = 0;
550 DecodeFN RegDecoder = nullptr;
551 if ((tmp & 0x18) == 0x00) { // INSVE_B
552 NSize = 4;
553 RegDecoder = DecodeMSA128BRegisterClass;
554 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
555 NSize = 3;
556 RegDecoder = DecodeMSA128HRegisterClass;
557 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
558 NSize = 2;
559 RegDecoder = DecodeMSA128WRegisterClass;
560 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
561 NSize = 1;
562 RegDecoder = DecodeMSA128DRegisterClass;
563 } else
564 llvm_unreachable("Invalid encoding");
565
566 assert(NSize != 0 && RegDecoder != nullptr);
567
568 // $wd
569 tmp = fieldFromInstruction(insn, 6, 5);
570 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
571 return MCDisassembler::Fail;
572 // $wd_in
573 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
574 return MCDisassembler::Fail;
575 // $n
576 tmp = fieldFromInstruction(insn, 16, NSize);
Jim Grosbache9119e42015-05-13 18:37:00 +0000577 MI.addOperand(MCOperand::createImm(tmp));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000578 // $ws
579 tmp = fieldFromInstruction(insn, 11, 5);
580 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
581 return MCDisassembler::Fail;
582 // $n2
Jim Grosbache9119e42015-05-13 18:37:00 +0000583 MI.addOperand(MCOperand::createImm(0));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000584
585 return MCDisassembler::Success;
586}
587
Daniel Sanders5c582b22014-05-22 11:23:21 +0000588template <typename InsnType>
589static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
590 uint64_t Address,
591 const void *Decoder) {
592 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
593 // (otherwise we would have matched the ADDI instruction from the earlier
594 // ISA's instead).
595 //
596 // We have:
597 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
598 // BOVC if rs >= rt
599 // BEQZALC if rs == 0 && rt != 0
600 // BEQC if rs < rt && rs != 0
601
602 InsnType Rs = fieldFromInstruction(insn, 21, 5);
603 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000604 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000605 bool HasRs = false;
606
607 if (Rs >= Rt) {
608 MI.setOpcode(Mips::BOVC);
609 HasRs = true;
610 } else if (Rs != 0 && Rs < Rt) {
611 MI.setOpcode(Mips::BEQC);
612 HasRs = true;
613 } else
614 MI.setOpcode(Mips::BEQZALC);
615
616 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000617 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000618 Rs)));
619
Jim Grosbache9119e42015-05-13 18:37:00 +0000620 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000621 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000622 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000623
624 return MCDisassembler::Success;
625}
626
627template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000628static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
629 uint64_t Address,
630 const void *Decoder) {
631 InsnType Rt = fieldFromInstruction(insn, 21, 5);
632 InsnType Rs = fieldFromInstruction(insn, 16, 5);
633 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
634
635 if (Rs >= Rt) {
636 MI.setOpcode(Mips::BOVC_MMR6);
637 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
638 Rt)));
639 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
640 Rs)));
641 } else if (Rs != 0 && Rs < Rt) {
642 MI.setOpcode(Mips::BEQC_MMR6);
643 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
644 Rs)));
645 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
646 Rt)));
647 } else {
648 MI.setOpcode(Mips::BEQZALC_MMR6);
649 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
650 Rt)));
651 }
652
653 MI.addOperand(MCOperand::createImm(Imm));
654
655 return MCDisassembler::Success;
656}
657
658template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000659static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
660 uint64_t Address,
661 const void *Decoder) {
662 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
663 // (otherwise we would have matched the ADDI instruction from the earlier
664 // ISA's instead).
665 //
666 // We have:
667 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
668 // BNVC if rs >= rt
669 // BNEZALC if rs == 0 && rt != 0
670 // BNEC if rs < rt && rs != 0
671
672 InsnType Rs = fieldFromInstruction(insn, 21, 5);
673 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000674 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000675 bool HasRs = false;
676
677 if (Rs >= Rt) {
678 MI.setOpcode(Mips::BNVC);
679 HasRs = true;
680 } else if (Rs != 0 && Rs < Rt) {
681 MI.setOpcode(Mips::BNEC);
682 HasRs = true;
683 } else
684 MI.setOpcode(Mips::BNEZALC);
685
686 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000687 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000688 Rs)));
689
Jim Grosbache9119e42015-05-13 18:37:00 +0000690 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000691 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000692 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000693
694 return MCDisassembler::Success;
695}
696
697template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000698static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
699 uint64_t Address,
700 const void *Decoder) {
701 InsnType Rt = fieldFromInstruction(insn, 21, 5);
702 InsnType Rs = fieldFromInstruction(insn, 16, 5);
703 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
704
705 if (Rs >= Rt) {
706 MI.setOpcode(Mips::BNVC_MMR6);
707 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
708 Rt)));
709 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
710 Rs)));
711 } else if (Rs != 0 && Rs < Rt) {
712 MI.setOpcode(Mips::BNEC_MMR6);
713 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
714 Rs)));
715 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
716 Rt)));
717 } else {
718 MI.setOpcode(Mips::BNEZALC_MMR6);
719 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
720 Rt)));
721 }
722
723 MI.addOperand(MCOperand::createImm(Imm));
724
725 return MCDisassembler::Success;
726}
727
728template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000729static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
730 uint64_t Address,
731 const void *Decoder) {
732 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
733 // (otherwise we would have matched the BLEZL instruction from the earlier
734 // ISA's instead).
735 //
736 // We have:
737 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
738 // Invalid if rs == 0
739 // BLEZC if rs == 0 && rt != 0
740 // BGEZC if rs == rt && rt != 0
741 // BGEC if rs != rt && rs != 0 && rt != 0
742
743 InsnType Rs = fieldFromInstruction(insn, 21, 5);
744 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000745 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000746 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000747
748 if (Rt == 0)
749 return MCDisassembler::Fail;
750 else if (Rs == 0)
751 MI.setOpcode(Mips::BLEZC);
752 else if (Rs == Rt)
753 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000754 else {
755 HasRs = true;
756 MI.setOpcode(Mips::BGEC);
757 }
758
759 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000760 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000761 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000762
Jim Grosbache9119e42015-05-13 18:37:00 +0000763 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000764 Rt)));
765
Jim Grosbache9119e42015-05-13 18:37:00 +0000766 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000767
768 return MCDisassembler::Success;
769}
770
771template <typename InsnType>
772static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
773 uint64_t Address,
774 const void *Decoder) {
775 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
776 // (otherwise we would have matched the BGTZL instruction from the earlier
777 // ISA's instead).
778 //
779 // We have:
780 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
781 // Invalid if rs == 0
782 // BGTZC if rs == 0 && rt != 0
783 // BLTZC if rs == rt && rt != 0
784 // BLTC if rs != rt && rs != 0 && rt != 0
785
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000786 bool HasRs = false;
787
Daniel Sanders5c582b22014-05-22 11:23:21 +0000788 InsnType Rs = fieldFromInstruction(insn, 21, 5);
789 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000790 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000791
792 if (Rt == 0)
793 return MCDisassembler::Fail;
794 else if (Rs == 0)
795 MI.setOpcode(Mips::BGTZC);
796 else if (Rs == Rt)
797 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000798 else {
799 MI.setOpcode(Mips::BLTC);
800 HasRs = true;
801 }
802
803 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000804 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000805 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000806
Jim Grosbache9119e42015-05-13 18:37:00 +0000807 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000808 Rt)));
809
Jim Grosbache9119e42015-05-13 18:37:00 +0000810 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000811
812 return MCDisassembler::Success;
813}
814
815template <typename InsnType>
816static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
817 uint64_t Address,
818 const void *Decoder) {
819 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
820 // (otherwise we would have matched the BGTZ instruction from the earlier
821 // ISA's instead).
822 //
823 // We have:
824 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
825 // BGTZ if rt == 0
826 // BGTZALC if rs == 0 && rt != 0
827 // BLTZALC if rs != 0 && rs == rt
828 // BLTUC if rs != 0 && rs != rt
829
830 InsnType Rs = fieldFromInstruction(insn, 21, 5);
831 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000832 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000833 bool HasRs = false;
834 bool HasRt = false;
835
836 if (Rt == 0) {
837 MI.setOpcode(Mips::BGTZ);
838 HasRs = true;
839 } else if (Rs == 0) {
840 MI.setOpcode(Mips::BGTZALC);
841 HasRt = true;
842 } else if (Rs == Rt) {
843 MI.setOpcode(Mips::BLTZALC);
844 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000845 } else {
846 MI.setOpcode(Mips::BLTUC);
847 HasRs = true;
848 HasRt = true;
849 }
Daniel Sanders5c582b22014-05-22 11:23:21 +0000850
851 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000852 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000853 Rs)));
854
855 if (HasRt)
Jim Grosbache9119e42015-05-13 18:37:00 +0000856 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000857 Rt)));
858
Jim Grosbache9119e42015-05-13 18:37:00 +0000859 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000860
861 return MCDisassembler::Success;
862}
863
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000864template <typename InsnType>
865static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
866 uint64_t Address,
867 const void *Decoder) {
868 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
869 // (otherwise we would have matched the BLEZL instruction from the earlier
870 // ISA's instead).
871 //
872 // We have:
873 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
874 // Invalid if rs == 0
875 // BLEZALC if rs == 0 && rt != 0
876 // BGEZALC if rs == rt && rt != 0
877 // BGEUC if rs != rt && rs != 0 && rt != 0
878
879 InsnType Rs = fieldFromInstruction(insn, 21, 5);
880 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000881 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000882 bool HasRs = false;
883
884 if (Rt == 0)
885 return MCDisassembler::Fail;
886 else if (Rs == 0)
887 MI.setOpcode(Mips::BLEZALC);
888 else if (Rs == Rt)
889 MI.setOpcode(Mips::BGEZALC);
890 else {
891 HasRs = true;
892 MI.setOpcode(Mips::BGEUC);
893 }
894
895 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000896 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000897 Rs)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000898 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000899 Rt)));
900
Jim Grosbache9119e42015-05-13 18:37:00 +0000901 MI.addOperand(MCOperand::createImm(Imm));
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000902
903 return MCDisassembler::Success;
904}
905
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000906/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
907/// according to the given endianess.
908static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
909 uint64_t &Size, uint32_t &Insn,
910 bool IsBigEndian) {
911 // We want to read exactly 2 Bytes of data.
912 if (Bytes.size() < 2) {
913 Size = 0;
914 return MCDisassembler::Fail;
915 }
916
917 if (IsBigEndian) {
918 Insn = (Bytes[0] << 8) | Bytes[1];
919 } else {
920 Insn = (Bytes[1] << 8) | Bytes[0];
921 }
922
923 return MCDisassembler::Success;
924}
925
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000926/// Read four bytes from the ArrayRef and return 32 bit word sorted
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000927/// according to the given endianess
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000928static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
929 uint64_t &Size, uint32_t &Insn,
930 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000931 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000932 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000933 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000934 return MCDisassembler::Fail;
935 }
936
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000937 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
938 // always precede the low 16 bits in the instruction stream (that is, they
939 // are placed at lower addresses in the instruction stream).
940 //
941 // microMIPS byte ordering:
942 // Big-endian: 0 | 1 | 2 | 3
943 // Little-endian: 1 | 0 | 3 | 2
944
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000945 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000946 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000947 Insn =
948 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
949 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +0000950 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000951 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000952 (Bytes[1] << 24);
953 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000954 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000955 (Bytes[3] << 24);
956 }
Akira Hatanaka71928e62012-04-17 18:03:21 +0000957 }
958
959 return MCDisassembler::Success;
960}
961
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000962DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000963 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000964 uint64_t Address,
965 raw_ostream &VStream,
966 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000967 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000968 DecodeStatus Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000969
Vladimir Medicdde3d582013-09-06 12:30:36 +0000970 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000971 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
Reid Klecknerebee6122015-11-19 21:51:55 +0000972 if (Result == MCDisassembler::Fail)
973 return MCDisassembler::Fail;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000974
Zoran Jovanovicada70912015-09-07 11:56:37 +0000975 if (hasMips32r6()) {
976 DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
977 // Calling the auto-generated decoder function for microMIPS32R6
978 // (and microMIPS64R6) 16-bit instructions.
979 Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
980 Address, this, STI);
981 if (Result != MCDisassembler::Fail) {
982 Size = 2;
983 return Result;
984 }
985 }
986
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000987 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
Zoran Jovanovicada70912015-09-07 11:56:37 +0000988 // Calling the auto-generated decoder function for microMIPS 16-bit
989 // instructions.
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000990 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
991 this, STI);
992 if (Result != MCDisassembler::Fail) {
993 Size = 2;
994 return Result;
995 }
996
997 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
998 if (Result == MCDisassembler::Fail)
999 return MCDisassembler::Fail;
1000
Jozef Kolek676d6012015-04-20 14:40:38 +00001001 if (hasMips32r6()) {
1002 DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1003 // Calling the auto-generated decoder function.
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001004 Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
Jozef Kolek676d6012015-04-20 14:40:38 +00001005 this, STI);
Zoran Jovanovicada70912015-09-07 11:56:37 +00001006 if (Result != MCDisassembler::Fail) {
1007 Size = 4;
1008 return Result;
1009 }
Jozef Kolek676d6012015-04-20 14:40:38 +00001010 }
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001011
Zoran Jovanovicada70912015-09-07 11:56:37 +00001012 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1013 // Calling the auto-generated decoder function.
1014 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1015 this, STI);
Vladimir Medicdde3d582013-09-06 12:30:36 +00001016 if (Result != MCDisassembler::Fail) {
1017 Size = 4;
1018 return Result;
1019 }
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001020
Zlatko Buljan6221be82016-03-31 08:51:24 +00001021 if (hasMips32r6() && isFP64()) {
1022 DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
1023 Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001024 Address, this, STI);
1025 if (Result != MCDisassembler::Fail) {
1026 Size = 4;
1027 return Result;
1028 }
1029 }
1030
Reid Klecknerebee6122015-11-19 21:51:55 +00001031 // This is an invalid instruction. Let the disassembler move forward by the
1032 // minimum instruction size.
1033 Size = 2;
Vladimir Medicdde3d582013-09-06 12:30:36 +00001034 return MCDisassembler::Fail;
1035 }
1036
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001037 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Reid Klecknerebee6122015-11-19 21:51:55 +00001038 if (Result == MCDisassembler::Fail) {
1039 Size = 4;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001040 return MCDisassembler::Fail;
Reid Klecknerebee6122015-11-19 21:51:55 +00001041 }
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001042
Daniel Sandersc171f652014-06-13 13:15:59 +00001043 if (hasCOP3()) {
1044 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1045 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001046 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Daniel Sandersc171f652014-06-13 13:15:59 +00001047 if (Result != MCDisassembler::Fail) {
1048 Size = 4;
1049 return Result;
1050 }
1051 }
1052
1053 if (hasMips32r6() && isGP64()) {
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001054 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
1055 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
1056 Address, this, STI);
Daniel Sanders0fa60412014-06-12 13:39:06 +00001057 if (Result != MCDisassembler::Fail) {
1058 Size = 4;
1059 return Result;
1060 }
1061 }
1062
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001063 if (hasMips32r6() && isPTR64()) {
1064 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1065 Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
1066 Address, this, STI);
1067 if (Result != MCDisassembler::Fail) {
1068 Size = 4;
1069 return Result;
1070 }
1071 }
1072
Daniel Sandersc171f652014-06-13 13:15:59 +00001073 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001074 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001075 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +00001076 Address, this, STI);
1077 if (Result != MCDisassembler::Fail) {
1078 Size = 4;
1079 return Result;
1080 }
1081 }
1082
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001083 if (hasMips2() && isPTR64()) {
1084 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1085 Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
1086 Address, this, STI);
1087 if (Result != MCDisassembler::Fail) {
1088 Size = 4;
1089 return Result;
1090 }
1091 }
1092
Kai Nacke3adf9b82015-05-28 16:23:16 +00001093 if (hasCnMips()) {
1094 DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
1095 Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
1096 Address, this, STI);
1097 if (Result != MCDisassembler::Fail) {
1098 Size = 4;
1099 return Result;
1100 }
1101 }
1102
Daniel Sandersa19216c2015-02-11 11:28:56 +00001103 if (isGP64()) {
1104 DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1105 Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1106 Address, this, STI);
1107 if (Result != MCDisassembler::Fail) {
1108 Size = 4;
1109 return Result;
1110 }
1111 }
1112
Daniel Sanders0fa60412014-06-12 13:39:06 +00001113 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +00001114 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001115 Result =
1116 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001117 if (Result != MCDisassembler::Fail) {
1118 Size = 4;
1119 return Result;
1120 }
1121
Reid Klecknerebee6122015-11-19 21:51:55 +00001122 Size = 4;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001123 return MCDisassembler::Fail;
1124}
1125
Reed Kotlerec8a5492013-02-14 03:05:25 +00001126static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1127 unsigned RegNo,
1128 uint64_t Address,
1129 const void *Decoder) {
1130
1131 return MCDisassembler::Fail;
1132
1133}
1134
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001135static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1136 unsigned RegNo,
1137 uint64_t Address,
1138 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001139
1140 if (RegNo > 31)
1141 return MCDisassembler::Fail;
1142
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001143 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001144 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001145 return MCDisassembler::Success;
1146}
1147
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001148static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1149 unsigned RegNo,
1150 uint64_t Address,
1151 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001152 if (RegNo > 7)
1153 return MCDisassembler::Fail;
1154 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001155 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001156 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001157}
1158
Jozef Kolek1904fa22014-11-24 14:25:53 +00001159static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1160 unsigned RegNo,
1161 uint64_t Address,
1162 const void *Decoder) {
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001163 if (RegNo > 7)
1164 return MCDisassembler::Fail;
1165 unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001166 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001167 return MCDisassembler::Success;
Jozef Kolek1904fa22014-11-24 14:25:53 +00001168}
1169
Zoran Jovanovic41688672015-02-10 16:36:20 +00001170static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1171 unsigned RegNo,
1172 uint64_t Address,
1173 const void *Decoder) {
1174 if (RegNo > 7)
1175 return MCDisassembler::Fail;
1176 unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001177 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic41688672015-02-10 16:36:20 +00001178 return MCDisassembler::Success;
1179}
1180
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001181static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1182 unsigned RegNo,
1183 uint64_t Address,
1184 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001185 if (RegNo > 31)
1186 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001187 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001188 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001189 return MCDisassembler::Success;
1190}
1191
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001192static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1193 unsigned RegNo,
1194 uint64_t Address,
1195 const void *Decoder) {
Daniel Sandersa19216c2015-02-11 11:28:56 +00001196 if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001197 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1198
1199 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1200}
1201
Akira Hatanaka654655f2013-08-14 00:53:38 +00001202static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1203 unsigned RegNo,
1204 uint64_t Address,
1205 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001206 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001207}
1208
Akira Hatanaka71928e62012-04-17 18:03:21 +00001209static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1210 unsigned RegNo,
1211 uint64_t Address,
1212 const void *Decoder) {
1213 if (RegNo > 31)
1214 return MCDisassembler::Fail;
1215
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001216 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001217 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001218 return MCDisassembler::Success;
1219}
1220
1221static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1222 unsigned RegNo,
1223 uint64_t Address,
1224 const void *Decoder) {
1225 if (RegNo > 31)
1226 return MCDisassembler::Fail;
1227
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001228 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001229 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001230 return MCDisassembler::Success;
1231}
1232
1233static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1234 unsigned RegNo,
1235 uint64_t Address,
1236 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +00001237 if (RegNo > 31)
1238 return MCDisassembler::Fail;
1239 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001240 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001241 return MCDisassembler::Success;
1242}
1243
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001244static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1245 unsigned RegNo,
1246 uint64_t Address,
1247 const void *Decoder) {
1248 if (RegNo > 7)
1249 return MCDisassembler::Fail;
1250 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001251 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001252 return MCDisassembler::Success;
1253}
1254
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001255static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1256 uint64_t Address,
1257 const void *Decoder) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001258 if (RegNo > 31)
1259 return MCDisassembler::Fail;
1260
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001261 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001262 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders0fa60412014-06-12 13:39:06 +00001263 return MCDisassembler::Success;
1264}
1265
Akira Hatanaka71928e62012-04-17 18:03:21 +00001266static DecodeStatus DecodeMem(MCInst &Inst,
1267 unsigned Insn,
1268 uint64_t Address,
1269 const void *Decoder) {
1270 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001271 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1272 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001273
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001274 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1275 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001276
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001277 if (Inst.getOpcode() == Mips::SC ||
1278 Inst.getOpcode() == Mips::SCD)
Jim Grosbache9119e42015-05-13 18:37:00 +00001279 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001280
1281 Inst.addOperand(MCOperand::createReg(Reg));
1282 Inst.addOperand(MCOperand::createReg(Base));
1283 Inst.addOperand(MCOperand::createImm(Offset));
1284
1285 return MCDisassembler::Success;
1286}
1287
1288static DecodeStatus DecodeMemEVA(MCInst &Inst,
1289 unsigned Insn,
1290 uint64_t Address,
1291 const void *Decoder) {
1292 int Offset = SignExtend32<9>(Insn >> 7);
1293 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1294 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1295
1296 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1297 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1298
1299 if (Inst.getOpcode() == Mips::SCE)
1300 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001301
Jim Grosbache9119e42015-05-13 18:37:00 +00001302 Inst.addOperand(MCOperand::createReg(Reg));
1303 Inst.addOperand(MCOperand::createReg(Base));
1304 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001305
1306 return MCDisassembler::Success;
1307}
1308
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +00001309static DecodeStatus DecodeLoadByte9(MCInst &Inst,
1310 unsigned Insn,
1311 uint64_t Address,
1312 const void *Decoder) {
1313 int Offset = SignExtend32<9>(Insn & 0x1ff);
1314 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1315 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1316
1317 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1318 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1319
1320 Inst.addOperand(MCOperand::createReg(Reg));
1321 Inst.addOperand(MCOperand::createReg(Base));
1322 Inst.addOperand(MCOperand::createImm(Offset));
1323
1324 return MCDisassembler::Success;
1325}
1326
1327static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1328 unsigned Insn,
1329 uint64_t Address,
1330 const void *Decoder) {
1331 int Offset = SignExtend32<16>(Insn & 0xffff);
1332 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1333 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1334
1335 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1336 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1337
1338 Inst.addOperand(MCOperand::createReg(Reg));
1339 Inst.addOperand(MCOperand::createReg(Base));
1340 Inst.addOperand(MCOperand::createImm(Offset));
1341
1342 return MCDisassembler::Success;
1343}
1344
Daniel Sanders92db6b72014-10-01 08:26:55 +00001345static DecodeStatus DecodeCacheOp(MCInst &Inst,
1346 unsigned Insn,
1347 uint64_t Address,
1348 const void *Decoder) {
1349 int Offset = SignExtend32<16>(Insn & 0xffff);
1350 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1351 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1352
1353 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1354
Jim Grosbache9119e42015-05-13 18:37:00 +00001355 Inst.addOperand(MCOperand::createReg(Base));
1356 Inst.addOperand(MCOperand::createImm(Offset));
1357 Inst.addOperand(MCOperand::createImm(Hint));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001358
1359 return MCDisassembler::Success;
1360}
1361
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001362static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1363 unsigned Insn,
1364 uint64_t Address,
1365 const void *Decoder) {
1366 int Offset = SignExtend32<12>(Insn & 0xfff);
1367 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1368 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1369
1370 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1371
Jim Grosbache9119e42015-05-13 18:37:00 +00001372 Inst.addOperand(MCOperand::createReg(Base));
1373 Inst.addOperand(MCOperand::createImm(Offset));
1374 Inst.addOperand(MCOperand::createImm(Hint));
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001375
1376 return MCDisassembler::Success;
1377}
1378
Zoran Jovanovicd9790792015-09-09 09:10:46 +00001379static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1380 unsigned Insn,
1381 uint64_t Address,
1382 const void *Decoder) {
1383 int Offset = SignExtend32<9>(Insn & 0x1ff);
1384 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1385 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1386
1387 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1388
1389 Inst.addOperand(MCOperand::createReg(Base));
1390 Inst.addOperand(MCOperand::createImm(Offset));
1391 Inst.addOperand(MCOperand::createImm(Hint));
1392
1393 return MCDisassembler::Success;
1394}
1395
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001396static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1397 unsigned Insn,
1398 uint64_t Address,
1399 const void *Decoder) {
1400 int Offset = SignExtend32<9>(Insn >> 7);
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001401 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1402 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1403
1404 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1405
Jim Grosbache9119e42015-05-13 18:37:00 +00001406 Inst.addOperand(MCOperand::createReg(Base));
1407 Inst.addOperand(MCOperand::createImm(Offset));
1408 Inst.addOperand(MCOperand::createImm(Hint));
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001409
1410 return MCDisassembler::Success;
1411}
1412
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +00001413static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
1414 unsigned Insn,
1415 uint64_t Address,
1416 const void *Decoder) {
1417 int Offset = SignExtend32<9>(Insn & 0x1ff);
1418 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1419 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1420
1421 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1422 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1423
1424 Inst.addOperand(MCOperand::createReg(Reg));
1425 Inst.addOperand(MCOperand::createReg(Base));
1426 Inst.addOperand(MCOperand::createImm(Offset));
1427
1428 return MCDisassembler::Success;
1429}
1430
Daniel Sandersb4484d62014-11-27 17:28:10 +00001431static DecodeStatus DecodeSyncI(MCInst &Inst,
1432 unsigned Insn,
1433 uint64_t Address,
1434 const void *Decoder) {
1435 int Offset = SignExtend32<16>(Insn & 0xffff);
1436 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1437
1438 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1439
Jim Grosbache9119e42015-05-13 18:37:00 +00001440 Inst.addOperand(MCOperand::createReg(Base));
1441 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sandersb4484d62014-11-27 17:28:10 +00001442
1443 return MCDisassembler::Success;
1444}
1445
Hrvoje Varga18148672015-10-28 11:04:29 +00001446static DecodeStatus DecodeSynciR6(MCInst &Inst,
1447 unsigned Insn,
1448 uint64_t Address,
1449 const void *Decoder) {
1450 int Immediate = SignExtend32<16>(Insn & 0xffff);
1451 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1452
1453 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1454
1455 Inst.addOperand(MCOperand::createReg(Base));
1456 Inst.addOperand(MCOperand::createImm(Immediate));
1457
1458 return MCDisassembler::Success;
1459}
1460
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001461static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1462 uint64_t Address, const void *Decoder) {
1463 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1464 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1465 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1466
1467 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1468 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1469
Jim Grosbache9119e42015-05-13 18:37:00 +00001470 Inst.addOperand(MCOperand::createReg(Reg));
1471 Inst.addOperand(MCOperand::createReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001472
1473 // The immediate field of an LD/ST instruction is scaled which means it must
1474 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1475 // data format.
1476 // .b - 1 byte
1477 // .h - 2 bytes
1478 // .w - 4 bytes
1479 // .d - 8 bytes
1480 switch(Inst.getOpcode())
1481 {
1482 default:
1483 assert (0 && "Unexpected instruction");
1484 return MCDisassembler::Fail;
1485 break;
1486 case Mips::LD_B:
1487 case Mips::ST_B:
Jim Grosbache9119e42015-05-13 18:37:00 +00001488 Inst.addOperand(MCOperand::createImm(Offset));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001489 break;
1490 case Mips::LD_H:
1491 case Mips::ST_H:
Jim Grosbache9119e42015-05-13 18:37:00 +00001492 Inst.addOperand(MCOperand::createImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001493 break;
1494 case Mips::LD_W:
1495 case Mips::ST_W:
Jim Grosbache9119e42015-05-13 18:37:00 +00001496 Inst.addOperand(MCOperand::createImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001497 break;
1498 case Mips::LD_D:
1499 case Mips::ST_D:
Jim Grosbache9119e42015-05-13 18:37:00 +00001500 Inst.addOperand(MCOperand::createImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001501 break;
1502 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001503
1504 return MCDisassembler::Success;
1505}
1506
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001507static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1508 unsigned Insn,
1509 uint64_t Address,
1510 const void *Decoder) {
1511 unsigned Offset = Insn & 0xf;
1512 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1513 unsigned Base = fieldFromInstruction(Insn, 4, 3);
1514
1515 switch (Inst.getOpcode()) {
1516 case Mips::LBU16_MM:
1517 case Mips::LHU16_MM:
1518 case Mips::LW16_MM:
1519 if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1520 == MCDisassembler::Fail)
1521 return MCDisassembler::Fail;
1522 break;
1523 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001524 case Mips::SB16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001525 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001526 case Mips::SH16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001527 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001528 case Mips::SW16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001529 if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1530 == MCDisassembler::Fail)
1531 return MCDisassembler::Fail;
1532 break;
1533 }
1534
1535 if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1536 == MCDisassembler::Fail)
1537 return MCDisassembler::Fail;
1538
1539 switch (Inst.getOpcode()) {
1540 case Mips::LBU16_MM:
1541 if (Offset == 0xf)
Jim Grosbache9119e42015-05-13 18:37:00 +00001542 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001543 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001544 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001545 break;
1546 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001547 case Mips::SB16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001548 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001549 break;
1550 case Mips::LHU16_MM:
1551 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001552 case Mips::SH16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001553 Inst.addOperand(MCOperand::createImm(Offset << 1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001554 break;
1555 case Mips::LW16_MM:
1556 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001557 case Mips::SW16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001558 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001559 break;
1560 }
1561
1562 return MCDisassembler::Success;
1563}
1564
Jozef Kolek12c69822014-12-23 16:16:33 +00001565static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1566 unsigned Insn,
1567 uint64_t Address,
1568 const void *Decoder) {
1569 unsigned Offset = Insn & 0x1F;
1570 unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1571
1572 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1573
Jim Grosbache9119e42015-05-13 18:37:00 +00001574 Inst.addOperand(MCOperand::createReg(Reg));
1575 Inst.addOperand(MCOperand::createReg(Mips::SP));
1576 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek12c69822014-12-23 16:16:33 +00001577
1578 return MCDisassembler::Success;
1579}
1580
Jozef Koleke10a02e2015-01-28 17:27:26 +00001581static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1582 unsigned Insn,
1583 uint64_t Address,
1584 const void *Decoder) {
1585 unsigned Offset = Insn & 0x7F;
1586 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1587
1588 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1589
Jim Grosbache9119e42015-05-13 18:37:00 +00001590 Inst.addOperand(MCOperand::createReg(Reg));
1591 Inst.addOperand(MCOperand::createReg(Mips::GP));
1592 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Koleke10a02e2015-01-28 17:27:26 +00001593
1594 return MCDisassembler::Success;
1595}
1596
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001597static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1598 unsigned Insn,
1599 uint64_t Address,
1600 const void *Decoder) {
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001601 int Offset;
1602 switch (Inst.getOpcode()) {
1603 case Mips::LWM16_MMR6:
1604 case Mips::SWM16_MMR6:
1605 Offset = fieldFromInstruction(Insn, 4, 4);
1606 break;
1607 default:
1608 Offset = SignExtend32<4>(Insn & 0xf);
1609 break;
1610 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001611
1612 if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1613 == MCDisassembler::Fail)
1614 return MCDisassembler::Fail;
1615
Jim Grosbache9119e42015-05-13 18:37:00 +00001616 Inst.addOperand(MCOperand::createReg(Mips::SP));
1617 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001618
1619 return MCDisassembler::Success;
1620}
1621
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001622static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1623 unsigned Insn,
1624 uint64_t Address,
1625 const void *Decoder) {
1626 int Offset = SignExtend32<9>(Insn & 0x1ff);
1627 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1628 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1629
1630 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1631 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1632
Hrvoje Varga3ef4dd72015-10-15 08:11:50 +00001633 if (Inst.getOpcode() == Mips::SCE_MM)
1634 Inst.addOperand(MCOperand::createReg(Reg));
1635
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001636 Inst.addOperand(MCOperand::createReg(Reg));
1637 Inst.addOperand(MCOperand::createReg(Base));
1638 Inst.addOperand(MCOperand::createImm(Offset));
1639
1640 return MCDisassembler::Success;
1641}
1642
Vladimir Medicdde3d582013-09-06 12:30:36 +00001643static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1644 unsigned Insn,
1645 uint64_t Address,
1646 const void *Decoder) {
1647 int Offset = SignExtend32<12>(Insn & 0x0fff);
1648 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1649 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1650
1651 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1652 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1653
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001654 switch (Inst.getOpcode()) {
1655 case Mips::SWM32_MM:
1656 case Mips::LWM32_MM:
1657 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1658 == MCDisassembler::Fail)
1659 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001660 Inst.addOperand(MCOperand::createReg(Base));
1661 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001662 break;
1663 case Mips::SC_MM:
Jim Grosbache9119e42015-05-13 18:37:00 +00001664 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001665 // fallthrough
1666 default:
Jim Grosbache9119e42015-05-13 18:37:00 +00001667 Inst.addOperand(MCOperand::createReg(Reg));
Zlatko Buljanba553a62016-05-09 08:07:28 +00001668 if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1669 Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
Jim Grosbache9119e42015-05-13 18:37:00 +00001670 Inst.addOperand(MCOperand::createReg(Reg+1));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001671
Jim Grosbache9119e42015-05-13 18:37:00 +00001672 Inst.addOperand(MCOperand::createReg(Base));
1673 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001674 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001675
1676 return MCDisassembler::Success;
1677}
1678
1679static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1680 unsigned Insn,
1681 uint64_t Address,
1682 const void *Decoder) {
1683 int Offset = SignExtend32<16>(Insn & 0xffff);
1684 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1685 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1686
1687 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1688 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1689
Jim Grosbache9119e42015-05-13 18:37:00 +00001690 Inst.addOperand(MCOperand::createReg(Reg));
1691 Inst.addOperand(MCOperand::createReg(Base));
1692 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medicdde3d582013-09-06 12:30:36 +00001693
1694 return MCDisassembler::Success;
1695}
1696
Akira Hatanaka71928e62012-04-17 18:03:21 +00001697static DecodeStatus DecodeFMem(MCInst &Inst,
1698 unsigned Insn,
1699 uint64_t Address,
1700 const void *Decoder) {
1701 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001702 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1703 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001704
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001705 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001706 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001707
Jim Grosbache9119e42015-05-13 18:37:00 +00001708 Inst.addOperand(MCOperand::createReg(Reg));
1709 Inst.addOperand(MCOperand::createReg(Base));
1710 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001711
1712 return MCDisassembler::Success;
1713}
1714
Zlatko Buljancba9f802016-07-11 07:41:56 +00001715static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1716 uint64_t Address, const void *Decoder) {
1717 // This function is the same as DecodeFMem but with the Reg and Base fields
1718 // swapped according to microMIPS spec.
1719 int Offset = SignExtend32<16>(Insn & 0xffff);
1720 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1721 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1722
1723 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1724 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1725
1726 Inst.addOperand(MCOperand::createReg(Reg));
1727 Inst.addOperand(MCOperand::createReg(Base));
1728 Inst.addOperand(MCOperand::createImm(Offset));
1729
1730 return MCDisassembler::Success;
1731}
1732
Daniel Sanders92db6b72014-10-01 08:26:55 +00001733static DecodeStatus DecodeFMem2(MCInst &Inst,
1734 unsigned Insn,
1735 uint64_t Address,
1736 const void *Decoder) {
1737 int Offset = SignExtend32<16>(Insn & 0xffff);
1738 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1739 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1740
1741 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1742 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1743
Jim Grosbache9119e42015-05-13 18:37:00 +00001744 Inst.addOperand(MCOperand::createReg(Reg));
1745 Inst.addOperand(MCOperand::createReg(Base));
1746 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001747
1748 return MCDisassembler::Success;
1749}
1750
1751static DecodeStatus DecodeFMem3(MCInst &Inst,
1752 unsigned Insn,
1753 uint64_t Address,
1754 const void *Decoder) {
1755 int Offset = SignExtend32<16>(Insn & 0xffff);
1756 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1757 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1758
1759 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1760 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1761
Jim Grosbache9119e42015-05-13 18:37:00 +00001762 Inst.addOperand(MCOperand::createReg(Reg));
1763 Inst.addOperand(MCOperand::createReg(Base));
1764 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001765
1766 return MCDisassembler::Success;
1767}
1768
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001769static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1770 unsigned Insn,
1771 uint64_t Address,
1772 const void *Decoder) {
1773 int Offset = SignExtend32<11>(Insn & 0x07ff);
1774 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1775 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1776
1777 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1778 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1779
Jim Grosbache9119e42015-05-13 18:37:00 +00001780 Inst.addOperand(MCOperand::createReg(Reg));
1781 Inst.addOperand(MCOperand::createReg(Base));
1782 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001783
1784 return MCDisassembler::Success;
1785}
Zlatko Buljancba9f802016-07-11 07:41:56 +00001786
1787static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1788 uint64_t Address, const void *Decoder) {
1789 int Offset = SignExtend32<11>(Insn & 0x07ff);
1790 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1791 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1792
1793 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1794 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1795
1796 Inst.addOperand(MCOperand::createReg(Reg));
1797 Inst.addOperand(MCOperand::createReg(Base));
1798 Inst.addOperand(MCOperand::createImm(Offset));
1799
1800 return MCDisassembler::Success;
1801}
1802
Daniel Sanders6a803f62014-06-16 13:13:03 +00001803static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1804 unsigned Insn,
1805 uint64_t Address,
1806 const void *Decoder) {
1807 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1808 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1809 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1810
1811 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1812 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1813
1814 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
Jim Grosbache9119e42015-05-13 18:37:00 +00001815 Inst.addOperand(MCOperand::createReg(Rt));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001816 }
1817
Jim Grosbache9119e42015-05-13 18:37:00 +00001818 Inst.addOperand(MCOperand::createReg(Rt));
1819 Inst.addOperand(MCOperand::createReg(Base));
1820 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001821
1822 return MCDisassembler::Success;
1823}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001824
1825static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1826 unsigned RegNo,
1827 uint64_t Address,
1828 const void *Decoder) {
1829 // Currently only hardware register 29 is supported.
1830 if (RegNo != 29)
1831 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001832 Inst.addOperand(MCOperand::createReg(Mips::HWR29));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001833 return MCDisassembler::Success;
1834}
1835
Akira Hatanaka71928e62012-04-17 18:03:21 +00001836static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1837 unsigned RegNo,
1838 uint64_t Address,
1839 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001840 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001841 return MCDisassembler::Fail;
1842
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001843 ;
1844 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
Jim Grosbache9119e42015-05-13 18:37:00 +00001845 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001846 return MCDisassembler::Success;
1847}
1848
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001849static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1850 unsigned RegNo,
1851 uint64_t Address,
1852 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001853 if (RegNo >= 4)
1854 return MCDisassembler::Fail;
1855
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001856 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001857 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001858 return MCDisassembler::Success;
1859}
1860
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001861static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1862 unsigned RegNo,
1863 uint64_t Address,
1864 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001865 if (RegNo >= 4)
1866 return MCDisassembler::Fail;
1867
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001868 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001869 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001870 return MCDisassembler::Success;
1871}
1872
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001873static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
1874 unsigned RegNo,
1875 uint64_t Address,
1876 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001877 if (RegNo >= 4)
1878 return MCDisassembler::Fail;
1879
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001880 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001881 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001882 return MCDisassembler::Success;
1883}
1884
Jack Carter3eb663b2013-09-26 00:09:46 +00001885static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1886 unsigned RegNo,
1887 uint64_t Address,
1888 const void *Decoder) {
1889 if (RegNo > 31)
1890 return MCDisassembler::Fail;
1891
1892 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001893 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter3eb663b2013-09-26 00:09:46 +00001894 return MCDisassembler::Success;
1895}
1896
Jack Carter5dc8ac92013-09-25 23:50:44 +00001897static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1898 unsigned RegNo,
1899 uint64_t Address,
1900 const void *Decoder) {
1901 if (RegNo > 31)
1902 return MCDisassembler::Fail;
1903
1904 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001905 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001906 return MCDisassembler::Success;
1907}
1908
1909static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1910 unsigned RegNo,
1911 uint64_t Address,
1912 const void *Decoder) {
1913 if (RegNo > 31)
1914 return MCDisassembler::Fail;
1915
1916 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001917 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001918 return MCDisassembler::Success;
1919}
1920
1921static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1922 unsigned RegNo,
1923 uint64_t Address,
1924 const void *Decoder) {
1925 if (RegNo > 31)
1926 return MCDisassembler::Fail;
1927
1928 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001929 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001930 return MCDisassembler::Success;
1931}
1932
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001933static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1934 unsigned RegNo,
1935 uint64_t Address,
1936 const void *Decoder) {
1937 if (RegNo > 7)
1938 return MCDisassembler::Fail;
1939
1940 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001941 Inst.addOperand(MCOperand::createReg(Reg));
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001942 return MCDisassembler::Success;
1943}
1944
Daniel Sandersa3134fa2015-06-27 15:39:19 +00001945static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1946 unsigned RegNo,
1947 uint64_t Address,
1948 const void *Decoder) {
1949 if (RegNo > 31)
1950 return MCDisassembler::Fail;
1951
1952 unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1953 Inst.addOperand(MCOperand::createReg(Reg));
1954 return MCDisassembler::Success;
1955}
1956
Daniel Sanders2a83d682014-05-21 12:56:39 +00001957static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1958 unsigned RegNo,
1959 uint64_t Address,
1960 const void *Decoder) {
1961 if (RegNo > 31)
1962 return MCDisassembler::Fail;
1963
1964 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001965 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders2a83d682014-05-21 12:56:39 +00001966 return MCDisassembler::Success;
1967}
1968
Akira Hatanaka71928e62012-04-17 18:03:21 +00001969static DecodeStatus DecodeBranchTarget(MCInst &Inst,
1970 unsigned Offset,
1971 uint64_t Address,
1972 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001973 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00001974 Inst.addOperand(MCOperand::createImm(BranchOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001975 return MCDisassembler::Success;
1976}
1977
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +00001978static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
1979 unsigned Offset,
1980 uint64_t Address,
1981 const void *Decoder) {
1982 int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
1983 Inst.addOperand(MCOperand::createImm(BranchOffset));
1984 return MCDisassembler::Success;
1985}
1986
Akira Hatanaka71928e62012-04-17 18:03:21 +00001987static DecodeStatus DecodeJumpTarget(MCInst &Inst,
1988 unsigned Insn,
1989 uint64_t Address,
1990 const void *Decoder) {
1991
Jim Grosbachecaef492012-08-14 19:06:05 +00001992 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00001993 Inst.addOperand(MCOperand::createImm(JumpOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001994 return MCDisassembler::Success;
1995}
1996
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001997static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
1998 unsigned Offset,
1999 uint64_t Address,
2000 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00002001 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002002
Jim Grosbache9119e42015-05-13 18:37:00 +00002003 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002004 return MCDisassembler::Success;
2005}
2006
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00002007static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
2008 unsigned Offset,
2009 uint64_t Address,
2010 const void *Decoder) {
2011 int32_t BranchOffset = SignExtend32<21>(Offset) << 1;
2012
2013 Inst.addOperand(MCOperand::createImm(BranchOffset));
2014 return MCDisassembler::Success;
2015}
2016
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002017static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2018 unsigned Offset,
2019 uint64_t Address,
2020 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00002021 int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002022
Jim Grosbache9119e42015-05-13 18:37:00 +00002023 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002024 return MCDisassembler::Success;
2025}
2026
Jozef Kolek9761e962015-01-12 12:03:34 +00002027static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2028 unsigned Offset,
2029 uint64_t Address,
2030 const void *Decoder) {
2031 int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002032 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek9761e962015-01-12 12:03:34 +00002033 return MCDisassembler::Success;
2034}
2035
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002036static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2037 unsigned Offset,
2038 uint64_t Address,
2039 const void *Decoder) {
2040 int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002041 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002042 return MCDisassembler::Success;
2043}
2044
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002045static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2046 unsigned Offset,
2047 uint64_t Address,
2048 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00002049 int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00002050 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002051 return MCDisassembler::Success;
2052}
2053
Zoran Jovanovica887b362015-11-30 12:56:18 +00002054static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2055 unsigned Offset,
2056 uint64_t Address,
2057 const void *Decoder) {
2058 int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
2059
2060 Inst.addOperand(MCOperand::createImm(BranchOffset));
2061 return MCDisassembler::Success;
2062}
2063
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002064static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2065 unsigned Insn,
2066 uint64_t Address,
2067 const void *Decoder) {
2068 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002069 Inst.addOperand(MCOperand::createImm(JumpOffset));
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002070 return MCDisassembler::Success;
2071}
Akira Hatanaka71928e62012-04-17 18:03:21 +00002072
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002073static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2074 unsigned Value,
2075 uint64_t Address,
2076 const void *Decoder) {
2077 if (Value == 0)
Jim Grosbache9119e42015-05-13 18:37:00 +00002078 Inst.addOperand(MCOperand::createImm(1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002079 else if (Value == 0x7)
Jim Grosbache9119e42015-05-13 18:37:00 +00002080 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002081 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002082 Inst.addOperand(MCOperand::createImm(Value << 2));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002083 return MCDisassembler::Success;
2084}
2085
Daniel Sanders97297772016-03-22 14:40:00 +00002086static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002087 unsigned Value,
2088 uint64_t Address,
2089 const void *Decoder) {
2090 if (Value == 0x7F)
Jim Grosbache9119e42015-05-13 18:37:00 +00002091 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002092 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002093 Inst.addOperand(MCOperand::createImm(Value));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002094 return MCDisassembler::Success;
2095}
2096
Zoran Jovanovic6b28f092015-09-09 13:55:45 +00002097static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
2098 unsigned Value,
2099 uint64_t Address,
2100 const void *Decoder) {
2101 Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
2102 return MCDisassembler::Success;
2103}
2104
Daniel Sanders19b7f762016-03-14 11:16:56 +00002105template <unsigned Bits, int Offset, int Scale>
2106static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2107 uint64_t Address,
2108 const void *Decoder) {
Daniel Sandersea4f6532015-11-06 12:22:31 +00002109 Value &= ((1 << Bits) - 1);
Daniel Sanders19b7f762016-03-14 11:16:56 +00002110 Value *= Scale;
Daniel Sandersea4f6532015-11-06 12:22:31 +00002111 Inst.addOperand(MCOperand::createImm(Value + Offset));
Matheus Almeida779c5932013-11-18 12:32:49 +00002112 return MCDisassembler::Success;
2113}
2114
Daniel Sanders97297772016-03-22 14:40:00 +00002115template <unsigned Bits, int Offset, int ScaleBy>
2116static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2117 uint64_t Address,
2118 const void *Decoder) {
2119 int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
Daniel Sanders78e89022016-03-11 11:37:50 +00002120 Inst.addOperand(MCOperand::createImm(Imm + Offset));
2121 return MCDisassembler::Success;
2122}
2123
Akira Hatanaka71928e62012-04-17 18:03:21 +00002124static DecodeStatus DecodeInsSize(MCInst &Inst,
2125 unsigned Insn,
2126 uint64_t Address,
2127 const void *Decoder) {
2128 // First we need to grab the pos(lsb) from MCInst.
2129 int Pos = Inst.getOperand(2).getImm();
2130 int Size = (int) Insn - Pos + 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002131 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002132 return MCDisassembler::Success;
2133}
2134
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002135static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2136 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002137 Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002138 return MCDisassembler::Success;
2139}
Zoran Jovanovic28551422014-06-09 09:49:51 +00002140
2141static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2142 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002143 Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00002144 return MCDisassembler::Success;
2145}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002146
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002147static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2148 uint64_t Address, const void *Decoder) {
2149 int32_t DecodedValue;
2150 switch (Insn) {
2151 case 0: DecodedValue = 256; break;
2152 case 1: DecodedValue = 257; break;
2153 case 510: DecodedValue = -258; break;
2154 case 511: DecodedValue = -257; break;
2155 default: DecodedValue = SignExtend32<9>(Insn); break;
2156 }
Jim Grosbache9119e42015-05-13 18:37:00 +00002157 Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002158 return MCDisassembler::Success;
2159}
2160
2161static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2162 uint64_t Address, const void *Decoder) {
2163 // Insn must be >= 0, since it is unsigned that condition is always true.
2164 assert(Insn < 16);
2165 int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2166 255, 32768, 65535};
Jim Grosbache9119e42015-05-13 18:37:00 +00002167 Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002168 return MCDisassembler::Success;
2169}
2170
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002171static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2172 unsigned Insn,
2173 uint64_t Address,
2174 const void *Decoder) {
2175 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
Zoran Jovanovicdc4b8c22015-09-15 15:21:27 +00002176 Mips::S6, Mips::S7, Mips::FP};
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002177 unsigned RegNum;
2178
2179 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002180
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002181 // Empty register lists are not allowed.
2182 if (RegLst == 0)
2183 return MCDisassembler::Fail;
2184
2185 RegNum = RegLst & 0xf;
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002186
2187 // RegLst values 10-15, and 26-31 are reserved.
2188 if (RegNum > 9)
2189 return MCDisassembler::Fail;
2190
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002191 for (unsigned i = 0; i < RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002192 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002193
2194 if (RegLst & 0x10)
Jim Grosbache9119e42015-05-13 18:37:00 +00002195 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002196
2197 return MCDisassembler::Success;
2198}
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002199
2200static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2201 uint64_t Address,
2202 const void *Decoder) {
2203 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00002204 unsigned RegLst;
2205 switch(Inst.getOpcode()) {
2206 default:
2207 RegLst = fieldFromInstruction(Insn, 4, 2);
2208 break;
2209 case Mips::LWM16_MMR6:
2210 case Mips::SWM16_MMR6:
2211 RegLst = fieldFromInstruction(Insn, 8, 2);
2212 break;
2213 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002214 unsigned RegNum = RegLst & 0x3;
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002215
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002216 for (unsigned i = 0; i <= RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002217 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002218
Jim Grosbache9119e42015-05-13 18:37:00 +00002219 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002220
2221 return MCDisassembler::Success;
2222}
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002223
Zoran Jovanovic41688672015-02-10 16:36:20 +00002224static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
2225 uint64_t Address, const void *Decoder) {
2226
2227 unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2228
2229 switch (RegPair) {
2230 default:
2231 return MCDisassembler::Fail;
2232 case 0:
Jim Grosbache9119e42015-05-13 18:37:00 +00002233 Inst.addOperand(MCOperand::createReg(Mips::A1));
2234 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002235 break;
2236 case 1:
Jim Grosbache9119e42015-05-13 18:37:00 +00002237 Inst.addOperand(MCOperand::createReg(Mips::A1));
2238 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002239 break;
2240 case 2:
Jim Grosbache9119e42015-05-13 18:37:00 +00002241 Inst.addOperand(MCOperand::createReg(Mips::A2));
2242 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002243 break;
2244 case 3:
Jim Grosbache9119e42015-05-13 18:37:00 +00002245 Inst.addOperand(MCOperand::createReg(Mips::A0));
2246 Inst.addOperand(MCOperand::createReg(Mips::S5));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002247 break;
2248 case 4:
Jim Grosbache9119e42015-05-13 18:37:00 +00002249 Inst.addOperand(MCOperand::createReg(Mips::A0));
2250 Inst.addOperand(MCOperand::createReg(Mips::S6));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002251 break;
2252 case 5:
Jim Grosbache9119e42015-05-13 18:37:00 +00002253 Inst.addOperand(MCOperand::createReg(Mips::A0));
2254 Inst.addOperand(MCOperand::createReg(Mips::A1));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002255 break;
2256 case 6:
Jim Grosbache9119e42015-05-13 18:37:00 +00002257 Inst.addOperand(MCOperand::createReg(Mips::A0));
2258 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002259 break;
2260 case 7:
Jim Grosbache9119e42015-05-13 18:37:00 +00002261 Inst.addOperand(MCOperand::createReg(Mips::A0));
2262 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002263 break;
2264 }
2265
2266 return MCDisassembler::Success;
2267}
2268
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002269static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2270 uint64_t Address, const void *Decoder) {
Justin Bogner6499b5f2015-06-23 07:28:57 +00002271 Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002272 return MCDisassembler::Success;
2273}
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002274
2275template <typename InsnType>
2276static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2277 uint64_t Address,
2278 const void *Decoder) {
2279 // We have:
2280 // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
2281 // Invalid if rt == 0
2282 // BGTZALC_MMR6 if rs == 0 && rt != 0
2283 // BLTZALC_MMR6 if rs != 0 && rs == rt
2284 // BLTUC_MMR6 if rs != 0 && rs != rt
2285
2286 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2287 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2288 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2289 bool HasRs = false;
2290 bool HasRt = false;
2291
2292 if (Rt == 0)
2293 return MCDisassembler::Fail;
2294 else if (Rs == 0) {
2295 MI.setOpcode(Mips::BGTZALC_MMR6);
2296 HasRt = true;
2297 }
2298 else if (Rs == Rt) {
2299 MI.setOpcode(Mips::BLTZALC_MMR6);
2300 HasRs = true;
2301 }
2302 else {
2303 MI.setOpcode(Mips::BLTUC_MMR6);
2304 HasRs = true;
2305 HasRt = true;
2306 }
2307
2308 if (HasRs)
2309 MI.addOperand(
2310 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2311
2312 if (HasRt)
2313 MI.addOperand(
2314 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2315
2316 MI.addOperand(MCOperand::createImm(Imm));
2317
2318 return MCDisassembler::Success;
2319}
2320
2321template <typename InsnType>
2322static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2323 uint64_t Address,
2324 const void *Decoder) {
2325 // We have:
2326 // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
2327 // Invalid if rs == 0
2328 // BLEZALC_MMR6 if rs == 0 && rt != 0
2329 // BGEZALC_MMR6 if rs == rt && rt != 0
2330 // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
2331
2332 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2333 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2334 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2335 bool HasRs = false;
2336
2337 if (Rt == 0)
2338 return MCDisassembler::Fail;
2339 else if (Rs == 0)
2340 MI.setOpcode(Mips::BLEZALC_MMR6);
2341 else if (Rs == Rt)
2342 MI.setOpcode(Mips::BGEZALC_MMR6);
2343 else {
2344 HasRs = true;
2345 MI.setOpcode(Mips::BGEUC_MMR6);
2346 }
2347
2348 if (HasRs)
2349 MI.addOperand(
2350 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2351 MI.addOperand(
2352 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2353
2354 MI.addOperand(MCOperand::createImm(Imm));
2355
2356 return MCDisassembler::Success;
2357}