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