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