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

📄 armsupp.c

📁 skyeye的开源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -