You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
3.4 KiB
143 lines
3.4 KiB
//=== MC/MCRegisterInfo.cpp - Target Register Description -------*- C++ -*-===// |
|
// |
|
// The LLVM Compiler Infrastructure |
|
// |
|
// This file is distributed under the University of Illinois Open Source |
|
// License. See LICENSE.TXT for details. |
|
// |
|
//===----------------------------------------------------------------------===// |
|
// |
|
// This file implements MCRegisterInfo functions. |
|
// |
|
//===----------------------------------------------------------------------===// |
|
|
|
/* Capstone Disassembler Engine */ |
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */ |
|
|
|
#include "MCRegisterInfo.h" |
|
|
|
/// DiffListIterator - Base iterator class that can traverse the |
|
/// differentially encoded register and regunit lists in DiffLists. |
|
/// Don't use this class directly, use one of the specialized sub-classes |
|
/// defined below. |
|
typedef struct DiffListIterator { |
|
uint16_t Val; |
|
MCPhysReg *List; |
|
} DiffListIterator; |
|
|
|
void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI, |
|
MCRegisterDesc *D, unsigned NR, |
|
unsigned RA, unsigned PC, |
|
MCRegisterClass *C, unsigned NC, |
|
uint16_t (*RURoots)[2], unsigned NRU, |
|
MCPhysReg *DL, |
|
char *Strings, |
|
uint16_t *SubIndices, unsigned NumIndices, |
|
uint16_t *RET) |
|
{ |
|
RI->Desc = D; |
|
RI->NumRegs = NR; |
|
RI->RAReg = RA; |
|
RI->PCReg = PC; |
|
RI->Classes = C; |
|
RI->DiffLists = DL; |
|
RI->RegStrings = Strings; |
|
RI->NumClasses = NC; |
|
RI->RegUnitRoots = RURoots; |
|
RI->NumRegUnits = NRU; |
|
RI->SubRegIndices = SubIndices; |
|
RI->NumSubRegIndices = NumIndices; |
|
RI->RegEncodingTable = RET; |
|
} |
|
|
|
static void DiffListIterator_init(DiffListIterator *d, MCPhysReg InitVal, MCPhysReg *DiffList) |
|
{ |
|
d->Val = InitVal; |
|
d->List = DiffList; |
|
} |
|
|
|
static uint16_t DiffListIterator_getVal(DiffListIterator *d) |
|
{ |
|
return d->Val; |
|
} |
|
|
|
static bool DiffListIterator_next(DiffListIterator *d) |
|
{ |
|
MCPhysReg D; |
|
|
|
if (d->List == 0) |
|
return false; |
|
|
|
D = *d->List; |
|
d->List++; |
|
d->Val += D; |
|
|
|
if (!D) |
|
d->List = 0; |
|
|
|
return (D != 0); |
|
} |
|
|
|
static bool DiffListIterator_isValid(DiffListIterator *d) |
|
{ |
|
return (d->List != 0); |
|
} |
|
|
|
unsigned MCRegisterInfo_getMatchingSuperReg(MCRegisterInfo *RI, unsigned Reg, unsigned SubIdx, MCRegisterClass *RC) |
|
{ |
|
DiffListIterator iter; |
|
|
|
if (Reg >= RI->NumRegs) { |
|
return 0; |
|
} |
|
|
|
DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SuperRegs); |
|
DiffListIterator_next(&iter); |
|
|
|
while(DiffListIterator_isValid(&iter)) { |
|
uint16_t val = DiffListIterator_getVal(&iter); |
|
if (MCRegisterClass_contains(RC, val) && Reg == MCRegisterInfo_getSubReg(RI, val, SubIdx)) |
|
return val; |
|
|
|
DiffListIterator_next(&iter); |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
unsigned MCRegisterInfo_getSubReg(MCRegisterInfo *RI, unsigned Reg, unsigned Idx) |
|
{ |
|
DiffListIterator iter; |
|
uint16_t *SRI = RI->SubRegIndices + RI->Desc[Reg].SubRegIndices; |
|
|
|
DiffListIterator_init(&iter, (MCPhysReg)Reg, RI->DiffLists + RI->Desc[Reg].SubRegs); |
|
DiffListIterator_next(&iter); |
|
|
|
while(DiffListIterator_isValid(&iter)) { |
|
if (*SRI == Idx) |
|
return DiffListIterator_getVal(&iter); |
|
DiffListIterator_next(&iter); |
|
++SRI; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
MCRegisterClass* MCRegisterInfo_getRegClass(MCRegisterInfo *RI, unsigned i) |
|
{ |
|
//assert(i < getNumRegClasses() && "Register Class ID out of range"); |
|
if (i >= RI->NumClasses) |
|
return 0; |
|
return &(RI->Classes[i]); |
|
} |
|
|
|
bool MCRegisterClass_contains(MCRegisterClass *c, unsigned Reg) |
|
{ |
|
unsigned InByte = Reg % 8; |
|
unsigned Byte = Reg / 8; |
|
|
|
if (Byte >= c->RegSetSize) |
|
return false; |
|
|
|
return (c->RegSet[Byte] & (1 << InByte)) != 0; |
|
}
|
|
|