1 //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is part of the Mips Disassembler.
12 //===----------------------------------------------------------------------===//
15 #include "MipsRegisterInfo.h"
16 #include "MipsSubtarget.h"
17 #include "llvm/MC/MCDisassembler.h"
18 #include "llvm/MC/MCFixedLenDisassembler.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/Support/MathExtras.h"
22 #include "llvm/Support/MemoryObject.h"
23 #include "llvm/Support/TargetRegistry.h"
27 typedef MCDisassembler::DecodeStatus DecodeStatus;
31 /// MipsDisassemblerBase - a disasembler class for Mips.
32 class MipsDisassemblerBase : public MCDisassembler {
34 /// Constructor - Initializes the disassembler.
36 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
38 MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
40 virtual ~MipsDisassemblerBase() {}
42 const MCRegisterInfo *getRegInfo() const { return RegInfo; }
45 const MCRegisterInfo *RegInfo;
50 /// MipsDisassembler - a disasembler class for Mips32.
51 class MipsDisassembler : public MipsDisassemblerBase {
53 /// Constructor - Initializes the disassembler.
55 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
57 MipsDisassemblerBase(STI, Info, bigEndian) {}
59 /// getInstruction - See MCDisassembler.
60 virtual DecodeStatus getInstruction(MCInst &instr,
62 const MemoryObject ®ion,
65 raw_ostream &cStream) const;
69 /// Mips64Disassembler - a disasembler class for Mips64.
70 class Mips64Disassembler : public MipsDisassemblerBase {
72 /// Constructor - Initializes the disassembler.
74 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
76 MipsDisassemblerBase(STI, Info, bigEndian) {}
78 /// getInstruction - See MCDisassembler.
79 virtual DecodeStatus getInstruction(MCInst &instr,
81 const MemoryObject ®ion,
84 raw_ostream &cStream) const;
87 } // end anonymous namespace
89 // Forward declare these because the autogenerated code will reference them.
90 // Definitions are further down.
91 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
96 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
101 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
104 const void *Decoder);
106 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
109 const void *Decoder);
111 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
114 const void *Decoder);
116 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
119 const void *Decoder);
121 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
124 const void *Decoder);
126 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
129 const void *Decoder);
131 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
134 const void *Decoder);
136 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
139 const void *Decoder);
141 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
144 const void *Decoder);
146 static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst,
149 const void *Decoder);
151 static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst,
154 const void *Decoder);
156 static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst,
159 const void *Decoder);
161 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
164 const void *Decoder);
166 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
169 const void *Decoder);
171 static DecodeStatus DecodeMem(MCInst &Inst,
174 const void *Decoder);
176 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
178 const void *Decoder);
180 static DecodeStatus DecodeSimm16(MCInst &Inst,
183 const void *Decoder);
185 static DecodeStatus DecodeInsSize(MCInst &Inst,
188 const void *Decoder);
190 static DecodeStatus DecodeExtSize(MCInst &Inst,
193 const void *Decoder);
196 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
200 static MCDisassembler *createMipsDisassembler(
202 const MCSubtargetInfo &STI) {
203 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
206 static MCDisassembler *createMipselDisassembler(
208 const MCSubtargetInfo &STI) {
209 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
212 static MCDisassembler *createMips64Disassembler(
214 const MCSubtargetInfo &STI) {
215 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
218 static MCDisassembler *createMips64elDisassembler(
220 const MCSubtargetInfo &STI) {
221 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
224 extern "C" void LLVMInitializeMipsDisassembler() {
225 // Register the disassembler.
226 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
227 createMipsDisassembler);
228 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
229 createMipselDisassembler);
230 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
231 createMips64Disassembler);
232 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
233 createMips64elDisassembler);
237 #include "MipsGenDisassemblerTables.inc"
239 /// readInstruction - read four bytes from the MemoryObject
240 /// and return 32 bit word sorted according to the given endianess
241 static DecodeStatus readInstruction32(const MemoryObject ®ion,
248 // We want to read exactly 4 Bytes of data.
249 if (region.readBytes(address, 4, Bytes) == -1) {
251 return MCDisassembler::Fail;
255 // Encoded as a big-endian 32-bit word in the stream.
256 insn = (Bytes[3] << 0) |
262 // Encoded as a small-endian 32-bit word in the stream.
263 insn = (Bytes[0] << 0) |
269 return MCDisassembler::Success;
273 MipsDisassembler::getInstruction(MCInst &instr,
275 const MemoryObject &Region,
277 raw_ostream &vStream,
278 raw_ostream &cStream) const {
281 DecodeStatus Result = readInstruction32(Region, Address, Size,
283 if (Result == MCDisassembler::Fail)
284 return MCDisassembler::Fail;
286 // Calling the auto-generated decoder function.
287 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
289 if (Result != MCDisassembler::Fail) {
294 return MCDisassembler::Fail;
298 Mips64Disassembler::getInstruction(MCInst &instr,
300 const MemoryObject &Region,
302 raw_ostream &vStream,
303 raw_ostream &cStream) const {
306 DecodeStatus Result = readInstruction32(Region, Address, Size,
308 if (Result == MCDisassembler::Fail)
309 return MCDisassembler::Fail;
311 // Calling the auto-generated decoder function.
312 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
314 if (Result != MCDisassembler::Fail) {
318 // If we fail to decode in Mips64 decoder space we can try in Mips32
319 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
321 if (Result != MCDisassembler::Fail) {
326 return MCDisassembler::Fail;
329 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
330 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
331 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
334 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
337 const void *Decoder) {
339 return MCDisassembler::Fail;
343 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
346 const void *Decoder) {
349 return MCDisassembler::Fail;
351 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
352 Inst.addOperand(MCOperand::CreateReg(Reg));
353 return MCDisassembler::Success;
356 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
359 const void *Decoder) {
361 return MCDisassembler::Fail;
362 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
363 Inst.addOperand(MCOperand::CreateReg(Reg));
364 return MCDisassembler::Success;
367 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
370 const void *Decoder) {
371 return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
374 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
377 const void *Decoder) {
379 return MCDisassembler::Fail;
381 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
382 Inst.addOperand(MCOperand::CreateReg(Reg));
383 return MCDisassembler::Success;
386 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
389 const void *Decoder) {
391 return MCDisassembler::Fail;
393 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
394 Inst.addOperand(MCOperand::CreateReg(Reg));
395 return MCDisassembler::Success;
398 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
401 const void *Decoder) {
403 return MCDisassembler::Fail;
404 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
405 Inst.addOperand(MCOperand::CreateReg(Reg));
406 return MCDisassembler::Success;
409 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
412 const void *Decoder) {
414 return MCDisassembler::Fail;
415 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
416 Inst.addOperand(MCOperand::CreateReg(Reg));
417 return MCDisassembler::Success;
420 static DecodeStatus DecodeMem(MCInst &Inst,
423 const void *Decoder) {
424 int Offset = SignExtend32<16>(Insn & 0xffff);
425 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
426 unsigned Base = fieldFromInstruction(Insn, 21, 5);
428 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
429 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
431 if(Inst.getOpcode() == Mips::SC){
432 Inst.addOperand(MCOperand::CreateReg(Reg));
435 Inst.addOperand(MCOperand::CreateReg(Reg));
436 Inst.addOperand(MCOperand::CreateReg(Base));
437 Inst.addOperand(MCOperand::CreateImm(Offset));
439 return MCDisassembler::Success;
442 static DecodeStatus DecodeFMem(MCInst &Inst,
445 const void *Decoder) {
446 int Offset = SignExtend32<16>(Insn & 0xffff);
447 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
448 unsigned Base = fieldFromInstruction(Insn, 21, 5);
450 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
451 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
453 Inst.addOperand(MCOperand::CreateReg(Reg));
454 Inst.addOperand(MCOperand::CreateReg(Base));
455 Inst.addOperand(MCOperand::CreateImm(Offset));
457 return MCDisassembler::Success;
461 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
464 const void *Decoder) {
465 // Currently only hardware register 29 is supported.
467 return MCDisassembler::Fail;
468 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
469 return MCDisassembler::Success;
472 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
475 const void *Decoder) {
476 if (RegNo > 30 || RegNo %2)
477 return MCDisassembler::Fail;
480 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
481 Inst.addOperand(MCOperand::CreateReg(Reg));
482 return MCDisassembler::Success;
485 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
488 const void *Decoder) {
489 //Currently only hardware register 29 is supported
491 return MCDisassembler::Fail;
492 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
493 return MCDisassembler::Success;
496 static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst,
499 const void *Decoder) {
501 return MCDisassembler::Fail;
503 unsigned Reg = getReg(Decoder, Mips::ACRegsDSPRegClassID, RegNo);
504 Inst.addOperand(MCOperand::CreateReg(Reg));
505 return MCDisassembler::Success;
508 static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst,
511 const void *Decoder) {
513 return MCDisassembler::Fail;
515 unsigned Reg = getReg(Decoder, Mips::HIRegsDSPRegClassID, RegNo);
516 Inst.addOperand(MCOperand::CreateReg(Reg));
517 return MCDisassembler::Success;
520 static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst,
523 const void *Decoder) {
525 return MCDisassembler::Fail;
527 unsigned Reg = getReg(Decoder, Mips::LORegsDSPRegClassID, RegNo);
528 Inst.addOperand(MCOperand::CreateReg(Reg));
529 return MCDisassembler::Success;
532 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
535 const void *Decoder) {
536 unsigned BranchOffset = Offset & 0xffff;
537 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
538 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
539 return MCDisassembler::Success;
542 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
545 const void *Decoder) {
547 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
548 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
549 return MCDisassembler::Success;
553 static DecodeStatus DecodeSimm16(MCInst &Inst,
556 const void *Decoder) {
557 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
558 return MCDisassembler::Success;
561 static DecodeStatus DecodeInsSize(MCInst &Inst,
564 const void *Decoder) {
565 // First we need to grab the pos(lsb) from MCInst.
566 int Pos = Inst.getOperand(2).getImm();
567 int Size = (int) Insn - Pos + 1;
568 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
569 return MCDisassembler::Success;
572 static DecodeStatus DecodeExtSize(MCInst &Inst,
575 const void *Decoder) {
576 int Size = (int) Insn + 1;
577 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
578 return MCDisassembler::Success;