All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aurelien Jarno <aurelien@aurel32.net>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [5120] SH4: Convert remaining non-fp ops to TCG
Date: Mon, 01 Sep 2008 13:09:06 +0000	[thread overview]
Message-ID: <E1Ka99W-0002he-PC@cvs.savannah.gnu.org> (raw)

Revision: 5120
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5120
Author:   aurel32
Date:     2008-09-01 13:09:06 +0000 (Mon, 01 Sep 2008)

Log Message:
-----------
SH4: Convert remaining non-fp ops to TCG

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

Modified Paths:
--------------
    trunk/target-sh4/exec.h
    trunk/target-sh4/helper.h
    trunk/target-sh4/op.c
    trunk/target-sh4/op_helper.c
    trunk/target-sh4/translate.c

Modified: trunk/target-sh4/exec.h
===================================================================
--- trunk/target-sh4/exec.h	2008-08-30 22:37:17 UTC (rev 5119)
+++ trunk/target-sh4/exec.h	2008-09-01 13:09:06 UTC (rev 5120)
@@ -71,10 +71,6 @@
 		    int use_asid, int update);
 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 cpu_loop_exit(void);

Modified: trunk/target-sh4/helper.h
===================================================================
--- trunk/target-sh4/helper.h	2008-08-30 22:37:17 UTC (rev 5119)
+++ trunk/target-sh4/helper.h	2008-09-01 13:09:06 UTC (rev 5120)
@@ -14,6 +14,7 @@
 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_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_macw, (uint32_t, uint32_t))
 

Modified: trunk/target-sh4/op.c
===================================================================
--- trunk/target-sh4/op.c	2008-08-30 22:37:17 UTC (rev 5119)
+++ trunk/target-sh4/op.c	2008-09-01 13:09:06 UTC (rev 5120)
@@ -37,84 +37,6 @@
 	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)
 {
     FT0 = env->fregs[PARAM1];

Modified: trunk/target-sh4/op_helper.c
===================================================================
--- trunk/target-sh4/op_helper.c	2008-08-30 22:37:17 UTC (rev 5119)
+++ trunk/target-sh4/op_helper.c	2008-09-01 13:09:06 UTC (rev 5120)
@@ -163,27 +163,27 @@
 #define SETM 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;
     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;
-    if ((0x80000000 & T1) != 0)
+    if ((0x80000000 & arg1) != 0)
 	SETQ;
     else
 	CLRQ;
-    tmp2 = T0;
-    T1 <<= 1;
-    T1 |= T;
+    tmp2 = arg0;
+    arg1 <<= 1;
+    arg1 |= T;
     switch (old_q) {
     case 0:
 	switch (M) {
 	case 0:
-	    tmp0 = T1;
-	    T1 -= tmp2;
-	    tmp1 = T1 > tmp0;
+	    tmp0 = arg1;
+	    arg1 -= tmp2;
+	    tmp1 = arg1 > tmp0;
 	    switch (Q) {
 	    case 0:
 		if (tmp1)
@@ -200,9 +200,9 @@
 	    }
 	    break;
 	case 1:
-	    tmp0 = T1;
-	    T1 += tmp2;
-	    tmp1 = T1 < tmp0;
+	    tmp0 = arg1;
+	    arg1 += tmp2;
+	    tmp1 = arg1 < tmp0;
 	    switch (Q) {
 	    case 0:
 		if (tmp1 == 0)
@@ -223,9 +223,9 @@
     case 1:
 	switch (M) {
 	case 0:
-	    tmp0 = T1;
-	    T1 += tmp2;
-	    tmp1 = T1 < tmp0;
+	    tmp0 = arg1;
+	    arg1 += tmp2;
+	    tmp1 = arg1 < tmp0;
 	    switch (Q) {
 	    case 0:
 		if (tmp1)
@@ -242,9 +242,9 @@
 	    }
 	    break;
 	case 1:
-	    tmp0 = T1;
-	    T1 -= tmp2;
-	    tmp1 = T1 > tmp0;
+	    tmp0 = arg1;
+	    arg1 -= tmp2;
+	    tmp1 = arg1 > tmp0;
 	    switch (Q) {
 	    case 0:
 		if (tmp1 == 0)
@@ -267,7 +267,8 @@
 	SETT;
     else
 	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)
@@ -365,30 +366,6 @@
     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)
 {
     env->fpscr = val & 0x003fffff;

Modified: trunk/target-sh4/translate.c
===================================================================
--- trunk/target-sh4/translate.c	2008-08-30 22:37:17 UTC (rev 5119)
+++ trunk/target-sh4/translate.c	2008-09-01 13:09:06 UTC (rev 5120)
@@ -337,6 +337,24 @@
     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 B6_4 ((ctx->opcode >> 4) & 0x7)
 #define B7_4 ((ctx->opcode >> 4) & 0xf)
@@ -643,20 +661,33 @@
 	gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]);
 	return;
     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)]);
-	gen_op_cmp_str_T0_T1();
+	{
+	    int label1 = gen_new_label();
+	    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;
     case 0x2007:		/* div0s 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)]);
-	gen_op_div0s_T0_T1();
+	gen_copy_bit_i32(cpu_sr, 8, cpu_gregs[REG(B11_8)], 31);	/* SR_Q */
+	gen_copy_bit_i32(cpu_sr, 9, cpu_gregs[REG(B7_4)], 31);	/* SR_M */
+	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;
     case 0x3004:		/* div1 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)]);
-	gen_op_div1_T0_T1();
-	tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
+	tcg_gen_helper_1_2(helper_div1, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
 	return;
     case 0x300d:		/* dmuls.l Rm,Rn */
 	{
@@ -758,16 +789,59 @@
 	tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
 	return;
     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)]);
-	gen_op_shad_T0_T1();
-	tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
+	{
+	    int label1 = gen_new_label();
+	    int label2 = gen_new_label();
+	    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;
     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)]);
-	gen_op_shld_T0_T1();
-	tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
+	{
+	    int label1 = gen_new_label();
+	    int label2 = gen_new_label();
+	    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;
     case 0x3008:		/* sub Rm,Rn */
 	tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
@@ -1213,31 +1287,38 @@
     case 0x0083:		/* pref @Rn */
 	return;
     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;
     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;
     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;
     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;
     case 0x4000:		/* shll Rn */
     case 0x4020:		/* shal Rn */
-	tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 0x80000000);
-	gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0);
+	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);
 	return;
     case 0x4021:		/* shar Rn */
-	tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 1);
-	gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0);
+	gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0);
 	tcg_gen_sari_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
 	return;
     case 0x4001:		/* shlr Rn */
-	tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 1);
-	gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0);
+	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);
 	return;
     case 0x4008:		/* shll2 Rn */

             reply	other threads:[~2008-09-01 13:09 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-01 13:09 Aurelien Jarno [this message]
2008-09-01 14:34 ` [Qemu-devel] [5120] SH4: Convert remaining non-fp ops to TCG Blue Swirl
2008-09-01 15:25   ` Aurelien Jarno

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1Ka99W-0002he-PC@cvs.savannah.gnu.org \
    --to=aurelien@aurel32.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.