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