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

📄 maverick.c

📁 SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具
💻 C
📖 第 1 页 / 共 2 页
字号:
{	static unsigned words;	if (type != ARMul_DATA) {		words = 0;		return ARMul_DONE;	}	if (BIT (22)) {		/* It's a long access, get two words.  */		/* cfstrd */		printfdbg ("cfstrd\n");		if (words == 0) {			if (state->bigendSig)				*data = (ARMword) DSPregs[DEST_REG].upper.i;			else				*data = (ARMword) DSPregs[DEST_REG].lower.i;		}		else {			if (state->bigendSig)				*data = (ARMword) DSPregs[DEST_REG].lower.i;			else				*data = (ARMword) DSPregs[DEST_REG].upper.i;		}		++words;		if (words == 2) {			printfdbg ("\tmem = mvd%d = %g\n", DEST_REG,				   mv_getRegDouble (DEST_REG));			return ARMul_DONE;		}		else			return ARMul_INC;	}	else {		/* Get just one word.  */		/* cfstrs */		printfdbg ("cfstrs mvf%d <-- %f\n", DEST_REG,			   DSPregs[DEST_REG].upper.f);		*data = (ARMword) DSPregs[DEST_REG].upper.i;		return ARMul_DONE;	}}unsignedDSPSTC5 (ARMul_State * state ATTRIBUTE_UNUSED,	 unsigned type, ARMword instr, ARMword * data){	static unsigned words;	if (type != ARMul_DATA) {		words = 0;		return ARMul_DONE;	}	if (BIT (22)) {		/* It's a long access, store two words.  */		/* cfstr64 */		printfdbg ("cfstr64\n");		if (words == 0) {			if (state->bigendSig)				*data = (ARMword) DSPregs[DEST_REG].upper.i;			else				*data = (ARMword) DSPregs[DEST_REG].lower.i;		}		else {			if (state->bigendSig)				*data = (ARMword) DSPregs[DEST_REG].lower.i;			else				*data = (ARMword) DSPregs[DEST_REG].upper.i;		}		++words;		if (words == 2) {			printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG,				   mv_getReg64int (DEST_REG));			return ARMul_DONE;		}		else			return ARMul_INC;	}	else {		/* Store just one word.  */		/* cfstr32 */		*data = (ARMword) DSPregs[DEST_REG].lower.i;		printfdbg ("cfstr32 MEM = %d\n", (int) *data);		return ARMul_DONE;	}}unsignedDSPCDP4 (ARMul_State * state, unsigned type, ARMword instr){	int opcode2;	opcode2 = BITS (5, 7);	switch (BITS (20, 21)) {	case 0:		switch (opcode2) {		case 0:	/* cfcpys */			printfdbg ("cfcpys mvf%d = mvf%d = %f\n",				   DEST_REG, SRC1_REG,				   DSPregs[SRC1_REG].upper.f);			DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f;			break;		case 1:	/* cfcpyd */			printfdbg ("cfcpyd mvd%d = mvd%d = %g\n",				   DEST_REG, SRC1_REG,				   mv_getRegDouble (SRC1_REG));			mv_setRegDouble (DEST_REG,					 mv_getRegDouble (SRC1_REG));			break;		case 2:	/* cfcvtds */			printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n",				   DEST_REG, SRC1_REG,				   (float) mv_getRegDouble (SRC1_REG));			DSPregs[DEST_REG].upper.f =				(float) mv_getRegDouble (SRC1_REG);			break;		case 3:	/* cfcvtsd */			printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n",				   DEST_REG, SRC1_REG,				   (double) DSPregs[SRC1_REG].upper.f);			mv_setRegDouble (DEST_REG,					 (double) DSPregs[SRC1_REG].upper.f);			break;		case 4:	/* cfcvt32s */			printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n",				   DEST_REG, SRC1_REG,				   (float) DSPregs[SRC1_REG].lower.i);			DSPregs[DEST_REG].upper.f =				(float) DSPregs[SRC1_REG].lower.i;			break;		case 5:	/* cfcvt32d */			printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n",				   DEST_REG, SRC1_REG,				   (double) DSPregs[SRC1_REG].lower.i);			mv_setRegDouble (DEST_REG,					 (double) DSPregs[SRC1_REG].lower.i);			break;		case 6:	/* cfcvt64s */			printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n",				   DEST_REG, SRC1_REG,				   (float) mv_getReg64int (SRC1_REG));			DSPregs[DEST_REG].upper.f =				(float) mv_getReg64int (SRC1_REG);			break;		case 7:	/* cfcvt64d */			printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n",				   DEST_REG, SRC1_REG,				   (double) mv_getReg64int (SRC1_REG));			mv_setRegDouble (DEST_REG,					 (double) mv_getReg64int (SRC1_REG));			break;		}		break;	case 1:		switch (opcode2) {		case 0:	/* cfmuls */			printfdbg ("cfmuls mvf%d = mvf%d = %f\n",				   DEST_REG,				   SRC1_REG,				   DSPregs[SRC1_REG].upper.f *				   DSPregs[SRC2_REG].upper.f);			DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f				* DSPregs[SRC2_REG].upper.f;			break;		case 1:	/* cfmuld */			printfdbg ("cfmuld mvd%d = mvd%d = %g\n",				   DEST_REG,				   SRC1_REG,				   mv_getRegDouble (SRC1_REG) *				   mv_getRegDouble (SRC2_REG));			mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)					 * mv_getRegDouble (SRC2_REG));			break;		default:			fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n",				 instr);			cirrus_not_implemented ("unknown");			break;		}		break;	case 3:		switch (opcode2) {		case 0:	/* cfabss */			DSPregs[DEST_REG].upper.f =				(DSPregs[SRC1_REG].upper.f <				 0.0F ? -DSPregs[SRC1_REG].upper.				 f : DSPregs[SRC1_REG].upper.f);			printfdbg ("cfabss mvf%d = |mvf%d| = %f\n", DEST_REG,				   SRC1_REG, DSPregs[DEST_REG].upper.f);			break;		case 1:	/* cfabsd */			mv_setRegDouble (DEST_REG,					 (mv_getRegDouble (SRC1_REG) < 0.0 ?					  -mv_getRegDouble (SRC1_REG)					  : mv_getRegDouble (SRC1_REG)));			printfdbg ("cfabsd mvd%d = |mvd%d| = %g\n",				   DEST_REG, SRC1_REG,				   mv_getRegDouble (DEST_REG));			break;		case 2:	/* cfnegs */			DSPregs[DEST_REG].upper.f =				-DSPregs[SRC1_REG].upper.f;			printfdbg ("cfnegs mvf%d = -mvf%d = %f\n", DEST_REG,				   SRC1_REG, DSPregs[DEST_REG].upper.f);			break;		case 3:	/* cfnegd */			mv_setRegDouble (DEST_REG,					 -mv_getRegDouble (SRC1_REG));			printfdbg ("cfnegd mvd%d = -mvd%d = %g\n", DEST_REG,				   mv_getRegDouble (DEST_REG));			break;		case 4:	/* cfadds */			DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f				+ DSPregs[SRC2_REG].upper.f;			printfdbg ("cfadds mvf%d = mvf%d + mvf%d = %f\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   DSPregs[DEST_REG].upper.f);			break;		case 5:	/* cfaddd */			mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)					 + mv_getRegDouble (SRC2_REG));			printfdbg ("cfaddd: mvd%d = mvd%d + mvd%d = %g\n",				   DEST_REG,				   SRC1_REG, SRC2_REG,				   mv_getRegDouble (DEST_REG));			break;		case 6:	/* cfsubs */			DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f				- DSPregs[SRC2_REG].upper.f;			printfdbg ("cfsubs: mvf%d = mvf%d - mvf%d = %f\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   DSPregs[DEST_REG].upper.f);			break;		case 7:	/* cfsubd */			mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)					 - mv_getRegDouble (SRC2_REG));			printfdbg ("cfsubd: mvd%d = mvd%d - mvd%d = %g\n",				   DEST_REG,				   SRC1_REG, SRC2_REG,				   mv_getRegDouble (DEST_REG));			break;		}		break;	default:		fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);		cirrus_not_implemented ("unknown");		break;	}	return ARMul_DONE;}unsignedDSPCDP5 (ARMul_State * state, unsigned type, ARMword instr){	int opcode2;	char shift;	opcode2 = BITS (5, 7);	/* Shift constants are 7bit signed numbers in bits 0..3|5..7.  */	shift = BITS (0, 3) | (BITS (5, 7)) << 4;	if (shift & 0x40)		shift |= 0xc0;	switch (BITS (20, 21)) {	case 0:		/* cfsh32 */		printfdbg ("cfsh32 %s amount=%d\n",			   shift < 0 ? "right" : "left", shift);		if (shift < 0)			/* Negative shift is a right shift.  */			DSPregs[DEST_REG].lower.i =				DSPregs[SRC1_REG].lower.i >> -shift;		else			/* Positive shift is a left shift.  */			DSPregs[DEST_REG].lower.i =				DSPregs[SRC1_REG].lower.i << shift;		break;	case 1:		switch (opcode2) {		case 0:	/* cfmul32 */			DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i				* DSPregs[SRC2_REG].lower.i;			printfdbg ("cfmul32 mvfx%d = mvfx%d * mvfx%d = %d\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   DSPregs[DEST_REG].lower.i);			break;		case 1:	/* cfmul64 */			mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG)					* mv_getReg64int (SRC2_REG));			printfdbg				("cfmul64 mvdx%d = mvdx%d * mvdx%d = %lld\n",				 DEST_REG, SRC1_REG, SRC2_REG,				 mv_getReg64int (DEST_REG));			break;		case 2:	/* cfmac32 */			DSPregs[DEST_REG].lower.i				+=				DSPregs[SRC1_REG].lower.i *				DSPregs[SRC2_REG].lower.i;			printfdbg ("cfmac32 mvfx%d += mvfx%d * mvfx%d = %d\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   DSPregs[DEST_REG].lower.i);			break;		case 3:	/* cfmsc32 */			DSPregs[DEST_REG].lower.i				-=				DSPregs[SRC1_REG].lower.i *				DSPregs[SRC2_REG].lower.i;			printfdbg ("cfmsc32 mvfx%d -= mvfx%d * mvfx%d = %d\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   DSPregs[DEST_REG].lower.i);			break;		case 4:	/* cfcvts32 */			/* fixme: this should round */			DSPregs[DEST_REG].lower.i =				(int) DSPregs[SRC1_REG].upper.f;			printfdbg ("cfcvts32 mvfx%d = mvf%d = %d\n", DEST_REG,				   SRC1_REG, DSPregs[DEST_REG].lower.i);			break;		case 5:	/* cfcvtd32 */			/* fixme: this should round */			DSPregs[DEST_REG].lower.i =				(int) mv_getRegDouble (SRC1_REG);			printfdbg ("cfcvtd32 mvdx%d = mvd%d = %d\n", DEST_REG,				   SRC1_REG, DSPregs[DEST_REG].lower.i);			break;		case 6:	/* cftruncs32 */			DSPregs[DEST_REG].lower.i =				(int) DSPregs[SRC1_REG].upper.f;			printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n",				   DEST_REG, SRC1_REG,				   DSPregs[DEST_REG].lower.i);			break;		case 7:	/* cftruncd32 */			DSPregs[DEST_REG].lower.i =				(int) mv_getRegDouble (SRC1_REG);			printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n",				   DEST_REG, SRC1_REG,				   DSPregs[DEST_REG].lower.i);			break;		}		break;	case 2:		/* cfsh64 */		printfdbg ("cfsh64\n");		if (shift < 0)			/* Negative shift is a right shift.  */			mv_setReg64int (DEST_REG,					mv_getReg64int (SRC1_REG) >> -shift);		else			/* Positive shift is a left shift.  */			mv_setReg64int (DEST_REG,					mv_getReg64int (SRC1_REG) << shift);		printfdbg ("\t%llx\n", mv_getReg64int (DEST_REG));		break;	case 3:		switch (opcode2) {		case 0:	/* cfabs32 */			DSPregs[DEST_REG].lower.i =				(DSPregs[SRC1_REG].lower.i <				 0 ? -DSPregs[SRC1_REG].lower.				 i : DSPregs[SRC1_REG].lower.i);			printfdbg ("cfabs32 mvfx%d = |mvfx%d| = %d\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   DSPregs[DEST_REG].lower.i);			break;		case 1:	/* cfabs64 */			mv_setReg64int (DEST_REG,					(mv_getReg64int (SRC1_REG) < 0					 ? -mv_getReg64int (SRC1_REG)					 : mv_getReg64int (SRC1_REG)));			printfdbg ("cfabs64 mvdx%d = |mvdx%d| = %lld\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   mv_getReg64int (DEST_REG));			break;		case 2:	/* cfneg32 */			DSPregs[DEST_REG].lower.i =				-DSPregs[SRC1_REG].lower.i;			printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   DSPregs[DEST_REG].lower.i);			break;		case 3:	/* cfneg64 */			mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG));			printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   mv_getReg64int (DEST_REG));			break;		case 4:	/* cfadd32 */			DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i				+ DSPregs[SRC2_REG].lower.i;			printfdbg ("cfadd32 mvfx%d = mvfx%d + mvfx%d = %d\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   DSPregs[DEST_REG].lower.i);			break;		case 5:	/* cfadd64 */			mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG)					+ mv_getReg64int (SRC2_REG));			printfdbg				("cfadd64 mvdx%d = mvdx%d + mvdx%d = %lld\n",				 DEST_REG, SRC1_REG, SRC2_REG,				 mv_getReg64int (DEST_REG));			break;		case 6:	/* cfsub32 */			DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i				- DSPregs[SRC2_REG].lower.i;			printfdbg ("cfsub32 mvfx%d = mvfx%d - mvfx%d = %d\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   DSPregs[DEST_REG].lower.i);			break;		case 7:	/* cfsub64 */			mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG)					- mv_getReg64int (SRC2_REG));			printfdbg ("cfsub64 mvdx%d = mvdx%d - mvdx%d = %d\n",				   DEST_REG, SRC1_REG, SRC2_REG,				   mv_getReg64int (DEST_REG));			break;		}		break;	default:		fprintf (stderr, "unknown opcode in DSPCDP5 0x%x\n", instr);		cirrus_not_implemented ("unknown");		break;	}	return ARMul_DONE;}unsignedDSPCDP6 (ARMul_State * state, unsigned type, ARMword instr){	int opcode2;	opcode2 = BITS (5, 7);	switch (BITS (20, 21)) {	case 0:		/* cfmadd32 */		cirrus_not_implemented ("cfmadd32");		break;	case 1:		/* cfmsub32 */		cirrus_not_implemented ("cfmsub32");		break;	case 2:		/* cfmadda32 */		cirrus_not_implemented ("cfmadda32");		break;	case 3:		/* cfmsuba32 */		cirrus_not_implemented ("cfmsuba32");		break;	default:		fprintf (stderr, "unknown opcode in DSPCDP6 0x%x\n", instr);	}	return ARMul_DONE;}/* Conversion functions.   32-bit integers are stored in the LOWER half of a 64-bit physical   register.   Single precision floats are stored in the UPPER half of a 64-bit   physical register.  */static doublemv_getRegDouble (int regnum){	reg_conv.ints[lsw_float_index] = DSPregs[regnum].upper.i;	reg_conv.ints[msw_float_index] = DSPregs[regnum].lower.i;	return reg_conv.d;}static voidmv_setRegDouble (int regnum, double val){	reg_conv.d = val;	DSPregs[regnum].upper.i = reg_conv.ints[lsw_float_index];	DSPregs[regnum].lower.i = reg_conv.ints[msw_float_index];}static long longmv_getReg64int (int regnum){	reg_conv.ints[lsw_int_index] = DSPregs[regnum].lower.i;	reg_conv.ints[msw_int_index] = DSPregs[regnum].upper.i;	return reg_conv.ll;}static voidmv_setReg64int (int regnum, long long val){	reg_conv.ll = val;	DSPregs[regnum].lower.i = reg_conv.ints[lsw_int_index];	DSPregs[regnum].upper.i = reg_conv.ints[msw_int_index];}/* Compute LSW in a double and a long long.  */voidmv_compute_host_endianness (ARMul_State * state){	static union	{		long long ll;		int ints[2];		int i;		double d;		float floats[2];		float f;	} conv;	/* Calculate where's the LSW in a 64bit int.  */	conv.ll = 45;	if (conv.ints[0] == 0) {		msw_int_index = 0;		lsw_int_index = 1;	}	else {		assert (conv.ints[1] == 0);		msw_int_index = 1;		lsw_int_index = 0;	}	/* Calculate where's the LSW in a double.  */	conv.d = 3.0;	if (conv.ints[0] == 0) {		msw_float_index = 0;		lsw_float_index = 1;	}	else {		assert (conv.ints[1] == 0);		msw_float_index = 1;		lsw_float_index = 0;	}	printfdbg ("lsw_int_index   %d\n", lsw_int_index);	printfdbg ("lsw_float_index %d\n", lsw_float_index);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -