SH4: Convert remaining non-fp ops to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5120 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									c047da1af4
								
							
						
					
					
						commit
						69d6275b00
					
				@ -71,10 +71,6 @@ int find_itlb_entry(CPUState * env, target_ulong address,
 | 
				
			|||||||
		    int use_asid, int update);
 | 
							    int use_asid, int update);
 | 
				
			||||||
int find_utlb_entry(CPUState * env, target_ulong address, int use_asid);
 | 
					int find_utlb_entry(CPUState * env, target_ulong address, int use_asid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_div1_T0_T1(void);
 | 
					 | 
				
			||||||
void helper_rotcl(uint32_t * addr);
 | 
					 | 
				
			||||||
void helper_rotcr(uint32_t * addr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_interrupt(CPUState * env);
 | 
					void do_interrupt(CPUState * env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cpu_loop_exit(void);
 | 
					void cpu_loop_exit(void);
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,7 @@ DEF_HELPER(uint32_t, helper_addc, (uint32_t, uint32_t))
 | 
				
			|||||||
DEF_HELPER(uint32_t, helper_subv, (uint32_t, uint32_t))
 | 
					DEF_HELPER(uint32_t, helper_subv, (uint32_t, uint32_t))
 | 
				
			||||||
DEF_HELPER(uint32_t, helper_subc, (uint32_t, uint32_t))
 | 
					DEF_HELPER(uint32_t, helper_subc, (uint32_t, uint32_t))
 | 
				
			||||||
DEF_HELPER(uint32_t, helper_negc, (uint32_t))
 | 
					DEF_HELPER(uint32_t, helper_negc, (uint32_t))
 | 
				
			||||||
 | 
					DEF_HELPER(uint32_t, helper_div1, (uint32_t, uint32_t))
 | 
				
			||||||
DEF_HELPER(void, helper_macl, (uint32_t, uint32_t))
 | 
					DEF_HELPER(void, helper_macl, (uint32_t, uint32_t))
 | 
				
			||||||
DEF_HELPER(void, helper_macw, (uint32_t, uint32_t))
 | 
					DEF_HELPER(void, helper_macw, (uint32_t, uint32_t))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -37,84 +37,6 @@ static inline void cond_t(int cond)
 | 
				
			|||||||
	clr_t();
 | 
						clr_t();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_cmp_str_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
 | 
					 | 
				
			||||||
	   (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
 | 
					 | 
				
			||||||
	   (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
 | 
					 | 
				
			||||||
	   (T0 & 0xff000000) == (T1 & 0xff000000));
 | 
					 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_div0s_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (T1 & 0x80000000)
 | 
					 | 
				
			||||||
	env->sr |= SR_Q;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
	env->sr &= ~SR_Q;
 | 
					 | 
				
			||||||
    if (T0 & 0x80000000)
 | 
					 | 
				
			||||||
	env->sr |= SR_M;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
	env->sr &= ~SR_M;
 | 
					 | 
				
			||||||
    cond_t((T1 ^ T0) & 0x80000000);
 | 
					 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_div1_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_div1_T0_T1();
 | 
					 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_shad_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((T0 & 0x80000000) == 0)
 | 
					 | 
				
			||||||
	T1 <<= (T0 & 0x1f);
 | 
					 | 
				
			||||||
    else if ((T0 & 0x1f) == 0)
 | 
					 | 
				
			||||||
	T1 = (T1 & 0x80000000)? 0xffffffff : 0;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
	T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
 | 
					 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_shld_T0_T1(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((T0 & 0x80000000) == 0)
 | 
					 | 
				
			||||||
	T1 <<= (T0 & 0x1f);
 | 
					 | 
				
			||||||
    else if ((T0 & 0x1f) == 0)
 | 
					 | 
				
			||||||
	T1 = 0;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
	T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
 | 
					 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_rotcl_Rn(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_rotcl(&env->gregs[PARAM1]);
 | 
					 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_rotcr_Rn(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    helper_rotcr(&env->gregs[PARAM1]);
 | 
					 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_rotl_Rn(void) 
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    cond_t(env->gregs[PARAM1] & 0x80000000);
 | 
					 | 
				
			||||||
    env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
 | 
					 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_rotr_Rn(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    cond_t(env->gregs[PARAM1] & 1);
 | 
					 | 
				
			||||||
    env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
 | 
					 | 
				
			||||||
	((env->sr & SR_T) ? 0x80000000 : 0);
 | 
					 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_fmov_frN_FT0(void)
 | 
					void OPPROTO op_fmov_frN_FT0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    FT0 = env->fregs[PARAM1];
 | 
					    FT0 = env->fregs[PARAM1];
 | 
				
			||||||
 | 
				
			|||||||
@ -163,27 +163,27 @@ uint32_t helper_addv(uint32_t arg0, uint32_t arg1)
 | 
				
			|||||||
#define SETM env->sr |= SR_M
 | 
					#define SETM env->sr |= SR_M
 | 
				
			||||||
#define CLRM env->sr &= ~SR_M
 | 
					#define CLRM env->sr &= ~SR_M
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_div1_T0_T1(void)
 | 
					uint32_t helper_div1(uint32_t arg0, uint32_t arg1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t tmp0, tmp2;
 | 
					    uint32_t tmp0, tmp2;
 | 
				
			||||||
    uint8_t old_q, tmp1 = 0xff;
 | 
					    uint8_t old_q, tmp1 = 0xff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //printf("div1 T0=0x%08x T1=0x%08x M=%d Q=%d T=%d\n", T0, T1, M, Q, T);
 | 
					    //printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, Q, T);
 | 
				
			||||||
    old_q = Q;
 | 
					    old_q = Q;
 | 
				
			||||||
    if ((0x80000000 & T1) != 0)
 | 
					    if ((0x80000000 & arg1) != 0)
 | 
				
			||||||
	SETQ;
 | 
						SETQ;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
	CLRQ;
 | 
						CLRQ;
 | 
				
			||||||
    tmp2 = T0;
 | 
					    tmp2 = arg0;
 | 
				
			||||||
    T1 <<= 1;
 | 
					    arg1 <<= 1;
 | 
				
			||||||
    T1 |= T;
 | 
					    arg1 |= T;
 | 
				
			||||||
    switch (old_q) {
 | 
					    switch (old_q) {
 | 
				
			||||||
    case 0:
 | 
					    case 0:
 | 
				
			||||||
	switch (M) {
 | 
						switch (M) {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
	    tmp0 = T1;
 | 
						    tmp0 = arg1;
 | 
				
			||||||
	    T1 -= tmp2;
 | 
						    arg1 -= tmp2;
 | 
				
			||||||
	    tmp1 = T1 > tmp0;
 | 
						    tmp1 = arg1 > tmp0;
 | 
				
			||||||
	    switch (Q) {
 | 
						    switch (Q) {
 | 
				
			||||||
	    case 0:
 | 
						    case 0:
 | 
				
			||||||
		if (tmp1)
 | 
							if (tmp1)
 | 
				
			||||||
@ -200,9 +200,9 @@ void helper_div1_T0_T1(void)
 | 
				
			|||||||
	    }
 | 
						    }
 | 
				
			||||||
	    break;
 | 
						    break;
 | 
				
			||||||
	case 1:
 | 
						case 1:
 | 
				
			||||||
	    tmp0 = T1;
 | 
						    tmp0 = arg1;
 | 
				
			||||||
	    T1 += tmp2;
 | 
						    arg1 += tmp2;
 | 
				
			||||||
	    tmp1 = T1 < tmp0;
 | 
						    tmp1 = arg1 < tmp0;
 | 
				
			||||||
	    switch (Q) {
 | 
						    switch (Q) {
 | 
				
			||||||
	    case 0:
 | 
						    case 0:
 | 
				
			||||||
		if (tmp1 == 0)
 | 
							if (tmp1 == 0)
 | 
				
			||||||
@ -223,9 +223,9 @@ void helper_div1_T0_T1(void)
 | 
				
			|||||||
    case 1:
 | 
					    case 1:
 | 
				
			||||||
	switch (M) {
 | 
						switch (M) {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
	    tmp0 = T1;
 | 
						    tmp0 = arg1;
 | 
				
			||||||
	    T1 += tmp2;
 | 
						    arg1 += tmp2;
 | 
				
			||||||
	    tmp1 = T1 < tmp0;
 | 
						    tmp1 = arg1 < tmp0;
 | 
				
			||||||
	    switch (Q) {
 | 
						    switch (Q) {
 | 
				
			||||||
	    case 0:
 | 
						    case 0:
 | 
				
			||||||
		if (tmp1)
 | 
							if (tmp1)
 | 
				
			||||||
@ -242,9 +242,9 @@ void helper_div1_T0_T1(void)
 | 
				
			|||||||
	    }
 | 
						    }
 | 
				
			||||||
	    break;
 | 
						    break;
 | 
				
			||||||
	case 1:
 | 
						case 1:
 | 
				
			||||||
	    tmp0 = T1;
 | 
						    tmp0 = arg1;
 | 
				
			||||||
	    T1 -= tmp2;
 | 
						    arg1 -= tmp2;
 | 
				
			||||||
	    tmp1 = T1 > tmp0;
 | 
						    tmp1 = arg1 > tmp0;
 | 
				
			||||||
	    switch (Q) {
 | 
						    switch (Q) {
 | 
				
			||||||
	    case 0:
 | 
						    case 0:
 | 
				
			||||||
		if (tmp1 == 0)
 | 
							if (tmp1 == 0)
 | 
				
			||||||
@ -267,7 +267,8 @@ void helper_div1_T0_T1(void)
 | 
				
			|||||||
	SETT;
 | 
						SETT;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
	CLRT;
 | 
						CLRT;
 | 
				
			||||||
    //printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T);
 | 
					    //printf("Output: arg1=0x%08x M=%d Q=%d T=%d\n", arg1, M, Q, T);
 | 
				
			||||||
 | 
					    return arg1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_macl(uint32_t arg0, uint32_t arg1)
 | 
					void helper_macl(uint32_t arg0, uint32_t arg1)
 | 
				
			||||||
@ -365,30 +366,6 @@ uint32_t helper_subv(uint32_t arg0, uint32_t arg1)
 | 
				
			|||||||
    return arg1;
 | 
					    return arg1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void helper_rotcl(uint32_t * addr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint32_t new;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    new = (*addr << 1) | (env->sr & SR_T);
 | 
					 | 
				
			||||||
    if (*addr & 0x80000000)
 | 
					 | 
				
			||||||
	env->sr |= SR_T;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
	env->sr &= ~SR_T;
 | 
					 | 
				
			||||||
    *addr = new;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void helper_rotcr(uint32_t * addr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint32_t new;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    new = (*addr >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0);
 | 
					 | 
				
			||||||
    if (*addr & 1)
 | 
					 | 
				
			||||||
	env->sr |= SR_T;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
	env->sr &= ~SR_T;
 | 
					 | 
				
			||||||
    *addr = new;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void helper_ld_fpscr(uint32_t val)
 | 
					void helper_ld_fpscr(uint32_t val)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    env->fpscr = val & 0x003fffff;
 | 
					    env->fpscr = val & 0x003fffff;
 | 
				
			||||||
 | 
				
			|||||||
@ -337,6 +337,24 @@ static inline void gen_store_flags(uint32_t flags)
 | 
				
			|||||||
    tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
 | 
					    tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    p0 &= 0x1f;
 | 
				
			||||||
 | 
					    p1 &= 0x1f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tcg_gen_andi_i32(tmp, t1, (1 << p1));
 | 
				
			||||||
 | 
					    tcg_gen_andi_i32(t0, t0, ~(1 << p0));
 | 
				
			||||||
 | 
					    if (p0 < p1)
 | 
				
			||||||
 | 
					        tcg_gen_shri_i32(tmp, tmp, p1 - p0);
 | 
				
			||||||
 | 
					    else if (p0 > p1)
 | 
				
			||||||
 | 
					        tcg_gen_shli_i32(tmp, tmp, p0 - p1);
 | 
				
			||||||
 | 
					    tcg_gen_or_i32(t0, t0, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tcg_temp_free(tmp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define B3_0 (ctx->opcode & 0xf)
 | 
					#define B3_0 (ctx->opcode & 0xf)
 | 
				
			||||||
#define B6_4 ((ctx->opcode >> 4) & 0x7)
 | 
					#define B6_4 ((ctx->opcode >> 4) & 0x7)
 | 
				
			||||||
#define B7_4 ((ctx->opcode >> 4) & 0xf)
 | 
					#define B7_4 ((ctx->opcode >> 4) & 0xf)
 | 
				
			||||||
@ -643,20 +661,33 @@ void _decode_opc(DisasContext * ctx)
 | 
				
			|||||||
	gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]);
 | 
						gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x200c:		/* cmp/str Rm,Rn */
 | 
					    case 0x200c:		/* cmp/str Rm,Rn */
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
 | 
						{
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
 | 
						    int label1 = gen_new_label();
 | 
				
			||||||
	gen_op_cmp_str_T0_T1();
 | 
						    int label2 = gen_new_label();
 | 
				
			||||||
 | 
						    tcg_gen_xor_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff000000);
 | 
				
			||||||
 | 
						    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x00ff0000);
 | 
				
			||||||
 | 
						    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x0000ff00);
 | 
				
			||||||
 | 
						    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x000000ff);
 | 
				
			||||||
 | 
						    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
 | 
				
			||||||
 | 
						    tcg_gen_br(label2);
 | 
				
			||||||
 | 
						    gen_set_label(label1);
 | 
				
			||||||
 | 
						    tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
 | 
				
			||||||
 | 
						    gen_set_label(label2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x2007:		/* div0s Rm,Rn */
 | 
					    case 0x2007:		/* div0s Rm,Rn */
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
 | 
						gen_copy_bit_i32(cpu_sr, 8, cpu_gregs[REG(B11_8)], 31);	/* SR_Q */
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
 | 
						gen_copy_bit_i32(cpu_sr, 9, cpu_gregs[REG(B7_4)], 31);	/* SR_M */
 | 
				
			||||||
	gen_op_div0s_T0_T1();
 | 
						tcg_gen_xor_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
 | 
				
			||||||
 | 
						gen_copy_bit_i32(cpu_sr, 0, cpu_T[0], 31);		/* SR_T */
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x3004:		/* div1 Rm,Rn */
 | 
					    case 0x3004:		/* div1 Rm,Rn */
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
 | 
						tcg_gen_helper_1_2(helper_div1, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
 | 
					 | 
				
			||||||
	gen_op_div1_T0_T1();
 | 
					 | 
				
			||||||
	tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
 | 
					 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x300d:		/* dmuls.l Rm,Rn */
 | 
					    case 0x300d:		/* dmuls.l Rm,Rn */
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -758,16 +789,59 @@ void _decode_opc(DisasContext * ctx)
 | 
				
			|||||||
	tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
 | 
						tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x400c:		/* shad Rm,Rn */
 | 
					    case 0x400c:		/* shad Rm,Rn */
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
 | 
						{
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
 | 
						    int label1 = gen_new_label();
 | 
				
			||||||
	gen_op_shad_T0_T1();
 | 
						    int label2 = gen_new_label();
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
 | 
						    int label3 = gen_new_label();
 | 
				
			||||||
 | 
						    int label4 = gen_new_label();
 | 
				
			||||||
 | 
						    tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B7_4)], 0, label1);
 | 
				
			||||||
 | 
						    /* Rm positive, shift to the left */
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f);
 | 
				
			||||||
 | 
						    tcg_gen_shl_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
 | 
				
			||||||
 | 
						    tcg_gen_br(label4);
 | 
				
			||||||
 | 
						    /* Rm negative, shift to the right */
 | 
				
			||||||
 | 
						    gen_set_label(label1);
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f);
 | 
				
			||||||
 | 
						    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2);
 | 
				
			||||||
 | 
						    tcg_gen_not_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f);
 | 
				
			||||||
 | 
						    tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1);
 | 
				
			||||||
 | 
						    tcg_gen_sar_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
 | 
				
			||||||
 | 
						    tcg_gen_br(label4);
 | 
				
			||||||
 | 
						    /* Rm = -32 */
 | 
				
			||||||
 | 
						    gen_set_label(label2);
 | 
				
			||||||
 | 
						    tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B11_8)], 0, label3);
 | 
				
			||||||
 | 
						    tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0);
 | 
				
			||||||
 | 
						    tcg_gen_br(label4);
 | 
				
			||||||
 | 
						    gen_set_label(label3);
 | 
				
			||||||
 | 
						    tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0xffffffff);
 | 
				
			||||||
 | 
						    gen_set_label(label4);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x400d:		/* shld Rm,Rn */
 | 
					    case 0x400d:		/* shld Rm,Rn */
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
 | 
						{
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
 | 
						    int label1 = gen_new_label();
 | 
				
			||||||
	gen_op_shld_T0_T1();
 | 
						    int label2 = gen_new_label();
 | 
				
			||||||
	tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
 | 
						    int label3 = gen_new_label();
 | 
				
			||||||
 | 
						    tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B7_4)], 0, label1);
 | 
				
			||||||
 | 
						    /* Rm positive, shift to the left */
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f);
 | 
				
			||||||
 | 
						    tcg_gen_shl_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
 | 
				
			||||||
 | 
						    tcg_gen_br(label3);
 | 
				
			||||||
 | 
						    /* Rm negative, shift to the right */
 | 
				
			||||||
 | 
						    gen_set_label(label1);
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f);
 | 
				
			||||||
 | 
						    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2);
 | 
				
			||||||
 | 
						    tcg_gen_not_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
 | 
				
			||||||
 | 
						    tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f);
 | 
				
			||||||
 | 
						    tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1);
 | 
				
			||||||
 | 
						    tcg_gen_shr_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
 | 
				
			||||||
 | 
						    tcg_gen_br(label3);
 | 
				
			||||||
 | 
						    /* Rm = -32 */
 | 
				
			||||||
 | 
						    gen_set_label(label2);
 | 
				
			||||||
 | 
						    tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0);
 | 
				
			||||||
 | 
						    gen_set_label(label3);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x3008:		/* sub Rm,Rn */
 | 
					    case 0x3008:		/* sub Rm,Rn */
 | 
				
			||||||
	tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
 | 
						tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
 | 
				
			||||||
@ -1213,31 +1287,38 @@ void _decode_opc(DisasContext * ctx)
 | 
				
			|||||||
    case 0x0083:		/* pref @Rn */
 | 
					    case 0x0083:		/* pref @Rn */
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x4024:		/* rotcl Rn */
 | 
					    case 0x4024:		/* rotcl Rn */
 | 
				
			||||||
	gen_op_rotcl_Rn(REG(B11_8));
 | 
						tcg_gen_mov_i32(cpu_T[0], cpu_sr);
 | 
				
			||||||
 | 
						gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31);
 | 
				
			||||||
 | 
						tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
				
			||||||
 | 
						gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 0, cpu_T[0], 0);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x4025:		/* rotcr Rn */
 | 
					    case 0x4025:		/* rotcr Rn */
 | 
				
			||||||
	gen_op_rotcr_Rn(REG(B11_8));
 | 
						tcg_gen_mov_i32(cpu_T[0], cpu_sr);
 | 
				
			||||||
 | 
						gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0);
 | 
				
			||||||
 | 
						tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
				
			||||||
 | 
						gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 31, cpu_T[0], 0);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x4004:		/* rotl Rn */
 | 
					    case 0x4004:		/* rotl Rn */
 | 
				
			||||||
	gen_op_rotl_Rn(REG(B11_8));
 | 
						gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31);
 | 
				
			||||||
 | 
						tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
				
			||||||
 | 
						gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 0, cpu_sr, 0);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x4005:		/* rotr Rn */
 | 
					    case 0x4005:		/* rotr Rn */
 | 
				
			||||||
	gen_op_rotr_Rn(REG(B11_8));
 | 
						gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0);
 | 
				
			||||||
 | 
						tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
				
			||||||
 | 
						gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 31, cpu_sr, 0);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x4000:		/* shll Rn */
 | 
					    case 0x4000:		/* shll Rn */
 | 
				
			||||||
    case 0x4020:		/* shal Rn */
 | 
					    case 0x4020:		/* shal Rn */
 | 
				
			||||||
	tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 0x80000000);
 | 
						gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31);
 | 
				
			||||||
	gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0);
 | 
					 | 
				
			||||||
	tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
						tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x4021:		/* shar Rn */
 | 
					    case 0x4021:		/* shar Rn */
 | 
				
			||||||
	tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 1);
 | 
						gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0);
 | 
				
			||||||
	gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0);
 | 
					 | 
				
			||||||
	tcg_gen_sari_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
						tcg_gen_sari_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x4001:		/* shlr Rn */
 | 
					    case 0x4001:		/* shlr Rn */
 | 
				
			||||||
	tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 1);
 | 
						gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0);
 | 
				
			||||||
	gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0);
 | 
					 | 
				
			||||||
	tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
						tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    case 0x4008:		/* shll2 Rn */
 | 
					    case 0x4008:		/* shll2 Rn */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user