MipsDisassembler.cpp revision 491d04969d9f29ed891c73238648853954ba4f81
1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is part of the Mips Disassembler. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 125e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)//===----------------------------------------------------------------------===// 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "Mips.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "MipsRegisterInfo.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "MipsSubtarget.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "llvm/MC/MCDisassembler.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/MC/MCFixedLenDisassembler.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/MC/MCInst.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/MC/MCSubtargetInfo.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/MathExtras.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/MemoryObject.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/TargetRegistry.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace llvm; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef MCDisassembler::DecodeStatus DecodeStatus; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// MipsDisassemblerBase - a disasembler class for Mips. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MipsDisassemblerBase : public MCDisassembler { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Constructor - Initializes the disassembler. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bigEndian) : 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MipsDisassemblerBase() {} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OwningPtr<const MCRegisterInfo> RegInfo; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool isBigEndian; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// MipsDisassembler - a disasembler class for Mips32. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MipsDisassembler : public MipsDisassemblerBase { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Constructor - Initializes the disassembler. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bigEndian) : 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MipsDisassemblerBase(STI, Info, bigEndian) {} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// getInstruction - See MCDisassembler. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual DecodeStatus getInstruction(MCInst &instr, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t &size, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MemoryObject ®ion, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t address, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_ostream &vStream, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_ostream &cStream) const; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Mips64Disassembler - a disasembler class for Mips64. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Mips64Disassembler : public MipsDisassemblerBase { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Constructor - Initializes the disassembler. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bigEndian) : 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MipsDisassemblerBase(STI, Info, bigEndian) {} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// getInstruction - See MCDisassembler. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual DecodeStatus getInstruction(MCInst &instr, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t &size, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MemoryObject ®ion, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t address, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_ostream &vStream, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_ostream &cStream) const; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // end anonymous namespace 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Forward declare these because the autogenerated code will reference them. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Definitions are further down. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Insn, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned RegNo, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeBranchTarget(MCInst &Inst, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Offset, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DecodeStatus DecodeJumpTarget(MCInst &Inst, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Insn, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t Address, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *Decoder); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 166static DecodeStatus DecodeMem(MCInst &Inst, 167 unsigned Insn, 168 uint64_t Address, 169 const void *Decoder); 170 171static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 172 uint64_t Address, 173 const void *Decoder); 174 175static DecodeStatus DecodeSimm16(MCInst &Inst, 176 unsigned Insn, 177 uint64_t Address, 178 const void *Decoder); 179 180static DecodeStatus DecodeInsSize(MCInst &Inst, 181 unsigned Insn, 182 uint64_t Address, 183 const void *Decoder); 184 185static DecodeStatus DecodeExtSize(MCInst &Inst, 186 unsigned Insn, 187 uint64_t Address, 188 const void *Decoder); 189 190namespace llvm { 191extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 192 TheMips64elTarget; 193} 194 195static MCDisassembler *createMipsDisassembler( 196 const Target &T, 197 const MCSubtargetInfo &STI) { 198 return new MipsDisassembler(STI, T.createMCRegInfo(""), true); 199} 200 201static MCDisassembler *createMipselDisassembler( 202 const Target &T, 203 const MCSubtargetInfo &STI) { 204 return new MipsDisassembler(STI, T.createMCRegInfo(""), false); 205} 206 207static MCDisassembler *createMips64Disassembler( 208 const Target &T, 209 const MCSubtargetInfo &STI) { 210 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); 211} 212 213static MCDisassembler *createMips64elDisassembler( 214 const Target &T, 215 const MCSubtargetInfo &STI) { 216 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); 217} 218 219extern "C" void LLVMInitializeMipsDisassembler() { 220 // Register the disassembler. 221 TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 222 createMipsDisassembler); 223 TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 224 createMipselDisassembler); 225 TargetRegistry::RegisterMCDisassembler(TheMips64Target, 226 createMips64Disassembler); 227 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 228 createMips64elDisassembler); 229} 230 231 232#include "MipsGenDisassemblerTables.inc" 233 234 /// readInstruction - read four bytes from the MemoryObject 235 /// and return 32 bit word sorted according to the given endianess 236static DecodeStatus readInstruction32(const MemoryObject ®ion, 237 uint64_t address, 238 uint64_t &size, 239 uint32_t &insn, 240 bool isBigEndian) { 241 uint8_t Bytes[4]; 242 243 // We want to read exactly 4 Bytes of data. 244 if (region.readBytes(address, 4, Bytes) == -1) { 245 size = 0; 246 return MCDisassembler::Fail; 247 } 248 249 if (isBigEndian) { 250 // Encoded as a big-endian 32-bit word in the stream. 251 insn = (Bytes[3] << 0) | 252 (Bytes[2] << 8) | 253 (Bytes[1] << 16) | 254 (Bytes[0] << 24); 255 } 256 else { 257 // Encoded as a small-endian 32-bit word in the stream. 258 insn = (Bytes[0] << 0) | 259 (Bytes[1] << 8) | 260 (Bytes[2] << 16) | 261 (Bytes[3] << 24); 262 } 263 264 return MCDisassembler::Success; 265} 266 267DecodeStatus 268MipsDisassembler::getInstruction(MCInst &instr, 269 uint64_t &Size, 270 const MemoryObject &Region, 271 uint64_t Address, 272 raw_ostream &vStream, 273 raw_ostream &cStream) const { 274 uint32_t Insn; 275 276 DecodeStatus Result = readInstruction32(Region, Address, Size, 277 Insn, isBigEndian); 278 if (Result == MCDisassembler::Fail) 279 return MCDisassembler::Fail; 280 281 // Calling the auto-generated decoder function. 282 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 283 this, STI); 284 if (Result != MCDisassembler::Fail) { 285 Size = 4; 286 return Result; 287 } 288 289 return MCDisassembler::Fail; 290} 291 292DecodeStatus 293Mips64Disassembler::getInstruction(MCInst &instr, 294 uint64_t &Size, 295 const MemoryObject &Region, 296 uint64_t Address, 297 raw_ostream &vStream, 298 raw_ostream &cStream) const { 299 uint32_t Insn; 300 301 DecodeStatus Result = readInstruction32(Region, Address, Size, 302 Insn, isBigEndian); 303 if (Result == MCDisassembler::Fail) 304 return MCDisassembler::Fail; 305 306 // Calling the auto-generated decoder function. 307 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address, 308 this, STI); 309 if (Result != MCDisassembler::Fail) { 310 Size = 4; 311 return Result; 312 } 313 // If we fail to decode in Mips64 decoder space we can try in Mips32 314 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 315 this, STI); 316 if (Result != MCDisassembler::Fail) { 317 Size = 4; 318 return Result; 319 } 320 321 return MCDisassembler::Fail; 322} 323 324static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 325 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 326 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo); 327} 328 329static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 330 unsigned RegNo, 331 uint64_t Address, 332 const void *Decoder) { 333 334 return MCDisassembler::Fail; 335 336} 337 338static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 339 unsigned RegNo, 340 uint64_t Address, 341 const void *Decoder) { 342 343 if (RegNo > 31) 344 return MCDisassembler::Fail; 345 346 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 347 Inst.addOperand(MCOperand::CreateReg(Reg)); 348 return MCDisassembler::Success; 349} 350 351static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 352 unsigned RegNo, 353 uint64_t Address, 354 const void *Decoder) { 355 if (RegNo > 31) 356 return MCDisassembler::Fail; 357 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 358 Inst.addOperand(MCOperand::CreateReg(Reg)); 359 return MCDisassembler::Success; 360} 361 362static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, 363 unsigned RegNo, 364 uint64_t Address, 365 const void *Decoder) { 366 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 367} 368 369static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 370 unsigned RegNo, 371 uint64_t Address, 372 const void *Decoder) { 373 if (RegNo > 31) 374 return MCDisassembler::Fail; 375 376 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 377 Inst.addOperand(MCOperand::CreateReg(Reg)); 378 return MCDisassembler::Success; 379} 380 381static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 382 unsigned RegNo, 383 uint64_t Address, 384 const void *Decoder) { 385 if (RegNo > 31) 386 return MCDisassembler::Fail; 387 388 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 389 Inst.addOperand(MCOperand::CreateReg(Reg)); 390 return MCDisassembler::Success; 391} 392 393static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 394 unsigned RegNo, 395 uint64_t Address, 396 const void *Decoder) { 397 if (RegNo > 31) 398 return MCDisassembler::Fail; 399 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 400 Inst.addOperand(MCOperand::CreateReg(Reg)); 401 return MCDisassembler::Success; 402} 403 404static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 405 unsigned RegNo, 406 uint64_t Address, 407 const void *Decoder) { 408 if (RegNo > 7) 409 return MCDisassembler::Fail; 410 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 411 Inst.addOperand(MCOperand::CreateReg(Reg)); 412 return MCDisassembler::Success; 413} 414 415static DecodeStatus DecodeMem(MCInst &Inst, 416 unsigned Insn, 417 uint64_t Address, 418 const void *Decoder) { 419 int Offset = SignExtend32<16>(Insn & 0xffff); 420 unsigned Reg = fieldFromInstruction(Insn, 16, 5); 421 unsigned Base = fieldFromInstruction(Insn, 21, 5); 422 423 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 424 Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 425 426 if(Inst.getOpcode() == Mips::SC){ 427 Inst.addOperand(MCOperand::CreateReg(Reg)); 428 } 429 430 Inst.addOperand(MCOperand::CreateReg(Reg)); 431 Inst.addOperand(MCOperand::CreateReg(Base)); 432 Inst.addOperand(MCOperand::CreateImm(Offset)); 433 434 return MCDisassembler::Success; 435} 436 437static DecodeStatus DecodeFMem(MCInst &Inst, 438 unsigned Insn, 439 uint64_t Address, 440 const void *Decoder) { 441 int Offset = SignExtend32<16>(Insn & 0xffff); 442 unsigned Reg = fieldFromInstruction(Insn, 16, 5); 443 unsigned Base = fieldFromInstruction(Insn, 21, 5); 444 445 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 446 Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 447 448 Inst.addOperand(MCOperand::CreateReg(Reg)); 449 Inst.addOperand(MCOperand::CreateReg(Base)); 450 Inst.addOperand(MCOperand::CreateImm(Offset)); 451 452 return MCDisassembler::Success; 453} 454 455 456static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 457 unsigned RegNo, 458 uint64_t Address, 459 const void *Decoder) { 460 // Currently only hardware register 29 is supported. 461 if (RegNo != 29) 462 return MCDisassembler::Fail; 463 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 464 return MCDisassembler::Success; 465} 466 467static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 468 unsigned RegNo, 469 uint64_t Address, 470 const void *Decoder) { 471 if (RegNo > 30 || RegNo %2) 472 return MCDisassembler::Fail; 473 474 ; 475 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 476 Inst.addOperand(MCOperand::CreateReg(Reg)); 477 return MCDisassembler::Success; 478} 479 480static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 481 unsigned RegNo, 482 uint64_t Address, 483 const void *Decoder) { 484 if (RegNo >= 4) 485 return MCDisassembler::Fail; 486 487 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 488 Inst.addOperand(MCOperand::CreateReg(Reg)); 489 return MCDisassembler::Success; 490} 491 492static DecodeStatus DecodeHIRegsDSPRegisterClass(MCInst &Inst, 493 unsigned RegNo, 494 uint64_t Address, 495 const void *Decoder) { 496 if (RegNo >= 4) 497 return MCDisassembler::Fail; 498 499 unsigned Reg = getReg(Decoder, Mips::HIRegsDSPRegClassID, RegNo); 500 Inst.addOperand(MCOperand::CreateReg(Reg)); 501 return MCDisassembler::Success; 502} 503 504static DecodeStatus DecodeLORegsDSPRegisterClass(MCInst &Inst, 505 unsigned RegNo, 506 uint64_t Address, 507 const void *Decoder) { 508 if (RegNo >= 4) 509 return MCDisassembler::Fail; 510 511 unsigned Reg = getReg(Decoder, Mips::LORegsDSPRegClassID, RegNo); 512 Inst.addOperand(MCOperand::CreateReg(Reg)); 513 return MCDisassembler::Success; 514} 515 516static DecodeStatus DecodeBranchTarget(MCInst &Inst, 517 unsigned Offset, 518 uint64_t Address, 519 const void *Decoder) { 520 unsigned BranchOffset = Offset & 0xffff; 521 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 522 Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 523 return MCDisassembler::Success; 524} 525 526static DecodeStatus DecodeJumpTarget(MCInst &Inst, 527 unsigned Insn, 528 uint64_t Address, 529 const void *Decoder) { 530 531 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 532 Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 533 return MCDisassembler::Success; 534} 535 536 537static DecodeStatus DecodeSimm16(MCInst &Inst, 538 unsigned Insn, 539 uint64_t Address, 540 const void *Decoder) { 541 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 542 return MCDisassembler::Success; 543} 544 545static DecodeStatus DecodeInsSize(MCInst &Inst, 546 unsigned Insn, 547 uint64_t Address, 548 const void *Decoder) { 549 // First we need to grab the pos(lsb) from MCInst. 550 int Pos = Inst.getOperand(2).getImm(); 551 int Size = (int) Insn - Pos + 1; 552 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 553 return MCDisassembler::Success; 554} 555 556static DecodeStatus DecodeExtSize(MCInst &Inst, 557 unsigned Insn, 558 uint64_t Address, 559 const void *Decoder) { 560 int Size = (int) Insn + 1; 561 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 562 return MCDisassembler::Success; 563} 564