diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /capstone/MCRegisterInfo.c | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'capstone/MCRegisterInfo.c')
-rw-r--r-- | capstone/MCRegisterInfo.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/capstone/MCRegisterInfo.c b/capstone/MCRegisterInfo.c new file mode 100644 index 000000000..595d5ab2c --- /dev/null +++ b/capstone/MCRegisterInfo.c @@ -0,0 +1,143 @@ +//=== MC/MCRegisterInfo.cpp - Target Register Description -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements MCRegisterInfo functions. +// +//===----------------------------------------------------------------------===// + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */ + +#include "MCRegisterInfo.h" + +/// DiffListIterator - Base iterator class that can traverse the +/// differentially encoded register and regunit lists in DiffLists. +/// Don't use this class directly, use one of the specialized sub-classes +/// defined below. +typedef struct DiffListIterator { + uint16_t Val; + const MCPhysReg *List; +} DiffListIterator; + +void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI, + const MCRegisterDesc *D, unsigned NR, + unsigned RA, unsigned PC, + const MCRegisterClass *C, unsigned NC, + uint16_t (*RURoots)[2], unsigned NRU, + const MCPhysReg *DL, + const char *Strings, + const uint16_t *SubIndices, unsigned NumIndices, + const uint16_t *RET) +{ + RI->Desc = D; + RI->NumRegs = NR; + RI->RAReg = RA; + RI->PCReg = PC; + RI->Classes = C; + RI->DiffLists = DL; + RI->RegStrings = Strings; + RI->NumClasses = NC; + RI->RegUnitRoots = RURoots; + RI->NumRegUnits = NRU; + RI->SubRegIndices = SubIndices; + RI->NumSubRegIndices = NumIndices; + RI->RegEncodingTable = RET; +} + +static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal, const MCPhysReg *DiffList) +{ + d->Val = InitVal; + d->List = DiffList; +} + +static uint16_t DiffListIterator_getVal(DiffListIterator *d) +{ + return d->Val; +} + +static bool DiffListIterator_next(DiffListIterator *d) +{ + MCPhysReg D; + + if (d->List == 0) + return false; + + D = *d->List; + d->List++; + d->Val += D; + + if (!D) + d->List = 0; + + return (D != 0); +} + +static bool DiffListIterator_isValid(DiffListIterator *d) +{ + return (d->List != 0); +} + +unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC) +{ + DiffListIterator iter; + + if (Reg >= RI->NumRegs) { + return 0; + } + + DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SuperRegs); + DiffListIterator_next(&iter); + + while(DiffListIterator_isValid(&iter)) { + uint16_t val = DiffListIterator_getVal(&iter); + if (MCRegisterClass_contains(RC, val) && Reg == MCRegisterInfo_getSubReg(RI, val, SubIdx)) + return val; + + DiffListIterator_next(&iter); + } + + return 0; +} + +unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg, unsigned Idx) +{ + DiffListIterator iter; + const uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices; + + DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SubRegs); + DiffListIterator_next(&iter); + + while(DiffListIterator_isValid(&iter)) { + if (*SRI == Idx) + return DiffListIterator_getVal(&iter); + DiffListIterator_next(&iter); + ++SRI; + } + + return 0; +} + +const MCRegisterClass* MCRegisterInfo_getRegClass(const MCRegisterInfo *RI, unsigned i) +{ + //assert(i < getNumRegClasses() && "Register Class ID out of range"); + if (i >= RI->NumClasses) + return 0; + return &(RI->Classes[i]); +} + +bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg) +{ + unsigned InByte = Reg % 8; + unsigned Byte = Reg / 8; + + if (Byte >= c->RegSetSize) + return false; + + return (c->RegSet[Byte] & (1 << InByte)) != 0; +} |