blob: f8ac809343f84d4742333c7bdd96bc7f11e83bc7 [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
Michael Kupersteindb0712f2015-05-26 10:47:10 +000042 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
43 bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
Daniel Sandersc171f652014-06-13 13:15:59 +000044 bool hasMips32r6() const {
Michael Kupersteindb0712f2015-05-26 10:47:10 +000045 return STI.getFeatureBits()[Mips::FeatureMips32r6];
Daniel Sanders5c582b22014-05-22 11:23:21 +000046 }
Zlatko Buljan6221be82016-03-31 08:51:24 +000047 bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
Daniel Sanders5c582b22014-05-22 11:23:21 +000048
Michael Kupersteindb0712f2015-05-26 10:47:10 +000049 bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
Daniel Sanders0fa60412014-06-12 13:39:06 +000050
Kai Nacke3adf9b82015-05-28 16:23:16 +000051 bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
52
Daniel Sandersc171f652014-06-13 13:15:59 +000053 bool hasCOP3() const {
54 // Only present in MIPS-I and MIPS-II
55 return !hasMips32() && !hasMips3();
56 }
57
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000058 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000059 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000060 raw_ostream &VStream,
61 raw_ostream &CStream) const override;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000062};
63
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000064} // end anonymous namespace
65
Akira Hatanaka71928e62012-04-17 18:03:21 +000066// Forward declare these because the autogenerated code will reference them.
67// Definitions are further down.
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000068static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
69 unsigned RegNo,
70 uint64_t Address,
71 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +000072
Reed Kotlerec8a5492013-02-14 03:05:25 +000073static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
74 unsigned RegNo,
75 uint64_t Address,
76 const void *Decoder);
77
Zoran Jovanovicb0852e52014-10-21 08:23:11 +000078static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
79 unsigned RegNo,
80 uint64_t Address,
81 const void *Decoder);
82
Jozef Kolek1904fa22014-11-24 14:25:53 +000083static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
84 unsigned RegNo,
85 uint64_t Address,
86 const void *Decoder);
87
Zoran Jovanovic41688672015-02-10 16:36:20 +000088static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
89 unsigned RegNo,
90 uint64_t Address,
91 const void *Decoder);
92
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000093static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
94 unsigned RegNo,
95 uint64_t Address,
96 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +000097
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000098static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
99 unsigned Insn,
100 uint64_t Address,
101 const void *Decoder);
102
Akira Hatanaka654655f2013-08-14 00:53:38 +0000103static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
104 unsigned RegNo,
105 uint64_t Address,
106 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000107
Akira Hatanaka71928e62012-04-17 18:03:21 +0000108static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
109 unsigned RegNo,
110 uint64_t Address,
111 const void *Decoder);
112
113static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
114 unsigned RegNo,
115 uint64_t Address,
116 const void *Decoder);
117
118static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
119 unsigned RegNo,
120 uint64_t Address,
121 const void *Decoder);
122
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000123static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
124 unsigned RegNo,
125 uint64_t Address,
126 const void *Decoder);
127
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +0000128static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
129 uint64_t Address,
130 const void *Decoder);
Daniel Sanders0fa60412014-06-12 13:39:06 +0000131
Akira Hatanaka71928e62012-04-17 18:03:21 +0000132static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
133 unsigned Insn,
134 uint64_t Address,
135 const void *Decoder);
136
137static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
138 unsigned RegNo,
139 uint64_t Address,
140 const void *Decoder);
141
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000142static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
143 unsigned RegNo,
144 uint64_t Address,
145 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000146
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000147static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
148 unsigned RegNo,
149 uint64_t Address,
150 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000151
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000152static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
153 unsigned RegNo,
154 uint64_t Address,
155 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000156
Jack Carter3eb663b2013-09-26 00:09:46 +0000157static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
158 unsigned RegNo,
159 uint64_t Address,
160 const void *Decoder);
161
Jack Carter5dc8ac92013-09-25 23:50:44 +0000162static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
163 unsigned RegNo,
164 uint64_t Address,
165 const void *Decoder);
166
167static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
168 unsigned RegNo,
169 uint64_t Address,
170 const void *Decoder);
171
172static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
173 unsigned RegNo,
174 uint64_t Address,
175 const void *Decoder);
176
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000177static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
178 unsigned RegNo,
179 uint64_t Address,
180 const void *Decoder);
181
Daniel Sandersa3134fa2015-06-27 15:39:19 +0000182static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
183 unsigned RegNo,
184 uint64_t Address,
185 const void *Decoder);
186
Daniel Sanders2a83d682014-05-21 12:56:39 +0000187static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
188 unsigned RegNo,
189 uint64_t Address,
190 const void *Decoder);
191
Akira Hatanaka71928e62012-04-17 18:03:21 +0000192static DecodeStatus DecodeBranchTarget(MCInst &Inst,
193 unsigned Offset,
194 uint64_t Address,
195 const void *Decoder);
196
Akira Hatanaka71928e62012-04-17 18:03:21 +0000197static DecodeStatus DecodeJumpTarget(MCInst &Inst,
198 unsigned Insn,
199 uint64_t Address,
200 const void *Decoder);
201
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000202static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
203 unsigned Offset,
204 uint64_t Address,
205 const void *Decoder);
206
207static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
208 unsigned Offset,
209 uint64_t Address,
210 const void *Decoder);
211
Jozef Kolek9761e962015-01-12 12:03:34 +0000212// DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
213// shifted left by 1 bit.
214static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
215 unsigned Offset,
216 uint64_t Address,
217 const void *Decoder);
218
Jozef Kolek5cfebdd2015-01-21 12:39:30 +0000219// DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
220// shifted left by 1 bit.
221static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
222 unsigned Offset,
223 uint64_t Address,
224 const void *Decoder);
225
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000226// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
227// shifted left by 1 bit.
228static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
229 unsigned Offset,
230 uint64_t Address,
231 const void *Decoder);
232
Zoran Jovanovica887b362015-11-30 12:56:18 +0000233// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
234// shifted left by 1 bit.
235static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
236 unsigned Offset,
237 uint64_t Address,
238 const void *Decoder);
239
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000240// DecodeJumpTargetMM - Decode microMIPS jump target, which is
241// shifted left by 1 bit.
242static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
243 unsigned Insn,
244 uint64_t Address,
245 const void *Decoder);
246
Akira Hatanaka71928e62012-04-17 18:03:21 +0000247static DecodeStatus DecodeMem(MCInst &Inst,
248 unsigned Insn,
249 uint64_t Address,
250 const void *Decoder);
251
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000252static DecodeStatus DecodeMemEVA(MCInst &Inst,
253 unsigned Insn,
254 uint64_t Address,
255 const void *Decoder);
256
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +0000257static DecodeStatus DecodeLoadByte9(MCInst &Inst,
258 unsigned Insn,
259 uint64_t Address,
260 const void *Decoder);
261
262static DecodeStatus DecodeLoadByte15(MCInst &Inst,
263 unsigned Insn,
264 uint64_t Address,
265 const void *Decoder);
266
Daniel Sanders92db6b72014-10-01 08:26:55 +0000267static DecodeStatus DecodeCacheOp(MCInst &Inst,
268 unsigned Insn,
269 uint64_t Address,
270 const void *Decoder);
271
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000272static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
273 unsigned Insn,
274 uint64_t Address,
275 const void *Decoder);
Vladimir Medicdf464ae2015-01-29 11:33:41 +0000276
Jozef Kolekab6d1cc2014-12-23 19:55:34 +0000277static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
278 unsigned Insn,
279 uint64_t Address,
280 const void *Decoder);
281
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +0000282static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
283 unsigned Insn,
284 uint64_t Address,
285 const void *Decoder);
286
Zoran Jovanovicd9790792015-09-09 09:10:46 +0000287static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
288 unsigned Insn,
289 uint64_t Address,
290 const void *Decoder);
291
Daniel Sandersb4484d62014-11-27 17:28:10 +0000292static DecodeStatus DecodeSyncI(MCInst &Inst,
293 unsigned Insn,
294 uint64_t Address,
295 const void *Decoder);
296
Hrvoje Varga18148672015-10-28 11:04:29 +0000297static DecodeStatus DecodeSynciR6(MCInst &Inst,
298 unsigned Insn,
299 uint64_t Address,
300 const void *Decoder);
301
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000302static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
303 uint64_t Address, const void *Decoder);
304
Jozef Kolek315e7ec2014-11-26 18:56:38 +0000305static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
306 unsigned Insn,
307 uint64_t Address,
308 const void *Decoder);
309
Jozef Kolek12c69822014-12-23 16:16:33 +0000310static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
311 unsigned Insn,
312 uint64_t Address,
313 const void *Decoder);
314
Jozef Koleke10a02e2015-01-28 17:27:26 +0000315static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
316 unsigned Insn,
317 uint64_t Address,
318 const void *Decoder);
319
Jozef Kolekd68d424a2015-02-10 12:41:13 +0000320static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
321 unsigned Insn,
322 uint64_t Address,
323 const void *Decoder);
324
Zoran Jovanovica6593ff2015-08-18 12:53:08 +0000325static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
326 unsigned Insn,
327 uint64_t Address,
328 const void *Decoder);
329
Vladimir Medicdde3d582013-09-06 12:30:36 +0000330static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
331 unsigned Insn,
332 uint64_t Address,
333 const void *Decoder);
334
335static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
336 unsigned Insn,
337 uint64_t Address,
338 const void *Decoder);
339
Akira Hatanaka71928e62012-04-17 18:03:21 +0000340static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
341 uint64_t Address,
342 const void *Decoder);
343
Hrvoje Varga117625a2016-04-20 06:34:48 +0000344static DecodeStatus DecodeFMemMMR6(MCInst &Inst, unsigned Insn,
345 uint64_t Address,
346 const void *Decoder);
347
Daniel Sanders92db6b72014-10-01 08:26:55 +0000348static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
349 uint64_t Address,
350 const void *Decoder);
351
352static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
353 uint64_t Address,
354 const void *Decoder);
355
Vladimir Medic435cf8a2015-01-21 10:47:36 +0000356static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
357 uint64_t Address,
358 const void *Decoder);
359
Hrvoje Varga117625a2016-04-20 06:34:48 +0000360static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
361 uint64_t Address,
362 const void *Decoder);
363
Daniel Sanders6a803f62014-06-16 13:13:03 +0000364static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
365 unsigned Insn,
366 uint64_t Address,
367 const void *Decoder);
368
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000369static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
370 unsigned Value,
371 uint64_t Address,
372 const void *Decoder);
373
Daniel Sanders97297772016-03-22 14:40:00 +0000374static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000375 unsigned Value,
376 uint64_t Address,
377 const void *Decoder);
378
Zoran Jovanovic6b28f092015-09-09 13:55:45 +0000379static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
380 unsigned Value,
381 uint64_t Address,
382 const void *Decoder);
383
Daniel Sanders19b7f762016-03-14 11:16:56 +0000384template <unsigned Bits, int Offset, int Scale>
385static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
386 uint64_t Address,
387 const void *Decoder);
388
Daniel Sandersea4f6532015-11-06 12:22:31 +0000389template <unsigned Bits, int Offset>
390static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
Daniel Sanders19b7f762016-03-14 11:16:56 +0000391 uint64_t Address,
392 const void *Decoder) {
393 return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
394 Decoder);
395}
Matheus Almeida779c5932013-11-18 12:32:49 +0000396
Daniel Sanders97297772016-03-22 14:40:00 +0000397template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
398static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
399 uint64_t Address,
400 const void *Decoder);
Daniel Sanders78e89022016-03-11 11:37:50 +0000401
Akira Hatanaka71928e62012-04-17 18:03:21 +0000402static DecodeStatus DecodeInsSize(MCInst &Inst,
403 unsigned Insn,
404 uint64_t Address,
405 const void *Decoder);
406
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000407static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
408 uint64_t Address, const void *Decoder);
409
Zoran Jovanovic28551422014-06-09 09:49:51 +0000410static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
411 uint64_t Address, const void *Decoder);
412
Vladimir Medicb682ddf2014-12-01 11:12:04 +0000413static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
414 uint64_t Address, const void *Decoder);
415
416static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
417 uint64_t Address, const void *Decoder);
418
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000419static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
420 uint64_t Address, const void *Decoder);
421
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000422/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
423/// handle.
424template <typename InsnType>
425static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
426 const void *Decoder);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000427
428template <typename InsnType>
429static DecodeStatus
430DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
431 const void *Decoder);
432
433template <typename InsnType>
434static DecodeStatus
435DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
436 const void *Decoder);
437
438template <typename InsnType>
439static DecodeStatus
440DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
441 const void *Decoder);
442
443template <typename InsnType>
444static DecodeStatus
445DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
446 const void *Decoder);
447
448template <typename InsnType>
449static DecodeStatus
450DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
451 const void *Decoder);
452
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000453template <typename InsnType>
454static DecodeStatus
455DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
456 const void *Decoder);
457
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +0000458template <typename InsnType>
459static DecodeStatus
460DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
461 const void *Decoder);
462
463template <typename InsnType>
464static DecodeStatus
465DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
466 const void *Decoder);
467
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000468static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
469 uint64_t Address,
470 const void *Decoder);
471
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000472static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
473 uint64_t Address,
474 const void *Decoder);
475
Zoran Jovanovic41688672015-02-10 16:36:20 +0000476static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
477 uint64_t Address,
478 const void *Decoder);
479
Akira Hatanaka71928e62012-04-17 18:03:21 +0000480namespace llvm {
481extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
482 TheMips64elTarget;
483}
484
485static MCDisassembler *createMipsDisassembler(
486 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000487 const MCSubtargetInfo &STI,
488 MCContext &Ctx) {
489 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000490}
491
492static MCDisassembler *createMipselDisassembler(
493 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000494 const MCSubtargetInfo &STI,
495 MCContext &Ctx) {
496 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000497}
498
Akira Hatanaka71928e62012-04-17 18:03:21 +0000499extern "C" void LLVMInitializeMipsDisassembler() {
500 // Register the disassembler.
501 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
502 createMipsDisassembler);
503 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
504 createMipselDisassembler);
505 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000506 createMipsDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000507 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000508 createMipselDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000509}
510
Akira Hatanaka71928e62012-04-17 18:03:21 +0000511#include "MipsGenDisassemblerTables.inc"
512
Daniel Sanders5c582b22014-05-22 11:23:21 +0000513static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
Daniel Sandersa19216c2015-02-11 11:28:56 +0000514 const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000515 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
516 return *(RegInfo->getRegClass(RC).begin() + RegNo);
517}
518
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000519template <typename InsnType>
520static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
521 const void *Decoder) {
522 typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
523 // The size of the n field depends on the element size
524 // The register class also depends on this.
525 InsnType tmp = fieldFromInstruction(insn, 17, 5);
526 unsigned NSize = 0;
527 DecodeFN RegDecoder = nullptr;
528 if ((tmp & 0x18) == 0x00) { // INSVE_B
529 NSize = 4;
530 RegDecoder = DecodeMSA128BRegisterClass;
531 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
532 NSize = 3;
533 RegDecoder = DecodeMSA128HRegisterClass;
534 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
535 NSize = 2;
536 RegDecoder = DecodeMSA128WRegisterClass;
537 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
538 NSize = 1;
539 RegDecoder = DecodeMSA128DRegisterClass;
540 } else
541 llvm_unreachable("Invalid encoding");
542
543 assert(NSize != 0 && RegDecoder != nullptr);
544
545 // $wd
546 tmp = fieldFromInstruction(insn, 6, 5);
547 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
548 return MCDisassembler::Fail;
549 // $wd_in
550 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
551 return MCDisassembler::Fail;
552 // $n
553 tmp = fieldFromInstruction(insn, 16, NSize);
Jim Grosbache9119e42015-05-13 18:37:00 +0000554 MI.addOperand(MCOperand::createImm(tmp));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000555 // $ws
556 tmp = fieldFromInstruction(insn, 11, 5);
557 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
558 return MCDisassembler::Fail;
559 // $n2
Jim Grosbache9119e42015-05-13 18:37:00 +0000560 MI.addOperand(MCOperand::createImm(0));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000561
562 return MCDisassembler::Success;
563}
564
Daniel Sanders5c582b22014-05-22 11:23:21 +0000565template <typename InsnType>
566static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
567 uint64_t Address,
568 const void *Decoder) {
569 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
570 // (otherwise we would have matched the ADDI instruction from the earlier
571 // ISA's instead).
572 //
573 // We have:
574 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
575 // BOVC if rs >= rt
576 // BEQZALC if rs == 0 && rt != 0
577 // BEQC if rs < rt && rs != 0
578
579 InsnType Rs = fieldFromInstruction(insn, 21, 5);
580 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000581 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000582 bool HasRs = false;
583
584 if (Rs >= Rt) {
585 MI.setOpcode(Mips::BOVC);
586 HasRs = true;
587 } else if (Rs != 0 && Rs < Rt) {
588 MI.setOpcode(Mips::BEQC);
589 HasRs = true;
590 } else
591 MI.setOpcode(Mips::BEQZALC);
592
593 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000594 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000595 Rs)));
596
Jim Grosbache9119e42015-05-13 18:37:00 +0000597 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000598 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000599 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000600
601 return MCDisassembler::Success;
602}
603
604template <typename InsnType>
605static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
606 uint64_t Address,
607 const void *Decoder) {
608 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
609 // (otherwise we would have matched the ADDI instruction from the earlier
610 // ISA's instead).
611 //
612 // We have:
613 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
614 // BNVC if rs >= rt
615 // BNEZALC if rs == 0 && rt != 0
616 // BNEC if rs < rt && rs != 0
617
618 InsnType Rs = fieldFromInstruction(insn, 21, 5);
619 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000620 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000621 bool HasRs = false;
622
623 if (Rs >= Rt) {
624 MI.setOpcode(Mips::BNVC);
625 HasRs = true;
626 } else if (Rs != 0 && Rs < Rt) {
627 MI.setOpcode(Mips::BNEC);
628 HasRs = true;
629 } else
630 MI.setOpcode(Mips::BNEZALC);
631
632 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000633 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000634 Rs)));
635
Jim Grosbache9119e42015-05-13 18:37:00 +0000636 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000637 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000638 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000639
640 return MCDisassembler::Success;
641}
642
643template <typename InsnType>
644static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
645 uint64_t Address,
646 const void *Decoder) {
647 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
648 // (otherwise we would have matched the BLEZL instruction from the earlier
649 // ISA's instead).
650 //
651 // We have:
652 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
653 // Invalid if rs == 0
654 // BLEZC if rs == 0 && rt != 0
655 // BGEZC if rs == rt && rt != 0
656 // BGEC if rs != rt && rs != 0 && rt != 0
657
658 InsnType Rs = fieldFromInstruction(insn, 21, 5);
659 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000660 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000661 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000662
663 if (Rt == 0)
664 return MCDisassembler::Fail;
665 else if (Rs == 0)
666 MI.setOpcode(Mips::BLEZC);
667 else if (Rs == Rt)
668 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000669 else {
670 HasRs = true;
671 MI.setOpcode(Mips::BGEC);
672 }
673
674 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000675 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000676 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000677
Jim Grosbache9119e42015-05-13 18:37:00 +0000678 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000679 Rt)));
680
Jim Grosbache9119e42015-05-13 18:37:00 +0000681 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000682
683 return MCDisassembler::Success;
684}
685
686template <typename InsnType>
687static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
688 uint64_t Address,
689 const void *Decoder) {
690 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
691 // (otherwise we would have matched the BGTZL instruction from the earlier
692 // ISA's instead).
693 //
694 // We have:
695 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
696 // Invalid if rs == 0
697 // BGTZC if rs == 0 && rt != 0
698 // BLTZC if rs == rt && rt != 0
699 // BLTC if rs != rt && rs != 0 && rt != 0
700
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000701 bool HasRs = false;
702
Daniel Sanders5c582b22014-05-22 11:23:21 +0000703 InsnType Rs = fieldFromInstruction(insn, 21, 5);
704 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000705 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000706
707 if (Rt == 0)
708 return MCDisassembler::Fail;
709 else if (Rs == 0)
710 MI.setOpcode(Mips::BGTZC);
711 else if (Rs == Rt)
712 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000713 else {
714 MI.setOpcode(Mips::BLTC);
715 HasRs = true;
716 }
717
718 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000719 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000720 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000721
Jim Grosbache9119e42015-05-13 18:37:00 +0000722 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000723 Rt)));
724
Jim Grosbache9119e42015-05-13 18:37:00 +0000725 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000726
727 return MCDisassembler::Success;
728}
729
730template <typename InsnType>
731static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
732 uint64_t Address,
733 const void *Decoder) {
734 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
735 // (otherwise we would have matched the BGTZ instruction from the earlier
736 // ISA's instead).
737 //
738 // We have:
739 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
740 // BGTZ if rt == 0
741 // BGTZALC if rs == 0 && rt != 0
742 // BLTZALC if rs != 0 && rs == rt
743 // BLTUC if rs != 0 && rs != rt
744
745 InsnType Rs = fieldFromInstruction(insn, 21, 5);
746 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000747 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000748 bool HasRs = false;
749 bool HasRt = false;
750
751 if (Rt == 0) {
752 MI.setOpcode(Mips::BGTZ);
753 HasRs = true;
754 } else if (Rs == 0) {
755 MI.setOpcode(Mips::BGTZALC);
756 HasRt = true;
757 } else if (Rs == Rt) {
758 MI.setOpcode(Mips::BLTZALC);
759 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000760 } else {
761 MI.setOpcode(Mips::BLTUC);
762 HasRs = true;
763 HasRt = true;
764 }
Daniel Sanders5c582b22014-05-22 11:23:21 +0000765
766 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000767 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000768 Rs)));
769
770 if (HasRt)
Jim Grosbache9119e42015-05-13 18:37:00 +0000771 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000772 Rt)));
773
Jim Grosbache9119e42015-05-13 18:37:00 +0000774 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000775
776 return MCDisassembler::Success;
777}
778
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000779template <typename InsnType>
780static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
781 uint64_t Address,
782 const void *Decoder) {
783 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
784 // (otherwise we would have matched the BLEZL instruction from the earlier
785 // ISA's instead).
786 //
787 // We have:
788 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
789 // Invalid if rs == 0
790 // BLEZALC if rs == 0 && rt != 0
791 // BGEZALC if rs == rt && rt != 0
792 // BGEUC if rs != rt && rs != 0 && rt != 0
793
794 InsnType Rs = fieldFromInstruction(insn, 21, 5);
795 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000796 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000797 bool HasRs = false;
798
799 if (Rt == 0)
800 return MCDisassembler::Fail;
801 else if (Rs == 0)
802 MI.setOpcode(Mips::BLEZALC);
803 else if (Rs == Rt)
804 MI.setOpcode(Mips::BGEZALC);
805 else {
806 HasRs = true;
807 MI.setOpcode(Mips::BGEUC);
808 }
809
810 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000811 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000812 Rs)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000813 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000814 Rt)));
815
Jim Grosbache9119e42015-05-13 18:37:00 +0000816 MI.addOperand(MCOperand::createImm(Imm));
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000817
818 return MCDisassembler::Success;
819}
820
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000821/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
822/// according to the given endianess.
823static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
824 uint64_t &Size, uint32_t &Insn,
825 bool IsBigEndian) {
826 // We want to read exactly 2 Bytes of data.
827 if (Bytes.size() < 2) {
828 Size = 0;
829 return MCDisassembler::Fail;
830 }
831
832 if (IsBigEndian) {
833 Insn = (Bytes[0] << 8) | Bytes[1];
834 } else {
835 Insn = (Bytes[1] << 8) | Bytes[0];
836 }
837
838 return MCDisassembler::Success;
839}
840
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000841/// Read four bytes from the ArrayRef and return 32 bit word sorted
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000842/// according to the given endianess
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000843static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
844 uint64_t &Size, uint32_t &Insn,
845 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000846 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000847 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000848 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000849 return MCDisassembler::Fail;
850 }
851
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000852 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
853 // always precede the low 16 bits in the instruction stream (that is, they
854 // are placed at lower addresses in the instruction stream).
855 //
856 // microMIPS byte ordering:
857 // Big-endian: 0 | 1 | 2 | 3
858 // Little-endian: 1 | 0 | 3 | 2
859
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000860 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000861 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000862 Insn =
863 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
864 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +0000865 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000866 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000867 (Bytes[1] << 24);
868 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000869 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000870 (Bytes[3] << 24);
871 }
Akira Hatanaka71928e62012-04-17 18:03:21 +0000872 }
873
874 return MCDisassembler::Success;
875}
876
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000877DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000878 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000879 uint64_t Address,
880 raw_ostream &VStream,
881 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000882 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000883 DecodeStatus Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000884
Vladimir Medicdde3d582013-09-06 12:30:36 +0000885 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000886 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
Reid Klecknerebee6122015-11-19 21:51:55 +0000887 if (Result == MCDisassembler::Fail)
888 return MCDisassembler::Fail;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000889
Zoran Jovanovicada70912015-09-07 11:56:37 +0000890 if (hasMips32r6()) {
891 DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
892 // Calling the auto-generated decoder function for microMIPS32R6
893 // (and microMIPS64R6) 16-bit instructions.
894 Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
895 Address, this, STI);
896 if (Result != MCDisassembler::Fail) {
897 Size = 2;
898 return Result;
899 }
900 }
901
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000902 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
Zoran Jovanovicada70912015-09-07 11:56:37 +0000903 // Calling the auto-generated decoder function for microMIPS 16-bit
904 // instructions.
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000905 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
906 this, STI);
907 if (Result != MCDisassembler::Fail) {
908 Size = 2;
909 return Result;
910 }
911
912 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
913 if (Result == MCDisassembler::Fail)
914 return MCDisassembler::Fail;
915
Jozef Kolek676d6012015-04-20 14:40:38 +0000916 if (hasMips32r6()) {
917 DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
918 // Calling the auto-generated decoder function.
Zoran Jovanovic366783e2015-08-12 12:45:16 +0000919 Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
Jozef Kolek676d6012015-04-20 14:40:38 +0000920 this, STI);
Zoran Jovanovicada70912015-09-07 11:56:37 +0000921 if (Result != MCDisassembler::Fail) {
922 Size = 4;
923 return Result;
924 }
Jozef Kolek676d6012015-04-20 14:40:38 +0000925 }
Zoran Jovanovic366783e2015-08-12 12:45:16 +0000926
Zoran Jovanovicada70912015-09-07 11:56:37 +0000927 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
928 // Calling the auto-generated decoder function.
929 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
930 this, STI);
Vladimir Medicdde3d582013-09-06 12:30:36 +0000931 if (Result != MCDisassembler::Fail) {
932 Size = 4;
933 return Result;
934 }
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +0000935
Zlatko Buljan6221be82016-03-31 08:51:24 +0000936 if (hasMips32r6() && isFP64()) {
937 DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
938 Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +0000939 Address, this, STI);
940 if (Result != MCDisassembler::Fail) {
941 Size = 4;
942 return Result;
943 }
944 }
945
Reid Klecknerebee6122015-11-19 21:51:55 +0000946 // This is an invalid instruction. Let the disassembler move forward by the
947 // minimum instruction size.
948 Size = 2;
Vladimir Medicdde3d582013-09-06 12:30:36 +0000949 return MCDisassembler::Fail;
950 }
951
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000952 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Reid Klecknerebee6122015-11-19 21:51:55 +0000953 if (Result == MCDisassembler::Fail) {
954 Size = 4;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000955 return MCDisassembler::Fail;
Reid Klecknerebee6122015-11-19 21:51:55 +0000956 }
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000957
Daniel Sandersc171f652014-06-13 13:15:59 +0000958 if (hasCOP3()) {
959 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
960 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000961 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Daniel Sandersc171f652014-06-13 13:15:59 +0000962 if (Result != MCDisassembler::Fail) {
963 Size = 4;
964 return Result;
965 }
966 }
967
968 if (hasMips32r6() && isGP64()) {
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +0000969 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
970 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
971 Address, this, STI);
Daniel Sanders0fa60412014-06-12 13:39:06 +0000972 if (Result != MCDisassembler::Fail) {
973 Size = 4;
974 return Result;
975 }
976 }
977
Daniel Sandersc171f652014-06-13 13:15:59 +0000978 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +0000979 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000980 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000981 Address, this, STI);
982 if (Result != MCDisassembler::Fail) {
983 Size = 4;
984 return Result;
985 }
986 }
987
Kai Nacke3adf9b82015-05-28 16:23:16 +0000988 if (hasCnMips()) {
989 DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
990 Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
991 Address, this, STI);
992 if (Result != MCDisassembler::Fail) {
993 Size = 4;
994 return Result;
995 }
996 }
997
Daniel Sandersa19216c2015-02-11 11:28:56 +0000998 if (isGP64()) {
999 DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1000 Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1001 Address, this, STI);
1002 if (Result != MCDisassembler::Fail) {
1003 Size = 4;
1004 return Result;
1005 }
1006 }
1007
Daniel Sanders0fa60412014-06-12 13:39:06 +00001008 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +00001009 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001010 Result =
1011 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001012 if (Result != MCDisassembler::Fail) {
1013 Size = 4;
1014 return Result;
1015 }
1016
Reid Klecknerebee6122015-11-19 21:51:55 +00001017 Size = 4;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001018 return MCDisassembler::Fail;
1019}
1020
Reed Kotlerec8a5492013-02-14 03:05:25 +00001021static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1022 unsigned RegNo,
1023 uint64_t Address,
1024 const void *Decoder) {
1025
1026 return MCDisassembler::Fail;
1027
1028}
1029
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001030static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1031 unsigned RegNo,
1032 uint64_t Address,
1033 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001034
1035 if (RegNo > 31)
1036 return MCDisassembler::Fail;
1037
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001038 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001039 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001040 return MCDisassembler::Success;
1041}
1042
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001043static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1044 unsigned RegNo,
1045 uint64_t Address,
1046 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001047 if (RegNo > 7)
1048 return MCDisassembler::Fail;
1049 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001050 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001051 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001052}
1053
Jozef Kolek1904fa22014-11-24 14:25:53 +00001054static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1055 unsigned RegNo,
1056 uint64_t Address,
1057 const void *Decoder) {
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001058 if (RegNo > 7)
1059 return MCDisassembler::Fail;
1060 unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001061 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001062 return MCDisassembler::Success;
Jozef Kolek1904fa22014-11-24 14:25:53 +00001063}
1064
Zoran Jovanovic41688672015-02-10 16:36:20 +00001065static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1066 unsigned RegNo,
1067 uint64_t Address,
1068 const void *Decoder) {
1069 if (RegNo > 7)
1070 return MCDisassembler::Fail;
1071 unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001072 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic41688672015-02-10 16:36:20 +00001073 return MCDisassembler::Success;
1074}
1075
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001076static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1077 unsigned RegNo,
1078 uint64_t Address,
1079 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001080 if (RegNo > 31)
1081 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001082 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001083 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001084 return MCDisassembler::Success;
1085}
1086
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001087static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1088 unsigned RegNo,
1089 uint64_t Address,
1090 const void *Decoder) {
Daniel Sandersa19216c2015-02-11 11:28:56 +00001091 if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001092 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1093
1094 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1095}
1096
Akira Hatanaka654655f2013-08-14 00:53:38 +00001097static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1098 unsigned RegNo,
1099 uint64_t Address,
1100 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001101 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001102}
1103
Akira Hatanaka71928e62012-04-17 18:03:21 +00001104static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1105 unsigned RegNo,
1106 uint64_t Address,
1107 const void *Decoder) {
1108 if (RegNo > 31)
1109 return MCDisassembler::Fail;
1110
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001111 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001112 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001113 return MCDisassembler::Success;
1114}
1115
1116static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1117 unsigned RegNo,
1118 uint64_t Address,
1119 const void *Decoder) {
1120 if (RegNo > 31)
1121 return MCDisassembler::Fail;
1122
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001123 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001124 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001125 return MCDisassembler::Success;
1126}
1127
1128static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1129 unsigned RegNo,
1130 uint64_t Address,
1131 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +00001132 if (RegNo > 31)
1133 return MCDisassembler::Fail;
1134 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001135 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001136 return MCDisassembler::Success;
1137}
1138
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001139static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1140 unsigned RegNo,
1141 uint64_t Address,
1142 const void *Decoder) {
1143 if (RegNo > 7)
1144 return MCDisassembler::Fail;
1145 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001146 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001147 return MCDisassembler::Success;
1148}
1149
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001150static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1151 uint64_t Address,
1152 const void *Decoder) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001153 if (RegNo > 31)
1154 return MCDisassembler::Fail;
1155
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001156 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001157 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders0fa60412014-06-12 13:39:06 +00001158 return MCDisassembler::Success;
1159}
1160
Akira Hatanaka71928e62012-04-17 18:03:21 +00001161static DecodeStatus DecodeMem(MCInst &Inst,
1162 unsigned Insn,
1163 uint64_t Address,
1164 const void *Decoder) {
1165 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001166 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1167 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001168
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001169 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1170 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001171
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001172 if (Inst.getOpcode() == Mips::SC ||
1173 Inst.getOpcode() == Mips::SCD)
Jim Grosbache9119e42015-05-13 18:37:00 +00001174 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001175
1176 Inst.addOperand(MCOperand::createReg(Reg));
1177 Inst.addOperand(MCOperand::createReg(Base));
1178 Inst.addOperand(MCOperand::createImm(Offset));
1179
1180 return MCDisassembler::Success;
1181}
1182
1183static DecodeStatus DecodeMemEVA(MCInst &Inst,
1184 unsigned Insn,
1185 uint64_t Address,
1186 const void *Decoder) {
1187 int Offset = SignExtend32<9>(Insn >> 7);
1188 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1189 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1190
1191 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1192 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1193
1194 if (Inst.getOpcode() == Mips::SCE)
1195 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001196
Jim Grosbache9119e42015-05-13 18:37:00 +00001197 Inst.addOperand(MCOperand::createReg(Reg));
1198 Inst.addOperand(MCOperand::createReg(Base));
1199 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001200
1201 return MCDisassembler::Success;
1202}
1203
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +00001204static DecodeStatus DecodeLoadByte9(MCInst &Inst,
1205 unsigned Insn,
1206 uint64_t Address,
1207 const void *Decoder) {
1208 int Offset = SignExtend32<9>(Insn & 0x1ff);
1209 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1210 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1211
1212 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1213 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1214
1215 Inst.addOperand(MCOperand::createReg(Reg));
1216 Inst.addOperand(MCOperand::createReg(Base));
1217 Inst.addOperand(MCOperand::createImm(Offset));
1218
1219 return MCDisassembler::Success;
1220}
1221
1222static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1223 unsigned Insn,
1224 uint64_t Address,
1225 const void *Decoder) {
1226 int Offset = SignExtend32<16>(Insn & 0xffff);
1227 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1228 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1229
1230 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1231 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1232
1233 Inst.addOperand(MCOperand::createReg(Reg));
1234 Inst.addOperand(MCOperand::createReg(Base));
1235 Inst.addOperand(MCOperand::createImm(Offset));
1236
1237 return MCDisassembler::Success;
1238}
1239
Daniel Sanders92db6b72014-10-01 08:26:55 +00001240static DecodeStatus DecodeCacheOp(MCInst &Inst,
1241 unsigned Insn,
1242 uint64_t Address,
1243 const void *Decoder) {
1244 int Offset = SignExtend32<16>(Insn & 0xffff);
1245 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1246 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1247
1248 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1249
Jim Grosbache9119e42015-05-13 18:37:00 +00001250 Inst.addOperand(MCOperand::createReg(Base));
1251 Inst.addOperand(MCOperand::createImm(Offset));
1252 Inst.addOperand(MCOperand::createImm(Hint));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001253
1254 return MCDisassembler::Success;
1255}
1256
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001257static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1258 unsigned Insn,
1259 uint64_t Address,
1260 const void *Decoder) {
1261 int Offset = SignExtend32<12>(Insn & 0xfff);
1262 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1263 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1264
1265 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1266
Jim Grosbache9119e42015-05-13 18:37:00 +00001267 Inst.addOperand(MCOperand::createReg(Base));
1268 Inst.addOperand(MCOperand::createImm(Offset));
1269 Inst.addOperand(MCOperand::createImm(Hint));
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001270
1271 return MCDisassembler::Success;
1272}
1273
Zoran Jovanovicd9790792015-09-09 09:10:46 +00001274static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1275 unsigned Insn,
1276 uint64_t Address,
1277 const void *Decoder) {
1278 int Offset = SignExtend32<9>(Insn & 0x1ff);
1279 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1280 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1281
1282 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1283
1284 Inst.addOperand(MCOperand::createReg(Base));
1285 Inst.addOperand(MCOperand::createImm(Offset));
1286 Inst.addOperand(MCOperand::createImm(Hint));
1287
1288 return MCDisassembler::Success;
1289}
1290
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001291static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1292 unsigned Insn,
1293 uint64_t Address,
1294 const void *Decoder) {
1295 int Offset = SignExtend32<9>(Insn >> 7);
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001296 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1297 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1298
1299 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1300
Jim Grosbache9119e42015-05-13 18:37:00 +00001301 Inst.addOperand(MCOperand::createReg(Base));
1302 Inst.addOperand(MCOperand::createImm(Offset));
1303 Inst.addOperand(MCOperand::createImm(Hint));
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001304
1305 return MCDisassembler::Success;
1306}
1307
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +00001308static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
1309 unsigned Insn,
1310 uint64_t Address,
1311 const void *Decoder) {
1312 int Offset = SignExtend32<9>(Insn & 0x1ff);
1313 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1314 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1315
1316 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1317 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1318
1319 Inst.addOperand(MCOperand::createReg(Reg));
1320 Inst.addOperand(MCOperand::createReg(Base));
1321 Inst.addOperand(MCOperand::createImm(Offset));
1322
1323 return MCDisassembler::Success;
1324}
1325
Daniel Sandersb4484d62014-11-27 17:28:10 +00001326static DecodeStatus DecodeSyncI(MCInst &Inst,
1327 unsigned Insn,
1328 uint64_t Address,
1329 const void *Decoder) {
1330 int Offset = SignExtend32<16>(Insn & 0xffff);
1331 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1332
1333 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1334
Jim Grosbache9119e42015-05-13 18:37:00 +00001335 Inst.addOperand(MCOperand::createReg(Base));
1336 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sandersb4484d62014-11-27 17:28:10 +00001337
1338 return MCDisassembler::Success;
1339}
1340
Hrvoje Varga18148672015-10-28 11:04:29 +00001341static DecodeStatus DecodeSynciR6(MCInst &Inst,
1342 unsigned Insn,
1343 uint64_t Address,
1344 const void *Decoder) {
1345 int Immediate = SignExtend32<16>(Insn & 0xffff);
1346 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1347
1348 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1349
1350 Inst.addOperand(MCOperand::createReg(Base));
1351 Inst.addOperand(MCOperand::createImm(Immediate));
1352
1353 return MCDisassembler::Success;
1354}
1355
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001356static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1357 uint64_t Address, const void *Decoder) {
1358 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1359 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1360 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1361
1362 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1363 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1364
Jim Grosbache9119e42015-05-13 18:37:00 +00001365 Inst.addOperand(MCOperand::createReg(Reg));
1366 Inst.addOperand(MCOperand::createReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001367
1368 // The immediate field of an LD/ST instruction is scaled which means it must
1369 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1370 // data format.
1371 // .b - 1 byte
1372 // .h - 2 bytes
1373 // .w - 4 bytes
1374 // .d - 8 bytes
1375 switch(Inst.getOpcode())
1376 {
1377 default:
1378 assert (0 && "Unexpected instruction");
1379 return MCDisassembler::Fail;
1380 break;
1381 case Mips::LD_B:
1382 case Mips::ST_B:
Jim Grosbache9119e42015-05-13 18:37:00 +00001383 Inst.addOperand(MCOperand::createImm(Offset));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001384 break;
1385 case Mips::LD_H:
1386 case Mips::ST_H:
Jim Grosbache9119e42015-05-13 18:37:00 +00001387 Inst.addOperand(MCOperand::createImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001388 break;
1389 case Mips::LD_W:
1390 case Mips::ST_W:
Jim Grosbache9119e42015-05-13 18:37:00 +00001391 Inst.addOperand(MCOperand::createImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001392 break;
1393 case Mips::LD_D:
1394 case Mips::ST_D:
Jim Grosbache9119e42015-05-13 18:37:00 +00001395 Inst.addOperand(MCOperand::createImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001396 break;
1397 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001398
1399 return MCDisassembler::Success;
1400}
1401
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001402static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1403 unsigned Insn,
1404 uint64_t Address,
1405 const void *Decoder) {
1406 unsigned Offset = Insn & 0xf;
1407 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1408 unsigned Base = fieldFromInstruction(Insn, 4, 3);
1409
1410 switch (Inst.getOpcode()) {
1411 case Mips::LBU16_MM:
1412 case Mips::LHU16_MM:
1413 case Mips::LW16_MM:
1414 if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1415 == MCDisassembler::Fail)
1416 return MCDisassembler::Fail;
1417 break;
1418 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001419 case Mips::SB16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001420 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001421 case Mips::SH16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001422 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001423 case Mips::SW16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001424 if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1425 == MCDisassembler::Fail)
1426 return MCDisassembler::Fail;
1427 break;
1428 }
1429
1430 if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1431 == MCDisassembler::Fail)
1432 return MCDisassembler::Fail;
1433
1434 switch (Inst.getOpcode()) {
1435 case Mips::LBU16_MM:
1436 if (Offset == 0xf)
Jim Grosbache9119e42015-05-13 18:37:00 +00001437 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001438 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001439 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001440 break;
1441 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001442 case Mips::SB16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001443 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001444 break;
1445 case Mips::LHU16_MM:
1446 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001447 case Mips::SH16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001448 Inst.addOperand(MCOperand::createImm(Offset << 1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001449 break;
1450 case Mips::LW16_MM:
1451 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001452 case Mips::SW16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001453 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001454 break;
1455 }
1456
1457 return MCDisassembler::Success;
1458}
1459
Jozef Kolek12c69822014-12-23 16:16:33 +00001460static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1461 unsigned Insn,
1462 uint64_t Address,
1463 const void *Decoder) {
1464 unsigned Offset = Insn & 0x1F;
1465 unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1466
1467 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1468
Jim Grosbache9119e42015-05-13 18:37:00 +00001469 Inst.addOperand(MCOperand::createReg(Reg));
1470 Inst.addOperand(MCOperand::createReg(Mips::SP));
1471 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek12c69822014-12-23 16:16:33 +00001472
1473 return MCDisassembler::Success;
1474}
1475
Jozef Koleke10a02e2015-01-28 17:27:26 +00001476static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1477 unsigned Insn,
1478 uint64_t Address,
1479 const void *Decoder) {
1480 unsigned Offset = Insn & 0x7F;
1481 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1482
1483 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1484
Jim Grosbache9119e42015-05-13 18:37:00 +00001485 Inst.addOperand(MCOperand::createReg(Reg));
1486 Inst.addOperand(MCOperand::createReg(Mips::GP));
1487 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Koleke10a02e2015-01-28 17:27:26 +00001488
1489 return MCDisassembler::Success;
1490}
1491
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001492static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1493 unsigned Insn,
1494 uint64_t Address,
1495 const void *Decoder) {
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001496 int Offset;
1497 switch (Inst.getOpcode()) {
1498 case Mips::LWM16_MMR6:
1499 case Mips::SWM16_MMR6:
1500 Offset = fieldFromInstruction(Insn, 4, 4);
1501 break;
1502 default:
1503 Offset = SignExtend32<4>(Insn & 0xf);
1504 break;
1505 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001506
1507 if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1508 == MCDisassembler::Fail)
1509 return MCDisassembler::Fail;
1510
Jim Grosbache9119e42015-05-13 18:37:00 +00001511 Inst.addOperand(MCOperand::createReg(Mips::SP));
1512 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001513
1514 return MCDisassembler::Success;
1515}
1516
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001517static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1518 unsigned Insn,
1519 uint64_t Address,
1520 const void *Decoder) {
1521 int Offset = SignExtend32<9>(Insn & 0x1ff);
1522 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1523 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1524
1525 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1526 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1527
Hrvoje Varga3ef4dd72015-10-15 08:11:50 +00001528 if (Inst.getOpcode() == Mips::SCE_MM)
1529 Inst.addOperand(MCOperand::createReg(Reg));
1530
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001531 Inst.addOperand(MCOperand::createReg(Reg));
1532 Inst.addOperand(MCOperand::createReg(Base));
1533 Inst.addOperand(MCOperand::createImm(Offset));
1534
1535 return MCDisassembler::Success;
1536}
1537
Vladimir Medicdde3d582013-09-06 12:30:36 +00001538static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1539 unsigned Insn,
1540 uint64_t Address,
1541 const void *Decoder) {
1542 int Offset = SignExtend32<12>(Insn & 0x0fff);
1543 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1544 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1545
1546 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1547 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1548
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001549 switch (Inst.getOpcode()) {
1550 case Mips::SWM32_MM:
1551 case Mips::LWM32_MM:
1552 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1553 == MCDisassembler::Fail)
1554 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001555 Inst.addOperand(MCOperand::createReg(Base));
1556 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001557 break;
1558 case Mips::SC_MM:
Jim Grosbache9119e42015-05-13 18:37:00 +00001559 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001560 // fallthrough
1561 default:
Jim Grosbache9119e42015-05-13 18:37:00 +00001562 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001563 if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM)
Jim Grosbache9119e42015-05-13 18:37:00 +00001564 Inst.addOperand(MCOperand::createReg(Reg+1));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001565
Jim Grosbache9119e42015-05-13 18:37:00 +00001566 Inst.addOperand(MCOperand::createReg(Base));
1567 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001568 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001569
1570 return MCDisassembler::Success;
1571}
1572
1573static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1574 unsigned Insn,
1575 uint64_t Address,
1576 const void *Decoder) {
1577 int Offset = SignExtend32<16>(Insn & 0xffff);
1578 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1579 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1580
1581 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1582 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1583
Jim Grosbache9119e42015-05-13 18:37:00 +00001584 Inst.addOperand(MCOperand::createReg(Reg));
1585 Inst.addOperand(MCOperand::createReg(Base));
1586 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medicdde3d582013-09-06 12:30:36 +00001587
1588 return MCDisassembler::Success;
1589}
1590
Akira Hatanaka71928e62012-04-17 18:03:21 +00001591static DecodeStatus DecodeFMem(MCInst &Inst,
1592 unsigned Insn,
1593 uint64_t Address,
1594 const void *Decoder) {
1595 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001596 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1597 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001598
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001599 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001600 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001601
Jim Grosbache9119e42015-05-13 18:37:00 +00001602 Inst.addOperand(MCOperand::createReg(Reg));
1603 Inst.addOperand(MCOperand::createReg(Base));
1604 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001605
1606 return MCDisassembler::Success;
1607}
1608
Hrvoje Varga117625a2016-04-20 06:34:48 +00001609static DecodeStatus DecodeFMemMMR6(MCInst &Inst, unsigned Insn,
1610 uint64_t Address, const void *Decoder) {
1611 int Offset = SignExtend32<16>(Insn & 0xffff);
1612 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1613 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1614
1615 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1616 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1617
1618 Inst.addOperand(MCOperand::createReg(Reg));
1619 Inst.addOperand(MCOperand::createReg(Base));
1620 Inst.addOperand(MCOperand::createImm(Offset));
1621
1622 return MCDisassembler::Success;
1623}
1624
Daniel Sanders92db6b72014-10-01 08:26:55 +00001625static DecodeStatus DecodeFMem2(MCInst &Inst,
1626 unsigned Insn,
1627 uint64_t Address,
1628 const void *Decoder) {
1629 int Offset = SignExtend32<16>(Insn & 0xffff);
1630 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1631 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1632
1633 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1634 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1635
Jim Grosbache9119e42015-05-13 18:37:00 +00001636 Inst.addOperand(MCOperand::createReg(Reg));
1637 Inst.addOperand(MCOperand::createReg(Base));
1638 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001639
1640 return MCDisassembler::Success;
1641}
1642
1643static DecodeStatus DecodeFMem3(MCInst &Inst,
1644 unsigned Insn,
1645 uint64_t Address,
1646 const void *Decoder) {
1647 int Offset = SignExtend32<16>(Insn & 0xffff);
1648 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1649 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1650
1651 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1652 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1653
Jim Grosbache9119e42015-05-13 18:37:00 +00001654 Inst.addOperand(MCOperand::createReg(Reg));
1655 Inst.addOperand(MCOperand::createReg(Base));
1656 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001657
1658 return MCDisassembler::Success;
1659}
1660
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001661static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1662 unsigned Insn,
1663 uint64_t Address,
1664 const void *Decoder) {
1665 int Offset = SignExtend32<11>(Insn & 0x07ff);
1666 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1667 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1668
1669 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1670 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1671
Jim Grosbache9119e42015-05-13 18:37:00 +00001672 Inst.addOperand(MCOperand::createReg(Reg));
1673 Inst.addOperand(MCOperand::createReg(Base));
1674 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001675
1676 return MCDisassembler::Success;
1677}
Hrvoje Varga117625a2016-04-20 06:34:48 +00001678
1679static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1680 uint64_t Address, const void *Decoder) {
1681 int Offset = SignExtend32<11>(Insn & 0x07ff);
1682 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1683 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1684
1685 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1686 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1687
1688 Inst.addOperand(MCOperand::createReg(Reg));
1689 Inst.addOperand(MCOperand::createReg(Base));
1690 Inst.addOperand(MCOperand::createImm(Offset));
1691
1692 return MCDisassembler::Success;
1693}
Daniel Sanders6a803f62014-06-16 13:13:03 +00001694static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1695 unsigned Insn,
1696 uint64_t Address,
1697 const void *Decoder) {
1698 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1699 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1700 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1701
1702 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1703 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1704
1705 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
Jim Grosbache9119e42015-05-13 18:37:00 +00001706 Inst.addOperand(MCOperand::createReg(Rt));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001707 }
1708
Jim Grosbache9119e42015-05-13 18:37:00 +00001709 Inst.addOperand(MCOperand::createReg(Rt));
1710 Inst.addOperand(MCOperand::createReg(Base));
1711 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001712
1713 return MCDisassembler::Success;
1714}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001715
1716static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1717 unsigned RegNo,
1718 uint64_t Address,
1719 const void *Decoder) {
1720 // Currently only hardware register 29 is supported.
1721 if (RegNo != 29)
1722 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001723 Inst.addOperand(MCOperand::createReg(Mips::HWR29));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001724 return MCDisassembler::Success;
1725}
1726
Akira Hatanaka71928e62012-04-17 18:03:21 +00001727static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1728 unsigned RegNo,
1729 uint64_t Address,
1730 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001731 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001732 return MCDisassembler::Fail;
1733
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001734 ;
1735 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
Jim Grosbache9119e42015-05-13 18:37:00 +00001736 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001737 return MCDisassembler::Success;
1738}
1739
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001740static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1741 unsigned RegNo,
1742 uint64_t Address,
1743 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001744 if (RegNo >= 4)
1745 return MCDisassembler::Fail;
1746
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001747 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001748 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001749 return MCDisassembler::Success;
1750}
1751
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001752static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1753 unsigned RegNo,
1754 uint64_t Address,
1755 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001756 if (RegNo >= 4)
1757 return MCDisassembler::Fail;
1758
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001759 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001760 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001761 return MCDisassembler::Success;
1762}
1763
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001764static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
1765 unsigned RegNo,
1766 uint64_t Address,
1767 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001768 if (RegNo >= 4)
1769 return MCDisassembler::Fail;
1770
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001771 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001772 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001773 return MCDisassembler::Success;
1774}
1775
Jack Carter3eb663b2013-09-26 00:09:46 +00001776static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1777 unsigned RegNo,
1778 uint64_t Address,
1779 const void *Decoder) {
1780 if (RegNo > 31)
1781 return MCDisassembler::Fail;
1782
1783 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001784 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter3eb663b2013-09-26 00:09:46 +00001785 return MCDisassembler::Success;
1786}
1787
Jack Carter5dc8ac92013-09-25 23:50:44 +00001788static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1789 unsigned RegNo,
1790 uint64_t Address,
1791 const void *Decoder) {
1792 if (RegNo > 31)
1793 return MCDisassembler::Fail;
1794
1795 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001796 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001797 return MCDisassembler::Success;
1798}
1799
1800static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1801 unsigned RegNo,
1802 uint64_t Address,
1803 const void *Decoder) {
1804 if (RegNo > 31)
1805 return MCDisassembler::Fail;
1806
1807 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001808 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001809 return MCDisassembler::Success;
1810}
1811
1812static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1813 unsigned RegNo,
1814 uint64_t Address,
1815 const void *Decoder) {
1816 if (RegNo > 31)
1817 return MCDisassembler::Fail;
1818
1819 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001820 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001821 return MCDisassembler::Success;
1822}
1823
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001824static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1825 unsigned RegNo,
1826 uint64_t Address,
1827 const void *Decoder) {
1828 if (RegNo > 7)
1829 return MCDisassembler::Fail;
1830
1831 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001832 Inst.addOperand(MCOperand::createReg(Reg));
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001833 return MCDisassembler::Success;
1834}
1835
Daniel Sandersa3134fa2015-06-27 15:39:19 +00001836static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1837 unsigned RegNo,
1838 uint64_t Address,
1839 const void *Decoder) {
1840 if (RegNo > 31)
1841 return MCDisassembler::Fail;
1842
1843 unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1844 Inst.addOperand(MCOperand::createReg(Reg));
1845 return MCDisassembler::Success;
1846}
1847
Daniel Sanders2a83d682014-05-21 12:56:39 +00001848static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1849 unsigned RegNo,
1850 uint64_t Address,
1851 const void *Decoder) {
1852 if (RegNo > 31)
1853 return MCDisassembler::Fail;
1854
1855 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001856 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders2a83d682014-05-21 12:56:39 +00001857 return MCDisassembler::Success;
1858}
1859
Akira Hatanaka71928e62012-04-17 18:03:21 +00001860static DecodeStatus DecodeBranchTarget(MCInst &Inst,
1861 unsigned Offset,
1862 uint64_t Address,
1863 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001864 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00001865 Inst.addOperand(MCOperand::createImm(BranchOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001866 return MCDisassembler::Success;
1867}
1868
Akira Hatanaka71928e62012-04-17 18:03:21 +00001869static DecodeStatus DecodeJumpTarget(MCInst &Inst,
1870 unsigned Insn,
1871 uint64_t Address,
1872 const void *Decoder) {
1873
Jim Grosbachecaef492012-08-14 19:06:05 +00001874 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00001875 Inst.addOperand(MCOperand::createImm(JumpOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001876 return MCDisassembler::Success;
1877}
1878
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001879static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
1880 unsigned Offset,
1881 uint64_t Address,
1882 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001883 int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001884
Jim Grosbache9119e42015-05-13 18:37:00 +00001885 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001886 return MCDisassembler::Success;
1887}
1888
1889static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
1890 unsigned Offset,
1891 uint64_t Address,
1892 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001893 int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001894
Jim Grosbache9119e42015-05-13 18:37:00 +00001895 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001896 return MCDisassembler::Success;
1897}
1898
Jozef Kolek9761e962015-01-12 12:03:34 +00001899static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
1900 unsigned Offset,
1901 uint64_t Address,
1902 const void *Decoder) {
1903 int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001904 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek9761e962015-01-12 12:03:34 +00001905 return MCDisassembler::Success;
1906}
1907
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00001908static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
1909 unsigned Offset,
1910 uint64_t Address,
1911 const void *Decoder) {
1912 int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001913 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00001914 return MCDisassembler::Success;
1915}
1916
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001917static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
1918 unsigned Offset,
1919 uint64_t Address,
1920 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001921 int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00001922 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001923 return MCDisassembler::Success;
1924}
1925
Zoran Jovanovica887b362015-11-30 12:56:18 +00001926static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
1927 unsigned Offset,
1928 uint64_t Address,
1929 const void *Decoder) {
1930 int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
1931
1932 Inst.addOperand(MCOperand::createImm(BranchOffset));
1933 return MCDisassembler::Success;
1934}
1935
Zoran Jovanovic507e0842013-10-29 16:38:59 +00001936static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1937 unsigned Insn,
1938 uint64_t Address,
1939 const void *Decoder) {
1940 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001941 Inst.addOperand(MCOperand::createImm(JumpOffset));
Zoran Jovanovic507e0842013-10-29 16:38:59 +00001942 return MCDisassembler::Success;
1943}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001944
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001945static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1946 unsigned Value,
1947 uint64_t Address,
1948 const void *Decoder) {
1949 if (Value == 0)
Jim Grosbache9119e42015-05-13 18:37:00 +00001950 Inst.addOperand(MCOperand::createImm(1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001951 else if (Value == 0x7)
Jim Grosbache9119e42015-05-13 18:37:00 +00001952 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001953 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001954 Inst.addOperand(MCOperand::createImm(Value << 2));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001955 return MCDisassembler::Success;
1956}
1957
Daniel Sanders97297772016-03-22 14:40:00 +00001958static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001959 unsigned Value,
1960 uint64_t Address,
1961 const void *Decoder) {
1962 if (Value == 0x7F)
Jim Grosbache9119e42015-05-13 18:37:00 +00001963 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001964 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001965 Inst.addOperand(MCOperand::createImm(Value));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001966 return MCDisassembler::Success;
1967}
1968
Zoran Jovanovic6b28f092015-09-09 13:55:45 +00001969static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
1970 unsigned Value,
1971 uint64_t Address,
1972 const void *Decoder) {
1973 Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
1974 return MCDisassembler::Success;
1975}
1976
Daniel Sanders19b7f762016-03-14 11:16:56 +00001977template <unsigned Bits, int Offset, int Scale>
1978static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
1979 uint64_t Address,
1980 const void *Decoder) {
Daniel Sandersea4f6532015-11-06 12:22:31 +00001981 Value &= ((1 << Bits) - 1);
Daniel Sanders19b7f762016-03-14 11:16:56 +00001982 Value *= Scale;
Daniel Sandersea4f6532015-11-06 12:22:31 +00001983 Inst.addOperand(MCOperand::createImm(Value + Offset));
Matheus Almeida779c5932013-11-18 12:32:49 +00001984 return MCDisassembler::Success;
1985}
1986
Daniel Sanders97297772016-03-22 14:40:00 +00001987template <unsigned Bits, int Offset, int ScaleBy>
1988static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
1989 uint64_t Address,
1990 const void *Decoder) {
1991 int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
Daniel Sanders78e89022016-03-11 11:37:50 +00001992 Inst.addOperand(MCOperand::createImm(Imm + Offset));
1993 return MCDisassembler::Success;
1994}
1995
Akira Hatanaka71928e62012-04-17 18:03:21 +00001996static DecodeStatus DecodeInsSize(MCInst &Inst,
1997 unsigned Insn,
1998 uint64_t Address,
1999 const void *Decoder) {
2000 // First we need to grab the pos(lsb) from MCInst.
2001 int Pos = Inst.getOperand(2).getImm();
2002 int Size = (int) Insn - Pos + 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002003 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002004 return MCDisassembler::Success;
2005}
2006
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002007static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2008 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002009 Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002010 return MCDisassembler::Success;
2011}
Zoran Jovanovic28551422014-06-09 09:49:51 +00002012
2013static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2014 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002015 Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00002016 return MCDisassembler::Success;
2017}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002018
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002019static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2020 uint64_t Address, const void *Decoder) {
2021 int32_t DecodedValue;
2022 switch (Insn) {
2023 case 0: DecodedValue = 256; break;
2024 case 1: DecodedValue = 257; break;
2025 case 510: DecodedValue = -258; break;
2026 case 511: DecodedValue = -257; break;
2027 default: DecodedValue = SignExtend32<9>(Insn); break;
2028 }
Jim Grosbache9119e42015-05-13 18:37:00 +00002029 Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002030 return MCDisassembler::Success;
2031}
2032
2033static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2034 uint64_t Address, const void *Decoder) {
2035 // Insn must be >= 0, since it is unsigned that condition is always true.
2036 assert(Insn < 16);
2037 int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2038 255, 32768, 65535};
Jim Grosbache9119e42015-05-13 18:37:00 +00002039 Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002040 return MCDisassembler::Success;
2041}
2042
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002043static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2044 unsigned Insn,
2045 uint64_t Address,
2046 const void *Decoder) {
2047 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
Zoran Jovanovicdc4b8c22015-09-15 15:21:27 +00002048 Mips::S6, Mips::S7, Mips::FP};
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002049 unsigned RegNum;
2050
2051 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002052
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002053 // Empty register lists are not allowed.
2054 if (RegLst == 0)
2055 return MCDisassembler::Fail;
2056
2057 RegNum = RegLst & 0xf;
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002058
2059 // RegLst values 10-15, and 26-31 are reserved.
2060 if (RegNum > 9)
2061 return MCDisassembler::Fail;
2062
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002063 for (unsigned i = 0; i < RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002064 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002065
2066 if (RegLst & 0x10)
Jim Grosbache9119e42015-05-13 18:37:00 +00002067 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002068
2069 return MCDisassembler::Success;
2070}
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002071
2072static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2073 uint64_t Address,
2074 const void *Decoder) {
2075 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00002076 unsigned RegLst;
2077 switch(Inst.getOpcode()) {
2078 default:
2079 RegLst = fieldFromInstruction(Insn, 4, 2);
2080 break;
2081 case Mips::LWM16_MMR6:
2082 case Mips::SWM16_MMR6:
2083 RegLst = fieldFromInstruction(Insn, 8, 2);
2084 break;
2085 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002086 unsigned RegNum = RegLst & 0x3;
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002087
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002088 for (unsigned i = 0; i <= RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002089 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002090
Jim Grosbache9119e42015-05-13 18:37:00 +00002091 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002092
2093 return MCDisassembler::Success;
2094}
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002095
Zoran Jovanovic41688672015-02-10 16:36:20 +00002096static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
2097 uint64_t Address, const void *Decoder) {
2098
2099 unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2100
2101 switch (RegPair) {
2102 default:
2103 return MCDisassembler::Fail;
2104 case 0:
Jim Grosbache9119e42015-05-13 18:37:00 +00002105 Inst.addOperand(MCOperand::createReg(Mips::A1));
2106 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002107 break;
2108 case 1:
Jim Grosbache9119e42015-05-13 18:37:00 +00002109 Inst.addOperand(MCOperand::createReg(Mips::A1));
2110 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002111 break;
2112 case 2:
Jim Grosbache9119e42015-05-13 18:37:00 +00002113 Inst.addOperand(MCOperand::createReg(Mips::A2));
2114 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002115 break;
2116 case 3:
Jim Grosbache9119e42015-05-13 18:37:00 +00002117 Inst.addOperand(MCOperand::createReg(Mips::A0));
2118 Inst.addOperand(MCOperand::createReg(Mips::S5));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002119 break;
2120 case 4:
Jim Grosbache9119e42015-05-13 18:37:00 +00002121 Inst.addOperand(MCOperand::createReg(Mips::A0));
2122 Inst.addOperand(MCOperand::createReg(Mips::S6));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002123 break;
2124 case 5:
Jim Grosbache9119e42015-05-13 18:37:00 +00002125 Inst.addOperand(MCOperand::createReg(Mips::A0));
2126 Inst.addOperand(MCOperand::createReg(Mips::A1));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002127 break;
2128 case 6:
Jim Grosbache9119e42015-05-13 18:37:00 +00002129 Inst.addOperand(MCOperand::createReg(Mips::A0));
2130 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002131 break;
2132 case 7:
Jim Grosbache9119e42015-05-13 18:37:00 +00002133 Inst.addOperand(MCOperand::createReg(Mips::A0));
2134 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002135 break;
2136 }
2137
2138 return MCDisassembler::Success;
2139}
2140
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002141static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2142 uint64_t Address, const void *Decoder) {
Justin Bogner6499b5f2015-06-23 07:28:57 +00002143 Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002144 return MCDisassembler::Success;
2145}
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002146
2147template <typename InsnType>
2148static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2149 uint64_t Address,
2150 const void *Decoder) {
2151 // We have:
2152 // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
2153 // Invalid if rt == 0
2154 // BGTZALC_MMR6 if rs == 0 && rt != 0
2155 // BLTZALC_MMR6 if rs != 0 && rs == rt
2156 // BLTUC_MMR6 if rs != 0 && rs != rt
2157
2158 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2159 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2160 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2161 bool HasRs = false;
2162 bool HasRt = false;
2163
2164 if (Rt == 0)
2165 return MCDisassembler::Fail;
2166 else if (Rs == 0) {
2167 MI.setOpcode(Mips::BGTZALC_MMR6);
2168 HasRt = true;
2169 }
2170 else if (Rs == Rt) {
2171 MI.setOpcode(Mips::BLTZALC_MMR6);
2172 HasRs = true;
2173 }
2174 else {
2175 MI.setOpcode(Mips::BLTUC_MMR6);
2176 HasRs = true;
2177 HasRt = true;
2178 }
2179
2180 if (HasRs)
2181 MI.addOperand(
2182 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2183
2184 if (HasRt)
2185 MI.addOperand(
2186 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2187
2188 MI.addOperand(MCOperand::createImm(Imm));
2189
2190 return MCDisassembler::Success;
2191}
2192
2193template <typename InsnType>
2194static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2195 uint64_t Address,
2196 const void *Decoder) {
2197 // We have:
2198 // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
2199 // Invalid if rs == 0
2200 // BLEZALC_MMR6 if rs == 0 && rt != 0
2201 // BGEZALC_MMR6 if rs == rt && rt != 0
2202 // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
2203
2204 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2205 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2206 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2207 bool HasRs = false;
2208
2209 if (Rt == 0)
2210 return MCDisassembler::Fail;
2211 else if (Rs == 0)
2212 MI.setOpcode(Mips::BLEZALC_MMR6);
2213 else if (Rs == Rt)
2214 MI.setOpcode(Mips::BGEZALC_MMR6);
2215 else {
2216 HasRs = true;
2217 MI.setOpcode(Mips::BGEUC_MMR6);
2218 }
2219
2220 if (HasRs)
2221 MI.addOperand(
2222 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2223 MI.addOperand(
2224 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2225
2226 MI.addOperand(MCOperand::createImm(Imm));
2227
2228 return MCDisassembler::Success;
2229}