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