qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] SH4: convert fmov/fadd to TCG
@ 2008-08-30 19:36 Shin-ichiro KAWASAKI
  2008-08-30 20:23 ` Blue Swirl
  0 siblings, 1 reply; 6+ messages in thread
From: Shin-ichiro KAWASAKI @ 2008-08-30 19:36 UTC (permalink / raw)
  To: qemu-devel

This patch converts two SH4 float instructions, 'fmov Rm,Rn' and
'fadd' into TCG.  Before converting other float instructions
into TCG, comments on it will be appreciated.

- TCG variables intorudced for float operation : FT[01], and DT[01].
- I think float registers 'fregs' are not to be mapped for
  TCG variables, because TCG does not support float operations, now.
  Instead of it, float register load/store function introduced.
  For 64 bit operation, they do 32 bit swap with temporary TCG vars.
  I hope that this won't result too much overhead.
- A comment is added to imply that SH-Linux does not run
  'fmov' in 64 bit .

Regards,
Shin-ichiro KAWASAKI


Index: trunk/target-sh4/op.c
===================================================================
--- trunk/target-sh4/op.c	(revision 5116)
+++ trunk/target-sh4/op.c	(working copy)
@@ -230,18 +230,6 @@
     RETURN();
 }
 
-void OPPROTO op_fadd_FT(void)
-{
-    FT0 = float32_add(FT0, FT1, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fadd_DT(void)
-{
-    DT0 = float64_add(DT0, DT1, &env->fp_status);
-    RETURN();
-}
-
 void OPPROTO op_fsub_FT(void)
 {
     FT0 = float32_sub(FT0, FT1, &env->fp_status);
Index: trunk/target-sh4/helper.h
===================================================================
--- trunk/target-sh4/helper.h	(revision 5116)
+++ trunk/target-sh4/helper.h	(working copy)
@@ -16,3 +16,6 @@
 DEF_HELPER(uint32_t, helper_negc, (uint32_t))
 DEF_HELPER(void, helper_macl, (uint32_t, uint32_t))
 DEF_HELPER(void, helper_macw, (uint32_t, uint32_t))
+
+DEF_HELPER(uint32_t, helper_fadd_FT, (uint32_t, uint32_t, CPUState *))
+DEF_HELPER(uint64_t, helper_fadd_DT, (uint64_t, uint64_t, CPUState *))
Index: trunk/target-sh4/op_helper.c
===================================================================
--- trunk/target-sh4/op_helper.c	(revision 5116)
+++ trunk/target-sh4/op_helper.c	(working copy)
@@ -388,3 +388,15 @@
 	env->sr &= ~SR_T;
     *addr = new;
 }
+
+uint32_t helper_fadd_FT(uint32_t t0, uint32_t t1, CPUState * env)
+{
+    float32 ret = float32_add(*(float32*)&t0, *(float32*)&t1, &env->fp_status);
+    return *(uint32_t*)(&ret);
+}
+
+uint64_t helper_fadd_DT(uint64_t t0, uint64_t t1, CPUState * env)
+{
+    float64 ret = float64_add(*(float64*)&t0, *(float64*)&t1, &env->fp_status);
+    return *(uint64_t*)(&ret);
+}
Index: trunk/target-sh4/translate.c
===================================================================
--- trunk/target-sh4/translate.c	(revision 5116)
+++ trunk/target-sh4/translate.c	(working copy)
@@ -69,6 +69,8 @@
 
 /* dyngen register indexes */
 static TCGv cpu_T[2];
+static TCGv cpu_FT[2];
+static TCGv cpu_DT[2];
 
 #include "gen-icount.h"
 
@@ -90,6 +92,14 @@
     cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
     cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
     cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
+    cpu_FT[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+				   offsetof(CPUState, ft0), "FT0");
+    cpu_FT[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+				   offsetof(CPUState, ft1), "FT1");
+    cpu_DT[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+				   offsetof(CPUState, dt0), "DT0");
+    cpu_DT[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+				   offsetof(CPUState, dt1), "DT1");
 
     for (i = 0; i < 24; i++)
         cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
@@ -345,6 +355,42 @@
     tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
 }
 
+static inline void gen_ld_frN(TCGv ft, TCGv cpu_env, uint32_t reg)
+{
+    tcg_gen_ld_i32(ft, cpu_env, offsetof(CPUState, fregs[reg]));
+}
+
+static inline void gen_ld_drN(TCGv dt, TCGv cpu_env, uint32_t reg)
+{
+    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+	        
+    tcg_gen_ld_i64(dt, cpu_env, offsetof(CPUState, fregs[reg]));
+    tcg_gen_shli_i64(tmp, dt, 32);
+    tcg_gen_shri_i64(dt, dt, 32);
+    tcg_gen_or_i64(dt, tmp, dt);
+
+    tcg_temp_free(tmp);
+}
+
+static inline void gen_st_frN(TCGv ft, TCGv cpu_env, uint32_t reg)
+{
+    tcg_gen_st_i32(ft, cpu_env, offsetof(CPUState, fregs[reg]));
+}
+
+static inline void gen_st_drN(TCGv dt, TCGv cpu_env, uint32_t reg)
+{
+    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
+    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
+	        
+    tcg_gen_shli_i64(tmp1, dt, 32);
+    tcg_gen_shri_i64(tmp2, dt, 32);
+    tcg_gen_or_i64(tmp1, tmp1, tmp2);
+    tcg_gen_st_i64(tmp1, cpu_env, offsetof(CPUState, fregs[reg]));
+
+    tcg_temp_free(tmp1);
+    tcg_temp_free(tmp2);
+}
+
 #define B3_0 (ctx->opcode & 0xf)
 #define B6_4 ((ctx->opcode >> 4) & 0x7)
 #define B7_4 ((ctx->opcode >> 4) & 0xf)
@@ -811,12 +857,14 @@
 	tcg_gen_xor_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
 	return;
     case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
+        /* 64 bit fmov code is not tested, because SH-Linux seems
+	   not to set FPSCR_SZ flag true. */
 	if (ctx->fpscr & FPSCR_SZ) {
-	    gen_op_fmov_drN_DT0(XREG(B7_4));
-	    gen_op_fmov_DT0_drN(XREG(B11_8));
+	    gen_ld_drN(cpu_DT[0], cpu_env, XREG(B7_4));
+	    gen_st_drN(cpu_DT[1], cpu_env, XREG(B11_8));
 	} else {
-	    gen_op_fmov_frN_FT0(FREG(B7_4));
-	    gen_op_fmov_FT0_frN(FREG(B11_8));
+	    gen_ld_frN(cpu_FT[0], cpu_env, FREG(B7_4));
+	    gen_st_frN(cpu_FT[0], cpu_env, FREG(B11_8));
 	}
 	return;
     case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
@@ -905,17 +953,22 @@
 	if (ctx->fpscr & FPSCR_PR) {
 	    if (ctx->opcode & 0x0110)
 		break; /* illegal instruction */
-	    gen_op_fmov_drN_DT1(DREG(B7_4));
-	    gen_op_fmov_drN_DT0(DREG(B11_8));
+	    gen_ld_drN(cpu_DT[1], cpu_env, DREG(B7_4));
+	    gen_ld_drN(cpu_DT[0], cpu_env, DREG(B11_8));
 	}
 	else {
-	    gen_op_fmov_frN_FT1(FREG(B7_4));
-	    gen_op_fmov_frN_FT0(FREG(B11_8));
+	    gen_ld_frN(cpu_FT[1], cpu_env, FREG(B7_4));
+	    gen_ld_frN(cpu_FT[0], cpu_env, FREG(B11_8));
 	}
 
 	switch (ctx->opcode & 0xf00f) {
 	case 0xf000:		/* fadd Rm,Rn */
-	    ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
+	    if (ctx->fpscr & FPSCR_PR)
+	        tcg_gen_helper_1_3(helper_fadd_DT, cpu_DT[0],
+				   cpu_DT[0], cpu_DT[1], cpu_env);
+	    else
+	        tcg_gen_helper_1_3(helper_fadd_FT, cpu_FT[0],
+				   cpu_FT[0], cpu_FT[1], cpu_env);
 	    break;
 	case 0xf001:		/* fsub Rm,Rn */
 	    ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
@@ -935,10 +988,10 @@
 	}
 
 	if (ctx->fpscr & FPSCR_PR) {
-	    gen_op_fmov_DT0_drN(DREG(B11_8));
+	    gen_st_drN(cpu_DT[0], cpu_env, DREG(B11_8));
 	}
 	else {
-	    gen_op_fmov_FT0_frN(FREG(B11_8));
+	    gen_st_frN(cpu_FT[0], cpu_env, FREG(B11_8));
 	}
 	return;
     }

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-09-01 22:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-30 19:36 [Qemu-devel] [PATCH] SH4: convert fmov/fadd to TCG Shin-ichiro KAWASAKI
2008-08-30 20:23 ` Blue Swirl
2008-08-31 17:28   ` Shin-ichiro KAWASAKI
2008-08-31 18:28     ` Blue Swirl
2008-08-31 19:32     ` Aurelien Jarno
2008-09-01 22:11       ` Aurelien Jarno

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).