blob: 8f2516330a0bac677b53f1ebde16a63da39c9e80 [file] [log] [blame]
Akira Hatanaka71928e62012-04-17 18:03:21 +00001//===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is part of the Mips Disassembler.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Mips.h"
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000015#include "MipsRegisterInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "MipsSubtarget.h"
Lang Hamesa1bc0f52014-04-15 04:40:56 +000017#include "llvm/MC/MCContext.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000018#include "llvm/MC/MCDisassembler.h"
Jim Grosbachecaef492012-08-14 19:06:05 +000019#include "llvm/MC/MCFixedLenDisassembler.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/Support/MathExtras.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000023#include "llvm/Support/TargetRegistry.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000024
Akira Hatanaka71928e62012-04-17 18:03:21 +000025using namespace llvm;
26
Chandler Carruthe96dd892014-04-21 22:55:11 +000027#define DEBUG_TYPE "mips-disassembler"
28
Akira Hatanaka71928e62012-04-17 18:03:21 +000029typedef MCDisassembler::DecodeStatus DecodeStatus;
30
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000031namespace {
32
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000033/// A disasembler class for Mips.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000034class MipsDisassemblerBase : public MCDisassembler {
Akira Hatanaka71928e62012-04-17 18:03:21 +000035public:
Lang Hamesa1bc0f52014-04-15 04:40:56 +000036 MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000037 bool IsBigEndian)
38 : MCDisassembler(STI, Ctx),
39 IsN64(STI.getFeatureBits() & Mips::FeatureN64),
40 IsBigEndian(IsBigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000041
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000042 virtual ~MipsDisassemblerBase() {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000043
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000044 bool isN64() const { return IsN64; }
45
Akira Hatanaka71928e62012-04-17 18:03:21 +000046private:
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000047 bool IsN64;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000048protected:
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000049 bool IsBigEndian;
Akira Hatanaka71928e62012-04-17 18:03:21 +000050};
51
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000052/// A disasembler class for Mips32.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000053class MipsDisassembler : public MipsDisassemblerBase {
Vladimir Medicdde3d582013-09-06 12:30:36 +000054 bool IsMicroMips;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000055public:
Daniel Sandersc171f652014-06-13 13:15:59 +000056 MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian)
57 : MipsDisassemblerBase(STI, Ctx, bigEndian) {
58 IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
59 }
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000060
Daniel Sandersc171f652014-06-13 13:15:59 +000061 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
62 bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; }
63 bool hasMips32r6() const {
Daniel Sanders5c582b22014-05-22 11:23:21 +000064 return STI.getFeatureBits() & Mips::FeatureMips32r6;
65 }
66
Daniel Sanders0fa60412014-06-12 13:39:06 +000067 bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
68
Daniel Sandersc171f652014-06-13 13:15:59 +000069 bool hasCOP3() const {
70 // Only present in MIPS-I and MIPS-II
71 return !hasMips32() && !hasMips3();
72 }
73
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000074 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000075 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000076 raw_ostream &VStream,
77 raw_ostream &CStream) const override;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000078};
79
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000080/// A disasembler class for Mips64.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000081class Mips64Disassembler : public MipsDisassemblerBase {
Akira Hatanaka71928e62012-04-17 18:03:21 +000082public:
Lang Hamesa1bc0f52014-04-15 04:40:56 +000083 Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000084 bool bigEndian) :
Lang Hamesa1bc0f52014-04-15 04:40:56 +000085 MipsDisassemblerBase(STI, Ctx, bigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000086
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000087 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000088 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000089 raw_ostream &VStream,
90 raw_ostream &CStream) const override;
Akira Hatanaka71928e62012-04-17 18:03:21 +000091};
92
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000093} // end anonymous namespace
94
Akira Hatanaka71928e62012-04-17 18:03:21 +000095// Forward declare these because the autogenerated code will reference them.
96// Definitions are further down.
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000097static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
98 unsigned RegNo,
99 uint64_t Address,
100 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000101
Reed Kotlerec8a5492013-02-14 03:05:25 +0000102static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
103 unsigned RegNo,
104 uint64_t Address,
105 const void *Decoder);
106
Zoran Jovanovicb0852e52014-10-21 08:23:11 +0000107static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
108 unsigned RegNo,
109 uint64_t Address,
110 const void *Decoder);
111
Jozef Kolek1904fa22014-11-24 14:25:53 +0000112static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
113 unsigned RegNo,
114 uint64_t Address,
115 const void *Decoder);
116
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000117static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
118 unsigned RegNo,
119 uint64_t Address,
120 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000121
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000122static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
123 unsigned Insn,
124 uint64_t Address,
125 const void *Decoder);
126
Akira Hatanaka654655f2013-08-14 00:53:38 +0000127static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
128 unsigned RegNo,
129 uint64_t Address,
130 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000131
Akira Hatanaka71928e62012-04-17 18:03:21 +0000132static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
133 unsigned RegNo,
134 uint64_t Address,
135 const void *Decoder);
136
137static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
138 unsigned RegNo,
139 uint64_t Address,
140 const void *Decoder);
141
142static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
143 unsigned RegNo,
144 uint64_t Address,
145 const void *Decoder);
146
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000147static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
148 unsigned RegNo,
149 uint64_t Address,
150 const void *Decoder);
151
Daniel Sanders0fa60412014-06-12 13:39:06 +0000152static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
153 uint64_t Address,
154 const void *Decoder);
155
Akira Hatanaka71928e62012-04-17 18:03:21 +0000156static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
157 unsigned Insn,
158 uint64_t Address,
159 const void *Decoder);
160
161static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
162 unsigned RegNo,
163 uint64_t Address,
164 const void *Decoder);
165
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000166static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
167 unsigned RegNo,
168 uint64_t Address,
169 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000170
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000171static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
172 unsigned RegNo,
173 uint64_t Address,
174 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000175
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000176static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
177 unsigned RegNo,
178 uint64_t Address,
179 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000180
Jack Carter3eb663b2013-09-26 00:09:46 +0000181static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
182 unsigned RegNo,
183 uint64_t Address,
184 const void *Decoder);
185
Jack Carter5dc8ac92013-09-25 23:50:44 +0000186static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
187 unsigned RegNo,
188 uint64_t Address,
189 const void *Decoder);
190
191static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
192 unsigned RegNo,
193 uint64_t Address,
194 const void *Decoder);
195
196static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
197 unsigned RegNo,
198 uint64_t Address,
199 const void *Decoder);
200
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000201static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
202 unsigned RegNo,
203 uint64_t Address,
204 const void *Decoder);
205
Daniel Sanders2a83d682014-05-21 12:56:39 +0000206static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
207 unsigned RegNo,
208 uint64_t Address,
209 const void *Decoder);
210
Akira Hatanaka71928e62012-04-17 18:03:21 +0000211static DecodeStatus DecodeBranchTarget(MCInst &Inst,
212 unsigned Offset,
213 uint64_t Address,
214 const void *Decoder);
215
Akira Hatanaka71928e62012-04-17 18:03:21 +0000216static DecodeStatus DecodeJumpTarget(MCInst &Inst,
217 unsigned Insn,
218 uint64_t Address,
219 const void *Decoder);
220
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000221static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
222 unsigned Offset,
223 uint64_t Address,
224 const void *Decoder);
225
226static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
227 unsigned Offset,
228 uint64_t Address,
229 const void *Decoder);
230
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000231// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
232// shifted left by 1 bit.
233static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
234 unsigned Offset,
235 uint64_t Address,
236 const void *Decoder);
237
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000238// DecodeJumpTargetMM - Decode microMIPS jump target, which is
239// shifted left by 1 bit.
240static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
241 unsigned Insn,
242 uint64_t Address,
243 const void *Decoder);
244
Akira Hatanaka71928e62012-04-17 18:03:21 +0000245static DecodeStatus DecodeMem(MCInst &Inst,
246 unsigned Insn,
247 uint64_t Address,
248 const void *Decoder);
249
Daniel Sanders92db6b72014-10-01 08:26:55 +0000250static DecodeStatus DecodeCacheOp(MCInst &Inst,
251 unsigned Insn,
252 uint64_t Address,
253 const void *Decoder);
254
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000255static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
256 uint64_t Address, const void *Decoder);
257
Vladimir Medicdde3d582013-09-06 12:30:36 +0000258static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
259 unsigned Insn,
260 uint64_t Address,
261 const void *Decoder);
262
263static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
264 unsigned Insn,
265 uint64_t Address,
266 const void *Decoder);
267
Akira Hatanaka71928e62012-04-17 18:03:21 +0000268static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
269 uint64_t Address,
270 const void *Decoder);
271
Daniel Sanders92db6b72014-10-01 08:26:55 +0000272static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn,
273 uint64_t Address,
274 const void *Decoder);
275
276static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn,
277 uint64_t Address,
278 const void *Decoder);
279
Daniel Sanders6a803f62014-06-16 13:13:03 +0000280static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
281 unsigned Insn,
282 uint64_t Address,
283 const void *Decoder);
284
Akira Hatanaka71928e62012-04-17 18:03:21 +0000285static DecodeStatus DecodeSimm16(MCInst &Inst,
286 unsigned Insn,
287 uint64_t Address,
288 const void *Decoder);
289
Matheus Almeida779c5932013-11-18 12:32:49 +0000290// Decode the immediate field of an LSA instruction which
291// is off by one.
292static DecodeStatus DecodeLSAImm(MCInst &Inst,
293 unsigned Insn,
294 uint64_t Address,
295 const void *Decoder);
296
Akira Hatanaka71928e62012-04-17 18:03:21 +0000297static DecodeStatus DecodeInsSize(MCInst &Inst,
298 unsigned Insn,
299 uint64_t Address,
300 const void *Decoder);
301
302static DecodeStatus DecodeExtSize(MCInst &Inst,
303 unsigned Insn,
304 uint64_t Address,
305 const void *Decoder);
306
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000307static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
308 uint64_t Address, const void *Decoder);
309
Zoran Jovanovic28551422014-06-09 09:49:51 +0000310static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
311 uint64_t Address, const void *Decoder);
312
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000313/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
314/// handle.
315template <typename InsnType>
316static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
317 const void *Decoder);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000318
319template <typename InsnType>
320static DecodeStatus
321DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
322 const void *Decoder);
323
324template <typename InsnType>
325static DecodeStatus
326DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
327 const void *Decoder);
328
329template <typename InsnType>
330static DecodeStatus
331DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
332 const void *Decoder);
333
334template <typename InsnType>
335static DecodeStatus
336DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
337 const void *Decoder);
338
339template <typename InsnType>
340static DecodeStatus
341DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
342 const void *Decoder);
343
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000344template <typename InsnType>
345static DecodeStatus
346DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
347 const void *Decoder);
348
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +0000349static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
350 uint64_t Address,
351 const void *Decoder);
352
Akira Hatanaka71928e62012-04-17 18:03:21 +0000353namespace llvm {
354extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
355 TheMips64elTarget;
356}
357
358static MCDisassembler *createMipsDisassembler(
359 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000360 const MCSubtargetInfo &STI,
361 MCContext &Ctx) {
362 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000363}
364
365static MCDisassembler *createMipselDisassembler(
366 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000367 const MCSubtargetInfo &STI,
368 MCContext &Ctx) {
369 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000370}
371
372static MCDisassembler *createMips64Disassembler(
373 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000374 const MCSubtargetInfo &STI,
375 MCContext &Ctx) {
376 return new Mips64Disassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000377}
378
379static MCDisassembler *createMips64elDisassembler(
380 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000381 const MCSubtargetInfo &STI,
382 MCContext &Ctx) {
383 return new Mips64Disassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000384}
385
386extern "C" void LLVMInitializeMipsDisassembler() {
387 // Register the disassembler.
388 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
389 createMipsDisassembler);
390 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
391 createMipselDisassembler);
392 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
393 createMips64Disassembler);
394 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
395 createMips64elDisassembler);
396}
397
Akira Hatanaka71928e62012-04-17 18:03:21 +0000398#include "MipsGenDisassemblerTables.inc"
399
Daniel Sanders5c582b22014-05-22 11:23:21 +0000400static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
401 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
402 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
403 return *(RegInfo->getRegClass(RC).begin() + RegNo);
404}
405
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000406template <typename InsnType>
407static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
408 const void *Decoder) {
409 typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
410 // The size of the n field depends on the element size
411 // The register class also depends on this.
412 InsnType tmp = fieldFromInstruction(insn, 17, 5);
413 unsigned NSize = 0;
414 DecodeFN RegDecoder = nullptr;
415 if ((tmp & 0x18) == 0x00) { // INSVE_B
416 NSize = 4;
417 RegDecoder = DecodeMSA128BRegisterClass;
418 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
419 NSize = 3;
420 RegDecoder = DecodeMSA128HRegisterClass;
421 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
422 NSize = 2;
423 RegDecoder = DecodeMSA128WRegisterClass;
424 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
425 NSize = 1;
426 RegDecoder = DecodeMSA128DRegisterClass;
427 } else
428 llvm_unreachable("Invalid encoding");
429
430 assert(NSize != 0 && RegDecoder != nullptr);
431
432 // $wd
433 tmp = fieldFromInstruction(insn, 6, 5);
434 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
435 return MCDisassembler::Fail;
436 // $wd_in
437 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
438 return MCDisassembler::Fail;
439 // $n
440 tmp = fieldFromInstruction(insn, 16, NSize);
441 MI.addOperand(MCOperand::CreateImm(tmp));
442 // $ws
443 tmp = fieldFromInstruction(insn, 11, 5);
444 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
445 return MCDisassembler::Fail;
446 // $n2
447 MI.addOperand(MCOperand::CreateImm(0));
448
449 return MCDisassembler::Success;
450}
451
Daniel Sanders5c582b22014-05-22 11:23:21 +0000452template <typename InsnType>
453static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
454 uint64_t Address,
455 const void *Decoder) {
456 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
457 // (otherwise we would have matched the ADDI instruction from the earlier
458 // ISA's instead).
459 //
460 // We have:
461 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
462 // BOVC if rs >= rt
463 // BEQZALC if rs == 0 && rt != 0
464 // BEQC if rs < rt && rs != 0
465
466 InsnType Rs = fieldFromInstruction(insn, 21, 5);
467 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000468 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000469 bool HasRs = false;
470
471 if (Rs >= Rt) {
472 MI.setOpcode(Mips::BOVC);
473 HasRs = true;
474 } else if (Rs != 0 && Rs < Rt) {
475 MI.setOpcode(Mips::BEQC);
476 HasRs = true;
477 } else
478 MI.setOpcode(Mips::BEQZALC);
479
480 if (HasRs)
481 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
482 Rs)));
483
484 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
485 Rt)));
486 MI.addOperand(MCOperand::CreateImm(Imm));
487
488 return MCDisassembler::Success;
489}
490
491template <typename InsnType>
492static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
493 uint64_t Address,
494 const void *Decoder) {
495 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
496 // (otherwise we would have matched the ADDI instruction from the earlier
497 // ISA's instead).
498 //
499 // We have:
500 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
501 // BNVC if rs >= rt
502 // BNEZALC if rs == 0 && rt != 0
503 // BNEC if rs < rt && rs != 0
504
505 InsnType Rs = fieldFromInstruction(insn, 21, 5);
506 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000507 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000508 bool HasRs = false;
509
510 if (Rs >= Rt) {
511 MI.setOpcode(Mips::BNVC);
512 HasRs = true;
513 } else if (Rs != 0 && Rs < Rt) {
514 MI.setOpcode(Mips::BNEC);
515 HasRs = true;
516 } else
517 MI.setOpcode(Mips::BNEZALC);
518
519 if (HasRs)
520 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
521 Rs)));
522
523 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
524 Rt)));
525 MI.addOperand(MCOperand::CreateImm(Imm));
526
527 return MCDisassembler::Success;
528}
529
530template <typename InsnType>
531static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
532 uint64_t Address,
533 const void *Decoder) {
534 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
535 // (otherwise we would have matched the BLEZL instruction from the earlier
536 // ISA's instead).
537 //
538 // We have:
539 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
540 // Invalid if rs == 0
541 // BLEZC if rs == 0 && rt != 0
542 // BGEZC if rs == rt && rt != 0
543 // BGEC if rs != rt && rs != 0 && rt != 0
544
545 InsnType Rs = fieldFromInstruction(insn, 21, 5);
546 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000547 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000548 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000549
550 if (Rt == 0)
551 return MCDisassembler::Fail;
552 else if (Rs == 0)
553 MI.setOpcode(Mips::BLEZC);
554 else if (Rs == Rt)
555 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000556 else {
557 HasRs = true;
558 MI.setOpcode(Mips::BGEC);
559 }
560
561 if (HasRs)
562 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
563 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000564
565 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
566 Rt)));
567
568 MI.addOperand(MCOperand::CreateImm(Imm));
569
570 return MCDisassembler::Success;
571}
572
573template <typename InsnType>
574static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
575 uint64_t Address,
576 const void *Decoder) {
577 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
578 // (otherwise we would have matched the BGTZL instruction from the earlier
579 // ISA's instead).
580 //
581 // We have:
582 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
583 // Invalid if rs == 0
584 // BGTZC if rs == 0 && rt != 0
585 // BLTZC if rs == rt && rt != 0
586 // BLTC if rs != rt && rs != 0 && rt != 0
587
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000588 bool HasRs = false;
589
Daniel Sanders5c582b22014-05-22 11:23:21 +0000590 InsnType Rs = fieldFromInstruction(insn, 21, 5);
591 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000592 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000593
594 if (Rt == 0)
595 return MCDisassembler::Fail;
596 else if (Rs == 0)
597 MI.setOpcode(Mips::BGTZC);
598 else if (Rs == Rt)
599 MI.setOpcode(Mips::BLTZC);
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000600 else {
601 MI.setOpcode(Mips::BLTC);
602 HasRs = true;
603 }
604
605 if (HasRs)
606 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
607 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000608
609 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
610 Rt)));
611
612 MI.addOperand(MCOperand::CreateImm(Imm));
613
614 return MCDisassembler::Success;
615}
616
617template <typename InsnType>
618static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
619 uint64_t Address,
620 const void *Decoder) {
621 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
622 // (otherwise we would have matched the BGTZ instruction from the earlier
623 // ISA's instead).
624 //
625 // We have:
626 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
627 // BGTZ if rt == 0
628 // BGTZALC if rs == 0 && rt != 0
629 // BLTZALC if rs != 0 && rs == rt
630 // BLTUC if rs != 0 && rs != rt
631
632 InsnType Rs = fieldFromInstruction(insn, 21, 5);
633 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000634 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000635 bool HasRs = false;
636 bool HasRt = false;
637
638 if (Rt == 0) {
639 MI.setOpcode(Mips::BGTZ);
640 HasRs = true;
641 } else if (Rs == 0) {
642 MI.setOpcode(Mips::BGTZALC);
643 HasRt = true;
644 } else if (Rs == Rt) {
645 MI.setOpcode(Mips::BLTZALC);
646 HasRs = true;
Zoran Jovanovic5c14b062014-06-18 14:36:00 +0000647 } else {
648 MI.setOpcode(Mips::BLTUC);
649 HasRs = true;
650 HasRt = true;
651 }
Daniel Sanders5c582b22014-05-22 11:23:21 +0000652
653 if (HasRs)
654 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
655 Rs)));
656
657 if (HasRt)
658 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
659 Rt)));
660
661 MI.addOperand(MCOperand::CreateImm(Imm));
662
663 return MCDisassembler::Success;
664}
665
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000666template <typename InsnType>
667static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
668 uint64_t Address,
669 const void *Decoder) {
670 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
671 // (otherwise we would have matched the BLEZL instruction from the earlier
672 // ISA's instead).
673 //
674 // We have:
675 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
676 // Invalid if rs == 0
677 // BLEZALC if rs == 0 && rt != 0
678 // BGEZALC if rs == rt && rt != 0
679 // BGEUC if rs != rt && rs != 0 && rt != 0
680
681 InsnType Rs = fieldFromInstruction(insn, 21, 5);
682 InsnType Rt = fieldFromInstruction(insn, 16, 5);
Alexey Samsonovd37bab62014-09-02 17:49:16 +0000683 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000684 bool HasRs = false;
685
686 if (Rt == 0)
687 return MCDisassembler::Fail;
688 else if (Rs == 0)
689 MI.setOpcode(Mips::BLEZALC);
690 else if (Rs == Rt)
691 MI.setOpcode(Mips::BGEZALC);
692 else {
693 HasRs = true;
694 MI.setOpcode(Mips::BGEUC);
695 }
696
697 if (HasRs)
698 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
699 Rs)));
700 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
701 Rt)));
702
703 MI.addOperand(MCOperand::CreateImm(Imm));
704
705 return MCDisassembler::Success;
706}
707
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000708/// Read two bytes from the ArrayRef and return 16 bit halfword sorted
709/// according to the given endianess.
710static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
711 uint64_t &Size, uint32_t &Insn,
712 bool IsBigEndian) {
713 // We want to read exactly 2 Bytes of data.
714 if (Bytes.size() < 2) {
715 Size = 0;
716 return MCDisassembler::Fail;
717 }
718
719 if (IsBigEndian) {
720 Insn = (Bytes[0] << 8) | Bytes[1];
721 } else {
722 Insn = (Bytes[1] << 8) | Bytes[0];
723 }
724
725 return MCDisassembler::Success;
726}
727
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000728/// Read four bytes from the ArrayRef and return 32 bit word sorted
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000729/// according to the given endianess
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000730static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
731 uint64_t &Size, uint32_t &Insn,
732 bool IsBigEndian, bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000733 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000734 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000735 Size = 0;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000736 return MCDisassembler::Fail;
737 }
738
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000739 // High 16 bits of a 32-bit microMIPS instruction (where the opcode is)
740 // always precede the low 16 bits in the instruction stream (that is, they
741 // are placed at lower addresses in the instruction stream).
742 //
743 // microMIPS byte ordering:
744 // Big-endian: 0 | 1 | 2 | 3
745 // Little-endian: 1 | 0 | 3 | 2
746
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000747 if (IsBigEndian) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000748 // Encoded as a big-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000749 Insn =
750 (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24);
751 } else {
Vladimir Medicdde3d582013-09-06 12:30:36 +0000752 if (IsMicroMips) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000753 Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000754 (Bytes[1] << 24);
755 } else {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000756 Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
Vladimir Medicdde3d582013-09-06 12:30:36 +0000757 (Bytes[3] << 24);
758 }
Akira Hatanaka71928e62012-04-17 18:03:21 +0000759 }
760
761 return MCDisassembler::Success;
762}
763
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000764DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000765 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000766 uint64_t Address,
767 raw_ostream &VStream,
768 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000769 uint32_t Insn;
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000770 DecodeStatus Result;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000771
Vladimir Medicdde3d582013-09-06 12:30:36 +0000772 if (IsMicroMips) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000773 Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian);
774
775 DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n");
776 // Calling the auto-generated decoder function.
777 Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,
778 this, STI);
779 if (Result != MCDisassembler::Fail) {
780 Size = 2;
781 return Result;
782 }
783
784 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true);
785 if (Result == MCDisassembler::Fail)
786 return MCDisassembler::Fail;
787
788 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n");
Vladimir Medicdde3d582013-09-06 12:30:36 +0000789 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000790 Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address,
Vladimir Medicdde3d582013-09-06 12:30:36 +0000791 this, STI);
792 if (Result != MCDisassembler::Fail) {
793 Size = 4;
794 return Result;
795 }
796 return MCDisassembler::Fail;
797 }
798
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000799 Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
800 if (Result == MCDisassembler::Fail)
801 return MCDisassembler::Fail;
802
Daniel Sandersc171f652014-06-13 13:15:59 +0000803 if (hasCOP3()) {
804 DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n");
805 Result =
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000806 decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI);
Daniel Sandersc171f652014-06-13 13:15:59 +0000807 if (Result != MCDisassembler::Fail) {
808 Size = 4;
809 return Result;
810 }
811 }
812
813 if (hasMips32r6() && isGP64()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +0000814 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000815 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn,
Daniel Sanders0fa60412014-06-12 13:39:06 +0000816 Address, this, STI);
817 if (Result != MCDisassembler::Fail) {
818 Size = 4;
819 return Result;
820 }
821 }
822
Daniel Sandersc171f652014-06-13 13:15:59 +0000823 if (hasMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +0000824 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000825 Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn,
Daniel Sanders5c582b22014-05-22 11:23:21 +0000826 Address, this, STI);
827 if (Result != MCDisassembler::Fail) {
828 Size = 4;
829 return Result;
830 }
831 }
832
Daniel Sanders0fa60412014-06-12 13:39:06 +0000833 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +0000834 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000835 Result =
836 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000837 if (Result != MCDisassembler::Fail) {
838 Size = 4;
839 return Result;
840 }
841
842 return MCDisassembler::Fail;
843}
844
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000845DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000846 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000847 uint64_t Address,
848 raw_ostream &VStream,
849 raw_ostream &CStream) const {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000850 uint32_t Insn;
851
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000852 DecodeStatus Result =
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000853 readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000854 if (Result == MCDisassembler::Fail)
855 return MCDisassembler::Fail;
856
857 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000858 Result =
859 decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000860 if (Result != MCDisassembler::Fail) {
861 Size = 4;
862 return Result;
863 }
864 // If we fail to decode in Mips64 decoder space we can try in Mips32
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000865 Result =
866 decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000867 if (Result != MCDisassembler::Fail) {
868 Size = 4;
869 return Result;
870 }
871
872 return MCDisassembler::Fail;
873}
874
Reed Kotlerec8a5492013-02-14 03:05:25 +0000875static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
876 unsigned RegNo,
877 uint64_t Address,
878 const void *Decoder) {
879
880 return MCDisassembler::Fail;
881
882}
883
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000884static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
885 unsigned RegNo,
886 uint64_t Address,
887 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000888
889 if (RegNo > 31)
890 return MCDisassembler::Fail;
891
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000892 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000893 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000894 return MCDisassembler::Success;
895}
896
Zoran Jovanovicb0852e52014-10-21 08:23:11 +0000897static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst,
898 unsigned RegNo,
899 uint64_t Address,
900 const void *Decoder) {
Jozef Kolekea22c4c2014-11-24 13:29:59 +0000901 if (RegNo > 7)
902 return MCDisassembler::Fail;
903 unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo);
904 Inst.addOperand(MCOperand::CreateReg(Reg));
905 return MCDisassembler::Success;
Zoran Jovanovicb0852e52014-10-21 08:23:11 +0000906}
907
Jozef Kolek1904fa22014-11-24 14:25:53 +0000908static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
909 unsigned RegNo,
910 uint64_t Address,
911 const void *Decoder) {
912 return MCDisassembler::Fail;
913}
914
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000915static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
916 unsigned RegNo,
917 uint64_t Address,
918 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000919 if (RegNo > 31)
920 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000921 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000922 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000923 return MCDisassembler::Success;
924}
925
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000926static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
927 unsigned RegNo,
928 uint64_t Address,
929 const void *Decoder) {
930 if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
931 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
932
933 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
934}
935
Akira Hatanaka654655f2013-08-14 00:53:38 +0000936static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
937 unsigned RegNo,
938 uint64_t Address,
939 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000940 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000941}
942
Akira Hatanaka71928e62012-04-17 18:03:21 +0000943static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
944 unsigned RegNo,
945 uint64_t Address,
946 const void *Decoder) {
947 if (RegNo > 31)
948 return MCDisassembler::Fail;
949
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000950 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
951 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000952 return MCDisassembler::Success;
953}
954
955static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
956 unsigned RegNo,
957 uint64_t Address,
958 const void *Decoder) {
959 if (RegNo > 31)
960 return MCDisassembler::Fail;
961
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000962 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
963 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000964 return MCDisassembler::Success;
965}
966
967static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
968 unsigned RegNo,
969 uint64_t Address,
970 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +0000971 if (RegNo > 31)
972 return MCDisassembler::Fail;
973 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
974 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000975 return MCDisassembler::Success;
976}
977
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000978static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
979 unsigned RegNo,
980 uint64_t Address,
981 const void *Decoder) {
982 if (RegNo > 7)
983 return MCDisassembler::Fail;
984 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
985 Inst.addOperand(MCOperand::CreateReg(Reg));
986 return MCDisassembler::Success;
987}
988
Daniel Sanders0fa60412014-06-12 13:39:06 +0000989static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
990 uint64_t Address,
991 const void *Decoder) {
992 if (RegNo > 31)
993 return MCDisassembler::Fail;
994
995 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
996 Inst.addOperand(MCOperand::CreateReg(Reg));
997 return MCDisassembler::Success;
998}
999
Akira Hatanaka71928e62012-04-17 18:03:21 +00001000static DecodeStatus DecodeMem(MCInst &Inst,
1001 unsigned Insn,
1002 uint64_t Address,
1003 const void *Decoder) {
1004 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001005 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1006 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001007
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001008 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1009 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001010
1011 if(Inst.getOpcode() == Mips::SC){
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001012 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001013 }
1014
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001015 Inst.addOperand(MCOperand::CreateReg(Reg));
1016 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001017 Inst.addOperand(MCOperand::CreateImm(Offset));
1018
1019 return MCDisassembler::Success;
1020}
1021
Daniel Sanders92db6b72014-10-01 08:26:55 +00001022static DecodeStatus DecodeCacheOp(MCInst &Inst,
1023 unsigned Insn,
1024 uint64_t Address,
1025 const void *Decoder) {
1026 int Offset = SignExtend32<16>(Insn & 0xffff);
1027 unsigned Hint = fieldFromInstruction(Insn, 16, 5);
1028 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1029
1030 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1031
1032 Inst.addOperand(MCOperand::CreateReg(Base));
1033 Inst.addOperand(MCOperand::CreateImm(Offset));
1034 Inst.addOperand(MCOperand::CreateImm(Hint));
1035
1036 return MCDisassembler::Success;
1037}
1038
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001039static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
1040 uint64_t Address, const void *Decoder) {
1041 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
1042 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
1043 unsigned Base = fieldFromInstruction(Insn, 11, 5);
1044
1045 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
1046 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1047
1048 Inst.addOperand(MCOperand::CreateReg(Reg));
1049 Inst.addOperand(MCOperand::CreateReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001050
1051 // The immediate field of an LD/ST instruction is scaled which means it must
1052 // be multiplied (when decoding) by the size (in bytes) of the instructions'
1053 // data format.
1054 // .b - 1 byte
1055 // .h - 2 bytes
1056 // .w - 4 bytes
1057 // .d - 8 bytes
1058 switch(Inst.getOpcode())
1059 {
1060 default:
1061 assert (0 && "Unexpected instruction");
1062 return MCDisassembler::Fail;
1063 break;
1064 case Mips::LD_B:
1065 case Mips::ST_B:
1066 Inst.addOperand(MCOperand::CreateImm(Offset));
1067 break;
1068 case Mips::LD_H:
1069 case Mips::ST_H:
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001070 Inst.addOperand(MCOperand::CreateImm(Offset * 2));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001071 break;
1072 case Mips::LD_W:
1073 case Mips::ST_W:
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001074 Inst.addOperand(MCOperand::CreateImm(Offset * 4));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001075 break;
1076 case Mips::LD_D:
1077 case Mips::ST_D:
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001078 Inst.addOperand(MCOperand::CreateImm(Offset * 8));
Matheus Almeida6b59c442013-12-05 11:06:22 +00001079 break;
1080 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +00001081
1082 return MCDisassembler::Success;
1083}
1084
Vladimir Medicdde3d582013-09-06 12:30:36 +00001085static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
1086 unsigned Insn,
1087 uint64_t Address,
1088 const void *Decoder) {
1089 int Offset = SignExtend32<12>(Insn & 0x0fff);
1090 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1091 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1092
1093 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1094 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1095
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001096 switch (Inst.getOpcode()) {
1097 case Mips::SWM32_MM:
1098 case Mips::LWM32_MM:
1099 if (DecodeRegListOperand(Inst, Insn, Address, Decoder)
1100 == MCDisassembler::Fail)
1101 return MCDisassembler::Fail;
1102 Inst.addOperand(MCOperand::CreateReg(Base));
1103 Inst.addOperand(MCOperand::CreateImm(Offset));
1104 break;
1105 case Mips::SC_MM:
Zoran Jovanovic285cc282014-02-28 18:22:56 +00001106 Inst.addOperand(MCOperand::CreateReg(Reg));
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001107 // fallthrough
1108 default:
1109 Inst.addOperand(MCOperand::CreateReg(Reg));
1110 Inst.addOperand(MCOperand::CreateReg(Base));
1111 Inst.addOperand(MCOperand::CreateImm(Offset));
1112 }
Vladimir Medicdde3d582013-09-06 12:30:36 +00001113
1114 return MCDisassembler::Success;
1115}
1116
1117static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1118 unsigned Insn,
1119 uint64_t Address,
1120 const void *Decoder) {
1121 int Offset = SignExtend32<16>(Insn & 0xffff);
1122 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1123 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1124
1125 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1126 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1127
1128 Inst.addOperand(MCOperand::CreateReg(Reg));
1129 Inst.addOperand(MCOperand::CreateReg(Base));
1130 Inst.addOperand(MCOperand::CreateImm(Offset));
1131
1132 return MCDisassembler::Success;
1133}
1134
Akira Hatanaka71928e62012-04-17 18:03:21 +00001135static DecodeStatus DecodeFMem(MCInst &Inst,
1136 unsigned Insn,
1137 uint64_t Address,
1138 const void *Decoder) {
1139 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001140 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1141 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001142
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001143 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001144 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001145
1146 Inst.addOperand(MCOperand::CreateReg(Reg));
1147 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001148 Inst.addOperand(MCOperand::CreateImm(Offset));
1149
1150 return MCDisassembler::Success;
1151}
1152
Daniel Sanders92db6b72014-10-01 08:26:55 +00001153static DecodeStatus DecodeFMem2(MCInst &Inst,
1154 unsigned Insn,
1155 uint64_t Address,
1156 const void *Decoder) {
1157 int Offset = SignExtend32<16>(Insn & 0xffff);
1158 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1159 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1160
1161 Reg = getReg(Decoder, Mips::COP2RegClassID, Reg);
1162 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1163
1164 Inst.addOperand(MCOperand::CreateReg(Reg));
1165 Inst.addOperand(MCOperand::CreateReg(Base));
1166 Inst.addOperand(MCOperand::CreateImm(Offset));
1167
1168 return MCDisassembler::Success;
1169}
1170
1171static DecodeStatus DecodeFMem3(MCInst &Inst,
1172 unsigned Insn,
1173 uint64_t Address,
1174 const void *Decoder) {
1175 int Offset = SignExtend32<16>(Insn & 0xffff);
1176 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1177 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1178
1179 Reg = getReg(Decoder, Mips::COP3RegClassID, Reg);
1180 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1181
1182 Inst.addOperand(MCOperand::CreateReg(Reg));
1183 Inst.addOperand(MCOperand::CreateReg(Base));
1184 Inst.addOperand(MCOperand::CreateImm(Offset));
1185
1186 return MCDisassembler::Success;
1187}
1188
Daniel Sanders6a803f62014-06-16 13:13:03 +00001189static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst,
1190 unsigned Insn,
1191 uint64_t Address,
1192 const void *Decoder) {
1193 int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff);
1194 unsigned Rt = fieldFromInstruction(Insn, 16, 5);
1195 unsigned Base = fieldFromInstruction(Insn, 21, 5);
1196
1197 Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt);
1198 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1199
1200 if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){
1201 Inst.addOperand(MCOperand::CreateReg(Rt));
1202 }
1203
1204 Inst.addOperand(MCOperand::CreateReg(Rt));
1205 Inst.addOperand(MCOperand::CreateReg(Base));
1206 Inst.addOperand(MCOperand::CreateImm(Offset));
1207
1208 return MCDisassembler::Success;
1209}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001210
1211static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1212 unsigned RegNo,
1213 uint64_t Address,
1214 const void *Decoder) {
1215 // Currently only hardware register 29 is supported.
1216 if (RegNo != 29)
1217 return MCDisassembler::Fail;
1218 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
1219 return MCDisassembler::Success;
1220}
1221
Akira Hatanaka71928e62012-04-17 18:03:21 +00001222static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1223 unsigned RegNo,
1224 uint64_t Address,
1225 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001226 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001227 return MCDisassembler::Fail;
1228
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001229 ;
1230 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1231 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001232 return MCDisassembler::Success;
1233}
1234
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001235static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1236 unsigned RegNo,
1237 uint64_t Address,
1238 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001239 if (RegNo >= 4)
1240 return MCDisassembler::Fail;
1241
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001242 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001243 Inst.addOperand(MCOperand::CreateReg(Reg));
1244 return MCDisassembler::Success;
1245}
1246
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001247static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1248 unsigned RegNo,
1249 uint64_t Address,
1250 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001251 if (RegNo >= 4)
1252 return MCDisassembler::Fail;
1253
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001254 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001255 Inst.addOperand(MCOperand::CreateReg(Reg));
1256 return MCDisassembler::Success;
1257}
1258
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001259static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
1260 unsigned RegNo,
1261 uint64_t Address,
1262 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001263 if (RegNo >= 4)
1264 return MCDisassembler::Fail;
1265
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001266 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001267 Inst.addOperand(MCOperand::CreateReg(Reg));
1268 return MCDisassembler::Success;
1269}
1270
Jack Carter3eb663b2013-09-26 00:09:46 +00001271static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1272 unsigned RegNo,
1273 uint64_t Address,
1274 const void *Decoder) {
1275 if (RegNo > 31)
1276 return MCDisassembler::Fail;
1277
1278 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
1279 Inst.addOperand(MCOperand::CreateReg(Reg));
1280 return MCDisassembler::Success;
1281}
1282
Jack Carter5dc8ac92013-09-25 23:50:44 +00001283static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1284 unsigned RegNo,
1285 uint64_t Address,
1286 const void *Decoder) {
1287 if (RegNo > 31)
1288 return MCDisassembler::Fail;
1289
1290 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
1291 Inst.addOperand(MCOperand::CreateReg(Reg));
1292 return MCDisassembler::Success;
1293}
1294
1295static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1296 unsigned RegNo,
1297 uint64_t Address,
1298 const void *Decoder) {
1299 if (RegNo > 31)
1300 return MCDisassembler::Fail;
1301
1302 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
1303 Inst.addOperand(MCOperand::CreateReg(Reg));
1304 return MCDisassembler::Success;
1305}
1306
1307static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1308 unsigned RegNo,
1309 uint64_t Address,
1310 const void *Decoder) {
1311 if (RegNo > 31)
1312 return MCDisassembler::Fail;
1313
1314 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
1315 Inst.addOperand(MCOperand::CreateReg(Reg));
1316 return MCDisassembler::Success;
1317}
1318
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001319static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1320 unsigned RegNo,
1321 uint64_t Address,
1322 const void *Decoder) {
1323 if (RegNo > 7)
1324 return MCDisassembler::Fail;
1325
1326 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1327 Inst.addOperand(MCOperand::CreateReg(Reg));
1328 return MCDisassembler::Success;
1329}
1330
Daniel Sanders2a83d682014-05-21 12:56:39 +00001331static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1332 unsigned RegNo,
1333 uint64_t Address,
1334 const void *Decoder) {
1335 if (RegNo > 31)
1336 return MCDisassembler::Fail;
1337
1338 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
1339 Inst.addOperand(MCOperand::CreateReg(Reg));
1340 return MCDisassembler::Success;
1341}
1342
Akira Hatanaka71928e62012-04-17 18:03:21 +00001343static DecodeStatus DecodeBranchTarget(MCInst &Inst,
1344 unsigned Offset,
1345 uint64_t Address,
1346 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001347 int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001348 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1349 return MCDisassembler::Success;
1350}
1351
Akira Hatanaka71928e62012-04-17 18:03:21 +00001352static DecodeStatus DecodeJumpTarget(MCInst &Inst,
1353 unsigned Insn,
1354 uint64_t Address,
1355 const void *Decoder) {
1356
Jim Grosbachecaef492012-08-14 19:06:05 +00001357 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001358 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1359 return MCDisassembler::Success;
1360}
1361
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001362static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
1363 unsigned Offset,
1364 uint64_t Address,
1365 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001366 int32_t BranchOffset = SignExtend32<21>(Offset) * 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001367
1368 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1369 return MCDisassembler::Success;
1370}
1371
1372static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
1373 unsigned Offset,
1374 uint64_t Address,
1375 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001376 int32_t BranchOffset = SignExtend32<26>(Offset) * 4;
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001377
1378 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1379 return MCDisassembler::Success;
1380}
1381
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001382static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
1383 unsigned Offset,
1384 uint64_t Address,
1385 const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001386 int32_t BranchOffset = SignExtend32<16>(Offset) * 2;
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001387 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1388 return MCDisassembler::Success;
1389}
1390
Zoran Jovanovic507e0842013-10-29 16:38:59 +00001391static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1392 unsigned Insn,
1393 uint64_t Address,
1394 const void *Decoder) {
1395 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1396 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1397 return MCDisassembler::Success;
1398}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001399
1400static DecodeStatus DecodeSimm16(MCInst &Inst,
1401 unsigned Insn,
1402 uint64_t Address,
1403 const void *Decoder) {
1404 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
1405 return MCDisassembler::Success;
1406}
1407
Matheus Almeida779c5932013-11-18 12:32:49 +00001408static DecodeStatus DecodeLSAImm(MCInst &Inst,
1409 unsigned Insn,
1410 uint64_t Address,
1411 const void *Decoder) {
1412 // We add one to the immediate field as it was encoded as 'imm - 1'.
1413 Inst.addOperand(MCOperand::CreateImm(Insn + 1));
1414 return MCDisassembler::Success;
1415}
1416
Akira Hatanaka71928e62012-04-17 18:03:21 +00001417static DecodeStatus DecodeInsSize(MCInst &Inst,
1418 unsigned Insn,
1419 uint64_t Address,
1420 const void *Decoder) {
1421 // First we need to grab the pos(lsb) from MCInst.
1422 int Pos = Inst.getOperand(2).getImm();
1423 int Size = (int) Insn - Pos + 1;
1424 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
1425 return MCDisassembler::Success;
1426}
1427
1428static DecodeStatus DecodeExtSize(MCInst &Inst,
1429 unsigned Insn,
1430 uint64_t Address,
1431 const void *Decoder) {
1432 int Size = (int) Insn + 1;
1433 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
1434 return MCDisassembler::Success;
1435}
Daniel Sandersb59e1a42014-05-15 10:45:58 +00001436
1437static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1438 uint64_t Address, const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001439 Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4));
Daniel Sandersb59e1a42014-05-15 10:45:58 +00001440 return MCDisassembler::Success;
1441}
Zoran Jovanovic28551422014-06-09 09:49:51 +00001442
1443static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
1444 uint64_t Address, const void *Decoder) {
Alexey Samsonovd37bab62014-09-02 17:49:16 +00001445 Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8));
Zoran Jovanovic28551422014-06-09 09:49:51 +00001446 return MCDisassembler::Success;
1447}
Zoran Jovanovica4c4b5f2014-11-19 16:44:02 +00001448
1449static DecodeStatus DecodeRegListOperand(MCInst &Inst,
1450 unsigned Insn,
1451 uint64_t Address,
1452 const void *Decoder) {
1453 unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
1454 Mips::S6, Mips::FP};
1455 unsigned RegNum;
1456
1457 unsigned RegLst = fieldFromInstruction(Insn, 21, 5);
1458 // Empty register lists are not allowed.
1459 if (RegLst == 0)
1460 return MCDisassembler::Fail;
1461
1462 RegNum = RegLst & 0xf;
1463 for (unsigned i = 0; i < RegNum; i++)
1464 Inst.addOperand(MCOperand::CreateReg(Regs[i]));
1465
1466 if (RegLst & 0x10)
1467 Inst.addOperand(MCOperand::CreateReg(Mips::RA));
1468
1469 return MCDisassembler::Success;
1470}