capstone
/
MCRegisterInfo.c
151 строка · 3.6 Кб
1//=== MC/MCRegisterInfo.cpp - Target Register Description -------*- 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 implements MCRegisterInfo functions.
11//
12//===----------------------------------------------------------------------===//
13
14/* Capstone Disassembly Engine */
15/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
16
17#include "MCRegisterInfo.h"18
19/// DiffListIterator - Base iterator class that can traverse the
20/// differentially encoded register and regunit lists in DiffLists.
21/// Don't use this class directly, use one of the specialized sub-classes
22/// defined below.
23typedef struct DiffListIterator {24uint16_t Val;25const MCPhysReg *List;26} DiffListIterator;27
28void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI,29const MCRegisterDesc *D, unsigned NR,30unsigned RA, unsigned PC,31const MCRegisterClass *C, unsigned NC,32uint16_t (*RURoots)[2], unsigned NRU,33const MCPhysReg *DL,34const char *Strings,35const uint16_t *SubIndices, unsigned NumIndices,36const uint16_t *RET)37{
38RI->Desc = D;39RI->NumRegs = NR;40RI->RAReg = RA;41RI->PCReg = PC;42RI->Classes = C;43RI->DiffLists = DL;44RI->RegStrings = Strings;45RI->NumClasses = NC;46RI->RegUnitRoots = RURoots;47RI->NumRegUnits = NRU;48RI->SubRegIndices = SubIndices;49RI->NumSubRegIndices = NumIndices;50RI->RegEncodingTable = RET;51}
52
53static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal, const MCPhysReg *DiffList)54{
55d->Val = InitVal;56d->List = DiffList;57}
58
59static uint16_t DiffListIterator_getVal(DiffListIterator *d)60{
61return d->Val;62}
63
64static bool DiffListIterator_next(DiffListIterator *d)65{
66MCPhysReg D;67
68if (d->List == 0)69return false;70
71D = *d->List;72d->List++;73d->Val += D;74
75if (!D)76d->List = 0;77
78return (D != 0);79}
80
81static bool DiffListIterator_isValid(DiffListIterator *d)82{
83return (d->List != 0);84}
85
86unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC)87{
88DiffListIterator iter;89
90if (Reg >= RI->NumRegs) {91return 0;92}93
94DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SuperRegs);95DiffListIterator_next(&iter);96
97while(DiffListIterator_isValid(&iter)) {98uint16_t val = DiffListIterator_getVal(&iter);99if (MCRegisterClass_contains(RC, val) && Reg == MCRegisterInfo_getSubReg(RI, val, SubIdx))100return val;101
102DiffListIterator_next(&iter);103}104
105return 0;106}
107
108unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg, unsigned Idx)109{
110DiffListIterator iter;111const uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices;112
113DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SubRegs);114DiffListIterator_next(&iter);115
116while(DiffListIterator_isValid(&iter)) {117if (*SRI == Idx)118return DiffListIterator_getVal(&iter);119DiffListIterator_next(&iter);120++SRI;121}122
123return 0;124}
125
126const MCRegisterClass* MCRegisterInfo_getRegClass(const MCRegisterInfo *RI, unsigned i)127{
128//assert(i < getNumRegClasses() && "Register Class ID out of range");129if (i >= RI->NumClasses)130return 0;131return &(RI->Classes[i]);132}
133
134bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg)135{
136unsigned InByte = 0;137unsigned Byte = 0;138
139// Make sure that MCRegisterInfo_getRegClass didn't return 0140// (for calls to GETREGCLASS_CONTAIN0)141if(!c)142return false;143
144InByte = Reg % 8;145Byte = Reg / 8;146
147if (Byte >= c->RegSetSize)148return false;149
150return (c->RegSet[Byte] & (1 << InByte)) != 0;151}
152