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