📄 validate.c
字号:
wordsToGet = BIT(22) ? state->ValCP5_LDCL_Words : 1;
if ((type == ARMul_CP_FIRST) || (result == ARMul_CP_FIRST)) {
regNum = BITS(12,15); /* Get the register number */
words = 0; /* Reset the word fetch counter */
if (wordsToGet == 1) {
return ARMul_CP_LAST;
}
else {
return ARMul_CP_INC;
}
}
if (type == ARMul_CP_TRANSFER) {
if (wordsToGet == 1) {
return ARMul_CP_LAST;
}
else {
return ARMul_CP_INC;
}
}
if (BIT(22)) {
/* Its a LDCL instruction so 2 words to fetch */
/* Do the data access, incrementing the register as we go */
state->ValCP5Reg[regNum++] = data;
regNum &= 0xf;
/* If we've got enough words then return done, else request more ! */
words++;
if (words >= wordsToGet) {
return ARMul_CP_DONE;
}
else if ((words+1) == wordsToGet) {
return ARMul_CP_LAST;
}
else {
return ARMul_CP_INC;
}
}
else {
/* NOT a long access so get just one word */
state->ValCP5Reg[BITS(12,15)] = data;
return ARMul_CP_DONE;
}
}
static int CP5LDC(void *handle, int type, ARMword instr, ARMword *data)
{
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return CheckLast(handle, DoCP5LDC(handle, type, instr, data ? *data : 0,
CheckBusyCycles(handle, CP5_WAIT_COUNT), cycle_count));
}
static int DoCP5STC(void *handle, int type, ARMword instr, ARMword *data, unsigned long busy_cycles, ARMTime cycle_count)
{
ValidateState *state=(ValidateState *)handle;
static int regNum;
static unsigned words;
static unsigned wordsToSend;
int result = type;
if (busy_cycles && CheckBusyWait(type, &state->CP5Busy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
if ((type == ARMul_CP_FIRST) || (result == ARMul_CP_FIRST)) {
regNum = BITS(12,15); /* Get the register number */
words = 0; /* Reset the word fetch counter */
wordsToSend = 1; /* just to be safe */
return ARMul_CP_INC;
}
if (BIT(22)) {
/* it's a long access*/
/* Its a CPDTL instruction so 2 words */
wordsToSend = 2;
/* Now do the data access */
*data = state->ValCP5Reg[regNum++];
/* Store the data in Register[regNum] and increment regNum for the
next transfer */
/* If we've got enough words then return done, else request more ! */
if (++words >= wordsToSend)
return ARMul_CP_DONE;
else
return ARMul_CP_INC;
}
else {
/* get just one word */
*data = state->ValCP5Reg[regNum];
return ARMul_CP_DONE;
}
}
static int CP5STC(void *handle, int type, ARMword instr, ARMword *data)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return CheckLast(handle, DoCP5STC(handle, type, instr, data, CheckBusyCycles(handle, CP5_WAIT_COUNT), cycle_count));
}
/* CP7 LDC instruction. Does 4 word accesses */
static int DoCP7LDC(void *handle, int type, ARMword instr, ARMword data, unsigned long busy_cycles, ARMTime cycle_count)
{
ValidateState *state=(ValidateState *)handle;
static int regNum;
static unsigned words;
static unsigned wordsToGet;
int result = type;
if (busy_cycles && CheckBusyWait(type, &state->CP7Busy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
wordsToGet = BIT(22) ? 4 : 1;
if ((type == ARMul_CP_FIRST) || (result == ARMul_CP_FIRST)) {
regNum = BITS(12,15); /* Get the register number */
words = 0; /* Reset the word fetch counter */
if (wordsToGet == 1) {
return ARMul_CP_LAST;
}
else {
return ARMul_CP_INC;
}
}
else if (type == ARMul_CP_TRANSFER) {
if (wordsToGet == 1) {
return ARMul_CP_LAST;
}
else {
return ARMul_CP_INC;
}
}
if (BIT(22)) {
/* Its a LDCL instruction so 4 words to fetch */
/* Do the data access, incrementing the register as we go */
ValCP7Reg[regNum++] = data;
regNum &= 0xf;
/* If we've got enough words then return done, else request more ! */
words ++;
if (words >= wordsToGet) {
return ARMul_CP_DONE;
}
else if ((words+1) == wordsToGet) {
return ARMul_CP_LAST;
}
else {
return ARMul_CP_INC;
}
}
else {
/* NOT a long access so get just one word */
ValCP7Reg[BITS(12,15)] = data;
return ARMul_CP_DONE;
}
}
static int CP7LDC(void *handle, int type, ARMword instr, ARMword *data)
{
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return CheckLast(handle, DoCP7LDC(handle, type, instr, data ? *data : 0,
CheckBusyCycles(handle, 0), cycle_count));
}
/* CP1 and CP3 use the same logic as CP7 but add extra busy-wait cycles */
static int CP3LDC(void *handle, int type, ARMword instr, ARMword *data)
{
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return CheckLast(handle, DoCP7LDC(handle, type, instr, data ? *data : 0,
CheckBusyCycles(handle, CP3_WAIT_COUNT), cycle_count));
}
static int CP1LDC(void *handle, int type, ARMword instr, ARMword *data)
{
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return CheckLast(handle, DoCP7LDC(handle, type, instr, data ? *data : 0, CheckBusyCycles(handle, CP1_WAIT_COUNT), cycle_count));
}
static int DoCP7STC(void *handle, int type, ARMword instr, ARMword *data, unsigned long busy_cycles, ARMTime cycle_count)
{
ValidateState *state=(ValidateState *)handle;
static int regNum;
static unsigned words;
static unsigned wordsToSend;
int result = type;
if (busy_cycles && CheckBusyWait(type, &state->CP7Busy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
if ((type == ARMul_CP_FIRST) || (result == ARMul_CP_FIRST)) {
regNum = BITS(12,15); /* Get the register number */
words = 0; /* Reset the word fetch counter */
wordsToSend = 1; /* just to be safe */
return ARMul_CP_INC;
}
if (BIT(22)) {
/* it's a long access*/
/* Its a STCL instruction so 4 words */
wordsToSend = 4;
/* Now do the data access */
*data = ValCP7Reg[regNum++];
/* Store the data in Register[regNum] and increment regNum for the
next transfer */
/* If we've got enough words then return done, else request more ! */
if (++words >= wordsToSend)
return ARMul_CP_DONE;
else
return ARMul_CP_INC;
}
else {
/* get just one word */
*data = ValCP7Reg[regNum];
return ARMul_CP_DONE;
}
}
static int CP7STC(void *handle, int type, ARMword instr, ARMword *data)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return CheckLast(handle, DoCP7STC(handle, type, instr, data, CheckBusyCycles(handle, 0), cycle_count));
}
/* CP1 and CP3 use the same logic as CP7 but add extra busy-wait cycles */
static int CP1STC(void *handle, int type, ARMword instr, ARMword *data)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return CheckLast(handle, DoCP7STC(handle, type, instr, data, CheckBusyCycles(handle, CP1_WAIT_COUNT), cycle_count));
}
static int CP3STC(void *handle, int type, ARMword instr, ARMword *data)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return CheckLast(handle, DoCP7STC(handle, type, instr, data, CheckBusyCycles(handle, CP3_WAIT_COUNT), cycle_count));
}
/* CP8 LDC instruction. Does 2 word accesses */
static int DoCP8LDC(void *handle, int type, ARMword instr, ARMword data, unsigned long busy_cycles, ARMTime cycle_count)
{
ValidateState *state=(ValidateState *)handle;
static int regNum;
static unsigned words;
static unsigned wordsToGet;
int result = type;
if (busy_cycles && CheckBusyWait(type, &state->CP8Busy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
wordsToGet = BIT(22) ? 2 : 1;
if ((type == ARMul_CP_FIRST) || (result == ARMul_CP_FIRST)) {
regNum = BITS(12,15); /* Get the register number */
words = 0; /* Reset the word fetch counter */
if (wordsToGet == 1) {
return ARMul_CP_LAST;
}
else {
return ARMul_CP_INC;
}
}
else if (type == ARMul_CP_TRANSFER) {
if (wordsToGet == 1) {
return ARMul_CP_LAST;
}
else {
return ARMul_CP_INC;
}
}
if (BIT(22)) {
/* Its a LDCL instruction so 2 words to fetch */
/* Do the data access, incrementing the register as we go */
ValCP8Reg[regNum++] = data;
regNum &= 0xf;
/* If we've got enough words then return done, else request more ! */
words ++;
if (words >= wordsToGet) {
return ARMul_CP_DONE;
}
else if ((words+1) == wordsToGet) {
return ARMul_CP_LAST;
}
else {
return ARMul_CP_INC;
}
}
else {
/* NOT a long access so get just one word */
ValCP8Reg[BITS(12,15)] = data;
return ARMul_CP_DONE;
}
}
static int CP8LDC(void *handle, int type, ARMword instr, ARMword *data)
{
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
return CheckLast(handle, DoCP8LDC(handle, type, instr, data ? *data : 0, CheckBusyCycles(handle, 0), cycle_count));
}
static int DoCP8STC(void *handle, int type, ARMword instr, ARMword *data, unsigned long busy_cycles, ARMTime cycle_count)
{
ValidateState *state=(ValidateState *)handle;
static int regNum;
static unsigned words;
static unsigned wordsToSend;
int result = type;
if (busy_cycles && CheckBusyWait(type, &state->CP8Busy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
if ((type == ARMul_CP_FIRST) || (result == ARMul_CP_FIRST)) {
regNum = BITS(12,15); /* Get the register number */
words = 0; /* Reset the word fetch counter */
wordsToSend = 1; /* just to be safe */
return ARMul_CP_INC;
}
if (BIT(22)) {
/* it's a long access*/
/* Its a CPDTL instruction so 2 words */
wordsToSend = 2;
/* Now do the data access */
*data = ValCP8Reg[regNum++];
/* Store the data in Register[regNum] and increment regNum for the
next transfer */
/* If we've got enough words then return done, else request more ! */
if (++words >= wordsToSend)
return ARMul_CP_DONE;
else
return ARMul_CP_INC;
}
else {
/* get just one word */
*data = ValCP8Reg[regNum];
return ARMul_CP_DONE;
}
}
static int CP8STC(void *handle, int type, ARMword instr, ARMword *data)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return CheckLast(handle, DoCP8STC(handle, type, instr, data, CheckBusyCycles(handle, 0), cycle_count));
}
/* MRC instructions for CP 4,5, 7 and 8 - */
/* there are 8 versions to allow variations between CP's, with a single */
/* function (DoMRC) which does all the stuff common to all MRC's */
static int DoMRC(void *handle, int type, ARMword instr, ARMword *value,
ARMword reg_val, unsigned long busy_cycles,
CPBusyWait *CPBusy, ARMTime cycle_count)
{
int result = 0;
UNUSEDARG(instr); (void)handle;
if (busy_cycles && CheckBusyWait(type, CPBusy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
if (type == ARMul_CP_FIRST || result == ARMul_CP_FIRST) {
*value = reg_val;
return ARMul_CP_DONE; /* Complete */
}
return ARMul_CP_BUSY;
}
static int DoMRRC(void *handle, int type, ARMword instr, ARMword *value,
ARMword reg_val, ARMword reg_val2,
unsigned long busy_cycles,
CPBusyWait *CPBusy, ARMTime cycle_count)
{
int result = 0;
UNUSEDARG(instr); (void)handle;
if (busy_cycles && CheckBusyWait(type, CPBusy, busy_cycles, cycle_count, &result)) {
return result; /* Either busy waiting or interrupted */
}
if (type == ARMul_CP_FIRST || result == ARMul_CP_FIRST) {
value[0] = reg_val;
value[1] = reg_val2;
return ARMul_CP_DONE; /* Complete */
}
return ARMul_CP_BUSY;
}
static int CP1MRC(void *handle, int type, ARMword instr,ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return DoMRC(handle, type, instr, value, ValCP1Reg[BITS(16,19)],
CheckBusyCycles(handle, CP1_WAIT_COUNT), &state->CP1Busy, cycle_count);
}
static int CP3MRC(void *handle, int type, ARMword instr,ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount(state);
return DoMRC(handle, type, instr, value, ValCP3Reg[BITS(16,19)],
CheckBusyCycles(handle, CP3_WAIT_COUNT), &state->CP3Busy, cycle_count);
}
static int CP4MRC(void *handle, int type, ARMword instr,ARMword *value)
{
ValidateState *state=(ValidateState *)handle;
ARMTime cycle_count = GetCycleCount((ValidateState*)handle);
#if 1
/* If a previous CDP p4 initiated a busy-wait, wait for that! */
if (cycle_count < state->CPBusyUntil[4])
return ARMul_CP_BUSY;
if (type == ARMul_CP_BUSY)
type = ARMul_CP_FIRST;
#endif
return DoMRC(handle, type, instr, value, ValCP4Reg[BITS(16,19)],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -