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 DecodeInsSize(MCInst &Inst, 187 unsigned Insn, 188 uint64_t Address, 189 const void *Decoder); 190 191 static DecodeStatus DecodeExtSize(MCInst &Inst, 192 unsigned Insn, 193 uint64_t Address, 194 const void *Decoder); 195 196 namespace llvm { 197 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 198 TheMips64elTarget; 199 } 200 201 static MCDisassembler *createMipsDisassembler( 202 const Target &T, 203 const MCSubtargetInfo &STI) { 204 return new MipsDisassembler(STI, T.createMCRegInfo(""), true); 205 } 206 207 static MCDisassembler *createMipselDisassembler( 208 const Target &T, 209 const MCSubtargetInfo &STI) { 210 return new MipsDisassembler(STI, T.createMCRegInfo(""), false); 211 } 212 213 static MCDisassembler *createMips64Disassembler( 214 const Target &T, 215 const MCSubtargetInfo &STI) { 216 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); 217 } 218 219 static MCDisassembler *createMips64elDisassembler( 220 const Target &T, 221 const MCSubtargetInfo &STI) { 222 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); 223 } 224 225 extern "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 242 static 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, Bytes) == -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 273 DecodeStatus 274 MipsDisassembler::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 298 DecodeStatus 299 Mips64Disassembler::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 330 static 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 335 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 336 unsigned RegNo, 337 uint64_t Address, 338 const void *Decoder) { 339 340 return MCDisassembler::Fail; 341 342 } 343 344 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 345 unsigned RegNo, 346 uint64_t Address, 347 const void *Decoder) { 348 349 if (RegNo > 31) 350 return MCDisassembler::Fail; 351 352 unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo); 353 Inst.addOperand(MCOperand::CreateReg(Reg)); 354 return MCDisassembler::Success; 355 } 356 357 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 358 unsigned RegNo, 359 uint64_t Address, 360 const void *Decoder) { 361 if (RegNo > 31) 362 return MCDisassembler::Fail; 363 unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo); 364 Inst.addOperand(MCOperand::CreateReg(Reg)); 365 return MCDisassembler::Success; 366 } 367 368 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, 369 unsigned RegNo, 370 uint64_t Address, 371 const void *Decoder) { 372 return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder); 373 } 374 375 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 376 unsigned RegNo, 377 uint64_t Address, 378 const void *Decoder) { 379 if (RegNo > 31) 380 return MCDisassembler::Fail; 381 382 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 383 Inst.addOperand(MCOperand::CreateReg(Reg)); 384 return MCDisassembler::Success; 385 } 386 387 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 388 unsigned RegNo, 389 uint64_t Address, 390 const void *Decoder) { 391 if (RegNo > 31) 392 return MCDisassembler::Fail; 393 394 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 395 Inst.addOperand(MCOperand::CreateReg(Reg)); 396 return MCDisassembler::Success; 397 } 398 399 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 400 unsigned RegNo, 401 uint64_t Address, 402 const void *Decoder) { 403 if (RegNo > 31) 404 return MCDisassembler::Fail; 405 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 406 Inst.addOperand(MCOperand::CreateReg(Reg)); 407 return MCDisassembler::Success; 408 } 409 410 static DecodeStatus DecodeMem(MCInst &Inst, 411 unsigned Insn, 412 uint64_t Address, 413 const void *Decoder) { 414 int Offset = SignExtend32<16>(Insn & 0xffff); 415 unsigned Reg = fieldFromInstruction(Insn, 16, 5); 416 unsigned Base = fieldFromInstruction(Insn, 21, 5); 417 418 Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg); 419 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 420 421 if(Inst.getOpcode() == Mips::SC){ 422 Inst.addOperand(MCOperand::CreateReg(Reg)); 423 } 424 425 Inst.addOperand(MCOperand::CreateReg(Reg)); 426 Inst.addOperand(MCOperand::CreateReg(Base)); 427 Inst.addOperand(MCOperand::CreateImm(Offset)); 428 429 return MCDisassembler::Success; 430 } 431 432 static DecodeStatus DecodeFMem(MCInst &Inst, 433 unsigned Insn, 434 uint64_t Address, 435 const void *Decoder) { 436 int Offset = SignExtend32<16>(Insn & 0xffff); 437 unsigned Reg = fieldFromInstruction(Insn, 16, 5); 438 unsigned Base = fieldFromInstruction(Insn, 21, 5); 439 440 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 441 Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 442 443 Inst.addOperand(MCOperand::CreateReg(Reg)); 444 Inst.addOperand(MCOperand::CreateReg(Base)); 445 Inst.addOperand(MCOperand::CreateImm(Offset)); 446 447 return MCDisassembler::Success; 448 } 449 450 451 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 452 unsigned RegNo, 453 uint64_t Address, 454 const void *Decoder) { 455 // Currently only hardware register 29 is supported. 456 if (RegNo != 29) 457 return MCDisassembler::Fail; 458 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 459 return MCDisassembler::Success; 460 } 461 462 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 463 unsigned RegNo, 464 uint64_t Address, 465 const void *Decoder) { 466 if (RegNo > 30 || RegNo %2) 467 return MCDisassembler::Fail; 468 469 ; 470 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 471 Inst.addOperand(MCOperand::CreateReg(Reg)); 472 return MCDisassembler::Success; 473 } 474 475 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 476 unsigned RegNo, 477 uint64_t Address, 478 const void *Decoder) { 479 //Currently only hardware register 29 is supported 480 if (RegNo != 29) 481 return MCDisassembler::Fail; 482 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64)); 483 return MCDisassembler::Success; 484 } 485 486 static DecodeStatus DecodeACRegsDSPRegisterClass(MCInst &Inst, 487 unsigned RegNo, 488 uint64_t Address, 489 const void *Decoder) { 490 if (RegNo >= 4) 491 return MCDisassembler::Fail; 492 493 unsigned Reg = getReg(Decoder, Mips::ACRegsDSPRegClassID, RegNo); 494 Inst.addOperand(MCOperand::CreateReg(Reg)); 495 return MCDisassembler::Success; 496 } 497 498 static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst, 499 unsigned RegNo, 500 uint64_t Address, 501 const void *Decoder) { 502 if (RegNo >= 4) 503 return MCDisassembler::Fail; 504 505 unsigned Reg = getReg(Decoder, Mips::HIRegsDSPRegClassID, RegNo); 506 Inst.addOperand(MCOperand::CreateReg(Reg)); 507 return MCDisassembler::Success; 508 } 509 510 static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst, 511 unsigned RegNo, 512 uint64_t Address, 513 const void *Decoder) { 514 if (RegNo >= 4) 515 return MCDisassembler::Fail; 516 517 unsigned Reg = getReg(Decoder, Mips::LORegsDSPRegClassID, RegNo); 518 Inst.addOperand(MCOperand::CreateReg(Reg)); 519 return MCDisassembler::Success; 520 } 521 522 static DecodeStatus DecodeBranchTarget(MCInst &Inst, 523 unsigned Offset, 524 uint64_t Address, 525 const void *Decoder) { 526 unsigned BranchOffset = Offset & 0xffff; 527 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 528 Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 529 return MCDisassembler::Success; 530 } 531 532 static DecodeStatus DecodeBC1(MCInst &Inst, 533 unsigned Insn, 534 uint64_t Address, 535 const void *Decoder) { 536 unsigned BranchOffset = Insn & 0xffff; 537 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 538 Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 539 return MCDisassembler::Success; 540 } 541 542 static DecodeStatus DecodeJumpTarget(MCInst &Inst, 543 unsigned Insn, 544 uint64_t Address, 545 const void *Decoder) { 546 547 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 548 Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 549 return MCDisassembler::Success; 550 } 551 552 553 static DecodeStatus DecodeSimm16(MCInst &Inst, 554 unsigned Insn, 555 uint64_t Address, 556 const void *Decoder) { 557 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 558 return MCDisassembler::Success; 559 } 560 561 static DecodeStatus DecodeInsSize(MCInst &Inst, 562 unsigned Insn, 563 uint64_t Address, 564 const void *Decoder) { 565 // First we need to grab the pos(lsb) from MCInst. 566 int Pos = Inst.getOperand(2).getImm(); 567 int Size = (int) Insn - Pos + 1; 568 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 569 return MCDisassembler::Success; 570 } 571 572 static DecodeStatus DecodeExtSize(MCInst &Inst, 573 unsigned Insn, 574 uint64_t Address, 575 const void *Decoder) { 576 int Size = (int) Insn + 1; 577 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 578 return MCDisassembler::Success; 579 } 580