blob: 6e12a5d5e5c11ac60e0d6423ec056b6d70d986e6 [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"
Akira Hatanaka71928e62012-04-17 18:03:21 +000017#include "llvm/MC/MCDisassembler.h"
Jim Grosbachecaef492012-08-14 19:06:05 +000018#include "llvm/MC/MCFixedLenDisassembler.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000019#include "llvm/MC/MCInst.h"
20#include "llvm/MC/MCSubtargetInfo.h"
21#include "llvm/Support/MathExtras.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000022#include "llvm/Support/MemoryObject.h"
23#include "llvm/Support/TargetRegistry.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000024
Akira Hatanaka71928e62012-04-17 18:03:21 +000025using namespace llvm;
26
27typedef MCDisassembler::DecodeStatus DecodeStatus;
28
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000029namespace {
30
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000031/// MipsDisassemblerBase - a disasembler class for Mips.
32class MipsDisassemblerBase : public MCDisassembler {
Akira Hatanaka71928e62012-04-17 18:03:21 +000033public:
34 /// Constructor - Initializes the disassembler.
35 ///
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000036 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
37 bool bigEndian) :
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000038 MCDisassembler(STI), RegInfo(Info),
39 IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000040
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000041 virtual ~MipsDisassemblerBase() {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000042
Benjamin Kramerdcfd5b52013-08-03 22:16:16 +000043 const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000044
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000045 bool isN64() const { return IsN64; }
46
Akira Hatanaka71928e62012-04-17 18:03:21 +000047private:
Benjamin Kramerdcfd5b52013-08-03 22:16:16 +000048 OwningPtr<const MCRegisterInfo> RegInfo;
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 {
56public:
57 /// Constructor - Initializes the disassembler.
58 ///
59 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
60 bool bigEndian) :
61 MipsDisassemblerBase(STI, Info, bigEndian) {}
62
63 /// getInstruction - See MCDisassembler.
64 virtual DecodeStatus getInstruction(MCInst &instr,
65 uint64_t &size,
66 const MemoryObject &region,
67 uint64_t address,
68 raw_ostream &vStream,
69 raw_ostream &cStream) const;
70};
71
Akira Hatanaka71928e62012-04-17 18:03:21 +000072
73/// Mips64Disassembler - a disasembler class for Mips64.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000074class Mips64Disassembler : public MipsDisassemblerBase {
Akira Hatanaka71928e62012-04-17 18:03:21 +000075public:
76 /// Constructor - Initializes the disassembler.
77 ///
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000078 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
79 bool bigEndian) :
80 MipsDisassemblerBase(STI, Info, bigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000081
82 /// getInstruction - See MCDisassembler.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000083 virtual DecodeStatus getInstruction(MCInst &instr,
84 uint64_t &size,
85 const MemoryObject &region,
86 uint64_t address,
87 raw_ostream &vStream,
88 raw_ostream &cStream) const;
Akira Hatanaka71928e62012-04-17 18:03:21 +000089};
90
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000091} // end anonymous namespace
92
Akira Hatanaka71928e62012-04-17 18:03:21 +000093// Forward declare these because the autogenerated code will reference them.
94// Definitions are further down.
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000095static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
96 unsigned RegNo,
97 uint64_t Address,
98 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +000099
Reed Kotlerec8a5492013-02-14 03:05:25 +0000100static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
101 unsigned RegNo,
102 uint64_t Address,
103 const void *Decoder);
104
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000105static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
106 unsigned RegNo,
107 uint64_t Address,
108 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000109
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000110static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
111 unsigned Insn,
112 uint64_t Address,
113 const void *Decoder);
114
Akira Hatanaka654655f2013-08-14 00:53:38 +0000115static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
116 unsigned RegNo,
117 uint64_t Address,
118 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000119
Akira Hatanaka71928e62012-04-17 18:03:21 +0000120static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
121 unsigned RegNo,
122 uint64_t Address,
123 const void *Decoder);
124
125static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
126 unsigned RegNo,
127 uint64_t Address,
128 const void *Decoder);
129
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000130static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
131 unsigned RegNo,
132 uint64_t Address,
133 const void *Decoder);
134
Akira Hatanaka71928e62012-04-17 18:03:21 +0000135static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
136 unsigned RegNo,
137 uint64_t Address,
138 const void *Decoder);
139
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000140static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
141 unsigned RegNo,
142 uint64_t Address,
143 const void *Decoder);
144
Akira Hatanaka71928e62012-04-17 18:03:21 +0000145static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
146 unsigned Insn,
147 uint64_t Address,
148 const void *Decoder);
149
150static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
151 unsigned RegNo,
152 uint64_t Address,
153 const void *Decoder);
154
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000155static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
156 unsigned RegNo,
157 uint64_t Address,
158 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000159
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000160static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
161 unsigned RegNo,
162 uint64_t Address,
163 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000164
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000165static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
166 unsigned RegNo,
167 uint64_t Address,
168 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000169
Akira Hatanaka71928e62012-04-17 18:03:21 +0000170static DecodeStatus DecodeBranchTarget(MCInst &Inst,
171 unsigned Offset,
172 uint64_t Address,
173 const void *Decoder);
174
Akira Hatanaka71928e62012-04-17 18:03:21 +0000175static DecodeStatus DecodeJumpTarget(MCInst &Inst,
176 unsigned Insn,
177 uint64_t Address,
178 const void *Decoder);
179
180static DecodeStatus DecodeMem(MCInst &Inst,
181 unsigned Insn,
182 uint64_t Address,
183 const void *Decoder);
184
185static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
186 uint64_t Address,
187 const void *Decoder);
188
189static DecodeStatus DecodeSimm16(MCInst &Inst,
190 unsigned Insn,
191 uint64_t Address,
192 const void *Decoder);
193
Akira Hatanaka71928e62012-04-17 18:03:21 +0000194static DecodeStatus DecodeInsSize(MCInst &Inst,
195 unsigned Insn,
196 uint64_t Address,
197 const void *Decoder);
198
199static DecodeStatus DecodeExtSize(MCInst &Inst,
200 unsigned Insn,
201 uint64_t Address,
202 const void *Decoder);
203
204namespace llvm {
205extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
206 TheMips64elTarget;
207}
208
209static MCDisassembler *createMipsDisassembler(
210 const Target &T,
211 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000212 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000213}
214
215static MCDisassembler *createMipselDisassembler(
216 const Target &T,
217 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000218 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000219}
220
221static MCDisassembler *createMips64Disassembler(
222 const Target &T,
223 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000224 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000225}
226
227static MCDisassembler *createMips64elDisassembler(
228 const Target &T,
229 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000230 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000231}
232
233extern "C" void LLVMInitializeMipsDisassembler() {
234 // Register the disassembler.
235 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
236 createMipsDisassembler);
237 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
238 createMipselDisassembler);
239 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
240 createMips64Disassembler);
241 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
242 createMips64elDisassembler);
243}
244
245
246#include "MipsGenDisassemblerTables.inc"
247
248 /// readInstruction - read four bytes from the MemoryObject
249 /// and return 32 bit word sorted according to the given endianess
250static DecodeStatus readInstruction32(const MemoryObject &region,
251 uint64_t address,
252 uint64_t &size,
253 uint32_t &insn,
254 bool isBigEndian) {
255 uint8_t Bytes[4];
256
257 // We want to read exactly 4 Bytes of data.
Benjamin Kramer534d3a42013-05-24 10:54:58 +0000258 if (region.readBytes(address, 4, Bytes) == -1) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000259 size = 0;
260 return MCDisassembler::Fail;
261 }
262
263 if (isBigEndian) {
264 // Encoded as a big-endian 32-bit word in the stream.
265 insn = (Bytes[3] << 0) |
266 (Bytes[2] << 8) |
267 (Bytes[1] << 16) |
268 (Bytes[0] << 24);
269 }
270 else {
271 // Encoded as a small-endian 32-bit word in the stream.
272 insn = (Bytes[0] << 0) |
273 (Bytes[1] << 8) |
274 (Bytes[2] << 16) |
275 (Bytes[3] << 24);
276 }
277
278 return MCDisassembler::Success;
279}
280
281DecodeStatus
282MipsDisassembler::getInstruction(MCInst &instr,
283 uint64_t &Size,
284 const MemoryObject &Region,
285 uint64_t Address,
286 raw_ostream &vStream,
287 raw_ostream &cStream) const {
288 uint32_t Insn;
289
290 DecodeStatus Result = readInstruction32(Region, Address, Size,
291 Insn, isBigEndian);
292 if (Result == MCDisassembler::Fail)
293 return MCDisassembler::Fail;
294
295 // Calling the auto-generated decoder function.
Jim Grosbachecaef492012-08-14 19:06:05 +0000296 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
297 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000298 if (Result != MCDisassembler::Fail) {
299 Size = 4;
300 return Result;
301 }
302
303 return MCDisassembler::Fail;
304}
305
306DecodeStatus
307Mips64Disassembler::getInstruction(MCInst &instr,
308 uint64_t &Size,
309 const MemoryObject &Region,
310 uint64_t Address,
311 raw_ostream &vStream,
312 raw_ostream &cStream) const {
313 uint32_t Insn;
314
315 DecodeStatus Result = readInstruction32(Region, Address, Size,
316 Insn, isBigEndian);
317 if (Result == MCDisassembler::Fail)
318 return MCDisassembler::Fail;
319
320 // Calling the auto-generated decoder function.
Jim Grosbachecaef492012-08-14 19:06:05 +0000321 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
322 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000323 if (Result != MCDisassembler::Fail) {
324 Size = 4;
325 return Result;
326 }
327 // If we fail to decode in Mips64 decoder space we can try in Mips32
Jim Grosbachecaef492012-08-14 19:06:05 +0000328 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
329 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000330 if (Result != MCDisassembler::Fail) {
331 Size = 4;
332 return Result;
333 }
334
335 return MCDisassembler::Fail;
336}
337
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000338static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
339 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
340 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
341}
342
Reed Kotlerec8a5492013-02-14 03:05:25 +0000343static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
344 unsigned RegNo,
345 uint64_t Address,
346 const void *Decoder) {
347
348 return MCDisassembler::Fail;
349
350}
351
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000352static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
353 unsigned RegNo,
354 uint64_t Address,
355 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000356
357 if (RegNo > 31)
358 return MCDisassembler::Fail;
359
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000360 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000361 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000362 return MCDisassembler::Success;
363}
364
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000365static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
366 unsigned RegNo,
367 uint64_t Address,
368 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000369 if (RegNo > 31)
370 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000371 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000372 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000373 return MCDisassembler::Success;
374}
375
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000376static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
377 unsigned RegNo,
378 uint64_t Address,
379 const void *Decoder) {
380 if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
381 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
382
383 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
384}
385
Akira Hatanaka654655f2013-08-14 00:53:38 +0000386static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
387 unsigned RegNo,
388 uint64_t Address,
389 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000390 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000391}
392
Akira Hatanaka71928e62012-04-17 18:03:21 +0000393static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
394 unsigned RegNo,
395 uint64_t Address,
396 const void *Decoder) {
397 if (RegNo > 31)
398 return MCDisassembler::Fail;
399
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000400 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
401 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000402 return MCDisassembler::Success;
403}
404
405static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
406 unsigned RegNo,
407 uint64_t Address,
408 const void *Decoder) {
409 if (RegNo > 31)
410 return MCDisassembler::Fail;
411
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000412 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
413 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000414 return MCDisassembler::Success;
415}
416
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000417static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
418 unsigned RegNo,
419 uint64_t Address,
420 const void *Decoder) {
421 if (RegNo > 31)
422 return MCDisassembler::Fail;
423
424 unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
425 Inst.addOperand(MCOperand::CreateReg(Reg));
426 return MCDisassembler::Success;
427}
428
Akira Hatanaka71928e62012-04-17 18:03:21 +0000429static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
430 unsigned RegNo,
431 uint64_t Address,
432 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +0000433 if (RegNo > 31)
434 return MCDisassembler::Fail;
435 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
436 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000437 return MCDisassembler::Success;
438}
439
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000440static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
441 unsigned RegNo,
442 uint64_t Address,
443 const void *Decoder) {
444 if (RegNo > 7)
445 return MCDisassembler::Fail;
446 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
447 Inst.addOperand(MCOperand::CreateReg(Reg));
448 return MCDisassembler::Success;
449}
450
Akira Hatanaka71928e62012-04-17 18:03:21 +0000451static DecodeStatus DecodeMem(MCInst &Inst,
452 unsigned Insn,
453 uint64_t Address,
454 const void *Decoder) {
455 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +0000456 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
457 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000458
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000459 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
460 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000461
462 if(Inst.getOpcode() == Mips::SC){
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000463 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000464 }
465
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000466 Inst.addOperand(MCOperand::CreateReg(Reg));
467 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000468 Inst.addOperand(MCOperand::CreateImm(Offset));
469
470 return MCDisassembler::Success;
471}
472
473static DecodeStatus DecodeFMem(MCInst &Inst,
474 unsigned Insn,
475 uint64_t Address,
476 const void *Decoder) {
477 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +0000478 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
479 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000480
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000481 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000482 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000483
484 Inst.addOperand(MCOperand::CreateReg(Reg));
485 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000486 Inst.addOperand(MCOperand::CreateImm(Offset));
487
488 return MCDisassembler::Success;
489}
490
491
492static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
493 unsigned RegNo,
494 uint64_t Address,
495 const void *Decoder) {
496 // Currently only hardware register 29 is supported.
497 if (RegNo != 29)
498 return MCDisassembler::Fail;
499 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
500 return MCDisassembler::Success;
501}
502
Akira Hatanaka71928e62012-04-17 18:03:21 +0000503static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
504 unsigned RegNo,
505 uint64_t Address,
506 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000507 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +0000508 return MCDisassembler::Fail;
509
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000510 ;
511 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
512 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000513 return MCDisassembler::Success;
514}
515
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000516static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
517 unsigned RegNo,
518 uint64_t Address,
519 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000520 if (RegNo >= 4)
521 return MCDisassembler::Fail;
522
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000523 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000524 Inst.addOperand(MCOperand::CreateReg(Reg));
525 return MCDisassembler::Success;
526}
527
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000528static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
529 unsigned RegNo,
530 uint64_t Address,
531 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000532 if (RegNo >= 4)
533 return MCDisassembler::Fail;
534
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000535 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000536 Inst.addOperand(MCOperand::CreateReg(Reg));
537 return MCDisassembler::Success;
538}
539
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000540static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
541 unsigned RegNo,
542 uint64_t Address,
543 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000544 if (RegNo >= 4)
545 return MCDisassembler::Fail;
546
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000547 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000548 Inst.addOperand(MCOperand::CreateReg(Reg));
549 return MCDisassembler::Success;
550}
551
Akira Hatanaka71928e62012-04-17 18:03:21 +0000552static DecodeStatus DecodeBranchTarget(MCInst &Inst,
553 unsigned Offset,
554 uint64_t Address,
555 const void *Decoder) {
556 unsigned BranchOffset = Offset & 0xffff;
557 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
558 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
559 return MCDisassembler::Success;
560}
561
Akira Hatanaka71928e62012-04-17 18:03:21 +0000562static DecodeStatus DecodeJumpTarget(MCInst &Inst,
563 unsigned Insn,
564 uint64_t Address,
565 const void *Decoder) {
566
Jim Grosbachecaef492012-08-14 19:06:05 +0000567 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000568 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
569 return MCDisassembler::Success;
570}
571
572
573static DecodeStatus DecodeSimm16(MCInst &Inst,
574 unsigned Insn,
575 uint64_t Address,
576 const void *Decoder) {
577 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
578 return MCDisassembler::Success;
579}
580
581static DecodeStatus DecodeInsSize(MCInst &Inst,
582 unsigned Insn,
583 uint64_t Address,
584 const void *Decoder) {
585 // First we need to grab the pos(lsb) from MCInst.
586 int Pos = Inst.getOperand(2).getImm();
587 int Size = (int) Insn - Pos + 1;
588 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
589 return MCDisassembler::Success;
590}
591
592static DecodeStatus DecodeExtSize(MCInst &Inst,
593 unsigned Insn,
594 uint64_t Address,
595 const void *Decoder) {
596 int Size = (int) Insn + 1;
597 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
598 return MCDisassembler::Success;
599}