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