blob: 4af67037e970ad75b1cef0458143aea6a3dae270 [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
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000042 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
43
Akira Hatanaka71928e62012-04-17 18:03:21 +000044private:
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000045 const MCRegisterInfo *RegInfo;
46protected:
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.
91static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
92 unsigned RegNo,
93 uint64_t Address,
94 const void *Decoder);
95
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 Hatanaka71928e62012-04-17 18:03:21 +0000101static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
102 unsigned RegNo,
103 uint64_t Address,
104 const void *Decoder);
105
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000106static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
107 unsigned RegNo,
108 uint64_t Address,
109 const void *Decoder);
110
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
126static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
127 unsigned Insn,
128 uint64_t Address,
129 const void *Decoder);
130
131static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
132 unsigned RegNo,
133 uint64_t Address,
134 const void *Decoder);
135
Jack Carter2a74a87b2013-01-17 00:28:20 +0000136static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
137 unsigned Insn,
138 uint64_t Address,
139 const void *Decoder);
140
Akira Hatanakafb221c12013-03-30 01:58:00 +0000141static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst,
142 unsigned RegNo,
143 uint64_t Address,
144 const void *Decoder);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000145
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000146static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst,
147 unsigned RegNo,
148 uint64_t Address,
149 const void *Decoder);
150
151static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst,
152 unsigned RegNo,
153 uint64_t Address,
154 const void *Decoder);
155
Akira Hatanaka71928e62012-04-17 18:03:21 +0000156static DecodeStatus DecodeBranchTarget(MCInst &Inst,
157 unsigned Offset,
158 uint64_t Address,
159 const void *Decoder);
160
161static DecodeStatus DecodeBC1(MCInst &Inst,
162 unsigned Insn,
163 uint64_t Address,
164 const void *Decoder);
165
166
167static DecodeStatus DecodeJumpTarget(MCInst &Inst,
168 unsigned Insn,
169 uint64_t Address,
170 const void *Decoder);
171
172static DecodeStatus DecodeMem(MCInst &Inst,
173 unsigned Insn,
174 uint64_t Address,
175 const void *Decoder);
176
177static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
178 uint64_t Address,
179 const void *Decoder);
180
181static DecodeStatus DecodeSimm16(MCInst &Inst,
182 unsigned Insn,
183 uint64_t Address,
184 const void *Decoder);
185
186static DecodeStatus DecodeCondCode(MCInst &Inst,
187 unsigned Insn,
188 uint64_t Address,
189 const void *Decoder);
190
191static DecodeStatus DecodeInsSize(MCInst &Inst,
192 unsigned Insn,
193 uint64_t Address,
194 const void *Decoder);
195
196static DecodeStatus DecodeExtSize(MCInst &Inst,
197 unsigned Insn,
198 uint64_t Address,
199 const void *Decoder);
200
201namespace llvm {
202extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
203 TheMips64elTarget;
204}
205
206static MCDisassembler *createMipsDisassembler(
207 const Target &T,
208 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000209 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000210}
211
212static MCDisassembler *createMipselDisassembler(
213 const Target &T,
214 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000215 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000216}
217
218static MCDisassembler *createMips64Disassembler(
219 const Target &T,
220 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000221 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000222}
223
224static MCDisassembler *createMips64elDisassembler(
225 const Target &T,
226 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000227 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000228}
229
230extern "C" void LLVMInitializeMipsDisassembler() {
231 // Register the disassembler.
232 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
233 createMipsDisassembler);
234 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
235 createMipselDisassembler);
236 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
237 createMips64Disassembler);
238 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
239 createMips64elDisassembler);
240}
241
242
243#include "MipsGenDisassemblerTables.inc"
244
245 /// readInstruction - read four bytes from the MemoryObject
246 /// and return 32 bit word sorted according to the given endianess
247static DecodeStatus readInstruction32(const MemoryObject &region,
248 uint64_t address,
249 uint64_t &size,
250 uint32_t &insn,
251 bool isBigEndian) {
252 uint8_t Bytes[4];
253
254 // We want to read exactly 4 Bytes of data.
Benjamin Kramer534d3a42013-05-24 10:54:58 +0000255 if (region.readBytes(address, 4, Bytes) == -1) {
Akira Hatanaka71928e62012-04-17 18:03:21 +0000256 size = 0;
257 return MCDisassembler::Fail;
258 }
259
260 if (isBigEndian) {
261 // Encoded as a big-endian 32-bit word in the stream.
262 insn = (Bytes[3] << 0) |
263 (Bytes[2] << 8) |
264 (Bytes[1] << 16) |
265 (Bytes[0] << 24);
266 }
267 else {
268 // Encoded as a small-endian 32-bit word in the stream.
269 insn = (Bytes[0] << 0) |
270 (Bytes[1] << 8) |
271 (Bytes[2] << 16) |
272 (Bytes[3] << 24);
273 }
274
275 return MCDisassembler::Success;
276}
277
278DecodeStatus
279MipsDisassembler::getInstruction(MCInst &instr,
280 uint64_t &Size,
281 const MemoryObject &Region,
282 uint64_t Address,
283 raw_ostream &vStream,
284 raw_ostream &cStream) const {
285 uint32_t Insn;
286
287 DecodeStatus Result = readInstruction32(Region, Address, Size,
288 Insn, isBigEndian);
289 if (Result == MCDisassembler::Fail)
290 return MCDisassembler::Fail;
291
292 // Calling the auto-generated decoder function.
Jim Grosbachecaef492012-08-14 19:06:05 +0000293 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
294 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000295 if (Result != MCDisassembler::Fail) {
296 Size = 4;
297 return Result;
298 }
299
300 return MCDisassembler::Fail;
301}
302
303DecodeStatus
304Mips64Disassembler::getInstruction(MCInst &instr,
305 uint64_t &Size,
306 const MemoryObject &Region,
307 uint64_t Address,
308 raw_ostream &vStream,
309 raw_ostream &cStream) const {
310 uint32_t Insn;
311
312 DecodeStatus Result = readInstruction32(Region, Address, Size,
313 Insn, isBigEndian);
314 if (Result == MCDisassembler::Fail)
315 return MCDisassembler::Fail;
316
317 // Calling the auto-generated decoder function.
Jim Grosbachecaef492012-08-14 19:06:05 +0000318 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
319 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000320 if (Result != MCDisassembler::Fail) {
321 Size = 4;
322 return Result;
323 }
324 // If we fail to decode in Mips64 decoder space we can try in Mips32
Jim Grosbachecaef492012-08-14 19:06:05 +0000325 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
326 this, STI);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000327 if (Result != MCDisassembler::Fail) {
328 Size = 4;
329 return Result;
330 }
331
332 return MCDisassembler::Fail;
333}
334
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000335static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
336 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
337 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
338}
339
Reed Kotlerec8a5492013-02-14 03:05:25 +0000340static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
341 unsigned RegNo,
342 uint64_t Address,
343 const void *Decoder) {
344
345 return MCDisassembler::Fail;
346
347}
348
Akira Hatanaka71928e62012-04-17 18:03:21 +0000349static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
350 unsigned RegNo,
351 uint64_t Address,
352 const void *Decoder) {
353
354 if (RegNo > 31)
355 return MCDisassembler::Fail;
356
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000357 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
358 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000359 return MCDisassembler::Success;
360}
361
362static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
363 unsigned RegNo,
364 uint64_t Address,
365 const void *Decoder) {
366 if (RegNo > 31)
367 return MCDisassembler::Fail;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000368 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
369 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000370 return MCDisassembler::Success;
371}
372
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000373static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
374 unsigned RegNo,
375 uint64_t Address,
376 const void *Decoder) {
377 return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
378}
379
Akira Hatanaka71928e62012-04-17 18:03:21 +0000380static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
381 unsigned RegNo,
382 uint64_t Address,
383 const void *Decoder) {
384 if (RegNo > 31)
385 return MCDisassembler::Fail;
386
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000387 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
388 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000389 return MCDisassembler::Success;
390}
391
392static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
393 unsigned RegNo,
394 uint64_t Address,
395 const void *Decoder) {
396 if (RegNo > 31)
397 return MCDisassembler::Fail;
398
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000399 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
400 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000401 return MCDisassembler::Success;
402}
403
404static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
405 unsigned RegNo,
406 uint64_t Address,
407 const void *Decoder) {
408 Inst.addOperand(MCOperand::CreateReg(RegNo));
409 return MCDisassembler::Success;
410}
411
412static DecodeStatus DecodeMem(MCInst &Inst,
413 unsigned Insn,
414 uint64_t Address,
415 const void *Decoder) {
416 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +0000417 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
418 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000419
420 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
421 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000422
423 if(Inst.getOpcode() == Mips::SC){
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000424 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000425 }
426
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000427 Inst.addOperand(MCOperand::CreateReg(Reg));
428 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000429 Inst.addOperand(MCOperand::CreateImm(Offset));
430
431 return MCDisassembler::Success;
432}
433
434static DecodeStatus DecodeFMem(MCInst &Inst,
435 unsigned Insn,
436 uint64_t Address,
437 const void *Decoder) {
438 int Offset = SignExtend32<16>(Insn & 0xffff);
Jim Grosbachecaef492012-08-14 19:06:05 +0000439 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
440 unsigned Base = fieldFromInstruction(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000441
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000442 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
443 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
444
445 Inst.addOperand(MCOperand::CreateReg(Reg));
446 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000447 Inst.addOperand(MCOperand::CreateImm(Offset));
448
449 return MCDisassembler::Success;
450}
451
452
453static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
454 unsigned RegNo,
455 uint64_t Address,
456 const void *Decoder) {
457 // Currently only hardware register 29 is supported.
458 if (RegNo != 29)
459 return MCDisassembler::Fail;
460 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
461 return MCDisassembler::Success;
462}
463
464static DecodeStatus DecodeCondCode(MCInst &Inst,
465 unsigned Insn,
466 uint64_t Address,
467 const void *Decoder) {
468 int CondCode = Insn & 0xf;
469 Inst.addOperand(MCOperand::CreateImm(CondCode));
470 return MCDisassembler::Success;
471}
472
473static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
474 unsigned RegNo,
475 uint64_t Address,
476 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000477 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +0000478 return MCDisassembler::Fail;
479
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000480 ;
481 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
482 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000483 return MCDisassembler::Success;
484}
485
Jack Carter2a74a87b2013-01-17 00:28:20 +0000486static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
487 unsigned RegNo,
488 uint64_t Address,
489 const void *Decoder) {
490 //Currently only hardware register 29 is supported
491 if (RegNo != 29)
492 return MCDisassembler::Fail;
493 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
494 return MCDisassembler::Success;
495}
496
Akira Hatanakafb221c12013-03-30 01:58:00 +0000497static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst,
498 unsigned RegNo,
499 uint64_t Address,
500 const void *Decoder) {
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000501 if (RegNo >= 4)
502 return MCDisassembler::Fail;
503
Akira Hatanakafb221c12013-03-30 01:58:00 +0000504 unsigned Reg = getReg(Decoder, Mips::ACRegsDSPRegClassID, RegNo);
Akira Hatanakaecabd1a2012-09-27 02:01:10 +0000505 Inst.addOperand(MCOperand::CreateReg(Reg));
506 return MCDisassembler::Success;
507}
508
Akira Hatanaka59bfaf72013-04-18 00:52:44 +0000509static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst,
510 unsigned RegNo,
511 uint64_t Address,
512 const void *Decoder) {
513 if (RegNo >= 4)
514 return MCDisassembler::Fail;
515
516 unsigned Reg = getReg(Decoder, Mips::HIRegsDSPRegClassID, RegNo);
517 Inst.addOperand(MCOperand::CreateReg(Reg));
518 return MCDisassembler::Success;
519}
520
521static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst,
522 unsigned RegNo,
523 uint64_t Address,
524 const void *Decoder) {
525 if (RegNo >= 4)
526 return MCDisassembler::Fail;
527
528 unsigned Reg = getReg(Decoder, Mips::LORegsDSPRegClassID, RegNo);
529 Inst.addOperand(MCOperand::CreateReg(Reg));
530 return MCDisassembler::Success;
531}
532
Akira Hatanaka71928e62012-04-17 18:03:21 +0000533static DecodeStatus DecodeBranchTarget(MCInst &Inst,
534 unsigned Offset,
535 uint64_t Address,
536 const void *Decoder) {
537 unsigned BranchOffset = Offset & 0xffff;
538 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
539 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
540 return MCDisassembler::Success;
541}
542
543static DecodeStatus DecodeBC1(MCInst &Inst,
544 unsigned Insn,
545 uint64_t Address,
546 const void *Decoder) {
547 unsigned BranchOffset = Insn & 0xffff;
548 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
549 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
550 return MCDisassembler::Success;
551}
552
553static DecodeStatus DecodeJumpTarget(MCInst &Inst,
554 unsigned Insn,
555 uint64_t Address,
556 const void *Decoder) {
557
Jim Grosbachecaef492012-08-14 19:06:05 +0000558 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
Akira Hatanaka71928e62012-04-17 18:03:21 +0000559 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
560 return MCDisassembler::Success;
561}
562
563
564static DecodeStatus DecodeSimm16(MCInst &Inst,
565 unsigned Insn,
566 uint64_t Address,
567 const void *Decoder) {
568 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
569 return MCDisassembler::Success;
570}
571
572static DecodeStatus DecodeInsSize(MCInst &Inst,
573 unsigned Insn,
574 uint64_t Address,
575 const void *Decoder) {
576 // First we need to grab the pos(lsb) from MCInst.
577 int Pos = Inst.getOperand(2).getImm();
578 int Size = (int) Insn - Pos + 1;
579 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
580 return MCDisassembler::Success;
581}
582
583static DecodeStatus DecodeExtSize(MCInst &Inst,
584 unsigned Insn,
585 uint64_t Address,
586 const void *Decoder) {
587 int Size = (int) Insn + 1;
588 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
589 return MCDisassembler::Success;
590}