📄 armsupp.c
字号:
ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result){ ASSIGNV (AddOverflow (a, b, result));}/* Assigns the C flag after an subtraction of a and b to give result. */voidARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result){ ASSIGNC ((NEG (a) && POS (b)) || (NEG (a) && POS (result)) || (POS (b) && POS (result)));}/* Assigns the V flag after an subtraction of a and b to give result. */voidARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result){ ASSIGNV (SubOverflow (a, b, result));}/* This function does the work of generating the addresses used in an LDC instruction. The code here is always post-indexed, it's up to the caller to get the input address correct and to handle base register modification. It also handles the Busy-Waiting. */voidARMul_LDC (ARMul_State * state, ARMword instr, ARMword address){ unsigned cpab; ARMword data; UNDEF_LSCPCBaseWb; //printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);/*chy 2004-05-23 should update this function in the future,should concern dataabort*/// chy 2004-05-25 , fix it now,so needn't printf // printf("SKYEYE ARMul_LDC, should update this function!!!!!\n"); //exit(-1); if (!CP_ACCESS_ALLOWED (state, CPNum)) { /* printf ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n", CPNum, instr, address); */ ARMul_UndefInstr (state, instr); return; } if (ADDREXCEPT (address)) INTERNALABORT (address); cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0); while (cpab == ARMul_BUSY) { ARMul_Icycles (state, 1, 0); if (IntPending (state)) { cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, instr, 0); return; } else cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, 0); } if (cpab == ARMul_CANT) { /* printf ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n", CPNum, instr, address); */ CPTAKEABORT; return; } cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0); data = ARMul_LoadWordN (state, address); //chy 2004-05-25 if (state->abortSig || state->Aborted) goto L_ldc_takeabort; BUSUSEDINCPCN;//chy 2004-05-25/* if (BIT (21)) LSBase = state->Base;*/ cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); while (cpab == ARMul_INC) { address += 4; data = ARMul_LoadWordN (state, address); //chy 2004-05-25 if (state->abortSig || state->Aborted) goto L_ldc_takeabort; cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); }//chy 2004-05-25 L_ldc_takeabort: if (BIT (21)) { if (! ((state->abortSig || state->Aborted) && state->lateabtSig == LOW)) LSBase = state->Base; } if (state->abortSig || state->Aborted) TAKEABORT;}/* This function does the work of generating the addresses used in an STC instruction. The code here is always post-indexed, it's up to the caller to get the input address correct and to handle base register modification. It also handles the Busy-Waiting. */voidARMul_STC (ARMul_State * state, ARMword instr, ARMword address){ unsigned cpab; ARMword data; UNDEF_LSCPCBaseWb; //printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address); /*chy 2004-05-23 should update this function in the future,should concern dataabort */// skyeye_instr_debug=0;printf("SKYEYE debug end!!!!\n");// chy 2004-05-25 , fix it now,so needn't printf // printf("SKYEYE ARMul_STC, should update this function!!!!!\n"); //exit(-1); if (!CP_ACCESS_ALLOWED (state, CPNum)) { /* printf ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr, CPnum is %x, instr %x, addr %x\n", CPNum, instr, address); */ ARMul_UndefInstr (state, instr); return; } if (ADDREXCEPT (address) || VECTORACCESS (address)) INTERNALABORT (address); cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data); while (cpab == ARMul_BUSY) { ARMul_Icycles (state, 1, 0); if (IntPending (state)) { cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, instr, 0); return; } else cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, &data); } if (cpab == ARMul_CANT) { /* printf ("SKYEYE ARMul_STC,CANT, undefinstr, CPnum is %x, instr %x, addr %x\n", CPNum, instr, address); */ CPTAKEABORT; return; }#ifndef MODE32 if (ADDREXCEPT (address) || VECTORACCESS (address)) INTERNALABORT (address);#endif BUSUSEDINCPCN;//chy 2004-05-25/* if (BIT (21)) LSBase = state->Base;*/ cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); ARMul_StoreWordN (state, address, data); //chy 2004-05-25 if (state->abortSig || state->Aborted) goto L_stc_takeabort; while (cpab == ARMul_INC) { address += 4; cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); ARMul_StoreWordN (state, address, data); //chy 2004-05-25 if (state->abortSig || state->Aborted) goto L_stc_takeabort; }//chy 2004-05-25 L_stc_takeabort: if (BIT (21)) { if (! ((state->abortSig || state->Aborted) && state->lateabtSig == LOW)) LSBase = state->Base; } if (state->abortSig || state->Aborted) TAKEABORT;}/* This function does the Busy-Waiting for an MCR instruction. */voidARMul_MCR (ARMul_State * state, ARMword instr, ARMword source){ unsigned cpab; //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source); if (!CP_ACCESS_ALLOWED (state, CPNum)) { //chy 2004-07-19 should fix in the future ????!!!! //printf("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source); ARMul_UndefInstr (state, instr); return; } cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source); while (cpab == ARMul_BUSY) { ARMul_Icycles (state, 1, 0); if (IntPending (state)) { cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0); return; } else cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source); } if (cpab == ARMul_CANT) { printf ("SKYEYE ARMul_MCR, CANT, UndefinedInstr CPnum is %x, source %x\n", CPNum, source); ARMul_Abort (state, ARMul_UndefinedInstrV); } else { BUSUSEDINCPCN; ARMul_Ccycles (state, 1, 0); }}/* This function does the Busy-Waiting for an MRC instruction. */ARMwordARMul_MRC (ARMul_State * state, ARMword instr){ unsigned cpab; ARMword result = 0; //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr); if (!CP_ACCESS_ALLOWED (state, CPNum)) { //chy 2004-07-19 should fix in the future????!!!! //printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n",CPNum, instr); ARMul_UndefInstr (state, instr); return; } cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result); while (cpab == ARMul_BUSY) { ARMul_Icycles (state, 1, 0); if (IntPending (state)) { cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, instr, 0); return (0); } else cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, &result); } if (cpab == ARMul_CANT) { printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr); ARMul_Abort (state, ARMul_UndefinedInstrV); /* Parent will destroy the flags otherwise. */ result = ECC; } else { BUSUSEDINCPCN; ARMul_Ccycles (state, 1, 0); ARMul_Icycles (state, 1, 0); } return result;}/* This function does the Busy-Waiting for an CDP instruction. */voidARMul_CDP (ARMul_State * state, ARMword instr){ unsigned cpab; if (!CP_ACCESS_ALLOWED (state, CPNum)) { ARMul_UndefInstr (state, instr); return; } cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr); while (cpab == ARMul_BUSY) { ARMul_Icycles (state, 1, 0); if (IntPending (state)) { cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, instr); return; } else cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr); } if (cpab == ARMul_CANT) ARMul_Abort (state, ARMul_UndefinedInstrV); else BUSUSEDN;}/* This function handles Undefined instructions, as CP isntruction. */voidARMul_UndefInstr (ARMul_State * state, ARMword instr ATTRIBUTE_UNUSED){ ARMul_Abort (state, ARMul_UndefinedInstrV);}/* Return TRUE if an interrupt is pending, FALSE otherwise. */unsignedIntPending (ARMul_State * state){ /* Any exceptions. */ if (state->NresetSig == LOW) { ARMul_Abort (state, ARMul_ResetV); return TRUE; } else if (!state->NfiqSig && !FFLAG) { ARMul_Abort (state, ARMul_FIQV); return TRUE; } else if (!state->NirqSig && !IFLAG) { ARMul_Abort (state, ARMul_IRQV); return TRUE; } return FALSE;}/* Align a word access to a non word boundary. */ARMwordARMul_Align (state, address, data) ARMul_State *state ATTRIBUTE_UNUSED; ARMword address; ARMword data;{ /* This code assumes the address is really unaligned, as a shift by 32 is undefined in C. */ address = (address & 3) << 3; /* Get the word address. */ return ((data >> address) | (data << (32 - address))); /* rot right */}/* This routine is used to call another routine after a certain number of cycles have been executed. The first parameter is the number of cycles delay before the function is called, the second argument is a pointer to the function. A delay of zero doesn't work, just call the function. */voidARMul_ScheduleEvent (ARMul_State * state, unsigned int delay, unsigned (*what) (ARMul_State *)){ unsigned int when; struct EventNode *event; if (state->EventSet++ == 0) state->Now = ARMul_Time (state); when = (state->Now + delay) % EVENTLISTSIZE; event = (struct EventNode *) malloc (sizeof (struct EventNode)); if (!event) { printf ("SKYEYE:ARMul_ScheduleEvent: malloc event error\n"); skyeye_exit (-1); } event->func = what; event->next = *(state->EventPtr + when); *(state->EventPtr + when) = event;}/* This routine is called at the beginning of every cycle, to envoke scheduled events. */voidARMul_EnvokeEvent (ARMul_State * state){ static unsigned int then; then = state->Now; state->Now = ARMul_Time (state) % EVENTLISTSIZE; if (then < state->Now) /* Schedule events. */ EnvokeList (state, then, state->Now); else if (then > state->Now) { /* Need to wrap around the list. */ EnvokeList (state, then, EVENTLISTSIZE - 1L); EnvokeList (state, 0L, state->Now); }}/* Envokes all the entries in a range. */static voidEnvokeList (ARMul_State * state, unsigned int from, unsigned int to){ for (; from <= to; from++) { struct EventNode *anevent; anevent = *(state->EventPtr + from); while (anevent) { (anevent->func) (state); state->EventSet--; anevent = anevent->next; } *(state->EventPtr + from) = NULL; }}/* This routine is returns the number of clock ticks since the last reset. */unsigned intARMul_Time (ARMul_State * state){ return (state->NumScycles + state->NumNcycles + state->NumIcycles + state->NumCcycles + state->NumFcycles);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -