blob: 74a8f4f2152a19414e7550bd830a7e19e8c5f22e [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>
Simon Dardiscf060792016-09-16 13:50:43 +0000442static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
443 const void *Decoder);
444
445template <typename InsnType>
446static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
447 const void *Decoder);
448
449template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000450static DecodeStatus
451DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
452 const void *Decoder);
453
454template <typename InsnType>
455static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000456DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
457 const void *Decoder);
458
459template <typename InsnType>
460static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000461DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
462 const void *Decoder);
463
464template <typename InsnType>
465static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000466DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
467 const void *Decoder);
468
469template <typename InsnType>
470static DecodeStatus
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000471DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
472 const void *Decoder);
473
474template <typename InsnType>
475static DecodeStatus
476DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
477 const void *Decoder);
478
479template <typename InsnType>
480static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000481DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
482 const void *Decoder);
483
484template <typename InsnType>
485static DecodeStatus
486DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
487 const void *Decoder);
488
489template <typename InsnType>
490static DecodeStatus
491DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
492 const void *Decoder);
493
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000494template <typename InsnType>
495static DecodeStatus
496DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
497 const void *Decoder);
498
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +0000499template <typename InsnType>
500static DecodeStatus
501DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
502 const void *Decoder);
503
504template <typename InsnType>
505static DecodeStatus
506DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
507 const void *Decoder);
508
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000509static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
510 uint64_t Address,
511 const void *Decoder);
512
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000513static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
514 uint64_t Address,
515 const void *Decoder);
516
Zoran Jovanovic41688672015-02-10 16:36:20 +0000517static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
518 uint64_t Address,
519 const void *Decoder);
520
Akira Hatanaka71928e62012-04-17 18:03:21 +0000521namespace llvm {
522extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
523 TheMips64elTarget;
524}
525
526static MCDisassembler *createMipsDisassembler(
527 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000528 const MCSubtargetInfo &STI,
529 MCContext &Ctx) {
530 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000531}
532
533static MCDisassembler *createMipselDisassembler(
534 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000535 const MCSubtargetInfo &STI,
536 MCContext &Ctx) {
537 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000538}
539
Akira Hatanaka71928e62012-04-17 18:03:21 +0000540extern "C" void LLVMInitializeMipsDisassembler() {
541 // Register the disassembler.
542 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
543 createMipsDisassembler);
544 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
545 createMipselDisassembler);
546 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000547 createMipsDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000548 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000549 createMipselDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000550}
551
Akira Hatanaka71928e62012-04-17 18:03:21 +0000552#include "MipsGenDisassemblerTables.inc"
553
Daniel Sanders5c582b22014-05-22 11:23:21 +0000554static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
Daniel Sandersa19216c2015-02-11 11:28:56 +0000555 const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000556 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
557 return *(RegInfo->getRegClass(RC).begin() + RegNo);
558}
559
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000560template <typename InsnType>
561static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
562 const void *Decoder) {
563 typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
564 // The size of the n field depends on the element size
565 // The register class also depends on this.
566 InsnType tmp = fieldFromInstruction(insn, 17, 5);
567 unsigned NSize = 0;
568 DecodeFN RegDecoder = nullptr;
569 if ((tmp & 0x18) == 0x00) { // INSVE_B
570 NSize = 4;
571 RegDecoder = DecodeMSA128BRegisterClass;
572 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
573 NSize = 3;
574 RegDecoder = DecodeMSA128HRegisterClass;
575 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
576 NSize = 2;
577 RegDecoder = DecodeMSA128WRegisterClass;
578 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
579 NSize = 1;
580 RegDecoder = DecodeMSA128DRegisterClass;
581 } else
582 llvm_unreachable("Invalid encoding");
583
584 assert(NSize != 0 && RegDecoder != nullptr);
585
586 // $wd
587 tmp = fieldFromInstruction(insn, 6, 5);
588 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
589 return MCDisassembler::Fail;
590 // $wd_in
591 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
592 return MCDisassembler::Fail;
593 // $n
594 tmp = fieldFromInstruction(insn, 16, NSize);
Jim Grosbache9119e42015-05-13 18:37:00 +0000595 MI.addOperand(MCOperand::createImm(tmp));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000596 // $ws
597 tmp = fieldFromInstruction(insn, 11, 5);
598 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
599 return MCDisassembler::Fail;
600 // $n2
Jim Grosbache9119e42015-05-13 18:37:00 +0000601 MI.addOperand(MCOperand::createImm(0));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000602
603 return MCDisassembler::Success;
604}
605
Daniel Sanders5c582b22014-05-22 11:23:21 +0000606template <typename InsnType>
Simon Dardiscf060792016-09-16 13:50:43 +0000607static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
608 const void *Decoder) {
609 InsnType Rt = fieldFromInstruction(insn, 16, 5);
610 InsnType Imm = fieldFromInstruction(insn, 0, 16);
611 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
612 Rt)));
613 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
614 Rt)));
615 MI.addOperand(MCOperand::createImm(Imm));
616
617 return MCDisassembler::Success;
618}
619
620template <typename InsnType>
621static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
622 const void *Decoder) {
623 InsnType Rt = fieldFromInstruction(insn, 21, 5);
624 InsnType Imm = fieldFromInstruction(insn, 0, 16);
625 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
626 Rt)));
627 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
628 Rt)));
629 MI.addOperand(MCOperand::createImm(Imm));
630
631 return MCDisassembler::Success;
632}
633
634template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000635static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
636 uint64_t Address,
637 const void *Decoder) {
638 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
639 // (otherwise we would have matched the ADDI instruction from the earlier
640 // ISA's instead).
641 //
642 // We have:
643 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
644 // BOVC if rs >= rt
645 // BEQZALC if rs == 0 && rt != 0
646 // BEQC if rs < rt && rs != 0
647
648 InsnType Rs = fieldFromInstruction(insn, 21, 5);
649 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000650 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000651 bool HasRs = false;
652
653 if (Rs >= Rt) {
654 MI.setOpcode(Mips::BOVC);
655 HasRs = true;
656 } else if (Rs != 0 && Rs < Rt) {
657 MI.setOpcode(Mips::BEQC);
658 HasRs = true;
659 } else
660 MI.setOpcode(Mips::BEQZALC);
661
662 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000663 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000664 Rs)));
665
Jim Grosbache9119e42015-05-13 18:37:00 +0000666 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000667 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000668 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000669
670 return MCDisassembler::Success;
671}
672
673template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000674static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
675 uint64_t Address,
676 const void *Decoder) {
677 InsnType Rt = fieldFromInstruction(insn, 21, 5);
678 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000679 int64_t Imm = 0;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000680
681 if (Rs >= Rt) {
682 MI.setOpcode(Mips::BOVC_MMR6);
683 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
684 Rt)));
685 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
686 Rs)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000687 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000688 } else if (Rs != 0 && Rs < Rt) {
689 MI.setOpcode(Mips::BEQC_MMR6);
690 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
691 Rs)));
692 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
693 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000694 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000695 } else {
696 MI.setOpcode(Mips::BEQZALC_MMR6);
697 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
698 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000699 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000700 }
701
702 MI.addOperand(MCOperand::createImm(Imm));
703
704 return MCDisassembler::Success;
705}
706
707template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000708static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
709 uint64_t Address,
710 const void *Decoder) {
711 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
712 // (otherwise we would have matched the ADDI instruction from the earlier
713 // ISA's instead).
714 //
715 // We have:
716 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
717 // BNVC if rs >= rt
718 // BNEZALC if rs == 0 && rt != 0
719 // BNEC if rs < rt && rs != 0
720
721 InsnType Rs = fieldFromInstruction(insn, 21, 5);
722 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000723 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000724 bool HasRs = false;
725
726 if (Rs >= Rt) {
727 MI.setOpcode(Mips::BNVC);
728 HasRs = true;
729 } else if (Rs != 0 && Rs < Rt) {
730 MI.setOpcode(Mips::BNEC);
731 HasRs = true;
732 } else
733 MI.setOpcode(Mips::BNEZALC);
734
735 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000736 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000737 Rs)));
738
Jim Grosbache9119e42015-05-13 18:37:00 +0000739 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000740 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000741 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000742
743 return MCDisassembler::Success;
744}
745
746template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000747static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
748 uint64_t Address,
749 const void *Decoder) {
750 InsnType Rt = fieldFromInstruction(insn, 21, 5);
751 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000752 int64_t Imm = 0;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000753
754 if (Rs >= Rt) {
755 MI.setOpcode(Mips::BNVC_MMR6);
756 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
757 Rt)));
758 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
759 Rs)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000760 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000761 } else if (Rs != 0 && Rs < Rt) {
762 MI.setOpcode(Mips::BNEC_MMR6);
763 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
764 Rs)));
765 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
766 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000767 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000768 } else {
769 MI.setOpcode(Mips::BNEZALC_MMR6);
770 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
771 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000772 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000773 }
774
775 MI.addOperand(MCOperand::createImm(Imm));
776
777 return MCDisassembler::Success;
778}
779
780template <typename InsnType>
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000781static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
782 uint64_t Address,
783 const void *Decoder) {
784 // We have:
785 // 0b110101 ttttt sssss iiiiiiiiiiiiiiii
786 // Invalid if rt == 0
787 // BGTZC_MMR6 if rs == 0 && rt != 0
788 // BLTZC_MMR6 if rs == rt && rt != 0
789 // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0
790
791 InsnType Rt = fieldFromInstruction(insn, 21, 5);
792 InsnType Rs = fieldFromInstruction(insn, 16, 5);
793 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
794 bool HasRs = false;
795
796 if (Rt == 0)
797 return MCDisassembler::Fail;
798 else if (Rs == 0)
799 MI.setOpcode(Mips::BGTZC_MMR6);
800 else if (Rs == Rt)
801 MI.setOpcode(Mips::BLTZC_MMR6);
802 else {
803 MI.setOpcode(Mips::BLTC_MMR6);
804 HasRs = true;
805 }
806
807 if (HasRs)
808 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
809 Rs)));
810
811 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
812 Rt)));
813
814 MI.addOperand(MCOperand::createImm(Imm));
815
816 return MCDisassembler::Success;
817}
818
819template <typename InsnType>
820static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
821 uint64_t Address,
822 const void *Decoder) {
823 // We have:
824 // 0b111101 ttttt sssss iiiiiiiiiiiiiiii
825 // Invalid if rt == 0
826 // BLEZC_MMR6 if rs == 0 && rt != 0
827 // BGEZC_MMR6 if rs == rt && rt != 0
828 // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0
829
830 InsnType Rt = fieldFromInstruction(insn, 21, 5);
831 InsnType Rs = fieldFromInstruction(insn, 16, 5);
832 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
833 bool HasRs = false;
834
835 if (Rt == 0)
836 return MCDisassembler::Fail;
837 else if (Rs == 0)
838 MI.setOpcode(Mips::BLEZC_MMR6);
839 else if (Rs == Rt)
840 MI.setOpcode(Mips::BGEZC_MMR6);
841 else {
842 HasRs = true;
843 MI.setOpcode(Mips::BGEC_MMR6);
844 }
845
846 if (HasRs)
847 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
848 Rs)));
849
850 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
851 Rt)));
852
853 MI.addOperand(MCOperand::createImm(Imm));
854
855 return MCDisassembler::Success;
856}
857
858template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000859static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
860 uint64_t Address,
861 const void *Decoder) {
862 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
863 // (otherwise we would have matched the BLEZL instruction from the earlier
864 // ISA's instead).
865 //
866 // We have:
867 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
868 // Invalid if rs == 0
869 // BLEZC if rs == 0 && rt != 0
870 // BGEZC if rs == rt && rt != 0
871 // BGEC if rs != rt && rs != 0 && rt != 0
872
873 InsnType Rs = fieldFromInstruction(insn, 21, 5);
874 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000875 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000876 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000877
878 if (Rt == 0)
879 return MCDisassembler::Fail;
880 else if (Rs == 0)
881 MI.setOpcode(Mips::BLEZC);
882 else if (Rs == Rt)
883 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000884 else {
885 HasRs = true;
886 MI.setOpcode(Mips::BGEC);
887 }
888
889 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000890 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000891 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000892
Jim Grosbache9119e42015-05-13 18:37:00 +0000893 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000894 Rt)));
895
Jim Grosbache9119e42015-05-13 18:37:00 +0000896 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000897
898 return MCDisassembler::Success;
899}
900
901template <typename InsnType>
902static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
903 uint64_t Address,
904 const void *Decoder) {
905 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
906 // (otherwise we would have matched the BGTZL instruction from the earlier
907 // ISA's instead).
908 //
909 // We have:
910 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
911 // Invalid if rs == 0
912 // BGTZC if rs == 0 && rt != 0
913 // BLTZC if rs == rt && rt != 0
914 // BLTC if rs != rt && rs != 0 && rt != 0
915
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000916 bool HasRs = false;
917
Daniel Sanders5c582b22014-05-22 11:23:21 +0000918 InsnType Rs = fieldFromInstruction(insn, 21, 5);
919 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000920 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000921
922 if (Rt == 0)
923 return MCDisassembler::Fail;
924 else if (Rs == 0)
925 MI.setOpcode(Mips::BGTZC);
926 else if (Rs == Rt)
927 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000928 else {
929 MI.setOpcode(Mips::BLTC);
930 HasRs = true;
931 }
932
933 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000934 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000935 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000936
Jim Grosbache9119e42015-05-13 18:37:00 +0000937 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000938 Rt)));
939
Jim Grosbache9119e42015-05-13 18:37:00 +0000940 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000941
942 return MCDisassembler::Success;
943}
944
945template <typename InsnType>
946static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
947 uint64_t Address,
948 const void *Decoder) {
949 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
950 // (otherwise we would have matched the BGTZ instruction from the earlier
951 // ISA's instead).
952 //
953 // We have:
954 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
955 // BGTZ if rt == 0
956 // BGTZALC if rs == 0 && rt != 0
957 // BLTZALC if rs != 0 && rs == rt
958 // BLTUC if rs != 0 && rs != rt
959
960 InsnType Rs = fieldFromInstruction(insn, 21, 5);
961 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000962 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000963 bool HasRs = false;
964 bool HasRt = false;
965
966 if (Rt == 0) {
967 MI.setOpcode(Mips::BGTZ);
968 HasRs = true;
969 } else if (Rs == 0) {
970 MI.setOpcode(Mips::BGTZALC);
971 HasRt = true;
972 } else if (Rs == Rt) {
973 MI.setOpcode(Mips::BLTZALC);
974 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000975 } else {
976 MI.setOpcode(Mips::BLTUC);
977 HasRs = true;
978 HasRt = true;
979 }
Daniel Sanders5c582b22014-05-22 11:23:21 +0000980
981 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000982 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000983 Rs)));
984
985 if (HasRt)
Jim Grosbache9119e42015-05-13 18:37:00 +0000986 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000987 Rt)));
988
Jim Grosbache9119e42015-05-13 18:37:00 +0000989 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000990
991 return MCDisassembler::Success;
992}
993
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000994template <typename InsnType>
995static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
996 uint64_t Address,
997 const void *Decoder) {
998 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
999 // (otherwise we would have matched the BLEZL instruction from the earlier
1000 // ISA's instead).
1001 //
1002 // We have:
1003 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
1004 // Invalid if rs == 0
1005 // BLEZALC if rs == 0 && rt != 0
1006 // BGEZALC if rs == rt && rt != 0
1007 // BGEUC if rs != rt && rs != 0 && rt != 0
1008
1009 InsnType Rs = fieldFromInstruction(insn, 21, 5);
1010 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +00001011 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001012 bool HasRs = false;
1013
1014 if (Rt == 0)
1015 return MCDisassembler::Fail;
1016 else if (Rs == 0)
1017 MI.setOpcode(Mips::BLEZALC);
1018 else if (Rs == Rt)
1019 MI.setOpcode(Mips::BGEZALC);
1020 else {
1021 HasRs = true;
1022 MI.setOpcode(Mips::BGEUC);
1023 }
1024
1025 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +00001026 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001027 Rs)));
Jim Grosbache9119e42015-05-13 18:37:00 +00001028 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001029 Rt)));
1030
Jim Grosbache9119e42015-05-13 18:37:00 +00001031 MI.addOperand(MCOperand::createImm(Imm));
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001032
1033 return MCDisassembler::Success;
1034}
1035
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001036/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1037/// according to the given endianess.
1038static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1039 uint64_t &Size, uint32_t &Insn,
1040 bool IsBigEndian) {
1041 // We want to read exactly 2 Bytes of data.
1042 if (Bytes.size() < 2) {
1043 Size = 0;
1044 return MCDisassembler::Fail;
1045 }
1046
1047 if (IsBigEndian) {
1048 Insn = (Bytes[0] << 8) | Bytes[1];
1049 } else {
1050 Insn = (Bytes[1] << 8) | Bytes[0];
1051 }
1052
1053 return MCDisassembler::Success;
1054}
1055
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001056/// Read four bytes from the ArrayRef and return 32 bit word sorted
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001057/// according to the given endianess
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001058static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
1059 uint64_t &Size, uint32_t &Insn,
1060 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001061 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001062 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001063 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001064 return MCDisassembler::Fail;
1065 }
1066
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001067 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1068 // always precede the low 16 bits in the instruction stream (that is, they
1069 // are placed at lower addresses in the instruction stream).
1070 //
1071 // microMIPS byte ordering:
1072 // Big-endian: 0 | 1 | 2 | 3
1073 // Little-endian: 1 | 0 | 3 | 2
1074
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001075 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001076 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001077 Insn =
1078 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
1079 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +00001080 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001081 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +00001082 (Bytes[1] << 24);
1083 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001084 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +00001085 (Bytes[3] << 24);
1086 }
Akira Hatanaka71928e62012-04-17 18:03:21 +00001087 }
1088
1089 return MCDisassembler::Success;
1090}
1091
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001092DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001093 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001094 uint64_t Address,
1095 raw_ostream &VStream,
1096 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001097 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001098 DecodeStatus Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001099
Vladimir Medicdde3d582013-09-06 12:30:36 +00001100 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001101 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
Reid Klecknerebee6122015-11-19 21:51:55 +00001102 if (Result == MCDisassembler::Fail)
1103 return MCDisassembler::Fail;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001104
Zoran Jovanovicada70912015-09-07 11:56:37 +00001105 if (hasMips32r6()) {
1106 DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1107 // Calling the auto-generated decoder function for microMIPS32R6
1108 // (and microMIPS64R6) 16-bit instructions.
1109 Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1110 Address, this, STI);
1111 if (Result != MCDisassembler::Fail) {
1112 Size = 2;
1113 return Result;
1114 }
1115 }
1116
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001117 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
Zoran Jovanovicada70912015-09-07 11:56:37 +00001118 // Calling the auto-generated decoder function for microMIPS 16-bit
1119 // instructions.
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001120 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1121 this, STI);
1122 if (Result != MCDisassembler::Fail) {
1123 Size = 2;
1124 return Result;
1125 }
1126
1127 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
1128 if (Result == MCDisassembler::Fail)
1129 return MCDisassembler::Fail;
1130
Jozef Kolek676d6012015-04-20 14:40:38 +00001131 if (hasMips32r6()) {
1132 DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1133 // Calling the auto-generated decoder function.
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001134 Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
Jozef Kolek676d6012015-04-20 14:40:38 +00001135 this, STI);
Zoran Jovanovicada70912015-09-07 11:56:37 +00001136 if (Result != MCDisassembler::Fail) {
1137 Size = 4;
1138 return Result;
1139 }
Jozef Kolek676d6012015-04-20 14:40:38 +00001140 }
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001141
Zoran Jovanovicada70912015-09-07 11:56:37 +00001142 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1143 // Calling the auto-generated decoder function.
1144 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1145 this, STI);
Vladimir Medicdde3d582013-09-06 12:30:36 +00001146 if (Result != MCDisassembler::Fail) {
1147 Size = 4;
1148 return Result;
1149 }
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001150
Zlatko Buljan6221be82016-03-31 08:51:24 +00001151 if (hasMips32r6() && isFP64()) {
1152 DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
1153 Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001154 Address, this, STI);
1155 if (Result != MCDisassembler::Fail) {
1156 Size = 4;
1157 return Result;
1158 }
1159 }
1160
Reid Klecknerebee6122015-11-19 21:51:55 +00001161 // This is an invalid instruction. Let the disassembler move forward by the
1162 // minimum instruction size.
1163 Size = 2;
Vladimir Medicdde3d582013-09-06 12:30:36 +00001164 return MCDisassembler::Fail;
1165 }
1166
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001167 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Reid Klecknerebee6122015-11-19 21:51:55 +00001168 if (Result == MCDisassembler::Fail) {
1169 Size = 4;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001170 return MCDisassembler::Fail;
Reid Klecknerebee6122015-11-19 21:51:55 +00001171 }
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001172
Daniel Sandersc171f652014-06-13 13:15:59 +00001173 if (hasCOP3()) {
1174 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1175 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001176 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Daniel Sandersc171f652014-06-13 13:15:59 +00001177 if (Result != MCDisassembler::Fail) {
1178 Size = 4;
1179 return Result;
1180 }
1181 }
1182
1183 if (hasMips32r6() && isGP64()) {
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001184 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
1185 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
1186 Address, this, STI);
Daniel Sanders0fa60412014-06-12 13:39:06 +00001187 if (Result != MCDisassembler::Fail) {
1188 Size = 4;
1189 return Result;
1190 }
1191 }
1192
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001193 if (hasMips32r6() && isPTR64()) {
1194 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1195 Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
1196 Address, this, STI);
1197 if (Result != MCDisassembler::Fail) {
1198 Size = 4;
1199 return Result;
1200 }
1201 }
1202
Daniel Sandersc171f652014-06-13 13:15:59 +00001203 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001204 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001205 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +00001206 Address, this, STI);
1207 if (Result != MCDisassembler::Fail) {
1208 Size = 4;
1209 return Result;
1210 }
1211 }
1212
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001213 if (hasMips2() && isPTR64()) {
1214 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1215 Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
1216 Address, this, STI);
1217 if (Result != MCDisassembler::Fail) {
1218 Size = 4;
1219 return Result;
1220 }
1221 }
1222
Kai Nacke3adf9b82015-05-28 16:23:16 +00001223 if (hasCnMips()) {
1224 DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
1225 Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
1226 Address, this, STI);
1227 if (Result != MCDisassembler::Fail) {
1228 Size = 4;
1229 return Result;
1230 }
1231 }
1232
Daniel Sandersa19216c2015-02-11 11:28:56 +00001233 if (isGP64()) {
1234 DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1235 Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1236 Address, this, STI);
1237 if (Result != MCDisassembler::Fail) {
1238 Size = 4;
1239 return Result;
1240 }
1241 }
1242
Daniel Sanders0fa60412014-06-12 13:39:06 +00001243 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +00001244 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001245 Result =
1246 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001247 if (Result != MCDisassembler::Fail) {
1248 Size = 4;
1249 return Result;
1250 }
1251
Reid Klecknerebee6122015-11-19 21:51:55 +00001252 Size = 4;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001253 return MCDisassembler::Fail;
1254}
1255
Reed Kotlerec8a5492013-02-14 03:05:25 +00001256static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1257 unsigned RegNo,
1258 uint64_t Address,
1259 const void *Decoder) {
1260
1261 return MCDisassembler::Fail;
1262
1263}
1264
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001265static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1266 unsigned RegNo,
1267 uint64_t Address,
1268 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001269
1270 if (RegNo > 31)
1271 return MCDisassembler::Fail;
1272
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001273 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001274 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001275 return MCDisassembler::Success;
1276}
1277
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001278static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1279 unsigned RegNo,
1280 uint64_t Address,
1281 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001282 if (RegNo > 7)
1283 return MCDisassembler::Fail;
1284 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001285 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001286 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001287}
1288
Jozef Kolek1904fa22014-11-24 14:25:53 +00001289static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1290 unsigned RegNo,
1291 uint64_t Address,
1292 const void *Decoder) {
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001293 if (RegNo > 7)
1294 return MCDisassembler::Fail;
1295 unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001296 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001297 return MCDisassembler::Success;
Jozef Kolek1904fa22014-11-24 14:25:53 +00001298}
1299
Zoran Jovanovic41688672015-02-10 16:36:20 +00001300static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1301 unsigned RegNo,
1302 uint64_t Address,
1303 const void *Decoder) {
1304 if (RegNo > 7)
1305 return MCDisassembler::Fail;
1306 unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001307 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic41688672015-02-10 16:36:20 +00001308 return MCDisassembler::Success;
1309}
1310
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001311static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1312 unsigned RegNo,
1313 uint64_t Address,
1314 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001315 if (RegNo > 31)
1316 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001317 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001318 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001319 return MCDisassembler::Success;
1320}
1321
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001322static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1323 unsigned RegNo,
1324 uint64_t Address,
1325 const void *Decoder) {
Daniel Sandersa19216c2015-02-11 11:28:56 +00001326 if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001327 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1328
1329 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1330}
1331
Akira Hatanaka654655f2013-08-14 00:53:38 +00001332static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1333 unsigned RegNo,
1334 uint64_t Address,
1335 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001336 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001337}
1338
Akira Hatanaka71928e62012-04-17 18:03:21 +00001339static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1340 unsigned RegNo,
1341 uint64_t Address,
1342 const void *Decoder) {
1343 if (RegNo > 31)
1344 return MCDisassembler::Fail;
1345
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001346 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001347 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001348 return MCDisassembler::Success;
1349}
1350
1351static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1352 unsigned RegNo,
1353 uint64_t Address,
1354 const void *Decoder) {
1355 if (RegNo > 31)
1356 return MCDisassembler::Fail;
1357
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001358 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001359 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001360 return MCDisassembler::Success;
1361}
1362
1363static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1364 unsigned RegNo,
1365 uint64_t Address,
1366 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +00001367 if (RegNo > 31)
1368 return MCDisassembler::Fail;
1369 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001370 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001371 return MCDisassembler::Success;
1372}
1373
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001374static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1375 unsigned RegNo,
1376 uint64_t Address,
1377 const void *Decoder) {
1378 if (RegNo > 7)
1379 return MCDisassembler::Fail;
1380 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001381 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001382 return MCDisassembler::Success;
1383}
1384
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001385static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1386 uint64_t Address,
1387 const void *Decoder) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001388 if (RegNo > 31)
1389 return MCDisassembler::Fail;
1390
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001391 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001392 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders0fa60412014-06-12 13:39:06 +00001393 return MCDisassembler::Success;
1394}
1395
Akira Hatanaka71928e62012-04-17 18:03:21 +00001396static DecodeStatus DecodeMem(MCInst &Inst,
1397 unsigned Insn,
1398 uint64_t Address,
1399 const void *Decoder) {
1400 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001401 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1402 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001403
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001404 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1405 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001406
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001407 if (Inst.getOpcode() == Mips::SC ||
1408 Inst.getOpcode() == Mips::SCD)
Jim Grosbache9119e42015-05-13 18:37:00 +00001409 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001410
1411 Inst.addOperand(MCOperand::createReg(Reg));
1412 Inst.addOperand(MCOperand::createReg(Base));
1413 Inst.addOperand(MCOperand::createImm(Offset));
1414
1415 return MCDisassembler::Success;
1416}
1417
1418static DecodeStatus DecodeMemEVA(MCInst &Inst,
1419 unsigned Insn,
1420 uint64_t Address,
1421 const void *Decoder) {
1422 int Offset = SignExtend32<9>(Insn >> 7);
1423 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1424 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1425
1426 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1427 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1428
1429 if (Inst.getOpcode() == Mips::SCE)
1430 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001431
Jim Grosbache9119e42015-05-13 18:37:00 +00001432 Inst.addOperand(MCOperand::createReg(Reg));
1433 Inst.addOperand(MCOperand::createReg(Base));
1434 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001435
1436 return MCDisassembler::Success;
1437}
1438
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +00001439static DecodeStatus DecodeLoadByte9(MCInst &Inst,
1440 unsigned Insn,
1441 uint64_t Address,
1442 const void *Decoder) {
1443 int Offset = SignExtend32<9>(Insn & 0x1ff);
1444 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1445 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1446
1447 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1448 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1449
1450 Inst.addOperand(MCOperand::createReg(Reg));
1451 Inst.addOperand(MCOperand::createReg(Base));
1452 Inst.addOperand(MCOperand::createImm(Offset));
1453
1454 return MCDisassembler::Success;
1455}
1456
1457static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1458 unsigned Insn,
1459 uint64_t Address,
1460 const void *Decoder) {
1461 int Offset = SignExtend32<16>(Insn & 0xffff);
1462 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1463 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1464
1465 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1466 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1467
1468 Inst.addOperand(MCOperand::createReg(Reg));
1469 Inst.addOperand(MCOperand::createReg(Base));
1470 Inst.addOperand(MCOperand::createImm(Offset));
1471
1472 return MCDisassembler::Success;
1473}
1474
Daniel Sanders92db6b72014-10-01 08:26:55 +00001475static DecodeStatus DecodeCacheOp(MCInst &Inst,
1476 unsigned Insn,
1477 uint64_t Address,
1478 const void *Decoder) {
1479 int Offset = SignExtend32<16>(Insn & 0xffff);
1480 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1481 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1482
1483 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1484
Jim Grosbache9119e42015-05-13 18:37:00 +00001485 Inst.addOperand(MCOperand::createReg(Base));
1486 Inst.addOperand(MCOperand::createImm(Offset));
1487 Inst.addOperand(MCOperand::createImm(Hint));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001488
1489 return MCDisassembler::Success;
1490}
1491
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001492static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1493 unsigned Insn,
1494 uint64_t Address,
1495 const void *Decoder) {
1496 int Offset = SignExtend32<12>(Insn & 0xfff);
1497 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1498 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1499
1500 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1501
Jim Grosbache9119e42015-05-13 18:37:00 +00001502 Inst.addOperand(MCOperand::createReg(Base));
1503 Inst.addOperand(MCOperand::createImm(Offset));
1504 Inst.addOperand(MCOperand::createImm(Hint));
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001505
1506 return MCDisassembler::Success;
1507}
1508
Zoran Jovanovicd9790792015-09-09 09:10:46 +00001509static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1510 unsigned Insn,
1511 uint64_t Address,
1512 const void *Decoder) {
1513 int Offset = SignExtend32<9>(Insn & 0x1ff);
1514 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1515 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1516
1517 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1518
1519 Inst.addOperand(MCOperand::createReg(Base));
1520 Inst.addOperand(MCOperand::createImm(Offset));
1521 Inst.addOperand(MCOperand::createImm(Hint));
1522
1523 return MCDisassembler::Success;
1524}
1525
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001526static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1527 unsigned Insn,
1528 uint64_t Address,
1529 const void *Decoder) {
1530 int Offset = SignExtend32<9>(Insn >> 7);
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001531 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1532 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1533
1534 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1535
Jim Grosbache9119e42015-05-13 18:37:00 +00001536 Inst.addOperand(MCOperand::createReg(Base));
1537 Inst.addOperand(MCOperand::createImm(Offset));
1538 Inst.addOperand(MCOperand::createImm(Hint));
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001539
1540 return MCDisassembler::Success;
1541}
1542
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +00001543static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
1544 unsigned Insn,
1545 uint64_t Address,
1546 const void *Decoder) {
1547 int Offset = SignExtend32<9>(Insn & 0x1ff);
1548 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1549 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1550
1551 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1552 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1553
1554 Inst.addOperand(MCOperand::createReg(Reg));
1555 Inst.addOperand(MCOperand::createReg(Base));
1556 Inst.addOperand(MCOperand::createImm(Offset));
1557
1558 return MCDisassembler::Success;
1559}
1560
Daniel Sandersb4484d62014-11-27 17:28:10 +00001561static DecodeStatus DecodeSyncI(MCInst &Inst,
1562 unsigned Insn,
1563 uint64_t Address,
1564 const void *Decoder) {
1565 int Offset = SignExtend32<16>(Insn & 0xffff);
1566 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1567
1568 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1569
Jim Grosbache9119e42015-05-13 18:37:00 +00001570 Inst.addOperand(MCOperand::createReg(Base));
1571 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sandersb4484d62014-11-27 17:28:10 +00001572
1573 return MCDisassembler::Success;
1574}
1575
Hrvoje Varga18148672015-10-28 11:04:29 +00001576static DecodeStatus DecodeSynciR6(MCInst &Inst,
1577 unsigned Insn,
1578 uint64_t Address,
1579 const void *Decoder) {
1580 int Immediate = SignExtend32<16>(Insn & 0xffff);
1581 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1582
1583 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1584
1585 Inst.addOperand(MCOperand::createReg(Base));
1586 Inst.addOperand(MCOperand::createImm(Immediate));
1587
1588 return MCDisassembler::Success;
1589}
1590
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001591static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1592 uint64_t Address, const void *Decoder) {
1593 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1594 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1595 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1596
1597 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1598 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1599
Jim Grosbache9119e42015-05-13 18:37:00 +00001600 Inst.addOperand(MCOperand::createReg(Reg));
1601 Inst.addOperand(MCOperand::createReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001602
1603 // The immediate field of an LD/ST instruction is scaled which means it must
1604 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1605 // data format.
1606 // .b - 1 byte
1607 // .h - 2 bytes
1608 // .w - 4 bytes
1609 // .d - 8 bytes
1610 switch(Inst.getOpcode())
1611 {
1612 default:
1613 assert (0 && "Unexpected instruction");
1614 return MCDisassembler::Fail;
1615 break;
1616 case Mips::LD_B:
1617 case Mips::ST_B:
Jim Grosbache9119e42015-05-13 18:37:00 +00001618 Inst.addOperand(MCOperand::createImm(Offset));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001619 break;
1620 case Mips::LD_H:
1621 case Mips::ST_H:
Jim Grosbache9119e42015-05-13 18:37:00 +00001622 Inst.addOperand(MCOperand::createImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001623 break;
1624 case Mips::LD_W:
1625 case Mips::ST_W:
Jim Grosbache9119e42015-05-13 18:37:00 +00001626 Inst.addOperand(MCOperand::createImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001627 break;
1628 case Mips::LD_D:
1629 case Mips::ST_D:
Jim Grosbache9119e42015-05-13 18:37:00 +00001630 Inst.addOperand(MCOperand::createImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001631 break;
1632 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001633
1634 return MCDisassembler::Success;
1635}
1636
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001637static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1638 unsigned Insn,
1639 uint64_t Address,
1640 const void *Decoder) {
1641 unsigned Offset = Insn & 0xf;
1642 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1643 unsigned Base = fieldFromInstruction(Insn, 4, 3);
1644
1645 switch (Inst.getOpcode()) {
1646 case Mips::LBU16_MM:
1647 case Mips::LHU16_MM:
1648 case Mips::LW16_MM:
1649 if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1650 == MCDisassembler::Fail)
1651 return MCDisassembler::Fail;
1652 break;
1653 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001654 case Mips::SB16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001655 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001656 case Mips::SH16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001657 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001658 case Mips::SW16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001659 if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1660 == MCDisassembler::Fail)
1661 return MCDisassembler::Fail;
1662 break;
1663 }
1664
1665 if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1666 == MCDisassembler::Fail)
1667 return MCDisassembler::Fail;
1668
1669 switch (Inst.getOpcode()) {
1670 case Mips::LBU16_MM:
1671 if (Offset == 0xf)
Jim Grosbache9119e42015-05-13 18:37:00 +00001672 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001673 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001674 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001675 break;
1676 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001677 case Mips::SB16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001678 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001679 break;
1680 case Mips::LHU16_MM:
1681 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001682 case Mips::SH16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001683 Inst.addOperand(MCOperand::createImm(Offset << 1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001684 break;
1685 case Mips::LW16_MM:
1686 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001687 case Mips::SW16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001688 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001689 break;
1690 }
1691
1692 return MCDisassembler::Success;
1693}
1694
Jozef Kolek12c69822014-12-23 16:16:33 +00001695static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1696 unsigned Insn,
1697 uint64_t Address,
1698 const void *Decoder) {
1699 unsigned Offset = Insn & 0x1F;
1700 unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1701
1702 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1703
Jim Grosbache9119e42015-05-13 18:37:00 +00001704 Inst.addOperand(MCOperand::createReg(Reg));
1705 Inst.addOperand(MCOperand::createReg(Mips::SP));
1706 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek12c69822014-12-23 16:16:33 +00001707
1708 return MCDisassembler::Success;
1709}
1710
Jozef Koleke10a02e2015-01-28 17:27:26 +00001711static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1712 unsigned Insn,
1713 uint64_t Address,
1714 const void *Decoder) {
1715 unsigned Offset = Insn & 0x7F;
1716 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1717
1718 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1719
Jim Grosbache9119e42015-05-13 18:37:00 +00001720 Inst.addOperand(MCOperand::createReg(Reg));
1721 Inst.addOperand(MCOperand::createReg(Mips::GP));
1722 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Koleke10a02e2015-01-28 17:27:26 +00001723
1724 return MCDisassembler::Success;
1725}
1726
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001727static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1728 unsigned Insn,
1729 uint64_t Address,
1730 const void *Decoder) {
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001731 int Offset;
1732 switch (Inst.getOpcode()) {
1733 case Mips::LWM16_MMR6:
1734 case Mips::SWM16_MMR6:
1735 Offset = fieldFromInstruction(Insn, 4, 4);
1736 break;
1737 default:
1738 Offset = SignExtend32<4>(Insn & 0xf);
1739 break;
1740 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001741
1742 if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1743 == MCDisassembler::Fail)
1744 return MCDisassembler::Fail;
1745
Jim Grosbache9119e42015-05-13 18:37:00 +00001746 Inst.addOperand(MCOperand::createReg(Mips::SP));
1747 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001748
1749 return MCDisassembler::Success;
1750}
1751
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001752static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1753 unsigned Insn,
1754 uint64_t Address,
1755 const void *Decoder) {
1756 int Offset = SignExtend32<9>(Insn & 0x1ff);
1757 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1758 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1759
1760 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1761 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1762
Hrvoje Varga3ef4dd72015-10-15 08:11:50 +00001763 if (Inst.getOpcode() == Mips::SCE_MM)
1764 Inst.addOperand(MCOperand::createReg(Reg));
1765
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001766 Inst.addOperand(MCOperand::createReg(Reg));
1767 Inst.addOperand(MCOperand::createReg(Base));
1768 Inst.addOperand(MCOperand::createImm(Offset));
1769
1770 return MCDisassembler::Success;
1771}
1772
Vladimir Medicdde3d582013-09-06 12:30:36 +00001773static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1774 unsigned Insn,
1775 uint64_t Address,
1776 const void *Decoder) {
1777 int Offset = SignExtend32<12>(Insn & 0x0fff);
1778 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1779 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1780
1781 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1782 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1783
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001784 switch (Inst.getOpcode()) {
1785 case Mips::SWM32_MM:
1786 case Mips::LWM32_MM:
1787 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1788 == MCDisassembler::Fail)
1789 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001790 Inst.addOperand(MCOperand::createReg(Base));
1791 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001792 break;
1793 case Mips::SC_MM:
Jim Grosbache9119e42015-05-13 18:37:00 +00001794 Inst.addOperand(MCOperand::createReg(Reg));
Justin Bognerb03fd122016-08-17 05:10:15 +00001795 LLVM_FALLTHROUGH;
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001796 default:
Jim Grosbache9119e42015-05-13 18:37:00 +00001797 Inst.addOperand(MCOperand::createReg(Reg));
Zlatko Buljanba553a62016-05-09 08:07:28 +00001798 if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1799 Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
Jim Grosbache9119e42015-05-13 18:37:00 +00001800 Inst.addOperand(MCOperand::createReg(Reg+1));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001801
Jim Grosbache9119e42015-05-13 18:37:00 +00001802 Inst.addOperand(MCOperand::createReg(Base));
1803 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001804 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001805
1806 return MCDisassembler::Success;
1807}
1808
1809static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1810 unsigned Insn,
1811 uint64_t Address,
1812 const void *Decoder) {
1813 int Offset = SignExtend32<16>(Insn & 0xffff);
1814 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1815 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1816
1817 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1818 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1819
Jim Grosbache9119e42015-05-13 18:37:00 +00001820 Inst.addOperand(MCOperand::createReg(Reg));
1821 Inst.addOperand(MCOperand::createReg(Base));
1822 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medicdde3d582013-09-06 12:30:36 +00001823
1824 return MCDisassembler::Success;
1825}
1826
Akira Hatanaka71928e62012-04-17 18:03:21 +00001827static DecodeStatus DecodeFMem(MCInst &Inst,
1828 unsigned Insn,
1829 uint64_t Address,
1830 const void *Decoder) {
1831 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001832 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1833 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001834
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001835 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001836 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001837
Jim Grosbache9119e42015-05-13 18:37:00 +00001838 Inst.addOperand(MCOperand::createReg(Reg));
1839 Inst.addOperand(MCOperand::createReg(Base));
1840 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001841
1842 return MCDisassembler::Success;
1843}
1844
Zlatko Buljancba9f802016-07-11 07:41:56 +00001845static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1846 uint64_t Address, const void *Decoder) {
1847 // This function is the same as DecodeFMem but with the Reg and Base fields
1848 // swapped according to microMIPS spec.
1849 int Offset = SignExtend32<16>(Insn & 0xffff);
1850 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1851 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1852
1853 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1854 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1855
1856 Inst.addOperand(MCOperand::createReg(Reg));
1857 Inst.addOperand(MCOperand::createReg(Base));
1858 Inst.addOperand(MCOperand::createImm(Offset));
1859
1860 return MCDisassembler::Success;
1861}
1862
Daniel Sanders92db6b72014-10-01 08:26:55 +00001863static DecodeStatus DecodeFMem2(MCInst &Inst,
1864 unsigned Insn,
1865 uint64_t Address,
1866 const void *Decoder) {
1867 int Offset = SignExtend32<16>(Insn & 0xffff);
1868 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1869 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1870
1871 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1872 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1873
Jim Grosbache9119e42015-05-13 18:37:00 +00001874 Inst.addOperand(MCOperand::createReg(Reg));
1875 Inst.addOperand(MCOperand::createReg(Base));
1876 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001877
1878 return MCDisassembler::Success;
1879}
1880
1881static DecodeStatus DecodeFMem3(MCInst &Inst,
1882 unsigned Insn,
1883 uint64_t Address,
1884 const void *Decoder) {
1885 int Offset = SignExtend32<16>(Insn & 0xffff);
1886 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1887 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1888
1889 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1890 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1891
Jim Grosbache9119e42015-05-13 18:37:00 +00001892 Inst.addOperand(MCOperand::createReg(Reg));
1893 Inst.addOperand(MCOperand::createReg(Base));
1894 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001895
1896 return MCDisassembler::Success;
1897}
1898
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001899static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1900 unsigned Insn,
1901 uint64_t Address,
1902 const void *Decoder) {
1903 int Offset = SignExtend32<11>(Insn & 0x07ff);
1904 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1905 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1906
1907 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1908 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1909
Jim Grosbache9119e42015-05-13 18:37:00 +00001910 Inst.addOperand(MCOperand::createReg(Reg));
1911 Inst.addOperand(MCOperand::createReg(Base));
1912 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001913
1914 return MCDisassembler::Success;
1915}
Zlatko Buljancba9f802016-07-11 07:41:56 +00001916
1917static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1918 uint64_t Address, const void *Decoder) {
1919 int Offset = SignExtend32<11>(Insn & 0x07ff);
1920 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1921 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1922
1923 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1924 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1925
1926 Inst.addOperand(MCOperand::createReg(Reg));
1927 Inst.addOperand(MCOperand::createReg(Base));
1928 Inst.addOperand(MCOperand::createImm(Offset));
1929
1930 return MCDisassembler::Success;
1931}
1932
Daniel Sanders6a803f62014-06-16 13:13:03 +00001933static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1934 unsigned Insn,
1935 uint64_t Address,
1936 const void *Decoder) {
1937 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1938 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1939 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1940
1941 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1942 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1943
1944 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
Jim Grosbache9119e42015-05-13 18:37:00 +00001945 Inst.addOperand(MCOperand::createReg(Rt));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001946 }
1947
Jim Grosbache9119e42015-05-13 18:37:00 +00001948 Inst.addOperand(MCOperand::createReg(Rt));
1949 Inst.addOperand(MCOperand::createReg(Base));
1950 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001951
1952 return MCDisassembler::Success;
1953}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001954
1955static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1956 unsigned RegNo,
1957 uint64_t Address,
1958 const void *Decoder) {
1959 // Currently only hardware register 29 is supported.
1960 if (RegNo != 29)
1961 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001962 Inst.addOperand(MCOperand::createReg(Mips::HWR29));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001963 return MCDisassembler::Success;
1964}
1965
Akira Hatanaka71928e62012-04-17 18:03:21 +00001966static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1967 unsigned RegNo,
1968 uint64_t Address,
1969 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001970 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001971 return MCDisassembler::Fail;
1972
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001973 ;
1974 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
Jim Grosbache9119e42015-05-13 18:37:00 +00001975 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001976 return MCDisassembler::Success;
1977}
1978
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001979static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1980 unsigned RegNo,
1981 uint64_t Address,
1982 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001983 if (RegNo >= 4)
1984 return MCDisassembler::Fail;
1985
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001986 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001987 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001988 return MCDisassembler::Success;
1989}
1990
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001991static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1992 unsigned RegNo,
1993 uint64_t Address,
1994 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001995 if (RegNo >= 4)
1996 return MCDisassembler::Fail;
1997
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001998 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001999 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002000 return MCDisassembler::Success;
2001}
2002
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002003static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
2004 unsigned RegNo,
2005 uint64_t Address,
2006 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002007 if (RegNo >= 4)
2008 return MCDisassembler::Fail;
2009
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002010 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002011 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002012 return MCDisassembler::Success;
2013}
2014
Jack Carter3eb663b2013-09-26 00:09:46 +00002015static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
2016 unsigned RegNo,
2017 uint64_t Address,
2018 const void *Decoder) {
2019 if (RegNo > 31)
2020 return MCDisassembler::Fail;
2021
2022 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002023 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter3eb663b2013-09-26 00:09:46 +00002024 return MCDisassembler::Success;
2025}
2026
Jack Carter5dc8ac92013-09-25 23:50:44 +00002027static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
2028 unsigned RegNo,
2029 uint64_t Address,
2030 const void *Decoder) {
2031 if (RegNo > 31)
2032 return MCDisassembler::Fail;
2033
2034 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002035 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002036 return MCDisassembler::Success;
2037}
2038
2039static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
2040 unsigned RegNo,
2041 uint64_t Address,
2042 const void *Decoder) {
2043 if (RegNo > 31)
2044 return MCDisassembler::Fail;
2045
2046 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002047 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002048 return MCDisassembler::Success;
2049}
2050
2051static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
2052 unsigned RegNo,
2053 uint64_t Address,
2054 const void *Decoder) {
2055 if (RegNo > 31)
2056 return MCDisassembler::Fail;
2057
2058 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002059 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002060 return MCDisassembler::Success;
2061}
2062
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002063static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
2064 unsigned RegNo,
2065 uint64_t Address,
2066 const void *Decoder) {
2067 if (RegNo > 7)
2068 return MCDisassembler::Fail;
2069
2070 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002071 Inst.addOperand(MCOperand::createReg(Reg));
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002072 return MCDisassembler::Success;
2073}
2074
Daniel Sandersa3134fa2015-06-27 15:39:19 +00002075static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
2076 unsigned RegNo,
2077 uint64_t Address,
2078 const void *Decoder) {
2079 if (RegNo > 31)
2080 return MCDisassembler::Fail;
2081
2082 unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
2083 Inst.addOperand(MCOperand::createReg(Reg));
2084 return MCDisassembler::Success;
2085}
2086
Daniel Sanders2a83d682014-05-21 12:56:39 +00002087static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
2088 unsigned RegNo,
2089 uint64_t Address,
2090 const void *Decoder) {
2091 if (RegNo > 31)
2092 return MCDisassembler::Fail;
2093
2094 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002095 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders2a83d682014-05-21 12:56:39 +00002096 return MCDisassembler::Success;
2097}
2098
Akira Hatanaka71928e62012-04-17 18:03:21 +00002099static DecodeStatus DecodeBranchTarget(MCInst &Inst,
2100 unsigned Offset,
2101 uint64_t Address,
2102 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00002103 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00002104 Inst.addOperand(MCOperand::createImm(BranchOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002105 return MCDisassembler::Success;
2106}
2107
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +00002108static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
2109 unsigned Offset,
2110 uint64_t Address,
2111 const void *Decoder) {
2112 int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
2113 Inst.addOperand(MCOperand::createImm(BranchOffset));
2114 return MCDisassembler::Success;
2115}
2116
Akira Hatanaka71928e62012-04-17 18:03:21 +00002117static DecodeStatus DecodeJumpTarget(MCInst &Inst,
2118 unsigned Insn,
2119 uint64_t Address,
2120 const void *Decoder) {
2121
Jim Grosbachecaef492012-08-14 19:06:05 +00002122 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00002123 Inst.addOperand(MCOperand::createImm(JumpOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002124 return MCDisassembler::Success;
2125}
2126
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002127static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2128 unsigned Offset,
2129 uint64_t Address,
2130 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00002131 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002132
Jim Grosbache9119e42015-05-13 18:37:00 +00002133 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002134 return MCDisassembler::Success;
2135}
2136
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00002137static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
2138 unsigned Offset,
2139 uint64_t Address,
2140 const void *Decoder) {
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002141 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00002142
2143 Inst.addOperand(MCOperand::createImm(BranchOffset));
2144 return MCDisassembler::Success;
2145}
2146
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002147static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2148 unsigned Offset,
2149 uint64_t Address,
2150 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00002151 int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002152
Jim Grosbache9119e42015-05-13 18:37:00 +00002153 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002154 return MCDisassembler::Success;
2155}
2156
Jozef Kolek9761e962015-01-12 12:03:34 +00002157static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2158 unsigned Offset,
2159 uint64_t Address,
2160 const void *Decoder) {
2161 int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002162 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek9761e962015-01-12 12:03:34 +00002163 return MCDisassembler::Success;
2164}
2165
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002166static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2167 unsigned Offset,
2168 uint64_t Address,
2169 const void *Decoder) {
2170 int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002171 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002172 return MCDisassembler::Success;
2173}
2174
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002175static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2176 unsigned Offset,
2177 uint64_t Address,
2178 const void *Decoder) {
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002179 int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00002180 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002181 return MCDisassembler::Success;
2182}
2183
Zoran Jovanovica887b362015-11-30 12:56:18 +00002184static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2185 unsigned Offset,
2186 uint64_t Address,
2187 const void *Decoder) {
2188 int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
2189
2190 Inst.addOperand(MCOperand::createImm(BranchOffset));
2191 return MCDisassembler::Success;
2192}
2193
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002194static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2195 unsigned Insn,
2196 uint64_t Address,
2197 const void *Decoder) {
2198 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002199 Inst.addOperand(MCOperand::createImm(JumpOffset));
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002200 return MCDisassembler::Success;
2201}
Akira Hatanaka71928e62012-04-17 18:03:21 +00002202
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002203static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2204 unsigned Value,
2205 uint64_t Address,
2206 const void *Decoder) {
2207 if (Value == 0)
Jim Grosbache9119e42015-05-13 18:37:00 +00002208 Inst.addOperand(MCOperand::createImm(1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002209 else if (Value == 0x7)
Jim Grosbache9119e42015-05-13 18:37:00 +00002210 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002211 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002212 Inst.addOperand(MCOperand::createImm(Value << 2));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002213 return MCDisassembler::Success;
2214}
2215
Daniel Sanders97297772016-03-22 14:40:00 +00002216static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002217 unsigned Value,
2218 uint64_t Address,
2219 const void *Decoder) {
2220 if (Value == 0x7F)
Jim Grosbache9119e42015-05-13 18:37:00 +00002221 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002222 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002223 Inst.addOperand(MCOperand::createImm(Value));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002224 return MCDisassembler::Success;
2225}
2226
Zoran Jovanovic6b28f092015-09-09 13:55:45 +00002227static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
2228 unsigned Value,
2229 uint64_t Address,
2230 const void *Decoder) {
2231 Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
2232 return MCDisassembler::Success;
2233}
2234
Daniel Sanders19b7f762016-03-14 11:16:56 +00002235template <unsigned Bits, int Offset, int Scale>
2236static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2237 uint64_t Address,
2238 const void *Decoder) {
Daniel Sandersea4f6532015-11-06 12:22:31 +00002239 Value &= ((1 << Bits) - 1);
Daniel Sanders19b7f762016-03-14 11:16:56 +00002240 Value *= Scale;
Daniel Sandersea4f6532015-11-06 12:22:31 +00002241 Inst.addOperand(MCOperand::createImm(Value + Offset));
Matheus Almeida779c5932013-11-18 12:32:49 +00002242 return MCDisassembler::Success;
2243}
2244
Daniel Sanders97297772016-03-22 14:40:00 +00002245template <unsigned Bits, int Offset, int ScaleBy>
2246static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2247 uint64_t Address,
2248 const void *Decoder) {
2249 int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
Daniel Sanders78e89022016-03-11 11:37:50 +00002250 Inst.addOperand(MCOperand::createImm(Imm + Offset));
2251 return MCDisassembler::Success;
2252}
2253
Akira Hatanaka71928e62012-04-17 18:03:21 +00002254static DecodeStatus DecodeInsSize(MCInst &Inst,
2255 unsigned Insn,
2256 uint64_t Address,
2257 const void *Decoder) {
2258 // First we need to grab the pos(lsb) from MCInst.
2259 int Pos = Inst.getOperand(2).getImm();
2260 int Size = (int) Insn - Pos + 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002261 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002262 return MCDisassembler::Success;
2263}
2264
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002265static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2266 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002267 Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002268 return MCDisassembler::Success;
2269}
Zoran Jovanovic28551422014-06-09 09:49:51 +00002270
2271static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2272 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002273 Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00002274 return MCDisassembler::Success;
2275}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002276
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002277static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2278 uint64_t Address, const void *Decoder) {
2279 int32_t DecodedValue;
2280 switch (Insn) {
2281 case 0: DecodedValue = 256; break;
2282 case 1: DecodedValue = 257; break;
2283 case 510: DecodedValue = -258; break;
2284 case 511: DecodedValue = -257; break;
2285 default: DecodedValue = SignExtend32<9>(Insn); break;
2286 }
Jim Grosbache9119e42015-05-13 18:37:00 +00002287 Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002288 return MCDisassembler::Success;
2289}
2290
2291static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2292 uint64_t Address, const void *Decoder) {
2293 // Insn must be >= 0, since it is unsigned that condition is always true.
2294 assert(Insn < 16);
2295 int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2296 255, 32768, 65535};
Jim Grosbache9119e42015-05-13 18:37:00 +00002297 Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002298 return MCDisassembler::Success;
2299}
2300
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002301static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2302 unsigned Insn,
2303 uint64_t Address,
2304 const void *Decoder) {
2305 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
Zoran Jovanovicdc4b8c22015-09-15 15:21:27 +00002306 Mips::S6, Mips::S7, Mips::FP};
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002307 unsigned RegNum;
2308
2309 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002310
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002311 // Empty register lists are not allowed.
2312 if (RegLst == 0)
2313 return MCDisassembler::Fail;
2314
2315 RegNum = RegLst & 0xf;
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002316
2317 // RegLst values 10-15, and 26-31 are reserved.
2318 if (RegNum > 9)
2319 return MCDisassembler::Fail;
2320
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002321 for (unsigned i = 0; i < RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002322 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002323
2324 if (RegLst & 0x10)
Jim Grosbache9119e42015-05-13 18:37:00 +00002325 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002326
2327 return MCDisassembler::Success;
2328}
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002329
2330static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2331 uint64_t Address,
2332 const void *Decoder) {
2333 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00002334 unsigned RegLst;
2335 switch(Inst.getOpcode()) {
2336 default:
2337 RegLst = fieldFromInstruction(Insn, 4, 2);
2338 break;
2339 case Mips::LWM16_MMR6:
2340 case Mips::SWM16_MMR6:
2341 RegLst = fieldFromInstruction(Insn, 8, 2);
2342 break;
2343 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002344 unsigned RegNum = RegLst & 0x3;
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002345
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002346 for (unsigned i = 0; i <= RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002347 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002348
Jim Grosbache9119e42015-05-13 18:37:00 +00002349 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002350
2351 return MCDisassembler::Success;
2352}
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002353
Zoran Jovanovic41688672015-02-10 16:36:20 +00002354static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
2355 uint64_t Address, const void *Decoder) {
2356
2357 unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2358
2359 switch (RegPair) {
2360 default:
2361 return MCDisassembler::Fail;
2362 case 0:
Jim Grosbache9119e42015-05-13 18:37:00 +00002363 Inst.addOperand(MCOperand::createReg(Mips::A1));
2364 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002365 break;
2366 case 1:
Jim Grosbache9119e42015-05-13 18:37:00 +00002367 Inst.addOperand(MCOperand::createReg(Mips::A1));
2368 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002369 break;
2370 case 2:
Jim Grosbache9119e42015-05-13 18:37:00 +00002371 Inst.addOperand(MCOperand::createReg(Mips::A2));
2372 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002373 break;
2374 case 3:
Jim Grosbache9119e42015-05-13 18:37:00 +00002375 Inst.addOperand(MCOperand::createReg(Mips::A0));
2376 Inst.addOperand(MCOperand::createReg(Mips::S5));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002377 break;
2378 case 4:
Jim Grosbache9119e42015-05-13 18:37:00 +00002379 Inst.addOperand(MCOperand::createReg(Mips::A0));
2380 Inst.addOperand(MCOperand::createReg(Mips::S6));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002381 break;
2382 case 5:
Jim Grosbache9119e42015-05-13 18:37:00 +00002383 Inst.addOperand(MCOperand::createReg(Mips::A0));
2384 Inst.addOperand(MCOperand::createReg(Mips::A1));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002385 break;
2386 case 6:
Jim Grosbache9119e42015-05-13 18:37:00 +00002387 Inst.addOperand(MCOperand::createReg(Mips::A0));
2388 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002389 break;
2390 case 7:
Jim Grosbache9119e42015-05-13 18:37:00 +00002391 Inst.addOperand(MCOperand::createReg(Mips::A0));
2392 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002393 break;
2394 }
2395
2396 return MCDisassembler::Success;
2397}
2398
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002399static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2400 uint64_t Address, const void *Decoder) {
Justin Bogner6499b5f2015-06-23 07:28:57 +00002401 Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002402 return MCDisassembler::Success;
2403}
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002404
2405template <typename InsnType>
2406static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2407 uint64_t Address,
2408 const void *Decoder) {
2409 // We have:
2410 // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
2411 // Invalid if rt == 0
2412 // BGTZALC_MMR6 if rs == 0 && rt != 0
2413 // BLTZALC_MMR6 if rs != 0 && rs == rt
2414 // BLTUC_MMR6 if rs != 0 && rs != rt
2415
2416 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2417 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002418 InsnType Imm = 0;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002419 bool HasRs = false;
2420 bool HasRt = false;
2421
2422 if (Rt == 0)
2423 return MCDisassembler::Fail;
2424 else if (Rs == 0) {
2425 MI.setOpcode(Mips::BGTZALC_MMR6);
2426 HasRt = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002427 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002428 }
2429 else if (Rs == Rt) {
2430 MI.setOpcode(Mips::BLTZALC_MMR6);
2431 HasRs = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002432 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002433 }
2434 else {
2435 MI.setOpcode(Mips::BLTUC_MMR6);
2436 HasRs = true;
2437 HasRt = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002438 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002439 }
2440
2441 if (HasRs)
2442 MI.addOperand(
2443 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2444
2445 if (HasRt)
2446 MI.addOperand(
2447 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2448
2449 MI.addOperand(MCOperand::createImm(Imm));
2450
2451 return MCDisassembler::Success;
2452}
2453
2454template <typename InsnType>
2455static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2456 uint64_t Address,
2457 const void *Decoder) {
2458 // We have:
2459 // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002460 // Invalid if rt == 0
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002461 // BLEZALC_MMR6 if rs == 0 && rt != 0
2462 // BGEZALC_MMR6 if rs == rt && rt != 0
2463 // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
2464
2465 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2466 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002467 InsnType Imm = 0;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002468 bool HasRs = false;
2469
2470 if (Rt == 0)
2471 return MCDisassembler::Fail;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002472 else if (Rs == 0) {
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002473 MI.setOpcode(Mips::BLEZALC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002474 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2475 }
2476 else if (Rs == Rt) {
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002477 MI.setOpcode(Mips::BGEZALC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002478 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2479 }
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002480 else {
2481 HasRs = true;
2482 MI.setOpcode(Mips::BGEUC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002483 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002484 }
2485
2486 if (HasRs)
2487 MI.addOperand(
2488 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2489 MI.addOperand(
2490 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2491
2492 MI.addOperand(MCOperand::createImm(Imm));
2493
2494 return MCDisassembler::Success;
2495}