blob: 1f2d210a84a616a522fe1e48d9b89f7811f7a02b [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) :
38 MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000039
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000040 virtual ~MipsDisassemblerBase() {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000041
Benjamin Kramerdcfd5b52013-08-03 22:16:16 +000042 const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000043
Akira Hatanaka71928e62012-04-17 18:03:21 +000044private:
Benjamin Kramerdcfd5b52013-08-03 22:16:16 +000045 OwningPtr<const MCRegisterInfo> RegInfo;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000046protected:
Akira Hatanaka71928e62012-04-17 18:03:21 +000047 bool isBigEndian;
48};
49
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000050/// MipsDisassembler - a disasembler class for Mips32.
51class MipsDisassembler : public MipsDisassemblerBase {
52public:
53 /// Constructor - Initializes the disassembler.
54 ///
55 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
56 bool bigEndian) :
57 MipsDisassemblerBase(STI, Info, bigEndian) {}
58
59 /// getInstruction - See MCDisassembler.
60 virtual DecodeStatus getInstruction(MCInst &instr,
61 uint64_t &size,
62 const MemoryObject &region,
63 uint64_t address,
64 raw_ostream &vStream,
65 raw_ostream &cStream) const;
66};
67
Akira Hatanaka71928e62012-04-17 18:03:21 +000068
69/// Mips64Disassembler - a disasembler class for Mips64.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000070class Mips64Disassembler : public MipsDisassemblerBase {
Akira Hatanaka71928e62012-04-17 18:03:21 +000071public:
72 /// Constructor - Initializes the disassembler.
73 ///
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000074 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
75 bool bigEndian) :
76 MipsDisassemblerBase(STI, Info, bigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000077
78 /// getInstruction - See MCDisassembler.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000079 virtual DecodeStatus getInstruction(MCInst &instr,
80 uint64_t &size,
81 const MemoryObject &region,
82 uint64_t address,
83 raw_ostream &vStream,
84 raw_ostream &cStream) const;
Akira Hatanaka71928e62012-04-17 18:03:21 +000085};
86
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000087} // end anonymous namespace
88
Akira Hatanaka71928e62012-04-17 18:03:21 +000089// Forward declare these because the autogenerated code will reference them.
90// Definitions are further down.
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000091static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
92 unsigned RegNo,
93 uint64_t Address,
94 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +000095
Reed Kotlerec8a5492013-02-14 03:05:25 +000096static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
97 unsigned RegNo,
98 uint64_t Address,
99 const void *Decoder);
100
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000101static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
102 unsigned RegNo,
103 uint64_t Address,
104 const void *Decoder);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000105
Akira Hatanaka654655f2013-08-14 00:53:38 +0000106static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
107 unsigned RegNo,
108 uint64_t Address,
109 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000110
Akira Hatanaka71928e62012-04-17 18:03:21 +0000111static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
112 unsigned RegNo,
113 uint64_t Address,
114 const void *Decoder);
115
116static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
117 unsigned RegNo,
118 uint64_t Address,
119 const void *Decoder);
120
121static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
122 unsigned RegNo,
123 uint64_t Address,
124 const void *Decoder);
125
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000126static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
127 unsigned RegNo,
128 uint64_t Address,
129 const void *Decoder);
130
Akira Hatanaka71928e62012-04-17 18:03:21 +0000131static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
132 unsigned Insn,
133 uint64_t Address,
134 const void *Decoder);
135
136static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
137 unsigned RegNo,
138 uint64_t Address,
139 const void *Decoder);
140
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000141static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
142 unsigned RegNo,
143 uint64_t Address,
144 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000145
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000146static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
147 unsigned RegNo,
148 uint64_t Address,
149 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000150
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000151static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
152 unsigned RegNo,
153 uint64_t Address,
154 const void *Decoder);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000155
Akira Hatanaka71928e62012-04-17 18:03:21 +0000156static DecodeStatus DecodeBranchTarget(MCInst &Inst,
157 unsigned Offset,
158 uint64_t Address,
159 const void *Decoder);
160
Akira Hatanaka71928e62012-04-17 18:03:21 +0000161static DecodeStatus DecodeJumpTarget(MCInst &Inst,
162 unsigned Insn,
163 uint64_t Address,
164 const void *Decoder);
165
166static DecodeStatus DecodeMem(MCInst &Inst,
167 unsigned Insn,
168 uint64_t Address,
169 const void *Decoder);
170
171static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
172 uint64_t Address,
173 const void *Decoder);
174
175static DecodeStatus DecodeSimm16(MCInst &Inst,
176 unsigned Insn,
177 uint64_t Address,
178 const void *Decoder);
179
Akira Hatanaka71928e62012-04-17 18:03:21 +0000180static DecodeStatus DecodeInsSize(MCInst &Inst,
181 unsigned Insn,
182 uint64_t Address,
183 const void *Decoder);
184
185static DecodeStatus DecodeExtSize(MCInst &Inst,
186 unsigned Insn,
187 uint64_t Address,
188 const void *Decoder);
189
190namespace llvm {
191extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
192 TheMips64elTarget;
193}
194
195static MCDisassembler *createMipsDisassembler(
196 const Target &T,
197 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000198 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000199}
200
201static MCDisassembler *createMipselDisassembler(
202 const Target &T,
203 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000204 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000205}
206
207static MCDisassembler *createMips64Disassembler(
208 const Target &T,
209 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000210 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000211}
212
213static MCDisassembler *createMips64elDisassembler(
214 const Target &T,
215 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000216 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000217}
218
219extern "C" void LLVMInitializeMipsDisassembler() {
220 // Register the disassembler.
221 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
222 createMipsDisassembler);
223 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
224 createMipselDisassembler);
225 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
226 createMips64Disassembler);
227 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
228 createMips64elDisassembler);
229}
230
231
232#include "MipsGenDisassemblerTables.inc"
233
234 /// readInstruction - read four bytes from the MemoryObject
235 /// and return 32 bit word sorted according to the given endianess
236static DecodeStatus readInstruction32(const MemoryObject &region,
237 uint64_t address,
238 uint64_t &size,
239 uint32_t &insn,
240 bool isBigEndian) {
241 uint8_t Bytes[4];
242
243 // We want to read exactly 4 Bytes of data.
Benjamin Kramer534d3a42013-05-24 10:54:58 +0000244 if (region.readBytes(address, 4, Bytes) == -1) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000245 size = 0;
246 return MCDisassembler::Fail;
247 }
248
249 if (isBigEndian) {
250 // Encoded as a big-endian 32-bit word in the stream.
251 insn = (Bytes[3] << 0) |
252 (Bytes[2] << 8) |
253 (Bytes[1] << 16) |
254 (Bytes[0] << 24);
255 }
256 else {
257 // Encoded as a small-endian 32-bit word in the stream.
258 insn = (Bytes[0] << 0) |
259 (Bytes[1] << 8) |
260 (Bytes[2] << 16) |
261 (Bytes[3] << 24);
262 }
263
264 return MCDisassembler::Success;
265}
266
267DecodeStatus
268MipsDisassembler::getInstruction(MCInst &instr,
269 uint64_t &Size,
270 const MemoryObject &Region,
271 uint64_t Address,
272 raw_ostream &vStream,
273 raw_ostream &cStream) const {
274 uint32_t Insn;
275
276 DecodeStatus Result = readInstruction32(Region, Address, Size,
277 Insn, isBigEndian);
278 if (Result == MCDisassembler::Fail)
279 return MCDisassembler::Fail;
280
281 // Calling the auto-generated decoder function.
Jim Grosbachecaef492012-08-14 19:06:05 +0000282 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
283 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000284 if (Result != MCDisassembler::Fail) {
285 Size = 4;
286 return Result;
287 }
288
289 return MCDisassembler::Fail;
290}
291
292DecodeStatus
293Mips64Disassembler::getInstruction(MCInst &instr,
294 uint64_t &Size,
295 const MemoryObject &Region,
296 uint64_t Address,
297 raw_ostream &vStream,
298 raw_ostream &cStream) const {
299 uint32_t Insn;
300
301 DecodeStatus Result = readInstruction32(Region, Address, Size,
302 Insn, isBigEndian);
303 if (Result == MCDisassembler::Fail)
304 return MCDisassembler::Fail;
305
306 // Calling the auto-generated decoder function.
Jim Grosbachecaef492012-08-14 19:06:05 +0000307 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
308 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000309 if (Result != MCDisassembler::Fail) {
310 Size = 4;
311 return Result;
312 }
313 // If we fail to decode in Mips64 decoder space we can try in Mips32
Jim Grosbachecaef492012-08-14 19:06:05 +0000314 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
315 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000316 if (Result != MCDisassembler::Fail) {
317 Size = 4;
318 return Result;
319 }
320
321 return MCDisassembler::Fail;
322}
323
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000324static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
325 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
326 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
327}
328
Reed Kotlerec8a5492013-02-14 03:05:25 +0000329static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
330 unsigned RegNo,
331 uint64_t Address,
332 const void *Decoder) {
333
334 return MCDisassembler::Fail;
335
336}
337
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000338static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
339 unsigned RegNo,
340 uint64_t Address,
341 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000342
343 if (RegNo > 31)
344 return MCDisassembler::Fail;
345
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000346 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000347 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000348 return MCDisassembler::Success;
349}
350
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000351static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
352 unsigned RegNo,
353 uint64_t Address,
354 const void *Decoder) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000355 if (RegNo > 31)
356 return MCDisassembler::Fail;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000357 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000358 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000359 return MCDisassembler::Success;
360}
361
Akira Hatanaka654655f2013-08-14 00:53:38 +0000362static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
363 unsigned RegNo,
364 uint64_t Address,
365 const void *Decoder) {
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000366 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000367}
368
Akira Hatanaka71928e62012-04-17 18:03:21 +0000369static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
370 unsigned RegNo,
371 uint64_t Address,
372 const void *Decoder) {
373 if (RegNo > 31)
374 return MCDisassembler::Fail;
375
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000376 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
377 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000378 return MCDisassembler::Success;
379}
380
381static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
382 unsigned RegNo,
383 uint64_t Address,
384 const void *Decoder) {
385 if (RegNo > 31)
386 return MCDisassembler::Fail;
387
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000388 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
389 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000390 return MCDisassembler::Success;
391}
392
393static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
394 unsigned RegNo,
395 uint64_t Address,
396 const void *Decoder) {
Chad Rosier253777f2013-06-26 22:23:32 +0000397 if (RegNo > 31)
398 return MCDisassembler::Fail;
399 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
400 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000401 return MCDisassembler::Success;
402}
403
Akira Hatanaka1fb1b8b2013-07-26 20:13:47 +0000404static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
405 unsigned RegNo,
406 uint64_t Address,
407 const void *Decoder) {
408 if (RegNo > 7)
409 return MCDisassembler::Fail;
410 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
411 Inst.addOperand(MCOperand::CreateReg(Reg));
412 return MCDisassembler::Success;
413}
414
Akira Hatanaka71928e62012-04-17 18:03:21 +0000415static DecodeStatus DecodeMem(MCInst &Inst,
416 unsigned Insn,
417 uint64_t Address,
418 const void *Decoder) {
419 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +0000420 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
421 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000422
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000423 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
424 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000425
426 if(Inst.getOpcode() == Mips::SC){
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000427 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000428 }
429
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000430 Inst.addOperand(MCOperand::CreateReg(Reg));
431 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000432 Inst.addOperand(MCOperand::CreateImm(Offset));
433
434 return MCDisassembler::Success;
435}
436
437static DecodeStatus DecodeFMem(MCInst &Inst,
438 unsigned Insn,
439 uint64_t Address,
440 const void *Decoder) {
441 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +0000442 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
443 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000444
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000445 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000446 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000447
448 Inst.addOperand(MCOperand::CreateReg(Reg));
449 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000450 Inst.addOperand(MCOperand::CreateImm(Offset));
451
452 return MCDisassembler::Success;
453}
454
455
456static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
457 unsigned RegNo,
458 uint64_t Address,
459 const void *Decoder) {
460 // Currently only hardware register 29 is supported.
461 if (RegNo != 29)
462 return MCDisassembler::Fail;
463 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
464 return MCDisassembler::Success;
465}
466
Akira Hatanaka71928e62012-04-17 18:03:21 +0000467static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
468 unsigned RegNo,
469 uint64_t Address,
470 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000471 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +0000472 return MCDisassembler::Fail;
473
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000474 ;
475 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
476 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000477 return MCDisassembler::Success;
478}
479
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000480static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
481 unsigned RegNo,
482 uint64_t Address,
483 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000484 if (RegNo >= 4)
485 return MCDisassembler::Fail;
486
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000487 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000488 Inst.addOperand(MCOperand::CreateReg(Reg));
489 return MCDisassembler::Success;
490}
491
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000492static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
493 unsigned RegNo,
494 uint64_t Address,
495 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000496 if (RegNo >= 4)
497 return MCDisassembler::Fail;
498
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000499 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000500 Inst.addOperand(MCOperand::CreateReg(Reg));
501 return MCDisassembler::Success;
502}
503
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000504static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
505 unsigned RegNo,
506 uint64_t Address,
507 const void *Decoder) {
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000508 if (RegNo >= 4)
509 return MCDisassembler::Fail;
510
Akira Hatanaka8002a3f2013-08-14 00:47:08 +0000511 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000512 Inst.addOperand(MCOperand::CreateReg(Reg));
513 return MCDisassembler::Success;
514}
515
Akira Hatanaka71928e62012-04-17 18:03:21 +0000516static DecodeStatus DecodeBranchTarget(MCInst &Inst,
517 unsigned Offset,
518 uint64_t Address,
519 const void *Decoder) {
520 unsigned BranchOffset = Offset & 0xffff;
521 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
522 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
523 return MCDisassembler::Success;
524}
525
Akira Hatanaka71928e62012-04-17 18:03:21 +0000526static DecodeStatus DecodeJumpTarget(MCInst &Inst,
527 unsigned Insn,
528 uint64_t Address,
529 const void *Decoder) {
530
Jim Grosbachecaef492012-08-14 19:06:05 +0000531 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000532 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
533 return MCDisassembler::Success;
534}
535
536
537static DecodeStatus DecodeSimm16(MCInst &Inst,
538 unsigned Insn,
539 uint64_t Address,
540 const void *Decoder) {
541 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
542 return MCDisassembler::Success;
543}
544
545static DecodeStatus DecodeInsSize(MCInst &Inst,
546 unsigned Insn,
547 uint64_t Address,
548 const void *Decoder) {
549 // First we need to grab the pos(lsb) from MCInst.
550 int Pos = Inst.getOperand(2).getImm();
551 int Size = (int) Insn - Pos + 1;
552 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
553 return MCDisassembler::Success;
554}
555
556static DecodeStatus DecodeExtSize(MCInst &Inst,
557 unsigned Insn,
558 uint64_t Address,
559 const void *Decoder) {
560 int Size = (int) Insn + 1;
561 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
562 return MCDisassembler::Success;
563}