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