Coverage Report

Created: 2026-08-31 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/capstonenext/MCRegisterInfo.c
Line
Count
Source
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.
23
typedef struct DiffListIterator {
24
  uint16_t Val;
25
  const MCPhysReg *List;
26
} DiffListIterator;
27
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, const char *Strings,
34
               const uint16_t *SubIndices,
35
               unsigned NumIndices, const uint16_t *RET)
36
90.0k
{
37
90.0k
  RI->Desc = D;
38
90.0k
  RI->NumRegs = NR;
39
90.0k
  RI->RAReg = RA;
40
90.0k
  RI->PCReg = PC;
41
90.0k
  RI->Classes = C;
42
90.0k
  RI->DiffLists = DL;
43
90.0k
  RI->RegStrings = Strings;
44
90.0k
  RI->NumClasses = NC;
45
90.0k
  RI->RegUnitRoots = RURoots;
46
90.0k
  RI->NumRegUnits = NRU;
47
90.0k
  RI->SubRegIndices = SubIndices;
48
90.0k
  RI->NumSubRegIndices = NumIndices;
49
90.0k
  RI->RegEncodingTable = RET;
50
90.0k
}
51
52
static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal,
53
          const MCPhysReg *DiffList)
54
856k
{
55
856k
  d->Val = InitVal;
56
856k
  d->List = DiffList;
57
856k
}
58
59
static uint16_t DiffListIterator_getVal(DiffListIterator *d)
60
453k
{
61
453k
  return d->Val;
62
453k
}
63
64
static bool DiffListIterator_next(DiffListIterator *d)
65
6.46M
{
66
6.46M
  MCPhysReg D;
67
68
6.46M
  if (d->List == 0)
69
0
    return false;
70
71
6.46M
  D = *d->List;
72
6.46M
  d->List++;
73
6.46M
  d->Val += D;
74
75
6.46M
  if (!D)
76
405k
    d->List = 0;
77
78
6.46M
  return (D != 0);
79
6.46M
}
80
81
static bool DiffListIterator_isValid(DiffListIterator *d)
82
6.46M
{
83
6.46M
  return (d->List != 0);
84
6.46M
}
85
86
unsigned MCRegisterInfo_getMatchingSuperReg(const MCRegisterInfo *RI,
87
              unsigned Reg, unsigned SubIdx,
88
              const MCRegisterClass *RC)
89
24.2k
{
90
24.2k
  DiffListIterator iter;
91
92
24.2k
  if (Reg >= RI->NumRegs) {
93
0
    return 0;
94
0
  }
95
96
24.2k
  DiffListIterator_init(&iter, (MCPhysReg)Reg,
97
24.2k
            RI->DiffLists + RI->Desc[Reg].SuperRegs);
98
24.2k
  DiffListIterator_next(&iter);
99
100
26.5k
  while (DiffListIterator_isValid(&iter)) {
101
26.5k
    uint16_t val = DiffListIterator_getVal(&iter);
102
26.5k
    if (MCRegisterClass_contains(RC, val) &&
103
24.2k
        Reg == MCRegisterInfo_getSubReg(RI, val, SubIdx))
104
24.2k
      return val;
105
106
2.28k
    DiffListIterator_next(&iter);
107
2.28k
  }
108
109
0
  return 0;
110
24.2k
}
111
112
unsigned MCRegisterInfo_getSubReg(const MCRegisterInfo *RI, unsigned Reg,
113
          unsigned Idx)
114
832k
{
115
832k
  DiffListIterator iter;
116
832k
  const uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices;
117
118
832k
  DiffListIterator_init(&iter, (MCPhysReg)Reg,
119
832k
            RI->DiffLists + RI->Desc[Reg].SubRegs);
120
832k
  DiffListIterator_next(&iter);
121
122
6.44M
  while (DiffListIterator_isValid(&iter)) {
123
6.03M
    if (*SRI == Idx)
124
426k
      return DiffListIterator_getVal(&iter);
125
5.61M
    DiffListIterator_next(&iter);
126
5.61M
    ++SRI;
127
5.61M
  }
128
129
405k
  return 0;
130
832k
}
131
132
const MCRegisterClass *MCRegisterInfo_getRegClass(const MCRegisterInfo *RI,
133
              unsigned i)
134
4.94M
{
135
  //assert(i < getNumRegClasses() && "Register Class ID out of range");
136
4.94M
  if (i >= RI->NumClasses)
137
0
    return 0;
138
4.94M
  return &(RI->Classes[i]);
139
4.94M
}
140
141
bool MCRegisterClass_contains(const MCRegisterClass *c, unsigned Reg)
142
4.29M
{
143
4.29M
  unsigned InByte = 0;
144
4.29M
  unsigned Byte = 0;
145
146
  // Make sure that MCRegisterInfo_getRegClass didn't return 0
147
  // (for calls to GETREGCLASS_CONTAIN0)
148
4.29M
  if (!c)
149
0
    return false;
150
151
4.29M
  InByte = Reg % 8;
152
4.29M
  Byte = Reg / 8;
153
154
4.29M
  if (Byte >= c->RegSetSize)
155
873k
    return false;
156
157
3.42M
  return (c->RegSet[Byte] & (1 << InByte)) != 0;
158
4.29M
}
159
160
unsigned MCRegisterClass_getRegister(const MCRegisterClass *c, unsigned RegNo)
161
289k
{
162
289k
  return c->RegsBegin[RegNo];
163
289k
}