blob: 3d29a0dac25f94e77eb845a38d999fb11bbf1034 [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
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000520static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
521 uint64_t Address,
522 const void *Decoder);
523
Zoran Jovanovicf9a02502014-11-27 18:28:59 +0000524static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
525 uint64_t Address,
526 const void *Decoder);
527
Simon Dardis169df4e2017-11-06 12:59:53 +0000528static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
Zoran Jovanovic41688672015-02-10 16:36:20 +0000529 uint64_t Address,
530 const void *Decoder);
531
Akira Hatanaka71928e62012-04-17 18:03:21 +0000532namespace llvm {
Eugene Zelenko926883e2017-02-01 01:22:51 +0000533
Mehdi Aminif42454b2016-10-09 23:00:34 +0000534Target &getTheMipselTarget();
535Target &getTheMipsTarget();
536Target &getTheMips64Target();
537Target &getTheMips64elTarget();
Eugene Zelenko926883e2017-02-01 01:22:51 +0000538
539} // end namespace llvm
Akira Hatanaka71928e62012-04-17 18:03:21 +0000540
541static MCDisassembler *createMipsDisassembler(
542 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000543 const MCSubtargetInfo &STI,
544 MCContext &Ctx) {
545 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000546}
547
548static MCDisassembler *createMipselDisassembler(
549 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000550 const MCSubtargetInfo &STI,
551 MCContext &Ctx) {
552 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000553}
554
Akira Hatanaka71928e62012-04-17 18:03:21 +0000555extern "C" void LLVMInitializeMipsDisassembler() {
556 // Register the disassembler.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000557 TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(),
Akira Hatanaka71928e62012-04-17 18:03:21 +0000558 createMipsDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000559 TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(),
Akira Hatanaka71928e62012-04-17 18:03:21 +0000560 createMipselDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000561 TargetRegistry::RegisterMCDisassembler(getTheMips64Target(),
Daniel Sandersa19216c2015-02-11 11:28:56 +0000562 createMipsDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000563 TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(),
Daniel Sandersa19216c2015-02-11 11:28:56 +0000564 createMipselDisassembler);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000565}
566
Akira Hatanaka71928e62012-04-17 18:03:21 +0000567#include "MipsGenDisassemblerTables.inc"
568
Daniel Sanders5c582b22014-05-22 11:23:21 +0000569static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
Daniel Sandersa19216c2015-02-11 11:28:56 +0000570 const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000571 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
572 return *(RegInfo->getRegClass(RC).begin() + RegNo);
573}
574
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000575template <typename InsnType>
576static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
577 const void *Decoder) {
Eugene Zelenko79220eae2017-08-03 22:12:30 +0000578 using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *);
579
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000580 // The size of the n field depends on the element size
581 // The register class also depends on this.
582 InsnType tmp = fieldFromInstruction(insn, 17, 5);
583 unsigned NSize = 0;
584 DecodeFN RegDecoder = nullptr;
585 if ((tmp & 0x18) == 0x00) { // INSVE_B
586 NSize = 4;
587 RegDecoder = DecodeMSA128BRegisterClass;
588 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
589 NSize = 3;
590 RegDecoder = DecodeMSA128HRegisterClass;
591 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
592 NSize = 2;
593 RegDecoder = DecodeMSA128WRegisterClass;
594 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
595 NSize = 1;
596 RegDecoder = DecodeMSA128DRegisterClass;
597 } else
598 llvm_unreachable("Invalid encoding");
599
600 assert(NSize != 0 && RegDecoder != nullptr);
601
602 // $wd
603 tmp = fieldFromInstruction(insn, 6, 5);
604 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
605 return MCDisassembler::Fail;
606 // $wd_in
607 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
608 return MCDisassembler::Fail;
609 // $n
610 tmp = fieldFromInstruction(insn, 16, NSize);
Jim Grosbache9119e42015-05-13 18:37:00 +0000611 MI.addOperand(MCOperand::createImm(tmp));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000612 // $ws
613 tmp = fieldFromInstruction(insn, 11, 5);
614 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
615 return MCDisassembler::Fail;
616 // $n2
Jim Grosbache9119e42015-05-13 18:37:00 +0000617 MI.addOperand(MCOperand::createImm(0));
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000618
619 return MCDisassembler::Success;
620}
621
Daniel Sanders5c582b22014-05-22 11:23:21 +0000622template <typename InsnType>
Simon Dardiscf060792016-09-16 13:50:43 +0000623static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address,
624 const void *Decoder) {
Simon Dardisb3fd1892016-10-14 09:31:42 +0000625 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Simon Dardiscf060792016-09-16 13:50:43 +0000626 InsnType Imm = fieldFromInstruction(insn, 0, 16);
627 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
Simon Dardisb3fd1892016-10-14 09:31:42 +0000628 Rs)));
Simon Dardiscf060792016-09-16 13:50:43 +0000629 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
Simon Dardisb3fd1892016-10-14 09:31:42 +0000630 Rs)));
Simon Dardiscf060792016-09-16 13:50:43 +0000631 MI.addOperand(MCOperand::createImm(Imm));
632
633 return MCDisassembler::Success;
634}
635
636template <typename InsnType>
637static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address,
638 const void *Decoder) {
Simon Dardisb3fd1892016-10-14 09:31:42 +0000639 InsnType Rs = fieldFromInstruction(insn, 21, 5);
Simon Dardiscf060792016-09-16 13:50:43 +0000640 InsnType Imm = fieldFromInstruction(insn, 0, 16);
641 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
Simon Dardisb3fd1892016-10-14 09:31:42 +0000642 Rs)));
Simon Dardiscf060792016-09-16 13:50:43 +0000643 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID,
Simon Dardisb3fd1892016-10-14 09:31:42 +0000644 Rs)));
Simon Dardiscf060792016-09-16 13:50:43 +0000645 MI.addOperand(MCOperand::createImm(Imm));
646
647 return MCDisassembler::Success;
648}
649
650template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000651static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
652 uint64_t Address,
653 const void *Decoder) {
654 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
655 // (otherwise we would have matched the ADDI instruction from the earlier
656 // ISA's instead).
657 //
658 // We have:
659 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
660 // BOVC if rs >= rt
661 // BEQZALC if rs == 0 && rt != 0
662 // BEQC if rs < rt && rs != 0
663
664 InsnType Rs = fieldFromInstruction(insn, 21, 5);
665 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000666 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000667 bool HasRs = false;
668
669 if (Rs >= Rt) {
670 MI.setOpcode(Mips::BOVC);
671 HasRs = true;
672 } else if (Rs != 0 && Rs < Rt) {
673 MI.setOpcode(Mips::BEQC);
674 HasRs = true;
675 } else
676 MI.setOpcode(Mips::BEQZALC);
677
678 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000679 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000680 Rs)));
681
Jim Grosbache9119e42015-05-13 18:37:00 +0000682 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000683 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000684 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000685
686 return MCDisassembler::Success;
687}
688
689template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000690static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn,
691 uint64_t Address,
692 const void *Decoder) {
693 InsnType Rt = fieldFromInstruction(insn, 21, 5);
694 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000695 int64_t Imm = 0;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000696
697 if (Rs >= Rt) {
698 MI.setOpcode(Mips::BOVC_MMR6);
699 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
700 Rt)));
701 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
702 Rs)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000703 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000704 } else if (Rs != 0 && Rs < Rt) {
705 MI.setOpcode(Mips::BEQC_MMR6);
706 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
707 Rs)));
708 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
709 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000710 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000711 } else {
712 MI.setOpcode(Mips::BEQZALC_MMR6);
713 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
714 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000715 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000716 }
717
718 MI.addOperand(MCOperand::createImm(Imm));
719
720 return MCDisassembler::Success;
721}
722
723template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000724static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
725 uint64_t Address,
726 const void *Decoder) {
727 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
728 // (otherwise we would have matched the ADDI instruction from the earlier
729 // ISA's instead).
730 //
731 // We have:
732 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
733 // BNVC if rs >= rt
734 // BNEZALC if rs == 0 && rt != 0
735 // BNEC if rs < rt && rs != 0
736
737 InsnType Rs = fieldFromInstruction(insn, 21, 5);
738 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000739 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000740 bool HasRs = false;
741
742 if (Rs >= Rt) {
743 MI.setOpcode(Mips::BNVC);
744 HasRs = true;
745 } else if (Rs != 0 && Rs < Rt) {
746 MI.setOpcode(Mips::BNEC);
747 HasRs = true;
748 } else
749 MI.setOpcode(Mips::BNEZALC);
750
751 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000752 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000753 Rs)));
754
Jim Grosbache9119e42015-05-13 18:37:00 +0000755 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000756 Rt)));
Jim Grosbache9119e42015-05-13 18:37:00 +0000757 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000758
759 return MCDisassembler::Success;
760}
761
762template <typename InsnType>
Hrvoje Vargac962c492016-06-09 12:57:23 +0000763static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn,
764 uint64_t Address,
765 const void *Decoder) {
766 InsnType Rt = fieldFromInstruction(insn, 21, 5);
767 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000768 int64_t Imm = 0;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000769
770 if (Rs >= Rt) {
771 MI.setOpcode(Mips::BNVC_MMR6);
772 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
773 Rt)));
774 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
775 Rs)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000776 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000777 } else if (Rs != 0 && Rs < Rt) {
778 MI.setOpcode(Mips::BNEC_MMR6);
779 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
780 Rs)));
781 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
782 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000783 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000784 } else {
785 MI.setOpcode(Mips::BNEZALC_MMR6);
786 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
787 Rt)));
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000788 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Hrvoje Vargac962c492016-06-09 12:57:23 +0000789 }
790
791 MI.addOperand(MCOperand::createImm(Imm));
792
793 return MCDisassembler::Success;
794}
795
796template <typename InsnType>
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +0000797static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn,
798 uint64_t Address,
799 const void *Decoder) {
800 // We have:
801 // 0b110101 ttttt sssss iiiiiiiiiiiiiiii
802 // Invalid if rt == 0
803 // BGTZC_MMR6 if rs == 0 && rt != 0
804 // BLTZC_MMR6 if rs == rt && rt != 0
805 // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0
806
807 InsnType Rt = fieldFromInstruction(insn, 21, 5);
808 InsnType Rs = fieldFromInstruction(insn, 16, 5);
809 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
810 bool HasRs = false;
811
812 if (Rt == 0)
813 return MCDisassembler::Fail;
814 else if (Rs == 0)
815 MI.setOpcode(Mips::BGTZC_MMR6);
816 else if (Rs == Rt)
817 MI.setOpcode(Mips::BLTZC_MMR6);
818 else {
819 MI.setOpcode(Mips::BLTC_MMR6);
820 HasRs = true;
821 }
822
823 if (HasRs)
824 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
825 Rs)));
826
827 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
828 Rt)));
829
830 MI.addOperand(MCOperand::createImm(Imm));
831
832 return MCDisassembler::Success;
833}
834
835template <typename InsnType>
836static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn,
837 uint64_t Address,
838 const void *Decoder) {
839 // We have:
840 // 0b111101 ttttt sssss iiiiiiiiiiiiiiii
841 // Invalid if rt == 0
842 // BLEZC_MMR6 if rs == 0 && rt != 0
843 // BGEZC_MMR6 if rs == rt && rt != 0
844 // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0
845
846 InsnType Rt = fieldFromInstruction(insn, 21, 5);
847 InsnType Rs = fieldFromInstruction(insn, 16, 5);
848 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
849 bool HasRs = false;
850
851 if (Rt == 0)
852 return MCDisassembler::Fail;
853 else if (Rs == 0)
854 MI.setOpcode(Mips::BLEZC_MMR6);
855 else if (Rs == Rt)
856 MI.setOpcode(Mips::BGEZC_MMR6);
857 else {
858 HasRs = true;
859 MI.setOpcode(Mips::BGEC_MMR6);
860 }
861
862 if (HasRs)
863 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
864 Rs)));
865
866 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
867 Rt)));
868
869 MI.addOperand(MCOperand::createImm(Imm));
870
871 return MCDisassembler::Success;
872}
873
874template <typename InsnType>
Daniel Sanders5c582b22014-05-22 11:23:21 +0000875static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
876 uint64_t Address,
877 const void *Decoder) {
878 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
879 // (otherwise we would have matched the BLEZL instruction from the earlier
880 // ISA's instead).
881 //
882 // We have:
883 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
884 // Invalid if rs == 0
885 // BLEZC if rs == 0 && rt != 0
886 // BGEZC if rs == rt && rt != 0
887 // BGEC if rs != rt && rs != 0 && rt != 0
888
889 InsnType Rs = fieldFromInstruction(insn, 21, 5);
890 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000891 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000892 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000893
894 if (Rt == 0)
895 return MCDisassembler::Fail;
896 else if (Rs == 0)
897 MI.setOpcode(Mips::BLEZC);
898 else if (Rs == Rt)
899 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000900 else {
901 HasRs = true;
902 MI.setOpcode(Mips::BGEC);
903 }
904
905 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000906 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000907 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000908
Jim Grosbache9119e42015-05-13 18:37:00 +0000909 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000910 Rt)));
911
Jim Grosbache9119e42015-05-13 18:37:00 +0000912 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000913
914 return MCDisassembler::Success;
915}
916
917template <typename InsnType>
918static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
919 uint64_t Address,
920 const void *Decoder) {
921 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
922 // (otherwise we would have matched the BGTZL instruction from the earlier
923 // ISA's instead).
924 //
925 // We have:
926 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
927 // Invalid if rs == 0
928 // BGTZC if rs == 0 && rt != 0
929 // BLTZC if rs == rt && rt != 0
930 // BLTC if rs != rt && rs != 0 && rt != 0
931
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000932 bool HasRs = false;
933
Daniel Sanders5c582b22014-05-22 11:23:21 +0000934 InsnType Rs = fieldFromInstruction(insn, 21, 5);
935 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000936 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000937
938 if (Rt == 0)
939 return MCDisassembler::Fail;
940 else if (Rs == 0)
941 MI.setOpcode(Mips::BGTZC);
942 else if (Rs == Rt)
943 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000944 else {
945 MI.setOpcode(Mips::BLTC);
946 HasRs = true;
947 }
948
949 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000950 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000951 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000952
Jim Grosbache9119e42015-05-13 18:37:00 +0000953 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000954 Rt)));
955
Jim Grosbache9119e42015-05-13 18:37:00 +0000956 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000957
958 return MCDisassembler::Success;
959}
960
961template <typename InsnType>
962static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
963 uint64_t Address,
964 const void *Decoder) {
965 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
966 // (otherwise we would have matched the BGTZ instruction from the earlier
967 // ISA's instead).
968 //
969 // We have:
970 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
971 // BGTZ if rt == 0
972 // BGTZALC if rs == 0 && rt != 0
973 // BLTZALC if rs != 0 && rs == rt
974 // BLTUC if rs != 0 && rs != rt
975
976 InsnType Rs = fieldFromInstruction(insn, 21, 5);
977 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +0000978 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000979 bool HasRs = false;
980 bool HasRt = false;
981
982 if (Rt == 0) {
983 MI.setOpcode(Mips::BGTZ);
984 HasRs = true;
985 } else if (Rs == 0) {
986 MI.setOpcode(Mips::BGTZALC);
987 HasRt = true;
988 } else if (Rs == Rt) {
989 MI.setOpcode(Mips::BLTZALC);
990 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000991 } else {
992 MI.setOpcode(Mips::BLTUC);
993 HasRs = true;
994 HasRt = true;
995 }
Daniel Sanders5c582b22014-05-22 11:23:21 +0000996
997 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +0000998 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000999 Rs)));
1000
1001 if (HasRt)
Jim Grosbache9119e42015-05-13 18:37:00 +00001002 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Daniel Sanders5c582b22014-05-22 11:23:21 +00001003 Rt)));
1004
Jim Grosbache9119e42015-05-13 18:37:00 +00001005 MI.addOperand(MCOperand::createImm(Imm));
Daniel Sanders5c582b22014-05-22 11:23:21 +00001006
1007 return MCDisassembler::Success;
1008}
1009
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001010template <typename InsnType>
1011static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
1012 uint64_t Address,
1013 const void *Decoder) {
1014 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
1015 // (otherwise we would have matched the BLEZL instruction from the earlier
1016 // ISA's instead).
1017 //
1018 // We have:
1019 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
1020 // Invalid if rs == 0
1021 // BLEZALC if rs == 0 && rt != 0
1022 // BGEZALC if rs == rt && rt != 0
1023 // BGEUC if rs != rt && rs != 0 && rt != 0
1024
1025 InsnType Rs = fieldFromInstruction(insn, 21, 5);
1026 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Sagar Thakur672c7102016-05-24 09:57:10 +00001027 int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001028 bool HasRs = false;
1029
1030 if (Rt == 0)
1031 return MCDisassembler::Fail;
1032 else if (Rs == 0)
1033 MI.setOpcode(Mips::BLEZALC);
1034 else if (Rs == Rt)
1035 MI.setOpcode(Mips::BGEZALC);
1036 else {
1037 HasRs = true;
1038 MI.setOpcode(Mips::BGEUC);
1039 }
1040
1041 if (HasRs)
Jim Grosbache9119e42015-05-13 18:37:00 +00001042 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001043 Rs)));
Jim Grosbache9119e42015-05-13 18:37:00 +00001044 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001045 Rt)));
1046
Jim Grosbache9119e42015-05-13 18:37:00 +00001047 MI.addOperand(MCOperand::createImm(Imm));
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +00001048
1049 return MCDisassembler::Success;
1050}
1051
Simon Dardis55e44672017-09-14 17:27:53 +00001052// Override the generated disassembler to produce DEXT all the time. This is
1053// for feature / behaviour parity with binutils.
1054template <typename InsnType>
1055static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
1056 const void *Decoder) {
1057 unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
1058 unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
1059 unsigned Size = 0;
1060 unsigned Pos = 0;
Simon Dardis55e44672017-09-14 17:27:53 +00001061
1062 switch (MI.getOpcode()) {
Simon Dardis55e44672017-09-14 17:27:53 +00001063 case Mips::DEXT:
1064 Pos = Lsb;
1065 Size = Msbd + 1;
1066 break;
Simon Dardis55e44672017-09-14 17:27:53 +00001067 case Mips::DEXTM:
1068 Pos = Lsb;
1069 Size = Msbd + 1 + 32;
1070 break;
Simon Dardis55e44672017-09-14 17:27:53 +00001071 case Mips::DEXTU:
1072 Pos = Lsb + 32;
1073 Size = Msbd + 1;
1074 break;
1075 default:
1076 llvm_unreachable("Unknown DEXT instruction!");
1077 }
1078
Aleksandar Beserminjid6dada12017-12-11 11:21:40 +00001079 MI.setOpcode(Mips::DEXT);
Simon Dardis55e44672017-09-14 17:27:53 +00001080
Simon Dardis55e44672017-09-14 17:27:53 +00001081 InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1082 InsnType Rt = fieldFromInstruction(Insn, 16, 5);
Simon Dardis55e44672017-09-14 17:27:53 +00001083
1084 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1085 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
1086 MI.addOperand(MCOperand::createImm(Pos));
1087 MI.addOperand(MCOperand::createImm(Size));
1088
1089 return MCDisassembler::Success;
1090}
1091
Simon Dardis6f83ae32017-09-14 15:17:50 +00001092// Override the generated disassembler to produce DINS all the time. This is
1093// for feature / behaviour parity with binutils.
1094template <typename InsnType>
1095static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address,
1096 const void *Decoder) {
1097 unsigned Msbd = fieldFromInstruction(Insn, 11, 5);
1098 unsigned Lsb = fieldFromInstruction(Insn, 6, 5);
1099 unsigned Size = 0;
1100 unsigned Pos = 0;
Simon Dardis6f83ae32017-09-14 15:17:50 +00001101
1102 switch (MI.getOpcode()) {
Simon Dardis6f83ae32017-09-14 15:17:50 +00001103 case Mips::DINS:
1104 Pos = Lsb;
1105 Size = Msbd + 1 - Pos;
1106 break;
Simon Dardis6f83ae32017-09-14 15:17:50 +00001107 case Mips::DINSM:
1108 Pos = Lsb;
1109 Size = Msbd + 33 - Pos;
1110 break;
Simon Dardis6f83ae32017-09-14 15:17:50 +00001111 case Mips::DINSU:
1112 Pos = Lsb + 32;
1113 // mbsd = pos + size - 33
1114 // mbsd - pos + 33 = size
1115 Size = Msbd + 33 - Pos;
1116 break;
1117 default:
1118 llvm_unreachable("Unknown DINS instruction!");
1119 }
1120
Simon Dardis6f83ae32017-09-14 15:17:50 +00001121 InsnType Rs = fieldFromInstruction(Insn, 21, 5);
1122 InsnType Rt = fieldFromInstruction(Insn, 16, 5);
Simon Dardis6f83ae32017-09-14 15:17:50 +00001123
Aleksandar Beserminjid6dada12017-12-11 11:21:40 +00001124 MI.setOpcode(Mips::DINS);
Simon Dardis6f83ae32017-09-14 15:17:50 +00001125 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt)));
1126 MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs)));
1127 MI.addOperand(MCOperand::createImm(Pos));
1128 MI.addOperand(MCOperand::createImm(Size));
1129
1130 return MCDisassembler::Success;
1131}
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001132/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
Simon Pilgrimdcd84332016-11-18 11:53:36 +00001133/// according to the given endianness.
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001134static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
1135 uint64_t &Size, uint32_t &Insn,
1136 bool IsBigEndian) {
1137 // We want to read exactly 2 Bytes of data.
1138 if (Bytes.size() < 2) {
1139 Size = 0;
1140 return MCDisassembler::Fail;
1141 }
1142
1143 if (IsBigEndian) {
1144 Insn = (Bytes[0] << 8) | Bytes[1];
1145 } else {
1146 Insn = (Bytes[1] << 8) | Bytes[0];
1147 }
1148
1149 return MCDisassembler::Success;
1150}
1151
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001152/// Read four bytes from the ArrayRef and return 32 bit word sorted
Simon Pilgrimdcd84332016-11-18 11:53:36 +00001153/// according to the given endianness.
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001154static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
1155 uint64_t &Size, uint32_t &Insn,
1156 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001157 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001158 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001159 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001160 return MCDisassembler::Fail;
1161 }
1162
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001163 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
1164 // always precede the low 16 bits in the instruction stream (that is, they
1165 // are placed at lower addresses in the instruction stream).
1166 //
1167 // microMIPS byte ordering:
1168 // Big-endian: 0 | 1 | 2 | 3
1169 // Little-endian: 1 | 0 | 3 | 2
1170
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001171 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001172 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001173 Insn =
1174 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
1175 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +00001176 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001177 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +00001178 (Bytes[1] << 24);
1179 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001180 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +00001181 (Bytes[3] << 24);
1182 }
Akira Hatanaka71928e62012-04-17 18:03:21 +00001183 }
1184
1185 return MCDisassembler::Success;
1186}
1187
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001188DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001189 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001190 uint64_t Address,
1191 raw_ostream &VStream,
1192 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001193 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001194 DecodeStatus Result;
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001195 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001196
Vladimir Medicdde3d582013-09-06 12:30:36 +00001197 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001198 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
Reid Klecknerebee6122015-11-19 21:51:55 +00001199 if (Result == MCDisassembler::Fail)
1200 return MCDisassembler::Fail;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001201
Zoran Jovanovicada70912015-09-07 11:56:37 +00001202 if (hasMips32r6()) {
1203 DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n");
1204 // Calling the auto-generated decoder function for microMIPS32R6
Aleksandar Beserminjid6dada12017-12-11 11:21:40 +00001205 // 16-bit instructions.
Zoran Jovanovicada70912015-09-07 11:56:37 +00001206 Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn,
1207 Address, this, STI);
1208 if (Result != MCDisassembler::Fail) {
1209 Size = 2;
1210 return Result;
1211 }
1212 }
1213
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001214 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
Zoran Jovanovicada70912015-09-07 11:56:37 +00001215 // Calling the auto-generated decoder function for microMIPS 16-bit
1216 // instructions.
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001217 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
1218 this, STI);
1219 if (Result != MCDisassembler::Fail) {
1220 Size = 2;
1221 return Result;
1222 }
1223
1224 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
1225 if (Result == MCDisassembler::Fail)
1226 return MCDisassembler::Fail;
1227
Jozef Kolek676d6012015-04-20 14:40:38 +00001228 if (hasMips32r6()) {
1229 DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");
1230 // Calling the auto-generated decoder function.
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001231 Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,
Jozef Kolek676d6012015-04-20 14:40:38 +00001232 this, STI);
Zoran Jovanovicada70912015-09-07 11:56:37 +00001233 if (Result != MCDisassembler::Fail) {
1234 Size = 4;
1235 return Result;
1236 }
Jozef Kolek676d6012015-04-20 14:40:38 +00001237 }
Zoran Jovanovic366783e2015-08-12 12:45:16 +00001238
Zoran Jovanovicada70912015-09-07 11:56:37 +00001239 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
1240 // Calling the auto-generated decoder function.
1241 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
1242 this, STI);
Vladimir Medicdde3d582013-09-06 12:30:36 +00001243 if (Result != MCDisassembler::Fail) {
1244 Size = 4;
1245 return Result;
1246 }
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001247
Simon Dardis51a7ae22017-10-05 10:27:37 +00001248 if (isFP64()) {
1249 DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n");
1250 Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn,
Hrvoje Varga2cb74ac2016-03-24 08:02:09 +00001251 Address, this, STI);
1252 if (Result != MCDisassembler::Fail) {
1253 Size = 4;
1254 return Result;
1255 }
1256 }
1257
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001258 // This is an invalid instruction. Claim that the Size is 2 bytes. Since
1259 // microMIPS instructions have a minimum alignment of 2, the next 2 bytes
1260 // could form a valid instruction. The two bytes we rejected as an
1261 // instruction could have actually beeen an inline constant pool that is
1262 // unconditionally branched over.
Reid Klecknerebee6122015-11-19 21:51:55 +00001263 Size = 2;
Vladimir Medicdde3d582013-09-06 12:30:36 +00001264 return MCDisassembler::Fail;
1265 }
1266
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001267 // Attempt to read the instruction so that we can attempt to decode it. If
1268 // the buffer is not 4 bytes long, let the higher level logic figure out
1269 // what to do with a size of zero and MCDisassembler::Fail.
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001270 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001271 if (Result == MCDisassembler::Fail)
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001272 return MCDisassembler::Fail;
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001273
1274 // The only instruction size for standard encoded MIPS.
1275 Size = 4;
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001276
Daniel Sandersc171f652014-06-13 13:15:59 +00001277 if (hasCOP3()) {
1278 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
1279 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001280 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001281 if (Result != MCDisassembler::Fail)
Daniel Sandersc171f652014-06-13 13:15:59 +00001282 return Result;
Daniel Sandersc171f652014-06-13 13:15:59 +00001283 }
1284
1285 if (hasMips32r6() && isGP64()) {
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001286 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
1287 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
1288 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001289 if (Result != MCDisassembler::Fail)
Daniel Sanders0fa60412014-06-12 13:39:06 +00001290 return Result;
Daniel Sanders0fa60412014-06-12 13:39:06 +00001291 }
1292
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001293 if (hasMips32r6() && isPTR64()) {
1294 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1295 Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn,
1296 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001297 if (Result != MCDisassembler::Fail)
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001298 return Result;
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001299 }
1300
Daniel Sandersc171f652014-06-13 13:15:59 +00001301 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001302 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001303 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +00001304 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001305 if (Result != MCDisassembler::Fail)
Daniel Sanders5c582b22014-05-22 11:23:21 +00001306 return Result;
Daniel Sanders5c582b22014-05-22 11:23:21 +00001307 }
1308
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001309 if (hasMips2() && isPTR64()) {
1310 DEBUG(dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n");
1311 Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn,
1312 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001313 if (Result != MCDisassembler::Fail)
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001314 return Result;
Simon Dardis4fbf76f2016-06-14 11:29:28 +00001315 }
1316
Kai Nacke3adf9b82015-05-28 16:23:16 +00001317 if (hasCnMips()) {
1318 DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n");
1319 Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn,
1320 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001321 if (Result != MCDisassembler::Fail)
Kai Nacke3adf9b82015-05-28 16:23:16 +00001322 return Result;
Kai Nacke3adf9b82015-05-28 16:23:16 +00001323 }
1324
Daniel Sandersa19216c2015-02-11 11:28:56 +00001325 if (isGP64()) {
1326 DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n");
1327 Result = decodeInstruction(DecoderTableMips6432, Instr, Insn,
1328 Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001329 if (Result != MCDisassembler::Fail)
Daniel Sandersa19216c2015-02-11 11:28:56 +00001330 return Result;
Daniel Sandersa19216c2015-02-11 11:28:56 +00001331 }
1332
Simon Dardis51a7ae22017-10-05 10:27:37 +00001333 if (isFP64()) {
1334 DEBUG(dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n");
1335 Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn,
1336 Address, this, STI);
1337 if (Result != MCDisassembler::Fail)
1338 return Result;
1339 }
1340
Daniel Sanders0fa60412014-06-12 13:39:06 +00001341 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +00001342 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +00001343 Result =
1344 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Simon Dardisa5f52dc2017-02-24 10:50:27 +00001345 if (Result != MCDisassembler::Fail)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001346 return Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001347
1348 return MCDisassembler::Fail;
1349}
1350
Reed Kotlerec8a5492013-02-14 03:05:25 +00001351static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1352 unsigned RegNo,
1353 uint64_t Address,
1354 const void *Decoder) {
Reed Kotlerec8a5492013-02-14 03:05:25 +00001355 return MCDisassembler::Fail;
Reed Kotlerec8a5492013-02-14 03:05:25 +00001356}
1357
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001358static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
1359 unsigned RegNo,
1360 uint64_t Address,
1361 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001362 if (RegNo > 31)
1363 return MCDisassembler::Fail;
1364
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001365 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001366 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001367 return MCDisassembler::Success;
1368}
1369
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001370static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
1371 unsigned RegNo,
1372 uint64_t Address,
1373 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001374 if (RegNo > 7)
1375 return MCDisassembler::Fail;
1376 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001377 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolekea22c4c2014-11-24 13:29:59 +00001378 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +00001379}
1380
Jozef Kolek1904fa22014-11-24 14:25:53 +00001381static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
1382 unsigned RegNo,
1383 uint64_t Address,
1384 const void *Decoder) {
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001385 if (RegNo > 7)
1386 return MCDisassembler::Fail;
1387 unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001388 Inst.addOperand(MCOperand::createReg(Reg));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001389 return MCDisassembler::Success;
Jozef Kolek1904fa22014-11-24 14:25:53 +00001390}
1391
Zoran Jovanovic41688672015-02-10 16:36:20 +00001392static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1393 unsigned RegNo,
1394 uint64_t Address,
1395 const void *Decoder) {
1396 if (RegNo > 7)
1397 return MCDisassembler::Fail;
1398 unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001399 Inst.addOperand(MCOperand::createReg(Reg));
Zoran Jovanovic41688672015-02-10 16:36:20 +00001400 return MCDisassembler::Success;
1401}
1402
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001403static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1404 unsigned RegNo,
1405 uint64_t Address,
1406 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +00001407 if (RegNo > 31)
1408 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001409 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001410 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001411 return MCDisassembler::Success;
1412}
1413
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001414static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1415 unsigned RegNo,
1416 uint64_t Address,
1417 const void *Decoder) {
Daniel Sandersa19216c2015-02-11 11:28:56 +00001418 if (static_cast<const MipsDisassembler *>(Decoder)->isGP64())
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001419 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
1420
1421 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
1422}
1423
Akira Hatanaka654655f2013-08-14 00:53:38 +00001424static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1425 unsigned RegNo,
1426 uint64_t Address,
1427 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001428 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001429}
1430
Akira Hatanaka71928e62012-04-17 18:03:21 +00001431static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1432 unsigned RegNo,
1433 uint64_t Address,
1434 const void *Decoder) {
1435 if (RegNo > 31)
1436 return MCDisassembler::Fail;
1437
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001438 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001439 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001440 return MCDisassembler::Success;
1441}
1442
1443static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1444 unsigned RegNo,
1445 uint64_t Address,
1446 const void *Decoder) {
1447 if (RegNo > 31)
1448 return MCDisassembler::Fail;
1449
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001450 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001451 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001452 return MCDisassembler::Success;
1453}
1454
1455static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1456 unsigned RegNo,
1457 uint64_t Address,
1458 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +00001459 if (RegNo > 31)
1460 return MCDisassembler::Fail;
1461 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001462 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001463 return MCDisassembler::Success;
1464}
1465
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001466static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1467 unsigned RegNo,
1468 uint64_t Address,
1469 const void *Decoder) {
1470 if (RegNo > 7)
1471 return MCDisassembler::Fail;
1472 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001473 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +00001474 return MCDisassembler::Success;
1475}
1476
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001477static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
1478 uint64_t Address,
1479 const void *Decoder) {
Daniel Sanders0fa60412014-06-12 13:39:06 +00001480 if (RegNo > 31)
1481 return MCDisassembler::Fail;
1482
Vasileios Kalintiris36901dd2016-03-01 20:25:43 +00001483 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00001484 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders0fa60412014-06-12 13:39:06 +00001485 return MCDisassembler::Success;
1486}
1487
Akira Hatanaka71928e62012-04-17 18:03:21 +00001488static DecodeStatus DecodeMem(MCInst &Inst,
1489 unsigned Insn,
1490 uint64_t Address,
1491 const void *Decoder) {
1492 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001493 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1494 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001495
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001496 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1497 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001498
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001499 if (Inst.getOpcode() == Mips::SC ||
1500 Inst.getOpcode() == Mips::SCD)
Jim Grosbache9119e42015-05-13 18:37:00 +00001501 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001502
1503 Inst.addOperand(MCOperand::createReg(Reg));
1504 Inst.addOperand(MCOperand::createReg(Base));
1505 Inst.addOperand(MCOperand::createImm(Offset));
1506
1507 return MCDisassembler::Success;
1508}
1509
1510static DecodeStatus DecodeMemEVA(MCInst &Inst,
1511 unsigned Insn,
1512 uint64_t Address,
1513 const void *Decoder) {
1514 int Offset = SignExtend32<9>(Insn >> 7);
1515 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1516 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1517
1518 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1519 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1520
1521 if (Inst.getOpcode() == Mips::SCE)
1522 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001523
Jim Grosbache9119e42015-05-13 18:37:00 +00001524 Inst.addOperand(MCOperand::createReg(Reg));
1525 Inst.addOperand(MCOperand::createReg(Base));
1526 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001527
1528 return MCDisassembler::Success;
1529}
1530
Hrvoje Varga3c88fbd2015-10-16 12:24:58 +00001531static DecodeStatus DecodeLoadByte15(MCInst &Inst,
1532 unsigned Insn,
1533 uint64_t Address,
1534 const void *Decoder) {
1535 int Offset = SignExtend32<16>(Insn & 0xffff);
1536 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1537 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1538
1539 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1540 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1541
1542 Inst.addOperand(MCOperand::createReg(Reg));
1543 Inst.addOperand(MCOperand::createReg(Base));
1544 Inst.addOperand(MCOperand::createImm(Offset));
1545
1546 return MCDisassembler::Success;
1547}
1548
Daniel Sanders92db6b72014-10-01 08:26:55 +00001549static DecodeStatus DecodeCacheOp(MCInst &Inst,
1550 unsigned Insn,
1551 uint64_t Address,
1552 const void *Decoder) {
1553 int Offset = SignExtend32<16>(Insn & 0xffff);
1554 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1555 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1556
1557 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1558
Jim Grosbache9119e42015-05-13 18:37:00 +00001559 Inst.addOperand(MCOperand::createReg(Base));
1560 Inst.addOperand(MCOperand::createImm(Offset));
1561 Inst.addOperand(MCOperand::createImm(Hint));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001562
1563 return MCDisassembler::Success;
1564}
1565
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001566static DecodeStatus DecodeCacheOpMM(MCInst &Inst,
1567 unsigned Insn,
1568 uint64_t Address,
1569 const void *Decoder) {
1570 int Offset = SignExtend32<12>(Insn & 0xfff);
1571 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1572 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1573
1574 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1575
Jim Grosbache9119e42015-05-13 18:37:00 +00001576 Inst.addOperand(MCOperand::createReg(Base));
1577 Inst.addOperand(MCOperand::createImm(Offset));
1578 Inst.addOperand(MCOperand::createImm(Hint));
Jozef Kolekab6d1cc2014-12-23 19:55:34 +00001579
1580 return MCDisassembler::Success;
1581}
1582
Zoran Jovanovicd9790792015-09-09 09:10:46 +00001583static DecodeStatus DecodePrefeOpMM(MCInst &Inst,
1584 unsigned Insn,
1585 uint64_t Address,
1586 const void *Decoder) {
1587 int Offset = SignExtend32<9>(Insn & 0x1ff);
1588 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1589 unsigned Hint = fieldFromInstruction(Insn, 21, 5);
1590
1591 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1592
1593 Inst.addOperand(MCOperand::createReg(Base));
1594 Inst.addOperand(MCOperand::createImm(Offset));
1595 Inst.addOperand(MCOperand::createImm(Hint));
1596
1597 return MCDisassembler::Success;
1598}
1599
Daniel Sanderse4e83a72015-09-15 10:02:16 +00001600static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst,
1601 unsigned Insn,
1602 uint64_t Address,
1603 const void *Decoder) {
1604 int Offset = SignExtend32<9>(Insn >> 7);
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001605 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1606 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1607
1608 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1609
Jim Grosbache9119e42015-05-13 18:37:00 +00001610 Inst.addOperand(MCOperand::createReg(Base));
1611 Inst.addOperand(MCOperand::createImm(Offset));
1612 Inst.addOperand(MCOperand::createImm(Hint));
Vladimir Medicdf464ae2015-01-29 11:33:41 +00001613
1614 return MCDisassembler::Success;
1615}
1616
Daniel Sandersb4484d62014-11-27 17:28:10 +00001617static DecodeStatus DecodeSyncI(MCInst &Inst,
1618 unsigned Insn,
1619 uint64_t Address,
1620 const void *Decoder) {
1621 int Offset = SignExtend32<16>(Insn & 0xffff);
1622 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1623
1624 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1625
Jim Grosbache9119e42015-05-13 18:37:00 +00001626 Inst.addOperand(MCOperand::createReg(Base));
1627 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sandersb4484d62014-11-27 17:28:10 +00001628
1629 return MCDisassembler::Success;
1630}
1631
Hrvoje Varga18148672015-10-28 11:04:29 +00001632static DecodeStatus DecodeSynciR6(MCInst &Inst,
1633 unsigned Insn,
1634 uint64_t Address,
1635 const void *Decoder) {
1636 int Immediate = SignExtend32<16>(Insn & 0xffff);
1637 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1638
1639 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1640
1641 Inst.addOperand(MCOperand::createReg(Base));
1642 Inst.addOperand(MCOperand::createImm(Immediate));
1643
1644 return MCDisassembler::Success;
1645}
1646
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001647static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1648 uint64_t Address, const void *Decoder) {
1649 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1650 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1651 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1652
1653 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1654 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1655
Jim Grosbache9119e42015-05-13 18:37:00 +00001656 Inst.addOperand(MCOperand::createReg(Reg));
1657 Inst.addOperand(MCOperand::createReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001658
1659 // The immediate field of an LD/ST instruction is scaled which means it must
1660 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1661 // data format.
1662 // .b - 1 byte
1663 // .h - 2 bytes
1664 // .w - 4 bytes
1665 // .d - 8 bytes
1666 switch(Inst.getOpcode())
1667 {
1668 default:
Eugene Zelenko926883e2017-02-01 01:22:51 +00001669 assert(false && "Unexpected instruction");
Matheus Almeida6b59c442013-12-05 11:06:22 +00001670 return MCDisassembler::Fail;
1671 break;
1672 case Mips::LD_B:
1673 case Mips::ST_B:
Jim Grosbache9119e42015-05-13 18:37:00 +00001674 Inst.addOperand(MCOperand::createImm(Offset));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001675 break;
1676 case Mips::LD_H:
1677 case Mips::ST_H:
Jim Grosbache9119e42015-05-13 18:37:00 +00001678 Inst.addOperand(MCOperand::createImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001679 break;
1680 case Mips::LD_W:
1681 case Mips::ST_W:
Jim Grosbache9119e42015-05-13 18:37:00 +00001682 Inst.addOperand(MCOperand::createImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001683 break;
1684 case Mips::LD_D:
1685 case Mips::ST_D:
Jim Grosbache9119e42015-05-13 18:37:00 +00001686 Inst.addOperand(MCOperand::createImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001687 break;
1688 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001689
1690 return MCDisassembler::Success;
1691}
1692
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001693static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
1694 unsigned Insn,
1695 uint64_t Address,
1696 const void *Decoder) {
1697 unsigned Offset = Insn & 0xf;
1698 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1699 unsigned Base = fieldFromInstruction(Insn, 4, 3);
1700
1701 switch (Inst.getOpcode()) {
1702 case Mips::LBU16_MM:
1703 case Mips::LHU16_MM:
1704 case Mips::LW16_MM:
1705 if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
1706 == MCDisassembler::Fail)
1707 return MCDisassembler::Fail;
1708 break;
1709 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001710 case Mips::SB16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001711 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001712 case Mips::SH16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001713 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001714 case Mips::SW16_MMR6:
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001715 if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
1716 == MCDisassembler::Fail)
1717 return MCDisassembler::Fail;
1718 break;
1719 }
1720
1721 if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
1722 == MCDisassembler::Fail)
1723 return MCDisassembler::Fail;
1724
1725 switch (Inst.getOpcode()) {
1726 case Mips::LBU16_MM:
1727 if (Offset == 0xf)
Jim Grosbache9119e42015-05-13 18:37:00 +00001728 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001729 else
Jim Grosbache9119e42015-05-13 18:37:00 +00001730 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001731 break;
1732 case Mips::SB16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001733 case Mips::SB16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001734 Inst.addOperand(MCOperand::createImm(Offset));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001735 break;
1736 case Mips::LHU16_MM:
1737 case Mips::SH16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001738 case Mips::SH16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001739 Inst.addOperand(MCOperand::createImm(Offset << 1));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001740 break;
1741 case Mips::LW16_MM:
1742 case Mips::SW16_MM:
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001743 case Mips::SW16_MMR6:
Jim Grosbache9119e42015-05-13 18:37:00 +00001744 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek315e7ec2014-11-26 18:56:38 +00001745 break;
1746 }
1747
1748 return MCDisassembler::Success;
1749}
1750
Jozef Kolek12c69822014-12-23 16:16:33 +00001751static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst,
1752 unsigned Insn,
1753 uint64_t Address,
1754 const void *Decoder) {
1755 unsigned Offset = Insn & 0x1F;
1756 unsigned Reg = fieldFromInstruction(Insn, 5, 5);
1757
1758 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1759
Jim Grosbache9119e42015-05-13 18:37:00 +00001760 Inst.addOperand(MCOperand::createReg(Reg));
1761 Inst.addOperand(MCOperand::createReg(Mips::SP));
1762 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolek12c69822014-12-23 16:16:33 +00001763
1764 return MCDisassembler::Success;
1765}
1766
Jozef Koleke10a02e2015-01-28 17:27:26 +00001767static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst,
1768 unsigned Insn,
1769 uint64_t Address,
1770 const void *Decoder) {
1771 unsigned Offset = Insn & 0x7F;
1772 unsigned Reg = fieldFromInstruction(Insn, 7, 3);
1773
1774 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1775
Jim Grosbache9119e42015-05-13 18:37:00 +00001776 Inst.addOperand(MCOperand::createReg(Reg));
1777 Inst.addOperand(MCOperand::createReg(Mips::GP));
1778 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Koleke10a02e2015-01-28 17:27:26 +00001779
1780 return MCDisassembler::Success;
1781}
1782
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001783static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,
1784 unsigned Insn,
1785 uint64_t Address,
1786 const void *Decoder) {
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00001787 int Offset;
1788 switch (Inst.getOpcode()) {
1789 case Mips::LWM16_MMR6:
1790 case Mips::SWM16_MMR6:
1791 Offset = fieldFromInstruction(Insn, 4, 4);
1792 break;
1793 default:
1794 Offset = SignExtend32<4>(Insn & 0xf);
1795 break;
1796 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001797
1798 if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)
1799 == MCDisassembler::Fail)
1800 return MCDisassembler::Fail;
1801
Jim Grosbache9119e42015-05-13 18:37:00 +00001802 Inst.addOperand(MCOperand::createReg(Mips::SP));
1803 Inst.addOperand(MCOperand::createImm(Offset << 2));
Jozef Kolekd68d424a2015-02-10 12:41:13 +00001804
1805 return MCDisassembler::Success;
1806}
1807
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001808static DecodeStatus DecodeMemMMImm9(MCInst &Inst,
1809 unsigned Insn,
1810 uint64_t Address,
1811 const void *Decoder) {
1812 int Offset = SignExtend32<9>(Insn & 0x1ff);
1813 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1814 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1815
1816 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1817 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1818
Hrvoje Varga3ef4dd72015-10-15 08:11:50 +00001819 if (Inst.getOpcode() == Mips::SCE_MM)
1820 Inst.addOperand(MCOperand::createReg(Reg));
1821
Zoran Jovanovica6593ff2015-08-18 12:53:08 +00001822 Inst.addOperand(MCOperand::createReg(Reg));
1823 Inst.addOperand(MCOperand::createReg(Base));
1824 Inst.addOperand(MCOperand::createImm(Offset));
1825
1826 return MCDisassembler::Success;
1827}
1828
Vladimir Medicdde3d582013-09-06 12:30:36 +00001829static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1830 unsigned Insn,
1831 uint64_t Address,
1832 const void *Decoder) {
1833 int Offset = SignExtend32<12>(Insn & 0x0fff);
1834 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1835 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1836
1837 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1838 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1839
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001840 switch (Inst.getOpcode()) {
1841 case Mips::SWM32_MM:
1842 case Mips::LWM32_MM:
1843 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1844 == MCDisassembler::Fail)
1845 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00001846 Inst.addOperand(MCOperand::createReg(Base));
1847 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001848 break;
1849 case Mips::SC_MM:
Jim Grosbache9119e42015-05-13 18:37:00 +00001850 Inst.addOperand(MCOperand::createReg(Reg));
Justin Bognerb03fd122016-08-17 05:10:15 +00001851 LLVM_FALLTHROUGH;
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001852 default:
Jim Grosbache9119e42015-05-13 18:37:00 +00001853 Inst.addOperand(MCOperand::createReg(Reg));
Zlatko Buljanba553a62016-05-09 08:07:28 +00001854 if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM ||
1855 Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6)
Jim Grosbache9119e42015-05-13 18:37:00 +00001856 Inst.addOperand(MCOperand::createReg(Reg+1));
Zoran Jovanovic2deca342014-12-16 14:59:10 +00001857
Jim Grosbache9119e42015-05-13 18:37:00 +00001858 Inst.addOperand(MCOperand::createReg(Base));
1859 Inst.addOperand(MCOperand::createImm(Offset));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001860 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001861
1862 return MCDisassembler::Success;
1863}
1864
1865static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1866 unsigned Insn,
1867 uint64_t Address,
1868 const void *Decoder) {
1869 int Offset = SignExtend32<16>(Insn & 0xffff);
1870 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1871 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1872
1873 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1874 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1875
Jim Grosbache9119e42015-05-13 18:37:00 +00001876 Inst.addOperand(MCOperand::createReg(Reg));
1877 Inst.addOperand(MCOperand::createReg(Base));
1878 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medicdde3d582013-09-06 12:30:36 +00001879
1880 return MCDisassembler::Success;
1881}
1882
Akira Hatanaka71928e62012-04-17 18:03:21 +00001883static DecodeStatus DecodeFMem(MCInst &Inst,
1884 unsigned Insn,
1885 uint64_t Address,
1886 const void *Decoder) {
1887 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001888 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1889 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001890
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001891 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001892 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001893
Jim Grosbache9119e42015-05-13 18:37:00 +00001894 Inst.addOperand(MCOperand::createReg(Reg));
1895 Inst.addOperand(MCOperand::createReg(Base));
1896 Inst.addOperand(MCOperand::createImm(Offset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001897
1898 return MCDisassembler::Success;
1899}
1900
Zlatko Buljancba9f802016-07-11 07:41:56 +00001901static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn,
1902 uint64_t Address, const void *Decoder) {
1903 // This function is the same as DecodeFMem but with the Reg and Base fields
1904 // swapped according to microMIPS spec.
1905 int Offset = SignExtend32<16>(Insn & 0xffff);
1906 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1907 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1908
1909 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
1910 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1911
1912 Inst.addOperand(MCOperand::createReg(Reg));
1913 Inst.addOperand(MCOperand::createReg(Base));
1914 Inst.addOperand(MCOperand::createImm(Offset));
1915
1916 return MCDisassembler::Success;
1917}
1918
Daniel Sanders92db6b72014-10-01 08:26:55 +00001919static DecodeStatus DecodeFMem2(MCInst &Inst,
1920 unsigned Insn,
1921 uint64_t Address,
1922 const void *Decoder) {
1923 int Offset = SignExtend32<16>(Insn & 0xffff);
1924 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1925 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1926
1927 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1928 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1929
Jim Grosbache9119e42015-05-13 18:37:00 +00001930 Inst.addOperand(MCOperand::createReg(Reg));
1931 Inst.addOperand(MCOperand::createReg(Base));
1932 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001933
1934 return MCDisassembler::Success;
1935}
1936
1937static DecodeStatus DecodeFMem3(MCInst &Inst,
1938 unsigned Insn,
1939 uint64_t Address,
1940 const void *Decoder) {
1941 int Offset = SignExtend32<16>(Insn & 0xffff);
1942 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1943 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1944
1945 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1946 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1947
Jim Grosbache9119e42015-05-13 18:37:00 +00001948 Inst.addOperand(MCOperand::createReg(Reg));
1949 Inst.addOperand(MCOperand::createReg(Base));
1950 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders92db6b72014-10-01 08:26:55 +00001951
1952 return MCDisassembler::Success;
1953}
1954
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001955static DecodeStatus DecodeFMemCop2R6(MCInst &Inst,
1956 unsigned Insn,
1957 uint64_t Address,
1958 const void *Decoder) {
1959 int Offset = SignExtend32<11>(Insn & 0x07ff);
1960 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1961 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1962
1963 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1964 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1965
Jim Grosbache9119e42015-05-13 18:37:00 +00001966 Inst.addOperand(MCOperand::createReg(Reg));
1967 Inst.addOperand(MCOperand::createReg(Base));
1968 Inst.addOperand(MCOperand::createImm(Offset));
Vladimir Medic435cf8a2015-01-21 10:47:36 +00001969
1970 return MCDisassembler::Success;
1971}
Zlatko Buljancba9f802016-07-11 07:41:56 +00001972
1973static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn,
1974 uint64_t Address, const void *Decoder) {
1975 int Offset = SignExtend32<11>(Insn & 0x07ff);
1976 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1977 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1978
1979 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1980 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1981
1982 Inst.addOperand(MCOperand::createReg(Reg));
1983 Inst.addOperand(MCOperand::createReg(Base));
1984 Inst.addOperand(MCOperand::createImm(Offset));
1985
1986 return MCDisassembler::Success;
1987}
1988
Daniel Sanders6a803f62014-06-16 13:13:03 +00001989static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1990 unsigned Insn,
1991 uint64_t Address,
1992 const void *Decoder) {
1993 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1994 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1995 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1996
1997 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1998 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1999
2000 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
Jim Grosbache9119e42015-05-13 18:37:00 +00002001 Inst.addOperand(MCOperand::createReg(Rt));
Daniel Sanders6a803f62014-06-16 13:13:03 +00002002 }
2003
Jim Grosbache9119e42015-05-13 18:37:00 +00002004 Inst.addOperand(MCOperand::createReg(Rt));
2005 Inst.addOperand(MCOperand::createReg(Base));
2006 Inst.addOperand(MCOperand::createImm(Offset));
Daniel Sanders6a803f62014-06-16 13:13:03 +00002007
2008 return MCDisassembler::Success;
2009}
Akira Hatanaka71928e62012-04-17 18:03:21 +00002010
2011static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
2012 unsigned RegNo,
2013 uint64_t Address,
2014 const void *Decoder) {
2015 // Currently only hardware register 29 is supported.
2016 if (RegNo != 29)
2017 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +00002018 Inst.addOperand(MCOperand::createReg(Mips::HWR29));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002019 return MCDisassembler::Success;
2020}
2021
Akira Hatanaka71928e62012-04-17 18:03:21 +00002022static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
2023 unsigned RegNo,
2024 uint64_t Address,
2025 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00002026 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00002027 return MCDisassembler::Fail;
2028
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00002029 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
Jim Grosbache9119e42015-05-13 18:37:00 +00002030 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002031 return MCDisassembler::Success;
2032}
2033
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00002034static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
2035 unsigned RegNo,
2036 uint64_t Address,
2037 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00002038 if (RegNo >= 4)
2039 return MCDisassembler::Fail;
2040
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00002041 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002042 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00002043 return MCDisassembler::Success;
2044}
2045
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002046static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
2047 unsigned RegNo,
2048 uint64_t Address,
2049 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002050 if (RegNo >= 4)
2051 return MCDisassembler::Fail;
2052
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002053 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002054 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002055 return MCDisassembler::Success;
2056}
2057
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002058static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
2059 unsigned RegNo,
2060 uint64_t Address,
2061 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002062 if (RegNo >= 4)
2063 return MCDisassembler::Fail;
2064
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00002065 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002066 Inst.addOperand(MCOperand::createReg(Reg));
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00002067 return MCDisassembler::Success;
2068}
2069
Jack Carter3eb663b2013-09-26 00:09:46 +00002070static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
2071 unsigned RegNo,
2072 uint64_t Address,
2073 const void *Decoder) {
2074 if (RegNo > 31)
2075 return MCDisassembler::Fail;
2076
2077 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002078 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter3eb663b2013-09-26 00:09:46 +00002079 return MCDisassembler::Success;
2080}
2081
Jack Carter5dc8ac92013-09-25 23:50:44 +00002082static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
2083 unsigned RegNo,
2084 uint64_t Address,
2085 const void *Decoder) {
2086 if (RegNo > 31)
2087 return MCDisassembler::Fail;
2088
2089 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002090 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002091 return MCDisassembler::Success;
2092}
2093
2094static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
2095 unsigned RegNo,
2096 uint64_t Address,
2097 const void *Decoder) {
2098 if (RegNo > 31)
2099 return MCDisassembler::Fail;
2100
2101 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002102 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002103 return MCDisassembler::Success;
2104}
2105
2106static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
2107 unsigned RegNo,
2108 uint64_t Address,
2109 const void *Decoder) {
2110 if (RegNo > 31)
2111 return MCDisassembler::Fail;
2112
2113 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002114 Inst.addOperand(MCOperand::createReg(Reg));
Jack Carter5dc8ac92013-09-25 23:50:44 +00002115 return MCDisassembler::Success;
2116}
2117
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002118static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
2119 unsigned RegNo,
2120 uint64_t Address,
2121 const void *Decoder) {
2122 if (RegNo > 7)
2123 return MCDisassembler::Fail;
2124
2125 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002126 Inst.addOperand(MCOperand::createReg(Reg));
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002127 return MCDisassembler::Success;
2128}
2129
Daniel Sandersa3134fa2015-06-27 15:39:19 +00002130static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst,
2131 unsigned RegNo,
2132 uint64_t Address,
2133 const void *Decoder) {
2134 if (RegNo > 31)
2135 return MCDisassembler::Fail;
2136
2137 unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo);
2138 Inst.addOperand(MCOperand::createReg(Reg));
2139 return MCDisassembler::Success;
2140}
2141
Daniel Sanders2a83d682014-05-21 12:56:39 +00002142static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
2143 unsigned RegNo,
2144 uint64_t Address,
2145 const void *Decoder) {
2146 if (RegNo > 31)
2147 return MCDisassembler::Fail;
2148
2149 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +00002150 Inst.addOperand(MCOperand::createReg(Reg));
Daniel Sanders2a83d682014-05-21 12:56:39 +00002151 return MCDisassembler::Success;
2152}
2153
Akira Hatanaka71928e62012-04-17 18:03:21 +00002154static DecodeStatus DecodeBranchTarget(MCInst &Inst,
2155 unsigned Offset,
2156 uint64_t Address,
2157 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00002158 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00002159 Inst.addOperand(MCOperand::createImm(BranchOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002160 return MCDisassembler::Success;
2161}
2162
Hrvoje Varga6f09cdf2016-05-13 11:32:53 +00002163static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst,
2164 unsigned Offset,
2165 uint64_t Address,
2166 const void *Decoder) {
2167 int32_t BranchOffset = (SignExtend32<16>(Offset) * 2);
2168 Inst.addOperand(MCOperand::createImm(BranchOffset));
2169 return MCDisassembler::Success;
2170}
2171
Akira Hatanaka71928e62012-04-17 18:03:21 +00002172static DecodeStatus DecodeJumpTarget(MCInst &Inst,
2173 unsigned Insn,
2174 uint64_t Address,
2175 const void *Decoder) {
Jim Grosbachecaef492012-08-14 19:06:05 +00002176 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Jim Grosbache9119e42015-05-13 18:37:00 +00002177 Inst.addOperand(MCOperand::createImm(JumpOffset));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002178 return MCDisassembler::Success;
2179}
2180
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002181static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
2182 unsigned Offset,
2183 uint64_t Address,
2184 const void *Decoder) {
Sagar Thakur672c7102016-05-24 09:57:10 +00002185 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002186
Jim Grosbache9119e42015-05-13 18:37:00 +00002187 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002188 return MCDisassembler::Success;
2189}
2190
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00002191static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst,
2192 unsigned Offset,
2193 uint64_t Address,
2194 const void *Decoder) {
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002195 int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4;
Zoran Jovanovic84e4d592016-05-17 11:10:15 +00002196
2197 Inst.addOperand(MCOperand::createImm(BranchOffset));
2198 return MCDisassembler::Success;
2199}
2200
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00002201static DecodeStatus DecodeBranchTarget26(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<26>(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
Jozef Kolek9761e962015-01-12 12:03:34 +00002211static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst,
2212 unsigned Offset,
2213 uint64_t Address,
2214 const void *Decoder) {
Simon Atanasyan72982e692017-09-20 21:01:30 +00002215 int32_t BranchOffset = SignExtend32<8>(Offset << 1);
Jim Grosbache9119e42015-05-13 18:37:00 +00002216 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek9761e962015-01-12 12:03:34 +00002217 return MCDisassembler::Success;
2218}
2219
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002220static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst,
2221 unsigned Offset,
2222 uint64_t Address,
2223 const void *Decoder) {
Simon Atanasyan72982e692017-09-20 21:01:30 +00002224 int32_t BranchOffset = SignExtend32<11>(Offset << 1);
Jim Grosbache9119e42015-05-13 18:37:00 +00002225 Inst.addOperand(MCOperand::createImm(BranchOffset));
Jozef Kolek5cfebdd2015-01-21 12:39:30 +00002226 return MCDisassembler::Success;
2227}
2228
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002229static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
2230 unsigned Offset,
2231 uint64_t Address,
2232 const void *Decoder) {
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002233 int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4;
Jim Grosbache9119e42015-05-13 18:37:00 +00002234 Inst.addOperand(MCOperand::createImm(BranchOffset));
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00002235 return MCDisassembler::Success;
2236}
2237
Zoran Jovanovica887b362015-11-30 12:56:18 +00002238static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
2239 unsigned Offset,
2240 uint64_t Address,
2241 const void *Decoder) {
Simon Atanasyan72982e692017-09-20 21:01:30 +00002242 int32_t BranchOffset = SignExtend32<27>(Offset << 1);
Zoran Jovanovica887b362015-11-30 12:56:18 +00002243
2244 Inst.addOperand(MCOperand::createImm(BranchOffset));
2245 return MCDisassembler::Success;
2246}
2247
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002248static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
2249 unsigned Insn,
2250 uint64_t Address,
2251 const void *Decoder) {
2252 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002253 Inst.addOperand(MCOperand::createImm(JumpOffset));
Zoran Jovanovic507e0842013-10-29 16:38:59 +00002254 return MCDisassembler::Success;
2255}
Akira Hatanaka71928e62012-04-17 18:03:21 +00002256
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002257static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst,
2258 unsigned Value,
2259 uint64_t Address,
2260 const void *Decoder) {
2261 if (Value == 0)
Jim Grosbache9119e42015-05-13 18:37:00 +00002262 Inst.addOperand(MCOperand::createImm(1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002263 else if (Value == 0x7)
Jim Grosbache9119e42015-05-13 18:37:00 +00002264 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002265 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002266 Inst.addOperand(MCOperand::createImm(Value << 2));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002267 return MCDisassembler::Success;
2268}
2269
Daniel Sanders97297772016-03-22 14:40:00 +00002270static DecodeStatus DecodeLi16Imm(MCInst &Inst,
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002271 unsigned Value,
2272 uint64_t Address,
2273 const void *Decoder) {
2274 if (Value == 0x7F)
Jim Grosbache9119e42015-05-13 18:37:00 +00002275 Inst.addOperand(MCOperand::createImm(-1));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002276 else
Jim Grosbache9119e42015-05-13 18:37:00 +00002277 Inst.addOperand(MCOperand::createImm(Value));
Jozef Kolekaa2b9272014-11-27 14:41:44 +00002278 return MCDisassembler::Success;
2279}
2280
Zoran Jovanovic6b28f092015-09-09 13:55:45 +00002281static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst,
2282 unsigned Value,
2283 uint64_t Address,
2284 const void *Decoder) {
2285 Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value));
2286 return MCDisassembler::Success;
2287}
2288
Daniel Sanders19b7f762016-03-14 11:16:56 +00002289template <unsigned Bits, int Offset, int Scale>
2290static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2291 uint64_t Address,
2292 const void *Decoder) {
Daniel Sandersea4f6532015-11-06 12:22:31 +00002293 Value &= ((1 << Bits) - 1);
Daniel Sanders19b7f762016-03-14 11:16:56 +00002294 Value *= Scale;
Daniel Sandersea4f6532015-11-06 12:22:31 +00002295 Inst.addOperand(MCOperand::createImm(Value + Offset));
Matheus Almeida779c5932013-11-18 12:32:49 +00002296 return MCDisassembler::Success;
2297}
2298
Daniel Sanders97297772016-03-22 14:40:00 +00002299template <unsigned Bits, int Offset, int ScaleBy>
2300static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value,
2301 uint64_t Address,
2302 const void *Decoder) {
2303 int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy;
Daniel Sanders78e89022016-03-11 11:37:50 +00002304 Inst.addOperand(MCOperand::createImm(Imm + Offset));
2305 return MCDisassembler::Success;
2306}
2307
Akira Hatanaka71928e62012-04-17 18:03:21 +00002308static DecodeStatus DecodeInsSize(MCInst &Inst,
2309 unsigned Insn,
2310 uint64_t Address,
2311 const void *Decoder) {
2312 // First we need to grab the pos(lsb) from MCInst.
Simon Dardis6f83ae32017-09-14 15:17:50 +00002313 // This function only handles the 32 bit variants of ins, as dins
2314 // variants are handled differently.
Akira Hatanaka71928e62012-04-17 18:03:21 +00002315 int Pos = Inst.getOperand(2).getImm();
Simon Dardis6f83ae32017-09-14 15:17:50 +00002316 int Size = (int) Insn - Pos + 1;
Jim Grosbache9119e42015-05-13 18:37:00 +00002317 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size)));
Akira Hatanaka71928e62012-04-17 18:03:21 +00002318 return MCDisassembler::Success;
2319}
2320
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002321static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
2322 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002323 Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00002324 return MCDisassembler::Success;
2325}
Zoran Jovanovic28551422014-06-09 09:49:51 +00002326
2327static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
2328 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +00002329 Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00002330 return MCDisassembler::Success;
2331}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002332
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002333static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn,
2334 uint64_t Address, const void *Decoder) {
2335 int32_t DecodedValue;
2336 switch (Insn) {
2337 case 0: DecodedValue = 256; break;
2338 case 1: DecodedValue = 257; break;
2339 case 510: DecodedValue = -258; break;
2340 case 511: DecodedValue = -257; break;
2341 default: DecodedValue = SignExtend32<9>(Insn); break;
2342 }
Jim Grosbache9119e42015-05-13 18:37:00 +00002343 Inst.addOperand(MCOperand::createImm(DecodedValue * 4));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002344 return MCDisassembler::Success;
2345}
2346
2347static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn,
2348 uint64_t Address, const void *Decoder) {
2349 // Insn must be >= 0, since it is unsigned that condition is always true.
2350 assert(Insn < 16);
2351 int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64,
2352 255, 32768, 65535};
Jim Grosbache9119e42015-05-13 18:37:00 +00002353 Inst.addOperand(MCOperand::createImm(DecodedValues[Insn]));
Vladimir Medicb682ddf2014-12-01 11:12:04 +00002354 return MCDisassembler::Success;
2355}
2356
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002357static DecodeStatus DecodeRegListOperand(MCInst &Inst,
2358 unsigned Insn,
2359 uint64_t Address,
2360 const void *Decoder) {
2361 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
Zoran Jovanovicdc4b8c22015-09-15 15:21:27 +00002362 Mips::S6, Mips::S7, Mips::FP};
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002363 unsigned RegNum;
2364
2365 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002366
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002367 // Empty register lists are not allowed.
2368 if (RegLst == 0)
2369 return MCDisassembler::Fail;
2370
2371 RegNum = RegLst & 0xf;
Daniel Sandersdf19a5e2015-09-18 14:20:54 +00002372
2373 // RegLst values 10-15, and 26-31 are reserved.
2374 if (RegNum > 9)
2375 return MCDisassembler::Fail;
2376
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002377 for (unsigned i = 0; i < RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002378 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002379
2380 if (RegLst & 0x10)
Jim Grosbache9119e42015-05-13 18:37:00 +00002381 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00002382
2383 return MCDisassembler::Success;
2384}
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002385
2386static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
2387 uint64_t Address,
2388 const void *Decoder) {
2389 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3};
Zlatko Buljan797c2ae2015-11-12 13:21:33 +00002390 unsigned RegLst;
2391 switch(Inst.getOpcode()) {
2392 default:
2393 RegLst = fieldFromInstruction(Insn, 4, 2);
2394 break;
2395 case Mips::LWM16_MMR6:
2396 case Mips::SWM16_MMR6:
2397 RegLst = fieldFromInstruction(Insn, 8, 2);
2398 break;
2399 }
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002400 unsigned RegNum = RegLst & 0x3;
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002401
Jozef Kolekd68d424a2015-02-10 12:41:13 +00002402 for (unsigned i = 0; i <= RegNum; i++)
Jim Grosbache9119e42015-05-13 18:37:00 +00002403 Inst.addOperand(MCOperand::createReg(Regs[i]));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002404
Jim Grosbache9119e42015-05-13 18:37:00 +00002405 Inst.addOperand(MCOperand::createReg(Mips::RA));
Zoran Jovanovicf9a02502014-11-27 18:28:59 +00002406
2407 return MCDisassembler::Success;
2408}
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002409
Simon Dardis169df4e2017-11-06 12:59:53 +00002410static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair,
Zoran Jovanovic41688672015-02-10 16:36:20 +00002411 uint64_t Address, const void *Decoder) {
Zoran Jovanovic41688672015-02-10 16:36:20 +00002412 switch (RegPair) {
2413 default:
2414 return MCDisassembler::Fail;
2415 case 0:
Jim Grosbache9119e42015-05-13 18:37:00 +00002416 Inst.addOperand(MCOperand::createReg(Mips::A1));
2417 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002418 break;
2419 case 1:
Jim Grosbache9119e42015-05-13 18:37:00 +00002420 Inst.addOperand(MCOperand::createReg(Mips::A1));
2421 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002422 break;
2423 case 2:
Jim Grosbache9119e42015-05-13 18:37:00 +00002424 Inst.addOperand(MCOperand::createReg(Mips::A2));
2425 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002426 break;
2427 case 3:
Jim Grosbache9119e42015-05-13 18:37:00 +00002428 Inst.addOperand(MCOperand::createReg(Mips::A0));
2429 Inst.addOperand(MCOperand::createReg(Mips::S5));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002430 break;
2431 case 4:
Jim Grosbache9119e42015-05-13 18:37:00 +00002432 Inst.addOperand(MCOperand::createReg(Mips::A0));
2433 Inst.addOperand(MCOperand::createReg(Mips::S6));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002434 break;
2435 case 5:
Jim Grosbache9119e42015-05-13 18:37:00 +00002436 Inst.addOperand(MCOperand::createReg(Mips::A0));
2437 Inst.addOperand(MCOperand::createReg(Mips::A1));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002438 break;
2439 case 6:
Jim Grosbache9119e42015-05-13 18:37:00 +00002440 Inst.addOperand(MCOperand::createReg(Mips::A0));
2441 Inst.addOperand(MCOperand::createReg(Mips::A2));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002442 break;
2443 case 7:
Jim Grosbache9119e42015-05-13 18:37:00 +00002444 Inst.addOperand(MCOperand::createReg(Mips::A0));
2445 Inst.addOperand(MCOperand::createReg(Mips::A3));
Zoran Jovanovic41688672015-02-10 16:36:20 +00002446 break;
2447 }
2448
2449 return MCDisassembler::Success;
2450}
2451
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002452static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
2453 uint64_t Address, const void *Decoder) {
Justin Bogner6499b5f2015-06-23 07:28:57 +00002454 Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2)));
Jozef Kolek2c6d7322015-01-21 12:10:11 +00002455 return MCDisassembler::Success;
2456}
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002457
2458template <typename InsnType>
2459static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn,
2460 uint64_t Address,
2461 const void *Decoder) {
2462 // We have:
2463 // 0b000111 ttttt sssss iiiiiiiiiiiiiiii
2464 // Invalid if rt == 0
2465 // BGTZALC_MMR6 if rs == 0 && rt != 0
2466 // BLTZALC_MMR6 if rs != 0 && rs == rt
2467 // BLTUC_MMR6 if rs != 0 && rs != rt
2468
2469 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2470 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002471 InsnType Imm = 0;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002472 bool HasRs = false;
2473 bool HasRt = false;
2474
2475 if (Rt == 0)
2476 return MCDisassembler::Fail;
2477 else if (Rs == 0) {
2478 MI.setOpcode(Mips::BGTZALC_MMR6);
2479 HasRt = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002480 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002481 }
2482 else if (Rs == Rt) {
2483 MI.setOpcode(Mips::BLTZALC_MMR6);
2484 HasRs = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002485 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002486 }
2487 else {
2488 MI.setOpcode(Mips::BLTUC_MMR6);
2489 HasRs = true;
2490 HasRt = true;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002491 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002492 }
2493
2494 if (HasRs)
2495 MI.addOperand(
2496 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2497
2498 if (HasRt)
2499 MI.addOperand(
2500 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2501
2502 MI.addOperand(MCOperand::createImm(Imm));
2503
2504 return MCDisassembler::Success;
2505}
2506
2507template <typename InsnType>
2508static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn,
2509 uint64_t Address,
2510 const void *Decoder) {
2511 // We have:
2512 // 0b000110 ttttt sssss iiiiiiiiiiiiiiii
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002513 // Invalid if rt == 0
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002514 // BLEZALC_MMR6 if rs == 0 && rt != 0
2515 // BGEZALC_MMR6 if rs == rt && rt != 0
2516 // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0
2517
2518 InsnType Rt = fieldFromInstruction(insn, 21, 5);
2519 InsnType Rs = fieldFromInstruction(insn, 16, 5);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002520 InsnType Imm = 0;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002521 bool HasRs = false;
2522
2523 if (Rt == 0)
2524 return MCDisassembler::Fail;
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002525 else if (Rs == 0) {
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002526 MI.setOpcode(Mips::BLEZALC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002527 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2528 }
2529 else if (Rs == Rt) {
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002530 MI.setOpcode(Mips::BGEZALC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002531 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4;
2532 }
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002533 else {
2534 HasRs = true;
2535 MI.setOpcode(Mips::BGEUC_MMR6);
Hrvoje Vargaf0ed16e2016-08-22 12:17:59 +00002536 Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4;
Zoran Jovanovicfdbd0a32016-04-20 14:07:46 +00002537 }
2538
2539 if (HasRs)
2540 MI.addOperand(
2541 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs)));
2542 MI.addOperand(
2543 MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt)));
2544
2545 MI.addOperand(MCOperand::createImm(Imm));
2546
2547 return MCDisassembler::Success;
2548}