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 "MipsSubtarget.h" 16 #include "llvm/MC/EDInstInfo.h" 17 #include "llvm/MC/MCDisassembler.h" 18 #include "llvm/Support/MemoryObject.h" 19 #include "llvm/Support/TargetRegistry.h" 20 #include "llvm/MC/MCSubtargetInfo.h" 21 #include "llvm/MC/MCInst.h" 22 #include "llvm/MC/MCRegisterInfo.h" 23 #include "llvm/Support/MathExtras.h" 24 25 26 #include "MipsGenEDInfo.inc" 27 28 using namespace llvm; 29 30 typedef MCDisassembler::DecodeStatus DecodeStatus; 31 32 /// MipsDisassembler - a disasembler class for Mips32. 33 class MipsDisassembler : public MCDisassembler { 34 public: 35 /// Constructor - Initializes the disassembler. 36 /// 37 MipsDisassembler(const MCSubtargetInfo &STI, bool bigEndian) : 38 MCDisassembler(STI), isBigEndian(bigEndian) { 39 } 40 41 ~MipsDisassembler() { 42 } 43 44 /// getInstruction - See MCDisassembler. 45 DecodeStatus getInstruction(MCInst &instr, 46 uint64_t &size, 47 const MemoryObject ®ion, 48 uint64_t address, 49 raw_ostream &vStream, 50 raw_ostream &cStream) const; 51 52 /// getEDInfo - See MCDisassembler. 53 const EDInstInfo *getEDInfo() const; 54 55 private: 56 bool isBigEndian; 57 }; 58 59 60 /// Mips64Disassembler - a disasembler class for Mips64. 61 class Mips64Disassembler : public MCDisassembler { 62 public: 63 /// Constructor - Initializes the disassembler. 64 /// 65 Mips64Disassembler(const MCSubtargetInfo &STI, bool bigEndian) : 66 MCDisassembler(STI), isBigEndian(bigEndian) { 67 } 68 69 ~Mips64Disassembler() { 70 } 71 72 /// getInstruction - See MCDisassembler. 73 DecodeStatus getInstruction(MCInst &instr, 74 uint64_t &size, 75 const MemoryObject ®ion, 76 uint64_t address, 77 raw_ostream &vStream, 78 raw_ostream &cStream) const; 79 80 /// getEDInfo - See MCDisassembler. 81 const EDInstInfo *getEDInfo() const; 82 83 private: 84 bool isBigEndian; 85 }; 86 87 const EDInstInfo *MipsDisassembler::getEDInfo() const { 88 return instInfoMips; 89 } 90 91 const EDInstInfo *Mips64Disassembler::getEDInfo() const { 92 return instInfoMips; 93 } 94 95 // Decoder tables for Mips register 96 static const unsigned CPURegsTable[] = { 97 Mips::ZERO, Mips::AT, Mips::V0, Mips::V1, 98 Mips::A0, Mips::A1, Mips::A2, Mips::A3, 99 Mips::T0, Mips::T1, Mips::T2, Mips::T3, 100 Mips::T4, Mips::T5, Mips::T6, Mips::T7, 101 Mips::S0, Mips::S1, Mips::S2, Mips::S3, 102 Mips::S4, Mips::S5, Mips::S6, Mips::S7, 103 Mips::T8, Mips::T9, Mips::K0, Mips::K1, 104 Mips::GP, Mips::SP, Mips::FP, Mips::RA 105 }; 106 107 static const unsigned FGR32RegsTable[] = { 108 Mips::F0, Mips::F1, Mips::F2, Mips::F3, 109 Mips::F4, Mips::F5, Mips::F6, Mips::F7, 110 Mips::F8, Mips::F9, Mips::F10, Mips::F11, 111 Mips::F12, Mips::F13, Mips::F14, Mips::F15, 112 Mips::F16, Mips::F17, Mips::F18, Mips::F18, 113 Mips::F20, Mips::F21, Mips::F22, Mips::F23, 114 Mips::F24, Mips::F25, Mips::F26, Mips::F27, 115 Mips::F28, Mips::F29, Mips::F30, Mips::F31 116 }; 117 118 static const unsigned CPU64RegsTable[] = { 119 Mips::ZERO_64, Mips::AT_64, Mips::V0_64, Mips::V1_64, 120 Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64, 121 Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64, 122 Mips::T4_64, Mips::T5_64, Mips::T6_64, Mips::T7_64, 123 Mips::S0_64, Mips::S1_64, Mips::S2_64, Mips::S3_64, 124 Mips::S4_64, Mips::S5_64, Mips::S6_64, Mips::S7_64, 125 Mips::T8_64, Mips::T9_64, Mips::K0_64, Mips::K1_64, 126 Mips::GP_64, Mips::SP_64, Mips::FP_64, Mips::RA_64 127 }; 128 129 static const unsigned FGR64RegsTable[] = { 130 Mips::D0_64, Mips::D1_64, Mips::D2_64, Mips::D3_64, 131 Mips::D4_64, Mips::D5_64, Mips::D6_64, Mips::D7_64, 132 Mips::D8_64, Mips::D9_64, Mips::D10_64, Mips::D11_64, 133 Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64, 134 Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64, 135 Mips::D20_64, Mips::D21_64, Mips::D22_64, Mips::D23_64, 136 Mips::D24_64, Mips::D25_64, Mips::D26_64, Mips::D27_64, 137 Mips::D28_64, Mips::D29_64, Mips::D30_64, Mips::D31_64 138 }; 139 140 static const unsigned AFGR64RegsTable[] = { 141 Mips::D0, Mips::D1, Mips::D2, Mips::D3, 142 Mips::D4, Mips::D5, Mips::D6, Mips::D7, 143 Mips::D8, Mips::D9, Mips::D10, Mips::D11, 144 Mips::D12, Mips::D13, Mips::D14, Mips::D15 145 }; 146 147 // Forward declare these because the autogenerated code will reference them. 148 // Definitions are further down. 149 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 150 unsigned RegNo, 151 uint64_t Address, 152 const void *Decoder); 153 154 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 155 unsigned RegNo, 156 uint64_t Address, 157 const void *Decoder); 158 159 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 160 unsigned RegNo, 161 uint64_t Address, 162 const void *Decoder); 163 164 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 165 unsigned RegNo, 166 uint64_t Address, 167 const void *Decoder); 168 169 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 170 unsigned RegNo, 171 uint64_t Address, 172 const void *Decoder); 173 174 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 175 unsigned Insn, 176 uint64_t Address, 177 const void *Decoder); 178 179 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 180 unsigned RegNo, 181 uint64_t Address, 182 const void *Decoder); 183 184 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 185 unsigned Insn, 186 uint64_t Address, 187 const void *Decoder); 188 189 static DecodeStatus DecodeBranchTarget(MCInst &Inst, 190 unsigned Offset, 191 uint64_t Address, 192 const void *Decoder); 193 194 static DecodeStatus DecodeBC1(MCInst &Inst, 195 unsigned Insn, 196 uint64_t Address, 197 const void *Decoder); 198 199 200 static DecodeStatus DecodeJumpTarget(MCInst &Inst, 201 unsigned Insn, 202 uint64_t Address, 203 const void *Decoder); 204 205 static DecodeStatus DecodeMem(MCInst &Inst, 206 unsigned Insn, 207 uint64_t Address, 208 const void *Decoder); 209 210 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 211 uint64_t Address, 212 const void *Decoder); 213 214 static DecodeStatus DecodeSimm16(MCInst &Inst, 215 unsigned Insn, 216 uint64_t Address, 217 const void *Decoder); 218 219 static DecodeStatus DecodeCondCode(MCInst &Inst, 220 unsigned Insn, 221 uint64_t Address, 222 const void *Decoder); 223 224 static DecodeStatus DecodeInsSize(MCInst &Inst, 225 unsigned Insn, 226 uint64_t Address, 227 const void *Decoder); 228 229 static DecodeStatus DecodeExtSize(MCInst &Inst, 230 unsigned Insn, 231 uint64_t Address, 232 const void *Decoder); 233 234 namespace llvm { 235 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 236 TheMips64elTarget; 237 } 238 239 static MCDisassembler *createMipsDisassembler( 240 const Target &T, 241 const MCSubtargetInfo &STI) { 242 return new MipsDisassembler(STI,true); 243 } 244 245 static MCDisassembler *createMipselDisassembler( 246 const Target &T, 247 const MCSubtargetInfo &STI) { 248 return new MipsDisassembler(STI,false); 249 } 250 251 static MCDisassembler *createMips64Disassembler( 252 const Target &T, 253 const MCSubtargetInfo &STI) { 254 return new Mips64Disassembler(STI,true); 255 } 256 257 static MCDisassembler *createMips64elDisassembler( 258 const Target &T, 259 const MCSubtargetInfo &STI) { 260 return new Mips64Disassembler(STI, false); 261 } 262 263 extern "C" void LLVMInitializeMipsDisassembler() { 264 // Register the disassembler. 265 TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 266 createMipsDisassembler); 267 TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 268 createMipselDisassembler); 269 TargetRegistry::RegisterMCDisassembler(TheMips64Target, 270 createMips64Disassembler); 271 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 272 createMips64elDisassembler); 273 } 274 275 276 #include "MipsGenDisassemblerTables.inc" 277 278 /// readInstruction - read four bytes from the MemoryObject 279 /// and return 32 bit word sorted according to the given endianess 280 static DecodeStatus readInstruction32(const MemoryObject ®ion, 281 uint64_t address, 282 uint64_t &size, 283 uint32_t &insn, 284 bool isBigEndian) { 285 uint8_t Bytes[4]; 286 287 // We want to read exactly 4 Bytes of data. 288 if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) { 289 size = 0; 290 return MCDisassembler::Fail; 291 } 292 293 if (isBigEndian) { 294 // Encoded as a big-endian 32-bit word in the stream. 295 insn = (Bytes[3] << 0) | 296 (Bytes[2] << 8) | 297 (Bytes[1] << 16) | 298 (Bytes[0] << 24); 299 } 300 else { 301 // Encoded as a small-endian 32-bit word in the stream. 302 insn = (Bytes[0] << 0) | 303 (Bytes[1] << 8) | 304 (Bytes[2] << 16) | 305 (Bytes[3] << 24); 306 } 307 308 return MCDisassembler::Success; 309 } 310 311 DecodeStatus 312 MipsDisassembler::getInstruction(MCInst &instr, 313 uint64_t &Size, 314 const MemoryObject &Region, 315 uint64_t Address, 316 raw_ostream &vStream, 317 raw_ostream &cStream) const { 318 uint32_t Insn; 319 320 DecodeStatus Result = readInstruction32(Region, Address, Size, 321 Insn, isBigEndian); 322 if (Result == MCDisassembler::Fail) 323 return MCDisassembler::Fail; 324 325 // Calling the auto-generated decoder function. 326 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI); 327 if (Result != MCDisassembler::Fail) { 328 Size = 4; 329 return Result; 330 } 331 332 return MCDisassembler::Fail; 333 } 334 335 DecodeStatus 336 Mips64Disassembler::getInstruction(MCInst &instr, 337 uint64_t &Size, 338 const MemoryObject &Region, 339 uint64_t Address, 340 raw_ostream &vStream, 341 raw_ostream &cStream) const { 342 uint32_t Insn; 343 344 DecodeStatus Result = readInstruction32(Region, Address, Size, 345 Insn, isBigEndian); 346 if (Result == MCDisassembler::Fail) 347 return MCDisassembler::Fail; 348 349 // Calling the auto-generated decoder function. 350 Result = decodeMips64Instruction32(instr, Insn, Address, this, STI); 351 if (Result != MCDisassembler::Fail) { 352 Size = 4; 353 return Result; 354 } 355 // If we fail to decode in Mips64 decoder space we can try in Mips32 356 Result = decodeMipsInstruction32(instr, Insn, Address, this, STI); 357 if (Result != MCDisassembler::Fail) { 358 Size = 4; 359 return Result; 360 } 361 362 return MCDisassembler::Fail; 363 } 364 365 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 366 unsigned RegNo, 367 uint64_t Address, 368 const void *Decoder) { 369 370 if (RegNo > 31) 371 return MCDisassembler::Fail; 372 373 Inst.addOperand(MCOperand::CreateReg(CPU64RegsTable[RegNo])); 374 return MCDisassembler::Success; 375 } 376 377 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 378 unsigned RegNo, 379 uint64_t Address, 380 const void *Decoder) { 381 if (RegNo > 31) 382 return MCDisassembler::Fail; 383 384 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[RegNo])); 385 return MCDisassembler::Success; 386 } 387 388 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 389 unsigned RegNo, 390 uint64_t Address, 391 const void *Decoder) { 392 if (RegNo > 31) 393 return MCDisassembler::Fail; 394 395 Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[RegNo])); 396 return MCDisassembler::Success; 397 } 398 399 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 400 unsigned RegNo, 401 uint64_t Address, 402 const void *Decoder) { 403 if (RegNo > 31) 404 return MCDisassembler::Fail; 405 406 Inst.addOperand(MCOperand::CreateReg(FGR32RegsTable[RegNo])); 407 return MCDisassembler::Success; 408 } 409 410 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 411 unsigned RegNo, 412 uint64_t Address, 413 const void *Decoder) { 414 Inst.addOperand(MCOperand::CreateReg(RegNo)); 415 return MCDisassembler::Success; 416 } 417 418 static DecodeStatus DecodeMem(MCInst &Inst, 419 unsigned Insn, 420 uint64_t Address, 421 const void *Decoder) { 422 int Offset = SignExtend32<16>(Insn & 0xffff); 423 int Reg = (int)fieldFromInstruction32(Insn, 16, 5); 424 int Base = (int)fieldFromInstruction32(Insn, 21, 5); 425 426 if(Inst.getOpcode() == Mips::SC){ 427 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg])); 428 } 429 430 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg])); 431 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Base])); 432 Inst.addOperand(MCOperand::CreateImm(Offset)); 433 434 return MCDisassembler::Success; 435 } 436 437 static DecodeStatus DecodeFMem(MCInst &Inst, 438 unsigned Insn, 439 uint64_t Address, 440 const void *Decoder) { 441 int Offset = SignExtend32<16>(Insn & 0xffff); 442 int Reg = (int)fieldFromInstruction32(Insn, 16, 5); 443 int Base = (int)fieldFromInstruction32(Insn, 21, 5); 444 445 Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[Reg])); 446 Inst.addOperand(MCOperand::CreateReg(CPURegsTable[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 > 31) 478 return MCDisassembler::Fail; 479 480 Inst.addOperand(MCOperand::CreateReg(AFGR64RegsTable[RegNo])); 481 return MCDisassembler::Success; 482 } 483 484 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 485 unsigned RegNo, 486 uint64_t Address, 487 const void *Decoder) { 488 //Currently only hardware register 29 is supported 489 if (RegNo != 29) 490 return MCDisassembler::Fail; 491 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 492 return MCDisassembler::Success; 493 } 494 495 static DecodeStatus DecodeBranchTarget(MCInst &Inst, 496 unsigned Offset, 497 uint64_t Address, 498 const void *Decoder) { 499 unsigned BranchOffset = Offset & 0xffff; 500 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 501 Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 502 return MCDisassembler::Success; 503 } 504 505 static DecodeStatus DecodeBC1(MCInst &Inst, 506 unsigned Insn, 507 uint64_t Address, 508 const void *Decoder) { 509 unsigned BranchOffset = Insn & 0xffff; 510 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 511 Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 512 return MCDisassembler::Success; 513 } 514 515 static DecodeStatus DecodeJumpTarget(MCInst &Inst, 516 unsigned Insn, 517 uint64_t Address, 518 const void *Decoder) { 519 520 unsigned JumpOffset = fieldFromInstruction32(Insn, 0, 26) << 2; 521 Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 522 return MCDisassembler::Success; 523 } 524 525 526 static DecodeStatus DecodeSimm16(MCInst &Inst, 527 unsigned Insn, 528 uint64_t Address, 529 const void *Decoder) { 530 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 531 return MCDisassembler::Success; 532 } 533 534 static DecodeStatus DecodeInsSize(MCInst &Inst, 535 unsigned Insn, 536 uint64_t Address, 537 const void *Decoder) { 538 // First we need to grab the pos(lsb) from MCInst. 539 int Pos = Inst.getOperand(2).getImm(); 540 int Size = (int) Insn - Pos + 1; 541 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 542 return MCDisassembler::Success; 543 } 544 545 static DecodeStatus DecodeExtSize(MCInst &Inst, 546 unsigned Insn, 547 uint64_t Address, 548 const void *Decoder) { 549 int Size = (int) Insn + 1; 550 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 551 return MCDisassembler::Success; 552 } 553