blob: 042b456538c34181a3cb233490c2c86f6df89e08 [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"
15#include "MipsSubtarget.h"
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000016#include "MipsRegisterInfo.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000017#include "llvm/MC/EDInstInfo.h"
18#include "llvm/MC/MCDisassembler.h"
19#include "llvm/Support/MemoryObject.h"
20#include "llvm/Support/TargetRegistry.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/MC/MCInst.h"
Akira Hatanaka71928e62012-04-17 18:03:21 +000023#include "llvm/Support/MathExtras.h"
24
Akira Hatanaka71928e62012-04-17 18:03:21 +000025#include "MipsGenEDInfo.inc"
26
27using namespace llvm;
28
29typedef MCDisassembler::DecodeStatus DecodeStatus;
30
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000031namespace {
32
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000033/// MipsDisassemblerBase - a disasembler class for Mips.
34class MipsDisassemblerBase : public MCDisassembler {
Akira Hatanaka71928e62012-04-17 18:03:21 +000035public:
36 /// Constructor - Initializes the disassembler.
37 ///
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000038 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
39 bool bigEndian) :
40 MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000041
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000042 virtual ~MipsDisassemblerBase() {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000043
44 /// getEDInfo - See MCDisassembler.
45 const EDInstInfo *getEDInfo() const;
46
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000047 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
48
Akira Hatanaka71928e62012-04-17 18:03:21 +000049private:
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000050 const MCRegisterInfo *RegInfo;
51protected:
Akira Hatanaka71928e62012-04-17 18:03:21 +000052 bool isBigEndian;
53};
54
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000055/// MipsDisassembler - a disasembler class for Mips32.
56class MipsDisassembler : public MipsDisassemblerBase {
57public:
58 /// Constructor - Initializes the disassembler.
59 ///
60 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
61 bool bigEndian) :
62 MipsDisassemblerBase(STI, Info, bigEndian) {}
63
64 /// getInstruction - See MCDisassembler.
65 virtual DecodeStatus getInstruction(MCInst &instr,
66 uint64_t &size,
67 const MemoryObject &region,
68 uint64_t address,
69 raw_ostream &vStream,
70 raw_ostream &cStream) const;
71};
72
Akira Hatanaka71928e62012-04-17 18:03:21 +000073
74/// Mips64Disassembler - a disasembler class for Mips64.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000075class Mips64Disassembler : public MipsDisassemblerBase {
Akira Hatanaka71928e62012-04-17 18:03:21 +000076public:
77 /// Constructor - Initializes the disassembler.
78 ///
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000079 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
80 bool bigEndian) :
81 MipsDisassemblerBase(STI, Info, bigEndian) {}
Akira Hatanaka71928e62012-04-17 18:03:21 +000082
83 /// getInstruction - See MCDisassembler.
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000084 virtual DecodeStatus getInstruction(MCInst &instr,
85 uint64_t &size,
86 const MemoryObject &region,
87 uint64_t address,
88 raw_ostream &vStream,
89 raw_ostream &cStream) const;
Akira Hatanaka71928e62012-04-17 18:03:21 +000090};
91
Benjamin Kramercb3e98c2012-05-01 14:34:24 +000092} // end anonymous namespace
93
Akira Hatanaka9bf2b562012-07-09 18:46:47 +000094const EDInstInfo *MipsDisassemblerBase::getEDInfo() const {
Akira Hatanaka71928e62012-04-17 18:03:21 +000095 return instInfoMips;
96}
97
Akira Hatanaka71928e62012-04-17 18:03:21 +000098// Forward declare these because the autogenerated code will reference them.
99// Definitions are further down.
100static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
101 unsigned RegNo,
102 uint64_t Address,
103 const void *Decoder);
104
105static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
106 unsigned RegNo,
107 uint64_t Address,
108 const void *Decoder);
109
110static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
111 unsigned RegNo,
112 uint64_t Address,
113 const void *Decoder);
114
115static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
116 unsigned RegNo,
117 uint64_t Address,
118 const void *Decoder);
119
120static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
121 unsigned RegNo,
122 uint64_t Address,
123 const void *Decoder);
124
125static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
126 unsigned Insn,
127 uint64_t Address,
128 const void *Decoder);
129
130static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
131 unsigned RegNo,
132 uint64_t Address,
133 const void *Decoder);
134
135static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
136 unsigned Insn,
137 uint64_t Address,
138 const void *Decoder);
139
140static DecodeStatus DecodeBranchTarget(MCInst &Inst,
141 unsigned Offset,
142 uint64_t Address,
143 const void *Decoder);
144
145static DecodeStatus DecodeBC1(MCInst &Inst,
146 unsigned Insn,
147 uint64_t Address,
148 const void *Decoder);
149
150
151static DecodeStatus DecodeJumpTarget(MCInst &Inst,
152 unsigned Insn,
153 uint64_t Address,
154 const void *Decoder);
155
156static DecodeStatus DecodeMem(MCInst &Inst,
157 unsigned Insn,
158 uint64_t Address,
159 const void *Decoder);
160
161static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
162 uint64_t Address,
163 const void *Decoder);
164
165static DecodeStatus DecodeSimm16(MCInst &Inst,
166 unsigned Insn,
167 uint64_t Address,
168 const void *Decoder);
169
170static DecodeStatus DecodeCondCode(MCInst &Inst,
171 unsigned Insn,
172 uint64_t Address,
173 const void *Decoder);
174
175static DecodeStatus DecodeInsSize(MCInst &Inst,
176 unsigned Insn,
177 uint64_t Address,
178 const void *Decoder);
179
180static DecodeStatus DecodeExtSize(MCInst &Inst,
181 unsigned Insn,
182 uint64_t Address,
183 const void *Decoder);
184
185namespace llvm {
186extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
187 TheMips64elTarget;
188}
189
190static MCDisassembler *createMipsDisassembler(
191 const Target &T,
192 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000193 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000194}
195
196static MCDisassembler *createMipselDisassembler(
197 const Target &T,
198 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000199 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000200}
201
202static MCDisassembler *createMips64Disassembler(
203 const Target &T,
204 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000205 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000206}
207
208static MCDisassembler *createMips64elDisassembler(
209 const Target &T,
210 const MCSubtargetInfo &STI) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000211 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000212}
213
214extern "C" void LLVMInitializeMipsDisassembler() {
215 // Register the disassembler.
216 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
217 createMipsDisassembler);
218 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
219 createMipselDisassembler);
220 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
221 createMips64Disassembler);
222 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
223 createMips64elDisassembler);
224}
225
226
227#include "MipsGenDisassemblerTables.inc"
228
229 /// readInstruction - read four bytes from the MemoryObject
230 /// and return 32 bit word sorted according to the given endianess
231static DecodeStatus readInstruction32(const MemoryObject &region,
232 uint64_t address,
233 uint64_t &size,
234 uint32_t &insn,
235 bool isBigEndian) {
236 uint8_t Bytes[4];
237
238 // We want to read exactly 4 Bytes of data.
239 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
240 size = 0;
241 return MCDisassembler::Fail;
242 }
243
244 if (isBigEndian) {
245 // Encoded as a big-endian 32-bit word in the stream.
246 insn = (Bytes[3] << 0) |
247 (Bytes[2] << 8) |
248 (Bytes[1] << 16) |
249 (Bytes[0] << 24);
250 }
251 else {
252 // Encoded as a small-endian 32-bit word in the stream.
253 insn = (Bytes[0] << 0) |
254 (Bytes[1] << 8) |
255 (Bytes[2] << 16) |
256 (Bytes[3] << 24);
257 }
258
259 return MCDisassembler::Success;
260}
261
262DecodeStatus
263MipsDisassembler::getInstruction(MCInst &instr,
264 uint64_t &Size,
265 const MemoryObject &Region,
266 uint64_t Address,
267 raw_ostream &vStream,
268 raw_ostream &cStream) const {
269 uint32_t Insn;
270
271 DecodeStatus Result = readInstruction32(Region, Address, Size,
272 Insn, isBigEndian);
273 if (Result == MCDisassembler::Fail)
274 return MCDisassembler::Fail;
275
276 // Calling the auto-generated decoder function.
277 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
278 if (Result != MCDisassembler::Fail) {
279 Size = 4;
280 return Result;
281 }
282
283 return MCDisassembler::Fail;
284}
285
286DecodeStatus
287Mips64Disassembler::getInstruction(MCInst &instr,
288 uint64_t &Size,
289 const MemoryObject &Region,
290 uint64_t Address,
291 raw_ostream &vStream,
292 raw_ostream &cStream) const {
293 uint32_t Insn;
294
295 DecodeStatus Result = readInstruction32(Region, Address, Size,
296 Insn, isBigEndian);
297 if (Result == MCDisassembler::Fail)
298 return MCDisassembler::Fail;
299
300 // Calling the auto-generated decoder function.
301 Result = decodeMips64Instruction32(instr, Insn, Address, this, STI);
302 if (Result != MCDisassembler::Fail) {
303 Size = 4;
304 return Result;
305 }
306 // If we fail to decode in Mips64 decoder space we can try in Mips32
307 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
308 if (Result != MCDisassembler::Fail) {
309 Size = 4;
310 return Result;
311 }
312
313 return MCDisassembler::Fail;
314}
315
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000316static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
317 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
318 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
319}
320
Akira Hatanaka71928e62012-04-17 18:03:21 +0000321static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
322 unsigned RegNo,
323 uint64_t Address,
324 const void *Decoder) {
325
326 if (RegNo > 31)
327 return MCDisassembler::Fail;
328
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000329 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
330 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000331 return MCDisassembler::Success;
332}
333
334static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
335 unsigned RegNo,
336 uint64_t Address,
337 const void *Decoder) {
338 if (RegNo > 31)
339 return MCDisassembler::Fail;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000340 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
341 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000342 return MCDisassembler::Success;
343}
344
345static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
346 unsigned RegNo,
347 uint64_t Address,
348 const void *Decoder) {
349 if (RegNo > 31)
350 return MCDisassembler::Fail;
351
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000352 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
353 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000354 return MCDisassembler::Success;
355}
356
357static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
358 unsigned RegNo,
359 uint64_t Address,
360 const void *Decoder) {
361 if (RegNo > 31)
362 return MCDisassembler::Fail;
363
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000364 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
365 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000366 return MCDisassembler::Success;
367}
368
369static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
370 unsigned RegNo,
371 uint64_t Address,
372 const void *Decoder) {
373 Inst.addOperand(MCOperand::CreateReg(RegNo));
374 return MCDisassembler::Success;
375}
376
377static DecodeStatus DecodeMem(MCInst &Inst,
378 unsigned Insn,
379 uint64_t Address,
380 const void *Decoder) {
381 int Offset = SignExtend32<16>(Insn & 0xffff);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000382 unsigned Reg = fieldFromInstruction32(Insn, 16, 5);
383 unsigned Base = fieldFromInstruction32(Insn, 21, 5);
384
385 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
386 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000387
388 if(Inst.getOpcode() == Mips::SC){
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000389 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000390 }
391
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000392 Inst.addOperand(MCOperand::CreateReg(Reg));
393 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000394 Inst.addOperand(MCOperand::CreateImm(Offset));
395
396 return MCDisassembler::Success;
397}
398
399static DecodeStatus DecodeFMem(MCInst &Inst,
400 unsigned Insn,
401 uint64_t Address,
402 const void *Decoder) {
403 int Offset = SignExtend32<16>(Insn & 0xffff);
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000404 unsigned Reg = fieldFromInstruction32(Insn, 16, 5);
405 unsigned Base = fieldFromInstruction32(Insn, 21, 5);
Akira Hatanaka71928e62012-04-17 18:03:21 +0000406
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000407 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
408 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
409
410 Inst.addOperand(MCOperand::CreateReg(Reg));
411 Inst.addOperand(MCOperand::CreateReg(Base));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000412 Inst.addOperand(MCOperand::CreateImm(Offset));
413
414 return MCDisassembler::Success;
415}
416
417
418static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
419 unsigned RegNo,
420 uint64_t Address,
421 const void *Decoder) {
422 // Currently only hardware register 29 is supported.
423 if (RegNo != 29)
424 return MCDisassembler::Fail;
425 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
426 return MCDisassembler::Success;
427}
428
429static DecodeStatus DecodeCondCode(MCInst &Inst,
430 unsigned Insn,
431 uint64_t Address,
432 const void *Decoder) {
433 int CondCode = Insn & 0xf;
434 Inst.addOperand(MCOperand::CreateImm(CondCode));
435 return MCDisassembler::Success;
436}
437
438static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
439 unsigned RegNo,
440 uint64_t Address,
441 const void *Decoder) {
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000442 if (RegNo > 30 || RegNo %2)
Akira Hatanaka71928e62012-04-17 18:03:21 +0000443 return MCDisassembler::Fail;
444
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000445 ;
446 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
447 Inst.addOperand(MCOperand::CreateReg(Reg));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000448 return MCDisassembler::Success;
449}
450
451static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
452 unsigned RegNo,
453 uint64_t Address,
454 const void *Decoder) {
455 //Currently only hardware register 29 is supported
456 if (RegNo != 29)
457 return MCDisassembler::Fail;
Akira Hatanaka9bf2b562012-07-09 18:46:47 +0000458 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
Akira Hatanaka71928e62012-04-17 18:03:21 +0000459 return MCDisassembler::Success;
460}
461
462static DecodeStatus DecodeBranchTarget(MCInst &Inst,
463 unsigned Offset,
464 uint64_t Address,
465 const void *Decoder) {
466 unsigned BranchOffset = Offset & 0xffff;
467 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
468 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
469 return MCDisassembler::Success;
470}
471
472static DecodeStatus DecodeBC1(MCInst &Inst,
473 unsigned Insn,
474 uint64_t Address,
475 const void *Decoder) {
476 unsigned BranchOffset = Insn & 0xffff;
477 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
478 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
479 return MCDisassembler::Success;
480}
481
482static DecodeStatus DecodeJumpTarget(MCInst &Inst,
483 unsigned Insn,
484 uint64_t Address,
485 const void *Decoder) {
486
487 unsigned JumpOffset = fieldFromInstruction32(Insn, 0, 26) << 2;
488 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
489 return MCDisassembler::Success;
490}
491
492
493static DecodeStatus DecodeSimm16(MCInst &Inst,
494 unsigned Insn,
495 uint64_t Address,
496 const void *Decoder) {
497 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
498 return MCDisassembler::Success;
499}
500
501static DecodeStatus DecodeInsSize(MCInst &Inst,
502 unsigned Insn,
503 uint64_t Address,
504 const void *Decoder) {
505 // First we need to grab the pos(lsb) from MCInst.
506 int Pos = Inst.getOperand(2).getImm();
507 int Size = (int) Insn - Pos + 1;
508 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
509 return MCDisassembler::Success;
510}
511
512static DecodeStatus DecodeExtSize(MCInst &Inst,
513 unsigned Insn,
514 uint64_t Address,
515 const void *Decoder) {
516 int Size = (int) Insn + 1;
517 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
518 return MCDisassembler::Success;
519}