blob: 7b6ee1ba8c4537e9ee778c00606be832bfc62f58 [file] [log] [blame]
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001//=== 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 Disassembler Engine */
15/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
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 {
24 uint16_t Val;
25 MCPhysReg *List;
26} DiffListIterator;
27
28void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI,
29 MCRegisterDesc *D, unsigned NR,
30 unsigned RA, unsigned PC,
31 MCRegisterClass *C, unsigned NC,
32 uint16_t (*RURoots)[2], unsigned NRU,
33 MCPhysReg *DL,
34 char *Strings,
35 uint16_t *SubIndices, unsigned NumIndices,
36 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
53static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal, MCPhysReg *DiffList)
54{
55 d->Val = InitVal;
56 d->List = DiffList;
57}
58
59static uint16_t DiffListIterator_getVal(DiffListIterator *d)
60{
61 return d->Val;
62}
63
64static bool DiffListIterator_next(DiffListIterator *d)
65{
66 if (d->List == 0)
67 return false;
68
69 MCPhysReg D = *d->List;
70 d->List++;
71 d->Val += D;
72
73 if (!D)
74 d->List = 0;
75
76 return (D != 0);
77}
78
79static bool DiffListIterator_isValid(DiffListIterator *d)
80{
81 return (d->List != 0);
82}
83
84unsigned MCRegisterInfo_getMatchingSuperReg(MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, MCRegisterClass *RC)
85{
86 DiffListIterator iter;
87
88 if (Reg >= RI->NumRegs) {
89 return 0;
90 }
91
92 DiffListIterator_init(&iter, Reg, RI->DiffLists + RI->Desc[Reg].SuperRegs);
93 DiffListIterator_next(&iter);
94
95 while(DiffListIterator_isValid(&iter)) {
96 uint16_t val = DiffListIterator_getVal(&iter);
97 if (MCRegisterClass_contains(RC, val) && Reg == MCRegisterInfo_getSubReg(RI, val, SubIdx))
98 return val;
99
100 DiffListIterator_next(&iter);
101 }
102
103 return 0;
104}
105
106unsigned MCRegisterInfo_getSubReg(MCRegisterInfo *RI, unsigned Reg, unsigned Idx)
107{
108 DiffListIterator iter;
109 uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices;
110
111 DiffListIterator_init(&iter, Reg, RI->DiffLists + RI->Desc[Reg].SubRegs);
112 DiffListIterator_next(&iter);
113
114 while(DiffListIterator_isValid(&iter)) {
115 if (*SRI == Idx)
116 return DiffListIterator_getVal(&iter);
117 DiffListIterator_next(&iter);
118 ++SRI;
119 }
120
121 return 0;
122}
123
124MCRegisterClass* MCRegisterInfo_getRegClass(MCRegisterInfo *RI, unsigned i)
125{
126 //assert(i < getNumRegClasses() && "Register Class ID out of range");
127 if (i >= RI->NumClasses)
128 return 0;
129 return &(RI->Classes[i]);
130}
131
132bool MCRegisterClass_contains(MCRegisterClass *c, unsigned Reg)
133{
134 unsigned InByte = Reg % 8;
135 unsigned Byte = Reg / 8;
136
137 if (Byte >= c->RegSetSize)
138 return false;
139
140 return (c->RegSet[Byte] & (1 << InByte)) != 0;
141}