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-2014 */
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.
23 typedef struct DiffListIterator {
24 	uint16_t Val;
25 	const MCPhysReg *List;
26 } DiffListIterator;
27 
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 void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI,
29 		const MCRegisterDesc *D, unsigned NR,
30 		unsigned RA, unsigned PC,
31 		const MCRegisterClass *C, unsigned NC,
32 		uint16_t (*RURoots)[2], unsigned NRU,
33 		const MCPhysReg *DL,
34 		const char *Strings,
35 		const uint16_t *SubIndices, unsigned NumIndices,
36 		const uint16_t *RET)
37 {
38 	RI->Desc = D;
39 	RI->NumRegs = NR;
40 	RI->RAReg = RA;
41 	RI->PCReg = PC;
42 	RI->Classes = C;
43 	RI->DiffLists = DL;
44 	RI->RegStrings = Strings;
45 	RI->NumClasses = NC;
46 	RI->RegUnitRoots = RURoots;
47 	RI->NumRegUnits = NRU;
48 	RI->SubRegIndices = SubIndices;
49 	RI->NumSubRegIndices = NumIndices;
50 	RI->RegEncodingTable = RET;
51 }
52 
DiffListIterator_init(DiffListIterator * d,MCPhysReg InitVal,const MCPhysReg * DiffList)53 static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal, const MCPhysReg *DiffList)
54 {
55 	d->Val = InitVal;
56 	d->List = DiffList;
57 }
58 
DiffListIterator_getVal(DiffListIterator * d)59 static uint16_t DiffListIterator_getVal(DiffListIterator *d)
60 {
61 	return d->Val;
62 }
63 
DiffListIterator_next(DiffListIterator * d)64 static bool DiffListIterator_next(DiffListIterator *d)
65 {
66 	MCPhysReg D;
67 
68 	if (d->List == 0)
69 		return false;
70 
71 	D = *d->List;
72 	d->List++;
73 	d->Val += D;
74 
75 	if (!D)
76 		d->List = 0;
77 
78 	return (D != 0);
79 }
80 
DiffListIterator_isValid(DiffListIterator * d)81 static bool DiffListIterator_isValid(DiffListIterator *d)
82 {
83 	return (d->List != 0);
84 }
85 
MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo * RI,unsigned Reg,unsigned SubIdx,const MCRegisterClass * RC)86 unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC)
87 {
88 	DiffListIterator iter;
89 
90 	if (Reg >= RI->NumRegs) {
91 		return 0;
92 	}
93 
94 	DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SuperRegs);
95 	DiffListIterator_next(&iter);
96 
97 	while(DiffListIterator_isValid(&iter)) {
98 		uint16_t val = DiffListIterator_getVal(&iter);
99 		if (MCRegisterClass_contains(RC, val) && Reg ==  MCRegisterInfo_getSubReg(RI, val, SubIdx))
100 			return val;
101 
102 		DiffListIterator_next(&iter);
103 	}
104 
105 	return 0;
106 }
107 
MCRegisterInfo_getSubReg(const MCRegisterInfo * RI,unsigned Reg,unsigned Idx)108 unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg, unsigned Idx)
109 {
110 	DiffListIterator iter;
111 	const uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices;
112 
113 	DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SubRegs);
114 	DiffListIterator_next(&iter);
115 
116 	while(DiffListIterator_isValid(&iter)) {
117 		if (*SRI == Idx)
118 			return DiffListIterator_getVal(&iter);
119 		DiffListIterator_next(&iter);
120 		++SRI;
121 	}
122 
123 	return 0;
124 }
125 
MCRegisterInfo_getRegClass(const MCRegisterInfo * RI,unsigned i)126 const MCRegisterClass* MCRegisterInfo_getRegClass(const MCRegisterInfo *RI, unsigned i)
127 {
128 	//assert(i < getNumRegClasses() && "Register Class ID out of range");
129 	if (i >= RI->NumClasses)
130 		return 0;
131 	return &(RI->Classes[i]);
132 }
133 
MCRegisterClass_contains(const MCRegisterClass * c,unsigned Reg)134 bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg)
135 {
136 	unsigned InByte = Reg % 8;
137 	unsigned Byte = Reg / 8;
138 
139 	if (Byte >= c->RegSetSize)
140 		return false;
141 
142 	return (c->RegSet[Byte] & (1 << InByte)) != 0;
143 }
144