blob: 66db2f8f832b76d696d7391a28c3d2432043955f [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
Nguyen Anh Quynh30e4d7f2014-05-08 22:54:58 +080014/* Capstone Disassembly Engine */
Nguyen Anh Quynhcfe18ad2015-03-02 15:12:42 +080015/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080016
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;
Richard Henderson22ead3e2017-10-21 17:45:40 -070025 const MCPhysReg *List;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080026} DiffListIterator;
27
28void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI,
Richard Henderson22ead3e2017-10-21 17:45:40 -070029 const MCRegisterDesc *D, unsigned NR,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080030 unsigned RA, unsigned PC,
Richard Henderson22ead3e2017-10-21 17:45:40 -070031 const MCRegisterClass *C, unsigned NC,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080032 uint16_t (*RURoots)[2], unsigned NRU,
Richard Henderson22ead3e2017-10-21 17:45:40 -070033 const MCPhysReg *DL,
34 const char *Strings,
35 const uint16_t *SubIndices, unsigned NumIndices,
36 const uint16_t *RET)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080037{
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
Richard Henderson22ead3e2017-10-21 17:45:40 -070053static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal, const MCPhysReg *DiffList)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080054{
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{
Nguyen Anh Quynh2e79ba82014-01-23 22:22:45 +080066 MCPhysReg D;
Alex Ionescu46018db2014-01-22 09:45:00 -080067
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080068 if (d->List == 0)
69 return false;
70
Alex Ionescu46018db2014-01-22 09:45:00 -080071 D = *d->List;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080072 d->List++;
73 d->Val += D;
74
75 if (!D)
76 d->List = 0;
77
78 return (D != 0);
79}
80
81static bool DiffListIterator_isValid(DiffListIterator *d)
82{
83 return (d->List != 0);
84}
85
Richard Henderson22ead3e2017-10-21 17:45:40 -070086unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080087{
88 DiffListIterator iter;
89
90 if (Reg >= RI->NumRegs) {
91 return 0;
92 }
93
Alex Ionescu46018db2014-01-22 09:45:00 -080094 DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SuperRegs);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080095 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
Richard Henderson22ead3e2017-10-21 17:45:40 -0700108unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg, unsigned Idx)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800109{
110 DiffListIterator iter;
Richard Henderson22ead3e2017-10-21 17:45:40 -0700111 const uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800112
Alex Ionescu46018db2014-01-22 09:45:00 -0800113 DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SubRegs);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800114 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
Richard Henderson22ead3e2017-10-21 17:45:40 -0700126const MCRegisterClass* MCRegisterInfo_getRegClass(const MCRegisterInfo *RI, unsigned i)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800127{
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
Richard Henderson22ead3e2017-10-21 17:45:40 -0700134bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800135{
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}