LLVM API Documentation
00001 //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file is part of the Mips Disassembler. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "Mips.h" 00015 #include "MipsRegisterInfo.h" 00016 #include "MipsSubtarget.h" 00017 #include "llvm/MC/MCDisassembler.h" 00018 #include "llvm/MC/MCFixedLenDisassembler.h" 00019 #include "llvm/MC/MCInst.h" 00020 #include "llvm/MC/MCSubtargetInfo.h" 00021 #include "llvm/Support/MathExtras.h" 00022 #include "llvm/Support/MemoryObject.h" 00023 #include "llvm/Support/TargetRegistry.h" 00024 00025 using namespace llvm; 00026 00027 typedef MCDisassembler::DecodeStatus DecodeStatus; 00028 00029 namespace { 00030 00031 /// MipsDisassemblerBase - a disasembler class for Mips. 00032 class MipsDisassemblerBase : public MCDisassembler { 00033 public: 00034 /// Constructor - Initializes the disassembler. 00035 /// 00036 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 00037 bool bigEndian) : 00038 MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {} 00039 00040 virtual ~MipsDisassemblerBase() {} 00041 00042 const MCRegisterInfo *getRegInfo() const { return RegInfo; } 00043 00044 private: 00045 const MCRegisterInfo *RegInfo; 00046 protected: 00047 bool isBigEndian; 00048 }; 00049 00050 /// MipsDisassembler - a disasembler class for Mips32. 00051 class MipsDisassembler : public MipsDisassemblerBase { 00052 public: 00053 /// Constructor - Initializes the disassembler. 00054 /// 00055 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 00056 bool bigEndian) : 00057 MipsDisassemblerBase(STI, Info, bigEndian) {} 00058 00059 /// getInstruction - See MCDisassembler. 00060 virtual DecodeStatus getInstruction(MCInst &instr, 00061 uint64_t &size, 00062 const MemoryObject ®ion, 00063 uint64_t address, 00064 raw_ostream &vStream, 00065 raw_ostream &cStream) const; 00066 }; 00067 00068 00069 /// Mips64Disassembler - a disasembler class for Mips64. 00070 class Mips64Disassembler : public MipsDisassemblerBase { 00071 public: 00072 /// Constructor - Initializes the disassembler. 00073 /// 00074 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 00075 bool bigEndian) : 00076 MipsDisassemblerBase(STI, Info, bigEndian) {} 00077 00078 /// getInstruction - See MCDisassembler. 00079 virtual DecodeStatus getInstruction(MCInst &instr, 00080 uint64_t &size, 00081 const MemoryObject ®ion, 00082 uint64_t address, 00083 raw_ostream &vStream, 00084 raw_ostream &cStream) const; 00085 }; 00086 00087 } // end anonymous namespace 00088 00089 // Forward declare these because the autogenerated code will reference them. 00090 // Definitions are further down. 00091 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 00092 unsigned RegNo, 00093 uint64_t Address, 00094 const void *Decoder); 00095 00096 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 00097 unsigned RegNo, 00098 uint64_t Address, 00099 const void *Decoder); 00100 00101 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 00102 unsigned RegNo, 00103 uint64_t Address, 00104 const void *Decoder); 00105 00106 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, 00107 unsigned RegNo, 00108 uint64_t Address, 00109 const void *Decoder); 00110 00111 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 00112 unsigned RegNo, 00113 uint64_t Address, 00114 const void *Decoder); 00115 00116 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 00117 unsigned RegNo, 00118 uint64_t Address, 00119 const void *Decoder); 00120 00121 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 00122 unsigned RegNo, 00123 uint64_t Address, 00124 const void *Decoder); 00125 00126 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 00127 unsigned Insn, 00128 uint64_t Address, 00129 const void *Decoder); 00130 00131 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 00132 unsigned RegNo, 00133 uint64_t Address, 00134 const void *Decoder); 00135 00136 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 00137 unsigned Insn, 00138 uint64_t Address, 00139 const void *Decoder); 00140 00141 static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst, 00142 unsigned RegNo, 00143 uint64_t Address, 00144 const void *Decoder); 00145 00146 static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst, 00147 unsigned RegNo, 00148 uint64_t Address, 00149 const void *Decoder); 00150 00151 static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst, 00152 unsigned RegNo, 00153 uint64_t Address, 00154 const void *Decoder); 00155 00156 static DecodeStatus DecodeBranchTarget(MCInst &Inst, 00157 unsigned Offset, 00158 uint64_t Address, 00159 const void *Decoder); 00160 00161 static DecodeStatus DecodeBC1(MCInst &Inst, 00162 unsigned Insn, 00163 uint64_t Address, 00164 const void *Decoder); 00165 00166 00167 static DecodeStatus DecodeJumpTarget(MCInst &Inst, 00168 unsigned Insn, 00169 uint64_t Address, 00170 const void *Decoder); 00171 00172 static DecodeStatus DecodeMem(MCInst &Inst, 00173 unsigned Insn, 00174 uint64_t Address, 00175 const void *Decoder); 00176 00177 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 00178 uint64_t Address, 00179 const void *Decoder); 00180 00181 static DecodeStatus DecodeSimm16(MCInst &Inst, 00182 unsigned Insn, 00183 uint64_t Address, 00184 const void *Decoder); 00185 00186 static DecodeStatus DecodeCondCode(MCInst &Inst, 00187 unsigned Insn, 00188 uint64_t Address, 00189 const void *Decoder); 00190 00191 static DecodeStatus DecodeInsSize(MCInst &Inst, 00192 unsigned Insn, 00193 uint64_t Address, 00194 const void *Decoder); 00195 00196 static DecodeStatus DecodeExtSize(MCInst &Inst, 00197 unsigned Insn, 00198 uint64_t Address, 00199 const void *Decoder); 00200 00201 namespace llvm { 00202 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 00203 TheMips64elTarget; 00204 } 00205 00206 static MCDisassembler *createMipsDisassembler( 00207 const Target &T, 00208 const MCSubtargetInfo &STI) { 00209 return new MipsDisassembler(STI, T.createMCRegInfo(""), true); 00210 } 00211 00212 static MCDisassembler *createMipselDisassembler( 00213 const Target &T, 00214 const MCSubtargetInfo &STI) { 00215 return new MipsDisassembler(STI, T.createMCRegInfo(""), false); 00216 } 00217 00218 static MCDisassembler *createMips64Disassembler( 00219 const Target &T, 00220 const MCSubtargetInfo &STI) { 00221 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); 00222 } 00223 00224 static MCDisassembler *createMips64elDisassembler( 00225 const Target &T, 00226 const MCSubtargetInfo &STI) { 00227 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); 00228 } 00229 00230 extern "C" void LLVMInitializeMipsDisassembler() { 00231 // Register the disassembler. 00232 TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 00233 createMipsDisassembler); 00234 TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 00235 createMipselDisassembler); 00236 TargetRegistry::RegisterMCDisassembler(TheMips64Target, 00237 createMips64Disassembler); 00238 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 00239 createMips64elDisassembler); 00240 } 00241 00242 00243 #include "MipsGenDisassemblerTables.inc" 00244 00245 /// readInstruction - read four bytes from the MemoryObject 00246 /// and return 32 bit word sorted according to the given endianess 00247 static DecodeStatus readInstruction32(const MemoryObject ®ion, 00248 uint64_t address, 00249 uint64_t &size, 00250 uint32_t &insn, 00251 bool isBigEndian) { 00252 uint8_t Bytes[4]; 00253 00254 // We want to read exactly 4 Bytes of data. 00255 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) { 00256 size = 0; 00257 return MCDisassembler::Fail; 00258 } 00259 00260 if (isBigEndian) { 00261 // Encoded as a big-endian 32-bit word in the stream. 00262 insn = (Bytes[3] << 0) | 00263 (Bytes[2] << 8) | 00264 (Bytes[1] << 16) | 00265 (Bytes[0] << 24); 00266 } 00267 else { 00268 // Encoded as a small-endian 32-bit word in the stream. 00269 insn = (Bytes[0] << 0) | 00270 (Bytes[1] << 8) | 00271 (Bytes[2] << 16) | 00272 (Bytes[3] << 24); 00273 } 00274 00275 return MCDisassembler::Success; 00276 } 00277 00278 DecodeStatus 00279 MipsDisassembler::getInstruction(MCInst &instr, 00280 uint64_t &Size, 00281 const MemoryObject &Region, 00282 uint64_t Address, 00283 raw_ostream &vStream, 00284 raw_ostream &cStream) const { 00285 uint32_t Insn; 00286 00287 DecodeStatus Result = readInstruction32(Region, Address, Size, 00288 Insn, isBigEndian); 00289 if (Result == MCDisassembler::Fail) 00290 return MCDisassembler::Fail; 00291 00292 // Calling the auto-generated decoder function. 00293 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 00294 this, STI); 00295 if (Result != MCDisassembler::Fail) { 00296 Size = 4; 00297 return Result; 00298 } 00299 00300 return MCDisassembler::Fail; 00301 } 00302 00303 DecodeStatus 00304 Mips64Disassembler::getInstruction(MCInst &instr, 00305 uint64_t &Size, 00306 const MemoryObject &Region, 00307 uint64_t Address, 00308 raw_ostream &vStream, 00309 raw_ostream &cStream) const { 00310 uint32_t Insn; 00311 00312 DecodeStatus Result = readInstruction32(Region, Address, Size, 00313 Insn, isBigEndian); 00314 if (Result == MCDisassembler::Fail) 00315 return MCDisassembler::Fail; 00316 00317 // Calling the auto-generated decoder function. 00318 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address, 00319 this, STI); 00320 if (Result != MCDisassembler::Fail) { 00321 Size = 4; 00322 return Result; 00323 } 00324 // If we fail to decode in Mips64 decoder space we can try in Mips32 00325 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 00326 this, STI); 00327 if (Result != MCDisassembler::Fail) { 00328 Size = 4; 00329 return Result; 00330 } 00331 00332 return MCDisassembler::Fail; 00333 } 00334 00335 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 00336 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 00337 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo); 00338 } 00339 00340 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 00341 unsigned RegNo, 00342 uint64_t Address, 00343 const void *Decoder) { 00344 00345 return MCDisassembler::Fail; 00346 00347 } 00348 00349 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 00350 unsigned RegNo, 00351 uint64_t Address, 00352 const void *Decoder) { 00353 00354 if (RegNo > 31) 00355 return MCDisassembler::Fail; 00356 00357 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo); 00358 Inst.addOperand(MCOperand::CreateReg(Reg)); 00359 return MCDisassembler::Success; 00360 } 00361 00362 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 00363 unsigned RegNo, 00364 uint64_t Address, 00365 const void *Decoder) { 00366 if (RegNo > 31) 00367 return MCDisassembler::Fail; 00368 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo); 00369 Inst.addOperand(MCOperand::CreateReg(Reg)); 00370 return MCDisassembler::Success; 00371 } 00372 00373 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, 00374 unsigned RegNo, 00375 uint64_t Address, 00376 const void *Decoder) { 00377 return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder); 00378 } 00379 00380 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 00381 unsigned RegNo, 00382 uint64_t Address, 00383 const void *Decoder) { 00384 if (RegNo > 31) 00385 return MCDisassembler::Fail; 00386 00387 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 00388 Inst.addOperand(MCOperand::CreateReg(Reg)); 00389 return MCDisassembler::Success; 00390 } 00391 00392 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 00393 unsigned RegNo, 00394 uint64_t Address, 00395 const void *Decoder) { 00396 if (RegNo > 31) 00397 return MCDisassembler::Fail; 00398 00399 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 00400 Inst.addOperand(MCOperand::CreateReg(Reg)); 00401 return MCDisassembler::Success; 00402 } 00403 00404 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 00405 unsigned RegNo, 00406 uint64_t Address, 00407 const void *Decoder) { 00408 Inst.addOperand(MCOperand::CreateReg(RegNo)); 00409 return MCDisassembler::Success; 00410 } 00411 00412 static DecodeStatus DecodeMem(MCInst &Inst, 00413 unsigned Insn, 00414 uint64_t Address, 00415 const void *Decoder) { 00416 int Offset = SignExtend32<16>(Insn & 0xffff); 00417 unsigned Reg = fieldFromInstruction(Insn, 16, 5); 00418 unsigned Base = fieldFromInstruction(Insn, 21, 5); 00419 00420 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg); 00421 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 00422 00423 if(Inst.getOpcode() == Mips::SC){ 00424 Inst.addOperand(MCOperand::CreateReg(Reg)); 00425 } 00426 00427 Inst.addOperand(MCOperand::CreateReg(Reg)); 00428 Inst.addOperand(MCOperand::CreateReg(Base)); 00429 Inst.addOperand(MCOperand::CreateImm(Offset)); 00430 00431 return MCDisassembler::Success; 00432 } 00433 00434 static DecodeStatus DecodeFMem(MCInst &Inst, 00435 unsigned Insn, 00436 uint64_t Address, 00437 const void *Decoder) { 00438 int Offset = SignExtend32<16>(Insn & 0xffff); 00439 unsigned Reg = fieldFromInstruction(Insn, 16, 5); 00440 unsigned Base = fieldFromInstruction(Insn, 21, 5); 00441 00442 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 00443 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 00444 00445 Inst.addOperand(MCOperand::CreateReg(Reg)); 00446 Inst.addOperand(MCOperand::CreateReg(Base)); 00447 Inst.addOperand(MCOperand::CreateImm(Offset)); 00448 00449 return MCDisassembler::Success; 00450 } 00451 00452 00453 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 00454 unsigned RegNo, 00455 uint64_t Address, 00456 const void *Decoder) { 00457 // Currently only hardware register 29 is supported. 00458 if (RegNo != 29) 00459 return MCDisassembler::Fail; 00460 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 00461 return MCDisassembler::Success; 00462 } 00463 00464 static DecodeStatus DecodeCondCode(MCInst &Inst, 00465 unsigned Insn, 00466 uint64_t Address, 00467 const void *Decoder) { 00468 int CondCode = Insn & 0xf; 00469 Inst.addOperand(MCOperand::CreateImm(CondCode)); 00470 return MCDisassembler::Success; 00471 } 00472 00473 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 00474 unsigned RegNo, 00475 uint64_t Address, 00476 const void *Decoder) { 00477 if (RegNo > 30 || RegNo %2) 00478 return MCDisassembler::Fail; 00479 00480 ; 00481 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 00482 Inst.addOperand(MCOperand::CreateReg(Reg)); 00483 return MCDisassembler::Success; 00484 } 00485 00486 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 00487 unsigned RegNo, 00488 uint64_t Address, 00489 const void *Decoder) { 00490 //Currently only hardware register 29 is supported 00491 if (RegNo != 29) 00492 return MCDisassembler::Fail; 00493 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64)); 00494 return MCDisassembler::Success; 00495 } 00496 00497 static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst, 00498 unsigned RegNo, 00499 uint64_t Address, 00500 const void *Decoder) { 00501 if (RegNo >= 4) 00502 return MCDisassembler::Fail; 00503 00504 unsigned Reg = getReg(Decoder, Mips::ACRegsDSPRegClassID, RegNo); 00505 Inst.addOperand(MCOperand::CreateReg(Reg)); 00506 return MCDisassembler::Success; 00507 } 00508 00509 static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst, 00510 unsigned RegNo, 00511 uint64_t Address, 00512 const void *Decoder) { 00513 if (RegNo >= 4) 00514 return MCDisassembler::Fail; 00515 00516 unsigned Reg = getReg(Decoder, Mips::HIRegsDSPRegClassID, RegNo); 00517 Inst.addOperand(MCOperand::CreateReg(Reg)); 00518 return MCDisassembler::Success; 00519 } 00520 00521 static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst, 00522 unsigned RegNo, 00523 uint64_t Address, 00524 const void *Decoder) { 00525 if (RegNo >= 4) 00526 return MCDisassembler::Fail; 00527 00528 unsigned Reg = getReg(Decoder, Mips::LORegsDSPRegClassID, RegNo); 00529 Inst.addOperand(MCOperand::CreateReg(Reg)); 00530 return MCDisassembler::Success; 00531 } 00532 00533 static DecodeStatus DecodeBranchTarget(MCInst &Inst, 00534 unsigned Offset, 00535 uint64_t Address, 00536 const void *Decoder) { 00537 unsigned BranchOffset = Offset & 0xffff; 00538 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 00539 Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 00540 return MCDisassembler::Success; 00541 } 00542 00543 static DecodeStatus DecodeBC1(MCInst &Inst, 00544 unsigned Insn, 00545 uint64_t Address, 00546 const void *Decoder) { 00547 unsigned BranchOffset = Insn & 0xffff; 00548 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 00549 Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 00550 return MCDisassembler::Success; 00551 } 00552 00553 static DecodeStatus DecodeJumpTarget(MCInst &Inst, 00554 unsigned Insn, 00555 uint64_t Address, 00556 const void *Decoder) { 00557 00558 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 00559 Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 00560 return MCDisassembler::Success; 00561 } 00562 00563 00564 static DecodeStatus DecodeSimm16(MCInst &Inst, 00565 unsigned Insn, 00566 uint64_t Address, 00567 const void *Decoder) { 00568 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 00569 return MCDisassembler::Success; 00570 } 00571 00572 static DecodeStatus DecodeInsSize(MCInst &Inst, 00573 unsigned Insn, 00574 uint64_t Address, 00575 const void *Decoder) { 00576 // First we need to grab the pos(lsb) from MCInst. 00577 int Pos = Inst.getOperand(2).getImm(); 00578 int Size = (int) Insn - Pos + 1; 00579 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 00580 return MCDisassembler::Success; 00581 } 00582 00583 static DecodeStatus DecodeExtSize(MCInst &Inst, 00584 unsigned Insn, 00585 uint64_t Address, 00586 const void *Decoder) { 00587 int Size = (int) Insn + 1; 00588 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 00589 return MCDisassembler::Success; 00590 }