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. 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 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 81static bool DiffListIterator_isValid(DiffListIterator *d) 82{ 83 return (d->List != 0); 84} 85 86unsigned MCRegisterInfo_getMatchingSuperReg(MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, 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 108unsigned MCRegisterInfo_getSubReg(MCRegisterInfo *RI, unsigned Reg, unsigned Idx) 109{ 110 DiffListIterator iter; 111 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 126MCRegisterClass* MCRegisterInfo_getRegClass(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 134bool MCRegisterClass_contains(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