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