blob: 2f9c2868ca7216353cb77bf883176a9707228612 [file] [log] [blame]
Eugene Zelenko926883e2017-02-01 01:22:51 +00001//===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===//
Akira Hatanaka71928e62012-04-17 18:03:21 +00002//
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
Eugene Zelenko79220eae2017-08-03 22:12:30 +000014#include "MCTargetDesc/MipsMCTargetDesc.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000015#include "Mips.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000016#include "llvm/ADT/ArrayRef.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"
Eugene Zelenko926883e2017-02-01 01:22:51 +000021#include "llvm/MC/MCRegisterInfo.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000022#include "llvm/MC/MCSubtargetInfo.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000023#include "llvm/Support/Compiler.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/ErrorHandling.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000026#include "llvm/Support/MathExtras.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000027#include "llvm/Support/TargetRegistry.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000028#include "llvm/Support/raw_ostream.h"
Eugene Zelenko926883e2017-02-01 01:22:51 +000029#include <cassert>
30#include <cstdint>
Akira Hatanaka71928e62012-04-17 18:03:21 +000031
Akira Hatanaka71928e62012-04-17 18:03:21 +000032using namespace llvm;
33
Chandler Carruthe96dd892014-04-21 22:55:11 +000034#define DEBUG_TYPE "mips-disassembler"
35
Eugene Zelenko79220eae2017-08-03 22:12:30 +000036using DecodeStatus = MCDisassembler::DecodeStatus;
Akira Hatanaka71928e62012-04-17 18:03:21 +000037
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000038namespace {
39
Daniel Sandersa19216c2015-02-11 11:28:56 +000040class MipsDisassembler : public MCDisassembler {
Vladimir Medicdde3d582013-09-06 12:30:36 +000041 bool IsMicroMips;
Daniel Sandersa19216c2015-02-11 11:28:56 +000042 bool IsBigEndian;
Eugene Zelenko926883e2017-02-01 01:22:51 +000043
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000044public:
Daniel Sandersa19216c2015-02-11 11:28:56 +000045 MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian)
46 : MCDisassembler(STI, Ctx),
Michael Kupersteindb0712f2015-05-26 10:47:10 +000047 IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]),
Daniel Sandersa19216c2015-02-11 11:28:56 +000048 IsBigEndian(IsBigEndian) {}
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000049
Simon Dardis4fbf76f2016-06-14 11:29:28 +000050 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
Michael Kupersteindb0712f2015-05-26 10:47:10 +000051 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
52 bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; }
Eugene Zelenko926883e2017-02-01 01:22:51 +000053
Daniel Sandersc171f652014-06-13 13:15:59 +000054 bool hasMips32r6() const {
Michael Kupersteindb0712f2015-05-26 10:47:10 +000055 return STI.getFeatureBits()[Mips::FeatureMips32r6];
Daniel Sanders5c582b22014-05-22 11:23:21 +000056 }
Eugene Zelenko926883e2017-02-01 01:22:51 +000057
Zlatko Buljan6221be82016-03-31 08:51:24 +000058 bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
Daniel Sanders5c582b22014-05-22 11:23:21 +000059
Michael Kupersteindb0712f2015-05-26 10:47:10 +000060 bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
Daniel Sanders0fa60412014-06-12 13:39:06 +000061
Simon Dardis4fbf76f2016-06-14 11:29:28 +000062 bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; }
63
Kai Nacke3adf9b82015-05-28 16:23:16 +000064 bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; }
65
Daniel Sandersc171f652014-06-13 13:15:59 +000066 bool hasCOP3() const {
67 // Only present in MIPS-I and MIPS-II
68 return !hasMips32() && !hasMips3();
69 }
70
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000071 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000072 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000073 raw_ostream &VStream,
74 raw_ostream &CStream) const override;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000075};
76
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000077} // end anonymous namespace
78
Akira Hatanaka71928e62012-04-17 18:03:21 +000079// Forward declare these because the autogenerated code will reference them.
80// Definitions are further down.
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000081static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
82 unsigned RegNo,
83 uint64_t Address,
84 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +000085
Reed Kotlerec8a5492013-02-14 03:05:25 +000086static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
87 unsigned RegNo,
88 uint64_t Address,
89 const void *Decoder);
90
Zoran Jovanovicb0852e52014-10-21 08:23:11 +000091static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
92 unsigned RegNo,
93 uint64_t Address,
94 const void *Decoder);
95
Jozef Kolek1904fa22014-11-24 14:25:53 +000096static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
97 unsigned RegNo,
98 uint64_t Address,
99 const void *Decoder);
100
Zoran Jovanovic41688672015-02-10 16:36:20 +0000101static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
102 unsigned RegNo,
103 uint64_t Address,
104 const void *Decoder);
105
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000106static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
107 unsigned RegNo,
108 uint64_t Address,
109 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000110
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000111static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
112 unsigned Insn,
113 uint64_t Address,
114 const void *Decoder);
115
Akira Hatanaka654655f2013-08-14 00:53:38 +0000116static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
117 unsigned RegNo,
118 uint64_t Address,
119 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000120
Akira Hatanaka71928e62012-04-17 18:03:21 +0000121static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
122 unsigned RegNo,
123 uint64_t Address,
124 const void *Decoder);
125
126static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
127 unsigned RegNo,
128 uint64_t Address,
129 const void *Decoder);
130
131static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
132 unsigned RegNo,
133 uint64_t Address,
134 const void *Decoder);
135
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000136static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
137 unsigned RegNo,
138 uint64_t Address,
139 const void *Decoder);
140
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +0000141static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
142 uint64_t Address,
143 const void *Decoder);
Daniel Sanders0fa60412014-06-12 13:39:06 +0000144
Akira Hatanaka71928e62012-04-17 18:03:21 +0000145static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
146 unsigned Insn,
147 uint64_t Address,
148 const void *Decoder);
149
150static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
151 unsigned RegNo,
152 uint64_t Address,
153 const void *Decoder);
154
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000155static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
156 unsigned RegNo,
157 uint64_t Address,
158 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000159
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000160static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
161 unsigned RegNo,
162 uint64_t Address,
163 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000164
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000165static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
166 unsigned RegNo,
167 uint64_t Address,
168 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000169
Jack Carter3eb663b2013-09-26 00:09:46 +0000170static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
171 unsigned RegNo,
172 uint64_t Address,
173 const void *Decoder);
174
Jack Carter5dc8ac92013-09-25 23:50:44 +0000175static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
176 unsigned RegNo,
177 uint64_t Address,
178 const void *Decoder);
179
180static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
181 unsigned RegNo,
182 uint64_t Address,
183 const void *Decoder);
184
185static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
186 unsigned RegNo,
187 uint64_t Address,
188 const void *Decoder);
189
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000190static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
191 unsigned RegNo,
192 uint64_t Address,
193 const void *Decoder);
194
Daniel Sandersa3134fa2015-06-27 15:39:19 +0000195static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
196 unsigned RegNo,
197 uint64_t Address,
198 const void *Decoder);
199
Daniel Sanders2a83d682014-05-21 12:56:39 +0000200static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
201 unsigned RegNo,
202 uint64_t Address,
203 const void *Decoder);
204
Akira Hatanaka71928e62012-04-17 18:03:21 +0000205static DecodeStatus DecodeBranchTarget(MCInst &Inst,
206 unsigned Offset,
207 uint64_t Address,
208 const void *Decoder);
209
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +0000210static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
211 unsigned Offset,
212 uint64_t Address,
213 const void *Decoder);
214
Akira Hatanaka71928e62012-04-17 18:03:21 +0000215static DecodeStatus DecodeJumpTarget(MCInst &Inst,
216 unsigned Insn,
217 uint64_t Address,
218 const void *Decoder);
219
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000220static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
221 unsigned Offset,
222 uint64_t Address,
223 const void *Decoder);
224
Zoran Jovanovic84e4d592016-05-17 11:10:15 +0000225static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
226 unsigned Offset,
227 uint64_t Address,
228 const void *Decoder);
229
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000230static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
231 unsigned Offset,
232 uint64_t Address,
233 const void *Decoder);
234
Jozef Kolek9761e962015-01-12 12:03:34 +0000235// DecodeBranchTarget7MM - Decode microMIPS branch offset, which is
236// shifted left by 1 bit.
237static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
238 unsigned Offset,
239 uint64_t Address,
240 const void *Decoder);
241
Jozef Kolek5cfebdd2015-01-21 12:39:30 +0000242// DecodeBranchTarget10MM - Decode microMIPS branch offset, which is
243// shifted left by 1 bit.
244static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
245 unsigned Offset,
246 uint64_t Address,
247 const void *Decoder);
248
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000249// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
250// shifted left by 1 bit.
251static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
252 unsigned Offset,
253 uint64_t Address,
254 const void *Decoder);
255
Zoran Jovanovica887b362015-11-30 12:56:18 +0000256// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
257// shifted left by 1 bit.
258static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
259 unsigned Offset,
260 uint64_t Address,
261 const void *Decoder);
262
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000263// DecodeJumpTargetMM - Decode microMIPS jump target, which is
264// shifted left by 1 bit.
265static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
266 unsigned Insn,
267 uint64_t Address,
268 const void *Decoder);
269
Akira Hatanaka71928e62012-04-17 18:03:21 +0000270static DecodeStatus DecodeMem(MCInst &Inst,
271 unsigned Insn,
272 uint64_t Address,
273 const void *Decoder);
274
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000275static DecodeStatus DecodeMemEVA(MCInst &Inst,
276 unsigned Insn,
277 uint64_t Address,
278 const void *Decoder);
279
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +0000280static DecodeStatus DecodeLoadByte15(MCInst &Inst,
281 unsigned Insn,
282 uint64_t Address,
283 const void *Decoder);
284
Eugene Zelenko79220eae2017-08-03 22:12:30 +0000285static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address,
286 const void *Decoder);
Daniel Sanders92db6b72014-10-01 08:26:55 +0000287
Daniel Sanderse4e83a72015-09-15 10:02:16 +0000288static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
289 unsigned Insn,
290 uint64_t Address,
291 const void *Decoder);
Vladimir Medicdf464ae2015-01-29 11:33:41 +0000292
Jozef Kolekab6d1cc2014-12-23 19:55:34 +0000293static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
294 unsigned Insn,
295 uint64_t Address,
296 const void *Decoder);
297
Zoran Jovanovicd9790792015-09-09 09:10:46 +0000298static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
299 unsigned Insn,
300 uint64_t Address,
301 const void *Decoder);
302
Daniel Sandersb4484d62014-11-27 17:28:10 +0000303static DecodeStatus DecodeSyncI(MCInst &Inst,
304 unsigned Insn,
305 uint64_t Address,
306 const void *Decoder);
307
Hrvoje Varga18148672015-10-28 11:04:29 +0000308static DecodeStatus DecodeSynciR6(MCInst &Inst,
309 unsigned Insn,
310 uint64_t Address,
311 const void *Decoder);
312
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000313static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
314 uint64_t Address, const void *Decoder);
315
Jozef Kolek315e7ec2014-11-26 18:56:38 +0000316static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
317 unsigned Insn,
318 uint64_t Address,
319 const void *Decoder);
320
Jozef Kolek12c69822014-12-23 16:16:33 +0000321static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
322 unsigned Insn,
323 uint64_t Address,
324 const void *Decoder);
325
Jozef Koleke10a02e2015-01-28 17:27:26 +0000326static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
327 unsigned Insn,
328 uint64_t Address,
329 const void *Decoder);
330
Jozef Kolekd68d424a2015-02-10 12:41:13 +0000331static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
332 unsigned Insn,
333 uint64_t Address,
334 const void *Decoder);
335
Zoran Jovanovica6593ff2015-08-18 12:53:08 +0000336static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
337 unsigned Insn,
338 uint64_t Address,
339 const void *Decoder);
340
Vladimir Medicdde3d582013-09-06 12:30:36 +0000341static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
342 unsigned Insn,
343 uint64_t Address,
344 const void *Decoder);
345
346static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
347 unsigned Insn,
348 uint64_t Address,
349 const void *Decoder);
350
Akira Hatanaka71928e62012-04-17 18:03:21 +0000351static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
352 uint64_t Address,
353 const void *Decoder);
354
Zlatko Buljancba9f802016-07-11 07:41:56 +0000355static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
356 uint64_t Address,
357 const void *Decoder);
358
Eugene Zelenko79220eae2017-08-03 22:12:30 +0000359static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address,
360 const void *Decoder);
Daniel Sanders92db6b72014-10-01 08:26:55 +0000361
Eugene Zelenko79220eae2017-08-03 22:12:30 +0000362static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address,
363 const void *Decoder);
Daniel Sanders92db6b72014-10-01 08:26:55 +0000364
Vladimir Medic435cf8a2015-01-21 10:47:36 +0000365static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn,
Eugene Zelenko79220eae2017-08-03 22:12:30 +0000366 uint64_t Address, const void *Decoder);
Vladimir Medic435cf8a2015-01-21 10:47:36 +0000367
Zlatko Buljancba9f802016-07-11 07:41:56 +0000368static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
369 uint64_t Address,
370 const void *Decoder);
371
Daniel Sanders6a803f62014-06-16 13:13:03 +0000372static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
373 unsigned Insn,
374 uint64_t Address,
375 const void *Decoder);
376
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000377static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
378 unsigned Value,
379 uint64_t Address,
380 const void *Decoder);
381
Daniel Sanders97297772016-03-22 14:40:00 +0000382static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +0000383 unsigned Value,
384 uint64_t Address,
385 const void *Decoder);
386
Zoran Jovanovic6b28f092015-09-09 13:55:45 +0000387static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
388 unsigned Value,
389 uint64_t Address,
390 const void *Decoder);
391
Daniel Sanders19b7f762016-03-14 11:16:56 +0000392template <unsigned Bits, int Offset, int Scale>
393static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
394 uint64_t Address,
395 const void *Decoder);
396
Daniel Sandersea4f6532015-11-06 12:22:31 +0000397template <unsigned Bits, int Offset>
398static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value,
Daniel Sanders19b7f762016-03-14 11:16:56 +0000399 uint64_t Address,
400 const void *Decoder) {
401 return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address,
402 Decoder);
403}
Matheus Almeida779c5932013-11-18 12:32:49 +0000404
Daniel Sanders97297772016-03-22 14:40:00 +0000405template <unsigned Bits, int Offset = 0, int ScaleBy = 1>
406static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
407 uint64_t Address,
408 const void *Decoder);
Daniel Sanders78e89022016-03-11 11:37:50 +0000409
Akira Hatanaka71928e62012-04-17 18:03:21 +0000410static DecodeStatus DecodeInsSize(MCInst &Inst,
411 unsigned Insn,
412 uint64_t Address,
413 const void *Decoder);
414
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000415static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
416 uint64_t Address, const void *Decoder);
417
Zoran Jovanovic28551422014-06-09 09:49:51 +0000418static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
419 uint64_t Address, const void *Decoder);
420
Vladimir Medicb682ddf2014-12-01 11:12:04 +0000421static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
422 uint64_t Address, const void *Decoder);
423
424static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
425 uint64_t Address, const void *Decoder);
426
Jozef Kolek2c6d7322015-01-21 12:10:11 +0000427static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
428 uint64_t Address, const void *Decoder);
429
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000430/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
431/// handle.
432template <typename InsnType>
433static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
434 const void *Decoder);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000435
436template <typename InsnType>
Simon Dardiscf060792016-09-16 13:50:43 +0000437static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
438 const void *Decoder);
439
440template <typename InsnType>
441static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
442 const void *Decoder);
443
444template <typename InsnType>
Simon Dardisb3fd1892016-10-14 09:31:42 +0000445static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
446 const void *Decoder);
447
448template <typename InsnType>
449static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
450 const void *Decoder);
451
452template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000453static DecodeStatus
454DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
455 const void *Decoder);
456
457template <typename InsnType>
458static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000459DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
460 const void *Decoder);
461
462template <typename InsnType>
463static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000464DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
465 const void *Decoder);
466
467template <typename InsnType>
468static DecodeStatus
Hrvoje Vargac962c492016-06-09 12:57:23 +0000469DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
470 const void *Decoder);
471
472template <typename InsnType>
473static DecodeStatus
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000474DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
475 const void *Decoder);
476
477template <typename InsnType>
478static DecodeStatus
479DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
480 const void *Decoder);
481
482template <typename InsnType>
483static DecodeStatus
Daniel Sanders5c582b22014-05-22 11:23:21 +0000484DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
485 const void *Decoder);
486
487template <typename InsnType>
488static DecodeStatus
489DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
490 const void *Decoder);
491
492template <typename InsnType>
493static DecodeStatus
494DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
495 const void *Decoder);
496
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000497template <typename InsnType>
498static DecodeStatus
499DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
500 const void *Decoder);
501
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +0000502template <typename InsnType>
503static DecodeStatus
504DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
505 const void *Decoder);
506
507template <typename InsnType>
508static DecodeStatus
509DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address,
510 const void *Decoder);
511
Simon Dardis6f83ae32017-09-14 15:17:50 +0000512template <typename InsnType>
513static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
514 const void *Decoder);
515
Simon Dardis55e44672017-09-14 17:27:53 +0000516template <typename InsnType>
517static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
518 const void *Decoder);
519
Petar Jovanovic3408caf2018-03-14 14:13:31 +0000520template <typename InsnType>
521static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
522 const void *Decoder);
523
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000524static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
525 uint64_t Address,
526 const void *Decoder);
527
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000528static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
529 uint64_t Address,
530 const void *Decoder);
531
Simon Dardis169df4e2017-11-06 12:59:53 +0000532static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
Zoran Jovanovic41688672015-02-10 16:36:20 +0000533 uint64_t Address,
534 const void *Decoder);
535
Akira Hatanaka71928e62012-04-17 18:03:21 +0000536namespace llvm {
Eugene Zelenko926883e2017-02-01 01:22:51 +0000537
Mehdi Aminif42454b2016-10-09 23:00:34 +0000538Target &getTheMipselTarget();
539Target &getTheMipsTarget();
540Target &getTheMips64Target();
541Target &getTheMips64elTarget();
Eugene Zelenko926883e2017-02-01 01:22:51 +0000542
543} // end namespace llvm
Akira Hatanaka71928e62012-04-17 18:03:21 +0000544
545static MCDisassembler *createMipsDisassembler(
546 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000547 const MCSubtargetInfo &STI,
548 MCContext &Ctx) {
549 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000550}
551
552static MCDisassembler *createMipselDisassembler(
553 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000554 const MCSubtargetInfo &STI,
555 MCContext &Ctx) {
556 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000557}
558
Akira Hatanaka71928e62012-04-17 18:03:21 +0000559extern "C" void LLVMInitializeMipsDisassembler() {
560 // Register the disassembler.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000561 TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
Akira Hatanaka71928e62012-04-17 18:03:21 +0000562 createMipsDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000563 TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
Akira Hatanaka71928e62012-04-17 18:03:21 +0000564 createMipselDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000565 TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
Daniel Sandersa19216c2015-02-11 11:28:56 +0000566 createMipsDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000567 TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
Daniel Sandersa19216c2015-02-11 11:28:56 +0000568 createMipselDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000569}
570
Akira Hatanaka71928e62012-04-17 18:03:21 +0000571#include "MipsGenDisassemblerTables.inc"
572
Daniel Sanders5c582b22014-05-22 11:23:21 +0000573static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
Daniel Sandersa19216c2015-02-11 11:28:56 +0000574 const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000575 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
576 return *(RegInfo->getRegClass(RC).begin() + RegNo);
577}
578
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000579template <typename InsnType>
580static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
581 const void *Decoder) {
Eugene Zelenko79220eae2017-08-03 22:12:30 +0000582 using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *);
583
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000584 // The size of the n field depends on the element size
585 // The register class also depends on this.
586 InsnType tmp = fieldFromInstruction(insn, 17, 5);
587 unsigned NSize = 0;
588 DecodeFN RegDecoder = nullptr;
589 if ((tmp & 0x18) == 0x00) { // INSVE_B
590 NSize = 4;
591 RegDecoder = DecodeMSA128BRegisterClass;
592 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
593 NSize = 3;
594 RegDecoder = DecodeMSA128HRegisterClass;
595 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
596 NSize = 2;
597 RegDecoder = DecodeMSA128WRegisterClass;
598 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
599 NSize = 1;
600 RegDecoder = DecodeMSA128DRegisterClass;
601 } else
602 llvm_unreachable("Invalid encoding");
603
604 assert(NSize != 0 && RegDecoder != nullptr);
605
606 // $wd
607 tmp = fieldFromInstruction(insn, 6, 5);
608 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
609 return MCDisassembler::Fail;
610 // $wd_in
611 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
612 return MCDisassembler::Fail;
613 // $n
614 tmp = fieldFromInstruction(insn, 16, NSize);
Jim Grosbache9119e42015-05-13 18:37:00 +0000615 MI.addOperand(MCOperand::createImm(tmp));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000616 // $ws
617 tmp = fieldFromInstruction(insn, 11, 5);
618 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
619 return MCDisassembler::Fail;
620 // $n2
Jim Grosbache9119e42015-05-13 18:37:00 +0000621 MI.addOperand(MCOperand::createImm(0));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000622
623 return MCDisassembler::Success;
624}
625
Daniel Sanders5c582b22014-05-22 11:23:21 +0000626template <typename InsnType>
Simon Dardiscf060792016-09-16 13:50:43 +0000627static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
628 const void *Decoder) {
Simon Dardisb3fd1892016-10-14 09:31:42 +0000629 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Simon Dardiscf060792016-09-16 13:50:43 +0000630 InsnType Imm = fieldFromInstruction(insn, 0, 16);
631 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
Simon Dardisb3fd1892016-10-14 09:31:42 +0000632 Rs)));
Simon Dardiscf060792016-09-16 13:50:43 +0000633 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
Simon Dardisb3fd1892016-10-14 09:31:42 +0000634 Rs)));
Simon Dardiscf060792016-09-16 13:50:43 +0000635 MI.addOperand(MCOperand::createImm(Imm));
636
637 return MCDisassembler::Success;
638}
639
640template <typename InsnType>
641static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
642 const void *Decoder) {
Simon Dardisb3fd1892016-10-14 09:31:42 +0000643 InsnType Rs = fieldFromInstruction(insn, 21, 5);
Simon Dardiscf060792016-09-16 13:50:43 +0000644 InsnType Imm = fieldFromInstruction(insn, 0, 16);
645 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
Simon Dardisb3fd1892016-10-14 09:31:42 +0000646 Rs)));
Simon Dardiscf060792016-09-16 13:50:43 +0000647 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
Simon Dardisb3fd1892016-10-14 09:31:42 +0000648 Rs)));
Simon Dardiscf060792016-09-16 13:50:43 +0000649 MI.addOperand(MCOperand::createImm(Imm));
650
651 return MCDisassembler::Success;
652}
653
654template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000655static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
656 uint64_t Address,
657 const void *Decoder) {
658 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
659 // (otherwise we would have matched the ADDI instruction from the earlier
660 // ISA's instead).
661 //
662 // We have:
663 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
664 // BOVC if rs >= rt
665 // BEQZALC if rs == 0 && rt != 0
666 // BEQC if rs < rt && rs != 0
667
668 InsnType Rs = fieldFromInstruction(insn, 21, 5);
669 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000670 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000671 bool HasRs = false;
672
673 if (Rs >= Rt) {
674 MI.setOpcode(Mips::BOVC);
675 HasRs = true;
676 } else if (Rs != 0 && Rs < Rt) {
677 MI.setOpcode(Mips::BEQC);
678 HasRs = true;
679 } else
680 MI.setOpcode(Mips::BEQZALC);
681
682 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000683 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000684 Rs)));
685
Jim Grosbache9119e42015-05-13 18:37:00 +0000686 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000687 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000688 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000689
690 return MCDisassembler::Success;
691}
692
693template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000694static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
695 uint64_t Address,
696 const void *Decoder) {
697 InsnType Rt = fieldFromInstruction(insn, 21, 5);
698 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000699 int64_t Imm = 0;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000700
701 if (Rs >= Rt) {
702 MI.setOpcode(Mips::BOVC_MMR6);
703 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
704 Rt)));
705 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
706 Rs)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000707 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000708 } else if (Rs != 0 && Rs < Rt) {
709 MI.setOpcode(Mips::BEQC_MMR6);
710 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
711 Rs)));
712 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
713 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000714 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000715 } else {
716 MI.setOpcode(Mips::BEQZALC_MMR6);
717 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
718 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000719 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000720 }
721
722 MI.addOperand(MCOperand::createImm(Imm));
723
724 return MCDisassembler::Success;
725}
726
727template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000728static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
729 uint64_t Address,
730 const void *Decoder) {
731 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
732 // (otherwise we would have matched the ADDI instruction from the earlier
733 // ISA's instead).
734 //
735 // We have:
736 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
737 // BNVC if rs >= rt
738 // BNEZALC if rs == 0 && rt != 0
739 // BNEC if rs < rt && rs != 0
740
741 InsnType Rs = fieldFromInstruction(insn, 21, 5);
742 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000743 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000744 bool HasRs = false;
745
746 if (Rs >= Rt) {
747 MI.setOpcode(Mips::BNVC);
748 HasRs = true;
749 } else if (Rs != 0 && Rs < Rt) {
750 MI.setOpcode(Mips::BNEC);
751 HasRs = true;
752 } else
753 MI.setOpcode(Mips::BNEZALC);
754
755 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000756 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000757 Rs)));
758
Jim Grosbache9119e42015-05-13 18:37:00 +0000759 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000760 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000761 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000762
763 return MCDisassembler::Success;
764}
765
766template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000767static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
768 uint64_t Address,
769 const void *Decoder) {
770 InsnType Rt = fieldFromInstruction(insn, 21, 5);
771 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000772 int64_t Imm = 0;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000773
774 if (Rs >= Rt) {
775 MI.setOpcode(Mips::BNVC_MMR6);
776 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
777 Rt)));
778 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
779 Rs)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000780 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000781 } else if (Rs != 0 && Rs < Rt) {
782 MI.setOpcode(Mips::BNEC_MMR6);
783 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
784 Rs)));
785 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
786 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000787 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000788 } else {
789 MI.setOpcode(Mips::BNEZALC_MMR6);
790 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
791 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000792 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000793 }
794
795 MI.addOperand(MCOperand::createImm(Imm));
796
797 return MCDisassembler::Success;
798}
799
800template <typename InsnType>
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000801static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
802 uint64_t Address,
803 const void *Decoder) {
804 // We have:
805 // 0b110101 ttttt sssss iiiiiiiiiiiiiiii
806 // Invalid if rt == 0
807 // BGTZC_MMR6 if rs == 0 && rt != 0
808 // BLTZC_MMR6 if rs == rt && rt != 0
809 // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0
810
811 InsnType Rt = fieldFromInstruction(insn, 21, 5);
812 InsnType Rs = fieldFromInstruction(insn, 16, 5);
813 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
814 bool HasRs = false;
815
816 if (Rt == 0)
817 return MCDisassembler::Fail;
818 else if (Rs == 0)
819 MI.setOpcode(Mips::BGTZC_MMR6);
820 else if (Rs == Rt)
821 MI.setOpcode(Mips::BLTZC_MMR6);
822 else {
823 MI.setOpcode(Mips::BLTC_MMR6);
824 HasRs = true;
825 }
826
827 if (HasRs)
828 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
829 Rs)));
830
831 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
832 Rt)));
833
834 MI.addOperand(MCOperand::createImm(Imm));
835
836 return MCDisassembler::Success;
837}
838
839template <typename InsnType>
840static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
841 uint64_t Address,
842 const void *Decoder) {
843 // We have:
844 // 0b111101 ttttt sssss iiiiiiiiiiiiiiii
845 // Invalid if rt == 0
846 // BLEZC_MMR6 if rs == 0 && rt != 0
847 // BGEZC_MMR6 if rs == rt && rt != 0
848 // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0
849
850 InsnType Rt = fieldFromInstruction(insn, 21, 5);
851 InsnType Rs = fieldFromInstruction(insn, 16, 5);
852 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
853 bool HasRs = false;
854
855 if (Rt == 0)
856 return MCDisassembler::Fail;
857 else if (Rs == 0)
858 MI.setOpcode(Mips::BLEZC_MMR6);
859 else if (Rs == Rt)
860 MI.setOpcode(Mips::BGEZC_MMR6);
861 else {
862 HasRs = true;
863 MI.setOpcode(Mips::BGEC_MMR6);
864 }
865
866 if (HasRs)
867 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
868 Rs)));
869
870 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
871 Rt)));
872
873 MI.addOperand(MCOperand::createImm(Imm));
874
875 return MCDisassembler::Success;
876}
877
878template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000879static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
880 uint64_t Address,
881 const void *Decoder) {
882 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
883 // (otherwise we would have matched the BLEZL instruction from the earlier
884 // ISA's instead).
885 //
886 // We have:
887 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
888 // Invalid if rs == 0
889 // BLEZC if rs == 0 && rt != 0
890 // BGEZC if rs == rt && rt != 0
891 // BGEC if rs != rt && rs != 0 && rt != 0
892
893 InsnType Rs = fieldFromInstruction(insn, 21, 5);
894 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000895 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000896 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000897
898 if (Rt == 0)
899 return MCDisassembler::Fail;
900 else if (Rs == 0)
901 MI.setOpcode(Mips::BLEZC);
902 else if (Rs == Rt)
903 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000904 else {
905 HasRs = true;
906 MI.setOpcode(Mips::BGEC);
907 }
908
909 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000910 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000911 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000912
Jim Grosbache9119e42015-05-13 18:37:00 +0000913 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000914 Rt)));
915
Jim Grosbache9119e42015-05-13 18:37:00 +0000916 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000917
918 return MCDisassembler::Success;
919}
920
921template <typename InsnType>
922static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
923 uint64_t Address,
924 const void *Decoder) {
925 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
926 // (otherwise we would have matched the BGTZL instruction from the earlier
927 // ISA's instead).
928 //
929 // We have:
930 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
931 // Invalid if rs == 0
932 // BGTZC if rs == 0 && rt != 0
933 // BLTZC if rs == rt && rt != 0
934 // BLTC if rs != rt && rs != 0 && rt != 0
935
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000936 bool HasRs = false;
937
Daniel Sanders5c582b22014-05-22 11:23:21 +0000938 InsnType Rs = fieldFromInstruction(insn, 21, 5);
939 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000940 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000941
942 if (Rt == 0)
943 return MCDisassembler::Fail;
944 else if (Rs == 0)
945 MI.setOpcode(Mips::BGTZC);
946 else if (Rs == Rt)
947 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000948 else {
949 MI.setOpcode(Mips::BLTC);
950 HasRs = true;
951 }
952
953 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000954 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000955 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000956
Jim Grosbache9119e42015-05-13 18:37:00 +0000957 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000958 Rt)));
959
Jim Grosbache9119e42015-05-13 18:37:00 +0000960 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000961
962 return MCDisassembler::Success;
963}
964
965template <typename InsnType>
966static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
967 uint64_t Address,
968 const void *Decoder) {
969 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
970 // (otherwise we would have matched the BGTZ instruction from the earlier
971 // ISA's instead).
972 //
973 // We have:
974 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
975 // BGTZ if rt == 0
976 // BGTZALC if rs == 0 && rt != 0
977 // BLTZALC if rs != 0 && rs == rt
978 // BLTUC if rs != 0 && rs != rt
979
980 InsnType Rs = fieldFromInstruction(insn, 21, 5);
981 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000982 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000983 bool HasRs = false;
984 bool HasRt = false;
985
986 if (Rt == 0) {
987 MI.setOpcode(Mips::BGTZ);
988 HasRs = true;
989 } else if (Rs == 0) {
990 MI.setOpcode(Mips::BGTZALC);
991 HasRt = true;
992 } else if (Rs == Rt) {
993 MI.setOpcode(Mips::BLTZALC);
994 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000995 } else {
996 MI.setOpcode(Mips::BLTUC);
997 HasRs = true;
998 HasRt = true;
999 }
Daniel Sanders5c582b22014-05-22 11:23:21 +00001000
1001 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +00001002 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +00001003 Rs)));
1004
1005 if (HasRt)
Jim Grosbache9119e42015-05-13 18:37:00 +00001006 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +00001007 Rt)));
1008
Jim Grosbache9119e42015-05-13 18:37:00 +00001009 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +00001010
1011 return MCDisassembler::Success;
1012}
1013
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001014template <typename InsnType>
1015static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
1016 uint64_t Address,
1017 const void *Decoder) {
1018 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
1019 // (otherwise we would have matched the BLEZL instruction from the earlier
1020 // ISA's instead).
1021 //
1022 // We have:
1023 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
1024 // Invalid if rs == 0
1025 // BLEZALC if rs == 0 && rt != 0
1026 // BGEZALC if rs == rt && rt != 0
1027 // BGEUC if rs != rt && rs != 0 && rt != 0
1028
1029 InsnType Rs = fieldFromInstruction(insn, 21, 5);
1030 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +00001031 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001032 bool HasRs = false;
1033
1034 if (Rt == 0)
1035 return MCDisassembler::Fail;
1036 else if (Rs == 0)
1037 MI.setOpcode(Mips::BLEZALC);
1038 else if (Rs == Rt)
1039 MI.setOpcode(Mips::BGEZALC);
1040 else {
1041 HasRs = true;
1042 MI.setOpcode(Mips::BGEUC);
1043 }
1044
1045 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +00001046 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001047 Rs)));
Jim Grosbache9119e42015-05-13 18:37:00 +00001048 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001049 Rt)));
1050
Jim Grosbache9119e42015-05-13 18:37:00 +00001051 MI.addOperand(MCOperand::createImm(Imm));
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001052
1053 return MCDisassembler::Success;
1054}
1055
Simon Dardis55e44672017-09-14 17:27:53 +00001056// Override the generated disassembler to produce DEXT all the time. This is
1057// for feature / behaviour parity with binutils.
1058template <typename InsnType>
1059static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
1060 const void *Decoder) {
1061 unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
1062 unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
1063 unsigned Size = 0;
1064 unsigned Pos = 0;
Simon Dardis55e44672017-09-14 17:27:53 +00001065
1066 switch (MI.getOpcode()) {
Simon Dardis55e44672017-09-14 17:27:53 +00001067 case Mips::DEXT:
1068 Pos = Lsb;
1069 Size = Msbd + 1;
1070 break;
Simon Dardis55e44672017-09-14 17:27:53 +00001071 case Mips::DEXTM:
1072 Pos = Lsb;
1073 Size = Msbd + 1 + 32;
1074 break;
Simon Dardis55e44672017-09-14 17:27:53 +00001075 case Mips::DEXTU:
1076 Pos = Lsb + 32;
1077 Size = Msbd + 1;
1078 break;
1079 default:
1080 llvm_unreachable("Unknown DEXT instruction!");
1081 }
1082
Aleksandar Beserminjid6dada12017-12-11 11:21:40 +00001083 MI.setOpcode(Mips::DEXT);
Simon Dardis55e44672017-09-14 17:27:53 +00001084
Simon Dardis55e44672017-09-14 17:27:53 +00001085 InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1086 InsnType Rt = fieldFromInstruction(Insn, 16, 5);
Simon Dardis55e44672017-09-14 17:27:53 +00001087
1088 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1089 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
1090 MI.addOperand(MCOperand::createImm(Pos));
1091 MI.addOperand(MCOperand::createImm(Size));
1092
1093 return MCDisassembler::Success;
1094}
1095
Simon Dardis6f83ae32017-09-14 15:17:50 +00001096// Override the generated disassembler to produce DINS all the time. This is
1097// for feature / behaviour parity with binutils.
1098template <typename InsnType>
1099static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
1100 const void *Decoder) {
1101 unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
1102 unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
1103 unsigned Size = 0;
1104 unsigned Pos = 0;
Simon Dardis6f83ae32017-09-14 15:17:50 +00001105
1106 switch (MI.getOpcode()) {
Simon Dardis6f83ae32017-09-14 15:17:50 +00001107 case Mips::DINS:
1108 Pos = Lsb;
1109 Size = Msbd + 1 - Pos;
1110 break;
Simon Dardis6f83ae32017-09-14 15:17:50 +00001111 case Mips::DINSM:
1112 Pos = Lsb;
1113 Size = Msbd + 33 - Pos;
1114 break;
Simon Dardis6f83ae32017-09-14 15:17:50 +00001115 case Mips::DINSU:
1116 Pos = Lsb + 32;
1117 // mbsd = pos + size - 33
1118 // mbsd - pos + 33 = size
1119 Size = Msbd + 33 - Pos;
1120 break;
1121 default:
1122 llvm_unreachable("Unknown DINS instruction!");
1123 }
1124
Simon Dardis6f83ae32017-09-14 15:17:50 +00001125 InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1126 InsnType Rt = fieldFromInstruction(Insn, 16, 5);
Simon Dardis6f83ae32017-09-14 15:17:50 +00001127
Aleksandar Beserminjid6dada12017-12-11 11:21:40 +00001128 MI.setOpcode(Mips::DINS);
Simon Dardis6f83ae32017-09-14 15:17:50 +00001129 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1130 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
1131 MI.addOperand(MCOperand::createImm(Pos));
1132 MI.addOperand(MCOperand::createImm(Size));
1133
1134 return MCDisassembler::Success;
1135}
Petar Jovanovic3408caf2018-03-14 14:13:31 +00001136
1137// Auto-generated decoder wouldn't add the third operand for CRC32*.
1138template <typename InsnType>
1139static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
1140 const void *Decoder) {
1141 InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1142 InsnType Rt = fieldFromInstruction(Insn, 16, 5);
1143 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1144 Rt)));
1145 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1146 Rs)));
1147 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
1148 Rt)));
1149 return MCDisassembler::Success;
1150}
1151
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001152/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
Simon Pilgrimdcd84332016-11-18 11:53:36 +00001153/// according to the given endianness.
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001154static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1155 uint64_t &Size, uint32_t &Insn,
1156 bool IsBigEndian) {
1157 // We want to read exactly 2 Bytes of data.
1158 if (Bytes.size() < 2) {
1159 Size = 0;
1160 return MCDisassembler::Fail;
1161 }
1162
1163 if (IsBigEndian) {
1164 Insn = (Bytes[0] << 8) | Bytes[1];
1165 } else {
1166 Insn = (Bytes[1] << 8) | Bytes[0];
1167 }
1168
1169 return MCDisassembler::Success;
1170}
1171
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001172/// Read four bytes from the ArrayRef and return 32 bit word sorted
Simon Pilgrimdcd84332016-11-18 11:53:36 +00001173/// according to the given endianness.
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001174static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
1175 uint64_t &Size, uint32_t &Insn,
1176 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001177 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001178 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001179 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001180 return MCDisassembler::Fail;
1181 }
1182
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001183 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1184 // always precede the low 16 bits in the instruction stream (that is, they
1185 // are placed at lower addresses in the instruction stream).
1186 //
1187 // microMIPS byte ordering:
1188 // Big-endian: 0 | 1 | 2 | 3
1189 // Little-endian: 1 | 0 | 3 | 2
1190
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001191 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001192 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001193 Insn =
1194 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
1195 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +00001196 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001197 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +00001198 (Bytes[1] << 24);
1199 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001200 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +00001201 (Bytes[3] << 24);
1202 }
Akira Hatanaka71928e62012-04-17 18:03:21 +00001203 }
1204
1205 return MCDisassembler::Success;
1206}
1207
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001208DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001209 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001210 uint64_t Address,
1211 raw_ostream &VStream,
1212 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001213 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001214 DecodeStatus Result;
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001215 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001216
Vladimir Medicdde3d582013-09-06 12:30:36 +00001217 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001218 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
Reid Klecknerebee6122015-11-19 21:51:55 +00001219 if (Result == MCDisassembler::Fail)
1220 return MCDisassembler::Fail;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001221
Zoran Jovanovicada70912015-09-07 11:56:37 +00001222 if (hasMips32r6()) {
1223 DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1224 // Calling the auto-generated decoder function for microMIPS32R6
Aleksandar Beserminjid6dada12017-12-11 11:21:40 +00001225 // 16-bit instructions.
Zoran Jovanovicada70912015-09-07 11:56:37 +00001226 Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1227 Address, this, STI);
1228 if (Result != MCDisassembler::Fail) {
1229 Size = 2;
1230 return Result;
1231 }
1232 }
1233
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001234 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
Zoran Jovanovicada70912015-09-07 11:56:37 +00001235 // Calling the auto-generated decoder function for microMIPS 16-bit
1236 // instructions.
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001237 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1238 this, STI);
1239 if (Result != MCDisassembler::Fail) {
1240 Size = 2;
1241 return Result;
1242 }
1243
1244 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
1245 if (Result == MCDisassembler::Fail)
1246 return MCDisassembler::Fail;
1247
Jozef Kolek676d6012015-04-20 14:40:38 +00001248 if (hasMips32r6()) {
1249 DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1250 // Calling the auto-generated decoder function.
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001251 Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
Jozef Kolek676d6012015-04-20 14:40:38 +00001252 this, STI);
Zoran Jovanovicada70912015-09-07 11:56:37 +00001253 if (Result != MCDisassembler::Fail) {
1254 Size = 4;
1255 return Result;
1256 }
Jozef Kolek676d6012015-04-20 14:40:38 +00001257 }
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001258
Zoran Jovanovicada70912015-09-07 11:56:37 +00001259 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1260 // Calling the auto-generated decoder function.
1261 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1262 this, STI);
Vladimir Medicdde3d582013-09-06 12:30:36 +00001263 if (Result != MCDisassembler::Fail) {
1264 Size = 4;
1265 return Result;
1266 }
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001267
Simon Dardis51a7ae22017-10-05 10:27:37 +00001268 if (isFP64()) {
1269 DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
1270 Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001271 Address, this, STI);
1272 if (Result != MCDisassembler::Fail) {
1273 Size = 4;
1274 return Result;
1275 }
1276 }
1277
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001278 // This is an invalid instruction. Claim that the Size is 2 bytes. Since
1279 // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
1280 // could form a valid instruction. The two bytes we rejected as an
1281 // instruction could have actually beeen an inline constant pool that is
1282 // unconditionally branched over.
Reid Klecknerebee6122015-11-19 21:51:55 +00001283 Size = 2;
Vladimir Medicdde3d582013-09-06 12:30:36 +00001284 return MCDisassembler::Fail;
1285 }
1286
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001287 // Attempt to read the instruction so that we can attempt to decode it. If
1288 // the buffer is not 4 bytes long, let the higher level logic figure out
1289 // what to do with a size of zero and MCDisassembler::Fail.
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001290 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001291 if (Result == MCDisassembler::Fail)
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001292 return MCDisassembler::Fail;
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001293
1294 // The only instruction size for standard encoded MIPS.
1295 Size = 4;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001296
Daniel Sandersc171f652014-06-13 13:15:59 +00001297 if (hasCOP3()) {
1298 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1299 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001300 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001301 if (Result != MCDisassembler::Fail)
Daniel Sandersc171f652014-06-13 13:15:59 +00001302 return Result;
Daniel Sandersc171f652014-06-13 13:15:59 +00001303 }
1304
1305 if (hasMips32r6() && isGP64()) {
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001306 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
1307 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
1308 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001309 if (Result != MCDisassembler::Fail)
Daniel Sanders0fa60412014-06-12 13:39:06 +00001310 return Result;
Daniel Sanders0fa60412014-06-12 13:39:06 +00001311 }
1312
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001313 if (hasMips32r6() && isPTR64()) {
1314 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1315 Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
1316 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001317 if (Result != MCDisassembler::Fail)
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001318 return Result;
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001319 }
1320
Daniel Sandersc171f652014-06-13 13:15:59 +00001321 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001322 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001323 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +00001324 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001325 if (Result != MCDisassembler::Fail)
Daniel Sanders5c582b22014-05-22 11:23:21 +00001326 return Result;
Daniel Sanders5c582b22014-05-22 11:23:21 +00001327 }
1328
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001329 if (hasMips2() && isPTR64()) {
1330 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1331 Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
1332 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001333 if (Result != MCDisassembler::Fail)
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001334 return Result;
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001335 }
1336
Kai Nacke3adf9b82015-05-28 16:23:16 +00001337 if (hasCnMips()) {
1338 DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
1339 Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
1340 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001341 if (Result != MCDisassembler::Fail)
Kai Nacke3adf9b82015-05-28 16:23:16 +00001342 return Result;
Kai Nacke3adf9b82015-05-28 16:23:16 +00001343 }
1344
Daniel Sandersa19216c2015-02-11 11:28:56 +00001345 if (isGP64()) {
1346 DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1347 Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1348 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001349 if (Result != MCDisassembler::Fail)
Daniel Sandersa19216c2015-02-11 11:28:56 +00001350 return Result;
Daniel Sandersa19216c2015-02-11 11:28:56 +00001351 }
1352
Simon Dardis51a7ae22017-10-05 10:27:37 +00001353 if (isFP64()) {
1354 DEBUG(dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
1355 Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
1356 Address, this, STI);
1357 if (Result != MCDisassembler::Fail)
1358 return Result;
1359 }
1360
Daniel Sanders0fa60412014-06-12 13:39:06 +00001361 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +00001362 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001363 Result =
1364 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001365 if (Result != MCDisassembler::Fail)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001366 return Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001367
1368 return MCDisassembler::Fail;
1369}
1370
Reed Kotlerec8a5492013-02-14 03:05:25 +00001371static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1372 unsigned RegNo,
1373 uint64_t Address,
1374 const void *Decoder) {
Reed Kotlerec8a5492013-02-14 03:05:25 +00001375 return MCDisassembler::Fail;
Reed Kotlerec8a5492013-02-14 03:05:25 +00001376}
1377
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001378static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1379 unsigned RegNo,
1380 uint64_t Address,
1381 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001382 if (RegNo > 31)
1383 return MCDisassembler::Fail;
1384
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001385 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001386 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001387 return MCDisassembler::Success;
1388}
1389
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001390static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1391 unsigned RegNo,
1392 uint64_t Address,
1393 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001394 if (RegNo > 7)
1395 return MCDisassembler::Fail;
1396 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001397 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001398 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001399}
1400
Jozef Kolek1904fa22014-11-24 14:25:53 +00001401static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1402 unsigned RegNo,
1403 uint64_t Address,
1404 const void *Decoder) {
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001405 if (RegNo > 7)
1406 return MCDisassembler::Fail;
1407 unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001408 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001409 return MCDisassembler::Success;
Jozef Kolek1904fa22014-11-24 14:25:53 +00001410}
1411
Zoran Jovanovic41688672015-02-10 16:36:20 +00001412static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1413 unsigned RegNo,
1414 uint64_t Address,
1415 const void *Decoder) {
1416 if (RegNo > 7)
1417 return MCDisassembler::Fail;
1418 unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001419 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic41688672015-02-10 16:36:20 +00001420 return MCDisassembler::Success;
1421}
1422
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001423static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1424 unsigned RegNo,
1425 uint64_t Address,
1426 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001427 if (RegNo > 31)
1428 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001429 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001430 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001431 return MCDisassembler::Success;
1432}
1433
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001434static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1435 unsigned RegNo,
1436 uint64_t Address,
1437 const void *Decoder) {
Daniel Sandersa19216c2015-02-11 11:28:56 +00001438 if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001439 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1440
1441 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1442}
1443
Akira Hatanaka654655f2013-08-14 00:53:38 +00001444static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1445 unsigned RegNo,
1446 uint64_t Address,
1447 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001448 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001449}
1450
Akira Hatanaka71928e62012-04-17 18:03:21 +00001451static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1452 unsigned RegNo,
1453 uint64_t Address,
1454 const void *Decoder) {
1455 if (RegNo > 31)
1456 return MCDisassembler::Fail;
1457
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001458 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001459 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001460 return MCDisassembler::Success;
1461}
1462
1463static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1464 unsigned RegNo,
1465 uint64_t Address,
1466 const void *Decoder) {
1467 if (RegNo > 31)
1468 return MCDisassembler::Fail;
1469
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001470 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001471 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001472 return MCDisassembler::Success;
1473}
1474
1475static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1476 unsigned RegNo,
1477 uint64_t Address,
1478 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +00001479 if (RegNo > 31)
1480 return MCDisassembler::Fail;
1481 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001482 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001483 return MCDisassembler::Success;
1484}
1485
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001486static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1487 unsigned RegNo,
1488 uint64_t Address,
1489 const void *Decoder) {
1490 if (RegNo > 7)
1491 return MCDisassembler::Fail;
1492 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001493 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001494 return MCDisassembler::Success;
1495}
1496
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001497static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1498 uint64_t Address,
1499 const void *Decoder) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001500 if (RegNo > 31)
1501 return MCDisassembler::Fail;
1502
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001503 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001504 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders0fa60412014-06-12 13:39:06 +00001505 return MCDisassembler::Success;
1506}
1507
Akira Hatanaka71928e62012-04-17 18:03:21 +00001508static DecodeStatus DecodeMem(MCInst &Inst,
1509 unsigned Insn,
1510 uint64_t Address,
1511 const void *Decoder) {
1512 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001513 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1514 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001515
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001516 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1517 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001518
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001519 if (Inst.getOpcode() == Mips::SC ||
1520 Inst.getOpcode() == Mips::SCD)
Jim Grosbache9119e42015-05-13 18:37:00 +00001521 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001522
1523 Inst.addOperand(MCOperand::createReg(Reg));
1524 Inst.addOperand(MCOperand::createReg(Base));
1525 Inst.addOperand(MCOperand::createImm(Offset));
1526
1527 return MCDisassembler::Success;
1528}
1529
1530static DecodeStatus DecodeMemEVA(MCInst &Inst,
1531 unsigned Insn,
1532 uint64_t Address,
1533 const void *Decoder) {
1534 int Offset = SignExtend32<9>(Insn >> 7);
1535 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1536 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1537
1538 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1539 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1540
1541 if (Inst.getOpcode() == Mips::SCE)
1542 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001543
Jim Grosbache9119e42015-05-13 18:37:00 +00001544 Inst.addOperand(MCOperand::createReg(Reg));
1545 Inst.addOperand(MCOperand::createReg(Base));
1546 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001547
1548 return MCDisassembler::Success;
1549}
1550
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +00001551static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1552 unsigned Insn,
1553 uint64_t Address,
1554 const void *Decoder) {
1555 int Offset = SignExtend32<16>(Insn & 0xffff);
1556 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1557 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1558
1559 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1560 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1561
1562 Inst.addOperand(MCOperand::createReg(Reg));
1563 Inst.addOperand(MCOperand::createReg(Base));
1564 Inst.addOperand(MCOperand::createImm(Offset));
1565
1566 return MCDisassembler::Success;
1567}
1568
Daniel Sanders92db6b72014-10-01 08:26:55 +00001569static DecodeStatus DecodeCacheOp(MCInst &Inst,
1570 unsigned Insn,
1571 uint64_t Address,
1572 const void *Decoder) {
1573 int Offset = SignExtend32<16>(Insn & 0xffff);
1574 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1575 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1576
1577 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1578
Jim Grosbache9119e42015-05-13 18:37:00 +00001579 Inst.addOperand(MCOperand::createReg(Base));
1580 Inst.addOperand(MCOperand::createImm(Offset));
1581 Inst.addOperand(MCOperand::createImm(Hint));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001582
1583 return MCDisassembler::Success;
1584}
1585
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001586static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1587 unsigned Insn,
1588 uint64_t Address,
1589 const void *Decoder) {
1590 int Offset = SignExtend32<12>(Insn & 0xfff);
1591 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1592 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1593
1594 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1595
Jim Grosbache9119e42015-05-13 18:37:00 +00001596 Inst.addOperand(MCOperand::createReg(Base));
1597 Inst.addOperand(MCOperand::createImm(Offset));
1598 Inst.addOperand(MCOperand::createImm(Hint));
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001599
1600 return MCDisassembler::Success;
1601}
1602
Zoran Jovanovicd9790792015-09-09 09:10:46 +00001603static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1604 unsigned Insn,
1605 uint64_t Address,
1606 const void *Decoder) {
1607 int Offset = SignExtend32<9>(Insn & 0x1ff);
1608 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1609 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1610
1611 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1612
1613 Inst.addOperand(MCOperand::createReg(Base));
1614 Inst.addOperand(MCOperand::createImm(Offset));
1615 Inst.addOperand(MCOperand::createImm(Hint));
1616
1617 return MCDisassembler::Success;
1618}
1619
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001620static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1621 unsigned Insn,
1622 uint64_t Address,
1623 const void *Decoder) {
1624 int Offset = SignExtend32<9>(Insn >> 7);
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001625 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1626 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1627
1628 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1629
Jim Grosbache9119e42015-05-13 18:37:00 +00001630 Inst.addOperand(MCOperand::createReg(Base));
1631 Inst.addOperand(MCOperand::createImm(Offset));
1632 Inst.addOperand(MCOperand::createImm(Hint));
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001633
1634 return MCDisassembler::Success;
1635}
1636
Daniel Sandersb4484d62014-11-27 17:28:10 +00001637static DecodeStatus DecodeSyncI(MCInst &Inst,
1638 unsigned Insn,
1639 uint64_t Address,
1640 const void *Decoder) {
1641 int Offset = SignExtend32<16>(Insn & 0xffff);
1642 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1643
1644 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1645
Jim Grosbache9119e42015-05-13 18:37:00 +00001646 Inst.addOperand(MCOperand::createReg(Base));
1647 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sandersb4484d62014-11-27 17:28:10 +00001648
1649 return MCDisassembler::Success;
1650}
1651
Hrvoje Varga18148672015-10-28 11:04:29 +00001652static DecodeStatus DecodeSynciR6(MCInst &Inst,
1653 unsigned Insn,
1654 uint64_t Address,
1655 const void *Decoder) {
1656 int Immediate = SignExtend32<16>(Insn & 0xffff);
1657 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1658
1659 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1660
1661 Inst.addOperand(MCOperand::createReg(Base));
1662 Inst.addOperand(MCOperand::createImm(Immediate));
1663
1664 return MCDisassembler::Success;
1665}
1666
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001667static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1668 uint64_t Address, const void *Decoder) {
1669 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1670 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1671 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1672
1673 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1674 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1675
Jim Grosbache9119e42015-05-13 18:37:00 +00001676 Inst.addOperand(MCOperand::createReg(Reg));
1677 Inst.addOperand(MCOperand::createReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001678
1679 // The immediate field of an LD/ST instruction is scaled which means it must
1680 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1681 // data format.
1682 // .b - 1 byte
1683 // .h - 2 bytes
1684 // .w - 4 bytes
1685 // .d - 8 bytes
1686 switch(Inst.getOpcode())
1687 {
1688 default:
Eugene Zelenko926883e2017-02-01 01:22:51 +00001689 assert(false && "Unexpected instruction");
Matheus Almeida6b59c442013-12-05 11:06:22 +00001690 return MCDisassembler::Fail;
1691 break;
1692 case Mips::LD_B:
1693 case Mips::ST_B:
Jim Grosbache9119e42015-05-13 18:37:00 +00001694 Inst.addOperand(MCOperand::createImm(Offset));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001695 break;
1696 case Mips::LD_H:
1697 case Mips::ST_H:
Jim Grosbache9119e42015-05-13 18:37:00 +00001698 Inst.addOperand(MCOperand::createImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001699 break;
1700 case Mips::LD_W:
1701 case Mips::ST_W:
Jim Grosbache9119e42015-05-13 18:37:00 +00001702 Inst.addOperand(MCOperand::createImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001703 break;
1704 case Mips::LD_D:
1705 case Mips::ST_D:
Jim Grosbache9119e42015-05-13 18:37:00 +00001706 Inst.addOperand(MCOperand::createImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001707 break;
1708 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001709
1710 return MCDisassembler::Success;
1711}
1712
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001713static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1714 unsigned Insn,
1715 uint64_t Address,
1716 const void *Decoder) {
1717 unsigned Offset = Insn & 0xf;
1718 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1719 unsigned Base = fieldFromInstruction(Insn, 4, 3);
1720
1721 switch (Inst.getOpcode()) {
1722 case Mips::LBU16_MM:
1723 case Mips::LHU16_MM:
1724 case Mips::LW16_MM:
1725 if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1726 == MCDisassembler::Fail)
1727 return MCDisassembler::Fail;
1728 break;
1729 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001730 case Mips::SB16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001731 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001732 case Mips::SH16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001733 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001734 case Mips::SW16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001735 if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1736 == MCDisassembler::Fail)
1737 return MCDisassembler::Fail;
1738 break;
1739 }
1740
1741 if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1742 == MCDisassembler::Fail)
1743 return MCDisassembler::Fail;
1744
1745 switch (Inst.getOpcode()) {
1746 case Mips::LBU16_MM:
1747 if (Offset == 0xf)
Jim Grosbache9119e42015-05-13 18:37:00 +00001748 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001749 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001750 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001751 break;
1752 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001753 case Mips::SB16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001754 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001755 break;
1756 case Mips::LHU16_MM:
1757 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001758 case Mips::SH16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001759 Inst.addOperand(MCOperand::createImm(Offset << 1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001760 break;
1761 case Mips::LW16_MM:
1762 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001763 case Mips::SW16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001764 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001765 break;
1766 }
1767
1768 return MCDisassembler::Success;
1769}
1770
Jozef Kolek12c69822014-12-23 16:16:33 +00001771static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1772 unsigned Insn,
1773 uint64_t Address,
1774 const void *Decoder) {
1775 unsigned Offset = Insn & 0x1F;
1776 unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1777
1778 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1779
Jim Grosbache9119e42015-05-13 18:37:00 +00001780 Inst.addOperand(MCOperand::createReg(Reg));
1781 Inst.addOperand(MCOperand::createReg(Mips::SP));
1782 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek12c69822014-12-23 16:16:33 +00001783
1784 return MCDisassembler::Success;
1785}
1786
Jozef Koleke10a02e2015-01-28 17:27:26 +00001787static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1788 unsigned Insn,
1789 uint64_t Address,
1790 const void *Decoder) {
1791 unsigned Offset = Insn & 0x7F;
1792 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1793
1794 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1795
Jim Grosbache9119e42015-05-13 18:37:00 +00001796 Inst.addOperand(MCOperand::createReg(Reg));
1797 Inst.addOperand(MCOperand::createReg(Mips::GP));
1798 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Koleke10a02e2015-01-28 17:27:26 +00001799
1800 return MCDisassembler::Success;
1801}
1802
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001803static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1804 unsigned Insn,
1805 uint64_t Address,
1806 const void *Decoder) {
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001807 int Offset;
1808 switch (Inst.getOpcode()) {
1809 case Mips::LWM16_MMR6:
1810 case Mips::SWM16_MMR6:
1811 Offset = fieldFromInstruction(Insn, 4, 4);
1812 break;
1813 default:
1814 Offset = SignExtend32<4>(Insn & 0xf);
1815 break;
1816 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001817
1818 if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1819 == MCDisassembler::Fail)
1820 return MCDisassembler::Fail;
1821
Jim Grosbache9119e42015-05-13 18:37:00 +00001822 Inst.addOperand(MCOperand::createReg(Mips::SP));
1823 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001824
1825 return MCDisassembler::Success;
1826}
1827
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001828static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1829 unsigned Insn,
1830 uint64_t Address,
1831 const void *Decoder) {
1832 int Offset = SignExtend32<9>(Insn & 0x1ff);
1833 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1834 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1835
1836 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1837 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1838
Hrvoje Varga3ef4dd72015-10-15 08:11:50 +00001839 if (Inst.getOpcode() == Mips::SCE_MM)
1840 Inst.addOperand(MCOperand::createReg(Reg));
1841
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001842 Inst.addOperand(MCOperand::createReg(Reg));
1843 Inst.addOperand(MCOperand::createReg(Base));
1844 Inst.addOperand(MCOperand::createImm(Offset));
1845
1846 return MCDisassembler::Success;
1847}
1848
Vladimir Medicdde3d582013-09-06 12:30:36 +00001849static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1850 unsigned Insn,
1851 uint64_t Address,
1852 const void *Decoder) {
1853 int Offset = SignExtend32<12>(Insn & 0x0fff);
1854 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1855 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1856
1857 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1858 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1859
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001860 switch (Inst.getOpcode()) {
1861 case Mips::SWM32_MM:
1862 case Mips::LWM32_MM:
1863 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1864 == MCDisassembler::Fail)
1865 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001866 Inst.addOperand(MCOperand::createReg(Base));
1867 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001868 break;
1869 case Mips::SC_MM:
Jim Grosbache9119e42015-05-13 18:37:00 +00001870 Inst.addOperand(MCOperand::createReg(Reg));
Justin Bognerb03fd122016-08-17 05:10:15 +00001871 LLVM_FALLTHROUGH;
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001872 default:
Jim Grosbache9119e42015-05-13 18:37:00 +00001873 Inst.addOperand(MCOperand::createReg(Reg));
Zlatko Buljanba553a62016-05-09 08:07:28 +00001874 if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1875 Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
Jim Grosbache9119e42015-05-13 18:37:00 +00001876 Inst.addOperand(MCOperand::createReg(Reg+1));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001877
Jim Grosbache9119e42015-05-13 18:37:00 +00001878 Inst.addOperand(MCOperand::createReg(Base));
1879 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001880 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001881
1882 return MCDisassembler::Success;
1883}
1884
1885static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1886 unsigned Insn,
1887 uint64_t Address,
1888 const void *Decoder) {
1889 int Offset = SignExtend32<16>(Insn & 0xffff);
1890 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1891 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1892
1893 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1894 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1895
Jim Grosbache9119e42015-05-13 18:37:00 +00001896 Inst.addOperand(MCOperand::createReg(Reg));
1897 Inst.addOperand(MCOperand::createReg(Base));
1898 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medicdde3d582013-09-06 12:30:36 +00001899
1900 return MCDisassembler::Success;
1901}
1902
Akira Hatanaka71928e62012-04-17 18:03:21 +00001903static DecodeStatus DecodeFMem(MCInst &Inst,
1904 unsigned Insn,
1905 uint64_t Address,
1906 const void *Decoder) {
1907 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001908 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1909 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001910
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001911 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001912 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001913
Jim Grosbache9119e42015-05-13 18:37:00 +00001914 Inst.addOperand(MCOperand::createReg(Reg));
1915 Inst.addOperand(MCOperand::createReg(Base));
1916 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001917
1918 return MCDisassembler::Success;
1919}
1920
Zlatko Buljancba9f802016-07-11 07:41:56 +00001921static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1922 uint64_t Address, const void *Decoder) {
1923 // This function is the same as DecodeFMem but with the Reg and Base fields
1924 // swapped according to microMIPS spec.
1925 int Offset = SignExtend32<16>(Insn & 0xffff);
1926 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1927 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1928
1929 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1930 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1931
1932 Inst.addOperand(MCOperand::createReg(Reg));
1933 Inst.addOperand(MCOperand::createReg(Base));
1934 Inst.addOperand(MCOperand::createImm(Offset));
1935
1936 return MCDisassembler::Success;
1937}
1938
Daniel Sanders92db6b72014-10-01 08:26:55 +00001939static DecodeStatus DecodeFMem2(MCInst &Inst,
1940 unsigned Insn,
1941 uint64_t Address,
1942 const void *Decoder) {
1943 int Offset = SignExtend32<16>(Insn & 0xffff);
1944 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1945 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1946
1947 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1948 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1949
Jim Grosbache9119e42015-05-13 18:37:00 +00001950 Inst.addOperand(MCOperand::createReg(Reg));
1951 Inst.addOperand(MCOperand::createReg(Base));
1952 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001953
1954 return MCDisassembler::Success;
1955}
1956
1957static DecodeStatus DecodeFMem3(MCInst &Inst,
1958 unsigned Insn,
1959 uint64_t Address,
1960 const void *Decoder) {
1961 int Offset = SignExtend32<16>(Insn & 0xffff);
1962 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1963 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1964
1965 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1966 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1967
Jim Grosbache9119e42015-05-13 18:37:00 +00001968 Inst.addOperand(MCOperand::createReg(Reg));
1969 Inst.addOperand(MCOperand::createReg(Base));
1970 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001971
1972 return MCDisassembler::Success;
1973}
1974
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001975static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1976 unsigned Insn,
1977 uint64_t Address,
1978 const void *Decoder) {
1979 int Offset = SignExtend32<11>(Insn & 0x07ff);
1980 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1981 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1982
1983 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1984 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1985
Jim Grosbache9119e42015-05-13 18:37:00 +00001986 Inst.addOperand(MCOperand::createReg(Reg));
1987 Inst.addOperand(MCOperand::createReg(Base));
1988 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001989
1990 return MCDisassembler::Success;
1991}
Zlatko Buljancba9f802016-07-11 07:41:56 +00001992
1993static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1994 uint64_t Address, const void *Decoder) {
1995 int Offset = SignExtend32<11>(Insn & 0x07ff);
1996 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1997 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1998
1999 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
2000 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
2001
2002 Inst.addOperand(MCOperand::createReg(Reg));
2003 Inst.addOperand(MCOperand::createReg(Base));
2004 Inst.addOperand(MCOperand::createImm(Offset));
2005
2006 return MCDisassembler::Success;
2007}
2008
Daniel Sanders6a803f62014-06-16 13:13:03 +00002009static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
2010 unsigned Insn,
2011 uint64_t Address,
2012 const void *Decoder) {
2013 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
2014 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
2015 unsigned Base = fieldFromInstruction(Insn, 21, 5);
2016
2017 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
2018 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
2019
2020 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
Jim Grosbache9119e42015-05-13 18:37:00 +00002021 Inst.addOperand(MCOperand::createReg(Rt));
Daniel Sanders6a803f62014-06-16 13:13:03 +00002022 }
2023
Jim Grosbache9119e42015-05-13 18:37:00 +00002024 Inst.addOperand(MCOperand::createReg(Rt));
2025 Inst.addOperand(MCOperand::createReg(Base));
2026 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders6a803f62014-06-16 13:13:03 +00002027
2028 return MCDisassembler::Success;
2029}
Akira Hatanaka71928e62012-04-17 18:03:21 +00002030
2031static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
2032 unsigned RegNo,
2033 uint64_t Address,
2034 const void *Decoder) {
2035 // Currently only hardware register 29 is supported.
2036 if (RegNo != 29)
2037 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00002038 Inst.addOperand(MCOperand::createReg(Mips::HWR29));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002039 return MCDisassembler::Success;
2040}
2041
Akira Hatanaka71928e62012-04-17 18:03:21 +00002042static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
2043 unsigned RegNo,
2044 uint64_t Address,
2045 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00002046 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00002047 return MCDisassembler::Fail;
2048
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00002049 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
Jim Grosbache9119e42015-05-13 18:37:00 +00002050 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002051 return MCDisassembler::Success;
2052}
2053
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00002054static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
2055 unsigned RegNo,
2056 uint64_t Address,
2057 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00002058 if (RegNo >= 4)
2059 return MCDisassembler::Fail;
2060
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00002061 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002062 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00002063 return MCDisassembler::Success;
2064}
2065
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002066static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
2067 unsigned RegNo,
2068 uint64_t Address,
2069 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002070 if (RegNo >= 4)
2071 return MCDisassembler::Fail;
2072
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002073 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002074 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002075 return MCDisassembler::Success;
2076}
2077
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002078static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
2079 unsigned RegNo,
2080 uint64_t Address,
2081 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002082 if (RegNo >= 4)
2083 return MCDisassembler::Fail;
2084
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002085 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002086 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002087 return MCDisassembler::Success;
2088}
2089
Jack Carter3eb663b2013-09-26 00:09:46 +00002090static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
2091 unsigned RegNo,
2092 uint64_t Address,
2093 const void *Decoder) {
2094 if (RegNo > 31)
2095 return MCDisassembler::Fail;
2096
2097 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002098 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter3eb663b2013-09-26 00:09:46 +00002099 return MCDisassembler::Success;
2100}
2101
Jack Carter5dc8ac92013-09-25 23:50:44 +00002102static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
2103 unsigned RegNo,
2104 uint64_t Address,
2105 const void *Decoder) {
2106 if (RegNo > 31)
2107 return MCDisassembler::Fail;
2108
2109 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002110 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002111 return MCDisassembler::Success;
2112}
2113
2114static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
2115 unsigned RegNo,
2116 uint64_t Address,
2117 const void *Decoder) {
2118 if (RegNo > 31)
2119 return MCDisassembler::Fail;
2120
2121 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002122 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002123 return MCDisassembler::Success;
2124}
2125
2126static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
2127 unsigned RegNo,
2128 uint64_t Address,
2129 const void *Decoder) {
2130 if (RegNo > 31)
2131 return MCDisassembler::Fail;
2132
2133 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002134 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002135 return MCDisassembler::Success;
2136}
2137
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002138static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
2139 unsigned RegNo,
2140 uint64_t Address,
2141 const void *Decoder) {
2142 if (RegNo > 7)
2143 return MCDisassembler::Fail;
2144
2145 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002146 Inst.addOperand(MCOperand::createReg(Reg));
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002147 return MCDisassembler::Success;
2148}
2149
Daniel Sandersa3134fa2015-06-27 15:39:19 +00002150static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
2151 unsigned RegNo,
2152 uint64_t Address,
2153 const void *Decoder) {
2154 if (RegNo > 31)
2155 return MCDisassembler::Fail;
2156
2157 unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
2158 Inst.addOperand(MCOperand::createReg(Reg));
2159 return MCDisassembler::Success;
2160}
2161
Daniel Sanders2a83d682014-05-21 12:56:39 +00002162static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
2163 unsigned RegNo,
2164 uint64_t Address,
2165 const void *Decoder) {
2166 if (RegNo > 31)
2167 return MCDisassembler::Fail;
2168
2169 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002170 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders2a83d682014-05-21 12:56:39 +00002171 return MCDisassembler::Success;
2172}
2173
Akira Hatanaka71928e62012-04-17 18:03:21 +00002174static DecodeStatus DecodeBranchTarget(MCInst &Inst,
2175 unsigned Offset,
2176 uint64_t Address,
2177 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00002178 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00002179 Inst.addOperand(MCOperand::createImm(BranchOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002180 return MCDisassembler::Success;
2181}
2182
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +00002183static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
2184 unsigned Offset,
2185 uint64_t Address,
2186 const void *Decoder) {
2187 int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
2188 Inst.addOperand(MCOperand::createImm(BranchOffset));
2189 return MCDisassembler::Success;
2190}
2191
Akira Hatanaka71928e62012-04-17 18:03:21 +00002192static DecodeStatus DecodeJumpTarget(MCInst &Inst,
2193 unsigned Insn,
2194 uint64_t Address,
2195 const void *Decoder) {
Jim Grosbachecaef492012-08-14 19:06:05 +00002196 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00002197 Inst.addOperand(MCOperand::createImm(JumpOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002198 return MCDisassembler::Success;
2199}
2200
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002201static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2202 unsigned Offset,
2203 uint64_t Address,
2204 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00002205 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002206
Jim Grosbache9119e42015-05-13 18:37:00 +00002207 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002208 return MCDisassembler::Success;
2209}
2210
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00002211static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
2212 unsigned Offset,
2213 uint64_t Address,
2214 const void *Decoder) {
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002215 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00002216
2217 Inst.addOperand(MCOperand::createImm(BranchOffset));
2218 return MCDisassembler::Success;
2219}
2220
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002221static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
2222 unsigned Offset,
2223 uint64_t Address,
2224 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00002225 int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002226
Jim Grosbache9119e42015-05-13 18:37:00 +00002227 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002228 return MCDisassembler::Success;
2229}
2230
Jozef Kolek9761e962015-01-12 12:03:34 +00002231static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2232 unsigned Offset,
2233 uint64_t Address,
2234 const void *Decoder) {
Simon Atanasyan72982e692017-09-20 21:01:30 +00002235 int32_t BranchOffset = SignExtend32<8>(Offset << 1);
Jim Grosbache9119e42015-05-13 18:37:00 +00002236 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek9761e962015-01-12 12:03:34 +00002237 return MCDisassembler::Success;
2238}
2239
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002240static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2241 unsigned Offset,
2242 uint64_t Address,
2243 const void *Decoder) {
Simon Atanasyan72982e692017-09-20 21:01:30 +00002244 int32_t BranchOffset = SignExtend32<11>(Offset << 1);
Jim Grosbache9119e42015-05-13 18:37:00 +00002245 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002246 return MCDisassembler::Success;
2247}
2248
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002249static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2250 unsigned Offset,
2251 uint64_t Address,
2252 const void *Decoder) {
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002253 int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00002254 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002255 return MCDisassembler::Success;
2256}
2257
Zoran Jovanovica887b362015-11-30 12:56:18 +00002258static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2259 unsigned Offset,
2260 uint64_t Address,
2261 const void *Decoder) {
Simon Atanasyan72982e692017-09-20 21:01:30 +00002262 int32_t BranchOffset = SignExtend32<27>(Offset << 1);
Zoran Jovanovica887b362015-11-30 12:56:18 +00002263
2264 Inst.addOperand(MCOperand::createImm(BranchOffset));
2265 return MCDisassembler::Success;
2266}
2267
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002268static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2269 unsigned Insn,
2270 uint64_t Address,
2271 const void *Decoder) {
2272 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002273 Inst.addOperand(MCOperand::createImm(JumpOffset));
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002274 return MCDisassembler::Success;
2275}
Akira Hatanaka71928e62012-04-17 18:03:21 +00002276
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002277static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2278 unsigned Value,
2279 uint64_t Address,
2280 const void *Decoder) {
2281 if (Value == 0)
Jim Grosbache9119e42015-05-13 18:37:00 +00002282 Inst.addOperand(MCOperand::createImm(1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002283 else if (Value == 0x7)
Jim Grosbache9119e42015-05-13 18:37:00 +00002284 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002285 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002286 Inst.addOperand(MCOperand::createImm(Value << 2));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002287 return MCDisassembler::Success;
2288}
2289
Daniel Sanders97297772016-03-22 14:40:00 +00002290static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002291 unsigned Value,
2292 uint64_t Address,
2293 const void *Decoder) {
2294 if (Value == 0x7F)
Jim Grosbache9119e42015-05-13 18:37:00 +00002295 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002296 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002297 Inst.addOperand(MCOperand::createImm(Value));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002298 return MCDisassembler::Success;
2299}
2300
Zoran Jovanovic6b28f092015-09-09 13:55:45 +00002301static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
2302 unsigned Value,
2303 uint64_t Address,
2304 const void *Decoder) {
2305 Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
2306 return MCDisassembler::Success;
2307}
2308
Daniel Sanders19b7f762016-03-14 11:16:56 +00002309template <unsigned Bits, int Offset, int Scale>
2310static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2311 uint64_t Address,
2312 const void *Decoder) {
Daniel Sandersea4f6532015-11-06 12:22:31 +00002313 Value &= ((1 << Bits) - 1);
Daniel Sanders19b7f762016-03-14 11:16:56 +00002314 Value *= Scale;
Daniel Sandersea4f6532015-11-06 12:22:31 +00002315 Inst.addOperand(MCOperand::createImm(Value + Offset));
Matheus Almeida779c5932013-11-18 12:32:49 +00002316 return MCDisassembler::Success;
2317}
2318
Daniel Sanders97297772016-03-22 14:40:00 +00002319template <unsigned Bits, int Offset, int ScaleBy>
2320static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2321 uint64_t Address,
2322 const void *Decoder) {
2323 int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
Daniel Sanders78e89022016-03-11 11:37:50 +00002324 Inst.addOperand(MCOperand::createImm(Imm + Offset));
2325 return MCDisassembler::Success;
2326}
2327
Akira Hatanaka71928e62012-04-17 18:03:21 +00002328static DecodeStatus DecodeInsSize(MCInst &Inst,
2329 unsigned Insn,
2330 uint64_t Address,
2331 const void *Decoder) {
2332 // First we need to grab the pos(lsb) from MCInst.
Simon Dardis6f83ae32017-09-14 15:17:50 +00002333 // This function only handles the 32 bit variants of ins, as dins
2334 // variants are handled differently.
Akira Hatanaka71928e62012-04-17 18:03:21 +00002335 int Pos = Inst.getOperand(2).getImm();
Simon Dardis6f83ae32017-09-14 15:17:50 +00002336 int Size = (int) Insn - Pos + 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002337 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002338 return MCDisassembler::Success;
2339}
2340
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002341static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2342 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002343 Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002344 return MCDisassembler::Success;
2345}
Zoran Jovanovic28551422014-06-09 09:49:51 +00002346
2347static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2348 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002349 Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00002350 return MCDisassembler::Success;
2351}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002352
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002353static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2354 uint64_t Address, const void *Decoder) {
2355 int32_t DecodedValue;
2356 switch (Insn) {
2357 case 0: DecodedValue = 256; break;
2358 case 1: DecodedValue = 257; break;
2359 case 510: DecodedValue = -258; break;
2360 case 511: DecodedValue = -257; break;
2361 default: DecodedValue = SignExtend32<9>(Insn); break;
2362 }
Jim Grosbache9119e42015-05-13 18:37:00 +00002363 Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002364 return MCDisassembler::Success;
2365}
2366
2367static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2368 uint64_t Address, const void *Decoder) {
2369 // Insn must be >= 0, since it is unsigned that condition is always true.
2370 assert(Insn < 16);
2371 int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2372 255, 32768, 65535};
Jim Grosbache9119e42015-05-13 18:37:00 +00002373 Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002374 return MCDisassembler::Success;
2375}
2376
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002377static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2378 unsigned Insn,
2379 uint64_t Address,
2380 const void *Decoder) {
2381 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
Zoran Jovanovicdc4b8c22015-09-15 15:21:27 +00002382 Mips::S6, Mips::S7, Mips::FP};
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002383 unsigned RegNum;
2384
2385 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002386
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002387 // Empty register lists are not allowed.
2388 if (RegLst == 0)
2389 return MCDisassembler::Fail;
2390
2391 RegNum = RegLst & 0xf;
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002392
2393 // RegLst values 10-15, and 26-31 are reserved.
2394 if (RegNum > 9)
2395 return MCDisassembler::Fail;
2396
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002397 for (unsigned i = 0; i < RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002398 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002399
2400 if (RegLst & 0x10)
Jim Grosbache9119e42015-05-13 18:37:00 +00002401 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002402
2403 return MCDisassembler::Success;
2404}
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002405
2406static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2407 uint64_t Address,
2408 const void *Decoder) {
2409 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00002410 unsigned RegLst;
2411 switch(Inst.getOpcode()) {
2412 default:
2413 RegLst = fieldFromInstruction(Insn, 4, 2);
2414 break;
2415 case Mips::LWM16_MMR6:
2416 case Mips::SWM16_MMR6:
2417 RegLst = fieldFromInstruction(Insn, 8, 2);
2418 break;
2419 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002420 unsigned RegNum = RegLst & 0x3;
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002421
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002422 for (unsigned i = 0; i <= RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002423 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002424
Jim Grosbache9119e42015-05-13 18:37:00 +00002425 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002426
2427 return MCDisassembler::Success;
2428}
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002429
Simon Dardis169df4e2017-11-06 12:59:53 +00002430static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
Zoran Jovanovic41688672015-02-10 16:36:20 +00002431 uint64_t Address, const void *Decoder) {
Zoran Jovanovic41688672015-02-10 16:36:20 +00002432 switch (RegPair) {
2433 default:
2434 return MCDisassembler::Fail;
2435 case 0:
Jim Grosbache9119e42015-05-13 18:37:00 +00002436 Inst.addOperand(MCOperand::createReg(Mips::A1));
2437 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002438 break;
2439 case 1:
Jim Grosbache9119e42015-05-13 18:37:00 +00002440 Inst.addOperand(MCOperand::createReg(Mips::A1));
2441 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002442 break;
2443 case 2:
Jim Grosbache9119e42015-05-13 18:37:00 +00002444 Inst.addOperand(MCOperand::createReg(Mips::A2));
2445 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002446 break;
2447 case 3:
Jim Grosbache9119e42015-05-13 18:37:00 +00002448 Inst.addOperand(MCOperand::createReg(Mips::A0));
2449 Inst.addOperand(MCOperand::createReg(Mips::S5));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002450 break;
2451 case 4:
Jim Grosbache9119e42015-05-13 18:37:00 +00002452 Inst.addOperand(MCOperand::createReg(Mips::A0));
2453 Inst.addOperand(MCOperand::createReg(Mips::S6));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002454 break;
2455 case 5:
Jim Grosbache9119e42015-05-13 18:37:00 +00002456 Inst.addOperand(MCOperand::createReg(Mips::A0));
2457 Inst.addOperand(MCOperand::createReg(Mips::A1));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002458 break;
2459 case 6:
Jim Grosbache9119e42015-05-13 18:37:00 +00002460 Inst.addOperand(MCOperand::createReg(Mips::A0));
2461 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002462 break;
2463 case 7:
Jim Grosbache9119e42015-05-13 18:37:00 +00002464 Inst.addOperand(MCOperand::createReg(Mips::A0));
2465 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002466 break;
2467 }
2468
2469 return MCDisassembler::Success;
2470}
2471
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002472static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2473 uint64_t Address, const void *Decoder) {
Justin Bogner6499b5f2015-06-23 07:28:57 +00002474 Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002475 return MCDisassembler::Success;
2476}
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002477
2478template <typename InsnType>
2479static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2480 uint64_t Address,
2481 const void *Decoder) {
2482 // We have:
2483 // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
2484 // Invalid if rt == 0
2485 // BGTZALC_MMR6 if rs == 0 && rt != 0
2486 // BLTZALC_MMR6 if rs != 0 && rs == rt
2487 // BLTUC_MMR6 if rs != 0 && rs != rt
2488
2489 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2490 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002491 InsnType Imm = 0;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002492 bool HasRs = false;
2493 bool HasRt = false;
2494
2495 if (Rt == 0)
2496 return MCDisassembler::Fail;
2497 else if (Rs == 0) {
2498 MI.setOpcode(Mips::BGTZALC_MMR6);
2499 HasRt = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002500 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002501 }
2502 else if (Rs == Rt) {
2503 MI.setOpcode(Mips::BLTZALC_MMR6);
2504 HasRs = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002505 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002506 }
2507 else {
2508 MI.setOpcode(Mips::BLTUC_MMR6);
2509 HasRs = true;
2510 HasRt = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002511 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002512 }
2513
2514 if (HasRs)
2515 MI.addOperand(
2516 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2517
2518 if (HasRt)
2519 MI.addOperand(
2520 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2521
2522 MI.addOperand(MCOperand::createImm(Imm));
2523
2524 return MCDisassembler::Success;
2525}
2526
2527template <typename InsnType>
2528static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2529 uint64_t Address,
2530 const void *Decoder) {
2531 // We have:
2532 // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002533 // Invalid if rt == 0
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002534 // BLEZALC_MMR6 if rs == 0 && rt != 0
2535 // BGEZALC_MMR6 if rs == rt && rt != 0
2536 // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
2537
2538 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2539 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002540 InsnType Imm = 0;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002541 bool HasRs = false;
2542
2543 if (Rt == 0)
2544 return MCDisassembler::Fail;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002545 else if (Rs == 0) {
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002546 MI.setOpcode(Mips::BLEZALC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002547 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2548 }
2549 else if (Rs == Rt) {
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002550 MI.setOpcode(Mips::BGEZALC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002551 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2552 }
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002553 else {
2554 HasRs = true;
2555 MI.setOpcode(Mips::BGEUC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002556 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002557 }
2558
2559 if (HasRs)
2560 MI.addOperand(
2561 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2562 MI.addOperand(
2563 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2564
2565 MI.addOperand(MCOperand::createImm(Imm));
2566
2567 return MCDisassembler::Success;
2568}