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