ARM: Merge latest VFP fixes from 3dmoo team.
This commit is contained in:
		| @@ -28,230 +28,270 @@ | ||||
| #include "core/arm/skyeye_common/armdefs.h" | ||||
| #include "core/arm/skyeye_common/vfp/vfp.h" | ||||
|  | ||||
| #define DEBUG DBG | ||||
|  | ||||
| //ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */ | ||||
|  | ||||
| unsigned | ||||
| VFPInit (ARMul_State *state) | ||||
| { | ||||
| 	state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 |  | ||||
| 		VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION; | ||||
| 	state->VFP[VFP_OFFSET(VFP_FPEXC)] = 0; | ||||
| 	state->VFP[VFP_OFFSET(VFP_FPSCR)] = 0; | ||||
| 	 | ||||
| 	//persistent_state = state; | ||||
| 	/* Reset only specify VFP_FPEXC_EN = '0' */ | ||||
|     state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 | | ||||
|                                         VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION; | ||||
|     state->VFP[VFP_OFFSET(VFP_FPEXC)] = 0; | ||||
|     state->VFP[VFP_OFFSET(VFP_FPSCR)] = 0; | ||||
|  | ||||
| 	return No_exp; | ||||
|     //persistent_state = state; | ||||
|     /* Reset only specify VFP_FPEXC_EN = '0' */ | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value) | ||||
| VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value) | ||||
| { | ||||
| 	/* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ | ||||
| 	int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
| 	int OPC_1 = BITS (21, 23); | ||||
| 	int Rt = BITS (12, 15); | ||||
| 	int CRn = BITS (16, 19); | ||||
| 	int CRm = BITS (0, 3); | ||||
| 	int OPC_2 = BITS (5, 7); | ||||
| 	 | ||||
| 	/* TODO check access permission */ | ||||
| 	 | ||||
| 	/* CRn/opc1 CRm/opc2 */ | ||||
| 	 | ||||
| 	if (CoProc == 10 || CoProc == 11) | ||||
| 	{ | ||||
| 		#define VFP_MRC_TRANS | ||||
| 		#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| 		#undef VFP_MRC_TRANS | ||||
| 	} | ||||
| 	DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",  | ||||
| 	       instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); | ||||
|     /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ | ||||
|     int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
|     int OPC_1 = BITS (21, 23); | ||||
|     int Rt = BITS (12, 15); | ||||
|     int CRn = BITS (16, 19); | ||||
|     int CRm = BITS (0, 3); | ||||
|     int OPC_2 = BITS (5, 7); | ||||
|  | ||||
| 	return ARMul_CANT; | ||||
|     /* TODO check access permission */ | ||||
|  | ||||
|     /* CRn/opc1 CRm/opc2 */ | ||||
|  | ||||
|     if (CoProc == 10 || CoProc == 11) { | ||||
| #define VFP_MRC_TRANS | ||||
| #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| #undef VFP_MRC_TRANS | ||||
|     } | ||||
|     DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", | ||||
|           instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); | ||||
|  | ||||
|     return ARMul_CANT; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value) | ||||
| VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value) | ||||
| { | ||||
| 	/* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ | ||||
| 	int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
| 	int OPC_1 = BITS (21, 23); | ||||
| 	int Rt = BITS (12, 15); | ||||
| 	int CRn = BITS (16, 19); | ||||
| 	int CRm = BITS (0, 3); | ||||
| 	int OPC_2 = BITS (5, 7); | ||||
| 	 | ||||
| 	/* TODO check access permission */ | ||||
| 	 | ||||
| 	/* CRn/opc1 CRm/opc2 */ | ||||
| 	if (CoProc == 10 || CoProc == 11) | ||||
| 	{ | ||||
| 		#define VFP_MCR_TRANS | ||||
| 		#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| 		#undef VFP_MCR_TRANS | ||||
| 	} | ||||
| 	DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",  | ||||
| 	       instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); | ||||
|     /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ | ||||
|     int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
|     int OPC_1 = BITS (21, 23); | ||||
|     int Rt = BITS (12, 15); | ||||
|     int CRn = BITS (16, 19); | ||||
|     int CRm = BITS (0, 3); | ||||
|     int OPC_2 = BITS (5, 7); | ||||
|  | ||||
| 	return ARMul_CANT; | ||||
|     /* TODO check access permission */ | ||||
|  | ||||
|     /* CRn/opc1 CRm/opc2 */ | ||||
|     if (CoProc == 10 || CoProc == 11) { | ||||
| #define VFP_MCR_TRANS | ||||
| #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| #undef VFP_MCR_TRANS | ||||
|     } | ||||
|     DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", | ||||
|           instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); | ||||
|  | ||||
|     return ARMul_CANT; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| VFPMRRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value1, ARMword * value2) | ||||
| VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * value2) | ||||
| { | ||||
| 	/* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ | ||||
| 	int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
| 	int OPC_1 = BITS (4, 7); | ||||
| 	int Rt = BITS (12, 15); | ||||
| 	int Rt2 = BITS (16, 19); | ||||
| 	int CRm = BITS (0, 3); | ||||
| 	 | ||||
| 	if (CoProc == 10 || CoProc == 11) | ||||
| 	{ | ||||
| 		#define VFP_MRRC_TRANS | ||||
| 		#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| 		#undef VFP_MRRC_TRANS | ||||
| 	} | ||||
| 	DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",  | ||||
| 	       instr, CoProc, OPC_1, Rt, Rt2, CRm); | ||||
|     /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ | ||||
|     int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
|     int OPC_1 = BITS (4, 7); | ||||
|     int Rt = BITS (12, 15); | ||||
|     int Rt2 = BITS (16, 19); | ||||
|     int CRm = BITS (0, 3); | ||||
|  | ||||
| 	return ARMul_CANT; | ||||
|     if (CoProc == 10 || CoProc == 11) { | ||||
| #define VFP_MRRC_TRANS | ||||
| #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| #undef VFP_MRRC_TRANS | ||||
|     } | ||||
|     DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", | ||||
|           instr, CoProc, OPC_1, Rt, Rt2, CRm); | ||||
|  | ||||
|     return ARMul_CANT; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| VFPMCRR (ARMul_State * state, unsigned type, ARMword instr, ARMword value1, ARMword value2) | ||||
| VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2) | ||||
| { | ||||
| 	/* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ | ||||
| 	int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
| 	int OPC_1 = BITS (4, 7); | ||||
| 	int Rt = BITS (12, 15); | ||||
| 	int Rt2 = BITS (16, 19); | ||||
| 	int CRm = BITS (0, 3); | ||||
| 	 | ||||
| 	/* TODO check access permission */ | ||||
| 	 | ||||
| 	/* CRn/opc1 CRm/opc2 */ | ||||
| 	 | ||||
| 	if (CoProc == 11 || CoProc == 10) | ||||
| 	{ | ||||
| 		#define VFP_MCRR_TRANS | ||||
| 		#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| 		#undef VFP_MCRR_TRANS | ||||
| 	} | ||||
| 	DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",  | ||||
| 	       instr, CoProc, OPC_1, Rt, Rt2, CRm); | ||||
|     /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ | ||||
|     int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
|     int OPC_1 = BITS (4, 7); | ||||
|     int Rt = BITS (12, 15); | ||||
|     int Rt2 = BITS (16, 19); | ||||
|     int CRm = BITS (0, 3); | ||||
|  | ||||
| 	return ARMul_CANT; | ||||
|     /* TODO check access permission */ | ||||
|  | ||||
|     /* CRn/opc1 CRm/opc2 */ | ||||
|  | ||||
|     if (CoProc == 11 || CoProc == 10) { | ||||
| #define VFP_MCRR_TRANS | ||||
| #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| #undef VFP_MCRR_TRANS | ||||
|     } | ||||
|     DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", | ||||
|           instr, CoProc, OPC_1, Rt, Rt2, CRm); | ||||
|  | ||||
|     return ARMul_CANT; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| VFPSTC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value) | ||||
| VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value) | ||||
| { | ||||
| 	/* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */ | ||||
| 	int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
| 	int CRd = BITS (12, 15); | ||||
| 	int Rn = BITS (16, 19); | ||||
| 	int imm8 = BITS (0, 7); | ||||
| 	int P = BIT(24); | ||||
| 	int U = BIT(23); | ||||
| 	int D = BIT(22); | ||||
| 	int W = BIT(21); | ||||
| 	 | ||||
| 	/* TODO check access permission */ | ||||
| 	 | ||||
| 	/* VSTM */ | ||||
| 	if ( (P|U|D|W) == 0 ) | ||||
| 	{ | ||||
| 		DEBUG_LOG(ARM11, "In %s, UNDEFINED\n", __FUNCTION__); exit(-1); | ||||
| 	} | ||||
| 	if (CoProc == 10 || CoProc == 11) | ||||
| 	{ | ||||
| 		#if 1 | ||||
| 		if (P == 0 && U == 0 && W == 0) | ||||
| 		{ | ||||
| 			DEBUG_LOG(ARM11, "VSTM Related encodings\n"); exit(-1); | ||||
| 		} | ||||
| 		if (P == U && W == 1) | ||||
| 		{ | ||||
| 			DEBUG_LOG(ARM11, "UNDEFINED\n"); exit(-1); | ||||
| 		} | ||||
| 		#endif | ||||
|     /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */ | ||||
|     int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
|     int CRd = BITS (12, 15); | ||||
|     int Rn = BITS (16, 19); | ||||
|     int imm8 = BITS (0, 7); | ||||
|     int P = BIT(24); | ||||
|     int U = BIT(23); | ||||
|     int D = BIT(22); | ||||
|     int W = BIT(21); | ||||
|  | ||||
| 		#define VFP_STC_TRANS | ||||
| 		#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| 		#undef VFP_STC_TRANS | ||||
| 	} | ||||
| 	DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",  | ||||
| 	       instr, CoProc, CRd, Rn, imm8, P, U, D, W); | ||||
|     /* TODO check access permission */ | ||||
|  | ||||
| 	return ARMul_CANT; | ||||
|     /* VSTM */ | ||||
|     if ( (P|U|D|W) == 0 ) { | ||||
|         DEBUG("In %s, UNDEFINED\n", __FUNCTION__); | ||||
|         exit(-1); | ||||
|     } | ||||
|     if (CoProc == 10 || CoProc == 11) { | ||||
| #if 1 | ||||
|         if (P == 0 && U == 0 && W == 0) { | ||||
|             DEBUG("VSTM Related encodings\n"); | ||||
|             exit(-1); | ||||
|         } | ||||
|         if (P == U && W == 1) { | ||||
|             DEBUG("UNDEFINED\n"); | ||||
|             exit(-1); | ||||
|         } | ||||
| #endif | ||||
|  | ||||
| #define VFP_STC_TRANS | ||||
| #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| #undef VFP_STC_TRANS | ||||
|     } | ||||
|     DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", | ||||
|           instr, CoProc, CRd, Rn, imm8, P, U, D, W); | ||||
|  | ||||
|     return ARMul_CANT; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| VFPLDC (ARMul_State * state, unsigned type, ARMword instr, ARMword value) | ||||
| VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value) | ||||
| { | ||||
| 	/* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */ | ||||
| 	int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
| 	int CRd = BITS (12, 15); | ||||
| 	int Rn = BITS (16, 19); | ||||
| 	int imm8 = BITS (0, 7); | ||||
| 	int P = BIT(24); | ||||
| 	int U = BIT(23); | ||||
| 	int D = BIT(22); | ||||
| 	int W = BIT(21); | ||||
| 	 | ||||
| 	/* TODO check access permission */ | ||||
| 	 | ||||
| 	if ( (P|U|D|W) == 0 ) | ||||
| 	{ | ||||
| 		DEBUG_LOG(ARM11, "In %s, UNDEFINED\n", __FUNCTION__); exit(-1); | ||||
| 	} | ||||
| 	if (CoProc == 10 || CoProc == 11) | ||||
| 	{ | ||||
| 		#define VFP_LDC_TRANS | ||||
| 		#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| 		#undef VFP_LDC_TRANS | ||||
| 	} | ||||
| 	DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",  | ||||
| 	       instr, CoProc, CRd, Rn, imm8, P, U, D, W); | ||||
|     /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */ | ||||
|     int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
|     int CRd = BITS (12, 15); | ||||
|     int Rn = BITS (16, 19); | ||||
|     int imm8 = BITS (0, 7); | ||||
|     int P = BIT(24); | ||||
|     int U = BIT(23); | ||||
|     int D = BIT(22); | ||||
|     int W = BIT(21); | ||||
|  | ||||
| 	return ARMul_CANT; | ||||
|     /* TODO check access permission */ | ||||
|  | ||||
|     if ( (P|U|D|W) == 0 ) { | ||||
|         DEBUG("In %s, UNDEFINED\n", __FUNCTION__); | ||||
|         exit(-1); | ||||
|     } | ||||
|     if (CoProc == 10 || CoProc == 11) { | ||||
| #define VFP_LDC_TRANS | ||||
| #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| #undef VFP_LDC_TRANS | ||||
|     } | ||||
|     DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", | ||||
|           instr, CoProc, CRd, Rn, imm8, P, U, D, W); | ||||
|  | ||||
|     return ARMul_CANT; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| VFPCDP (ARMul_State * state, unsigned type, ARMword instr) | ||||
| VFPCDP (ARMul_State * state, unsigned type, u32 instr) | ||||
| { | ||||
| 	/* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */ | ||||
| 	int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
| 	int OPC_1 = BITS (20, 23); | ||||
| 	int CRd = BITS (12, 15); | ||||
| 	int CRn = BITS (16, 19); | ||||
| 	int CRm = BITS (0, 3); | ||||
| 	int OPC_2 = BITS (5, 7); | ||||
| 	 | ||||
| 	/* TODO check access permission */ | ||||
| 	 | ||||
| 	/* CRn/opc1 CRm/opc2 */ | ||||
|     /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */ | ||||
|     int CoProc = BITS (8, 11); /* 10 or 11 */ | ||||
|     int OPC_1 = BITS (20, 23); | ||||
|     int CRd = BITS (12, 15); | ||||
|     int CRn = BITS (16, 19); | ||||
|     int CRm = BITS (0, 3); | ||||
|     int OPC_2 = BITS (5, 7); | ||||
|  | ||||
| 	if (CoProc == 10 || CoProc == 11) | ||||
| 	{ | ||||
| 		#define VFP_CDP_TRANS | ||||
| 		#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| 		#undef VFP_CDP_TRANS | ||||
| 		 | ||||
| 		int exceptions = 0; | ||||
| 		if (CoProc == 10) | ||||
| 			exceptions = vfp_single_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); | ||||
| 		else  | ||||
| 			exceptions = vfp_double_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); | ||||
|     //ichfly | ||||
|     /*if ((instr & 0x0FBF0FD0) == 0x0EB70AC0) //vcvt.f64.f32	d8, s16 (s is bit 0-3 and LSB bit 22) (d is bit 12 - 15 MSB is Bit 6) | ||||
|     { | ||||
|         struct vfp_double vdd; | ||||
|         struct vfp_single vsd; | ||||
|         int dn = BITS(12, 15) + (BIT(22) << 4); | ||||
|         int sd = (BITS(0, 3) << 1) + BIT(5); | ||||
|         s32 n = vfp_get_float(state, sd); | ||||
|         vfp_single_unpack(&vsd, n); | ||||
|         if (vsd.exponent & 0x80) | ||||
|         { | ||||
|             vdd.exponent = (vsd.exponent&~0x80) | 0x400; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             vdd.exponent = vsd.exponent | 0x380; | ||||
|         } | ||||
|         vdd.sign = vsd.sign; | ||||
|         vdd.significand = (u64)(vsd.significand & ~0xC0000000) << 32; // I have no idea why but the 2 uppern bits are not from the significand | ||||
|         vfp_put_double(state, vfp_double_pack(&vdd), dn); | ||||
|         return ARMul_DONE; | ||||
|     } | ||||
|     if ((instr & 0x0FBF0FD0) == 0x0EB70BC0) //vcvt.f32.f64	s15, d6 | ||||
|     { | ||||
|         struct vfp_double vdd; | ||||
|         struct vfp_single vsd; | ||||
|         int sd = BITS(0, 3) + (BIT(5) << 4); | ||||
|         int dn = (BITS(12, 15) << 1) + BIT(22); | ||||
|         vfp_double_unpack(&vdd, vfp_get_double(state, sd)); | ||||
|         if (vdd.exponent & 0x400) //todo if the exponent is to low or to high for this convert | ||||
|         { | ||||
|             vsd.exponent = (vdd.exponent) | 0x80; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             vsd.exponent = vdd.exponent & ~0x80; | ||||
|         } | ||||
|         vsd.exponent &= 0xFF; | ||||
|        // vsd.exponent = vdd.exponent >> 3; | ||||
|         vsd.sign = vdd.sign; | ||||
|         vsd.significand = ((u64)(vdd.significand ) >> 32)& ~0xC0000000; | ||||
|         vfp_put_float(state, vfp_single_pack(&vsd), dn); | ||||
|         return ARMul_DONE; | ||||
|     }*/ | ||||
|  | ||||
| 		vfp_raise_exceptions(state, exceptions, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); | ||||
|     /* TODO check access permission */ | ||||
|  | ||||
| 		return ARMul_DONE; | ||||
| 	} | ||||
| 	DEBUG_LOG(ARM11, "Can't identify %x\n", instr); | ||||
| 	return ARMul_CANT; | ||||
|     /* CRn/opc1 CRm/opc2 */ | ||||
|  | ||||
|     if (CoProc == 10 || CoProc == 11) { | ||||
| #define VFP_CDP_TRANS | ||||
| #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" | ||||
| #undef VFP_CDP_TRANS | ||||
|  | ||||
|         int exceptions = 0; | ||||
|         if (CoProc == 10) | ||||
|             exceptions = vfp_single_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); | ||||
|         else | ||||
|             exceptions = vfp_double_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); | ||||
|  | ||||
|         vfp_raise_exceptions(state, exceptions, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); | ||||
|  | ||||
|         return ARMul_DONE; | ||||
|     } | ||||
|     DEBUG("Can't identify %x\n", instr); | ||||
|     return ARMul_CANT; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -301,29 +341,29 @@ VFPCDP (ARMul_State * state, unsigned type, ARMword instr) | ||||
| /* Miscellaneous functions */ | ||||
| int32_t vfp_get_float(arm_core_t* state, unsigned int reg) | ||||
| { | ||||
| 	DBG("VFP get float: s%d=[%08x]\n", reg, state->ExtReg[reg]); | ||||
| 	return state->ExtReg[reg]; | ||||
|     DEBUG("VFP get float: s%d=[%08x]\n", reg, state->ExtReg[reg]); | ||||
|     return state->ExtReg[reg]; | ||||
| } | ||||
|  | ||||
| void vfp_put_float(arm_core_t* state, int32_t val, unsigned int reg) | ||||
| { | ||||
| 	DBG("VFP put float: s%d <= [%08x]\n", reg, val); | ||||
| 	state->ExtReg[reg] = val; | ||||
|     DEBUG("VFP put float: s%d <= [%08x]\n", reg, val); | ||||
|     state->ExtReg[reg] = val; | ||||
| } | ||||
|  | ||||
| uint64_t vfp_get_double(arm_core_t* state, unsigned int reg) | ||||
| { | ||||
| 	uint64_t result; | ||||
| 	result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2]; | ||||
| 	DBG("VFP get double: s[%d-%d]=[%016llx]\n", reg*2+1, reg*2, result); | ||||
| 	return result; | ||||
|     uint64_t result; | ||||
|     result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2]; | ||||
|     DEBUG("VFP get double: s[%d-%d]=[%016llx]\n", reg*2+1, reg*2, result); | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg) | ||||
| { | ||||
| 	DBG("VFP put double: s[%d-%d] <= [%08x-%08x]\n", reg*2+1, reg*2, (uint32_t) (val>>32), (uint32_t) (val & 0xffffffff)); | ||||
| 	state->ExtReg[reg*2] = (uint32_t) (val & 0xffffffff); | ||||
| 	state->ExtReg[reg*2+1] = (uint32_t) (val>>32); | ||||
|     DEBUG("VFP put double: s[%d-%d] <= [%08x-%08x]\n", reg*2+1, reg*2, (uint32_t) (val>>32), (uint32_t) (val & 0xffffffff)); | ||||
|     state->ExtReg[reg*2] = (uint32_t) (val & 0xffffffff); | ||||
|     state->ExtReg[reg*2+1] = (uint32_t) (val>>32); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -333,25 +373,25 @@ void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg) | ||||
|  */ | ||||
| void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpscr) | ||||
| { | ||||
| 	int si_code = 0; | ||||
|     int si_code = 0; | ||||
|  | ||||
| 	vfpdebug("VFP: raising exceptions %08x\n", exceptions); | ||||
|     vfpdebug("VFP: raising exceptions %08x\n", exceptions); | ||||
|  | ||||
| 	if (exceptions == VFP_EXCEPTION_ERROR) { | ||||
| 		DEBUG_LOG(ARM11, "unhandled bounce %x\n", inst); | ||||
| 		exit(-1); | ||||
| 		return; | ||||
| 	} | ||||
|     if (exceptions == VFP_EXCEPTION_ERROR) { | ||||
|         DEBUG("unhandled bounce %x\n", inst); | ||||
|         exit(-1); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
| 	/* | ||||
| 	 * If any of the status flags are set, update the FPSCR. | ||||
| 	 * Comparison instructions always return at least one of | ||||
| 	 * these flags set. | ||||
| 	 */ | ||||
| 	if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) | ||||
| 		fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V); | ||||
|     /* | ||||
|      * If any of the status flags are set, update the FPSCR. | ||||
|      * Comparison instructions always return at least one of | ||||
|      * these flags set. | ||||
|      */ | ||||
|     if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) | ||||
|         fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V); | ||||
|  | ||||
| 	fpscr |= exceptions; | ||||
|     fpscr |= exceptions; | ||||
|  | ||||
| 	state->VFP[VFP_OFFSET(VFP_FPSCR)] = fpscr; | ||||
|     state->VFP[VFP_OFFSET(VFP_FPSCR)] = fpscr; | ||||
| } | ||||
|   | ||||
| @@ -44,7 +44,7 @@ | ||||
| #define pr_info //printf | ||||
| #define pr_debug //printf | ||||
|  | ||||
| static u32 vfp_fls(int x); | ||||
| static u32 fls(int x); | ||||
| #define do_div(n, base) {n/=base;} | ||||
|  | ||||
| /* From vfpinstr.h */ | ||||
| @@ -502,7 +502,7 @@ struct op { | ||||
| 	u32 flags; | ||||
| }; | ||||
|  | ||||
| static u32 vfp_fls(int x) | ||||
| static u32 fls(int x) | ||||
| { | ||||
| 	int r = 32; | ||||
|  | ||||
| @@ -532,4 +532,9 @@ static u32 vfp_fls(int x) | ||||
|  | ||||
| } | ||||
|  | ||||
| u32 vfp_double_normaliseroundintern(ARMul_State* state, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func); | ||||
| u32 vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *vdm, u32 fpscr); | ||||
| u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *vdm, u32 fpscr); | ||||
| u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, struct vfp_double* dm, u32 fpscr); | ||||
|  | ||||
| #endif | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user