MipsDisassembler.cpp revision 63d10fbc89c02758cd91e3b53749e55c2bd0cf65
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 28using namespace llvm; 29 30typedef MCDisassembler::DecodeStatus DecodeStatus; 31 32namespace { 33 34/// MipsDisassembler - a disasembler class for Mips32. 35class MipsDisassembler : public MCDisassembler { 36public: 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 57private: 58 bool isBigEndian; 59}; 60 61 62/// Mips64Disassembler - a disasembler class for Mips64. 63class Mips64Disassembler : public MCDisassembler { 64public: 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 85private: 86 bool isBigEndian; 87}; 88 89} // end anonymous namespace 90 91const EDInstInfo *MipsDisassembler::getEDInfo() const { 92 return instInfoMips; 93} 94 95const EDInstInfo *Mips64Disassembler::getEDInfo() const { 96 return instInfoMips; 97} 98 99// Decoder tables for Mips register 100static 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 111static 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 122static 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 133static 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 144static 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. 153static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 154 unsigned RegNo, 155 uint64_t Address, 156 const void *Decoder); 157 158static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 159 unsigned RegNo, 160 uint64_t Address, 161 const void *Decoder); 162 163static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 164 unsigned RegNo, 165 uint64_t Address, 166 const void *Decoder); 167 168static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 169 unsigned RegNo, 170 uint64_t Address, 171 const void *Decoder); 172 173static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 174 unsigned RegNo, 175 uint64_t Address, 176 const void *Decoder); 177 178static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 179 unsigned Insn, 180 uint64_t Address, 181 const void *Decoder); 182 183static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 184 unsigned RegNo, 185 uint64_t Address, 186 const void *Decoder); 187 188static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 189 unsigned Insn, 190 uint64_t Address, 191 const void *Decoder); 192 193static DecodeStatus DecodeBranchTarget(MCInst &Inst, 194 unsigned Offset, 195 uint64_t Address, 196 const void *Decoder); 197 198static DecodeStatus DecodeBC1(MCInst &Inst, 199 unsigned Insn, 200 uint64_t Address, 201 const void *Decoder); 202 203 204static DecodeStatus DecodeJumpTarget(MCInst &Inst, 205 unsigned Insn, 206 uint64_t Address, 207 const void *Decoder); 208 209static DecodeStatus DecodeMem(MCInst &Inst, 210 unsigned Insn, 211 uint64_t Address, 212 const void *Decoder); 213 214static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 215 uint64_t Address, 216 const void *Decoder); 217 218static DecodeStatus DecodeSimm16(MCInst &Inst, 219 unsigned Insn, 220 uint64_t Address, 221 const void *Decoder); 222 223static DecodeStatus DecodeCondCode(MCInst &Inst, 224 unsigned Insn, 225 uint64_t Address, 226 const void *Decoder); 227 228static DecodeStatus DecodeInsSize(MCInst &Inst, 229 unsigned Insn, 230 uint64_t Address, 231 const void *Decoder); 232 233static DecodeStatus DecodeExtSize(MCInst &Inst, 234 unsigned Insn, 235 uint64_t Address, 236 const void *Decoder); 237 238namespace llvm { 239extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 240 TheMips64elTarget; 241} 242 243static MCDisassembler *createMipsDisassembler( 244 const Target &T, 245 const MCSubtargetInfo &STI) { 246 return new MipsDisassembler(STI,true); 247} 248 249static MCDisassembler *createMipselDisassembler( 250 const Target &T, 251 const MCSubtargetInfo &STI) { 252 return new MipsDisassembler(STI,false); 253} 254 255static MCDisassembler *createMips64Disassembler( 256 const Target &T, 257 const MCSubtargetInfo &STI) { 258 return new Mips64Disassembler(STI,true); 259} 260 261static MCDisassembler *createMips64elDisassembler( 262 const Target &T, 263 const MCSubtargetInfo &STI) { 264 return new Mips64Disassembler(STI, false); 265} 266 267extern "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 284static 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 315DecodeStatus 316MipsDisassembler::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 339DecodeStatus 340Mips64Disassembler::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 369static 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 381static 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 392static 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 403static 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 414static 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 422static 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 441static 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 457static 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 468static 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 477static 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 488static 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 499static 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 509static 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 519static 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 530static 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 538static 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 549static 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