blob: f53998ea8e7571f57dc35379a82fdb18c998fcf5 [file] [log] [blame]
Akira Hatanaka71928e62012-04-17 18:03:21 +00001//===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is part of the Mips Disassembler.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Mips.h"
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000015#include "MipsRegisterInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "MipsSubtarget.h"
Lang Hamesa1bc0f52014-04-15 04:40:56 +000017#include "llvm/MC/MCContext.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000018#include "llvm/MC/MCDisassembler/MCDisassembler.h"
Jim Grosbachecaef492012-08-14 19:06:05 +000019#include "llvm/MC/MCFixedLenDisassembler.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/Support/MathExtras.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000023#include "llvm/Support/TargetRegistry.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000024
Akira Hatanaka71928e62012-04-17 18:03:21 +000025using namespace llvm;
26
Chandler Carruthe96dd892014-04-21 22:55:11 +000027#define DEBUG_TYPE "mips-disassembler"
28
Akira Hatanaka71928e62012-04-17 18:03:21 +000029typedef MCDisassembler::DecodeStatus DecodeStatus;
30
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000031namespace {
32
Daniel Sandersa19216c2015-02-11 11:28:56 +000033class MipsDisassembler : public MCDisassembler {
Vladimir Medicdde3d582013-09-06 12:30:36 +000034 bool IsMicroMips;
Daniel Sandersa19216c2015-02-11 11:28:56 +000035 bool IsBigEndian;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000036public:
Daniel Sandersa19216c2015-02-11 11:28:56 +000037 MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
38 : MCDisassembler(STI, Ctx),
Michael Kupersteindb0712f2015-05-26 10:47:10 +000039 IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
Daniel Sandersa19216c2015-02-11 11:28:56 +000040 IsBigEndian(IsBigEndian) {}
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000041
Simon Dardis4fbf76f2016-06-14 11:29:28 +000042 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
Michael Kupersteindb0712f2015-05-26 10:47:10 +000043 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
44 bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
Daniel Sandersc171f652014-06-13 13:15:59 +000045 bool hasMips32r6() const {
Michael Kupersteindb0712f2015-05-26 10:47:10 +000046 return STI.getFeatureBits()[Mips::FeatureMips32r6];
Daniel Sanders5c582b22014-05-22 11:23:21 +000047 }
Zlatko Buljan6221be82016-03-31 08:51:24 +000048 bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
Daniel Sanders5c582b22014-05-22 11:23:21 +000049
Michael Kupersteindb0712f2015-05-26 10:47:10 +000050 bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
Daniel Sanders0fa60412014-06-12 13:39:06 +000051
Simon Dardis4fbf76f2016-06-14 11:29:28 +000052 bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }
53
Kai Nacke3adf9b82015-05-28 16:23:16 +000054 bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
55
Daniel Sandersc171f652014-06-13 13:15:59 +000056 bool hasCOP3() const {
57 // Only present in MIPS-I and MIPS-II
58 return !hasMips32() && !hasMips3();
59 }
60
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000061 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000062 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000063 raw_ostream &VStream,
64 raw_ostream &CStream) const override;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000065};
66
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000067} // end anonymous namespace
68
Akira Hatanaka71928e62012-04-17 18:03:21 +000069// Forward declare these because the autogenerated code will reference them.
70// Definitions are further down.
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000071static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
72 unsigned RegNo,
73 uint64_t Address,
74 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +000075
Reed Kotlerec8a5492013-02-14 03:05:25 +000076static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
77 unsigned RegNo,
78 uint64_t Address,
79 const void *Decoder);
80
Zoran Jovanovicb0852e52014-10-21 08:23:11 +000081static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
82 unsigned RegNo,
83 uint64_t Address,
84 const void *Decoder);
85
Jozef Kolek1904fa22014-11-24 14:25:53 +000086static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
87 unsigned RegNo,
88 uint64_t Address,
89 const void *Decoder);
90
Zoran Jovanovic41688672015-02-10 16:36:20 +000091static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
92 unsigned RegNo,
93 uint64_t Address,
94 const void *Decoder);
95
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000096static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
97 unsigned RegNo,
98 uint64_t Address,
99 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000100
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000101static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
102 unsigned Insn,
103 uint64_t Address,
104 const void *Decoder);
105
Akira Hatanaka654655f2013-08-14 00:53:38 +0000106static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
107 unsigned RegNo,
108 uint64_t Address,
109 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000110
Akira Hatanaka71928e62012-04-17 18:03:21 +0000111static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
112 unsigned RegNo,
113 uint64_t Address,
114 const void *Decoder);
115
116static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
117 unsigned RegNo,
118 uint64_t Address,
119 const void *Decoder);
120
121static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
122 unsigned RegNo,
123 uint64_t Address,
124 const void *Decoder);
125
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000126static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
127 unsigned RegNo,
128 uint64_t Address,
129 const void *Decoder);
130
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +0000131static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
132 uint64_t Address,
133 const void *Decoder);
Daniel Sanders0fa60412014-06-12 13:39:06 +0000134
Akira Hatanaka71928e62012-04-17 18:03:21 +0000135static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
136 unsigned Insn,
137 uint64_t Address,
138 const void *Decoder);
139
140static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
141 unsigned RegNo,
142 uint64_t Address,
143 const void *Decoder);
144
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000145static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
146 unsigned RegNo,
147 uint64_t Address,
148 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000149
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000150static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
151 unsigned RegNo,
152 uint64_t Address,
153 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000154
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000155static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
156 unsigned RegNo,
157 uint64_t Address,
158 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000159
Jack Carter3eb663b2013-09-26 00:09:46 +0000160static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
161 unsigned RegNo,
162 uint64_t Address,
163 const void *Decoder);
164
Jack Carter5dc8ac92013-09-25 23:50:44 +0000165static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
166 unsigned RegNo,
167 uint64_t Address,
168 const void *Decoder);
169
170static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
171 unsigned RegNo,
172 uint64_t Address,
173 const void *Decoder);
174
175static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
176 unsigned RegNo,
177 uint64_t Address,
178 const void *Decoder);
179
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000180static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
181 unsigned RegNo,
182 uint64_t Address,
183 const void *Decoder);
184
Daniel Sandersa3134fa2015-06-27 15:39:19 +0000185static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
186 unsigned RegNo,
187 uint64_t Address,
188 const void *Decoder);
189
Daniel Sanders2a83d682014-05-21 12:56:39 +0000190static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
191 unsigned RegNo,
192 uint64_t Address,
193 const void *Decoder);
194
Akira Hatanaka71928e62012-04-17 18:03:21 +0000195static DecodeStatus DecodeBranchTarget(MCInst &Inst,
196 unsigned Offset,
197 uint64_t Address,
198 const void *Decoder);
199
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +0000200static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
201 unsigned Offset,
202 uint64_t Address,
203 const void *Decoder);
204
Akira Hatanaka71928e62012-04-17 18:03:21 +0000205static DecodeStatus DecodeJumpTarget(MCInst &Inst,
206 unsigned Insn,
207 uint64_t Address,
208 const void *Decoder);
209
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000210static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
211 unsigned Offset,
212 uint64_t Address,
213 const void *Decoder);
214
Zoran Jovanovic84e4d592016-05-17 11:10:15 +0000215static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
216 unsigned Offset,
217 uint64_t Address,
218 const void *Decoder);
219
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000220static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
221 unsigned Offset,
222 uint64_t Address,
223 const void *Decoder);
224
Jozef Kolek9761e962015-01-12 12:03:34 +0000225// DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
226// shifted left by 1 bit.
227static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
228 unsigned Offset,
229 uint64_t Address,
230 const void *Decoder);
231
Jozef Kolek5cfebdd2015-01-21 12:39:30 +0000232// DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
233// shifted left by 1 bit.
234static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
235 unsigned Offset,
236 uint64_t Address,
237 const void *Decoder);
238
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000239// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
240// shifted left by 1 bit.
241static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
242 unsigned Offset,
243 uint64_t Address,
244 const void *Decoder);
245
Zoran Jovanovica887b362015-11-30 12:56:18 +0000246// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
247// shifted left by 1 bit.
248static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
249 unsigned Offset,
250 uint64_t Address,
251 const void *Decoder);
252
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000253// DecodeJumpTargetMM - Decode microMIPS jump target, which is
254// shifted left by 1 bit.
255static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
256 unsigned Insn,
257 uint64_t Address,
258 const void *Decoder);
259
Akira Hatanaka71928e62012-04-17 18:03:21 +0000260static DecodeStatus DecodeMem(MCInst &Inst,
261 unsigned Insn,
262 uint64_t Address,
263 const void *Decoder);
264
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000265static DecodeStatus DecodeMemEVA(MCInst &Inst,
266 unsigned Insn,
267 uint64_t Address,
268 const void *Decoder);
269
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +0000270static DecodeStatus DecodeLoadByte9(MCInst &Inst,
271 unsigned Insn,
272 uint64_t Address,
273 const void *Decoder);
274
275static DecodeStatus DecodeLoadByte15(MCInst &Inst,
276 unsigned Insn,
277 uint64_t Address,
278 const void *Decoder);
279
Daniel Sanders92db6b72014-10-01 08:26:55 +0000280static DecodeStatus DecodeCacheOp(MCInst &Inst,
281 unsigned Insn,
282 uint64_t Address,
283 const void *Decoder);
284
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000285static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
286 unsigned Insn,
287 uint64_t Address,
288 const void *Decoder);
Vladimir Medicdf464ae2015-01-29 11:33:41 +0000289
Jozef Kolekab6d1cc2014-12-23 19:55:34 +0000290static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
291 unsigned Insn,
292 uint64_t Address,
293 const void *Decoder);
294
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +0000295static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
296 unsigned Insn,
297 uint64_t Address,
298 const void *Decoder);
299
Zoran Jovanovicd9790792015-09-09 09:10:46 +0000300static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
301 unsigned Insn,
302 uint64_t Address,
303 const void *Decoder);
304
Daniel Sandersb4484d62014-11-27 17:28:10 +0000305static DecodeStatus DecodeSyncI(MCInst &Inst,
306 unsigned Insn,
307 uint64_t Address,
308 const void *Decoder);
309
Hrvoje Varga18148672015-10-28 11:04:29 +0000310static DecodeStatus DecodeSynciR6(MCInst &Inst,
311 unsigned Insn,
312 uint64_t Address,
313 const void *Decoder);
314
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000315static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
316 uint64_t Address, const void *Decoder);
317
Jozef Kolek315e7ec2014-11-26 18:56:38 +0000318static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
319 unsigned Insn,
320 uint64_t Address,
321 const void *Decoder);
322
Jozef Kolek12c69822014-12-23 16:16:33 +0000323static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
324 unsigned Insn,
325 uint64_t Address,
326 const void *Decoder);
327
Jozef Koleke10a02e2015-01-28 17:27:26 +0000328static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
329 unsigned Insn,
330 uint64_t Address,
331 const void *Decoder);
332
Jozef Kolekd68d424a2015-02-10 12:41:13 +0000333static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
334 unsigned Insn,
335 uint64_t Address,
336 const void *Decoder);
337
Zoran Jovanovica6593ff2015-08-18 12:53:08 +0000338static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
339 unsigned Insn,
340 uint64_t Address,
341 const void *Decoder);
342
Vladimir Medicdde3d582013-09-06 12:30:36 +0000343static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
344 unsigned Insn,
345 uint64_t Address,
346 const void *Decoder);
347
348static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
349 unsigned Insn,
350 uint64_t Address,
351 const void *Decoder);
352
Akira Hatanaka71928e62012-04-17 18:03:21 +0000353static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
354 uint64_t Address,
355 const void *Decoder);
356
Zlatko Buljancba9f802016-07-11 07:41:56 +0000357static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
358 uint64_t Address,
359 const void *Decoder);
360
Daniel Sanders92db6b72014-10-01 08:26:55 +0000361static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
362 uint64_t Address,
363 const void *Decoder);
364
365static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
366 uint64_t Address,
367 const void *Decoder);
368
Vladimir Medic435cf8a2015-01-21 10:47:36 +0000369static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
370 uint64_t Address,
371 const void *Decoder);
372
Zlatko Buljancba9f802016-07-11 07:41:56 +0000373static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
374 uint64_t Address,
375 const void *Decoder);
376
Daniel Sanders6a803f62014-06-16 13:13:03 +0000377static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
378 unsigned Insn,
379 uint64_t Address,
380 const void *Decoder);
381
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000382static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
383 unsigned Value,
384 uint64_t Address,
385 const void *Decoder);
386
Daniel Sanders97297772016-03-22 14:40:00 +0000387static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000388 unsigned Value,
389 uint64_t Address,
390 const void *Decoder);
391
Zoran Jovanovic6b28f092015-09-09 13:55:45 +0000392static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
393 unsigned Value,
394 uint64_t Address,
395 const void *Decoder);
396
Daniel Sanders19b7f762016-03-14 11:16:56 +0000397template <unsigned Bits, int Offset, int Scale>
398static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
399 uint64_t Address,
400 const void *Decoder);
401
Daniel Sandersea4f6532015-11-06 12:22:31 +0000402template <unsigned Bits, int Offset>
403static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
Daniel Sanders19b7f762016-03-14 11:16:56 +0000404 uint64_t Address,
405 const void *Decoder) {
406 return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
407 Decoder);
408}
Matheus Almeida779c5932013-11-18 12:32:49 +0000409
Daniel Sanders97297772016-03-22 14:40:00 +0000410template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
411static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
412 uint64_t Address,
413 const void *Decoder);
Daniel Sanders78e89022016-03-11 11:37:50 +0000414
Akira Hatanaka71928e62012-04-17 18:03:21 +0000415static DecodeStatus DecodeInsSize(MCInst &Inst,
416 unsigned Insn,
417 uint64_t Address,
418 const void *Decoder);
419
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000420static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
421 uint64_t Address, const void *Decoder);
422
Zoran Jovanovic28551422014-06-09 09:49:51 +0000423static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
424 uint64_t Address, const void *Decoder);
425
Vladimir Medicb682ddf2014-12-01 11:12:04 +0000426static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
427 uint64_t Address, const void *Decoder);
428
429static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
430 uint64_t Address, const void *Decoder);
431
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000432static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
433 uint64_t Address, const void *Decoder);
434
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000435/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
436/// handle.
437template <typename InsnType>
438static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
439 const void *Decoder);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000440
441template <typename InsnType>
442static DecodeStatus
443DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
444 const void *Decoder);
445
446template <typename InsnType>
447static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000448DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
449 const void *Decoder);
450
451template <typename InsnType>
452static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000453DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
454 const void *Decoder);
455
456template <typename InsnType>
457static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000458DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
459 const void *Decoder);
460
461template <typename InsnType>
462static DecodeStatus
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000463DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
464 const void *Decoder);
465
466template <typename InsnType>
467static DecodeStatus
468DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
469 const void *Decoder);
470
471template <typename InsnType>
472static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000473DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
474 const void *Decoder);
475
476template <typename InsnType>
477static DecodeStatus
478DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
479 const void *Decoder);
480
481template <typename InsnType>
482static DecodeStatus
483DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
484 const void *Decoder);
485
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000486template <typename InsnType>
487static DecodeStatus
488DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
489 const void *Decoder);
490
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +0000491template <typename InsnType>
492static DecodeStatus
493DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
494 const void *Decoder);
495
496template <typename InsnType>
497static DecodeStatus
498DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
499 const void *Decoder);
500
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000501static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
502 uint64_t Address,
503 const void *Decoder);
504
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000505static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
506 uint64_t Address,
507 const void *Decoder);
508
Zoran Jovanovic41688672015-02-10 16:36:20 +0000509static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
510 uint64_t Address,
511 const void *Decoder);
512
Akira Hatanaka71928e62012-04-17 18:03:21 +0000513namespace llvm {
514extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
515 TheMips64elTarget;
516}
517
518static MCDisassembler *createMipsDisassembler(
519 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000520 const MCSubtargetInfo &STI,
521 MCContext &Ctx) {
522 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000523}
524
525static MCDisassembler *createMipselDisassembler(
526 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000527 const MCSubtargetInfo &STI,
528 MCContext &Ctx) {
529 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000530}
531
Akira Hatanaka71928e62012-04-17 18:03:21 +0000532extern "C" void LLVMInitializeMipsDisassembler() {
533 // Register the disassembler.
534 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
535 createMipsDisassembler);
536 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
537 createMipselDisassembler);
538 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000539 createMipsDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000540 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000541 createMipselDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000542}
543
Akira Hatanaka71928e62012-04-17 18:03:21 +0000544#include "MipsGenDisassemblerTables.inc"
545
Daniel Sanders5c582b22014-05-22 11:23:21 +0000546static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
Daniel Sandersa19216c2015-02-11 11:28:56 +0000547 const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000548 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
549 return *(RegInfo->getRegClass(RC).begin() + RegNo);
550}
551
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000552template <typename InsnType>
553static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
554 const void *Decoder) {
555 typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
556 // The size of the n field depends on the element size
557 // The register class also depends on this.
558 InsnType tmp = fieldFromInstruction(insn, 17, 5);
559 unsigned NSize = 0;
560 DecodeFN RegDecoder = nullptr;
561 if ((tmp & 0x18) == 0x00) { // INSVE_B
562 NSize = 4;
563 RegDecoder = DecodeMSA128BRegisterClass;
564 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
565 NSize = 3;
566 RegDecoder = DecodeMSA128HRegisterClass;
567 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
568 NSize = 2;
569 RegDecoder = DecodeMSA128WRegisterClass;
570 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
571 NSize = 1;
572 RegDecoder = DecodeMSA128DRegisterClass;
573 } else
574 llvm_unreachable("Invalid encoding");
575
576 assert(NSize != 0 && RegDecoder != nullptr);
577
578 // $wd
579 tmp = fieldFromInstruction(insn, 6, 5);
580 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
581 return MCDisassembler::Fail;
582 // $wd_in
583 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
584 return MCDisassembler::Fail;
585 // $n
586 tmp = fieldFromInstruction(insn, 16, NSize);
Jim Grosbache9119e42015-05-13 18:37:00 +0000587 MI.addOperand(MCOperand::createImm(tmp));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000588 // $ws
589 tmp = fieldFromInstruction(insn, 11, 5);
590 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
591 return MCDisassembler::Fail;
592 // $n2
Jim Grosbache9119e42015-05-13 18:37:00 +0000593 MI.addOperand(MCOperand::createImm(0));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000594
595 return MCDisassembler::Success;
596}
597
Daniel Sanders5c582b22014-05-22 11:23:21 +0000598template <typename InsnType>
599static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
600 uint64_t Address,
601 const void *Decoder) {
602 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
603 // (otherwise we would have matched the ADDI instruction from the earlier
604 // ISA's instead).
605 //
606 // We have:
607 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
608 // BOVC if rs >= rt
609 // BEQZALC if rs == 0 && rt != 0
610 // BEQC if rs < rt && rs != 0
611
612 InsnType Rs = fieldFromInstruction(insn, 21, 5);
613 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000614 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000615 bool HasRs = false;
616
617 if (Rs >= Rt) {
618 MI.setOpcode(Mips::BOVC);
619 HasRs = true;
620 } else if (Rs != 0 && Rs < Rt) {
621 MI.setOpcode(Mips::BEQC);
622 HasRs = true;
623 } else
624 MI.setOpcode(Mips::BEQZALC);
625
626 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000627 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000628 Rs)));
629
Jim Grosbache9119e42015-05-13 18:37:00 +0000630 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000631 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000632 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000633
634 return MCDisassembler::Success;
635}
636
637template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000638static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
639 uint64_t Address,
640 const void *Decoder) {
641 InsnType Rt = fieldFromInstruction(insn, 21, 5);
642 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000643 int64_t Imm = 0;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000644
645 if (Rs >= Rt) {
646 MI.setOpcode(Mips::BOVC_MMR6);
647 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
648 Rt)));
649 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
650 Rs)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000651 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000652 } else if (Rs != 0 && Rs < Rt) {
653 MI.setOpcode(Mips::BEQC_MMR6);
654 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
655 Rs)));
656 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
657 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000658 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000659 } else {
660 MI.setOpcode(Mips::BEQZALC_MMR6);
661 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
662 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000663 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000664 }
665
666 MI.addOperand(MCOperand::createImm(Imm));
667
668 return MCDisassembler::Success;
669}
670
671template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000672static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
673 uint64_t Address,
674 const void *Decoder) {
675 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
676 // (otherwise we would have matched the ADDI instruction from the earlier
677 // ISA's instead).
678 //
679 // We have:
680 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
681 // BNVC if rs >= rt
682 // BNEZALC if rs == 0 && rt != 0
683 // BNEC if rs < rt && rs != 0
684
685 InsnType Rs = fieldFromInstruction(insn, 21, 5);
686 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000687 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000688 bool HasRs = false;
689
690 if (Rs >= Rt) {
691 MI.setOpcode(Mips::BNVC);
692 HasRs = true;
693 } else if (Rs != 0 && Rs < Rt) {
694 MI.setOpcode(Mips::BNEC);
695 HasRs = true;
696 } else
697 MI.setOpcode(Mips::BNEZALC);
698
699 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000700 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000701 Rs)));
702
Jim Grosbache9119e42015-05-13 18:37:00 +0000703 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000704 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000705 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000706
707 return MCDisassembler::Success;
708}
709
710template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000711static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
712 uint64_t Address,
713 const void *Decoder) {
714 InsnType Rt = fieldFromInstruction(insn, 21, 5);
715 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000716 int64_t Imm = 0;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000717
718 if (Rs >= Rt) {
719 MI.setOpcode(Mips::BNVC_MMR6);
720 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
721 Rt)));
722 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
723 Rs)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000724 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000725 } else if (Rs != 0 && Rs < Rt) {
726 MI.setOpcode(Mips::BNEC_MMR6);
727 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
728 Rs)));
729 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
730 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000731 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000732 } else {
733 MI.setOpcode(Mips::BNEZALC_MMR6);
734 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
735 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000736 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000737 }
738
739 MI.addOperand(MCOperand::createImm(Imm));
740
741 return MCDisassembler::Success;
742}
743
744template <typename InsnType>
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000745static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
746 uint64_t Address,
747 const void *Decoder) {
748 // We have:
749 // 0b110101 ttttt sssss iiiiiiiiiiiiiiii
750 // Invalid if rt == 0
751 // BGTZC_MMR6 if rs == 0 && rt != 0
752 // BLTZC_MMR6 if rs == rt && rt != 0
753 // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0
754
755 InsnType Rt = fieldFromInstruction(insn, 21, 5);
756 InsnType Rs = fieldFromInstruction(insn, 16, 5);
757 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
758 bool HasRs = false;
759
760 if (Rt == 0)
761 return MCDisassembler::Fail;
762 else if (Rs == 0)
763 MI.setOpcode(Mips::BGTZC_MMR6);
764 else if (Rs == Rt)
765 MI.setOpcode(Mips::BLTZC_MMR6);
766 else {
767 MI.setOpcode(Mips::BLTC_MMR6);
768 HasRs = true;
769 }
770
771 if (HasRs)
772 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
773 Rs)));
774
775 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
776 Rt)));
777
778 MI.addOperand(MCOperand::createImm(Imm));
779
780 return MCDisassembler::Success;
781}
782
783template <typename InsnType>
784static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
785 uint64_t Address,
786 const void *Decoder) {
787 // We have:
788 // 0b111101 ttttt sssss iiiiiiiiiiiiiiii
789 // Invalid if rt == 0
790 // BLEZC_MMR6 if rs == 0 && rt != 0
791 // BGEZC_MMR6 if rs == rt && rt != 0
792 // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0
793
794 InsnType Rt = fieldFromInstruction(insn, 21, 5);
795 InsnType Rs = fieldFromInstruction(insn, 16, 5);
796 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
797 bool HasRs = false;
798
799 if (Rt == 0)
800 return MCDisassembler::Fail;
801 else if (Rs == 0)
802 MI.setOpcode(Mips::BLEZC_MMR6);
803 else if (Rs == Rt)
804 MI.setOpcode(Mips::BGEZC_MMR6);
805 else {
806 HasRs = true;
807 MI.setOpcode(Mips::BGEC_MMR6);
808 }
809
810 if (HasRs)
811 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
812 Rs)));
813
814 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
815 Rt)));
816
817 MI.addOperand(MCOperand::createImm(Imm));
818
819 return MCDisassembler::Success;
820}
821
822template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000823static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
824 uint64_t Address,
825 const void *Decoder) {
826 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
827 // (otherwise we would have matched the BLEZL instruction from the earlier
828 // ISA's instead).
829 //
830 // We have:
831 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
832 // Invalid if rs == 0
833 // BLEZC if rs == 0 && rt != 0
834 // BGEZC if rs == rt && rt != 0
835 // BGEC if rs != rt && rs != 0 && rt != 0
836
837 InsnType Rs = fieldFromInstruction(insn, 21, 5);
838 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000839 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000840 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000841
842 if (Rt == 0)
843 return MCDisassembler::Fail;
844 else if (Rs == 0)
845 MI.setOpcode(Mips::BLEZC);
846 else if (Rs == Rt)
847 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000848 else {
849 HasRs = true;
850 MI.setOpcode(Mips::BGEC);
851 }
852
853 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000854 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000855 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000856
Jim Grosbache9119e42015-05-13 18:37:00 +0000857 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000858 Rt)));
859
Jim Grosbache9119e42015-05-13 18:37:00 +0000860 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000861
862 return MCDisassembler::Success;
863}
864
865template <typename InsnType>
866static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
867 uint64_t Address,
868 const void *Decoder) {
869 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
870 // (otherwise we would have matched the BGTZL instruction from the earlier
871 // ISA's instead).
872 //
873 // We have:
874 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
875 // Invalid if rs == 0
876 // BGTZC if rs == 0 && rt != 0
877 // BLTZC if rs == rt && rt != 0
878 // BLTC if rs != rt && rs != 0 && rt != 0
879
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000880 bool HasRs = false;
881
Daniel Sanders5c582b22014-05-22 11:23:21 +0000882 InsnType Rs = fieldFromInstruction(insn, 21, 5);
883 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000884 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000885
886 if (Rt == 0)
887 return MCDisassembler::Fail;
888 else if (Rs == 0)
889 MI.setOpcode(Mips::BGTZC);
890 else if (Rs == Rt)
891 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000892 else {
893 MI.setOpcode(Mips::BLTC);
894 HasRs = true;
895 }
896
897 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000898 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000899 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000900
Jim Grosbache9119e42015-05-13 18:37:00 +0000901 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000902 Rt)));
903
Jim Grosbache9119e42015-05-13 18:37:00 +0000904 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000905
906 return MCDisassembler::Success;
907}
908
909template <typename InsnType>
910static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
911 uint64_t Address,
912 const void *Decoder) {
913 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
914 // (otherwise we would have matched the BGTZ instruction from the earlier
915 // ISA's instead).
916 //
917 // We have:
918 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
919 // BGTZ if rt == 0
920 // BGTZALC if rs == 0 && rt != 0
921 // BLTZALC if rs != 0 && rs == rt
922 // BLTUC if rs != 0 && rs != rt
923
924 InsnType Rs = fieldFromInstruction(insn, 21, 5);
925 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000926 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000927 bool HasRs = false;
928 bool HasRt = false;
929
930 if (Rt == 0) {
931 MI.setOpcode(Mips::BGTZ);
932 HasRs = true;
933 } else if (Rs == 0) {
934 MI.setOpcode(Mips::BGTZALC);
935 HasRt = true;
936 } else if (Rs == Rt) {
937 MI.setOpcode(Mips::BLTZALC);
938 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000939 } else {
940 MI.setOpcode(Mips::BLTUC);
941 HasRs = true;
942 HasRt = true;
943 }
Daniel Sanders5c582b22014-05-22 11:23:21 +0000944
945 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000946 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000947 Rs)));
948
949 if (HasRt)
Jim Grosbache9119e42015-05-13 18:37:00 +0000950 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000951 Rt)));
952
Jim Grosbache9119e42015-05-13 18:37:00 +0000953 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000954
955 return MCDisassembler::Success;
956}
957
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000958template <typename InsnType>
959static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
960 uint64_t Address,
961 const void *Decoder) {
962 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
963 // (otherwise we would have matched the BLEZL instruction from the earlier
964 // ISA's instead).
965 //
966 // We have:
967 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
968 // Invalid if rs == 0
969 // BLEZALC if rs == 0 && rt != 0
970 // BGEZALC if rs == rt && rt != 0
971 // BGEUC if rs != rt && rs != 0 && rt != 0
972
973 InsnType Rs = fieldFromInstruction(insn, 21, 5);
974 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000975 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000976 bool HasRs = false;
977
978 if (Rt == 0)
979 return MCDisassembler::Fail;
980 else if (Rs == 0)
981 MI.setOpcode(Mips::BLEZALC);
982 else if (Rs == Rt)
983 MI.setOpcode(Mips::BGEZALC);
984 else {
985 HasRs = true;
986 MI.setOpcode(Mips::BGEUC);
987 }
988
989 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000990 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000991 Rs)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000992 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000993 Rt)));
994
Jim Grosbache9119e42015-05-13 18:37:00 +0000995 MI.addOperand(MCOperand::createImm(Imm));
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000996
997 return MCDisassembler::Success;
998}
999
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001000/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
1001/// according to the given endianess.
1002static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1003 uint64_t &Size, uint32_t &Insn,
1004 bool IsBigEndian) {
1005 // We want to read exactly 2 Bytes of data.
1006 if (Bytes.size() < 2) {
1007 Size = 0;
1008 return MCDisassembler::Fail;
1009 }
1010
1011 if (IsBigEndian) {
1012 Insn = (Bytes[0] << 8) | Bytes[1];
1013 } else {
1014 Insn = (Bytes[1] << 8) | Bytes[0];
1015 }
1016
1017 return MCDisassembler::Success;
1018}
1019
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001020/// Read four bytes from the ArrayRef and return 32 bit word sorted
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001021/// according to the given endianess
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001022static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
1023 uint64_t &Size, uint32_t &Insn,
1024 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001025 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001026 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001027 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001028 return MCDisassembler::Fail;
1029 }
1030
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001031 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1032 // always precede the low 16 bits in the instruction stream (that is, they
1033 // are placed at lower addresses in the instruction stream).
1034 //
1035 // microMIPS byte ordering:
1036 // Big-endian: 0 | 1 | 2 | 3
1037 // Little-endian: 1 | 0 | 3 | 2
1038
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001039 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001040 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001041 Insn =
1042 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
1043 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +00001044 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001045 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +00001046 (Bytes[1] << 24);
1047 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001048 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +00001049 (Bytes[3] << 24);
1050 }
Akira Hatanaka71928e62012-04-17 18:03:21 +00001051 }
1052
1053 return MCDisassembler::Success;
1054}
1055
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001056DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001057 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001058 uint64_t Address,
1059 raw_ostream &VStream,
1060 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001061 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001062 DecodeStatus Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001063
Vladimir Medicdde3d582013-09-06 12:30:36 +00001064 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001065 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
Reid Klecknerebee6122015-11-19 21:51:55 +00001066 if (Result == MCDisassembler::Fail)
1067 return MCDisassembler::Fail;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001068
Zoran Jovanovicada70912015-09-07 11:56:37 +00001069 if (hasMips32r6()) {
1070 DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1071 // Calling the auto-generated decoder function for microMIPS32R6
1072 // (and microMIPS64R6) 16-bit instructions.
1073 Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1074 Address, this, STI);
1075 if (Result != MCDisassembler::Fail) {
1076 Size = 2;
1077 return Result;
1078 }
1079 }
1080
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001081 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
Zoran Jovanovicada70912015-09-07 11:56:37 +00001082 // Calling the auto-generated decoder function for microMIPS 16-bit
1083 // instructions.
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001084 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1085 this, STI);
1086 if (Result != MCDisassembler::Fail) {
1087 Size = 2;
1088 return Result;
1089 }
1090
1091 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
1092 if (Result == MCDisassembler::Fail)
1093 return MCDisassembler::Fail;
1094
Jozef Kolek676d6012015-04-20 14:40:38 +00001095 if (hasMips32r6()) {
1096 DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1097 // Calling the auto-generated decoder function.
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001098 Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
Jozef Kolek676d6012015-04-20 14:40:38 +00001099 this, STI);
Zoran Jovanovicada70912015-09-07 11:56:37 +00001100 if (Result != MCDisassembler::Fail) {
1101 Size = 4;
1102 return Result;
1103 }
Jozef Kolek676d6012015-04-20 14:40:38 +00001104 }
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001105
Zoran Jovanovicada70912015-09-07 11:56:37 +00001106 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1107 // Calling the auto-generated decoder function.
1108 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1109 this, STI);
Vladimir Medicdde3d582013-09-06 12:30:36 +00001110 if (Result != MCDisassembler::Fail) {
1111 Size = 4;
1112 return Result;
1113 }
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001114
Zlatko Buljan6221be82016-03-31 08:51:24 +00001115 if (hasMips32r6() && isFP64()) {
1116 DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
1117 Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001118 Address, this, STI);
1119 if (Result != MCDisassembler::Fail) {
1120 Size = 4;
1121 return Result;
1122 }
1123 }
1124
Reid Klecknerebee6122015-11-19 21:51:55 +00001125 // This is an invalid instruction. Let the disassembler move forward by the
1126 // minimum instruction size.
1127 Size = 2;
Vladimir Medicdde3d582013-09-06 12:30:36 +00001128 return MCDisassembler::Fail;
1129 }
1130
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001131 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Reid Klecknerebee6122015-11-19 21:51:55 +00001132 if (Result == MCDisassembler::Fail) {
1133 Size = 4;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001134 return MCDisassembler::Fail;
Reid Klecknerebee6122015-11-19 21:51:55 +00001135 }
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001136
Daniel Sandersc171f652014-06-13 13:15:59 +00001137 if (hasCOP3()) {
1138 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1139 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001140 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Daniel Sandersc171f652014-06-13 13:15:59 +00001141 if (Result != MCDisassembler::Fail) {
1142 Size = 4;
1143 return Result;
1144 }
1145 }
1146
1147 if (hasMips32r6() && isGP64()) {
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001148 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
1149 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
1150 Address, this, STI);
Daniel Sanders0fa60412014-06-12 13:39:06 +00001151 if (Result != MCDisassembler::Fail) {
1152 Size = 4;
1153 return Result;
1154 }
1155 }
1156
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001157 if (hasMips32r6() && isPTR64()) {
1158 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1159 Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
1160 Address, this, STI);
1161 if (Result != MCDisassembler::Fail) {
1162 Size = 4;
1163 return Result;
1164 }
1165 }
1166
Daniel Sandersc171f652014-06-13 13:15:59 +00001167 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001168 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001169 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +00001170 Address, this, STI);
1171 if (Result != MCDisassembler::Fail) {
1172 Size = 4;
1173 return Result;
1174 }
1175 }
1176
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001177 if (hasMips2() && isPTR64()) {
1178 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1179 Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
1180 Address, this, STI);
1181 if (Result != MCDisassembler::Fail) {
1182 Size = 4;
1183 return Result;
1184 }
1185 }
1186
Kai Nacke3adf9b82015-05-28 16:23:16 +00001187 if (hasCnMips()) {
1188 DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
1189 Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
1190 Address, this, STI);
1191 if (Result != MCDisassembler::Fail) {
1192 Size = 4;
1193 return Result;
1194 }
1195 }
1196
Daniel Sandersa19216c2015-02-11 11:28:56 +00001197 if (isGP64()) {
1198 DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1199 Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1200 Address, this, STI);
1201 if (Result != MCDisassembler::Fail) {
1202 Size = 4;
1203 return Result;
1204 }
1205 }
1206
Daniel Sanders0fa60412014-06-12 13:39:06 +00001207 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +00001208 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001209 Result =
1210 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001211 if (Result != MCDisassembler::Fail) {
1212 Size = 4;
1213 return Result;
1214 }
1215
Reid Klecknerebee6122015-11-19 21:51:55 +00001216 Size = 4;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001217 return MCDisassembler::Fail;
1218}
1219
Reed Kotlerec8a5492013-02-14 03:05:25 +00001220static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1221 unsigned RegNo,
1222 uint64_t Address,
1223 const void *Decoder) {
1224
1225 return MCDisassembler::Fail;
1226
1227}
1228
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001229static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1230 unsigned RegNo,
1231 uint64_t Address,
1232 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001233
1234 if (RegNo > 31)
1235 return MCDisassembler::Fail;
1236
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001237 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001238 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001239 return MCDisassembler::Success;
1240}
1241
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001242static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1243 unsigned RegNo,
1244 uint64_t Address,
1245 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001246 if (RegNo > 7)
1247 return MCDisassembler::Fail;
1248 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001249 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001250 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001251}
1252
Jozef Kolek1904fa22014-11-24 14:25:53 +00001253static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1254 unsigned RegNo,
1255 uint64_t Address,
1256 const void *Decoder) {
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001257 if (RegNo > 7)
1258 return MCDisassembler::Fail;
1259 unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001260 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001261 return MCDisassembler::Success;
Jozef Kolek1904fa22014-11-24 14:25:53 +00001262}
1263
Zoran Jovanovic41688672015-02-10 16:36:20 +00001264static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1265 unsigned RegNo,
1266 uint64_t Address,
1267 const void *Decoder) {
1268 if (RegNo > 7)
1269 return MCDisassembler::Fail;
1270 unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001271 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic41688672015-02-10 16:36:20 +00001272 return MCDisassembler::Success;
1273}
1274
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001275static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1276 unsigned RegNo,
1277 uint64_t Address,
1278 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001279 if (RegNo > 31)
1280 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001281 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001282 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001283 return MCDisassembler::Success;
1284}
1285
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001286static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1287 unsigned RegNo,
1288 uint64_t Address,
1289 const void *Decoder) {
Daniel Sandersa19216c2015-02-11 11:28:56 +00001290 if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001291 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1292
1293 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1294}
1295
Akira Hatanaka654655f2013-08-14 00:53:38 +00001296static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1297 unsigned RegNo,
1298 uint64_t Address,
1299 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001300 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001301}
1302
Akira Hatanaka71928e62012-04-17 18:03:21 +00001303static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1304 unsigned RegNo,
1305 uint64_t Address,
1306 const void *Decoder) {
1307 if (RegNo > 31)
1308 return MCDisassembler::Fail;
1309
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001310 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001311 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001312 return MCDisassembler::Success;
1313}
1314
1315static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1316 unsigned RegNo,
1317 uint64_t Address,
1318 const void *Decoder) {
1319 if (RegNo > 31)
1320 return MCDisassembler::Fail;
1321
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001322 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001323 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001324 return MCDisassembler::Success;
1325}
1326
1327static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1328 unsigned RegNo,
1329 uint64_t Address,
1330 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +00001331 if (RegNo > 31)
1332 return MCDisassembler::Fail;
1333 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001334 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001335 return MCDisassembler::Success;
1336}
1337
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001338static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1339 unsigned RegNo,
1340 uint64_t Address,
1341 const void *Decoder) {
1342 if (RegNo > 7)
1343 return MCDisassembler::Fail;
1344 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001345 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001346 return MCDisassembler::Success;
1347}
1348
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001349static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1350 uint64_t Address,
1351 const void *Decoder) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001352 if (RegNo > 31)
1353 return MCDisassembler::Fail;
1354
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001355 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001356 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders0fa60412014-06-12 13:39:06 +00001357 return MCDisassembler::Success;
1358}
1359
Akira Hatanaka71928e62012-04-17 18:03:21 +00001360static DecodeStatus DecodeMem(MCInst &Inst,
1361 unsigned Insn,
1362 uint64_t Address,
1363 const void *Decoder) {
1364 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001365 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1366 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001367
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001368 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1369 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001370
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001371 if (Inst.getOpcode() == Mips::SC ||
1372 Inst.getOpcode() == Mips::SCD)
Jim Grosbache9119e42015-05-13 18:37:00 +00001373 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001374
1375 Inst.addOperand(MCOperand::createReg(Reg));
1376 Inst.addOperand(MCOperand::createReg(Base));
1377 Inst.addOperand(MCOperand::createImm(Offset));
1378
1379 return MCDisassembler::Success;
1380}
1381
1382static DecodeStatus DecodeMemEVA(MCInst &Inst,
1383 unsigned Insn,
1384 uint64_t Address,
1385 const void *Decoder) {
1386 int Offset = SignExtend32<9>(Insn >> 7);
1387 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1388 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1389
1390 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1391 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1392
1393 if (Inst.getOpcode() == Mips::SCE)
1394 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001395
Jim Grosbache9119e42015-05-13 18:37:00 +00001396 Inst.addOperand(MCOperand::createReg(Reg));
1397 Inst.addOperand(MCOperand::createReg(Base));
1398 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001399
1400 return MCDisassembler::Success;
1401}
1402
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +00001403static DecodeStatus DecodeLoadByte9(MCInst &Inst,
1404 unsigned Insn,
1405 uint64_t Address,
1406 const void *Decoder) {
1407 int Offset = SignExtend32<9>(Insn & 0x1ff);
1408 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1409 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1410
1411 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1412 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1413
1414 Inst.addOperand(MCOperand::createReg(Reg));
1415 Inst.addOperand(MCOperand::createReg(Base));
1416 Inst.addOperand(MCOperand::createImm(Offset));
1417
1418 return MCDisassembler::Success;
1419}
1420
1421static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1422 unsigned Insn,
1423 uint64_t Address,
1424 const void *Decoder) {
1425 int Offset = SignExtend32<16>(Insn & 0xffff);
1426 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1427 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1428
1429 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1430 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1431
1432 Inst.addOperand(MCOperand::createReg(Reg));
1433 Inst.addOperand(MCOperand::createReg(Base));
1434 Inst.addOperand(MCOperand::createImm(Offset));
1435
1436 return MCDisassembler::Success;
1437}
1438
Daniel Sanders92db6b72014-10-01 08:26:55 +00001439static DecodeStatus DecodeCacheOp(MCInst &Inst,
1440 unsigned Insn,
1441 uint64_t Address,
1442 const void *Decoder) {
1443 int Offset = SignExtend32<16>(Insn & 0xffff);
1444 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1445 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1446
1447 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1448
Jim Grosbache9119e42015-05-13 18:37:00 +00001449 Inst.addOperand(MCOperand::createReg(Base));
1450 Inst.addOperand(MCOperand::createImm(Offset));
1451 Inst.addOperand(MCOperand::createImm(Hint));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001452
1453 return MCDisassembler::Success;
1454}
1455
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001456static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1457 unsigned Insn,
1458 uint64_t Address,
1459 const void *Decoder) {
1460 int Offset = SignExtend32<12>(Insn & 0xfff);
1461 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1462 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1463
1464 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1465
Jim Grosbache9119e42015-05-13 18:37:00 +00001466 Inst.addOperand(MCOperand::createReg(Base));
1467 Inst.addOperand(MCOperand::createImm(Offset));
1468 Inst.addOperand(MCOperand::createImm(Hint));
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001469
1470 return MCDisassembler::Success;
1471}
1472
Zoran Jovanovicd9790792015-09-09 09:10:46 +00001473static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1474 unsigned Insn,
1475 uint64_t Address,
1476 const void *Decoder) {
1477 int Offset = SignExtend32<9>(Insn & 0x1ff);
1478 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1479 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1480
1481 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1482
1483 Inst.addOperand(MCOperand::createReg(Base));
1484 Inst.addOperand(MCOperand::createImm(Offset));
1485 Inst.addOperand(MCOperand::createImm(Hint));
1486
1487 return MCDisassembler::Success;
1488}
1489
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001490static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1491 unsigned Insn,
1492 uint64_t Address,
1493 const void *Decoder) {
1494 int Offset = SignExtend32<9>(Insn >> 7);
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001495 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1496 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1497
1498 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1499
Jim Grosbache9119e42015-05-13 18:37:00 +00001500 Inst.addOperand(MCOperand::createReg(Base));
1501 Inst.addOperand(MCOperand::createImm(Offset));
1502 Inst.addOperand(MCOperand::createImm(Hint));
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001503
1504 return MCDisassembler::Success;
1505}
1506
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +00001507static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
1508 unsigned Insn,
1509 uint64_t Address,
1510 const void *Decoder) {
1511 int Offset = SignExtend32<9>(Insn & 0x1ff);
1512 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1513 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1514
1515 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1516 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1517
1518 Inst.addOperand(MCOperand::createReg(Reg));
1519 Inst.addOperand(MCOperand::createReg(Base));
1520 Inst.addOperand(MCOperand::createImm(Offset));
1521
1522 return MCDisassembler::Success;
1523}
1524
Daniel Sandersb4484d62014-11-27 17:28:10 +00001525static DecodeStatus DecodeSyncI(MCInst &Inst,
1526 unsigned Insn,
1527 uint64_t Address,
1528 const void *Decoder) {
1529 int Offset = SignExtend32<16>(Insn & 0xffff);
1530 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1531
1532 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1533
Jim Grosbache9119e42015-05-13 18:37:00 +00001534 Inst.addOperand(MCOperand::createReg(Base));
1535 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sandersb4484d62014-11-27 17:28:10 +00001536
1537 return MCDisassembler::Success;
1538}
1539
Hrvoje Varga18148672015-10-28 11:04:29 +00001540static DecodeStatus DecodeSynciR6(MCInst &Inst,
1541 unsigned Insn,
1542 uint64_t Address,
1543 const void *Decoder) {
1544 int Immediate = SignExtend32<16>(Insn & 0xffff);
1545 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1546
1547 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1548
1549 Inst.addOperand(MCOperand::createReg(Base));
1550 Inst.addOperand(MCOperand::createImm(Immediate));
1551
1552 return MCDisassembler::Success;
1553}
1554
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001555static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1556 uint64_t Address, const void *Decoder) {
1557 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1558 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1559 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1560
1561 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1562 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1563
Jim Grosbache9119e42015-05-13 18:37:00 +00001564 Inst.addOperand(MCOperand::createReg(Reg));
1565 Inst.addOperand(MCOperand::createReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001566
1567 // The immediate field of an LD/ST instruction is scaled which means it must
1568 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1569 // data format.
1570 // .b - 1 byte
1571 // .h - 2 bytes
1572 // .w - 4 bytes
1573 // .d - 8 bytes
1574 switch(Inst.getOpcode())
1575 {
1576 default:
1577 assert (0 && "Unexpected instruction");
1578 return MCDisassembler::Fail;
1579 break;
1580 case Mips::LD_B:
1581 case Mips::ST_B:
Jim Grosbache9119e42015-05-13 18:37:00 +00001582 Inst.addOperand(MCOperand::createImm(Offset));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001583 break;
1584 case Mips::LD_H:
1585 case Mips::ST_H:
Jim Grosbache9119e42015-05-13 18:37:00 +00001586 Inst.addOperand(MCOperand::createImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001587 break;
1588 case Mips::LD_W:
1589 case Mips::ST_W:
Jim Grosbache9119e42015-05-13 18:37:00 +00001590 Inst.addOperand(MCOperand::createImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001591 break;
1592 case Mips::LD_D:
1593 case Mips::ST_D:
Jim Grosbache9119e42015-05-13 18:37:00 +00001594 Inst.addOperand(MCOperand::createImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001595 break;
1596 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001597
1598 return MCDisassembler::Success;
1599}
1600
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001601static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1602 unsigned Insn,
1603 uint64_t Address,
1604 const void *Decoder) {
1605 unsigned Offset = Insn & 0xf;
1606 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1607 unsigned Base = fieldFromInstruction(Insn, 4, 3);
1608
1609 switch (Inst.getOpcode()) {
1610 case Mips::LBU16_MM:
1611 case Mips::LHU16_MM:
1612 case Mips::LW16_MM:
1613 if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1614 == MCDisassembler::Fail)
1615 return MCDisassembler::Fail;
1616 break;
1617 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001618 case Mips::SB16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001619 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001620 case Mips::SH16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001621 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001622 case Mips::SW16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001623 if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1624 == MCDisassembler::Fail)
1625 return MCDisassembler::Fail;
1626 break;
1627 }
1628
1629 if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1630 == MCDisassembler::Fail)
1631 return MCDisassembler::Fail;
1632
1633 switch (Inst.getOpcode()) {
1634 case Mips::LBU16_MM:
1635 if (Offset == 0xf)
Jim Grosbache9119e42015-05-13 18:37:00 +00001636 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001637 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001638 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001639 break;
1640 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001641 case Mips::SB16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001642 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001643 break;
1644 case Mips::LHU16_MM:
1645 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001646 case Mips::SH16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001647 Inst.addOperand(MCOperand::createImm(Offset << 1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001648 break;
1649 case Mips::LW16_MM:
1650 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001651 case Mips::SW16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001652 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001653 break;
1654 }
1655
1656 return MCDisassembler::Success;
1657}
1658
Jozef Kolek12c69822014-12-23 16:16:33 +00001659static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1660 unsigned Insn,
1661 uint64_t Address,
1662 const void *Decoder) {
1663 unsigned Offset = Insn & 0x1F;
1664 unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1665
1666 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1667
Jim Grosbache9119e42015-05-13 18:37:00 +00001668 Inst.addOperand(MCOperand::createReg(Reg));
1669 Inst.addOperand(MCOperand::createReg(Mips::SP));
1670 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek12c69822014-12-23 16:16:33 +00001671
1672 return MCDisassembler::Success;
1673}
1674
Jozef Koleke10a02e2015-01-28 17:27:26 +00001675static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1676 unsigned Insn,
1677 uint64_t Address,
1678 const void *Decoder) {
1679 unsigned Offset = Insn & 0x7F;
1680 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1681
1682 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1683
Jim Grosbache9119e42015-05-13 18:37:00 +00001684 Inst.addOperand(MCOperand::createReg(Reg));
1685 Inst.addOperand(MCOperand::createReg(Mips::GP));
1686 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Koleke10a02e2015-01-28 17:27:26 +00001687
1688 return MCDisassembler::Success;
1689}
1690
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001691static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1692 unsigned Insn,
1693 uint64_t Address,
1694 const void *Decoder) {
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001695 int Offset;
1696 switch (Inst.getOpcode()) {
1697 case Mips::LWM16_MMR6:
1698 case Mips::SWM16_MMR6:
1699 Offset = fieldFromInstruction(Insn, 4, 4);
1700 break;
1701 default:
1702 Offset = SignExtend32<4>(Insn & 0xf);
1703 break;
1704 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001705
1706 if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1707 == MCDisassembler::Fail)
1708 return MCDisassembler::Fail;
1709
Jim Grosbache9119e42015-05-13 18:37:00 +00001710 Inst.addOperand(MCOperand::createReg(Mips::SP));
1711 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001712
1713 return MCDisassembler::Success;
1714}
1715
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001716static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1717 unsigned Insn,
1718 uint64_t Address,
1719 const void *Decoder) {
1720 int Offset = SignExtend32<9>(Insn & 0x1ff);
1721 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1722 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1723
1724 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1725 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1726
Hrvoje Varga3ef4dd72015-10-15 08:11:50 +00001727 if (Inst.getOpcode() == Mips::SCE_MM)
1728 Inst.addOperand(MCOperand::createReg(Reg));
1729
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001730 Inst.addOperand(MCOperand::createReg(Reg));
1731 Inst.addOperand(MCOperand::createReg(Base));
1732 Inst.addOperand(MCOperand::createImm(Offset));
1733
1734 return MCDisassembler::Success;
1735}
1736
Vladimir Medicdde3d582013-09-06 12:30:36 +00001737static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1738 unsigned Insn,
1739 uint64_t Address,
1740 const void *Decoder) {
1741 int Offset = SignExtend32<12>(Insn & 0x0fff);
1742 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1743 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1744
1745 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1746 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1747
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001748 switch (Inst.getOpcode()) {
1749 case Mips::SWM32_MM:
1750 case Mips::LWM32_MM:
1751 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1752 == MCDisassembler::Fail)
1753 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001754 Inst.addOperand(MCOperand::createReg(Base));
1755 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001756 break;
1757 case Mips::SC_MM:
Jim Grosbache9119e42015-05-13 18:37:00 +00001758 Inst.addOperand(MCOperand::createReg(Reg));
Justin Bognerb03fd122016-08-17 05:10:15 +00001759 LLVM_FALLTHROUGH;
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001760 default:
Jim Grosbache9119e42015-05-13 18:37:00 +00001761 Inst.addOperand(MCOperand::createReg(Reg));
Zlatko Buljanba553a62016-05-09 08:07:28 +00001762 if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1763 Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
Jim Grosbache9119e42015-05-13 18:37:00 +00001764 Inst.addOperand(MCOperand::createReg(Reg+1));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001765
Jim Grosbache9119e42015-05-13 18:37:00 +00001766 Inst.addOperand(MCOperand::createReg(Base));
1767 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001768 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001769
1770 return MCDisassembler::Success;
1771}
1772
1773static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1774 unsigned Insn,
1775 uint64_t Address,
1776 const void *Decoder) {
1777 int Offset = SignExtend32<16>(Insn & 0xffff);
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
Jim Grosbache9119e42015-05-13 18:37:00 +00001784 Inst.addOperand(MCOperand::createReg(Reg));
1785 Inst.addOperand(MCOperand::createReg(Base));
1786 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medicdde3d582013-09-06 12:30:36 +00001787
1788 return MCDisassembler::Success;
1789}
1790
Akira Hatanaka71928e62012-04-17 18:03:21 +00001791static DecodeStatus DecodeFMem(MCInst &Inst,
1792 unsigned Insn,
1793 uint64_t Address,
1794 const void *Decoder) {
1795 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001796 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1797 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001798
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001799 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001800 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001801
Jim Grosbache9119e42015-05-13 18:37:00 +00001802 Inst.addOperand(MCOperand::createReg(Reg));
1803 Inst.addOperand(MCOperand::createReg(Base));
1804 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001805
1806 return MCDisassembler::Success;
1807}
1808
Zlatko Buljancba9f802016-07-11 07:41:56 +00001809static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1810 uint64_t Address, const void *Decoder) {
1811 // This function is the same as DecodeFMem but with the Reg and Base fields
1812 // swapped according to microMIPS spec.
1813 int Offset = SignExtend32<16>(Insn & 0xffff);
1814 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1815 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1816
1817 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1818 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1819
1820 Inst.addOperand(MCOperand::createReg(Reg));
1821 Inst.addOperand(MCOperand::createReg(Base));
1822 Inst.addOperand(MCOperand::createImm(Offset));
1823
1824 return MCDisassembler::Success;
1825}
1826
Daniel Sanders92db6b72014-10-01 08:26:55 +00001827static DecodeStatus DecodeFMem2(MCInst &Inst,
1828 unsigned Insn,
1829 uint64_t Address,
1830 const void *Decoder) {
1831 int Offset = SignExtend32<16>(Insn & 0xffff);
1832 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1833 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1834
1835 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1836 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1837
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));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001841
1842 return MCDisassembler::Success;
1843}
1844
1845static DecodeStatus DecodeFMem3(MCInst &Inst,
1846 unsigned Insn,
1847 uint64_t Address,
1848 const void *Decoder) {
1849 int Offset = SignExtend32<16>(Insn & 0xffff);
1850 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1851 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1852
1853 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1854 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1855
Jim Grosbache9119e42015-05-13 18:37:00 +00001856 Inst.addOperand(MCOperand::createReg(Reg));
1857 Inst.addOperand(MCOperand::createReg(Base));
1858 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001859
1860 return MCDisassembler::Success;
1861}
1862
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001863static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1864 unsigned Insn,
1865 uint64_t Address,
1866 const void *Decoder) {
1867 int Offset = SignExtend32<11>(Insn & 0x07ff);
1868 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1869 unsigned Base = fieldFromInstruction(Insn, 11, 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));
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001877
1878 return MCDisassembler::Success;
1879}
Zlatko Buljancba9f802016-07-11 07:41:56 +00001880
1881static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1882 uint64_t Address, const void *Decoder) {
1883 int Offset = SignExtend32<11>(Insn & 0x07ff);
1884 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1885 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1886
1887 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1888 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1889
1890 Inst.addOperand(MCOperand::createReg(Reg));
1891 Inst.addOperand(MCOperand::createReg(Base));
1892 Inst.addOperand(MCOperand::createImm(Offset));
1893
1894 return MCDisassembler::Success;
1895}
1896
Daniel Sanders6a803f62014-06-16 13:13:03 +00001897static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1898 unsigned Insn,
1899 uint64_t Address,
1900 const void *Decoder) {
1901 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1902 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1903 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1904
1905 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1906 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1907
1908 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
Jim Grosbache9119e42015-05-13 18:37:00 +00001909 Inst.addOperand(MCOperand::createReg(Rt));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001910 }
1911
Jim Grosbache9119e42015-05-13 18:37:00 +00001912 Inst.addOperand(MCOperand::createReg(Rt));
1913 Inst.addOperand(MCOperand::createReg(Base));
1914 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001915
1916 return MCDisassembler::Success;
1917}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001918
1919static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1920 unsigned RegNo,
1921 uint64_t Address,
1922 const void *Decoder) {
1923 // Currently only hardware register 29 is supported.
1924 if (RegNo != 29)
1925 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001926 Inst.addOperand(MCOperand::createReg(Mips::HWR29));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001927 return MCDisassembler::Success;
1928}
1929
Akira Hatanaka71928e62012-04-17 18:03:21 +00001930static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1931 unsigned RegNo,
1932 uint64_t Address,
1933 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001934 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001935 return MCDisassembler::Fail;
1936
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001937 ;
1938 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
Jim Grosbache9119e42015-05-13 18:37:00 +00001939 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001940 return MCDisassembler::Success;
1941}
1942
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001943static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1944 unsigned RegNo,
1945 uint64_t Address,
1946 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001947 if (RegNo >= 4)
1948 return MCDisassembler::Fail;
1949
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001950 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001951 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001952 return MCDisassembler::Success;
1953}
1954
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001955static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1956 unsigned RegNo,
1957 uint64_t Address,
1958 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001959 if (RegNo >= 4)
1960 return MCDisassembler::Fail;
1961
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001962 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001963 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001964 return MCDisassembler::Success;
1965}
1966
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001967static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
1968 unsigned RegNo,
1969 uint64_t Address,
1970 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001971 if (RegNo >= 4)
1972 return MCDisassembler::Fail;
1973
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001974 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001975 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001976 return MCDisassembler::Success;
1977}
1978
Jack Carter3eb663b2013-09-26 00:09:46 +00001979static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1980 unsigned RegNo,
1981 uint64_t Address,
1982 const void *Decoder) {
1983 if (RegNo > 31)
1984 return MCDisassembler::Fail;
1985
1986 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001987 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter3eb663b2013-09-26 00:09:46 +00001988 return MCDisassembler::Success;
1989}
1990
Jack Carter5dc8ac92013-09-25 23:50:44 +00001991static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1992 unsigned RegNo,
1993 uint64_t Address,
1994 const void *Decoder) {
1995 if (RegNo > 31)
1996 return MCDisassembler::Fail;
1997
1998 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001999 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002000 return MCDisassembler::Success;
2001}
2002
2003static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
2004 unsigned RegNo,
2005 uint64_t Address,
2006 const void *Decoder) {
2007 if (RegNo > 31)
2008 return MCDisassembler::Fail;
2009
2010 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002011 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002012 return MCDisassembler::Success;
2013}
2014
2015static DecodeStatus DecodeMSA128DRegisterClass(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::MSA128DRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002023 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002024 return MCDisassembler::Success;
2025}
2026
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002027static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
2028 unsigned RegNo,
2029 uint64_t Address,
2030 const void *Decoder) {
2031 if (RegNo > 7)
2032 return MCDisassembler::Fail;
2033
2034 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002035 Inst.addOperand(MCOperand::createReg(Reg));
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002036 return MCDisassembler::Success;
2037}
2038
Daniel Sandersa3134fa2015-06-27 15:39:19 +00002039static DecodeStatus DecodeCOP0RegisterClass(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::COP0RegClassID, RegNo);
2047 Inst.addOperand(MCOperand::createReg(Reg));
2048 return MCDisassembler::Success;
2049}
2050
Daniel Sanders2a83d682014-05-21 12:56:39 +00002051static DecodeStatus DecodeCOP2RegisterClass(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::COP2RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002059 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders2a83d682014-05-21 12:56:39 +00002060 return MCDisassembler::Success;
2061}
2062
Akira Hatanaka71928e62012-04-17 18:03:21 +00002063static DecodeStatus DecodeBranchTarget(MCInst &Inst,
2064 unsigned Offset,
2065 uint64_t Address,
2066 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00002067 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00002068 Inst.addOperand(MCOperand::createImm(BranchOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002069 return MCDisassembler::Success;
2070}
2071
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +00002072static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
2073 unsigned Offset,
2074 uint64_t Address,
2075 const void *Decoder) {
2076 int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
2077 Inst.addOperand(MCOperand::createImm(BranchOffset));
2078 return MCDisassembler::Success;
2079}
2080
Akira Hatanaka71928e62012-04-17 18:03:21 +00002081static DecodeStatus DecodeJumpTarget(MCInst &Inst,
2082 unsigned Insn,
2083 uint64_t Address,
2084 const void *Decoder) {
2085
Jim Grosbachecaef492012-08-14 19:06:05 +00002086 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00002087 Inst.addOperand(MCOperand::createImm(JumpOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002088 return MCDisassembler::Success;
2089}
2090
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002091static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2092 unsigned Offset,
2093 uint64_t Address,
2094 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00002095 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002096
Jim Grosbache9119e42015-05-13 18:37:00 +00002097 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002098 return MCDisassembler::Success;
2099}
2100
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00002101static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
2102 unsigned Offset,
2103 uint64_t Address,
2104 const void *Decoder) {
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002105 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00002106
2107 Inst.addOperand(MCOperand::createImm(BranchOffset));
2108 return MCDisassembler::Success;
2109}
2110
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002111static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2112 unsigned Offset,
2113 uint64_t Address,
2114 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00002115 int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002116
Jim Grosbache9119e42015-05-13 18:37:00 +00002117 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002118 return MCDisassembler::Success;
2119}
2120
Jozef Kolek9761e962015-01-12 12:03:34 +00002121static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2122 unsigned Offset,
2123 uint64_t Address,
2124 const void *Decoder) {
2125 int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002126 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek9761e962015-01-12 12:03:34 +00002127 return MCDisassembler::Success;
2128}
2129
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002130static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2131 unsigned Offset,
2132 uint64_t Address,
2133 const void *Decoder) {
2134 int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002135 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002136 return MCDisassembler::Success;
2137}
2138
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002139static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2140 unsigned Offset,
2141 uint64_t Address,
2142 const void *Decoder) {
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002143 int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00002144 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002145 return MCDisassembler::Success;
2146}
2147
Zoran Jovanovica887b362015-11-30 12:56:18 +00002148static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2149 unsigned Offset,
2150 uint64_t Address,
2151 const void *Decoder) {
2152 int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
2153
2154 Inst.addOperand(MCOperand::createImm(BranchOffset));
2155 return MCDisassembler::Success;
2156}
2157
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002158static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2159 unsigned Insn,
2160 uint64_t Address,
2161 const void *Decoder) {
2162 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002163 Inst.addOperand(MCOperand::createImm(JumpOffset));
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002164 return MCDisassembler::Success;
2165}
Akira Hatanaka71928e62012-04-17 18:03:21 +00002166
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002167static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2168 unsigned Value,
2169 uint64_t Address,
2170 const void *Decoder) {
2171 if (Value == 0)
Jim Grosbache9119e42015-05-13 18:37:00 +00002172 Inst.addOperand(MCOperand::createImm(1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002173 else if (Value == 0x7)
Jim Grosbache9119e42015-05-13 18:37:00 +00002174 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002175 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002176 Inst.addOperand(MCOperand::createImm(Value << 2));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002177 return MCDisassembler::Success;
2178}
2179
Daniel Sanders97297772016-03-22 14:40:00 +00002180static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002181 unsigned Value,
2182 uint64_t Address,
2183 const void *Decoder) {
2184 if (Value == 0x7F)
Jim Grosbache9119e42015-05-13 18:37:00 +00002185 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002186 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002187 Inst.addOperand(MCOperand::createImm(Value));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002188 return MCDisassembler::Success;
2189}
2190
Zoran Jovanovic6b28f092015-09-09 13:55:45 +00002191static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
2192 unsigned Value,
2193 uint64_t Address,
2194 const void *Decoder) {
2195 Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
2196 return MCDisassembler::Success;
2197}
2198
Daniel Sanders19b7f762016-03-14 11:16:56 +00002199template <unsigned Bits, int Offset, int Scale>
2200static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2201 uint64_t Address,
2202 const void *Decoder) {
Daniel Sandersea4f6532015-11-06 12:22:31 +00002203 Value &= ((1 << Bits) - 1);
Daniel Sanders19b7f762016-03-14 11:16:56 +00002204 Value *= Scale;
Daniel Sandersea4f6532015-11-06 12:22:31 +00002205 Inst.addOperand(MCOperand::createImm(Value + Offset));
Matheus Almeida779c5932013-11-18 12:32:49 +00002206 return MCDisassembler::Success;
2207}
2208
Daniel Sanders97297772016-03-22 14:40:00 +00002209template <unsigned Bits, int Offset, int ScaleBy>
2210static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2211 uint64_t Address,
2212 const void *Decoder) {
2213 int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
Daniel Sanders78e89022016-03-11 11:37:50 +00002214 Inst.addOperand(MCOperand::createImm(Imm + Offset));
2215 return MCDisassembler::Success;
2216}
2217
Akira Hatanaka71928e62012-04-17 18:03:21 +00002218static DecodeStatus DecodeInsSize(MCInst &Inst,
2219 unsigned Insn,
2220 uint64_t Address,
2221 const void *Decoder) {
2222 // First we need to grab the pos(lsb) from MCInst.
2223 int Pos = Inst.getOperand(2).getImm();
2224 int Size = (int) Insn - Pos + 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002225 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002226 return MCDisassembler::Success;
2227}
2228
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002229static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2230 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002231 Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002232 return MCDisassembler::Success;
2233}
Zoran Jovanovic28551422014-06-09 09:49:51 +00002234
2235static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2236 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002237 Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00002238 return MCDisassembler::Success;
2239}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002240
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002241static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2242 uint64_t Address, const void *Decoder) {
2243 int32_t DecodedValue;
2244 switch (Insn) {
2245 case 0: DecodedValue = 256; break;
2246 case 1: DecodedValue = 257; break;
2247 case 510: DecodedValue = -258; break;
2248 case 511: DecodedValue = -257; break;
2249 default: DecodedValue = SignExtend32<9>(Insn); break;
2250 }
Jim Grosbache9119e42015-05-13 18:37:00 +00002251 Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002252 return MCDisassembler::Success;
2253}
2254
2255static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2256 uint64_t Address, const void *Decoder) {
2257 // Insn must be >= 0, since it is unsigned that condition is always true.
2258 assert(Insn < 16);
2259 int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2260 255, 32768, 65535};
Jim Grosbache9119e42015-05-13 18:37:00 +00002261 Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002262 return MCDisassembler::Success;
2263}
2264
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002265static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2266 unsigned Insn,
2267 uint64_t Address,
2268 const void *Decoder) {
2269 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
Zoran Jovanovicdc4b8c22015-09-15 15:21:27 +00002270 Mips::S6, Mips::S7, Mips::FP};
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002271 unsigned RegNum;
2272
2273 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002274
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002275 // Empty register lists are not allowed.
2276 if (RegLst == 0)
2277 return MCDisassembler::Fail;
2278
2279 RegNum = RegLst & 0xf;
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002280
2281 // RegLst values 10-15, and 26-31 are reserved.
2282 if (RegNum > 9)
2283 return MCDisassembler::Fail;
2284
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002285 for (unsigned i = 0; i < RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002286 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002287
2288 if (RegLst & 0x10)
Jim Grosbache9119e42015-05-13 18:37:00 +00002289 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002290
2291 return MCDisassembler::Success;
2292}
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002293
2294static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2295 uint64_t Address,
2296 const void *Decoder) {
2297 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00002298 unsigned RegLst;
2299 switch(Inst.getOpcode()) {
2300 default:
2301 RegLst = fieldFromInstruction(Insn, 4, 2);
2302 break;
2303 case Mips::LWM16_MMR6:
2304 case Mips::SWM16_MMR6:
2305 RegLst = fieldFromInstruction(Insn, 8, 2);
2306 break;
2307 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002308 unsigned RegNum = RegLst & 0x3;
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002309
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002310 for (unsigned i = 0; i <= RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002311 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002312
Jim Grosbache9119e42015-05-13 18:37:00 +00002313 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002314
2315 return MCDisassembler::Success;
2316}
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002317
Zoran Jovanovic41688672015-02-10 16:36:20 +00002318static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
2319 uint64_t Address, const void *Decoder) {
2320
2321 unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2322
2323 switch (RegPair) {
2324 default:
2325 return MCDisassembler::Fail;
2326 case 0:
Jim Grosbache9119e42015-05-13 18:37:00 +00002327 Inst.addOperand(MCOperand::createReg(Mips::A1));
2328 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002329 break;
2330 case 1:
Jim Grosbache9119e42015-05-13 18:37:00 +00002331 Inst.addOperand(MCOperand::createReg(Mips::A1));
2332 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002333 break;
2334 case 2:
Jim Grosbache9119e42015-05-13 18:37:00 +00002335 Inst.addOperand(MCOperand::createReg(Mips::A2));
2336 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002337 break;
2338 case 3:
Jim Grosbache9119e42015-05-13 18:37:00 +00002339 Inst.addOperand(MCOperand::createReg(Mips::A0));
2340 Inst.addOperand(MCOperand::createReg(Mips::S5));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002341 break;
2342 case 4:
Jim Grosbache9119e42015-05-13 18:37:00 +00002343 Inst.addOperand(MCOperand::createReg(Mips::A0));
2344 Inst.addOperand(MCOperand::createReg(Mips::S6));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002345 break;
2346 case 5:
Jim Grosbache9119e42015-05-13 18:37:00 +00002347 Inst.addOperand(MCOperand::createReg(Mips::A0));
2348 Inst.addOperand(MCOperand::createReg(Mips::A1));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002349 break;
2350 case 6:
Jim Grosbache9119e42015-05-13 18:37:00 +00002351 Inst.addOperand(MCOperand::createReg(Mips::A0));
2352 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002353 break;
2354 case 7:
Jim Grosbache9119e42015-05-13 18:37:00 +00002355 Inst.addOperand(MCOperand::createReg(Mips::A0));
2356 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002357 break;
2358 }
2359
2360 return MCDisassembler::Success;
2361}
2362
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002363static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2364 uint64_t Address, const void *Decoder) {
Justin Bogner6499b5f2015-06-23 07:28:57 +00002365 Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002366 return MCDisassembler::Success;
2367}
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002368
2369template <typename InsnType>
2370static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2371 uint64_t Address,
2372 const void *Decoder) {
2373 // We have:
2374 // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
2375 // Invalid if rt == 0
2376 // BGTZALC_MMR6 if rs == 0 && rt != 0
2377 // BLTZALC_MMR6 if rs != 0 && rs == rt
2378 // BLTUC_MMR6 if rs != 0 && rs != rt
2379
2380 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2381 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002382 InsnType Imm = 0;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002383 bool HasRs = false;
2384 bool HasRt = false;
2385
2386 if (Rt == 0)
2387 return MCDisassembler::Fail;
2388 else if (Rs == 0) {
2389 MI.setOpcode(Mips::BGTZALC_MMR6);
2390 HasRt = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002391 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002392 }
2393 else if (Rs == Rt) {
2394 MI.setOpcode(Mips::BLTZALC_MMR6);
2395 HasRs = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002396 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002397 }
2398 else {
2399 MI.setOpcode(Mips::BLTUC_MMR6);
2400 HasRs = true;
2401 HasRt = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002402 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002403 }
2404
2405 if (HasRs)
2406 MI.addOperand(
2407 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2408
2409 if (HasRt)
2410 MI.addOperand(
2411 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2412
2413 MI.addOperand(MCOperand::createImm(Imm));
2414
2415 return MCDisassembler::Success;
2416}
2417
2418template <typename InsnType>
2419static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2420 uint64_t Address,
2421 const void *Decoder) {
2422 // We have:
2423 // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002424 // Invalid if rt == 0
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002425 // BLEZALC_MMR6 if rs == 0 && rt != 0
2426 // BGEZALC_MMR6 if rs == rt && rt != 0
2427 // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
2428
2429 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2430 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002431 InsnType Imm = 0;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002432 bool HasRs = false;
2433
2434 if (Rt == 0)
2435 return MCDisassembler::Fail;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002436 else if (Rs == 0) {
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002437 MI.setOpcode(Mips::BLEZALC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002438 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2439 }
2440 else if (Rs == Rt) {
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002441 MI.setOpcode(Mips::BGEZALC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002442 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2443 }
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002444 else {
2445 HasRs = true;
2446 MI.setOpcode(Mips::BGEUC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002447 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002448 }
2449
2450 if (HasRs)
2451 MI.addOperand(
2452 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2453 MI.addOperand(
2454 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2455
2456 MI.addOperand(MCOperand::createImm(Imm));
2457
2458 return MCDisassembler::Success;
2459}