mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Merge pull request #359 from lioncash/vfp
vfp: Actually make the code somewhat readable
This commit is contained in:
		
						commit
						9a403d7dfb
					
				@ -28,9 +28,40 @@
 | 
				
			|||||||
#include "core/arm/dyncom/arm_dyncom_dec.h"
 | 
					#include "core/arm/dyncom/arm_dyncom_dec.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ISEITEM arm_instruction[] = {
 | 
					const ISEITEM arm_instruction[] = {
 | 
				
			||||||
	#define VFP_DECODE
 | 
						{"vmla",        4,      ARMVFP2,        23, 27, 0x1C,  20, 21, 0x0,    9, 11, 0x5,     4, 4, 0},
 | 
				
			||||||
	#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
						{"vmls",        7,      ARMVFP2,        28, 31, 0xF,   25, 27, 0x1,   23, 23, 1,  11, 11, 0,  8, 9, 0x2,  6, 6, 1,  4, 4, 0},
 | 
				
			||||||
	#undef VFP_DECODE
 | 
						{"vnmla",       4,      ARMVFP2,        23, 27, 0x1C,  20, 21, 0x1,    9, 11, 0x5,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vnmla",       5,      ARMVFP2,        23, 27, 0x1C,  20, 21, 0x2,    9, 11, 0x5,     6, 6, 1,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vnmls",       5,      ARMVFP2,        23, 27, 0x1C,  20, 21, 0x1,    9, 11, 0x5,     6, 6, 0,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vnmul",       5,      ARMVFP2,        23, 27, 0x1C,  20, 21, 0x2,    9, 11, 0x5,     6, 6, 1,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vmul",        5,      ARMVFP2,        23, 27, 0x1C,  20, 21, 0x2,    9, 11, 0x5,     6, 6, 0,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vadd",        5,      ARMVFP2,        23, 27, 0x1C,  20, 21, 0x3,    9, 11, 0x5,     6, 6, 0,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vsub",        5,      ARMVFP2,        23, 27, 0x1C,  20, 21, 0x3,    9, 11, 0x5,     6, 6, 1,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vdiv",        5,      ARMVFP2,        23, 27, 0x1D,  20, 21, 0x0,    9, 11, 0x5,     6, 6, 0,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vmov(i)",     4,      ARMVFP3,        23, 27, 0x1D,  20, 21, 0x3,    9, 11, 0x5,     4, 7, 0},
 | 
				
			||||||
 | 
						{"vmov(r)",     5,      ARMVFP3,        23, 27, 0x1D,  16, 21, 0x30,   9, 11, 0x5,     6, 7, 1,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vabs",        5,      ARMVFP2,        23, 27, 0x1D,  16, 21, 0x30,   9, 11, 0x5,     6, 7, 3,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vneg",        5,      ARMVFP2,        23, 27, 0x1D,  17, 21, 0x18,   9, 11, 0x5,     6, 7, 1,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vsqrt",       5,      ARMVFP2,        23, 27, 0x1D,  16, 21, 0x31,   9, 11, 0x5,     6, 7, 3,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vcmp",        5,      ARMVFP2,        23, 27, 0x1D,  16, 21, 0x34,   9, 11, 0x5,     6, 6, 1,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vcmp2",       5,      ARMVFP2,        23, 27, 0x1D,  16, 21, 0x35,   9, 11, 0x5,     0, 6, 0x40},
 | 
				
			||||||
 | 
						{"vcvt(bds)",   5,      ARMVFP2,        23, 27, 0x1D,  16, 21, 0x37,   9, 11, 0x5,     6, 7, 3,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vcvt(bff)",   6,      ARMVFP3,        23, 27, 0x1D,  19, 21, 0x7,    17, 17, 0x1,    9, 11,5,     6, 6, 1},
 | 
				
			||||||
 | 
						{"vcvt(bfi)",   5,      ARMVFP2,        23, 27, 0x1D,  19, 21, 0x7,    9, 11, 0x5,     6, 6, 1,     4, 4, 0},
 | 
				
			||||||
 | 
						{"vmovbrs",     3,      ARMVFP2,        21, 27, 0x70,   8, 11, 0xA,    0, 6, 0x10},
 | 
				
			||||||
 | 
						{"vmsr",        2,      ARMVFP2,        20, 27, 0xEE,   0, 11, 0xA10},
 | 
				
			||||||
 | 
						{"vmovbrc",     4,      ARMVFP2,        23, 27, 0x1C,   20, 20, 0x0,   8, 11, 0xB,     0,4,0x10},
 | 
				
			||||||
 | 
						{"vmrs",        2,      ARMVFP2,        20, 27, 0xEF,   0, 11, 0xA10},
 | 
				
			||||||
 | 
						{"vmovbcr",     4,      ARMVFP2,        24, 27, 0xE,    20, 20, 1,     8, 11, 0xB,     0,4,0x10},
 | 
				
			||||||
 | 
						{"vmovbrrss",   3,      ARMVFP2,        21, 27, 0x62,   8, 11, 0xA,    4, 4, 1},
 | 
				
			||||||
 | 
						{"vmovbrrd",    3,      ARMVFP2,        21, 27, 0x62,   6, 11, 0x2C,   4, 4, 1},
 | 
				
			||||||
 | 
						{"vstr",        3,      ARMVFP2,        24, 27, 0xD,    20, 21, 0,     9, 11,5},
 | 
				
			||||||
 | 
						{"vpush",       3,      ARMVFP2,        23, 27, 0x1A,   16, 21, 0x2D,  9, 11,5},
 | 
				
			||||||
 | 
						{"vstm",        3,      ARMVFP2,        25, 27, 0x6,    20, 20, 0,     9, 11,5},
 | 
				
			||||||
 | 
						{"vpop",        3,      ARMVFP2,        23, 27, 0x19,   16, 21, 0x3D,  9, 11,5},
 | 
				
			||||||
 | 
						{"vldr",        3,      ARMVFP2,        24, 27, 0xD,    20, 21, 1,     9, 11,5},
 | 
				
			||||||
 | 
						{"vldm",        3,      ARMVFP2,        25, 27, 0x6,    20, 20, 1,     9, 11,5},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{"srs"	,  4	,  6	, 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d,  8, 11, 0x00000005},
 | 
						{"srs"	,  4	,  6	, 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d,  8, 11, 0x00000005},
 | 
				
			||||||
	{"rfe"	,  4	,  6	, 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001,  8, 11, 0x0000000a},
 | 
						{"rfe"	,  4	,  6	, 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001,  8, 11, 0x0000000a},
 | 
				
			||||||
	{"bkpt"	,  2	,  3	, 20, 31, 0x00000e12,  4,  7, 0x00000007},
 | 
						{"bkpt"	,  2	,  3	, 20, 31, 0x00000e12,  4,  7, 0x00000007},
 | 
				
			||||||
@ -187,9 +218,40 @@ const ISEITEM arm_instruction[] = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ISEITEM arm_exclusion_code[] = {
 | 
					const ISEITEM arm_exclusion_code[] = {
 | 
				
			||||||
	#define VFP_DECODE_EXCLUSION
 | 
						{"vmla",        0,      ARMVFP2, 0},
 | 
				
			||||||
	#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
						{"vmls",        0,      ARMVFP2, 0},
 | 
				
			||||||
	#undef VFP_DECODE_EXCLUSION
 | 
						{"vnmla",       0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vnmla",       0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vnmls",       0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vnmul",       0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vmul",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vadd",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vsub",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vdiv",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vmov(i)",     0,      ARMVFP3, 0},
 | 
				
			||||||
 | 
						{"vmov(r)",     0,      ARMVFP3, 0},
 | 
				
			||||||
 | 
						{"vabs",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vneg",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vsqrt",       0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vcmp",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vcmp2",       0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vcvt(bff)",   0,      ARMVFP3,         4, 4, 1},
 | 
				
			||||||
 | 
						{"vcvt(bds)",   0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vcvt(bfi)",   0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vmovbrs",     0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vmsr",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vmovbrc",     0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vmrs",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vmovbcr",     0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vmovbrrss",   0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vmovbrrd",    0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vstr",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vpush",       0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vstm",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vpop",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vldr",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
						{"vldm",        0,      ARMVFP2, 0},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{"srs"	,  0	,  6	,  0},
 | 
						{"srs"	,  0	,  6	,  0},
 | 
				
			||||||
	{"rfe"	,  0	,  6	,  0},
 | 
						{"rfe"	,  0	,  6	,  0},
 | 
				
			||||||
	{"bkpt"	,  0	,  3	,  0},
 | 
						{"bkpt"	,  0	,  3	,  0},
 | 
				
			||||||
 | 
				
			|||||||
@ -3363,9 +3363,40 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index)    { UN
 | 
				
			|||||||
typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
 | 
					typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const transop_fp_t arm_instruction_trans[] = {
 | 
					const transop_fp_t arm_instruction_trans[] = {
 | 
				
			||||||
	#define VFP_INTERPRETER_TABLE
 | 
						INTERPRETER_TRANSLATE(vmla),
 | 
				
			||||||
	#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
						INTERPRETER_TRANSLATE(vmls),
 | 
				
			||||||
	#undef VFP_INTERPRETER_TABLE
 | 
						INTERPRETER_TRANSLATE(vnmla),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vnmla),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vnmls),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vnmul),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmul),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vadd),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vsub),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vdiv),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmovi),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmovr),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vabs),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vneg),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vsqrt),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vcmp),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vcmp2),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vcvtbds),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vcvtbff),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vcvtbfi),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmovbrs),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmsr),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmovbrc),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmrs),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmovbcr),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmovbrrss),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vmovbrrd),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vstr),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vpush),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vstm),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vpop),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vldr),
 | 
				
			||||||
 | 
						INTERPRETER_TRANSLATE(vldm),
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	INTERPRETER_TRANSLATE(srs),
 | 
						INTERPRETER_TRANSLATE(srs),
 | 
				
			||||||
	INTERPRETER_TRANSLATE(rfe),
 | 
						INTERPRETER_TRANSLATE(rfe),
 | 
				
			||||||
	INTERPRETER_TRANSLATE(bkpt),
 | 
						INTERPRETER_TRANSLATE(bkpt),
 | 
				
			||||||
@ -4206,10 +4237,12 @@ unsigned InterpreterMainLoop(ARMul_State* state)
 | 
				
			|||||||
    // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
 | 
					    // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
 | 
				
			||||||
    // to a clunky switch statement.
 | 
					    // to a clunky switch statement.
 | 
				
			||||||
#if defined __GNUC__ || defined __clang__
 | 
					#if defined __GNUC__ || defined __clang__
 | 
				
			||||||
    void *InstLabel[] = {
 | 
						void *InstLabel[] = {
 | 
				
			||||||
		#define VFP_INTERPRETER_LABEL
 | 
							&&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST,
 | 
				
			||||||
		#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
							&&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST,
 | 
				
			||||||
		#undef VFP_INTERPRETER_LABEL
 | 
							&&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST,
 | 
				
			||||||
 | 
							&&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		&&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
 | 
							&&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
 | 
				
			||||||
		&&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
 | 
							&&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
 | 
				
			||||||
		&&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
 | 
							&&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
 | 
				
			||||||
@ -4243,7 +4276,7 @@ unsigned InterpreterMainLoop(ARMul_State* state)
 | 
				
			|||||||
	DISPATCH:
 | 
						DISPATCH:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (!cpu->NirqSig) {
 | 
							if (!cpu->NirqSig) {
 | 
				
			||||||
                	if (!(cpu->Cpsr & 0x80)) {
 | 
								if (!(cpu->Cpsr & 0x80)) {
 | 
				
			||||||
				goto END;
 | 
									goto END;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -32,8 +32,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */
 | 
					//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned
 | 
					unsigned VFPInit(ARMul_State* state)
 | 
				
			||||||
VFPInit (ARMul_State *state)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 |
 | 
					    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;
 | 
					                                        VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION;
 | 
				
			||||||
@ -46,8 +45,7 @@ VFPInit (ARMul_State *state)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned
 | 
					unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
 | 
				
			||||||
VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
 | 
					    /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
 | 
				
			||||||
    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
					    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
				
			||||||
@ -61,10 +59,21 @@ VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* CRn/opc1 CRm/opc2 */
 | 
					    /* CRn/opc1 CRm/opc2 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (CoProc == 10 || CoProc == 11) {
 | 
					    if (CoProc == 10 || CoProc == 11)
 | 
				
			||||||
#define VFP_MRC_TRANS
 | 
					    {
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					        if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
 | 
				
			||||||
#undef VFP_MRC_TRANS
 | 
					        {
 | 
				
			||||||
 | 
					            /* VMOV r to s */
 | 
				
			||||||
 | 
					            /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
 | 
				
			||||||
 | 
					            VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            VMRS(state, CRn, Rt, value);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
 | 
					    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);
 | 
					          instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
 | 
				
			||||||
@ -72,8 +81,7 @@ VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
 | 
				
			|||||||
    return ARMul_CANT;
 | 
					    return ARMul_CANT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned
 | 
					unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
 | 
				
			||||||
VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
 | 
					    /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
 | 
				
			||||||
    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
					    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
				
			||||||
@ -86,10 +94,33 @@ VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
 | 
				
			|||||||
    /* TODO check access permission */
 | 
					    /* TODO check access permission */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* CRn/opc1 CRm/opc2 */
 | 
					    /* CRn/opc1 CRm/opc2 */
 | 
				
			||||||
    if (CoProc == 10 || CoProc == 11) {
 | 
					    if (CoProc == 10 || CoProc == 11)
 | 
				
			||||||
#define VFP_MCR_TRANS
 | 
					    {
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					        if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
 | 
				
			||||||
#undef VFP_MCR_TRANS
 | 
					        {
 | 
				
			||||||
 | 
					            /* VMOV s to r */
 | 
				
			||||||
 | 
					            /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
 | 
				
			||||||
 | 
					            VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            VMSR(state, CRn, Rt);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0x4) == 0 && CoProc == 11 && CRm == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (CoProc == 11 && CRm == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
 | 
					    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);
 | 
					          instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
 | 
				
			||||||
@ -97,8 +128,7 @@ VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
 | 
				
			|||||||
    return ARMul_CANT;
 | 
					    return ARMul_CANT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned
 | 
					unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* value2)
 | 
				
			||||||
VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * value2)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
 | 
					    /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
 | 
				
			||||||
    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
					    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
				
			||||||
@ -107,10 +137,20 @@ VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * valu
 | 
				
			|||||||
    int Rt2 = BITS (16, 19);
 | 
					    int Rt2 = BITS (16, 19);
 | 
				
			||||||
    int CRm = BITS (0, 3);
 | 
					    int CRm = BITS (0, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (CoProc == 10 || CoProc == 11) {
 | 
					    if (CoProc == 10 || CoProc == 11)
 | 
				
			||||||
#define VFP_MRRC_TRANS
 | 
					    {
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					        if (CoProc == 10 && (OPC_1 & 0xD) == 1)
 | 
				
			||||||
#undef VFP_MRRC_TRANS
 | 
					        {
 | 
				
			||||||
 | 
					            VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (CoProc == 11 && (OPC_1 & 0xD) == 1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
 | 
				
			||||||
 | 
					            VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
 | 
					    DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
 | 
				
			||||||
          instr, CoProc, OPC_1, Rt, Rt2, CRm);
 | 
					          instr, CoProc, OPC_1, Rt, Rt2, CRm);
 | 
				
			||||||
@ -118,8 +158,7 @@ VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * valu
 | 
				
			|||||||
    return ARMul_CANT;
 | 
					    return ARMul_CANT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned
 | 
					unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 value2)
 | 
				
			||||||
VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
 | 
					    /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
 | 
				
			||||||
    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
					    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
				
			||||||
@ -132,10 +171,20 @@ VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* CRn/opc1 CRm/opc2 */
 | 
					    /* CRn/opc1 CRm/opc2 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (CoProc == 11 || CoProc == 10) {
 | 
					    if (CoProc == 11 || CoProc == 10)
 | 
				
			||||||
#define VFP_MCRR_TRANS
 | 
					    {
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					        if (CoProc == 10 && (OPC_1 & 0xD) == 1)
 | 
				
			||||||
#undef VFP_MCRR_TRANS
 | 
					        {
 | 
				
			||||||
 | 
					            VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (CoProc == 11 && (OPC_1 & 0xD) == 1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
 | 
				
			||||||
 | 
					            VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
 | 
					    DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
 | 
				
			||||||
          instr, CoProc, OPC_1, Rt, Rt2, CRm);
 | 
					          instr, CoProc, OPC_1, Rt, Rt2, CRm);
 | 
				
			||||||
@ -143,8 +192,7 @@ VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
 | 
				
			|||||||
    return ARMul_CANT;
 | 
					    return ARMul_CANT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned
 | 
					unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value)
 | 
				
			||||||
VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */
 | 
					    /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */
 | 
				
			||||||
    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
					    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
				
			||||||
@ -175,9 +223,17 @@ VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VFP_STC_TRANS
 | 
					        if (P == 1 && W == 0)
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					        {
 | 
				
			||||||
#undef VFP_STC_TRANS
 | 
					            return VSTR(state, type, instr, value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (P == 1 && U == 0 && W == 1 && Rn == 0xD)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return VPUSH(state, type, instr, value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return VSTM(state, type, instr, value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
 | 
					    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);
 | 
					          instr, CoProc, CRd, Rn, imm8, P, U, D, W);
 | 
				
			||||||
@ -185,8 +241,7 @@ VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
 | 
				
			|||||||
    return ARMul_CANT;
 | 
					    return ARMul_CANT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned
 | 
					unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value)
 | 
				
			||||||
VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */
 | 
					    /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */
 | 
				
			||||||
    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
					    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
				
			||||||
@ -204,10 +259,19 @@ VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
 | 
				
			|||||||
        DEBUG("In %s, UNDEFINED\n", __FUNCTION__);
 | 
					        DEBUG("In %s, UNDEFINED\n", __FUNCTION__);
 | 
				
			||||||
        exit(-1);
 | 
					        exit(-1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (CoProc == 10 || CoProc == 11) {
 | 
					    if (CoProc == 10 || CoProc == 11)
 | 
				
			||||||
#define VFP_LDC_TRANS
 | 
					    {
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					        if (P == 1 && W == 0)
 | 
				
			||||||
#undef VFP_LDC_TRANS
 | 
					        {
 | 
				
			||||||
 | 
					            return VLDR(state, type, instr, value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (P == 0 && U == 1 && W == 1 && Rn == 0xD)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return VPOP(state, type, instr, value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return VLDM(state, type, instr, value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
 | 
					    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);
 | 
					          instr, CoProc, CRd, Rn, imm8, P, U, D, W);
 | 
				
			||||||
@ -215,8 +279,7 @@ VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
 | 
				
			|||||||
    return ARMul_CANT;
 | 
					    return ARMul_CANT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned
 | 
					unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
 | 
				
			||||||
VFPCDP (ARMul_State * state, unsigned type, u32 instr)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */
 | 
					    /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */
 | 
				
			||||||
    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
					    int CoProc = BITS (8, 11); /* 10 or 11 */
 | 
				
			||||||
@ -275,10 +338,83 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* CRn/opc1 CRm/opc2 */
 | 
					    /* CRn/opc1 CRm/opc2 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (CoProc == 10 || CoProc == 11) {
 | 
					    if (CoProc == 10 || CoProc == 11)
 | 
				
			||||||
#define VFP_CDP_TRANS
 | 
					    {
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					        if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 0)
 | 
				
			||||||
#undef VFP_CDP_TRANS
 | 
					            DBG("VMLA :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 2)
 | 
				
			||||||
 | 
					            DBG("VMLS :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 2)
 | 
				
			||||||
 | 
					            DBG("VNMLA :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 0)
 | 
				
			||||||
 | 
					            DBG("VNMLS :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 2)
 | 
				
			||||||
 | 
					            DBG("VNMUL :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 0)
 | 
				
			||||||
 | 
					            DBG("VMUL :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 0)
 | 
				
			||||||
 | 
					            DBG("VADD :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 2)
 | 
				
			||||||
 | 
					            DBG("VSUB :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xA && (OPC_2 & 0x2) == 0)
 | 
				
			||||||
 | 
					            DBG("VDIV :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && BITS(4, 7) == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            unsigned int single   = BIT(8) == 0;
 | 
				
			||||||
 | 
					            unsigned int d        = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
 | 
				
			||||||
 | 
					            unsigned int imm;
 | 
				
			||||||
 | 
					            instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (single)
 | 
				
			||||||
 | 
					                imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            VMOVI(state, single, d, imm);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x6) == 0x2)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            unsigned int single   = BIT(8) == 0;
 | 
				
			||||||
 | 
					            unsigned int d        = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
 | 
				
			||||||
 | 
					            unsigned int m        = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);;
 | 
				
			||||||
 | 
					            VMOVR(state, single, d, m);
 | 
				
			||||||
 | 
					            return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x7) == 6)
 | 
				
			||||||
 | 
					            DBG("VABS :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 2)
 | 
				
			||||||
 | 
					            DBG("VNEG :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 6)
 | 
				
			||||||
 | 
					            DBG("VSQRT :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && CRn == 4 && (OPC_2 & 0x2) == 2)
 | 
				
			||||||
 | 
					            DBG("VCMP(1) :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && CRn == 5 && (OPC_2 & 0x2) == 2 && CRm == 0)
 | 
				
			||||||
 | 
					            DBG("VCMP(2) :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && CRn == 7 && (OPC_2 & 0x6) == 6)
 | 
				
			||||||
 | 
					            DBG("VCVT(BDS) :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && CRn >= 0xA && (OPC_2 & 0x2) == 2)
 | 
				
			||||||
 | 
					            DBG("VCVT(BFF) :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((OPC_1 & 0xB) == 0xB && CRn > 7 && (OPC_2 & 0x2) == 2)
 | 
				
			||||||
 | 
					            DBG("VCVT(BFI) :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int exceptions = 0;
 | 
					        int exceptions = 0;
 | 
				
			||||||
        if (CoProc == 10)
 | 
					        if (CoProc == 10)
 | 
				
			||||||
@ -296,23 +432,93 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ----------- MRC ------------ */
 | 
					/* ----------- MRC ------------ */
 | 
				
			||||||
#define VFP_MRC_IMPL
 | 
					void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value)
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					{
 | 
				
			||||||
#undef VFP_MRC_IMPL
 | 
					    DBG("VMOV(BRS) :\n");
 | 
				
			||||||
 | 
					    if (to_arm)
 | 
				
			||||||
#define VFP_MRRC_IMPL
 | 
					    {
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					        DBG("\tr%d <= s%d=[%x]\n", t, n, state->ExtReg[n]);
 | 
				
			||||||
#undef VFP_MRRC_IMPL
 | 
					        *value = state->ExtReg[n];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DBG("\ts%d <= r%d=[%x]\n", n, t, *value);
 | 
				
			||||||
 | 
					        state->ExtReg[n] = *value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void VMRS(ARMul_State* state, ARMword reg, ARMword Rt, ARMword* value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    DBG("VMRS :");
 | 
				
			||||||
 | 
					    if (reg == 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (Rt != 15)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            *value = state->VFP[VFP_OFFSET(VFP_FPSCR)];
 | 
				
			||||||
 | 
					            DBG("\tr%d <= fpscr[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            *value = state->VFP[VFP_OFFSET(VFP_FPSCR)] ;
 | 
				
			||||||
 | 
					            DBG("\tflags <= fpscr[%1xxxxxxxx]\n", state->VFP[VFP_OFFSET(VFP_FPSCR)]>>28);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        switch (reg)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            case 0:
 | 
				
			||||||
 | 
					                *value = state->VFP[VFP_OFFSET(VFP_FPSID)];
 | 
				
			||||||
 | 
					                DBG("\tr%d <= fpsid[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSID)]);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 6:
 | 
				
			||||||
 | 
					                /* MVFR1, VFPv3 only ? */
 | 
				
			||||||
 | 
					                DBG("\tr%d <= MVFR1 unimplemented\n", Rt);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 7:
 | 
				
			||||||
 | 
					                /* MVFR0, VFPv3 only? */
 | 
				
			||||||
 | 
					                DBG("\tr%d <= MVFR0 unimplemented\n", Rt);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 8:
 | 
				
			||||||
 | 
					                *value = state->VFP[VFP_OFFSET(VFP_FPEXC)];
 | 
				
			||||||
 | 
					                DBG("\tr%d <= fpexc[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPEXC)]);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                DBG("\tSUBARCHITECTURE DEFINED\n");
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    DBG("VMOV(BRRD) :\n");
 | 
				
			||||||
 | 
					    if (to_arm)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DBG("\tr[%d-%d] <= s[%d-%d]=[%x-%x]\n", t2, t, n*2+1, n*2, state->ExtReg[n*2+1], state->ExtReg[n*2]);
 | 
				
			||||||
 | 
					        *value2 = state->ExtReg[n*2+1];
 | 
				
			||||||
 | 
					        *value1 = state->ExtReg[n*2];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DBG("\ts[%d-%d] <= r[%d-%d]=[%x-%x]\n", n*2+1, n*2, t2, t, *value2, *value1);
 | 
				
			||||||
 | 
					        state->ExtReg[n*2+1] = *value2;
 | 
				
			||||||
 | 
					        state->ExtReg[n*2] = *value1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ----------- MCR ------------ */
 | 
					/* ----------- MCR ------------ */
 | 
				
			||||||
#define VFP_MCR_IMPL
 | 
					void VMSR(ARMul_State* state, ARMword reg, ARMword Rt)
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					{
 | 
				
			||||||
#undef VFP_MCR_IMPL
 | 
					    if (reg == 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
#define VFP_MCRR_IMPL
 | 
					        DBG("VMSR :\tfpscr <= r%d=[%x]\n", Rt, state->Reg[Rt]);
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					        state->VFP[VFP_OFFSET(VFP_FPSCR)] = state->Reg[Rt];
 | 
				
			||||||
#undef VFP_MCRR_IMPL
 | 
					    }
 | 
				
			||||||
 | 
					    else if (reg == 8)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DBG("VMSR :\tfpexc <= r%d=[%x]\n", Rt, state->Reg[Rt]);
 | 
				
			||||||
 | 
					        state->VFP[VFP_OFFSET(VFP_FPEXC)] = state->Reg[Rt];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Memory operation are not inlined, as old Interpreter and Fast interpreter
 | 
					/* Memory operation are not inlined, as old Interpreter and Fast interpreter
 | 
				
			||||||
   don't have the same memory operation interface.
 | 
					   don't have the same memory operation interface.
 | 
				
			||||||
@ -322,21 +528,342 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr)
 | 
				
			|||||||
   of vfp instructions in old interpreter and fast interpreter are separate. */
 | 
					   of vfp instructions in old interpreter and fast interpreter are separate. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ----------- STC ------------ */
 | 
					/* ----------- STC ------------ */
 | 
				
			||||||
#define VFP_STC_IMPL
 | 
					int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value)
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					{
 | 
				
			||||||
#undef VFP_STC_IMPL
 | 
					    static int i = 0;
 | 
				
			||||||
 | 
					    static int single_reg, add, d, n, imm32, regs;
 | 
				
			||||||
 | 
					    if (type == ARMul_FIRST)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        single_reg = BIT(8) == 0;	/* Double precision */
 | 
				
			||||||
 | 
					        add = BIT(23);		/* */
 | 
				
			||||||
 | 
					        imm32 = BITS(0,7)<<2;	/* may not be used */
 | 
				
			||||||
 | 
					        d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
 | 
				
			||||||
 | 
					        n = BITS(16, 19);	/* destination register */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        DBG("VSTR :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i = 0;
 | 
				
			||||||
 | 
					        regs = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ARMul_DONE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (type == ARMul_DATA)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (single_reg)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            *value = state->ExtReg[d+i];
 | 
				
			||||||
 | 
					            DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d+i]);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /* FIXME Careful of endianness, may need to rework this */
 | 
				
			||||||
 | 
					            *value = state->ExtReg[d*2+i];
 | 
				
			||||||
 | 
					            DBG("\taddr[?] <= s[%d]=[%x]\n", d*2+i, state->ExtReg[d*2+i]);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs*2)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static int i = 0;
 | 
				
			||||||
 | 
					    static int single_regs, add, wback, d, n, imm32, regs;
 | 
				
			||||||
 | 
					    if (type == ARMul_FIRST)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        single_regs = BIT(8) == 0;	/* Single precision */
 | 
				
			||||||
 | 
					        d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
 | 
				
			||||||
 | 
					        imm32 = BITS(0,7)<<2;	/* may not be used */
 | 
				
			||||||
 | 
					        regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        DBG("VPUSH :\n");
 | 
				
			||||||
 | 
					        DBG("\tsp[%x]", state->Reg[R13]);
 | 
				
			||||||
 | 
					        state->Reg[R13] = state->Reg[R13] - imm32;
 | 
				
			||||||
 | 
					        DBG("=>[%x]\n", state->Reg[R13]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ARMul_DONE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (type == ARMul_DATA)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (single_regs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            *value = state->ExtReg[d + i];
 | 
				
			||||||
 | 
					            DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /* FIXME Careful of endianness, may need to rework this */
 | 
				
			||||||
 | 
					            *value = state->ExtReg[d*2 + i];
 | 
				
			||||||
 | 
					            DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs*2)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static int i = 0;
 | 
				
			||||||
 | 
					    static int single_regs, add, wback, d, n, imm32, regs;
 | 
				
			||||||
 | 
					    if (type == ARMul_FIRST)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        single_regs = BIT(8) == 0;	/* Single precision */
 | 
				
			||||||
 | 
					        add = BIT(23);		/* */
 | 
				
			||||||
 | 
					        wback = BIT(21);	/* write-back */
 | 
				
			||||||
 | 
					        d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
 | 
				
			||||||
 | 
					        n = BITS(16, 19);	/* destination register */
 | 
				
			||||||
 | 
					        imm32 = BITS(0,7) * 4;	/* may not be used */
 | 
				
			||||||
 | 
					        regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        DBG("VSTM :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (wback) {
 | 
				
			||||||
 | 
					            state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
 | 
				
			||||||
 | 
					            DBG("\twback r%d[%x]\n", n, state->Reg[n]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ARMul_DONE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (type == ARMul_DATA)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (single_regs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            *value = state->ExtReg[d + i];
 | 
				
			||||||
 | 
					            DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /* FIXME Careful of endianness, may need to rework this */
 | 
				
			||||||
 | 
					            *value = state->ExtReg[d*2 + i];
 | 
				
			||||||
 | 
					            DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs*2)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ----------- LDC ------------ */
 | 
					/* ----------- LDC ------------ */
 | 
				
			||||||
#define VFP_LDC_IMPL
 | 
					int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value)
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					{
 | 
				
			||||||
#undef VFP_LDC_IMPL
 | 
					    static int i = 0;
 | 
				
			||||||
 | 
					    static int single_regs, add, wback, d, n, imm32, regs;
 | 
				
			||||||
 | 
					    if (type == ARMul_FIRST)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        single_regs = BIT(8) == 0;	/* Single precision */
 | 
				
			||||||
 | 
					        d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
 | 
				
			||||||
 | 
					        imm32 = BITS(0,7)<<2;	/* may not be used */
 | 
				
			||||||
 | 
					        regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        DBG("VPOP :\n");
 | 
				
			||||||
 | 
					        DBG("\tsp[%x]", state->Reg[R13]);
 | 
				
			||||||
 | 
					        state->Reg[R13] = state->Reg[R13] + imm32;
 | 
				
			||||||
 | 
					        DBG("=>[%x]\n", state->Reg[R13]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ARMul_DONE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (type == ARMul_TRANSFER)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return ARMul_DONE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (type == ARMul_DATA)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (single_regs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            state->ExtReg[d + i] = value;
 | 
				
			||||||
 | 
					            DBG("\ts%d <= [%x]\n", d + i, value);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /* FIXME Careful of endianness, may need to rework this */
 | 
				
			||||||
 | 
					            state->ExtReg[d*2 + i] = value;
 | 
				
			||||||
 | 
					            DBG("\ts%d <= [%x]\n", d*2 + i, value);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs*2)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static int i = 0;
 | 
				
			||||||
 | 
					    static int single_reg, add, d, n, imm32, regs;
 | 
				
			||||||
 | 
					    if (type == ARMul_FIRST)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        single_reg = BIT(8) == 0;	/* Double precision */
 | 
				
			||||||
 | 
					        add = BIT(23);		/* */
 | 
				
			||||||
 | 
					        imm32 = BITS(0,7)<<2;	/* may not be used */
 | 
				
			||||||
 | 
					        d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
 | 
				
			||||||
 | 
					        n = BITS(16, 19);	/* destination register */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        DBG("VLDR :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i = 0;
 | 
				
			||||||
 | 
					        regs = 1;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return ARMul_DONE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (type == ARMul_TRANSFER)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return ARMul_DONE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (type == ARMul_DATA)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (single_reg)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            state->ExtReg[d+i] = value;
 | 
				
			||||||
 | 
					            DBG("\ts%d <= [%x]\n", d+i, value);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /* FIXME Careful of endianness, may need to rework this */
 | 
				
			||||||
 | 
					            state->ExtReg[d*2+i] = value;
 | 
				
			||||||
 | 
					            DBG("\ts[%d] <= [%x]\n", d*2+i, value);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs*2)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static int i = 0;
 | 
				
			||||||
 | 
					    static int single_regs, add, wback, d, n, imm32, regs;
 | 
				
			||||||
 | 
					    if (type == ARMul_FIRST)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        single_regs = BIT(8) == 0;	/* Single precision */
 | 
				
			||||||
 | 
					        add = BIT(23);		/* */
 | 
				
			||||||
 | 
					        wback = BIT(21);	/* write-back */
 | 
				
			||||||
 | 
					        d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
 | 
				
			||||||
 | 
					        n = BITS(16, 19);	/* destination register */
 | 
				
			||||||
 | 
					        imm32 = BITS(0,7) * 4;	/* may not be used */
 | 
				
			||||||
 | 
					        regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        DBG("VLDM :\n");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (wback) {
 | 
				
			||||||
 | 
					            state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
 | 
				
			||||||
 | 
					            DBG("\twback r%d[%x]\n", n, state->Reg[n]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ARMul_DONE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (type == ARMul_DATA)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (single_regs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            state->ExtReg[d + i] = value;
 | 
				
			||||||
 | 
					            DBG("\ts%d <= [%x] addr[?]\n", d+i, state->ExtReg[d + i]);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /* FIXME Careful of endianness, may need to rework this */
 | 
				
			||||||
 | 
					            state->ExtReg[d*2 + i] = value;
 | 
				
			||||||
 | 
					            DBG("\ts[%d] <= [%x] addr[?]\n", d*2 + i, state->ExtReg[d*2 + i]);
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            if (i < regs*2)
 | 
				
			||||||
 | 
					                return ARMul_INC;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return ARMul_DONE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ----------- CDP ------------ */
 | 
					/* ----------- CDP ------------ */
 | 
				
			||||||
#define VFP_CDP_IMPL
 | 
					void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm)
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
 | 
					{
 | 
				
			||||||
#undef VFP_CDP_IMPL
 | 
					    DBG("VMOV(I) :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (single)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DBG("\ts%d <= [%x]\n", d, imm);
 | 
				
			||||||
 | 
					        state->ExtReg[d] = imm;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Check endian please */
 | 
				
			||||||
 | 
					        DBG("\ts[%d-%d] <= [%x-%x]\n", d*2+1, d*2, imm, 0);
 | 
				
			||||||
 | 
					        state->ExtReg[d*2+1] = imm;
 | 
				
			||||||
 | 
					        state->ExtReg[d*2] = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    DBG("VMOV(R) :\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (single)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DBG("\ts%d <= s%d[%x]\n", d, m, state->ExtReg[m]);
 | 
				
			||||||
 | 
					        state->ExtReg[d] = state->ExtReg[m];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* Check endian please */
 | 
				
			||||||
 | 
					        DBG("\ts[%d-%d] <= s[%d-%d][%x-%x]\n", d*2+1, d*2, m*2+1, m*2, state->ExtReg[m*2+1], state->ExtReg[m*2]);
 | 
				
			||||||
 | 
					        state->ExtReg[d*2+1] = state->ExtReg[m*2+1];
 | 
				
			||||||
 | 
					        state->ExtReg[d*2] = state->ExtReg[m*2];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Miscellaneous functions */
 | 
					/* Miscellaneous functions */
 | 
				
			||||||
int32_t vfp_get_float(arm_core_t* state, unsigned int reg)
 | 
					int32_t vfp_get_float(arm_core_t* state, unsigned int reg)
 | 
				
			||||||
@ -366,8 +893,6 @@ void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg)
 | 
				
			|||||||
    state->ExtReg[reg*2+1] = (uint32_t) (val>>32);
 | 
					    state->ExtReg[reg*2+1] = (uint32_t) (val>>32);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Process bitmask of exception conditions. (from vfpmodule.c)
 | 
					 * Process bitmask of exception conditions. (from vfpmodule.c)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */
 | 
					#include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VFP_DEBUG_TRANSLATE DBG("in func %s, %x\n", __FUNCTION__, inst);
 | 
				
			||||||
 | 
					#define VFP_DEBUG_UNIMPLEMENTED(x) printf("in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1);
 | 
				
			||||||
 | 
					#define VFP_DEBUG_UNTESTED(x) printf("in func %s, " #x " untested\n", __FUNCTION__);
 | 
				
			||||||
 | 
					#define CHECK_VFP_ENABLED
 | 
				
			||||||
 | 
					#define CHECK_VFP_CDP_RET	vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); //if (ret == -1) {printf("VFP CDP FAILURE %x\n", inst_cream->instr); exit(-1);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned VFPInit (ARMul_State *state);
 | 
					unsigned VFPInit (ARMul_State *state);
 | 
				
			||||||
unsigned VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value);
 | 
					unsigned VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value);
 | 
				
			||||||
unsigned VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value);
 | 
					unsigned VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value);
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user