blob: c77cc47e1af4d9135bc542184900f15f39e883b1 [file] [log] [blame]
Akira Hatanaka71928e62012-04-17 18:03:21 +00001//===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is part of the Mips Disassembler.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Mips.h"
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000015#include "MipsRegisterInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "MipsSubtarget.h"
Lang Hamesa1bc0f52014-04-15 04:40:56 +000017#include "llvm/MC/MCContext.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000018#include "llvm/MC/MCDisassembler/MCDisassembler.h"
Jim Grosbachecaef492012-08-14 19:06:05 +000019#include "llvm/MC/MCFixedLenDisassembler.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/Support/MathExtras.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000023#include "llvm/Support/TargetRegistry.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000024
Akira Hatanaka71928e62012-04-17 18:03:21 +000025using namespace llvm;
26
Chandler Carruthe96dd892014-04-21 22:55:11 +000027#define DEBUG_TYPE "mips-disassembler"
28
Akira Hatanaka71928e62012-04-17 18:03:21 +000029typedef MCDisassembler::DecodeStatus DecodeStatus;
30
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000031namespace {
32
Daniel Sandersa19216c2015-02-11 11:28:56 +000033class MipsDisassembler : public MCDisassembler {
Vladimir Medicdde3d582013-09-06 12:30:36 +000034 bool IsMicroMips;
Daniel Sandersa19216c2015-02-11 11:28:56 +000035 bool IsBigEndian;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000036public:
Daniel Sandersa19216c2015-02-11 11:28:56 +000037 MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
38 : MCDisassembler(STI, Ctx),
Michael Kupersteindb0712f2015-05-26 10:47:10 +000039 IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
Daniel Sandersa19216c2015-02-11 11:28:56 +000040 IsBigEndian(IsBigEndian) {}
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000041
Michael Kupersteindb0712f2015-05-26 10:47:10 +000042 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
43 bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
Daniel Sandersc171f652014-06-13 13:15:59 +000044 bool hasMips32r6() const {
Michael Kupersteindb0712f2015-05-26 10:47:10 +000045 return STI.getFeatureBits()[Mips::FeatureMips32r6];
Daniel Sanders5c582b22014-05-22 11:23:21 +000046 }
Zlatko Buljan6221be82016-03-31 08:51:24 +000047 bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
Daniel Sanders5c582b22014-05-22 11:23:21 +000048
Michael Kupersteindb0712f2015-05-26 10:47:10 +000049 bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
Daniel Sanders0fa60412014-06-12 13:39:06 +000050
Kai Nacke3adf9b82015-05-28 16:23:16 +000051 bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
52
Daniel Sandersc171f652014-06-13 13:15:59 +000053 bool hasCOP3() const {
54 // Only present in MIPS-I and MIPS-II
55 return !hasMips32() && !hasMips3();
56 }
57
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000058 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000059 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000060 raw_ostream &VStream,
61 raw_ostream &CStream) const override;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000062};
63
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000064} // end anonymous namespace
65
Akira Hatanaka71928e62012-04-17 18:03:21 +000066// Forward declare these because the autogenerated code will reference them.
67// Definitions are further down.
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000068static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
69 unsigned RegNo,
70 uint64_t Address,
71 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +000072
Reed Kotlerec8a5492013-02-14 03:05:25 +000073static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
74 unsigned RegNo,
75 uint64_t Address,
76 const void *Decoder);
77
Zoran Jovanovicb0852e52014-10-21 08:23:11 +000078static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
79 unsigned RegNo,
80 uint64_t Address,
81 const void *Decoder);
82
Jozef Kolek1904fa22014-11-24 14:25:53 +000083static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
84 unsigned RegNo,
85 uint64_t Address,
86 const void *Decoder);
87
Zoran Jovanovic41688672015-02-10 16:36:20 +000088static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
89 unsigned RegNo,
90 uint64_t Address,
91 const void *Decoder);
92
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000093static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
94 unsigned RegNo,
95 uint64_t Address,
96 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +000097
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000098static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
99 unsigned Insn,
100 uint64_t Address,
101 const void *Decoder);
102
Akira Hatanaka654655f2013-08-14 00:53:38 +0000103static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
104 unsigned RegNo,
105 uint64_t Address,
106 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000107
Akira Hatanaka71928e62012-04-17 18:03:21 +0000108static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
109 unsigned RegNo,
110 uint64_t Address,
111 const void *Decoder);
112
113static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
114 unsigned RegNo,
115 uint64_t Address,
116 const void *Decoder);
117
118static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
119 unsigned RegNo,
120 uint64_t Address,
121 const void *Decoder);
122
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000123static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
124 unsigned RegNo,
125 uint64_t Address,
126 const void *Decoder);
127
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +0000128static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
129 uint64_t Address,
130 const void *Decoder);
Daniel Sanders0fa60412014-06-12 13:39:06 +0000131
Akira Hatanaka71928e62012-04-17 18:03:21 +0000132static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
133 unsigned Insn,
134 uint64_t Address,
135 const void *Decoder);
136
137static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
138 unsigned RegNo,
139 uint64_t Address,
140 const void *Decoder);
141
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000142static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
143 unsigned RegNo,
144 uint64_t Address,
145 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000146
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000147static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
148 unsigned RegNo,
149 uint64_t Address,
150 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000151
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000152static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
153 unsigned RegNo,
154 uint64_t Address,
155 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000156
Jack Carter3eb663b2013-09-26 00:09:46 +0000157static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
158 unsigned RegNo,
159 uint64_t Address,
160 const void *Decoder);
161
Jack Carter5dc8ac92013-09-25 23:50:44 +0000162static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
163 unsigned RegNo,
164 uint64_t Address,
165 const void *Decoder);
166
167static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
168 unsigned RegNo,
169 uint64_t Address,
170 const void *Decoder);
171
172static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
173 unsigned RegNo,
174 uint64_t Address,
175 const void *Decoder);
176
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000177static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
178 unsigned RegNo,
179 uint64_t Address,
180 const void *Decoder);
181
Daniel Sandersa3134fa2015-06-27 15:39:19 +0000182static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
183 unsigned RegNo,
184 uint64_t Address,
185 const void *Decoder);
186
Daniel Sanders2a83d682014-05-21 12:56:39 +0000187static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
188 unsigned RegNo,
189 uint64_t Address,
190 const void *Decoder);
191
Akira Hatanaka71928e62012-04-17 18:03:21 +0000192static DecodeStatus DecodeBranchTarget(MCInst &Inst,
193 unsigned Offset,
194 uint64_t Address,
195 const void *Decoder);
196
Akira Hatanaka71928e62012-04-17 18:03:21 +0000197static DecodeStatus DecodeJumpTarget(MCInst &Inst,
198 unsigned Insn,
199 uint64_t Address,
200 const void *Decoder);
201
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000202static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
203 unsigned Offset,
204 uint64_t Address,
205 const void *Decoder);
206
207static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
208 unsigned Offset,
209 uint64_t Address,
210 const void *Decoder);
211
Jozef Kolek9761e962015-01-12 12:03:34 +0000212// DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
213// shifted left by 1 bit.
214static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
215 unsigned Offset,
216 uint64_t Address,
217 const void *Decoder);
218
Jozef Kolek5cfebdd2015-01-21 12:39:30 +0000219// DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
220// shifted left by 1 bit.
221static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
222 unsigned Offset,
223 uint64_t Address,
224 const void *Decoder);
225
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000226// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
227// shifted left by 1 bit.
228static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
229 unsigned Offset,
230 uint64_t Address,
231 const void *Decoder);
232
Zoran Jovanovica887b362015-11-30 12:56:18 +0000233// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
234// shifted left by 1 bit.
235static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
236 unsigned Offset,
237 uint64_t Address,
238 const void *Decoder);
239
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000240// DecodeJumpTargetMM - Decode microMIPS jump target, which is
241// shifted left by 1 bit.
242static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
243 unsigned Insn,
244 uint64_t Address,
245 const void *Decoder);
246
Akira Hatanaka71928e62012-04-17 18:03:21 +0000247static DecodeStatus DecodeMem(MCInst &Inst,
248 unsigned Insn,
249 uint64_t Address,
250 const void *Decoder);
251
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000252static DecodeStatus DecodeMemEVA(MCInst &Inst,
253 unsigned Insn,
254 uint64_t Address,
255 const void *Decoder);
256
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +0000257static DecodeStatus DecodeLoadByte9(MCInst &Inst,
258 unsigned Insn,
259 uint64_t Address,
260 const void *Decoder);
261
262static DecodeStatus DecodeLoadByte15(MCInst &Inst,
263 unsigned Insn,
264 uint64_t Address,
265 const void *Decoder);
266
Daniel Sanders92db6b72014-10-01 08:26:55 +0000267static DecodeStatus DecodeCacheOp(MCInst &Inst,
268 unsigned Insn,
269 uint64_t Address,
270 const void *Decoder);
271
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000272static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
273 unsigned Insn,
274 uint64_t Address,
275 const void *Decoder);
Vladimir Medicdf464ae2015-01-29 11:33:41 +0000276
Jozef Kolekab6d1cc2014-12-23 19:55:34 +0000277static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
278 unsigned Insn,
279 uint64_t Address,
280 const void *Decoder);
281
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +0000282static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
283 unsigned Insn,
284 uint64_t Address,
285 const void *Decoder);
286
Zoran Jovanovicd9790792015-09-09 09:10:46 +0000287static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
288 unsigned Insn,
289 uint64_t Address,
290 const void *Decoder);
291
Daniel Sandersb4484d62014-11-27 17:28:10 +0000292static DecodeStatus DecodeSyncI(MCInst &Inst,
293 unsigned Insn,
294 uint64_t Address,
295 const void *Decoder);
296
Hrvoje Varga18148672015-10-28 11:04:29 +0000297static DecodeStatus DecodeSynciR6(MCInst &Inst,
298 unsigned Insn,
299 uint64_t Address,
300 const void *Decoder);
301
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000302static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
303 uint64_t Address, const void *Decoder);
304
Jozef Kolek315e7ec2014-11-26 18:56:38 +0000305static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
306 unsigned Insn,
307 uint64_t Address,
308 const void *Decoder);
309
Jozef Kolek12c69822014-12-23 16:16:33 +0000310static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
311 unsigned Insn,
312 uint64_t Address,
313 const void *Decoder);
314
Jozef Koleke10a02e2015-01-28 17:27:26 +0000315static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
316 unsigned Insn,
317 uint64_t Address,
318 const void *Decoder);
319
Jozef Kolekd68d424a2015-02-10 12:41:13 +0000320static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
321 unsigned Insn,
322 uint64_t Address,
323 const void *Decoder);
324
Zoran Jovanovica6593ff2015-08-18 12:53:08 +0000325static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
326 unsigned Insn,
327 uint64_t Address,
328 const void *Decoder);
329
Vladimir Medicdde3d582013-09-06 12:30:36 +0000330static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
331 unsigned Insn,
332 uint64_t Address,
333 const void *Decoder);
334
335static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
336 unsigned Insn,
337 uint64_t Address,
338 const void *Decoder);
339
Akira Hatanaka71928e62012-04-17 18:03:21 +0000340static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
341 uint64_t Address,
342 const void *Decoder);
343
Daniel Sanders92db6b72014-10-01 08:26:55 +0000344static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
345 uint64_t Address,
346 const void *Decoder);
347
348static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
349 uint64_t Address,
350 const void *Decoder);
351
Vladimir Medic435cf8a2015-01-21 10:47:36 +0000352static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
353 uint64_t Address,
354 const void *Decoder);
355
Daniel Sanders6a803f62014-06-16 13:13:03 +0000356static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
357 unsigned Insn,
358 uint64_t Address,
359 const void *Decoder);
360
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000361static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
362 unsigned Value,
363 uint64_t Address,
364 const void *Decoder);
365
Daniel Sanders97297772016-03-22 14:40:00 +0000366static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000367 unsigned Value,
368 uint64_t Address,
369 const void *Decoder);
370
Zoran Jovanovic6b28f092015-09-09 13:55:45 +0000371static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
372 unsigned Value,
373 uint64_t Address,
374 const void *Decoder);
375
Daniel Sanders19b7f762016-03-14 11:16:56 +0000376template <unsigned Bits, int Offset, int Scale>
377static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
378 uint64_t Address,
379 const void *Decoder);
380
Daniel Sandersea4f6532015-11-06 12:22:31 +0000381template <unsigned Bits, int Offset>
382static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
Daniel Sanders19b7f762016-03-14 11:16:56 +0000383 uint64_t Address,
384 const void *Decoder) {
385 return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
386 Decoder);
387}
Matheus Almeida779c5932013-11-18 12:32:49 +0000388
Daniel Sanders97297772016-03-22 14:40:00 +0000389template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
390static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
391 uint64_t Address,
392 const void *Decoder);
Daniel Sanders78e89022016-03-11 11:37:50 +0000393
Akira Hatanaka71928e62012-04-17 18:03:21 +0000394static DecodeStatus DecodeInsSize(MCInst &Inst,
395 unsigned Insn,
396 uint64_t Address,
397 const void *Decoder);
398
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000399static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
400 uint64_t Address, const void *Decoder);
401
Zoran Jovanovic28551422014-06-09 09:49:51 +0000402static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
403 uint64_t Address, const void *Decoder);
404
Vladimir Medicb682ddf2014-12-01 11:12:04 +0000405static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
406 uint64_t Address, const void *Decoder);
407
408static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
409 uint64_t Address, const void *Decoder);
410
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000411static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
412 uint64_t Address, const void *Decoder);
413
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000414/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
415/// handle.
416template <typename InsnType>
417static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
418 const void *Decoder);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000419
420template <typename InsnType>
421static DecodeStatus
422DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
423 const void *Decoder);
424
425template <typename InsnType>
426static DecodeStatus
427DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
428 const void *Decoder);
429
430template <typename InsnType>
431static DecodeStatus
432DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
433 const void *Decoder);
434
435template <typename InsnType>
436static DecodeStatus
437DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
438 const void *Decoder);
439
440template <typename InsnType>
441static DecodeStatus
442DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
443 const void *Decoder);
444
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000445template <typename InsnType>
446static DecodeStatus
447DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
448 const void *Decoder);
449
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +0000450template <typename InsnType>
451static DecodeStatus
452DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
453 const void *Decoder);
454
455template <typename InsnType>
456static DecodeStatus
457DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
458 const void *Decoder);
459
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000460static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
461 uint64_t Address,
462 const void *Decoder);
463
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000464static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
465 uint64_t Address,
466 const void *Decoder);
467
Zoran Jovanovic41688672015-02-10 16:36:20 +0000468static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
469 uint64_t Address,
470 const void *Decoder);
471
Akira Hatanaka71928e62012-04-17 18:03:21 +0000472namespace llvm {
473extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
474 TheMips64elTarget;
475}
476
477static MCDisassembler *createMipsDisassembler(
478 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000479 const MCSubtargetInfo &STI,
480 MCContext &Ctx) {
481 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000482}
483
484static MCDisassembler *createMipselDisassembler(
485 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000486 const MCSubtargetInfo &STI,
487 MCContext &Ctx) {
488 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000489}
490
Akira Hatanaka71928e62012-04-17 18:03:21 +0000491extern "C" void LLVMInitializeMipsDisassembler() {
492 // Register the disassembler.
493 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
494 createMipsDisassembler);
495 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
496 createMipselDisassembler);
497 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000498 createMipsDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000499 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
Daniel Sandersa19216c2015-02-11 11:28:56 +0000500 createMipselDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000501}
502
Akira Hatanaka71928e62012-04-17 18:03:21 +0000503#include "MipsGenDisassemblerTables.inc"
504
Daniel Sanders5c582b22014-05-22 11:23:21 +0000505static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
Daniel Sandersa19216c2015-02-11 11:28:56 +0000506 const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000507 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
508 return *(RegInfo->getRegClass(RC).begin() + RegNo);
509}
510
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000511template <typename InsnType>
512static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
513 const void *Decoder) {
514 typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
515 // The size of the n field depends on the element size
516 // The register class also depends on this.
517 InsnType tmp = fieldFromInstruction(insn, 17, 5);
518 unsigned NSize = 0;
519 DecodeFN RegDecoder = nullptr;
520 if ((tmp & 0x18) == 0x00) { // INSVE_B
521 NSize = 4;
522 RegDecoder = DecodeMSA128BRegisterClass;
523 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
524 NSize = 3;
525 RegDecoder = DecodeMSA128HRegisterClass;
526 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
527 NSize = 2;
528 RegDecoder = DecodeMSA128WRegisterClass;
529 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
530 NSize = 1;
531 RegDecoder = DecodeMSA128DRegisterClass;
532 } else
533 llvm_unreachable("Invalid encoding");
534
535 assert(NSize != 0 && RegDecoder != nullptr);
536
537 // $wd
538 tmp = fieldFromInstruction(insn, 6, 5);
539 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
540 return MCDisassembler::Fail;
541 // $wd_in
542 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
543 return MCDisassembler::Fail;
544 // $n
545 tmp = fieldFromInstruction(insn, 16, NSize);
Jim Grosbache9119e42015-05-13 18:37:00 +0000546 MI.addOperand(MCOperand::createImm(tmp));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000547 // $ws
548 tmp = fieldFromInstruction(insn, 11, 5);
549 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
550 return MCDisassembler::Fail;
551 // $n2
Jim Grosbache9119e42015-05-13 18:37:00 +0000552 MI.addOperand(MCOperand::createImm(0));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000553
554 return MCDisassembler::Success;
555}
556
Daniel Sanders5c582b22014-05-22 11:23:21 +0000557template <typename InsnType>
558static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
559 uint64_t Address,
560 const void *Decoder) {
561 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
562 // (otherwise we would have matched the ADDI instruction from the earlier
563 // ISA's instead).
564 //
565 // We have:
566 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
567 // BOVC if rs >= rt
568 // BEQZALC if rs == 0 && rt != 0
569 // BEQC if rs < rt && rs != 0
570
571 InsnType Rs = fieldFromInstruction(insn, 21, 5);
572 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000573 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000574 bool HasRs = false;
575
576 if (Rs >= Rt) {
577 MI.setOpcode(Mips::BOVC);
578 HasRs = true;
579 } else if (Rs != 0 && Rs < Rt) {
580 MI.setOpcode(Mips::BEQC);
581 HasRs = true;
582 } else
583 MI.setOpcode(Mips::BEQZALC);
584
585 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000586 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000587 Rs)));
588
Jim Grosbache9119e42015-05-13 18:37:00 +0000589 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000590 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000591 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000592
593 return MCDisassembler::Success;
594}
595
596template <typename InsnType>
597static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
598 uint64_t Address,
599 const void *Decoder) {
600 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
601 // (otherwise we would have matched the ADDI instruction from the earlier
602 // ISA's instead).
603 //
604 // We have:
605 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
606 // BNVC if rs >= rt
607 // BNEZALC if rs == 0 && rt != 0
608 // BNEC if rs < rt && rs != 0
609
610 InsnType Rs = fieldFromInstruction(insn, 21, 5);
611 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000612 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000613 bool HasRs = false;
614
615 if (Rs >= Rt) {
616 MI.setOpcode(Mips::BNVC);
617 HasRs = true;
618 } else if (Rs != 0 && Rs < Rt) {
619 MI.setOpcode(Mips::BNEC);
620 HasRs = true;
621 } else
622 MI.setOpcode(Mips::BNEZALC);
623
624 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000625 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000626 Rs)));
627
Jim Grosbache9119e42015-05-13 18:37:00 +0000628 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000629 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000630 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000631
632 return MCDisassembler::Success;
633}
634
635template <typename InsnType>
636static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
637 uint64_t Address,
638 const void *Decoder) {
639 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
640 // (otherwise we would have matched the BLEZL instruction from the earlier
641 // ISA's instead).
642 //
643 // We have:
644 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
645 // Invalid if rs == 0
646 // BLEZC if rs == 0 && rt != 0
647 // BGEZC if rs == rt && rt != 0
648 // BGEC if rs != rt && rs != 0 && rt != 0
649
650 InsnType Rs = fieldFromInstruction(insn, 21, 5);
651 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000652 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000653 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000654
655 if (Rt == 0)
656 return MCDisassembler::Fail;
657 else if (Rs == 0)
658 MI.setOpcode(Mips::BLEZC);
659 else if (Rs == Rt)
660 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000661 else {
662 HasRs = true;
663 MI.setOpcode(Mips::BGEC);
664 }
665
666 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000667 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000668 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000669
Jim Grosbache9119e42015-05-13 18:37:00 +0000670 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000671 Rt)));
672
Jim Grosbache9119e42015-05-13 18:37:00 +0000673 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000674
675 return MCDisassembler::Success;
676}
677
678template <typename InsnType>
679static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
680 uint64_t Address,
681 const void *Decoder) {
682 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
683 // (otherwise we would have matched the BGTZL instruction from the earlier
684 // ISA's instead).
685 //
686 // We have:
687 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
688 // Invalid if rs == 0
689 // BGTZC if rs == 0 && rt != 0
690 // BLTZC if rs == rt && rt != 0
691 // BLTC if rs != rt && rs != 0 && rt != 0
692
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000693 bool HasRs = false;
694
Daniel Sanders5c582b22014-05-22 11:23:21 +0000695 InsnType Rs = fieldFromInstruction(insn, 21, 5);
696 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000697 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000698
699 if (Rt == 0)
700 return MCDisassembler::Fail;
701 else if (Rs == 0)
702 MI.setOpcode(Mips::BGTZC);
703 else if (Rs == Rt)
704 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000705 else {
706 MI.setOpcode(Mips::BLTC);
707 HasRs = true;
708 }
709
710 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000711 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000712 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000713
Jim Grosbache9119e42015-05-13 18:37:00 +0000714 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000715 Rt)));
716
Jim Grosbache9119e42015-05-13 18:37:00 +0000717 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000718
719 return MCDisassembler::Success;
720}
721
722template <typename InsnType>
723static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
724 uint64_t Address,
725 const void *Decoder) {
726 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
727 // (otherwise we would have matched the BGTZ instruction from the earlier
728 // ISA's instead).
729 //
730 // We have:
731 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
732 // BGTZ if rt == 0
733 // BGTZALC if rs == 0 && rt != 0
734 // BLTZALC if rs != 0 && rs == rt
735 // BLTUC if rs != 0 && rs != rt
736
737 InsnType Rs = fieldFromInstruction(insn, 21, 5);
738 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000739 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000740 bool HasRs = false;
741 bool HasRt = false;
742
743 if (Rt == 0) {
744 MI.setOpcode(Mips::BGTZ);
745 HasRs = true;
746 } else if (Rs == 0) {
747 MI.setOpcode(Mips::BGTZALC);
748 HasRt = true;
749 } else if (Rs == Rt) {
750 MI.setOpcode(Mips::BLTZALC);
751 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000752 } else {
753 MI.setOpcode(Mips::BLTUC);
754 HasRs = true;
755 HasRt = true;
756 }
Daniel Sanders5c582b22014-05-22 11:23:21 +0000757
758 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000759 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000760 Rs)));
761
762 if (HasRt)
Jim Grosbache9119e42015-05-13 18:37:00 +0000763 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000764 Rt)));
765
Jim Grosbache9119e42015-05-13 18:37:00 +0000766 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000767
768 return MCDisassembler::Success;
769}
770
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000771template <typename InsnType>
772static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
773 uint64_t Address,
774 const void *Decoder) {
775 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
776 // (otherwise we would have matched the BLEZL instruction from the earlier
777 // ISA's instead).
778 //
779 // We have:
780 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
781 // Invalid if rs == 0
782 // BLEZALC if rs == 0 && rt != 0
783 // BGEZALC if rs == rt && rt != 0
784 // BGEUC if rs != rt && rs != 0 && rt != 0
785
786 InsnType Rs = fieldFromInstruction(insn, 21, 5);
787 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000788 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000789 bool HasRs = false;
790
791 if (Rt == 0)
792 return MCDisassembler::Fail;
793 else if (Rs == 0)
794 MI.setOpcode(Mips::BLEZALC);
795 else if (Rs == Rt)
796 MI.setOpcode(Mips::BGEZALC);
797 else {
798 HasRs = true;
799 MI.setOpcode(Mips::BGEUC);
800 }
801
802 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000803 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000804 Rs)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000805 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000806 Rt)));
807
Jim Grosbache9119e42015-05-13 18:37:00 +0000808 MI.addOperand(MCOperand::createImm(Imm));
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000809
810 return MCDisassembler::Success;
811}
812
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000813/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
814/// according to the given endianess.
815static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
816 uint64_t &Size, uint32_t &Insn,
817 bool IsBigEndian) {
818 // We want to read exactly 2 Bytes of data.
819 if (Bytes.size() < 2) {
820 Size = 0;
821 return MCDisassembler::Fail;
822 }
823
824 if (IsBigEndian) {
825 Insn = (Bytes[0] << 8) | Bytes[1];
826 } else {
827 Insn = (Bytes[1] << 8) | Bytes[0];
828 }
829
830 return MCDisassembler::Success;
831}
832
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000833/// Read four bytes from the ArrayRef and return 32 bit word sorted
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000834/// according to the given endianess
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000835static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
836 uint64_t &Size, uint32_t &Insn,
837 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000838 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000839 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000840 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000841 return MCDisassembler::Fail;
842 }
843
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000844 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
845 // always precede the low 16 bits in the instruction stream (that is, they
846 // are placed at lower addresses in the instruction stream).
847 //
848 // microMIPS byte ordering:
849 // Big-endian: 0 | 1 | 2 | 3
850 // Little-endian: 1 | 0 | 3 | 2
851
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000852 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000853 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000854 Insn =
855 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
856 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +0000857 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000858 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000859 (Bytes[1] << 24);
860 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000861 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000862 (Bytes[3] << 24);
863 }
Akira Hatanaka71928e62012-04-17 18:03:21 +0000864 }
865
866 return MCDisassembler::Success;
867}
868
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000869DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000870 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000871 uint64_t Address,
872 raw_ostream &VStream,
873 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000874 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000875 DecodeStatus Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000876
Vladimir Medicdde3d582013-09-06 12:30:36 +0000877 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000878 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
Reid Klecknerebee6122015-11-19 21:51:55 +0000879 if (Result == MCDisassembler::Fail)
880 return MCDisassembler::Fail;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000881
Zoran Jovanovicada70912015-09-07 11:56:37 +0000882 if (hasMips32r6()) {
883 DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
884 // Calling the auto-generated decoder function for microMIPS32R6
885 // (and microMIPS64R6) 16-bit instructions.
886 Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
887 Address, this, STI);
888 if (Result != MCDisassembler::Fail) {
889 Size = 2;
890 return Result;
891 }
892 }
893
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000894 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
Zoran Jovanovicada70912015-09-07 11:56:37 +0000895 // Calling the auto-generated decoder function for microMIPS 16-bit
896 // instructions.
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000897 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
898 this, STI);
899 if (Result != MCDisassembler::Fail) {
900 Size = 2;
901 return Result;
902 }
903
904 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
905 if (Result == MCDisassembler::Fail)
906 return MCDisassembler::Fail;
907
Jozef Kolek676d6012015-04-20 14:40:38 +0000908 if (hasMips32r6()) {
909 DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
910 // Calling the auto-generated decoder function.
Zoran Jovanovic366783e2015-08-12 12:45:16 +0000911 Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
Jozef Kolek676d6012015-04-20 14:40:38 +0000912 this, STI);
Zoran Jovanovicada70912015-09-07 11:56:37 +0000913 if (Result != MCDisassembler::Fail) {
914 Size = 4;
915 return Result;
916 }
Jozef Kolek676d6012015-04-20 14:40:38 +0000917 }
Zoran Jovanovic366783e2015-08-12 12:45:16 +0000918
Zoran Jovanovicada70912015-09-07 11:56:37 +0000919 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
920 // Calling the auto-generated decoder function.
921 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
922 this, STI);
Vladimir Medicdde3d582013-09-06 12:30:36 +0000923 if (Result != MCDisassembler::Fail) {
924 Size = 4;
925 return Result;
926 }
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +0000927
Zlatko Buljan6221be82016-03-31 08:51:24 +0000928 if (hasMips32r6() && isFP64()) {
929 DEBUG(dbgs() << "Trying MicroMips32r6FP64 table (32-bit opcodes):\n");
930 Result = decodeInstruction(DecoderTableMicroMips32r6FP6432, Instr, Insn,
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +0000931 Address, this, STI);
932 if (Result != MCDisassembler::Fail) {
933 Size = 4;
934 return Result;
935 }
936 }
937
Reid Klecknerebee6122015-11-19 21:51:55 +0000938 // This is an invalid instruction. Let the disassembler move forward by the
939 // minimum instruction size.
940 Size = 2;
Vladimir Medicdde3d582013-09-06 12:30:36 +0000941 return MCDisassembler::Fail;
942 }
943
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000944 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Reid Klecknerebee6122015-11-19 21:51:55 +0000945 if (Result == MCDisassembler::Fail) {
946 Size = 4;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000947 return MCDisassembler::Fail;
Reid Klecknerebee6122015-11-19 21:51:55 +0000948 }
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000949
Daniel Sandersc171f652014-06-13 13:15:59 +0000950 if (hasCOP3()) {
951 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
952 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000953 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Daniel Sandersc171f652014-06-13 13:15:59 +0000954 if (Result != MCDisassembler::Fail) {
955 Size = 4;
956 return Result;
957 }
958 }
959
960 if (hasMips32r6() && isGP64()) {
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +0000961 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
962 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
963 Address, this, STI);
Daniel Sanders0fa60412014-06-12 13:39:06 +0000964 if (Result != MCDisassembler::Fail) {
965 Size = 4;
966 return Result;
967 }
968 }
969
Daniel Sandersc171f652014-06-13 13:15:59 +0000970 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +0000971 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000972 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000973 Address, this, STI);
974 if (Result != MCDisassembler::Fail) {
975 Size = 4;
976 return Result;
977 }
978 }
979
Kai Nacke3adf9b82015-05-28 16:23:16 +0000980 if (hasCnMips()) {
981 DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
982 Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
983 Address, this, STI);
984 if (Result != MCDisassembler::Fail) {
985 Size = 4;
986 return Result;
987 }
988 }
989
Daniel Sandersa19216c2015-02-11 11:28:56 +0000990 if (isGP64()) {
991 DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
992 Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
993 Address, this, STI);
994 if (Result != MCDisassembler::Fail) {
995 Size = 4;
996 return Result;
997 }
998 }
999
Daniel Sanders0fa60412014-06-12 13:39:06 +00001000 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +00001001 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001002 Result =
1003 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001004 if (Result != MCDisassembler::Fail) {
1005 Size = 4;
1006 return Result;
1007 }
1008
Reid Klecknerebee6122015-11-19 21:51:55 +00001009 Size = 4;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001010 return MCDisassembler::Fail;
1011}
1012
Reed Kotlerec8a5492013-02-14 03:05:25 +00001013static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1014 unsigned RegNo,
1015 uint64_t Address,
1016 const void *Decoder) {
1017
1018 return MCDisassembler::Fail;
1019
1020}
1021
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001022static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1023 unsigned RegNo,
1024 uint64_t Address,
1025 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001026
1027 if (RegNo > 31)
1028 return MCDisassembler::Fail;
1029
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001030 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001031 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001032 return MCDisassembler::Success;
1033}
1034
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001035static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1036 unsigned RegNo,
1037 uint64_t Address,
1038 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001039 if (RegNo > 7)
1040 return MCDisassembler::Fail;
1041 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001042 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001043 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001044}
1045
Jozef Kolek1904fa22014-11-24 14:25:53 +00001046static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1047 unsigned RegNo,
1048 uint64_t Address,
1049 const void *Decoder) {
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001050 if (RegNo > 7)
1051 return MCDisassembler::Fail;
1052 unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001053 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001054 return MCDisassembler::Success;
Jozef Kolek1904fa22014-11-24 14:25:53 +00001055}
1056
Zoran Jovanovic41688672015-02-10 16:36:20 +00001057static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1058 unsigned RegNo,
1059 uint64_t Address,
1060 const void *Decoder) {
1061 if (RegNo > 7)
1062 return MCDisassembler::Fail;
1063 unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001064 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic41688672015-02-10 16:36:20 +00001065 return MCDisassembler::Success;
1066}
1067
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001068static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1069 unsigned RegNo,
1070 uint64_t Address,
1071 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001072 if (RegNo > 31)
1073 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001074 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001075 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001076 return MCDisassembler::Success;
1077}
1078
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001079static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1080 unsigned RegNo,
1081 uint64_t Address,
1082 const void *Decoder) {
Daniel Sandersa19216c2015-02-11 11:28:56 +00001083 if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001084 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1085
1086 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1087}
1088
Akira Hatanaka654655f2013-08-14 00:53:38 +00001089static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1090 unsigned RegNo,
1091 uint64_t Address,
1092 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001093 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001094}
1095
Akira Hatanaka71928e62012-04-17 18:03:21 +00001096static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1097 unsigned RegNo,
1098 uint64_t Address,
1099 const void *Decoder) {
1100 if (RegNo > 31)
1101 return MCDisassembler::Fail;
1102
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001103 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001104 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001105 return MCDisassembler::Success;
1106}
1107
1108static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1109 unsigned RegNo,
1110 uint64_t Address,
1111 const void *Decoder) {
1112 if (RegNo > 31)
1113 return MCDisassembler::Fail;
1114
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001115 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001116 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001117 return MCDisassembler::Success;
1118}
1119
1120static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1121 unsigned RegNo,
1122 uint64_t Address,
1123 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +00001124 if (RegNo > 31)
1125 return MCDisassembler::Fail;
1126 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001127 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001128 return MCDisassembler::Success;
1129}
1130
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001131static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1132 unsigned RegNo,
1133 uint64_t Address,
1134 const void *Decoder) {
1135 if (RegNo > 7)
1136 return MCDisassembler::Fail;
1137 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001138 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001139 return MCDisassembler::Success;
1140}
1141
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001142static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1143 uint64_t Address,
1144 const void *Decoder) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001145 if (RegNo > 31)
1146 return MCDisassembler::Fail;
1147
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001148 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001149 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders0fa60412014-06-12 13:39:06 +00001150 return MCDisassembler::Success;
1151}
1152
Akira Hatanaka71928e62012-04-17 18:03:21 +00001153static DecodeStatus DecodeMem(MCInst &Inst,
1154 unsigned Insn,
1155 uint64_t Address,
1156 const void *Decoder) {
1157 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001158 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1159 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001160
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001161 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1162 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001163
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001164 if (Inst.getOpcode() == Mips::SC ||
1165 Inst.getOpcode() == Mips::SCD)
Jim Grosbache9119e42015-05-13 18:37:00 +00001166 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001167
1168 Inst.addOperand(MCOperand::createReg(Reg));
1169 Inst.addOperand(MCOperand::createReg(Base));
1170 Inst.addOperand(MCOperand::createImm(Offset));
1171
1172 return MCDisassembler::Success;
1173}
1174
1175static DecodeStatus DecodeMemEVA(MCInst &Inst,
1176 unsigned Insn,
1177 uint64_t Address,
1178 const void *Decoder) {
1179 int Offset = SignExtend32<9>(Insn >> 7);
1180 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1181 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1182
1183 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1184 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1185
1186 if (Inst.getOpcode() == Mips::SCE)
1187 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001188
Jim Grosbache9119e42015-05-13 18:37:00 +00001189 Inst.addOperand(MCOperand::createReg(Reg));
1190 Inst.addOperand(MCOperand::createReg(Base));
1191 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001192
1193 return MCDisassembler::Success;
1194}
1195
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +00001196static DecodeStatus DecodeLoadByte9(MCInst &Inst,
1197 unsigned Insn,
1198 uint64_t Address,
1199 const void *Decoder) {
1200 int Offset = SignExtend32<9>(Insn & 0x1ff);
1201 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1202 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1203
1204 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1205 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1206
1207 Inst.addOperand(MCOperand::createReg(Reg));
1208 Inst.addOperand(MCOperand::createReg(Base));
1209 Inst.addOperand(MCOperand::createImm(Offset));
1210
1211 return MCDisassembler::Success;
1212}
1213
1214static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1215 unsigned Insn,
1216 uint64_t Address,
1217 const void *Decoder) {
1218 int Offset = SignExtend32<16>(Insn & 0xffff);
1219 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1220 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1221
1222 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1223 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1224
1225 Inst.addOperand(MCOperand::createReg(Reg));
1226 Inst.addOperand(MCOperand::createReg(Base));
1227 Inst.addOperand(MCOperand::createImm(Offset));
1228
1229 return MCDisassembler::Success;
1230}
1231
Daniel Sanders92db6b72014-10-01 08:26:55 +00001232static DecodeStatus DecodeCacheOp(MCInst &Inst,
1233 unsigned Insn,
1234 uint64_t Address,
1235 const void *Decoder) {
1236 int Offset = SignExtend32<16>(Insn & 0xffff);
1237 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1238 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1239
1240 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1241
Jim Grosbache9119e42015-05-13 18:37:00 +00001242 Inst.addOperand(MCOperand::createReg(Base));
1243 Inst.addOperand(MCOperand::createImm(Offset));
1244 Inst.addOperand(MCOperand::createImm(Hint));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001245
1246 return MCDisassembler::Success;
1247}
1248
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001249static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1250 unsigned Insn,
1251 uint64_t Address,
1252 const void *Decoder) {
1253 int Offset = SignExtend32<12>(Insn & 0xfff);
1254 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1255 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1256
1257 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1258
Jim Grosbache9119e42015-05-13 18:37:00 +00001259 Inst.addOperand(MCOperand::createReg(Base));
1260 Inst.addOperand(MCOperand::createImm(Offset));
1261 Inst.addOperand(MCOperand::createImm(Hint));
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001262
1263 return MCDisassembler::Success;
1264}
1265
Zoran Jovanovicd9790792015-09-09 09:10:46 +00001266static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1267 unsigned Insn,
1268 uint64_t Address,
1269 const void *Decoder) {
1270 int Offset = SignExtend32<9>(Insn & 0x1ff);
1271 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1272 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1273
1274 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1275
1276 Inst.addOperand(MCOperand::createReg(Base));
1277 Inst.addOperand(MCOperand::createImm(Offset));
1278 Inst.addOperand(MCOperand::createImm(Hint));
1279
1280 return MCDisassembler::Success;
1281}
1282
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001283static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1284 unsigned Insn,
1285 uint64_t Address,
1286 const void *Decoder) {
1287 int Offset = SignExtend32<9>(Insn >> 7);
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001288 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1289 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1290
1291 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1292
Jim Grosbache9119e42015-05-13 18:37:00 +00001293 Inst.addOperand(MCOperand::createReg(Base));
1294 Inst.addOperand(MCOperand::createImm(Offset));
1295 Inst.addOperand(MCOperand::createImm(Hint));
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001296
1297 return MCDisassembler::Success;
1298}
1299
Zoran Jovanovic9eaa30d2015-09-08 10:18:38 +00001300static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst,
1301 unsigned Insn,
1302 uint64_t Address,
1303 const void *Decoder) {
1304 int Offset = SignExtend32<9>(Insn & 0x1ff);
1305 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1306 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1307
1308 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1309 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1310
1311 Inst.addOperand(MCOperand::createReg(Reg));
1312 Inst.addOperand(MCOperand::createReg(Base));
1313 Inst.addOperand(MCOperand::createImm(Offset));
1314
1315 return MCDisassembler::Success;
1316}
1317
Daniel Sandersb4484d62014-11-27 17:28:10 +00001318static DecodeStatus DecodeSyncI(MCInst &Inst,
1319 unsigned Insn,
1320 uint64_t Address,
1321 const void *Decoder) {
1322 int Offset = SignExtend32<16>(Insn & 0xffff);
1323 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1324
1325 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1326
Jim Grosbache9119e42015-05-13 18:37:00 +00001327 Inst.addOperand(MCOperand::createReg(Base));
1328 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sandersb4484d62014-11-27 17:28:10 +00001329
1330 return MCDisassembler::Success;
1331}
1332
Hrvoje Varga18148672015-10-28 11:04:29 +00001333static DecodeStatus DecodeSynciR6(MCInst &Inst,
1334 unsigned Insn,
1335 uint64_t Address,
1336 const void *Decoder) {
1337 int Immediate = SignExtend32<16>(Insn & 0xffff);
1338 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1339
1340 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1341
1342 Inst.addOperand(MCOperand::createReg(Base));
1343 Inst.addOperand(MCOperand::createImm(Immediate));
1344
1345 return MCDisassembler::Success;
1346}
1347
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001348static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1349 uint64_t Address, const void *Decoder) {
1350 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1351 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1352 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1353
1354 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1355 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1356
Jim Grosbache9119e42015-05-13 18:37:00 +00001357 Inst.addOperand(MCOperand::createReg(Reg));
1358 Inst.addOperand(MCOperand::createReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001359
1360 // The immediate field of an LD/ST instruction is scaled which means it must
1361 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1362 // data format.
1363 // .b - 1 byte
1364 // .h - 2 bytes
1365 // .w - 4 bytes
1366 // .d - 8 bytes
1367 switch(Inst.getOpcode())
1368 {
1369 default:
1370 assert (0 && "Unexpected instruction");
1371 return MCDisassembler::Fail;
1372 break;
1373 case Mips::LD_B:
1374 case Mips::ST_B:
Jim Grosbache9119e42015-05-13 18:37:00 +00001375 Inst.addOperand(MCOperand::createImm(Offset));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001376 break;
1377 case Mips::LD_H:
1378 case Mips::ST_H:
Jim Grosbache9119e42015-05-13 18:37:00 +00001379 Inst.addOperand(MCOperand::createImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001380 break;
1381 case Mips::LD_W:
1382 case Mips::ST_W:
Jim Grosbache9119e42015-05-13 18:37:00 +00001383 Inst.addOperand(MCOperand::createImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001384 break;
1385 case Mips::LD_D:
1386 case Mips::ST_D:
Jim Grosbache9119e42015-05-13 18:37:00 +00001387 Inst.addOperand(MCOperand::createImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001388 break;
1389 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001390
1391 return MCDisassembler::Success;
1392}
1393
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001394static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1395 unsigned Insn,
1396 uint64_t Address,
1397 const void *Decoder) {
1398 unsigned Offset = Insn & 0xf;
1399 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1400 unsigned Base = fieldFromInstruction(Insn, 4, 3);
1401
1402 switch (Inst.getOpcode()) {
1403 case Mips::LBU16_MM:
1404 case Mips::LHU16_MM:
1405 case Mips::LW16_MM:
1406 if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1407 == MCDisassembler::Fail)
1408 return MCDisassembler::Fail;
1409 break;
1410 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001411 case Mips::SB16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001412 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001413 case Mips::SH16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001414 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001415 case Mips::SW16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001416 if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1417 == MCDisassembler::Fail)
1418 return MCDisassembler::Fail;
1419 break;
1420 }
1421
1422 if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1423 == MCDisassembler::Fail)
1424 return MCDisassembler::Fail;
1425
1426 switch (Inst.getOpcode()) {
1427 case Mips::LBU16_MM:
1428 if (Offset == 0xf)
Jim Grosbache9119e42015-05-13 18:37:00 +00001429 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001430 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001431 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001432 break;
1433 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001434 case Mips::SB16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001435 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001436 break;
1437 case Mips::LHU16_MM:
1438 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001439 case Mips::SH16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001440 Inst.addOperand(MCOperand::createImm(Offset << 1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001441 break;
1442 case Mips::LW16_MM:
1443 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001444 case Mips::SW16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001445 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001446 break;
1447 }
1448
1449 return MCDisassembler::Success;
1450}
1451
Jozef Kolek12c69822014-12-23 16:16:33 +00001452static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1453 unsigned Insn,
1454 uint64_t Address,
1455 const void *Decoder) {
1456 unsigned Offset = Insn & 0x1F;
1457 unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1458
1459 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1460
Jim Grosbache9119e42015-05-13 18:37:00 +00001461 Inst.addOperand(MCOperand::createReg(Reg));
1462 Inst.addOperand(MCOperand::createReg(Mips::SP));
1463 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek12c69822014-12-23 16:16:33 +00001464
1465 return MCDisassembler::Success;
1466}
1467
Jozef Koleke10a02e2015-01-28 17:27:26 +00001468static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1469 unsigned Insn,
1470 uint64_t Address,
1471 const void *Decoder) {
1472 unsigned Offset = Insn & 0x7F;
1473 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1474
1475 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1476
Jim Grosbache9119e42015-05-13 18:37:00 +00001477 Inst.addOperand(MCOperand::createReg(Reg));
1478 Inst.addOperand(MCOperand::createReg(Mips::GP));
1479 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Koleke10a02e2015-01-28 17:27:26 +00001480
1481 return MCDisassembler::Success;
1482}
1483
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001484static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1485 unsigned Insn,
1486 uint64_t Address,
1487 const void *Decoder) {
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001488 int Offset;
1489 switch (Inst.getOpcode()) {
1490 case Mips::LWM16_MMR6:
1491 case Mips::SWM16_MMR6:
1492 Offset = fieldFromInstruction(Insn, 4, 4);
1493 break;
1494 default:
1495 Offset = SignExtend32<4>(Insn & 0xf);
1496 break;
1497 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001498
1499 if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1500 == MCDisassembler::Fail)
1501 return MCDisassembler::Fail;
1502
Jim Grosbache9119e42015-05-13 18:37:00 +00001503 Inst.addOperand(MCOperand::createReg(Mips::SP));
1504 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001505
1506 return MCDisassembler::Success;
1507}
1508
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001509static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1510 unsigned Insn,
1511 uint64_t Address,
1512 const void *Decoder) {
1513 int Offset = SignExtend32<9>(Insn & 0x1ff);
1514 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1515 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1516
1517 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1518 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1519
Hrvoje Varga3ef4dd72015-10-15 08:11:50 +00001520 if (Inst.getOpcode() == Mips::SCE_MM)
1521 Inst.addOperand(MCOperand::createReg(Reg));
1522
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001523 Inst.addOperand(MCOperand::createReg(Reg));
1524 Inst.addOperand(MCOperand::createReg(Base));
1525 Inst.addOperand(MCOperand::createImm(Offset));
1526
1527 return MCDisassembler::Success;
1528}
1529
Vladimir Medicdde3d582013-09-06 12:30:36 +00001530static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1531 unsigned Insn,
1532 uint64_t Address,
1533 const void *Decoder) {
1534 int Offset = SignExtend32<12>(Insn & 0x0fff);
1535 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1536 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1537
1538 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1539 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1540
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001541 switch (Inst.getOpcode()) {
1542 case Mips::SWM32_MM:
1543 case Mips::LWM32_MM:
1544 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1545 == MCDisassembler::Fail)
1546 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001547 Inst.addOperand(MCOperand::createReg(Base));
1548 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001549 break;
1550 case Mips::SC_MM:
Jim Grosbache9119e42015-05-13 18:37:00 +00001551 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001552 // fallthrough
1553 default:
Jim Grosbache9119e42015-05-13 18:37:00 +00001554 Inst.addOperand(MCOperand::createReg(Reg));
Zlatko Buljanba553a62016-05-09 08:07:28 +00001555 if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1556 Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
Jim Grosbache9119e42015-05-13 18:37:00 +00001557 Inst.addOperand(MCOperand::createReg(Reg+1));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001558
Jim Grosbache9119e42015-05-13 18:37:00 +00001559 Inst.addOperand(MCOperand::createReg(Base));
1560 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001561 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001562
1563 return MCDisassembler::Success;
1564}
1565
1566static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1567 unsigned Insn,
1568 uint64_t Address,
1569 const void *Decoder) {
1570 int Offset = SignExtend32<16>(Insn & 0xffff);
1571 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1572 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1573
1574 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1575 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1576
Jim Grosbache9119e42015-05-13 18:37:00 +00001577 Inst.addOperand(MCOperand::createReg(Reg));
1578 Inst.addOperand(MCOperand::createReg(Base));
1579 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medicdde3d582013-09-06 12:30:36 +00001580
1581 return MCDisassembler::Success;
1582}
1583
Akira Hatanaka71928e62012-04-17 18:03:21 +00001584static DecodeStatus DecodeFMem(MCInst &Inst,
1585 unsigned Insn,
1586 uint64_t Address,
1587 const void *Decoder) {
1588 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001589 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1590 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001591
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001592 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001593 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001594
Jim Grosbache9119e42015-05-13 18:37:00 +00001595 Inst.addOperand(MCOperand::createReg(Reg));
1596 Inst.addOperand(MCOperand::createReg(Base));
1597 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001598
1599 return MCDisassembler::Success;
1600}
1601
Daniel Sanders92db6b72014-10-01 08:26:55 +00001602static DecodeStatus DecodeFMem2(MCInst &Inst,
1603 unsigned Insn,
1604 uint64_t Address,
1605 const void *Decoder) {
1606 int Offset = SignExtend32<16>(Insn & 0xffff);
1607 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1608 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1609
1610 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1611 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1612
Jim Grosbache9119e42015-05-13 18:37:00 +00001613 Inst.addOperand(MCOperand::createReg(Reg));
1614 Inst.addOperand(MCOperand::createReg(Base));
1615 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001616
1617 return MCDisassembler::Success;
1618}
1619
1620static DecodeStatus DecodeFMem3(MCInst &Inst,
1621 unsigned Insn,
1622 uint64_t Address,
1623 const void *Decoder) {
1624 int Offset = SignExtend32<16>(Insn & 0xffff);
1625 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1626 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1627
1628 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1629 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1630
Jim Grosbache9119e42015-05-13 18:37:00 +00001631 Inst.addOperand(MCOperand::createReg(Reg));
1632 Inst.addOperand(MCOperand::createReg(Base));
1633 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001634
1635 return MCDisassembler::Success;
1636}
1637
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001638static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1639 unsigned Insn,
1640 uint64_t Address,
1641 const void *Decoder) {
1642 int Offset = SignExtend32<11>(Insn & 0x07ff);
1643 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1644 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1645
1646 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1647 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1648
Jim Grosbache9119e42015-05-13 18:37:00 +00001649 Inst.addOperand(MCOperand::createReg(Reg));
1650 Inst.addOperand(MCOperand::createReg(Base));
1651 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001652
1653 return MCDisassembler::Success;
1654}
Daniel Sanders6a803f62014-06-16 13:13:03 +00001655static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1656 unsigned Insn,
1657 uint64_t Address,
1658 const void *Decoder) {
1659 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1660 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1661 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1662
1663 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1664 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1665
1666 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
Jim Grosbache9119e42015-05-13 18:37:00 +00001667 Inst.addOperand(MCOperand::createReg(Rt));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001668 }
1669
Jim Grosbache9119e42015-05-13 18:37:00 +00001670 Inst.addOperand(MCOperand::createReg(Rt));
1671 Inst.addOperand(MCOperand::createReg(Base));
1672 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders6a803f62014-06-16 13:13:03 +00001673
1674 return MCDisassembler::Success;
1675}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001676
1677static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1678 unsigned RegNo,
1679 uint64_t Address,
1680 const void *Decoder) {
1681 // Currently only hardware register 29 is supported.
1682 if (RegNo != 29)
1683 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001684 Inst.addOperand(MCOperand::createReg(Mips::HWR29));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001685 return MCDisassembler::Success;
1686}
1687
Akira Hatanaka71928e62012-04-17 18:03:21 +00001688static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1689 unsigned RegNo,
1690 uint64_t Address,
1691 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001692 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001693 return MCDisassembler::Fail;
1694
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001695 ;
1696 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
Jim Grosbache9119e42015-05-13 18:37:00 +00001697 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001698 return MCDisassembler::Success;
1699}
1700
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001701static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1702 unsigned RegNo,
1703 uint64_t Address,
1704 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001705 if (RegNo >= 4)
1706 return MCDisassembler::Fail;
1707
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001708 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001709 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001710 return MCDisassembler::Success;
1711}
1712
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001713static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1714 unsigned RegNo,
1715 uint64_t Address,
1716 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001717 if (RegNo >= 4)
1718 return MCDisassembler::Fail;
1719
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001720 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001721 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001722 return MCDisassembler::Success;
1723}
1724
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001725static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
1726 unsigned RegNo,
1727 uint64_t Address,
1728 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001729 if (RegNo >= 4)
1730 return MCDisassembler::Fail;
1731
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001732 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001733 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001734 return MCDisassembler::Success;
1735}
1736
Jack Carter3eb663b2013-09-26 00:09:46 +00001737static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1738 unsigned RegNo,
1739 uint64_t Address,
1740 const void *Decoder) {
1741 if (RegNo > 31)
1742 return MCDisassembler::Fail;
1743
1744 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001745 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter3eb663b2013-09-26 00:09:46 +00001746 return MCDisassembler::Success;
1747}
1748
Jack Carter5dc8ac92013-09-25 23:50:44 +00001749static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1750 unsigned RegNo,
1751 uint64_t Address,
1752 const void *Decoder) {
1753 if (RegNo > 31)
1754 return MCDisassembler::Fail;
1755
1756 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001757 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001758 return MCDisassembler::Success;
1759}
1760
1761static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1762 unsigned RegNo,
1763 uint64_t Address,
1764 const void *Decoder) {
1765 if (RegNo > 31)
1766 return MCDisassembler::Fail;
1767
1768 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001769 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001770 return MCDisassembler::Success;
1771}
1772
1773static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1774 unsigned RegNo,
1775 uint64_t Address,
1776 const void *Decoder) {
1777 if (RegNo > 31)
1778 return MCDisassembler::Fail;
1779
1780 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001781 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00001782 return MCDisassembler::Success;
1783}
1784
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001785static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1786 unsigned RegNo,
1787 uint64_t Address,
1788 const void *Decoder) {
1789 if (RegNo > 7)
1790 return MCDisassembler::Fail;
1791
1792 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001793 Inst.addOperand(MCOperand::createReg(Reg));
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001794 return MCDisassembler::Success;
1795}
1796
Daniel Sandersa3134fa2015-06-27 15:39:19 +00001797static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
1798 unsigned RegNo,
1799 uint64_t Address,
1800 const void *Decoder) {
1801 if (RegNo > 31)
1802 return MCDisassembler::Fail;
1803
1804 unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
1805 Inst.addOperand(MCOperand::createReg(Reg));
1806 return MCDisassembler::Success;
1807}
1808
Daniel Sanders2a83d682014-05-21 12:56:39 +00001809static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1810 unsigned RegNo,
1811 uint64_t Address,
1812 const void *Decoder) {
1813 if (RegNo > 31)
1814 return MCDisassembler::Fail;
1815
1816 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001817 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders2a83d682014-05-21 12:56:39 +00001818 return MCDisassembler::Success;
1819}
1820
Akira Hatanaka71928e62012-04-17 18:03:21 +00001821static DecodeStatus DecodeBranchTarget(MCInst &Inst,
1822 unsigned Offset,
1823 uint64_t Address,
1824 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001825 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00001826 Inst.addOperand(MCOperand::createImm(BranchOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001827 return MCDisassembler::Success;
1828}
1829
Akira Hatanaka71928e62012-04-17 18:03:21 +00001830static DecodeStatus DecodeJumpTarget(MCInst &Inst,
1831 unsigned Insn,
1832 uint64_t Address,
1833 const void *Decoder) {
1834
Jim Grosbachecaef492012-08-14 19:06:05 +00001835 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00001836 Inst.addOperand(MCOperand::createImm(JumpOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001837 return MCDisassembler::Success;
1838}
1839
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001840static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
1841 unsigned Offset,
1842 uint64_t Address,
1843 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001844 int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001845
Jim Grosbache9119e42015-05-13 18:37:00 +00001846 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001847 return MCDisassembler::Success;
1848}
1849
1850static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
1851 unsigned Offset,
1852 uint64_t Address,
1853 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001854 int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001855
Jim Grosbache9119e42015-05-13 18:37:00 +00001856 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001857 return MCDisassembler::Success;
1858}
1859
Jozef Kolek9761e962015-01-12 12:03:34 +00001860static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
1861 unsigned Offset,
1862 uint64_t Address,
1863 const void *Decoder) {
1864 int32_t BranchOffset = SignExtend32<7>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001865 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek9761e962015-01-12 12:03:34 +00001866 return MCDisassembler::Success;
1867}
1868
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00001869static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
1870 unsigned Offset,
1871 uint64_t Address,
1872 const void *Decoder) {
1873 int32_t BranchOffset = SignExtend32<10>(Offset) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001874 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00001875 return MCDisassembler::Success;
1876}
1877
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001878static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
1879 unsigned Offset,
1880 uint64_t Address,
1881 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001882 int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00001883 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001884 return MCDisassembler::Success;
1885}
1886
Zoran Jovanovica887b362015-11-30 12:56:18 +00001887static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
1888 unsigned Offset,
1889 uint64_t Address,
1890 const void *Decoder) {
1891 int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
1892
1893 Inst.addOperand(MCOperand::createImm(BranchOffset));
1894 return MCDisassembler::Success;
1895}
1896
Zoran Jovanovic507e0842013-10-29 16:38:59 +00001897static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1898 unsigned Insn,
1899 uint64_t Address,
1900 const void *Decoder) {
1901 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001902 Inst.addOperand(MCOperand::createImm(JumpOffset));
Zoran Jovanovic507e0842013-10-29 16:38:59 +00001903 return MCDisassembler::Success;
1904}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001905
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001906static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
1907 unsigned Value,
1908 uint64_t Address,
1909 const void *Decoder) {
1910 if (Value == 0)
Jim Grosbache9119e42015-05-13 18:37:00 +00001911 Inst.addOperand(MCOperand::createImm(1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001912 else if (Value == 0x7)
Jim Grosbache9119e42015-05-13 18:37:00 +00001913 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001914 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001915 Inst.addOperand(MCOperand::createImm(Value << 2));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001916 return MCDisassembler::Success;
1917}
1918
Daniel Sanders97297772016-03-22 14:40:00 +00001919static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001920 unsigned Value,
1921 uint64_t Address,
1922 const void *Decoder) {
1923 if (Value == 0x7F)
Jim Grosbache9119e42015-05-13 18:37:00 +00001924 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001925 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001926 Inst.addOperand(MCOperand::createImm(Value));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00001927 return MCDisassembler::Success;
1928}
1929
Zoran Jovanovic6b28f092015-09-09 13:55:45 +00001930static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
1931 unsigned Value,
1932 uint64_t Address,
1933 const void *Decoder) {
1934 Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
1935 return MCDisassembler::Success;
1936}
1937
Daniel Sanders19b7f762016-03-14 11:16:56 +00001938template <unsigned Bits, int Offset, int Scale>
1939static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
1940 uint64_t Address,
1941 const void *Decoder) {
Daniel Sandersea4f6532015-11-06 12:22:31 +00001942 Value &= ((1 << Bits) - 1);
Daniel Sanders19b7f762016-03-14 11:16:56 +00001943 Value *= Scale;
Daniel Sandersea4f6532015-11-06 12:22:31 +00001944 Inst.addOperand(MCOperand::createImm(Value + Offset));
Matheus Almeida779c5932013-11-18 12:32:49 +00001945 return MCDisassembler::Success;
1946}
1947
Daniel Sanders97297772016-03-22 14:40:00 +00001948template <unsigned Bits, int Offset, int ScaleBy>
1949static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
1950 uint64_t Address,
1951 const void *Decoder) {
1952 int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
Daniel Sanders78e89022016-03-11 11:37:50 +00001953 Inst.addOperand(MCOperand::createImm(Imm + Offset));
1954 return MCDisassembler::Success;
1955}
1956
Akira Hatanaka71928e62012-04-17 18:03:21 +00001957static DecodeStatus DecodeInsSize(MCInst &Inst,
1958 unsigned Insn,
1959 uint64_t Address,
1960 const void *Decoder) {
1961 // First we need to grab the pos(lsb) from MCInst.
1962 int Pos = Inst.getOperand(2).getImm();
1963 int Size = (int) Insn - Pos + 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00001964 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001965 return MCDisassembler::Success;
1966}
1967
Daniel Sandersb59e1a42014-05-15 10:45:58 +00001968static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1969 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00001970 Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00001971 return MCDisassembler::Success;
1972}
Zoran Jovanovic28551422014-06-09 09:49:51 +00001973
1974static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
1975 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00001976 Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00001977 return MCDisassembler::Success;
1978}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001979
Vladimir Medicb682ddf2014-12-01 11:12:04 +00001980static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
1981 uint64_t Address, const void *Decoder) {
1982 int32_t DecodedValue;
1983 switch (Insn) {
1984 case 0: DecodedValue = 256; break;
1985 case 1: DecodedValue = 257; break;
1986 case 510: DecodedValue = -258; break;
1987 case 511: DecodedValue = -257; break;
1988 default: DecodedValue = SignExtend32<9>(Insn); break;
1989 }
Jim Grosbache9119e42015-05-13 18:37:00 +00001990 Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00001991 return MCDisassembler::Success;
1992}
1993
1994static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
1995 uint64_t Address, const void *Decoder) {
1996 // Insn must be >= 0, since it is unsigned that condition is always true.
1997 assert(Insn < 16);
1998 int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
1999 255, 32768, 65535};
Jim Grosbache9119e42015-05-13 18:37:00 +00002000 Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002001 return MCDisassembler::Success;
2002}
2003
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002004static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2005 unsigned Insn,
2006 uint64_t Address,
2007 const void *Decoder) {
2008 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
Zoran Jovanovicdc4b8c22015-09-15 15:21:27 +00002009 Mips::S6, Mips::S7, Mips::FP};
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002010 unsigned RegNum;
2011
2012 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002013
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002014 // Empty register lists are not allowed.
2015 if (RegLst == 0)
2016 return MCDisassembler::Fail;
2017
2018 RegNum = RegLst & 0xf;
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002019
2020 // RegLst values 10-15, and 26-31 are reserved.
2021 if (RegNum > 9)
2022 return MCDisassembler::Fail;
2023
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002024 for (unsigned i = 0; i < RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002025 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002026
2027 if (RegLst & 0x10)
Jim Grosbache9119e42015-05-13 18:37:00 +00002028 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002029
2030 return MCDisassembler::Success;
2031}
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002032
2033static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2034 uint64_t Address,
2035 const void *Decoder) {
2036 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00002037 unsigned RegLst;
2038 switch(Inst.getOpcode()) {
2039 default:
2040 RegLst = fieldFromInstruction(Insn, 4, 2);
2041 break;
2042 case Mips::LWM16_MMR6:
2043 case Mips::SWM16_MMR6:
2044 RegLst = fieldFromInstruction(Insn, 8, 2);
2045 break;
2046 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002047 unsigned RegNum = RegLst & 0x3;
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002048
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002049 for (unsigned i = 0; i <= RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002050 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002051
Jim Grosbache9119e42015-05-13 18:37:00 +00002052 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002053
2054 return MCDisassembler::Success;
2055}
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002056
Zoran Jovanovic41688672015-02-10 16:36:20 +00002057static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
2058 uint64_t Address, const void *Decoder) {
2059
2060 unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
2061
2062 switch (RegPair) {
2063 default:
2064 return MCDisassembler::Fail;
2065 case 0:
Jim Grosbache9119e42015-05-13 18:37:00 +00002066 Inst.addOperand(MCOperand::createReg(Mips::A1));
2067 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002068 break;
2069 case 1:
Jim Grosbache9119e42015-05-13 18:37:00 +00002070 Inst.addOperand(MCOperand::createReg(Mips::A1));
2071 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002072 break;
2073 case 2:
Jim Grosbache9119e42015-05-13 18:37:00 +00002074 Inst.addOperand(MCOperand::createReg(Mips::A2));
2075 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002076 break;
2077 case 3:
Jim Grosbache9119e42015-05-13 18:37:00 +00002078 Inst.addOperand(MCOperand::createReg(Mips::A0));
2079 Inst.addOperand(MCOperand::createReg(Mips::S5));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002080 break;
2081 case 4:
Jim Grosbache9119e42015-05-13 18:37:00 +00002082 Inst.addOperand(MCOperand::createReg(Mips::A0));
2083 Inst.addOperand(MCOperand::createReg(Mips::S6));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002084 break;
2085 case 5:
Jim Grosbache9119e42015-05-13 18:37:00 +00002086 Inst.addOperand(MCOperand::createReg(Mips::A0));
2087 Inst.addOperand(MCOperand::createReg(Mips::A1));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002088 break;
2089 case 6:
Jim Grosbache9119e42015-05-13 18:37:00 +00002090 Inst.addOperand(MCOperand::createReg(Mips::A0));
2091 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002092 break;
2093 case 7:
Jim Grosbache9119e42015-05-13 18:37:00 +00002094 Inst.addOperand(MCOperand::createReg(Mips::A0));
2095 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002096 break;
2097 }
2098
2099 return MCDisassembler::Success;
2100}
2101
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002102static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2103 uint64_t Address, const void *Decoder) {
Justin Bogner6499b5f2015-06-23 07:28:57 +00002104 Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002105 return MCDisassembler::Success;
2106}
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002107
2108template <typename InsnType>
2109static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2110 uint64_t Address,
2111 const void *Decoder) {
2112 // We have:
2113 // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
2114 // Invalid if rt == 0
2115 // BGTZALC_MMR6 if rs == 0 && rt != 0
2116 // BLTZALC_MMR6 if rs != 0 && rs == rt
2117 // BLTUC_MMR6 if rs != 0 && rs != rt
2118
2119 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2120 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2121 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2122 bool HasRs = false;
2123 bool HasRt = false;
2124
2125 if (Rt == 0)
2126 return MCDisassembler::Fail;
2127 else if (Rs == 0) {
2128 MI.setOpcode(Mips::BGTZALC_MMR6);
2129 HasRt = true;
2130 }
2131 else if (Rs == Rt) {
2132 MI.setOpcode(Mips::BLTZALC_MMR6);
2133 HasRs = true;
2134 }
2135 else {
2136 MI.setOpcode(Mips::BLTUC_MMR6);
2137 HasRs = true;
2138 HasRt = true;
2139 }
2140
2141 if (HasRs)
2142 MI.addOperand(
2143 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2144
2145 if (HasRt)
2146 MI.addOperand(
2147 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2148
2149 MI.addOperand(MCOperand::createImm(Imm));
2150
2151 return MCDisassembler::Success;
2152}
2153
2154template <typename InsnType>
2155static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2156 uint64_t Address,
2157 const void *Decoder) {
2158 // We have:
2159 // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
2160 // Invalid if rs == 0
2161 // BLEZALC_MMR6 if rs == 0 && rt != 0
2162 // BGEZALC_MMR6 if rs == rt && rt != 0
2163 // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
2164
2165 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2166 InsnType Rs = fieldFromInstruction(insn, 16, 5);
2167 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2;
2168 bool HasRs = false;
2169
2170 if (Rt == 0)
2171 return MCDisassembler::Fail;
2172 else if (Rs == 0)
2173 MI.setOpcode(Mips::BLEZALC_MMR6);
2174 else if (Rs == Rt)
2175 MI.setOpcode(Mips::BGEZALC_MMR6);
2176 else {
2177 HasRs = true;
2178 MI.setOpcode(Mips::BGEUC_MMR6);
2179 }
2180
2181 if (HasRs)
2182 MI.addOperand(
2183 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2184 MI.addOperand(
2185 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2186
2187 MI.addOperand(MCOperand::createImm(Imm));
2188
2189 return MCDisassembler::Success;
2190}