⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 validate.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
  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 + -