MipsDisassembler.cpp revision edaf85606d7ac8368dd7fa0e9fd4042e523a6e3a
1//===- 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 "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" 24 25using namespace llvm; 26 27typedef MCDisassembler::DecodeStatus DecodeStatus; 28 29namespace { 30 31/// MipsDisassemblerBase - a disasembler class for Mips. 32class MipsDisassemblerBase : public MCDisassembler { 33public: 34 /// Constructor - Initializes the disassembler. 35 /// 36 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 37 bool bigEndian) : 38 MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {} 39 40 virtual ~MipsDisassemblerBase() {} 41 42 const MCRegisterInfo *getRegInfo() const { return RegInfo; } 43 44private: 45 const MCRegisterInfo *RegInfo; 46protected: 47 bool isBigEndian; 48}; 49 50/// 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 ®ion, 63 uint64_t address, 64 raw_ostream &vStream, 65 raw_ostream &cStream) const; 66}; 67 68 69/// Mips64Disassembler - a disasembler class for Mips64. 70class Mips64Disassembler : public MipsDisassemblerBase { 71public: 72 /// Constructor - Initializes the disassembler. 73 /// 74 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 75 bool bigEndian) : 76 MipsDisassemblerBase(STI, Info, bigEndian) {} 77 78 /// getInstruction - See MCDisassembler. 79 virtual DecodeStatus getInstruction(MCInst &instr, 80 uint64_t &size, 81 const MemoryObject ®ion, 82 uint64_t address, 83 raw_ostream &vStream, 84 raw_ostream &cStream) const; 85}; 86 87} // end anonymous namespace 88 89// 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 96static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 97 unsigned RegNo, 98 uint64_t Address, 99 const void *Decoder); 100 101static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, 102 unsigned RegNo, 103 uint64_t Address, 104 const void *Decoder); 105 106static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 107 unsigned RegNo, 108 uint64_t Address, 109 const void *Decoder); 110 111static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 112 unsigned RegNo, 113 uint64_t Address, 114 const void *Decoder); 115 116static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 117 unsigned RegNo, 118 uint64_t Address, 119 const void *Decoder); 120 121static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 122 unsigned Insn, 123 uint64_t Address, 124 const void *Decoder); 125 126static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 127 unsigned RegNo, 128 uint64_t Address, 129 const void *Decoder); 130 131static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst, 132 unsigned RegNo, 133 uint64_t Address, 134 const void *Decoder); 135 136static DecodeStatus DecodeBranchTarget(MCInst &Inst, 137 unsigned Offset, 138 uint64_t Address, 139 const void *Decoder); 140 141static DecodeStatus DecodeBC1(MCInst &Inst, 142 unsigned Insn, 143 uint64_t Address, 144 const void *Decoder); 145 146 147static DecodeStatus DecodeJumpTarget(MCInst &Inst, 148 unsigned Insn, 149 uint64_t Address, 150 const void *Decoder); 151 152static DecodeStatus DecodeMem(MCInst &Inst, 153 unsigned Insn, 154 uint64_t Address, 155 const void *Decoder); 156 157static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 158 uint64_t Address, 159 const void *Decoder); 160 161static DecodeStatus DecodeSimm16(MCInst &Inst, 162 unsigned Insn, 163 uint64_t Address, 164 const void *Decoder); 165 166static DecodeStatus DecodeCondCode(MCInst &Inst, 167 unsigned Insn, 168 uint64_t Address, 169 const void *Decoder); 170 171static DecodeStatus DecodeInsSize(MCInst &Inst, 172 unsigned Insn, 173 uint64_t Address, 174 const void *Decoder); 175 176static DecodeStatus DecodeExtSize(MCInst &Inst, 177 unsigned Insn, 178 uint64_t Address, 179 const void *Decoder); 180 181namespace llvm { 182extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 183 TheMips64elTarget; 184} 185 186static MCDisassembler *createMipsDisassembler( 187 const Target &T, 188 const MCSubtargetInfo &STI) { 189 return new MipsDisassembler(STI, T.createMCRegInfo(""), true); 190} 191 192static MCDisassembler *createMipselDisassembler( 193 const Target &T, 194 const MCSubtargetInfo &STI) { 195 return new MipsDisassembler(STI, T.createMCRegInfo(""), false); 196} 197 198static MCDisassembler *createMips64Disassembler( 199 const Target &T, 200 const MCSubtargetInfo &STI) { 201 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); 202} 203 204static MCDisassembler *createMips64elDisassembler( 205 const Target &T, 206 const MCSubtargetInfo &STI) { 207 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); 208} 209 210extern "C" void LLVMInitializeMipsDisassembler() { 211 // Register the disassembler. 212 TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 213 createMipsDisassembler); 214 TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 215 createMipselDisassembler); 216 TargetRegistry::RegisterMCDisassembler(TheMips64Target, 217 createMips64Disassembler); 218 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 219 createMips64elDisassembler); 220} 221 222 223#include "MipsGenDisassemblerTables.inc" 224 225 /// readInstruction - read four bytes from the MemoryObject 226 /// and return 32 bit word sorted according to the given endianess 227static DecodeStatus readInstruction32(const MemoryObject ®ion, 228 uint64_t address, 229 uint64_t &size, 230 uint32_t &insn, 231 bool isBigEndian) { 232 uint8_t Bytes[4]; 233 234 // We want to read exactly 4 Bytes of data. 235 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) { 236 size = 0; 237 return MCDisassembler::Fail; 238 } 239 240 if (isBigEndian) { 241 // Encoded as a big-endian 32-bit word in the stream. 242 insn = (Bytes[3] << 0) | 243 (Bytes[2] << 8) | 244 (Bytes[1] << 16) | 245 (Bytes[0] << 24); 246 } 247 else { 248 // Encoded as a small-endian 32-bit word in the stream. 249 insn = (Bytes[0] << 0) | 250 (Bytes[1] << 8) | 251 (Bytes[2] << 16) | 252 (Bytes[3] << 24); 253 } 254 255 return MCDisassembler::Success; 256} 257 258DecodeStatus 259MipsDisassembler::getInstruction(MCInst &instr, 260 uint64_t &Size, 261 const MemoryObject &Region, 262 uint64_t Address, 263 raw_ostream &vStream, 264 raw_ostream &cStream) const { 265 uint32_t Insn; 266 267 DecodeStatus Result = readInstruction32(Region, Address, Size, 268 Insn, isBigEndian); 269 if (Result == MCDisassembler::Fail) 270 return MCDisassembler::Fail; 271 272 // Calling the auto-generated decoder function. 273 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 274 this, STI); 275 if (Result != MCDisassembler::Fail) { 276 Size = 4; 277 return Result; 278 } 279 280 return MCDisassembler::Fail; 281} 282 283DecodeStatus 284Mips64Disassembler::getInstruction(MCInst &instr, 285 uint64_t &Size, 286 const MemoryObject &Region, 287 uint64_t Address, 288 raw_ostream &vStream, 289 raw_ostream &cStream) const { 290 uint32_t Insn; 291 292 DecodeStatus Result = readInstruction32(Region, Address, Size, 293 Insn, isBigEndian); 294 if (Result == MCDisassembler::Fail) 295 return MCDisassembler::Fail; 296 297 // Calling the auto-generated decoder function. 298 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address, 299 this, STI); 300 if (Result != MCDisassembler::Fail) { 301 Size = 4; 302 return Result; 303 } 304 // If we fail to decode in Mips64 decoder space we can try in Mips32 305 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 306 this, STI); 307 if (Result != MCDisassembler::Fail) { 308 Size = 4; 309 return Result; 310 } 311 312 return MCDisassembler::Fail; 313} 314 315static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 316 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 317 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo); 318} 319 320static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 321 unsigned RegNo, 322 uint64_t Address, 323 const void *Decoder) { 324 325 if (RegNo > 31) 326 return MCDisassembler::Fail; 327 328 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo); 329 Inst.addOperand(MCOperand::CreateReg(Reg)); 330 return MCDisassembler::Success; 331} 332 333static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 334 unsigned RegNo, 335 uint64_t Address, 336 const void *Decoder) { 337 if (RegNo > 31) 338 return MCDisassembler::Fail; 339 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo); 340 Inst.addOperand(MCOperand::CreateReg(Reg)); 341 return MCDisassembler::Success; 342} 343 344static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, 345 unsigned RegNo, 346 uint64_t Address, 347 const void *Decoder) { 348 return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder); 349} 350 351static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 352 unsigned RegNo, 353 uint64_t Address, 354 const void *Decoder) { 355 if (RegNo > 31) 356 return MCDisassembler::Fail; 357 358 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 359 Inst.addOperand(MCOperand::CreateReg(Reg)); 360 return MCDisassembler::Success; 361} 362 363static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 364 unsigned RegNo, 365 uint64_t Address, 366 const void *Decoder) { 367 if (RegNo > 31) 368 return MCDisassembler::Fail; 369 370 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 371 Inst.addOperand(MCOperand::CreateReg(Reg)); 372 return MCDisassembler::Success; 373} 374 375static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 376 unsigned RegNo, 377 uint64_t Address, 378 const void *Decoder) { 379 Inst.addOperand(MCOperand::CreateReg(RegNo)); 380 return MCDisassembler::Success; 381} 382 383static DecodeStatus DecodeMem(MCInst &Inst, 384 unsigned Insn, 385 uint64_t Address, 386 const void *Decoder) { 387 int Offset = SignExtend32<16>(Insn & 0xffff); 388 unsigned Reg = fieldFromInstruction(Insn, 16, 5); 389 unsigned Base = fieldFromInstruction(Insn, 21, 5); 390 391 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg); 392 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 393 394 if(Inst.getOpcode() == Mips::SC){ 395 Inst.addOperand(MCOperand::CreateReg(Reg)); 396 } 397 398 Inst.addOperand(MCOperand::CreateReg(Reg)); 399 Inst.addOperand(MCOperand::CreateReg(Base)); 400 Inst.addOperand(MCOperand::CreateImm(Offset)); 401 402 return MCDisassembler::Success; 403} 404 405static DecodeStatus DecodeFMem(MCInst &Inst, 406 unsigned Insn, 407 uint64_t Address, 408 const void *Decoder) { 409 int Offset = SignExtend32<16>(Insn & 0xffff); 410 unsigned Reg = fieldFromInstruction(Insn, 16, 5); 411 unsigned Base = fieldFromInstruction(Insn, 21, 5); 412 413 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 414 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 415 416 Inst.addOperand(MCOperand::CreateReg(Reg)); 417 Inst.addOperand(MCOperand::CreateReg(Base)); 418 Inst.addOperand(MCOperand::CreateImm(Offset)); 419 420 return MCDisassembler::Success; 421} 422 423 424static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 425 unsigned RegNo, 426 uint64_t Address, 427 const void *Decoder) { 428 // Currently only hardware register 29 is supported. 429 if (RegNo != 29) 430 return MCDisassembler::Fail; 431 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 432 return MCDisassembler::Success; 433} 434 435static DecodeStatus DecodeCondCode(MCInst &Inst, 436 unsigned Insn, 437 uint64_t Address, 438 const void *Decoder) { 439 int CondCode = Insn & 0xf; 440 Inst.addOperand(MCOperand::CreateImm(CondCode)); 441 return MCDisassembler::Success; 442} 443 444static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 445 unsigned RegNo, 446 uint64_t Address, 447 const void *Decoder) { 448 if (RegNo > 30 || RegNo %2) 449 return MCDisassembler::Fail; 450 451 ; 452 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 453 Inst.addOperand(MCOperand::CreateReg(Reg)); 454 return MCDisassembler::Success; 455} 456 457static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst, 458 unsigned RegNo, 459 uint64_t Address, 460 const void *Decoder) { 461 if (RegNo >= 4) 462 return MCDisassembler::Fail; 463 464 unsigned Reg = getReg(Decoder, Mips::ACRegsRegClassID, RegNo); 465 Inst.addOperand(MCOperand::CreateReg(Reg)); 466 return MCDisassembler::Success; 467} 468 469static DecodeStatus DecodeBranchTarget(MCInst &Inst, 470 unsigned Offset, 471 uint64_t Address, 472 const void *Decoder) { 473 unsigned BranchOffset = Offset & 0xffff; 474 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 475 Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 476 return MCDisassembler::Success; 477} 478 479static DecodeStatus DecodeBC1(MCInst &Inst, 480 unsigned Insn, 481 uint64_t Address, 482 const void *Decoder) { 483 unsigned BranchOffset = Insn & 0xffff; 484 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 485 Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 486 return MCDisassembler::Success; 487} 488 489static DecodeStatus DecodeJumpTarget(MCInst &Inst, 490 unsigned Insn, 491 uint64_t Address, 492 const void *Decoder) { 493 494 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 495 Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 496 return MCDisassembler::Success; 497} 498 499 500static DecodeStatus DecodeSimm16(MCInst &Inst, 501 unsigned Insn, 502 uint64_t Address, 503 const void *Decoder) { 504 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 505 return MCDisassembler::Success; 506} 507 508static DecodeStatus DecodeInsSize(MCInst &Inst, 509 unsigned Insn, 510 uint64_t Address, 511 const void *Decoder) { 512 // First we need to grab the pos(lsb) from MCInst. 513 int Pos = Inst.getOperand(2).getImm(); 514 int Size = (int) Insn - Pos + 1; 515 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 516 return MCDisassembler::Success; 517} 518 519static DecodeStatus DecodeExtSize(MCInst &Inst, 520 unsigned Insn, 521 uint64_t Address, 522 const void *Decoder) { 523 int Size = (int) Insn + 1; 524 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 525 return MCDisassembler::Success; 526} 527