aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp')
-rw-r--r--lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp60
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;
+}