blob: 0389d848ade4cba7f3eab472f7b3f59d793498d3 [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/MemoryObject.h"
24#include "llvm/Support/TargetRegistry.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000025
Akira Hatanaka71928e62012-04-17 18:03:21 +000026using namespace llvm;
27
Chandler Carruthe96dd892014-04-21 22:55:11 +000028#define DEBUG_TYPE "mips-disassembler"
29
Akira Hatanaka71928e62012-04-17 18:03:21 +000030typedef MCDisassembler::DecodeStatus DecodeStatus;
31
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000032namespace {
33
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000034/// MipsDisassemblerBase - a disasembler class for Mips.
35class MipsDisassemblerBase : public MCDisassembler {
Akira Hatanaka71928e62012-04-17 18:03:21 +000036public:
37 /// Constructor - Initializes the disassembler.
38 ///
Lang Hamesa1bc0f52014-04-15 04:40:56 +000039 MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx,
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000040 bool bigEndian) :
Lang Hamesa1bc0f52014-04-15 04:40:56 +000041 MCDisassembler(STI, Ctx),
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000042 IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000043
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000044 virtual ~MipsDisassemblerBase() {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000045
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000046 bool isN64() const { return IsN64; }
47
Akira Hatanaka71928e62012-04-17 18:03:21 +000048private:
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000049 bool IsN64;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000050protected:
Akira Hatanaka71928e62012-04-17 18:03:21 +000051 bool isBigEndian;
52};
53
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000054/// MipsDisassembler - a disasembler class for Mips32.
55class MipsDisassembler : public MipsDisassemblerBase {
Vladimir Medicdde3d582013-09-06 12:30:36 +000056 bool IsMicroMips;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000057public:
58 /// Constructor - Initializes the disassembler.
59 ///
Lang Hamesa1bc0f52014-04-15 04:40:56 +000060 MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000061 bool bigEndian) :
Lang Hamesa1bc0f52014-04-15 04:40:56 +000062 MipsDisassemblerBase(STI, Ctx, bigEndian) {
Vladimir Medicdde3d582013-09-06 12:30:36 +000063 IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
64 }
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000065
Daniel Sanders5c582b22014-05-22 11:23:21 +000066 bool isMips32r6() const {
67 return STI.getFeatureBits() & Mips::FeatureMips32r6;
68 }
69
Daniel Sanders0fa60412014-06-12 13:39:06 +000070 bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
71
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000072 /// getInstruction - See MCDisassembler.
Craig Topper56c590a2014-04-29 07:58:02 +000073 DecodeStatus getInstruction(MCInst &instr,
74 uint64_t &size,
75 const MemoryObject &region,
76 uint64_t address,
77 raw_ostream &vStream,
78 raw_ostream &cStream) const override;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000079};
80
Akira Hatanaka71928e62012-04-17 18:03:21 +000081
82/// Mips64Disassembler - a disasembler class for Mips64.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000083class Mips64Disassembler : public MipsDisassemblerBase {
Akira Hatanaka71928e62012-04-17 18:03:21 +000084public:
85 /// Constructor - Initializes the disassembler.
86 ///
Lang Hamesa1bc0f52014-04-15 04:40:56 +000087 Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000088 bool bigEndian) :
Lang Hamesa1bc0f52014-04-15 04:40:56 +000089 MipsDisassemblerBase(STI, Ctx, bigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000090
91 /// getInstruction - See MCDisassembler.
Craig Topper56c590a2014-04-29 07:58:02 +000092 DecodeStatus getInstruction(MCInst &instr,
93 uint64_t &size,
94 const MemoryObject &region,
95 uint64_t address,
96 raw_ostream &vStream,
97 raw_ostream &cStream) const override;
Akira Hatanaka71928e62012-04-17 18:03:21 +000098};
99
Benjamin Kramercb3e98c2012-05-01 14:34:24 +0000100} // end anonymous namespace
101
Akira Hatanaka71928e62012-04-17 18:03:21 +0000102// Forward declare these because the autogenerated code will reference them.
103// Definitions are further down.
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000104static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
105 unsigned RegNo,
106 uint64_t Address,
107 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000108
Reed Kotlerec8a5492013-02-14 03:05:25 +0000109static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
110 unsigned RegNo,
111 uint64_t Address,
112 const void *Decoder);
113
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000114static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
115 unsigned RegNo,
116 uint64_t Address,
117 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000118
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000119static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
120 unsigned Insn,
121 uint64_t Address,
122 const void *Decoder);
123
Akira Hatanaka654655f2013-08-14 00:53:38 +0000124static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
125 unsigned RegNo,
126 uint64_t Address,
127 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000128
Akira Hatanaka71928e62012-04-17 18:03:21 +0000129static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
130 unsigned RegNo,
131 uint64_t Address,
132 const void *Decoder);
133
134static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
135 unsigned RegNo,
136 uint64_t Address,
137 const void *Decoder);
138
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000139static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
140 unsigned RegNo,
141 uint64_t Address,
142 const void *Decoder);
143
Akira Hatanaka71928e62012-04-17 18:03:21 +0000144static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
145 unsigned RegNo,
146 uint64_t Address,
147 const void *Decoder);
148
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000149static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
150 unsigned RegNo,
151 uint64_t Address,
152 const void *Decoder);
153
Daniel Sanders0fa60412014-06-12 13:39:06 +0000154static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
155 uint64_t Address,
156 const void *Decoder);
157
Akira Hatanaka71928e62012-04-17 18:03:21 +0000158static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
159 unsigned Insn,
160 uint64_t Address,
161 const void *Decoder);
162
163static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
164 unsigned RegNo,
165 uint64_t Address,
166 const void *Decoder);
167
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000168static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
169 unsigned RegNo,
170 uint64_t Address,
171 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000172
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000173static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
174 unsigned RegNo,
175 uint64_t Address,
176 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000177
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000178static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
179 unsigned RegNo,
180 uint64_t Address,
181 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000182
Jack Carter3eb663b2013-09-26 00:09:46 +0000183static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
184 unsigned RegNo,
185 uint64_t Address,
186 const void *Decoder);
187
Jack Carter5dc8ac92013-09-25 23:50:44 +0000188static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
189 unsigned RegNo,
190 uint64_t Address,
191 const void *Decoder);
192
193static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
194 unsigned RegNo,
195 uint64_t Address,
196 const void *Decoder);
197
198static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
199 unsigned RegNo,
200 uint64_t Address,
201 const void *Decoder);
202
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000203static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
204 unsigned RegNo,
205 uint64_t Address,
206 const void *Decoder);
207
Daniel Sanders2a83d682014-05-21 12:56:39 +0000208static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
209 unsigned RegNo,
210 uint64_t Address,
211 const void *Decoder);
212
Akira Hatanaka71928e62012-04-17 18:03:21 +0000213static DecodeStatus DecodeBranchTarget(MCInst &Inst,
214 unsigned Offset,
215 uint64_t Address,
216 const void *Decoder);
217
Akira Hatanaka71928e62012-04-17 18:03:21 +0000218static DecodeStatus DecodeJumpTarget(MCInst &Inst,
219 unsigned Insn,
220 uint64_t Address,
221 const void *Decoder);
222
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +0000223static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
224 unsigned Offset,
225 uint64_t Address,
226 const void *Decoder);
227
228static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
229 unsigned Offset,
230 uint64_t Address,
231 const void *Decoder);
232
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +0000233// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
234// shifted left by 1 bit.
235static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
236 unsigned Offset,
237 uint64_t Address,
238 const void *Decoder);
239
Zoran Jovanovic507e0842013-10-29 16:38:59 +0000240// DecodeJumpTargetMM - Decode microMIPS jump target, which is
241// shifted left by 1 bit.
242static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
243 unsigned Insn,
244 uint64_t Address,
245 const void *Decoder);
246
Akira Hatanaka71928e62012-04-17 18:03:21 +0000247static DecodeStatus DecodeMem(MCInst &Inst,
248 unsigned Insn,
249 uint64_t Address,
250 const void *Decoder);
251
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000252static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
253 uint64_t Address, const void *Decoder);
254
Vladimir Medicdde3d582013-09-06 12:30:36 +0000255static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
256 unsigned Insn,
257 uint64_t Address,
258 const void *Decoder);
259
260static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
261 unsigned Insn,
262 uint64_t Address,
263 const void *Decoder);
264
Akira Hatanaka71928e62012-04-17 18:03:21 +0000265static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
266 uint64_t Address,
267 const void *Decoder);
268
269static DecodeStatus DecodeSimm16(MCInst &Inst,
270 unsigned Insn,
271 uint64_t Address,
272 const void *Decoder);
273
Matheus Almeida779c5932013-11-18 12:32:49 +0000274// Decode the immediate field of an LSA instruction which
275// is off by one.
276static DecodeStatus DecodeLSAImm(MCInst &Inst,
277 unsigned Insn,
278 uint64_t Address,
279 const void *Decoder);
280
Akira Hatanaka71928e62012-04-17 18:03:21 +0000281static DecodeStatus DecodeInsSize(MCInst &Inst,
282 unsigned Insn,
283 uint64_t Address,
284 const void *Decoder);
285
286static DecodeStatus DecodeExtSize(MCInst &Inst,
287 unsigned Insn,
288 uint64_t Address,
289 const void *Decoder);
290
Daniel Sandersb59e1a42014-05-15 10:45:58 +0000291static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
292 uint64_t Address, const void *Decoder);
293
Zoran Jovanovic28551422014-06-09 09:49:51 +0000294static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
295 uint64_t Address, const void *Decoder);
296
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000297/// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't
298/// handle.
299template <typename InsnType>
300static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
301 const void *Decoder);
Daniel Sanders5c582b22014-05-22 11:23:21 +0000302
303template <typename InsnType>
304static DecodeStatus
305DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
306 const void *Decoder);
307
308template <typename InsnType>
309static DecodeStatus
310DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
311 const void *Decoder);
312
313template <typename InsnType>
314static DecodeStatus
315DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
316 const void *Decoder);
317
318template <typename InsnType>
319static DecodeStatus
320DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
321 const void *Decoder);
322
323template <typename InsnType>
324static DecodeStatus
325DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
326 const void *Decoder);
327
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000328template <typename InsnType>
329static DecodeStatus
330DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
331 const void *Decoder);
332
Akira Hatanaka71928e62012-04-17 18:03:21 +0000333namespace llvm {
334extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
335 TheMips64elTarget;
336}
337
338static MCDisassembler *createMipsDisassembler(
339 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000340 const MCSubtargetInfo &STI,
341 MCContext &Ctx) {
342 return new MipsDisassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000343}
344
345static MCDisassembler *createMipselDisassembler(
346 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000347 const MCSubtargetInfo &STI,
348 MCContext &Ctx) {
349 return new MipsDisassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000350}
351
352static MCDisassembler *createMips64Disassembler(
353 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000354 const MCSubtargetInfo &STI,
355 MCContext &Ctx) {
356 return new Mips64Disassembler(STI, Ctx, true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000357}
358
359static MCDisassembler *createMips64elDisassembler(
360 const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000361 const MCSubtargetInfo &STI,
362 MCContext &Ctx) {
363 return new Mips64Disassembler(STI, Ctx, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000364}
365
366extern "C" void LLVMInitializeMipsDisassembler() {
367 // Register the disassembler.
368 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
369 createMipsDisassembler);
370 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
371 createMipselDisassembler);
372 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
373 createMips64Disassembler);
374 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
375 createMips64elDisassembler);
376}
377
Akira Hatanaka71928e62012-04-17 18:03:21 +0000378#include "MipsGenDisassemblerTables.inc"
379
Daniel Sanders5c582b22014-05-22 11:23:21 +0000380static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
381 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
382 const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
383 return *(RegInfo->getRegClass(RC).begin() + RegNo);
384}
385
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000386template <typename InsnType>
387static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
388 const void *Decoder) {
389 typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *);
390 // The size of the n field depends on the element size
391 // The register class also depends on this.
392 InsnType tmp = fieldFromInstruction(insn, 17, 5);
393 unsigned NSize = 0;
394 DecodeFN RegDecoder = nullptr;
395 if ((tmp & 0x18) == 0x00) { // INSVE_B
396 NSize = 4;
397 RegDecoder = DecodeMSA128BRegisterClass;
398 } else if ((tmp & 0x1c) == 0x10) { // INSVE_H
399 NSize = 3;
400 RegDecoder = DecodeMSA128HRegisterClass;
401 } else if ((tmp & 0x1e) == 0x18) { // INSVE_W
402 NSize = 2;
403 RegDecoder = DecodeMSA128WRegisterClass;
404 } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D
405 NSize = 1;
406 RegDecoder = DecodeMSA128DRegisterClass;
407 } else
408 llvm_unreachable("Invalid encoding");
409
410 assert(NSize != 0 && RegDecoder != nullptr);
411
412 // $wd
413 tmp = fieldFromInstruction(insn, 6, 5);
414 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
415 return MCDisassembler::Fail;
416 // $wd_in
417 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
418 return MCDisassembler::Fail;
419 // $n
420 tmp = fieldFromInstruction(insn, 16, NSize);
421 MI.addOperand(MCOperand::CreateImm(tmp));
422 // $ws
423 tmp = fieldFromInstruction(insn, 11, 5);
424 if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail)
425 return MCDisassembler::Fail;
426 // $n2
427 MI.addOperand(MCOperand::CreateImm(0));
428
429 return MCDisassembler::Success;
430}
431
Daniel Sanders5c582b22014-05-22 11:23:21 +0000432template <typename InsnType>
433static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
434 uint64_t Address,
435 const void *Decoder) {
436 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
437 // (otherwise we would have matched the ADDI instruction from the earlier
438 // ISA's instead).
439 //
440 // We have:
441 // 0b001000 sssss ttttt iiiiiiiiiiiiiiii
442 // BOVC if rs >= rt
443 // BEQZALC if rs == 0 && rt != 0
444 // BEQC if rs < rt && rs != 0
445
446 InsnType Rs = fieldFromInstruction(insn, 21, 5);
447 InsnType Rt = fieldFromInstruction(insn, 16, 5);
448 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
449 bool HasRs = false;
450
451 if (Rs >= Rt) {
452 MI.setOpcode(Mips::BOVC);
453 HasRs = true;
454 } else if (Rs != 0 && Rs < Rt) {
455 MI.setOpcode(Mips::BEQC);
456 HasRs = true;
457 } else
458 MI.setOpcode(Mips::BEQZALC);
459
460 if (HasRs)
461 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
462 Rs)));
463
464 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
465 Rt)));
466 MI.addOperand(MCOperand::CreateImm(Imm));
467
468 return MCDisassembler::Success;
469}
470
471template <typename InsnType>
472static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
473 uint64_t Address,
474 const void *Decoder) {
475 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
476 // (otherwise we would have matched the ADDI instruction from the earlier
477 // ISA's instead).
478 //
479 // We have:
480 // 0b011000 sssss ttttt iiiiiiiiiiiiiiii
481 // BNVC if rs >= rt
482 // BNEZALC if rs == 0 && rt != 0
483 // BNEC if rs < rt && rs != 0
484
485 InsnType Rs = fieldFromInstruction(insn, 21, 5);
486 InsnType Rt = fieldFromInstruction(insn, 16, 5);
487 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
488 bool HasRs = false;
489
490 if (Rs >= Rt) {
491 MI.setOpcode(Mips::BNVC);
492 HasRs = true;
493 } else if (Rs != 0 && Rs < Rt) {
494 MI.setOpcode(Mips::BNEC);
495 HasRs = true;
496 } else
497 MI.setOpcode(Mips::BNEZALC);
498
499 if (HasRs)
500 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
501 Rs)));
502
503 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
504 Rt)));
505 MI.addOperand(MCOperand::CreateImm(Imm));
506
507 return MCDisassembler::Success;
508}
509
510template <typename InsnType>
511static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
512 uint64_t Address,
513 const void *Decoder) {
514 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
515 // (otherwise we would have matched the BLEZL instruction from the earlier
516 // ISA's instead).
517 //
518 // We have:
519 // 0b010110 sssss ttttt iiiiiiiiiiiiiiii
520 // Invalid if rs == 0
521 // BLEZC if rs == 0 && rt != 0
522 // BGEZC if rs == rt && rt != 0
523 // BGEC if rs != rt && rs != 0 && rt != 0
524
525 InsnType Rs = fieldFromInstruction(insn, 21, 5);
526 InsnType Rt = fieldFromInstruction(insn, 16, 5);
527 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000528 bool HasRs = false;
Daniel Sanders5c582b22014-05-22 11:23:21 +0000529
530 if (Rt == 0)
531 return MCDisassembler::Fail;
532 else if (Rs == 0)
533 MI.setOpcode(Mips::BLEZC);
534 else if (Rs == Rt)
535 MI.setOpcode(Mips::BGEZC);
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000536 else {
537 HasRs = true;
538 MI.setOpcode(Mips::BGEC);
539 }
540
541 if (HasRs)
542 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
543 Rs)));
Daniel Sanders5c582b22014-05-22 11:23:21 +0000544
545 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
546 Rt)));
547
548 MI.addOperand(MCOperand::CreateImm(Imm));
549
550 return MCDisassembler::Success;
551}
552
553template <typename InsnType>
554static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
555 uint64_t Address,
556 const void *Decoder) {
557 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
558 // (otherwise we would have matched the BGTZL instruction from the earlier
559 // ISA's instead).
560 //
561 // We have:
562 // 0b010111 sssss ttttt iiiiiiiiiiiiiiii
563 // Invalid if rs == 0
564 // BGTZC if rs == 0 && rt != 0
565 // BLTZC if rs == rt && rt != 0
566 // BLTC if rs != rt && rs != 0 && rt != 0
567
568 InsnType Rs = fieldFromInstruction(insn, 21, 5);
569 InsnType Rt = fieldFromInstruction(insn, 16, 5);
570 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
571
572 if (Rt == 0)
573 return MCDisassembler::Fail;
574 else if (Rs == 0)
575 MI.setOpcode(Mips::BGTZC);
576 else if (Rs == Rt)
577 MI.setOpcode(Mips::BLTZC);
578 else
579 return MCDisassembler::Fail; // FIXME: BLTC is not implemented yet.
580
581 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
582 Rt)));
583
584 MI.addOperand(MCOperand::CreateImm(Imm));
585
586 return MCDisassembler::Success;
587}
588
589template <typename InsnType>
590static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
591 uint64_t Address,
592 const void *Decoder) {
593 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
594 // (otherwise we would have matched the BGTZ instruction from the earlier
595 // ISA's instead).
596 //
597 // We have:
598 // 0b000111 sssss ttttt iiiiiiiiiiiiiiii
599 // BGTZ if rt == 0
600 // BGTZALC if rs == 0 && rt != 0
601 // BLTZALC if rs != 0 && rs == rt
602 // BLTUC if rs != 0 && rs != rt
603
604 InsnType Rs = fieldFromInstruction(insn, 21, 5);
605 InsnType Rt = fieldFromInstruction(insn, 16, 5);
606 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
607 bool HasRs = false;
608 bool HasRt = false;
609
610 if (Rt == 0) {
611 MI.setOpcode(Mips::BGTZ);
612 HasRs = true;
613 } else if (Rs == 0) {
614 MI.setOpcode(Mips::BGTZALC);
615 HasRt = true;
616 } else if (Rs == Rt) {
617 MI.setOpcode(Mips::BLTZALC);
618 HasRs = true;
619 } else
620 return MCDisassembler::Fail; // BLTUC not implemented yet
621
622 if (HasRs)
623 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
624 Rs)));
625
626 if (HasRt)
627 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
628 Rt)));
629
630 MI.addOperand(MCOperand::CreateImm(Imm));
631
632 return MCDisassembler::Success;
633}
634
Zoran Jovanovic28a0ca02014-06-12 11:47:44 +0000635template <typename InsnType>
636static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn,
637 uint64_t Address,
638 const void *Decoder) {
639 // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
640 // (otherwise we would have matched the BLEZL instruction from the earlier
641 // ISA's instead).
642 //
643 // We have:
644 // 0b000110 sssss ttttt iiiiiiiiiiiiiiii
645 // Invalid if rs == 0
646 // BLEZALC if rs == 0 && rt != 0
647 // BGEZALC if rs == rt && rt != 0
648 // BGEUC if rs != rt && rs != 0 && rt != 0
649
650 InsnType Rs = fieldFromInstruction(insn, 21, 5);
651 InsnType Rt = fieldFromInstruction(insn, 16, 5);
652 InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
653 bool HasRs = false;
654
655 if (Rt == 0)
656 return MCDisassembler::Fail;
657 else if (Rs == 0)
658 MI.setOpcode(Mips::BLEZALC);
659 else if (Rs == Rt)
660 MI.setOpcode(Mips::BGEZALC);
661 else {
662 HasRs = true;
663 MI.setOpcode(Mips::BGEUC);
664 }
665
666 if (HasRs)
667 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
668 Rs)));
669 MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
670 Rt)));
671
672 MI.addOperand(MCOperand::CreateImm(Imm));
673
674 return MCDisassembler::Success;
675}
676
Akira Hatanaka71928e62012-04-17 18:03:21 +0000677 /// readInstruction - read four bytes from the MemoryObject
678 /// and return 32 bit word sorted according to the given endianess
679static DecodeStatus readInstruction32(const MemoryObject &region,
680 uint64_t address,
681 uint64_t &size,
682 uint32_t &insn,
Vladimir Medicdde3d582013-09-06 12:30:36 +0000683 bool isBigEndian,
684 bool IsMicroMips) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000685 uint8_t Bytes[4];
686
687 // We want to read exactly 4 Bytes of data.
Benjamin Kramer534d3a42013-05-24 10:54:58 +0000688 if (region.readBytes(address, 4, Bytes) == -1) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000689 size = 0;
690 return MCDisassembler::Fail;
691 }
692
693 if (isBigEndian) {
694 // Encoded as a big-endian 32-bit word in the stream.
695 insn = (Bytes[3] << 0) |
696 (Bytes[2] << 8) |
697 (Bytes[1] << 16) |
698 (Bytes[0] << 24);
699 }
700 else {
701 // Encoded as a small-endian 32-bit word in the stream.
Vladimir Medicdde3d582013-09-06 12:30:36 +0000702 // Little-endian byte ordering:
703 // mips32r2: 4 | 3 | 2 | 1
704 // microMIPS: 2 | 1 | 4 | 3
705 if (IsMicroMips) {
706 insn = (Bytes[2] << 0) |
707 (Bytes[3] << 8) |
708 (Bytes[0] << 16) |
709 (Bytes[1] << 24);
710 } else {
711 insn = (Bytes[0] << 0) |
712 (Bytes[1] << 8) |
713 (Bytes[2] << 16) |
714 (Bytes[3] << 24);
715 }
Akira Hatanaka71928e62012-04-17 18:03:21 +0000716 }
717
718 return MCDisassembler::Success;
719}
720
721DecodeStatus
722MipsDisassembler::getInstruction(MCInst &instr,
723 uint64_t &Size,
724 const MemoryObject &Region,
725 uint64_t Address,
726 raw_ostream &vStream,
727 raw_ostream &cStream) const {
728 uint32_t Insn;
729
730 DecodeStatus Result = readInstruction32(Region, Address, Size,
Vladimir Medicdde3d582013-09-06 12:30:36 +0000731 Insn, isBigEndian, IsMicroMips);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000732 if (Result == MCDisassembler::Fail)
733 return MCDisassembler::Fail;
734
Vladimir Medicdde3d582013-09-06 12:30:36 +0000735 if (IsMicroMips) {
Daniel Sanders0fa60412014-06-12 13:39:06 +0000736 DEBUG(dbgs() << "Trying MicroMips32 table (32-bit opcodes):\n");
Vladimir Medicdde3d582013-09-06 12:30:36 +0000737 // Calling the auto-generated decoder function.
738 Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
739 this, STI);
740 if (Result != MCDisassembler::Fail) {
741 Size = 4;
742 return Result;
743 }
744 return MCDisassembler::Fail;
745 }
746
Daniel Sanders0fa60412014-06-12 13:39:06 +0000747 if (isMips32r6() && isGP64()) {
748 DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n");
749 Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, instr, Insn,
750 Address, this, STI);
751 if (Result != MCDisassembler::Fail) {
752 Size = 4;
753 return Result;
754 }
755 }
756
Daniel Sanders5c582b22014-05-22 11:23:21 +0000757 if (isMips32r6()) {
Daniel Sanders0fa60412014-06-12 13:39:06 +0000758 DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n");
Daniel Sanders5c582b22014-05-22 11:23:21 +0000759 Result = decodeInstruction(DecoderTableMips32r6_64r632, instr, Insn,
760 Address, this, STI);
761 if (Result != MCDisassembler::Fail) {
762 Size = 4;
763 return Result;
764 }
765 }
766
Daniel Sanders0fa60412014-06-12 13:39:06 +0000767 DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n");
Akira Hatanaka71928e62012-04-17 18:03:21 +0000768 // Calling the auto-generated decoder function.
Jim Grosbachecaef492012-08-14 19:06:05 +0000769 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
770 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000771 if (Result != MCDisassembler::Fail) {
772 Size = 4;
773 return Result;
774 }
775
776 return MCDisassembler::Fail;
777}
778
779DecodeStatus
780Mips64Disassembler::getInstruction(MCInst &instr,
781 uint64_t &Size,
782 const MemoryObject &Region,
783 uint64_t Address,
784 raw_ostream &vStream,
785 raw_ostream &cStream) const {
786 uint32_t Insn;
787
788 DecodeStatus Result = readInstruction32(Region, Address, Size,
Vladimir Medicdde3d582013-09-06 12:30:36 +0000789 Insn, isBigEndian, false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000790 if (Result == MCDisassembler::Fail)
791 return MCDisassembler::Fail;
792
793 // Calling the auto-generated decoder function.
Jim Grosbachecaef492012-08-14 19:06:05 +0000794 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
795 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000796 if (Result != MCDisassembler::Fail) {
797 Size = 4;
798 return Result;
799 }
800 // If we fail to decode in Mips64 decoder space we can try in Mips32
Jim Grosbachecaef492012-08-14 19:06:05 +0000801 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
802 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000803 if (Result != MCDisassembler::Fail) {
804 Size = 4;
805 return Result;
806 }
807
808 return MCDisassembler::Fail;
809}
810
Reed Kotlerec8a5492013-02-14 03:05:25 +0000811static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
812 unsigned RegNo,
813 uint64_t Address,
814 const void *Decoder) {
815
816 return MCDisassembler::Fail;
817
818}
819
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000820static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
821 unsigned RegNo,
822 uint64_t Address,
823 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000824
825 if (RegNo > 31)
826 return MCDisassembler::Fail;
827
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000828 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000829 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000830 return MCDisassembler::Success;
831}
832
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000833static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
834 unsigned RegNo,
835 uint64_t Address,
836 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000837 if (RegNo > 31)
838 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000839 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000840 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000841 return MCDisassembler::Success;
842}
843
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000844static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
845 unsigned RegNo,
846 uint64_t Address,
847 const void *Decoder) {
848 if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
849 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
850
851 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
852}
853
Akira Hatanaka654655f2013-08-14 00:53:38 +0000854static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
855 unsigned RegNo,
856 uint64_t Address,
857 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000858 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000859}
860
Akira Hatanaka71928e62012-04-17 18:03:21 +0000861static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
862 unsigned RegNo,
863 uint64_t Address,
864 const void *Decoder) {
865 if (RegNo > 31)
866 return MCDisassembler::Fail;
867
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000868 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
869 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000870 return MCDisassembler::Success;
871}
872
873static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
874 unsigned RegNo,
875 uint64_t Address,
876 const void *Decoder) {
877 if (RegNo > 31)
878 return MCDisassembler::Fail;
879
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000880 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
881 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000882 return MCDisassembler::Success;
883}
884
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000885static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
886 unsigned RegNo,
887 uint64_t Address,
888 const void *Decoder) {
889 if (RegNo > 31)
890 return MCDisassembler::Fail;
891
892 unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
893 Inst.addOperand(MCOperand::CreateReg(Reg));
894 return MCDisassembler::Success;
895}
896
Akira Hatanaka71928e62012-04-17 18:03:21 +0000897static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
898 unsigned RegNo,
899 uint64_t Address,
900 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +0000901 if (RegNo > 31)
902 return MCDisassembler::Fail;
903 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
904 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000905 return MCDisassembler::Success;
906}
907
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000908static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
909 unsigned RegNo,
910 uint64_t Address,
911 const void *Decoder) {
912 if (RegNo > 7)
913 return MCDisassembler::Fail;
914 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
915 Inst.addOperand(MCOperand::CreateReg(Reg));
916 return MCDisassembler::Success;
917}
918
Daniel Sanders0fa60412014-06-12 13:39:06 +0000919static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo,
920 uint64_t Address,
921 const void *Decoder) {
922 if (RegNo > 31)
923 return MCDisassembler::Fail;
924
925 unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo);
926 Inst.addOperand(MCOperand::CreateReg(Reg));
927 return MCDisassembler::Success;
928}
929
Akira Hatanaka71928e62012-04-17 18:03:21 +0000930static DecodeStatus DecodeMem(MCInst &Inst,
931 unsigned Insn,
932 uint64_t Address,
933 const void *Decoder) {
934 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +0000935 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
936 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000937
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000938 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
939 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000940
941 if(Inst.getOpcode() == Mips::SC){
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000942 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000943 }
944
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000945 Inst.addOperand(MCOperand::CreateReg(Reg));
946 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000947 Inst.addOperand(MCOperand::CreateImm(Offset));
948
949 return MCDisassembler::Success;
950}
951
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000952static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
953 uint64_t Address, const void *Decoder) {
954 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
955 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
956 unsigned Base = fieldFromInstruction(Insn, 11, 5);
957
958 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
959 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
960
961 Inst.addOperand(MCOperand::CreateReg(Reg));
962 Inst.addOperand(MCOperand::CreateReg(Base));
Matheus Almeida6b59c442013-12-05 11:06:22 +0000963
964 // The immediate field of an LD/ST instruction is scaled which means it must
965 // be multiplied (when decoding) by the size (in bytes) of the instructions'
966 // data format.
967 // .b - 1 byte
968 // .h - 2 bytes
969 // .w - 4 bytes
970 // .d - 8 bytes
971 switch(Inst.getOpcode())
972 {
973 default:
974 assert (0 && "Unexpected instruction");
975 return MCDisassembler::Fail;
976 break;
977 case Mips::LD_B:
978 case Mips::ST_B:
979 Inst.addOperand(MCOperand::CreateImm(Offset));
980 break;
981 case Mips::LD_H:
982 case Mips::ST_H:
983 Inst.addOperand(MCOperand::CreateImm(Offset << 1));
984 break;
985 case Mips::LD_W:
986 case Mips::ST_W:
987 Inst.addOperand(MCOperand::CreateImm(Offset << 2));
988 break;
989 case Mips::LD_D:
990 case Mips::ST_D:
991 Inst.addOperand(MCOperand::CreateImm(Offset << 3));
992 break;
993 }
Matheus Almeidafe0bf9f2013-10-21 13:07:13 +0000994
995 return MCDisassembler::Success;
996}
997
Vladimir Medicdde3d582013-09-06 12:30:36 +0000998static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
999 unsigned Insn,
1000 uint64_t Address,
1001 const void *Decoder) {
1002 int Offset = SignExtend32<12>(Insn & 0x0fff);
1003 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1004 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1005
1006 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1007 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1008
Zoran Jovanovic285cc282014-02-28 18:22:56 +00001009 if (Inst.getOpcode() == Mips::SC_MM)
1010 Inst.addOperand(MCOperand::CreateReg(Reg));
1011
Vladimir Medicdde3d582013-09-06 12:30:36 +00001012 Inst.addOperand(MCOperand::CreateReg(Reg));
1013 Inst.addOperand(MCOperand::CreateReg(Base));
1014 Inst.addOperand(MCOperand::CreateImm(Offset));
1015
1016 return MCDisassembler::Success;
1017}
1018
1019static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
1020 unsigned Insn,
1021 uint64_t Address,
1022 const void *Decoder) {
1023 int Offset = SignExtend32<16>(Insn & 0xffff);
1024 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
1025 unsigned Base = fieldFromInstruction(Insn, 16, 5);
1026
1027 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
1028 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
1029
1030 Inst.addOperand(MCOperand::CreateReg(Reg));
1031 Inst.addOperand(MCOperand::CreateReg(Base));
1032 Inst.addOperand(MCOperand::CreateImm(Offset));
1033
1034 return MCDisassembler::Success;
1035}
1036
Akira Hatanaka71928e62012-04-17 18:03:21 +00001037static DecodeStatus DecodeFMem(MCInst &Inst,
1038 unsigned Insn,
1039 uint64_t Address,
1040 const void *Decoder) {
1041 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +00001042 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
1043 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +00001044
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001045 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001046 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001047
1048 Inst.addOperand(MCOperand::CreateReg(Reg));
1049 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001050 Inst.addOperand(MCOperand::CreateImm(Offset));
1051
1052 return MCDisassembler::Success;
1053}
1054
1055
1056static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1057 unsigned RegNo,
1058 uint64_t Address,
1059 const void *Decoder) {
1060 // Currently only hardware register 29 is supported.
1061 if (RegNo != 29)
1062 return MCDisassembler::Fail;
1063 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
1064 return MCDisassembler::Success;
1065}
1066
Akira Hatanaka71928e62012-04-17 18:03:21 +00001067static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1068 unsigned RegNo,
1069 uint64_t Address,
1070 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001071 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +00001072 return MCDisassembler::Fail;
1073
Akira Hatanaka9bf2b562012-07-09 18:46:47 +00001074 ;
1075 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
1076 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +00001077 return MCDisassembler::Success;
1078}
1079
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001080static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1081 unsigned RegNo,
1082 uint64_t Address,
1083 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001084 if (RegNo >= 4)
1085 return MCDisassembler::Fail;
1086
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001087 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +00001088 Inst.addOperand(MCOperand::CreateReg(Reg));
1089 return MCDisassembler::Success;
1090}
1091
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001092static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1093 unsigned RegNo,
1094 uint64_t Address,
1095 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001096 if (RegNo >= 4)
1097 return MCDisassembler::Fail;
1098
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001099 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001100 Inst.addOperand(MCOperand::CreateReg(Reg));
1101 return MCDisassembler::Success;
1102}
1103
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001104static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
1105 unsigned RegNo,
1106 uint64_t Address,
1107 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001108 if (RegNo >= 4)
1109 return MCDisassembler::Fail;
1110
Akira Hatanaka8002a3f2013-08-14 00:47:08 +00001111 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +00001112 Inst.addOperand(MCOperand::CreateReg(Reg));
1113 return MCDisassembler::Success;
1114}
1115
Jack Carter3eb663b2013-09-26 00:09:46 +00001116static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
1117 unsigned RegNo,
1118 uint64_t Address,
1119 const void *Decoder) {
1120 if (RegNo > 31)
1121 return MCDisassembler::Fail;
1122
1123 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
1124 Inst.addOperand(MCOperand::CreateReg(Reg));
1125 return MCDisassembler::Success;
1126}
1127
Jack Carter5dc8ac92013-09-25 23:50:44 +00001128static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
1129 unsigned RegNo,
1130 uint64_t Address,
1131 const void *Decoder) {
1132 if (RegNo > 31)
1133 return MCDisassembler::Fail;
1134
1135 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
1136 Inst.addOperand(MCOperand::CreateReg(Reg));
1137 return MCDisassembler::Success;
1138}
1139
1140static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
1141 unsigned RegNo,
1142 uint64_t Address,
1143 const void *Decoder) {
1144 if (RegNo > 31)
1145 return MCDisassembler::Fail;
1146
1147 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
1148 Inst.addOperand(MCOperand::CreateReg(Reg));
1149 return MCDisassembler::Success;
1150}
1151
1152static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
1153 unsigned RegNo,
1154 uint64_t Address,
1155 const void *Decoder) {
1156 if (RegNo > 31)
1157 return MCDisassembler::Fail;
1158
1159 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
1160 Inst.addOperand(MCOperand::CreateReg(Reg));
1161 return MCDisassembler::Success;
1162}
1163
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001164static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
1165 unsigned RegNo,
1166 uint64_t Address,
1167 const void *Decoder) {
1168 if (RegNo > 7)
1169 return MCDisassembler::Fail;
1170
1171 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
1172 Inst.addOperand(MCOperand::CreateReg(Reg));
1173 return MCDisassembler::Success;
1174}
1175
Daniel Sanders2a83d682014-05-21 12:56:39 +00001176static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst,
1177 unsigned RegNo,
1178 uint64_t Address,
1179 const void *Decoder) {
1180 if (RegNo > 31)
1181 return MCDisassembler::Fail;
1182
1183 unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo);
1184 Inst.addOperand(MCOperand::CreateReg(Reg));
1185 return MCDisassembler::Success;
1186}
1187
Akira Hatanaka71928e62012-04-17 18:03:21 +00001188static DecodeStatus DecodeBranchTarget(MCInst &Inst,
1189 unsigned Offset,
1190 uint64_t Address,
1191 const void *Decoder) {
Daniel Sanders5c582b22014-05-22 11:23:21 +00001192 int32_t BranchOffset = (SignExtend32<16>(Offset) << 2) + 4;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001193 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1194 return MCDisassembler::Success;
1195}
1196
Akira Hatanaka71928e62012-04-17 18:03:21 +00001197static DecodeStatus DecodeJumpTarget(MCInst &Inst,
1198 unsigned Insn,
1199 uint64_t Address,
1200 const void *Decoder) {
1201
Jim Grosbachecaef492012-08-14 19:06:05 +00001202 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Akira Hatanaka71928e62012-04-17 18:03:21 +00001203 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1204 return MCDisassembler::Success;
1205}
1206
Zoran Jovanovic3c8869d2014-05-16 11:03:45 +00001207static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
1208 unsigned Offset,
1209 uint64_t Address,
1210 const void *Decoder) {
1211 int32_t BranchOffset = SignExtend32<21>(Offset) << 2;
1212
1213 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1214 return MCDisassembler::Success;
1215}
1216
1217static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
1218 unsigned Offset,
1219 uint64_t Address,
1220 const void *Decoder) {
1221 int32_t BranchOffset = SignExtend32<26>(Offset) << 2;
1222
1223 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1224 return MCDisassembler::Success;
1225}
1226
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001227static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
1228 unsigned Offset,
1229 uint64_t Address,
1230 const void *Decoder) {
Daniel Sanders5c582b22014-05-22 11:23:21 +00001231 int32_t BranchOffset = SignExtend32<16>(Offset) << 1;
Zoran Jovanovic8a80aa72013-11-04 14:53:22 +00001232 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
1233 return MCDisassembler::Success;
1234}
1235
Zoran Jovanovic507e0842013-10-29 16:38:59 +00001236static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
1237 unsigned Insn,
1238 uint64_t Address,
1239 const void *Decoder) {
1240 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
1241 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
1242 return MCDisassembler::Success;
1243}
Akira Hatanaka71928e62012-04-17 18:03:21 +00001244
1245static DecodeStatus DecodeSimm16(MCInst &Inst,
1246 unsigned Insn,
1247 uint64_t Address,
1248 const void *Decoder) {
1249 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
1250 return MCDisassembler::Success;
1251}
1252
Matheus Almeida779c5932013-11-18 12:32:49 +00001253static DecodeStatus DecodeLSAImm(MCInst &Inst,
1254 unsigned Insn,
1255 uint64_t Address,
1256 const void *Decoder) {
1257 // We add one to the immediate field as it was encoded as 'imm - 1'.
1258 Inst.addOperand(MCOperand::CreateImm(Insn + 1));
1259 return MCDisassembler::Success;
1260}
1261
Akira Hatanaka71928e62012-04-17 18:03:21 +00001262static DecodeStatus DecodeInsSize(MCInst &Inst,
1263 unsigned Insn,
1264 uint64_t Address,
1265 const void *Decoder) {
1266 // First we need to grab the pos(lsb) from MCInst.
1267 int Pos = Inst.getOperand(2).getImm();
1268 int Size = (int) Insn - Pos + 1;
1269 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
1270 return MCDisassembler::Success;
1271}
1272
1273static DecodeStatus DecodeExtSize(MCInst &Inst,
1274 unsigned Insn,
1275 uint64_t Address,
1276 const void *Decoder) {
1277 int Size = (int) Insn + 1;
1278 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
1279 return MCDisassembler::Success;
1280}
Daniel Sandersb59e1a42014-05-15 10:45:58 +00001281
1282static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
1283 uint64_t Address, const void *Decoder) {
1284 Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) << 2));
1285 return MCDisassembler::Success;
1286}
Zoran Jovanovic28551422014-06-09 09:49:51 +00001287
1288static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn,
1289 uint64_t Address, const void *Decoder) {
1290 Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) << 3));
1291 return MCDisassembler::Success;
1292}