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