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