diff options
Diffstat (limited to 'lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp')
-rw-r--r-- | lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index 481b692ae8bf..1a619ebda84e 100644 --- a/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -40,7 +40,7 @@ using DecodeStatus = MCDisassembler::DecodeStatus; namespace { -/// \brief Hexagon disassembler for all Hexagon platforms. +/// Hexagon disassembler for all Hexagon platforms. class HexagonDisassembler : public MCDisassembler { public: std::unique_ptr<MCInstrInfo const> const MCII; @@ -127,12 +127,18 @@ static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo, static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, const void *Decoder); @@ -783,3 +789,55 @@ static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext()); return MCDisassembler::Success; } + +static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t /*Address*/, + const void *Decoder) { + using namespace Hexagon; + + static const MCPhysReg GuestRegDecoderTable[] = { + /* 0 */ GELR, GSR, GOSP, G3, + /* 4 */ G4, G5, G6, G7, + /* 8 */ G8, G9, G10, G11, + /* 12 */ G12, G13, G14, G15, + /* 16 */ GPMUCNT4, GPMUCNT5, GPMUCNT6, GPMUCNT7, + /* 20 */ G20, G21, G22, G23, + /* 24 */ GPCYCLELO, GPCYCLEHI, GPMUCNT0, GPMUCNT1, + /* 28 */ GPMUCNT2, GPMUCNT3, G30, G31 + }; + + if (RegNo >= array_lengthof(GuestRegDecoderTable)) + return MCDisassembler::Fail; + if (GuestRegDecoderTable[RegNo] == Hexagon::NoRegister) + return MCDisassembler::Fail; + + unsigned Register = GuestRegDecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Register)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t /*Address*/, + const void *Decoder) { + using namespace Hexagon; + + static const MCPhysReg GuestReg64DecoderTable[] = { + /* 0 */ G1_0, 0, G3_2, 0, + /* 4 */ G5_4, 0, G7_6, 0, + /* 8 */ G9_8, 0, G11_10, 0, + /* 12 */ G13_12, 0, G15_14, 0, + /* 16 */ G17_16, 0, G19_18, 0, + /* 20 */ G21_20, 0, G23_22, 0, + /* 24 */ G25_24, 0, G27_26, 0, + /* 28 */ G29_28, 0, G31_30, 0 + }; + + if (RegNo >= array_lengthof(GuestReg64DecoderTable)) + return MCDisassembler::Fail; + if (GuestReg64DecoderTable[RegNo] == Hexagon::NoRegister) + return MCDisassembler::Fail; + + unsigned Register = GuestReg64DecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Register)); + return MCDisassembler::Success; +} |