blob: ad247c3e9cb1e9059360b4e160d7475475df9fd7 [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
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +0000197static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
198 unsigned Offset,
199 uint64_t Address,
200 const void *Decoder);
201
Akira Hatanaka71928e62012-04-17 18:03:21 +0000202static DecodeStatus DecodeJumpTarget(MCInst &Inst,
203 unsigned Insn,
204 uint64_t Address,
205 const void *Decoder);
206
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000207static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
208 unsigned Offset,
209 uint64_t Address,
210 const void *Decoder);
211
Zoran Jovanovic84e4d592016-05-17 11:10:15 +0000212static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
213 unsigned Offset,
214 uint64_t Address,
215 const void *Decoder);
216
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000217static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
218 unsigned Offset,
219 uint64_t Address,
220 const void *Decoder);
221
Jozef Kolek9761e962015-01-12 12:03:34 +0000222// DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
223// shifted left by 1 bit.
224static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
225 unsigned Offset,
226 uint64_t Address,
227 const void *Decoder);
228
Jozef Kolek5cfebdd2015-01-21 12:39:30 +0000229// DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
230// shifted left by 1 bit.
231static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
232 unsigned Offset,
233 uint64_t Address,
234 const void *Decoder);
235
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000236// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
237// shifted left by 1 bit.
238static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
239 unsigned Offset,
240 uint64_t Address,
241 const void *Decoder);
242
Zoran Jovanovica887b362015-11-30 12:56:18 +0000243// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
244// shifted left by 1 bit.
245static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
246 unsigned Offset,
247 uint64_t Address,
248 const void *Decoder);
249
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000250// DecodeJumpTargetMM - Decode microMIPS jump target, which is
251// shifted left by 1 bit.
252static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
253 unsigned Insn,
254 uint64_t Address,
255 const void *Decoder);
256
Akira Hatanaka71928e62012-04-17 18:03:21 +0000257static DecodeStatus DecodeMem(MCInst &Inst,
258 unsigned Insn,
259 uint64_t Address,
260 const void *Decoder);
261
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000262static DecodeStatus DecodeMemEVA(MCInst &Inst,
263 unsigned Insn,
264 uint64_t Address,
265 const void *Decoder);
266
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +0000267static DecodeStatus DecodeLoadByte9(MCInst &Inst,
268 unsigned Insn,
269 uint64_t Address,
270 const void *Decoder);
271
272static DecodeStatus DecodeLoadByte15(MCInst &Inst,
273 unsigned Insn,
274 uint64_t Address,
275 const void *Decoder);
276
Daniel Sanders92db6b72014-10-01 08:26:55 +0000277static DecodeStatus DecodeCacheOp(MCInst &Inst,
278 unsigned Insn,
279 uint64_t Address,
280 const void *Decoder);
281
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000282static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
283 unsigned Insn,
284 uint64_t Address,
285 const void *Decoder);
Vladimir Medicdf464ae2015-01-29 11:33:41 +0000286
Jozef Kolekab6d1cc2014-12-23 19:55:34 +0000287static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
288 unsigned Insn,
289 uint64_t Address,
290 const void *Decoder);
291
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +0000292static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
293 unsigned Insn,
294 uint64_t Address,
295 const void *Decoder);
296
Zoran Jovanovicd9790792015-09-09 09:10:46 +0000297static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
298 unsigned Insn,
299 uint64_t Address,
300 const void *Decoder);
301
Daniel Sandersb4484d62014-11-27 17:28:10 +0000302static DecodeStatus DecodeSyncI(MCInst &Inst,
303 unsigned Insn,
304 uint64_t Address,
305 const void *Decoder);
306
Hrvoje Varga18148672015-10-28 11:04:29 +0000307static DecodeStatus DecodeSynciR6(MCInst &Inst,
308 unsigned Insn,
309 uint64_t Address,
310 const void *Decoder);
311
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000312static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
313 uint64_t Address, const void *Decoder);
314
Jozef Kolek315e7ec2014-11-26 18:56:38 +0000315static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
316 unsigned Insn,
317 uint64_t Address,
318 const void *Decoder);
319
Jozef Kolek12c69822014-12-23 16:16:33 +0000320static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
321 unsigned Insn,
322 uint64_t Address,
323 const void *Decoder);
324
Jozef Koleke10a02e2015-01-28 17:27:26 +0000325static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
326 unsigned Insn,
327 uint64_t Address,
328 const void *Decoder);
329
Jozef Kolekd68d424a2015-02-10 12:41:13 +0000330static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
331 unsigned Insn,
332 uint64_t Address,
333 const void *Decoder);
334
Zoran Jovanovica6593ff2015-08-18 12:53:08 +0000335static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
336 unsigned Insn,
337 uint64_t Address,
338 const void *Decoder);
339
Vladimir Medicdde3d582013-09-06 12:30:36 +0000340static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
341 unsigned Insn,
342 uint64_t Address,
343 const void *Decoder);
344
345static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
346 unsigned Insn,
347 uint64_t Address,
348 const void *Decoder);
349
Akira Hatanaka71928e62012-04-17 18:03:21 +0000350static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
351 uint64_t Address,
352 const void *Decoder);
353
Daniel Sanders92db6b72014-10-01 08:26:55 +0000354static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
355 uint64_t Address,
356 const void *Decoder);
357
358static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
359 uint64_t Address,
360 const void *Decoder);
361
Vladimir Medic435cf8a2015-01-21 10:47:36 +0000362static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
363 uint64_t Address,
364 const void *Decoder);
365
Daniel Sanders6a803f62014-06-16 13:13:03 +0000366static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
367 unsigned Insn,
368 uint64_t Address,
369 const void *Decoder);
370
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000371static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
372 unsigned Value,
373 uint64_t Address,
374 const void *Decoder);
375
Daniel Sanders97297772016-03-22 14:40:00 +0000376static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000377 unsigned Value,
378 uint64_t Address,
379 const void *Decoder);
380
Zoran Jovanovic6b28f092015-09-09 13:55:45 +0000381static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
382 unsigned Value,
383 uint64_t Address,
384 const void *Decoder);
385
Daniel Sanders19b7f762016-03-14 11:16:56 +0000386template <unsigned Bits, int Offset, int Scale>
387static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
388 uint64_t Address,
389 const void *Decoder);
390
Daniel Sandersea4f6532015-11-06 12:22:31 +0000391template <unsigned Bits, int Offset>
392static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
Daniel Sanders19b7f762016-03-14 11:16:56 +0000393 uint64_t Address,
394 const void *Decoder) {
395 return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
396 Decoder);
397}
Matheus Almeida779c5932013-11-18 12:32:49 +0000398
Daniel Sanders97297772016-03-22 14:40:00 +0000399template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
400static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
401 uint64_t Address,
402 const void *Decoder);
Daniel Sanders78e89022016-03-11 11:37:50 +0000403
Akira Hatanaka71928e62012-04-17 18:03:21 +0000404static DecodeStatus DecodeInsSize(MCInst &Inst,
405 unsigned Insn,
406 uint64_t Address,
407 const void *Decoder);
408
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000409static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
410 uint64_t Address, const void *Decoder);
411
Zoran Jovanovic28551422014-06-09 09:49:51 +0000412static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
413 uint64_t Address, const void *Decoder);
414
Vladimir Medicb682ddf2014-12-01 11:12:04 +0000415static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
416 uint64_t Address, const void *Decoder);
417
418static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
419 uint64_t Address, const void *Decoder);
420
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000421static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
422 uint64_t Address, const void *Decoder);
423
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000424/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
425/// handle.
426template <typename InsnType>
427static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
428 const void *Decoder);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000429
430template <typename InsnType>
431static DecodeStatus
432DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
433 const void *Decoder);
434
435template <typename InsnType>
436static DecodeStatus
437DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
438 const void *Decoder);
439
440template <typename InsnType>
441static DecodeStatus
442DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
443 const void *Decoder);
444
445template <typename InsnType>
446static DecodeStatus
447DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
448 const void *Decoder);
449
450template <typename InsnType>
451static DecodeStatus
452DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
453 const void *Decoder);
454
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000455template <typename InsnType>
456static DecodeStatus
457DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
458 const void *Decoder);
459
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +0000460template <typename InsnType>
461static DecodeStatus
462DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
463 const void *Decoder);
464
465template <typename InsnType>
466static DecodeStatus
467DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
468 const void *Decoder);
469
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000470static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
471 uint64_t Address,
472 const void *Decoder);
473
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000474static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
475 uint64_t Address,
476 const void *Decoder);
477
Zoran Jovanovic41688672015-02-10 16:36:20 +0000478static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
479 uint64_t Address,
480 const void *Decoder);
481
Akira Hatanaka71928e62012-04-17 18:03:21 +0000482namespace llvm {
483extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
484 TheMips64elTarget;
485}
486
487static MCDisassembler *createMipsDisassembler(
488 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000489 const MCSubtargetInfo &STI,
490 MCContext &Ctx) {
491 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000492}
493
494static MCDisassembler *createMipselDisassembler(
495 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000496 const MCSubtargetInfo &STI,
497 MCContext &Ctx) {
498 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000499}
500
Akira Hatanaka71928e62012-04-17 18:03:21 +0000501extern "C" void LLVMInitializeMipsDisassembler() {
502 // Register the disassembler.
503 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
504 createMipsDisassembler);
505 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
506 createMipselDisassembler);
507 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000508 createMipsDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000509 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000510 createMipselDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000511}
512
Akira Hatanaka71928e62012-04-17 18:03:21 +0000513#include "MipsGenDisassemblerTables.inc"
514
Daniel Sanders5c582b22014-05-22 11:23:21 +0000515static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
Daniel Sandersa19216c2015-02-11 11:28:56 +0000516 const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000517 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
518 return *(RegInfo->getRegClass(RC).begin() + RegNo);
519}
520
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000521template <typename InsnType>
522static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
523 const void *Decoder) {
524 typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
525 // The size of the n field depends on the element size
526 // The register class also depends on this.
527 InsnType tmp = fieldFromInstruction(insn, 17, 5);
528 unsigned NSize = 0;
529 DecodeFN RegDecoder = nullptr;
530 if ((tmp & 0x18) == 0x00) { // INSVE_B
531 NSize = 4;
532 RegDecoder = DecodeMSA128BRegisterClass;
533 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
534 NSize = 3;
535 RegDecoder = DecodeMSA128HRegisterClass;
536 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
537 NSize = 2;
538 RegDecoder = DecodeMSA128WRegisterClass;
539 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
540 NSize = 1;
541 RegDecoder = DecodeMSA128DRegisterClass;
542 } else
543 llvm_unreachable("Invalid encoding");
544
545 assert(NSize != 0 && RegDecoder != nullptr);
546
547 // $wd
548 tmp = fieldFromInstruction(insn, 6, 5);
549 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
550 return MCDisassembler::Fail;
551 // $wd_in
552 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
553 return MCDisassembler::Fail;
554 // $n
555 tmp = fieldFromInstruction(insn, 16, NSize);
Jim Grosbache9119e42015-05-13 18:37:00 +0000556 MI.addOperand(MCOperand::createImm(tmp));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000557 // $ws
558 tmp = fieldFromInstruction(insn, 11, 5);
559 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
560 return MCDisassembler::Fail;
561 // $n2
Jim Grosbache9119e42015-05-13 18:37:00 +0000562 MI.addOperand(MCOperand::createImm(0));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000563
564 return MCDisassembler::Success;
565}
566
Daniel Sanders5c582b22014-05-22 11:23:21 +0000567template <typename InsnType>
568static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
569 uint64_t Address,
570 const void *Decoder) {
571 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
572 // (otherwise we would have matched the ADDI instruction from the earlier
573 // ISA's instead).
574 //
575 // We have:
576 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
577 // BOVC if rs >= rt
578 // BEQZALC if rs == 0 && rt != 0
579 // BEQC if rs < rt && rs != 0
580
581 InsnType Rs = fieldFromInstruction(insn, 21, 5);
582 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000583 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000584 bool HasRs = false;
585
586 if (Rs >= Rt) {
587 MI.setOpcode(Mips::BOVC);
588 HasRs = true;
589 } else if (Rs != 0 && Rs < Rt) {
590 MI.setOpcode(Mips::BEQC);
591 HasRs = true;
592 } else
593 MI.setOpcode(Mips::BEQZALC);
594
595 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000596 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000597 Rs)));
598
Jim Grosbache9119e42015-05-13 18:37:00 +0000599 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000600 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000601 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000602
603 return MCDisassembler::Success;
604}
605
606template <typename InsnType>
607static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
608 uint64_t Address,
609 const void *Decoder) {
610 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
611 // (otherwise we would have matched the ADDI instruction from the earlier
612 // ISA's instead).
613 //
614 // We have:
615 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
616 // BNVC if rs >= rt
617 // BNEZALC if rs == 0 && rt != 0
618 // BNEC if rs < rt && rs != 0
619
620 InsnType Rs = fieldFromInstruction(insn, 21, 5);
621 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000622 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000623 bool HasRs = false;
624
625 if (Rs >= Rt) {
626 MI.setOpcode(Mips::BNVC);
627 HasRs = true;
628 } else if (Rs != 0 && Rs < Rt) {
629 MI.setOpcode(Mips::BNEC);
630 HasRs = true;
631 } else
632 MI.setOpcode(Mips::BNEZALC);
633
634 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000635 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000636 Rs)));
637
Jim Grosbache9119e42015-05-13 18:37:00 +0000638 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000639 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000640 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000641
642 return MCDisassembler::Success;
643}
644
645template <typename InsnType>
646static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
647 uint64_t Address,
648 const void *Decoder) {
649 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
650 // (otherwise we would have matched the BLEZL instruction from the earlier
651 // ISA's instead).
652 //
653 // We have:
654 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
655 // Invalid if rs == 0
656 // BLEZC if rs == 0 && rt != 0
657 // BGEZC if rs == rt && rt != 0
658 // BGEC if rs != rt && rs != 0 && rt != 0
659
660 InsnType Rs = fieldFromInstruction(insn, 21, 5);
661 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000662 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000663 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000664
665 if (Rt == 0)
666 return MCDisassembler::Fail;
667 else if (Rs == 0)
668 MI.setOpcode(Mips::BLEZC);
669 else if (Rs == Rt)
670 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000671 else {
672 HasRs = true;
673 MI.setOpcode(Mips::BGEC);
674 }
675
676 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000677 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000678 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000679
Jim Grosbache9119e42015-05-13 18:37:00 +0000680 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000681 Rt)));
682
Jim Grosbache9119e42015-05-13 18:37:00 +0000683 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000684
685 return MCDisassembler::Success;
686}
687
688template <typename InsnType>
689static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
690 uint64_t Address,
691 const void *Decoder) {
692 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
693 // (otherwise we would have matched the BGTZL instruction from the earlier
694 // ISA's instead).
695 //
696 // We have:
697 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
698 // Invalid if rs == 0
699 // BGTZC if rs == 0 && rt != 0
700 // BLTZC if rs == rt && rt != 0
701 // BLTC if rs != rt && rs != 0 && rt != 0
702
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000703 bool HasRs = false;
704
Daniel Sanders5c582b22014-05-22 11:23:21 +0000705 InsnType Rs = fieldFromInstruction(insn, 21, 5);
706 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000707 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000708
709 if (Rt == 0)
710 return MCDisassembler::Fail;
711 else if (Rs == 0)
712 MI.setOpcode(Mips::BGTZC);
713 else if (Rs == Rt)
714 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000715 else {
716 MI.setOpcode(Mips::BLTC);
717 HasRs = true;
718 }
719
720 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000721 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000722 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000723
Jim Grosbache9119e42015-05-13 18:37:00 +0000724 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000725 Rt)));
726
Jim Grosbache9119e42015-05-13 18:37:00 +0000727 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000728
729 return MCDisassembler::Success;
730}
731
732template <typename InsnType>
733static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
734 uint64_t Address,
735 const void *Decoder) {
736 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
737 // (otherwise we would have matched the BGTZ instruction from the earlier
738 // ISA's instead).
739 //
740 // We have:
741 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
742 // BGTZ if rt == 0
743 // BGTZALC if rs == 0 && rt != 0
744 // BLTZALC if rs != 0 && rs == rt
745 // BLTUC if rs != 0 && rs != rt
746
747 InsnType Rs = fieldFromInstruction(insn, 21, 5);
748 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000749 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000750 bool HasRs = false;
751 bool HasRt = false;
752
753 if (Rt == 0) {
754 MI.setOpcode(Mips::BGTZ);
755 HasRs = true;
756 } else if (Rs == 0) {
757 MI.setOpcode(Mips::BGTZALC);
758 HasRt = true;
759 } else if (Rs == Rt) {
760 MI.setOpcode(Mips::BLTZALC);
761 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000762 } else {
763 MI.setOpcode(Mips::BLTUC);
764 HasRs = true;
765 HasRt = true;
766 }
Daniel Sanders5c582b22014-05-22 11:23:21 +0000767
768 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000769 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000770 Rs)));
771
772 if (HasRt)
Jim Grosbache9119e42015-05-13 18:37:00 +0000773 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000774 Rt)));
775
Jim Grosbache9119e42015-05-13 18:37:00 +0000776 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000777
778 return MCDisassembler::Success;
779}
780
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000781template <typename InsnType>
782static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
783 uint64_t Address,
784 const void *Decoder) {
785 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
786 // (otherwise we would have matched the BLEZL instruction from the earlier
787 // ISA's instead).
788 //
789 // We have:
790 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
791 // Invalid if rs == 0
792 // BLEZALC if rs == 0 && rt != 0
793 // BGEZALC if rs == rt && rt != 0
794 // BGEUC if rs != rt && rs != 0 && rt != 0
795
796 InsnType Rs = fieldFromInstruction(insn, 21, 5);
797 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000798 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000799 bool HasRs = false;
800
801 if (Rt == 0)
802 return MCDisassembler::Fail;
803 else if (Rs == 0)
804 MI.setOpcode(Mips::BLEZALC);
805 else if (Rs == Rt)
806 MI.setOpcode(Mips::BGEZALC);
807 else {
808 HasRs = true;
809 MI.setOpcode(Mips::BGEUC);
810 }
811
812 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000813 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000814 Rs)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000815 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000816 Rt)));
817
Jim Grosbache9119e42015-05-13 18:37:00 +0000818 MI.addOperand(MCOperand::createImm(Imm));
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000819
820 return MCDisassembler::Success;
821}
822
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000823/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
824/// according to the given endianess.
825static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
826 uint64_t &Size, uint32_t &Insn,
827 bool IsBigEndian) {
828 // We want to read exactly 2 Bytes of data.
829 if (Bytes.size() < 2) {
830 Size = 0;
831 return MCDisassembler::Fail;
832 }
833
834 if (IsBigEndian) {
835 Insn = (Bytes[0] << 8) | Bytes[1];
836 } else {
837 Insn = (Bytes[1] << 8) | Bytes[0];
838 }
839
840 return MCDisassembler::Success;
841}
842
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000843/// Read four bytes from the ArrayRef and return 32 bit word sorted
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000844/// according to the given endianess
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000845static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
846 uint64_t &Size, uint32_t &Insn,
847 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000848 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000849 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000850 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000851 return MCDisassembler::Fail;
852 }
853
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000854 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
855 // always precede the low 16 bits in the instruction stream (that is, they
856 // are placed at lower addresses in the instruction stream).
857 //
858 // microMIPS byte ordering:
859 // Big-endian: 0 | 1 | 2 | 3
860 // Little-endian: 1 | 0 | 3 | 2
861
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000862 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000863 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000864 Insn =
865 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
866 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +0000867 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000868 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000869 (Bytes[1] << 24);
870 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000871 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000872 (Bytes[3] << 24);
873 }
Akira Hatanaka71928e62012-04-17 18:03:21 +0000874 }
875
876 return MCDisassembler::Success;
877}
878
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000879DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000880 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000881 uint64_t Address,
882 raw_ostream &VStream,
883 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000884 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000885 DecodeStatus Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000886
Vladimir Medicdde3d582013-09-06 12:30:36 +0000887 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000888 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
Reid Klecknerebee6122015-11-19 21:51:55 +0000889 if (Result == MCDisassembler::Fail)
890 return MCDisassembler::Fail;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000891
Zoran Jovanovicada70912015-09-07 11:56:37 +0000892 if (hasMips32r6()) {
893 DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
894 // Calling the auto-generated decoder function for microMIPS32R6
895 // (and microMIPS64R6) 16-bit instructions.
896 Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
897 Address, this, STI);
898 if (Result != MCDisassembler::Fail) {
899 Size = 2;
900 return Result;
901 }
902 }
903
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000904 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
Zoran Jovanovicada70912015-09-07 11:56:37 +0000905 // Calling the auto-generated decoder function for microMIPS 16-bit
906 // instructions.
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000907 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
908 this, STI);
909 if (Result != MCDisassembler::Fail) {
910 Size = 2;
911 return Result;
912 }
913
914 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
915 if (Result == MCDisassembler::Fail)
916 return MCDisassembler::Fail;
917
Jozef Kolek676d6012015-04-20 14:40:38 +0000918 if (hasMips32r6()) {
919 DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
920 // Calling the auto-generated decoder function.
Zoran Jovanovic366783e2015-08-12 12:45:16 +0000921 Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
Jozef Kolek676d6012015-04-20 14:40:38 +0000922 this, STI);
Zoran Jovanovicada70912015-09-07 11:56:37 +0000923 if (Result != MCDisassembler::Fail) {
924 Size = 4;
925 return Result;
926 }
Jozef Kolek676d6012015-04-20 14:40:38 +0000927 }
Zoran Jovanovic366783e2015-08-12 12:45:16 +0000928
Zoran Jovanovicada70912015-09-07 11:56:37 +0000929 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
930 // Calling the auto-generated decoder function.
931 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
932 this, STI);
Vladimir Medicdde3d582013-09-06 12:30:36 +0000933 if (Result != MCDisassembler::Fail) {
934 Size = 4;
935 return Result;
936 }
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +0000937
Zlatko Buljan6221be82016-03-31 08:51:24 +0000938 if (hasMips32r6() && isFP64()) {
939 DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
940 Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +0000941 Address, this, STI);
942 if (Result != MCDisassembler::Fail) {
943 Size = 4;
944 return Result;
945 }
946 }
947
Reid Klecknerebee6122015-11-19 21:51:55 +0000948 // This is an invalid instruction. Let the disassembler move forward by the
949 // minimum instruction size.
950 Size = 2;
Vladimir Medicdde3d582013-09-06 12:30:36 +0000951 return MCDisassembler::Fail;
952 }
953
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000954 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Reid Klecknerebee6122015-11-19 21:51:55 +0000955 if (Result == MCDisassembler::Fail) {
956 Size = 4;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000957 return MCDisassembler::Fail;
Reid Klecknerebee6122015-11-19 21:51:55 +0000958 }
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000959
Daniel Sandersc171f652014-06-13 13:15:59 +0000960 if (hasCOP3()) {
961 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
962 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000963 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Daniel Sandersc171f652014-06-13 13:15:59 +0000964 if (Result != MCDisassembler::Fail) {
965 Size = 4;
966 return Result;
967 }
968 }
969
970 if (hasMips32r6() && isGP64()) {
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +0000971 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
972 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
973 Address, this, STI);
Daniel Sanders0fa60412014-06-12 13:39:06 +0000974 if (Result != MCDisassembler::Fail) {
975 Size = 4;
976 return Result;
977 }
978 }
979
Daniel Sandersc171f652014-06-13 13:15:59 +0000980 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +0000981 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000982 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000983 Address, this, STI);
984 if (Result != MCDisassembler::Fail) {
985 Size = 4;
986 return Result;
987 }
988 }
989
Kai Nacke3adf9b82015-05-28 16:23:16 +0000990 if (hasCnMips()) {
991 DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
992 Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
993 Address, this, STI);
994 if (Result != MCDisassembler::Fail) {
995 Size = 4;
996 return Result;
997 }
998 }
999
Daniel Sandersa19216c2015-02-11 11:28:56 +00001000 if (isGP64()) {
1001 DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1002 Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1003 Address, this, STI);
1004 if (Result != MCDisassembler::Fail) {
1005 Size = 4;
1006 return Result;
1007 }
1008 }
1009
Daniel Sanders0fa60412014-06-12 13:39:06 +00001010 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +00001011 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001012 Result =
1013 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001014 if (Result != MCDisassembler::Fail) {
1015 Size = 4;
1016 return Result;
1017 }
1018
Reid Klecknerebee6122015-11-19 21:51:55 +00001019 Size = 4;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001020 return MCDisassembler::Fail;
1021}
1022
Reed Kotlerec8a5492013-02-14 03:05:25 +00001023static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1024 unsigned RegNo,
1025 uint64_t Address,
1026 const void *Decoder) {
1027
1028 return MCDisassembler::Fail;
1029
1030}
1031
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001032static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1033 unsigned RegNo,
1034 uint64_t Address,
1035 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001036
1037 if (RegNo > 31)
1038 return MCDisassembler::Fail;
1039
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001040 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001041 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001042 return MCDisassembler::Success;
1043}
1044
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001045static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1046 unsigned RegNo,
1047 uint64_t Address,
1048 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001049 if (RegNo > 7)
1050 return MCDisassembler::Fail;
1051 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001052 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001053 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001054}
1055
Jozef Kolek1904fa22014-11-24 14:25:53 +00001056static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1057 unsigned RegNo,
1058 uint64_t Address,
1059 const void *Decoder) {
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001060 if (RegNo > 7)
1061 return MCDisassembler::Fail;
1062 unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001063 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001064 return MCDisassembler::Success;
Jozef Kolek1904fa22014-11-24 14:25:53 +00001065}
1066
Zoran Jovanovic41688672015-02-10 16:36:20 +00001067static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1068 unsigned RegNo,
1069 uint64_t Address,
1070 const void *Decoder) {
1071 if (RegNo > 7)
1072 return MCDisassembler::Fail;
1073 unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001074 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic41688672015-02-10 16:36:20 +00001075 return MCDisassembler::Success;
1076}
1077
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001078static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1079 unsigned RegNo,
1080 uint64_t Address,
1081 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001082 if (RegNo > 31)
1083 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001084 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001085 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001086 return MCDisassembler::Success;
1087}
1088
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001089static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1090 unsigned RegNo,
1091 uint64_t Address,
1092 const void *Decoder) {
Daniel Sandersa19216c2015-02-11 11:28:56 +00001093 if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001094 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1095
1096 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1097}
1098
Akira Hatanaka654655f2013-08-14 00:53:38 +00001099static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1100 unsigned RegNo,
1101 uint64_t Address,
1102 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001103 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001104}
1105
Akira Hatanaka71928e62012-04-17 18:03:21 +00001106static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1107 unsigned RegNo,
1108 uint64_t Address,
1109 const void *Decoder) {
1110 if (RegNo > 31)
1111 return MCDisassembler::Fail;
1112
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001113 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001114 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001115 return MCDisassembler::Success;
1116}
1117
1118static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1119 unsigned RegNo,
1120 uint64_t Address,
1121 const void *Decoder) {
1122 if (RegNo > 31)
1123 return MCDisassembler::Fail;
1124
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001125 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001126 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001127 return MCDisassembler::Success;
1128}
1129
1130static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1131 unsigned RegNo,
1132 uint64_t Address,
1133 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +00001134 if (RegNo > 31)
1135 return MCDisassembler::Fail;
1136 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001137 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001138 return MCDisassembler::Success;
1139}
1140
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001141static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1142 unsigned RegNo,
1143 uint64_t Address,
1144 const void *Decoder) {
1145 if (RegNo > 7)
1146 return MCDisassembler::Fail;
1147 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001148 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001149 return MCDisassembler::Success;
1150}
1151
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001152static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1153 uint64_t Address,
1154 const void *Decoder) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001155 if (RegNo > 31)
1156 return MCDisassembler::Fail;
1157
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001158 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001159 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders0fa60412014-06-12 13:39:06 +00001160 return MCDisassembler::Success;
1161}
1162
Akira Hatanaka71928e62012-04-17 18:03:21 +00001163static DecodeStatus DecodeMem(MCInst &Inst,
1164 unsigned Insn,
1165 uint64_t Address,
1166 const void *Decoder) {
1167 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001168 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1169 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001170
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001171 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1172 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001173
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001174 if (Inst.getOpcode() == Mips::SC ||
1175 Inst.getOpcode() == Mips::SCD)
Jim Grosbache9119e42015-05-13 18:37:00 +00001176 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001177
1178 Inst.addOperand(MCOperand::createReg(Reg));
1179 Inst.addOperand(MCOperand::createReg(Base));
1180 Inst.addOperand(MCOperand::createImm(Offset));
1181
1182 return MCDisassembler::Success;
1183}
1184
1185static DecodeStatus DecodeMemEVA(MCInst &Inst,
1186 unsigned Insn,
1187 uint64_t Address,
1188 const void *Decoder) {
1189 int Offset = SignExtend32<9>(Insn >> 7);
1190 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1191 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1192
1193 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1194 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1195
1196 if (Inst.getOpcode() == Mips::SCE)
1197 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001198
Jim Grosbache9119e42015-05-13 18:37:00 +00001199 Inst.addOperand(MCOperand::createReg(Reg));
1200 Inst.addOperand(MCOperand::createReg(Base));
1201 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001202
1203 return MCDisassembler::Success;
1204}
1205
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +00001206static DecodeStatus DecodeLoadByte9(MCInst &Inst,
1207 unsigned Insn,
1208 uint64_t Address,
1209 const void *Decoder) {
1210 int Offset = SignExtend32<9>(Insn & 0x1ff);
1211 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1212 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1213
1214 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1215 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1216
1217 Inst.addOperand(MCOperand::createReg(Reg));
1218 Inst.addOperand(MCOperand::createReg(Base));
1219 Inst.addOperand(MCOperand::createImm(Offset));
1220
1221 return MCDisassembler::Success;
1222}
1223
1224static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1225 unsigned Insn,
1226 uint64_t Address,
1227 const void *Decoder) {
1228 int Offset = SignExtend32<16>(Insn & 0xffff);
1229 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1230 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1231
1232 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1233 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1234
1235 Inst.addOperand(MCOperand::createReg(Reg));
1236 Inst.addOperand(MCOperand::createReg(Base));
1237 Inst.addOperand(MCOperand::createImm(Offset));
1238
1239 return MCDisassembler::Success;
1240}
1241
Daniel Sanders92db6b72014-10-01 08:26:55 +00001242static DecodeStatus DecodeCacheOp(MCInst &Inst,
1243 unsigned Insn,
1244 uint64_t Address,
1245 const void *Decoder) {
1246 int Offset = SignExtend32<16>(Insn & 0xffff);
1247 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1248 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1249
1250 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1251
Jim Grosbache9119e42015-05-13 18:37:00 +00001252 Inst.addOperand(MCOperand::createReg(Base));
1253 Inst.addOperand(MCOperand::createImm(Offset));
1254 Inst.addOperand(MCOperand::createImm(Hint));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001255
1256 return MCDisassembler::Success;
1257}
1258
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001259static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1260 unsigned Insn,
1261 uint64_t Address,
1262 const void *Decoder) {
1263 int Offset = SignExtend32<12>(Insn & 0xfff);
1264 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1265 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1266
1267 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1268
Jim Grosbache9119e42015-05-13 18:37:00 +00001269 Inst.addOperand(MCOperand::createReg(Base));
1270 Inst.addOperand(MCOperand::createImm(Offset));
1271 Inst.addOperand(MCOperand::createImm(Hint));
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001272
1273 return MCDisassembler::Success;
1274}
1275
Zoran Jovanovicd9790792015-09-09 09:10:46 +00001276static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1277 unsigned Insn,
1278 uint64_t Address,
1279 const void *Decoder) {
1280 int Offset = SignExtend32<9>(Insn & 0x1ff);
1281 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1282 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1283
1284 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1285
1286 Inst.addOperand(MCOperand::createReg(Base));
1287 Inst.addOperand(MCOperand::createImm(Offset));
1288 Inst.addOperand(MCOperand::createImm(Hint));
1289
1290 return MCDisassembler::Success;
1291}
1292
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001293static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1294 unsigned Insn,
1295 uint64_t Address,
1296 const void *Decoder) {
1297 int Offset = SignExtend32<9>(Insn >> 7);
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001298 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1299 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1300
1301 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1302
Jim Grosbache9119e42015-05-13 18:37:00 +00001303 Inst.addOperand(MCOperand::createReg(Base));
1304 Inst.addOperand(MCOperand::createImm(Offset));
1305 Inst.addOperand(MCOperand::createImm(Hint));
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001306
1307 return MCDisassembler::Success;
1308}
1309
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +00001310static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
1311 unsigned Insn,
1312 uint64_t Address,
1313 const void *Decoder) {
1314 int Offset = SignExtend32<9>(Insn & 0x1ff);
1315 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1316 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1317
1318 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1319 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1320
1321 Inst.addOperand(MCOperand::createReg(Reg));
1322 Inst.addOperand(MCOperand::createReg(Base));
1323 Inst.addOperand(MCOperand::createImm(Offset));
1324
1325 return MCDisassembler::Success;
1326}
1327
Daniel Sandersb4484d62014-11-27 17:28:10 +00001328static DecodeStatus DecodeSyncI(MCInst &Inst,
1329 unsigned Insn,
1330 uint64_t Address,
1331 const void *Decoder) {
1332 int Offset = SignExtend32<16>(Insn & 0xffff);
1333 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1334
1335 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1336
Jim Grosbache9119e42015-05-13 18:37:00 +00001337 Inst.addOperand(MCOperand::createReg(Base));
1338 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sandersb4484d62014-11-27 17:28:10 +00001339
1340 return MCDisassembler::Success;
1341}
1342
Hrvoje Varga18148672015-10-28 11:04:29 +00001343static DecodeStatus DecodeSynciR6(MCInst &Inst,
1344 unsigned Insn,
1345 uint64_t Address,
1346 const void *Decoder) {
1347 int Immediate = SignExtend32<16>(Insn & 0xffff);
1348 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1349
1350 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1351
1352 Inst.addOperand(MCOperand::createReg(Base));
1353 Inst.addOperand(MCOperand::createImm(Immediate));
1354
1355 return MCDisassembler::Success;
1356}
1357
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001358static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1359 uint64_t Address, const void *Decoder) {
1360 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1361 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1362 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1363
1364 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1365 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1366
Jim Grosbache9119e42015-05-13 18:37:00 +00001367 Inst.addOperand(MCOperand::createReg(Reg));
1368 Inst.addOperand(MCOperand::createReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001369
1370 // The immediate field of an LD/ST instruction is scaled which means it must
1371 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1372 // data format.
1373 // .b - 1 byte
1374 // .h - 2 bytes
1375 // .w - 4 bytes
1376 // .d - 8 bytes
1377 switch(Inst.getOpcode())
1378 {
1379 default:
1380 assert (0 && "Unexpected instruction");
1381 return MCDisassembler::Fail;
1382 break;
1383 case Mips::LD_B:
1384 case Mips::ST_B:
Jim Grosbache9119e42015-05-13 18:37:00 +00001385 Inst.addOperand(MCOperand::createImm(Offset));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001386 break;
1387 case Mips::LD_H:
1388 case Mips::ST_H:
Jim Grosbache9119e42015-05-13 18:37:00 +00001389 Inst.addOperand(MCOperand::createImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001390 break;
1391 case Mips::LD_W:
1392 case Mips::ST_W:
Jim Grosbache9119e42015-05-13 18:37:00 +00001393 Inst.addOperand(MCOperand::createImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001394 break;
1395 case Mips::LD_D:
1396 case Mips::ST_D:
Jim Grosbache9119e42015-05-13 18:37:00 +00001397 Inst.addOperand(MCOperand::createImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001398 break;
1399 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001400
1401 return MCDisassembler::Success;
1402}
1403
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001404static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1405 unsigned Insn,
1406 uint64_t Address,
1407 const void *Decoder) {
1408 unsigned Offset = Insn & 0xf;
1409 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1410 unsigned Base = fieldFromInstruction(Insn, 4, 3);
1411
1412 switch (Inst.getOpcode()) {
1413 case Mips::LBU16_MM:
1414 case Mips::LHU16_MM:
1415 case Mips::LW16_MM:
1416 if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1417 == MCDisassembler::Fail)
1418 return MCDisassembler::Fail;
1419 break;
1420 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001421 case Mips::SB16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001422 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001423 case Mips::SH16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001424 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001425 case Mips::SW16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001426 if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1427 == MCDisassembler::Fail)
1428 return MCDisassembler::Fail;
1429 break;
1430 }
1431
1432 if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1433 == MCDisassembler::Fail)
1434 return MCDisassembler::Fail;
1435
1436 switch (Inst.getOpcode()) {
1437 case Mips::LBU16_MM:
1438 if (Offset == 0xf)
Jim Grosbache9119e42015-05-13 18:37:00 +00001439 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001440 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001441 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001442 break;
1443 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001444 case Mips::SB16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001445 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001446 break;
1447 case Mips::LHU16_MM:
1448 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001449 case Mips::SH16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001450 Inst.addOperand(MCOperand::createImm(Offset << 1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001451 break;
1452 case Mips::LW16_MM:
1453 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001454 case Mips::SW16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001455 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001456 break;
1457 }
1458
1459 return MCDisassembler::Success;
1460}
1461
Jozef Kolek12c69822014-12-23 16:16:33 +00001462static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1463 unsigned Insn,
1464 uint64_t Address,
1465 const void *Decoder) {
1466 unsigned Offset = Insn & 0x1F;
1467 unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1468
1469 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1470
Jim Grosbache9119e42015-05-13 18:37:00 +00001471 Inst.addOperand(MCOperand::createReg(Reg));
1472 Inst.addOperand(MCOperand::createReg(Mips::SP));
1473 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek12c69822014-12-23 16:16:33 +00001474
1475 return MCDisassembler::Success;
1476}
1477
Jozef Koleke10a02e2015-01-28 17:27:26 +00001478static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1479 unsigned Insn,
1480 uint64_t Address,
1481 const void *Decoder) {
1482 unsigned Offset = Insn & 0x7F;
1483 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1484
1485 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1486
Jim Grosbache9119e42015-05-13 18:37:00 +00001487 Inst.addOperand(MCOperand::createReg(Reg));
1488 Inst.addOperand(MCOperand::createReg(Mips::GP));
1489 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Koleke10a02e2015-01-28 17:27:26 +00001490
1491 return MCDisassembler::Success;
1492}
1493
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001494static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1495 unsigned Insn,
1496 uint64_t Address,
1497 const void *Decoder) {
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001498 int Offset;
1499 switch (Inst.getOpcode()) {
1500 case Mips::LWM16_MMR6:
1501 case Mips::SWM16_MMR6:
1502 Offset = fieldFromInstruction(Insn, 4, 4);
1503 break;
1504 default:
1505 Offset = SignExtend32<4>(Insn & 0xf);
1506 break;
1507 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001508
1509 if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1510 == MCDisassembler::Fail)
1511 return MCDisassembler::Fail;
1512
Jim Grosbache9119e42015-05-13 18:37:00 +00001513 Inst.addOperand(MCOperand::createReg(Mips::SP));
1514 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001515
1516 return MCDisassembler::Success;
1517}
1518
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001519static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1520 unsigned Insn,
1521 uint64_t Address,
1522 const void *Decoder) {
1523 int Offset = SignExtend32<9>(Insn & 0x1ff);
1524 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1525 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1526
1527 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1528 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1529
Hrvoje Varga3ef4dd72015-10-15 08:11:50 +00001530 if (Inst.getOpcode() == Mips::SCE_MM)
1531 Inst.addOperand(MCOperand::createReg(Reg));
1532
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001533 Inst.addOperand(MCOperand::createReg(Reg));
1534 Inst.addOperand(MCOperand::createReg(Base));
1535 Inst.addOperand(MCOperand::createImm(Offset));
1536
1537 return MCDisassembler::Success;
1538}
1539
Vladimir Medicdde3d582013-09-06 12:30:36 +00001540static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1541 unsigned Insn,
1542 uint64_t Address,
1543 const void *Decoder) {
1544 int Offset = SignExtend32<12>(Insn & 0x0fff);
1545 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1546 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1547
1548 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1549 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1550
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001551 switch (Inst.getOpcode()) {
1552 case Mips::SWM32_MM:
1553 case Mips::LWM32_MM:
1554 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1555 == MCDisassembler::Fail)
1556 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001557 Inst.addOperand(MCOperand::createReg(Base));
1558 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001559 break;
1560 case Mips::SC_MM:
Jim Grosbache9119e42015-05-13 18:37:00 +00001561 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001562 // fallthrough
1563 default:
Jim Grosbache9119e42015-05-13 18:37:00 +00001564 Inst.addOperand(MCOperand::createReg(Reg));
Zlatko Buljanba553a62016-05-09 08:07:28 +00001565 if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1566 Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
Jim Grosbache9119e42015-05-13 18:37:00 +00001567 Inst.addOperand(MCOperand::createReg(Reg+1));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001568
Jim Grosbache9119e42015-05-13 18:37:00 +00001569 Inst.addOperand(MCOperand::createReg(Base));
1570 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001571 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001572
1573 return MCDisassembler::Success;
1574}
1575
1576static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1577 unsigned Insn,
1578 uint64_t Address,
1579 const void *Decoder) {
1580 int Offset = SignExtend32<16>(Insn & 0xffff);
1581 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1582 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1583
1584 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1585 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1586
Jim Grosbache9119e42015-05-13 18:37:00 +00001587 Inst.addOperand(MCOperand::createReg(Reg));
1588 Inst.addOperand(MCOperand::createReg(Base));
1589 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medicdde3d582013-09-06 12:30:36 +00001590
1591 return MCDisassembler::Success;
1592}
1593
Akira Hatanaka71928e62012-04-17 18:03:21 +00001594static DecodeStatus DecodeFMem(MCInst &Inst,
1595 unsigned Insn,
1596 uint64_t Address,
1597 const void *Decoder) {
1598 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001599 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1600 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001601
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001602 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001603 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001604
Jim Grosbache9119e42015-05-13 18:37:00 +00001605 Inst.addOperand(MCOperand::createReg(Reg));
1606 Inst.addOperand(MCOperand::createReg(Base));
1607 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001608
1609 return MCDisassembler::Success;
1610}
1611
Daniel Sanders92db6b72014-10-01 08:26:55 +00001612static DecodeStatus DecodeFMem2(MCInst &Inst,
1613 unsigned Insn,
1614 uint64_t Address,
1615 const void *Decoder) {
1616 int Offset = SignExtend32<16>(Insn & 0xffff);
1617 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1618 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1619
1620 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1621 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1622
Jim Grosbache9119e42015-05-13 18:37:00 +00001623 Inst.addOperand(MCOperand::createReg(Reg));
1624 Inst.addOperand(MCOperand::createReg(Base));
1625 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001626
1627 return MCDisassembler::Success;
1628}
1629
1630static DecodeStatus DecodeFMem3(MCInst &Inst,
1631 unsigned Insn,
1632 uint64_t Address,
1633 const void *Decoder) {
1634 int Offset = SignExtend32<16>(Insn & 0xffff);
1635 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1636 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1637
1638 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1639 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1640
Jim Grosbache9119e42015-05-13 18:37:00 +00001641 Inst.addOperand(MCOperand::createReg(Reg));
1642 Inst.addOperand(MCOperand::createReg(Base));
1643 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001644
1645 return MCDisassembler::Success;
1646}
1647
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001648static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1649 unsigned Insn,
1650 uint64_t Address,
1651 const void *Decoder) {
1652 int Offset = SignExtend32<11>(Insn & 0x07ff);
1653 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1654 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1655
1656 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1657 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1658
Jim Grosbache9119e42015-05-13 18:37:00 +00001659 Inst.addOperand(MCOperand::createReg(Reg));
1660 Inst.addOperand(MCOperand::createReg(Base));
1661 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001662
1663 return MCDisassembler::Success;
1664}
Daniel Sanders6a803f62014-06-16 13:13:03 +00001665static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1666 unsigned Insn,
1667 uint64_t Address,
1668 const void *Decoder) {
1669 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1670 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1671 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1672
1673 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1674 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1675
1676 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
Jim Grosbache9119e42015-05-13 18:37:00 +00001677 Inst.addOperand(MCOperand::createReg(Rt));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001678 }
1679
Jim Grosbache9119e42015-05-13 18:37:00 +00001680 Inst.addOperand(MCOperand::createReg(Rt));
1681 Inst.addOperand(MCOperand::createReg(Base));
1682 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001683
1684 return MCDisassembler::Success;
1685}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001686
1687static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1688 unsigned RegNo,
1689 uint64_t Address,
1690 const void *Decoder) {
1691 // Currently only hardware register 29 is supported.
1692 if (RegNo != 29)
1693 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001694 Inst.addOperand(MCOperand::createReg(Mips::HWR29));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001695 return MCDisassembler::Success;
1696}
1697
Akira Hatanaka71928e62012-04-17 18:03:21 +00001698static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1699 unsigned RegNo,
1700 uint64_t Address,
1701 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001702 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001703 return MCDisassembler::Fail;
1704
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001705 ;
1706 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
Jim Grosbache9119e42015-05-13 18:37:00 +00001707 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001708 return MCDisassembler::Success;
1709}
1710
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001711static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1712 unsigned RegNo,
1713 uint64_t Address,
1714 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001715 if (RegNo >= 4)
1716 return MCDisassembler::Fail;
1717
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001718 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001719 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001720 return MCDisassembler::Success;
1721}
1722
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001723static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1724 unsigned RegNo,
1725 uint64_t Address,
1726 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001727 if (RegNo >= 4)
1728 return MCDisassembler::Fail;
1729
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001730 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001731 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001732 return MCDisassembler::Success;
1733}
1734
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001735static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
1736 unsigned RegNo,
1737 uint64_t Address,
1738 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001739 if (RegNo >= 4)
1740 return MCDisassembler::Fail;
1741
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001742 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001743 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001744 return MCDisassembler::Success;
1745}
1746
Jack Carter3eb663b2013-09-26 00:09:46 +00001747static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1748 unsigned RegNo,
1749 uint64_t Address,
1750 const void *Decoder) {
1751 if (RegNo > 31)
1752 return MCDisassembler::Fail;
1753
1754 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001755 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter3eb663b2013-09-26 00:09:46 +00001756 return MCDisassembler::Success;
1757}
1758
Jack Carter5dc8ac92013-09-25 23:50:44 +00001759static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1760 unsigned RegNo,
1761 uint64_t Address,
1762 const void *Decoder) {
1763 if (RegNo > 31)
1764 return MCDisassembler::Fail;
1765
1766 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001767 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001768 return MCDisassembler::Success;
1769}
1770
1771static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1772 unsigned RegNo,
1773 uint64_t Address,
1774 const void *Decoder) {
1775 if (RegNo > 31)
1776 return MCDisassembler::Fail;
1777
1778 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001779 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001780 return MCDisassembler::Success;
1781}
1782
1783static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1784 unsigned RegNo,
1785 uint64_t Address,
1786 const void *Decoder) {
1787 if (RegNo > 31)
1788 return MCDisassembler::Fail;
1789
1790 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001791 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001792 return MCDisassembler::Success;
1793}
1794
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001795static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1796 unsigned RegNo,
1797 uint64_t Address,
1798 const void *Decoder) {
1799 if (RegNo > 7)
1800 return MCDisassembler::Fail;
1801
1802 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001803 Inst.addOperand(MCOperand::createReg(Reg));
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001804 return MCDisassembler::Success;
1805}
1806
Daniel Sandersa3134fa2015-06-27 15:39:19 +00001807static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1808 unsigned RegNo,
1809 uint64_t Address,
1810 const void *Decoder) {
1811 if (RegNo > 31)
1812 return MCDisassembler::Fail;
1813
1814 unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1815 Inst.addOperand(MCOperand::createReg(Reg));
1816 return MCDisassembler::Success;
1817}
1818
Daniel Sanders2a83d682014-05-21 12:56:39 +00001819static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1820 unsigned RegNo,
1821 uint64_t Address,
1822 const void *Decoder) {
1823 if (RegNo > 31)
1824 return MCDisassembler::Fail;
1825
1826 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001827 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders2a83d682014-05-21 12:56:39 +00001828 return MCDisassembler::Success;
1829}
1830
Akira Hatanaka71928e62012-04-17 18:03:21 +00001831static DecodeStatus DecodeBranchTarget(MCInst &Inst,
1832 unsigned Offset,
1833 uint64_t Address,
1834 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001835 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00001836 Inst.addOperand(MCOperand::createImm(BranchOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001837 return MCDisassembler::Success;
1838}
1839
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +00001840static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
1841 unsigned Offset,
1842 uint64_t Address,
1843 const void *Decoder) {
1844 int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
1845 Inst.addOperand(MCOperand::createImm(BranchOffset));
1846 return MCDisassembler::Success;
1847}
1848
Akira Hatanaka71928e62012-04-17 18:03:21 +00001849static DecodeStatus DecodeJumpTarget(MCInst &Inst,
1850 unsigned Insn,
1851 uint64_t Address,
1852 const void *Decoder) {
1853
Jim Grosbachecaef492012-08-14 19:06:05 +00001854 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00001855 Inst.addOperand(MCOperand::createImm(JumpOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001856 return MCDisassembler::Success;
1857}
1858
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001859static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
1860 unsigned Offset,
1861 uint64_t Address,
1862 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00001863 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001864
Jim Grosbache9119e42015-05-13 18:37:00 +00001865 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001866 return MCDisassembler::Success;
1867}
1868
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00001869static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
1870 unsigned Offset,
1871 uint64_t Address,
1872 const void *Decoder) {
1873 int32_t BranchOffset = SignExtend32<21>(Offset) << 1;
1874
1875 Inst.addOperand(MCOperand::createImm(BranchOffset));
1876 return MCDisassembler::Success;
1877}
1878
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001879static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
1880 unsigned Offset,
1881 uint64_t Address,
1882 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00001883 int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 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
Jozef Kolek9761e962015-01-12 12:03:34 +00001889static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
1890 unsigned Offset,
1891 uint64_t Address,
1892 const void *Decoder) {
1893 int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001894 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek9761e962015-01-12 12:03:34 +00001895 return MCDisassembler::Success;
1896}
1897
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00001898static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
1899 unsigned Offset,
1900 uint64_t Address,
1901 const void *Decoder) {
1902 int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001903 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00001904 return MCDisassembler::Success;
1905}
1906
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001907static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
1908 unsigned Offset,
1909 uint64_t Address,
1910 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001911 int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00001912 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001913 return MCDisassembler::Success;
1914}
1915
Zoran Jovanovica887b362015-11-30 12:56:18 +00001916static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
1917 unsigned Offset,
1918 uint64_t Address,
1919 const void *Decoder) {
1920 int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
1921
1922 Inst.addOperand(MCOperand::createImm(BranchOffset));
1923 return MCDisassembler::Success;
1924}
1925
Zoran Jovanovic507e0842013-10-29 16:38:59 +00001926static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1927 unsigned Insn,
1928 uint64_t Address,
1929 const void *Decoder) {
1930 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001931 Inst.addOperand(MCOperand::createImm(JumpOffset));
Zoran Jovanovic507e0842013-10-29 16:38:59 +00001932 return MCDisassembler::Success;
1933}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001934
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001935static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1936 unsigned Value,
1937 uint64_t Address,
1938 const void *Decoder) {
1939 if (Value == 0)
Jim Grosbache9119e42015-05-13 18:37:00 +00001940 Inst.addOperand(MCOperand::createImm(1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001941 else if (Value == 0x7)
Jim Grosbache9119e42015-05-13 18:37:00 +00001942 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001943 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001944 Inst.addOperand(MCOperand::createImm(Value << 2));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001945 return MCDisassembler::Success;
1946}
1947
Daniel Sanders97297772016-03-22 14:40:00 +00001948static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001949 unsigned Value,
1950 uint64_t Address,
1951 const void *Decoder) {
1952 if (Value == 0x7F)
Jim Grosbache9119e42015-05-13 18:37:00 +00001953 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001954 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001955 Inst.addOperand(MCOperand::createImm(Value));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001956 return MCDisassembler::Success;
1957}
1958
Zoran Jovanovic6b28f092015-09-09 13:55:45 +00001959static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
1960 unsigned Value,
1961 uint64_t Address,
1962 const void *Decoder) {
1963 Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
1964 return MCDisassembler::Success;
1965}
1966
Daniel Sanders19b7f762016-03-14 11:16:56 +00001967template <unsigned Bits, int Offset, int Scale>
1968static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
1969 uint64_t Address,
1970 const void *Decoder) {
Daniel Sandersea4f6532015-11-06 12:22:31 +00001971 Value &= ((1 << Bits) - 1);
Daniel Sanders19b7f762016-03-14 11:16:56 +00001972 Value *= Scale;
Daniel Sandersea4f6532015-11-06 12:22:31 +00001973 Inst.addOperand(MCOperand::createImm(Value + Offset));
Matheus Almeida779c5932013-11-18 12:32:49 +00001974 return MCDisassembler::Success;
1975}
1976
Daniel Sanders97297772016-03-22 14:40:00 +00001977template <unsigned Bits, int Offset, int ScaleBy>
1978static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
1979 uint64_t Address,
1980 const void *Decoder) {
1981 int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
Daniel Sanders78e89022016-03-11 11:37:50 +00001982 Inst.addOperand(MCOperand::createImm(Imm + Offset));
1983 return MCDisassembler::Success;
1984}
1985
Akira Hatanaka71928e62012-04-17 18:03:21 +00001986static DecodeStatus DecodeInsSize(MCInst &Inst,
1987 unsigned Insn,
1988 uint64_t Address,
1989 const void *Decoder) {
1990 // First we need to grab the pos(lsb) from MCInst.
1991 int Pos = Inst.getOperand(2).getImm();
1992 int Size = (int) Insn - Pos + 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001993 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001994 return MCDisassembler::Success;
1995}
1996
Daniel Sandersb59e1a42014-05-15 10:45:58 +00001997static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1998 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00001999 Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002000 return MCDisassembler::Success;
2001}
Zoran Jovanovic28551422014-06-09 09:49:51 +00002002
2003static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2004 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002005 Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00002006 return MCDisassembler::Success;
2007}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002008
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002009static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2010 uint64_t Address, const void *Decoder) {
2011 int32_t DecodedValue;
2012 switch (Insn) {
2013 case 0: DecodedValue = 256; break;
2014 case 1: DecodedValue = 257; break;
2015 case 510: DecodedValue = -258; break;
2016 case 511: DecodedValue = -257; break;
2017 default: DecodedValue = SignExtend32<9>(Insn); break;
2018 }
Jim Grosbache9119e42015-05-13 18:37:00 +00002019 Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002020 return MCDisassembler::Success;
2021}
2022
2023static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2024 uint64_t Address, const void *Decoder) {
2025 // Insn must be >= 0, since it is unsigned that condition is always true.
2026 assert(Insn < 16);
2027 int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2028 255, 32768, 65535};
Jim Grosbache9119e42015-05-13 18:37:00 +00002029 Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002030 return MCDisassembler::Success;
2031}
2032
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002033static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2034 unsigned Insn,
2035 uint64_t Address,
2036 const void *Decoder) {
2037 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
Zoran Jovanovicdc4b8c22015-09-15 15:21:27 +00002038 Mips::S6, Mips::S7, Mips::FP};
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002039 unsigned RegNum;
2040
2041 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002042
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002043 // Empty register lists are not allowed.
2044 if (RegLst == 0)
2045 return MCDisassembler::Fail;
2046
2047 RegNum = RegLst & 0xf;
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002048
2049 // RegLst values 10-15, and 26-31 are reserved.
2050 if (RegNum > 9)
2051 return MCDisassembler::Fail;
2052
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002053 for (unsigned i = 0; i < RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002054 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002055
2056 if (RegLst & 0x10)
Jim Grosbache9119e42015-05-13 18:37:00 +00002057 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002058
2059 return MCDisassembler::Success;
2060}
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002061
2062static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2063 uint64_t Address,
2064 const void *Decoder) {
2065 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00002066 unsigned RegLst;
2067 switch(Inst.getOpcode()) {
2068 default:
2069 RegLst = fieldFromInstruction(Insn, 4, 2);
2070 break;
2071 case Mips::LWM16_MMR6:
2072 case Mips::SWM16_MMR6:
2073 RegLst = fieldFromInstruction(Insn, 8, 2);
2074 break;
2075 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002076 unsigned RegNum = RegLst & 0x3;
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002077
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002078 for (unsigned i = 0; i <= RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002079 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002080
Jim Grosbache9119e42015-05-13 18:37:00 +00002081 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002082
2083 return MCDisassembler::Success;
2084}
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002085
Zoran Jovanovic41688672015-02-10 16:36:20 +00002086static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
2087 uint64_t Address, const void *Decoder) {
2088
2089 unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2090
2091 switch (RegPair) {
2092 default:
2093 return MCDisassembler::Fail;
2094 case 0:
Jim Grosbache9119e42015-05-13 18:37:00 +00002095 Inst.addOperand(MCOperand::createReg(Mips::A1));
2096 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002097 break;
2098 case 1:
Jim Grosbache9119e42015-05-13 18:37:00 +00002099 Inst.addOperand(MCOperand::createReg(Mips::A1));
2100 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002101 break;
2102 case 2:
Jim Grosbache9119e42015-05-13 18:37:00 +00002103 Inst.addOperand(MCOperand::createReg(Mips::A2));
2104 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002105 break;
2106 case 3:
Jim Grosbache9119e42015-05-13 18:37:00 +00002107 Inst.addOperand(MCOperand::createReg(Mips::A0));
2108 Inst.addOperand(MCOperand::createReg(Mips::S5));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002109 break;
2110 case 4:
Jim Grosbache9119e42015-05-13 18:37:00 +00002111 Inst.addOperand(MCOperand::createReg(Mips::A0));
2112 Inst.addOperand(MCOperand::createReg(Mips::S6));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002113 break;
2114 case 5:
Jim Grosbache9119e42015-05-13 18:37:00 +00002115 Inst.addOperand(MCOperand::createReg(Mips::A0));
2116 Inst.addOperand(MCOperand::createReg(Mips::A1));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002117 break;
2118 case 6:
Jim Grosbache9119e42015-05-13 18:37:00 +00002119 Inst.addOperand(MCOperand::createReg(Mips::A0));
2120 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002121 break;
2122 case 7:
Jim Grosbache9119e42015-05-13 18:37:00 +00002123 Inst.addOperand(MCOperand::createReg(Mips::A0));
2124 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002125 break;
2126 }
2127
2128 return MCDisassembler::Success;
2129}
2130
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002131static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2132 uint64_t Address, const void *Decoder) {
Justin Bogner6499b5f2015-06-23 07:28:57 +00002133 Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002134 return MCDisassembler::Success;
2135}
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002136
2137template <typename InsnType>
2138static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2139 uint64_t Address,
2140 const void *Decoder) {
2141 // We have:
2142 // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
2143 // Invalid if rt == 0
2144 // BGTZALC_MMR6 if rs == 0 && rt != 0
2145 // BLTZALC_MMR6 if rs != 0 && rs == rt
2146 // BLTUC_MMR6 if rs != 0 && rs != rt
2147
2148 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2149 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2150 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2151 bool HasRs = false;
2152 bool HasRt = false;
2153
2154 if (Rt == 0)
2155 return MCDisassembler::Fail;
2156 else if (Rs == 0) {
2157 MI.setOpcode(Mips::BGTZALC_MMR6);
2158 HasRt = true;
2159 }
2160 else if (Rs == Rt) {
2161 MI.setOpcode(Mips::BLTZALC_MMR6);
2162 HasRs = true;
2163 }
2164 else {
2165 MI.setOpcode(Mips::BLTUC_MMR6);
2166 HasRs = true;
2167 HasRt = true;
2168 }
2169
2170 if (HasRs)
2171 MI.addOperand(
2172 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2173
2174 if (HasRt)
2175 MI.addOperand(
2176 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2177
2178 MI.addOperand(MCOperand::createImm(Imm));
2179
2180 return MCDisassembler::Success;
2181}
2182
2183template <typename InsnType>
2184static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2185 uint64_t Address,
2186 const void *Decoder) {
2187 // We have:
2188 // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
2189 // Invalid if rs == 0
2190 // BLEZALC_MMR6 if rs == 0 && rt != 0
2191 // BGEZALC_MMR6 if rs == rt && rt != 0
2192 // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
2193
2194 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2195 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2196 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2197 bool HasRs = false;
2198
2199 if (Rt == 0)
2200 return MCDisassembler::Fail;
2201 else if (Rs == 0)
2202 MI.setOpcode(Mips::BLEZALC_MMR6);
2203 else if (Rs == Rt)
2204 MI.setOpcode(Mips::BGEZALC_MMR6);
2205 else {
2206 HasRs = true;
2207 MI.setOpcode(Mips::BGEUC_MMR6);
2208 }
2209
2210 if (HasRs)
2211 MI.addOperand(
2212 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2213 MI.addOperand(
2214 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2215
2216 MI.addOperand(MCOperand::createImm(Imm));
2217
2218 return MCDisassembler::Success;
2219}