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 25 using namespace llvm; 26 27 typedef MCDisassembler::DecodeStatus DecodeStatus; 28 29 namespace { 30 31 /// MipsDisassemblerBase - a disasembler class for Mips. 32 class MipsDisassemblerBase : public MCDisassembler { 33 public: 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 47 private: 48 OwningPtr<const MCRegisterInfo> RegInfo; 49 bool IsN64; 50 protected: 51 bool isBigEndian; 52 }; 53 54 /// MipsDisassembler - a disasembler class for Mips32. 55 class MipsDisassembler : public MipsDisassemblerBase { 56 public: 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. 74 class Mips64Disassembler : public MipsDisassemblerBase { 75 public: 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. 95 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 96 unsigned RegNo, 97 uint64_t Address, 98 const void *Decoder); 99 100 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 101 unsigned RegNo, 102 uint64_t Address, 103 const void *Decoder); 104 105 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 106 unsigned RegNo, 107 uint64_t Address, 108 const void *Decoder); 109 110 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 111 unsigned Insn, 112 uint64_t Address, 113 const void *Decoder); 114 115 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 116 unsigned RegNo, 117 uint64_t Address, 118 const void *Decoder); 119 120 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 121 unsigned RegNo, 122 uint64_t Address, 123 const void *Decoder); 124 125 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 126 unsigned RegNo, 127 uint64_t Address, 128 const void *Decoder); 129 130 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst, 131 unsigned RegNo, 132 uint64_t Address, 133 const void *Decoder); 134 135 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 136 unsigned RegNo, 137 uint64_t Address, 138 const void *Decoder); 139 140 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 141 unsigned RegNo, 142 uint64_t Address, 143 const void *Decoder); 144 145 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 146 unsigned Insn, 147 uint64_t Address, 148 const void *Decoder); 149 150 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 151 unsigned RegNo, 152 uint64_t Address, 153 const void *Decoder); 154 155 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 156 unsigned RegNo, 157 uint64_t Address, 158 const void *Decoder); 159 160 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 161 unsigned RegNo, 162 uint64_t Address, 163 const void *Decoder); 164 165 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 166 unsigned RegNo, 167 uint64_t Address, 168 const void *Decoder); 169 170 static DecodeStatus DecodeBranchTarget(MCInst &Inst, 171 unsigned Offset, 172 uint64_t Address, 173 const void *Decoder); 174 175 static DecodeStatus DecodeJumpTarget(MCInst &Inst, 176 unsigned Insn, 177 uint64_t Address, 178 const void *Decoder); 179 180 static DecodeStatus DecodeMem(MCInst &Inst, 181 unsigned Insn, 182 uint64_t Address, 183 const void *Decoder); 184 185 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 186 uint64_t Address, 187 const void *Decoder); 188 189 static DecodeStatus DecodeSimm16(MCInst &Inst, 190 unsigned Insn, 191 uint64_t Address, 192 const void *Decoder); 193 194 static DecodeStatus DecodeInsSize(MCInst &Inst, 195 unsigned Insn, 196 uint64_t Address, 197 const void *Decoder); 198 199 static DecodeStatus DecodeExtSize(MCInst &Inst, 200 unsigned Insn, 201 uint64_t Address, 202 const void *Decoder); 203 204 namespace llvm { 205 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 206 TheMips64elTarget; 207 } 208 209 static MCDisassembler *createMipsDisassembler( 210 const Target &T, 211 const MCSubtargetInfo &STI) { 212 return new MipsDisassembler(STI, T.createMCRegInfo(""), true); 213 } 214 215 static MCDisassembler *createMipselDisassembler( 216 const Target &T, 217 const MCSubtargetInfo &STI) { 218 return new MipsDisassembler(STI, T.createMCRegInfo(""), false); 219 } 220 221 static MCDisassembler *createMips64Disassembler( 222 const Target &T, 223 const MCSubtargetInfo &STI) { 224 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); 225 } 226 227 static MCDisassembler *createMips64elDisassembler( 228 const Target &T, 229 const MCSubtargetInfo &STI) { 230 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); 231 } 232 233 extern "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 250 static 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 281 DecodeStatus 282 MipsDisassembler::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 306 DecodeStatus 307 Mips64Disassembler::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 338 static 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 343 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 344 unsigned RegNo, 345 uint64_t Address, 346 const void *Decoder) { 347 348 return MCDisassembler::Fail; 349 350 } 351 352 static 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 365 static 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 376 static 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 386 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 387 unsigned RegNo, 388 uint64_t Address, 389 const void *Decoder) { 390 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 391 } 392 393 static 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 405 static 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 417 static 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 429 static 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 440 static 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 451 static 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 473 static 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 492 static 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 503 static 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 516 static 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 528 static 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 540 static 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 552 static 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 562 static 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 573 static 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 581 static 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 592 static 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