qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [5124] SH4: convert floating-point ops to TCG


From: Aurelien Jarno
Subject: [Qemu-devel] [5124] SH4: convert floating-point ops to TCG
Date: Mon, 01 Sep 2008 22:11:58 +0000

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

Log Message:
-----------
SH4: convert floating-point ops to TCG

Signed-off-by: Aurelien Jarno <address@hidden>

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

Removed Paths:
-------------
    trunk/target-sh4/op_mem.c

Modified: trunk/target-sh4/helper.h
===================================================================
--- trunk/target-sh4/helper.h   2008-09-01 19:35:29 UTC (rev 5123)
+++ trunk/target-sh4/helper.h   2008-09-01 22:11:56 UTC (rev 5124)
@@ -19,3 +19,27 @@
 DEF_HELPER(void, helper_macw, (uint32_t, uint32_t))
 
 DEF_HELPER(void, helper_ld_fpscr, (uint32_t))
+
+DEF_HELPER(uint32_t, helper_fabs_FT, (uint32_t))
+DEF_HELPER(uint64_t, helper_fabs_DT, (uint64_t))
+DEF_HELPER(uint32_t, helper_fadd_FT, (uint32_t, uint32_t))
+DEF_HELPER(uint64_t, helper_fadd_DT, (uint64_t, uint64_t))
+DEF_HELPER(uint64_t, helper_fcnvsd_FT_DT, (uint32_t))
+DEF_HELPER(uint32_t, helper_fcnvds_DT_FT, (uint64_t))
+
+DEF_HELPER(void, helper_fcmp_eq_FT, (uint32_t, uint32_t))
+DEF_HELPER(void, helper_fcmp_eq_DT, (uint64_t, uint64_t))
+DEF_HELPER(void, helper_fcmp_gt_FT, (uint32_t, uint32_t))
+DEF_HELPER(void, helper_fcmp_gt_DT, (uint64_t, uint64_t))
+DEF_HELPER(uint32_t, helper_fdiv_FT, (uint32_t, uint32_t))
+DEF_HELPER(uint64_t, helper_fdiv_DT, (uint64_t, uint64_t))
+DEF_HELPER(uint32_t, helper_float_FT, (uint32_t))
+DEF_HELPER(uint64_t, helper_float_DT, (uint32_t))
+DEF_HELPER(uint32_t, helper_fmul_FT, (uint32_t, uint32_t))
+DEF_HELPER(uint64_t, helper_fmul_DT, (uint64_t, uint64_t))
+DEF_HELPER(uint32_t, helper_fsub_FT, (uint32_t, uint32_t))
+DEF_HELPER(uint64_t, helper_fsub_DT, (uint64_t, uint64_t))
+DEF_HELPER(uint32_t, helper_fsqrt_FT, (uint32_t))
+DEF_HELPER(uint64_t, helper_fsqrt_DT, (uint64_t))
+DEF_HELPER(uint32_t, helper_ftrc_FT, (uint32_t))
+DEF_HELPER(uint32_t, helper_ftrc_DT, (uint64_t))

Modified: trunk/target-sh4/op.c
===================================================================
--- trunk/target-sh4/op.c       2008-09-01 19:35:29 UTC (rev 5123)
+++ trunk/target-sh4/op.c       2008-09-01 22:11:56 UTC (rev 5124)
@@ -19,238 +19,9 @@
  */
 #include "exec.h"
 
-static inline void set_t(void)
-{
-    env->sr |= SR_T;
-}
-
-static inline void clr_t(void)
-{
-    env->sr &= ~SR_T;
-}
-
-static inline void cond_t(int cond)
-{
-    if (cond)
-       set_t();
-    else
-       clr_t();
-}
-
-void OPPROTO op_fmov_frN_FT0(void)
-{
-    FT0 = env->fregs[PARAM1];
-    RETURN();
-}
-
-void OPPROTO op_fmov_drN_DT0(void)
-{
-    CPU_DoubleU d;
-
-    d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
-    d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
-    DT0 = d.d;
-    RETURN();
-}
-
-void OPPROTO op_fmov_frN_FT1(void)
-{
-    FT1 = env->fregs[PARAM1];
-    RETURN();
-}
-
-void OPPROTO op_fmov_drN_DT1(void)
-{
-    CPU_DoubleU d;
-
-    d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
-    d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
-    DT1 = d.d;
-    RETURN();
-}
-
-void OPPROTO op_fmov_FT0_frN(void)
-{
-    env->fregs[PARAM1] = FT0;
-    RETURN();
-}
-
-void OPPROTO op_fmov_DT0_drN(void)
-{
-    CPU_DoubleU d;
-
-    d.d = DT0;
-    *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
-    *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
-    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);
-    RETURN();
-}
-
-void OPPROTO op_fsub_DT(void)
-{
-    DT0 = float64_sub(DT0, DT1, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fmul_FT(void)
-{
-    FT0 = float32_mul(FT0, FT1, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fmul_DT(void)
-{
-    DT0 = float64_mul(DT0, DT1, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fdiv_FT(void)
-{
-    FT0 = float32_div(FT0, FT1, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fdiv_DT(void)
-{
-    DT0 = float64_div(DT0, DT1, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fcmp_eq_FT(void)
-{
-    cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
-    RETURN();
-}
-
-void OPPROTO op_fcmp_eq_DT(void)
-{
-    cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
-    RETURN();
-}
-
-void OPPROTO op_fcmp_gt_FT(void)
-{
-    cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
-    RETURN();
-}
-
-void OPPROTO op_fcmp_gt_DT(void)
-{
-    cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
-    RETURN();
-}
-
-void OPPROTO op_float_FT(void)
-{
-    FT0 = int32_to_float32(env->fpul, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_float_DT(void)
-{
-    DT0 = int32_to_float64(env->fpul, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_ftrc_FT(void)
-{
-    env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_ftrc_DT(void)
-{
-    env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
-    RETURN();
-}
-
 void OPPROTO op_fneg_frN(void)
 {
     env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
     RETURN();
 }
 
-void OPPROTO op_fabs_FT(void)
-{
-    FT0 = float32_abs(FT0);
-    RETURN();
-}
-
-void OPPROTO op_fabs_DT(void)
-{
-    DT0 = float64_abs(DT0);
-    RETURN();
-}
-
-void OPPROTO op_fcnvsd_FT_DT(void)
-{
-    DT0 = float32_to_float64(FT0, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fcnvds_DT_FT(void)
-{
-    FT0 = float64_to_float32(DT0, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fsqrt_FT(void)
-{
-    FT0 = float32_sqrt(FT0, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fsqrt_DT(void)
-{
-    DT0 = float64_sqrt(DT0, &env->fp_status);
-    RETURN();
-}
-
-void OPPROTO op_fmov_T0_frN(void)
-{
-    *(uint32_t *)&env->fregs[PARAM1] = T0;
-    RETURN();
-}
-
-void OPPROTO op_movl_fpul_FT0(void)
-{
-    FT0 = *(float32 *)&env->fpul;
-    RETURN();
-}
-
-void OPPROTO op_movl_FT0_fpul(void)
-{
-    *(float32 *)&env->fpul = FT0;
-    RETURN();
-}
-
-/* Load and store */
-#define MEMSUFFIX _raw
-#include "op_mem.c"
-#undef MEMSUFFIX
-#if !defined(CONFIG_USER_ONLY)
-#define MEMSUFFIX _user
-#include "op_mem.c"
-#undef MEMSUFFIX
-
-#define MEMSUFFIX _kernel
-#include "op_mem.c"
-#undef MEMSUFFIX
-#endif

Modified: trunk/target-sh4/op_helper.c
===================================================================
--- trunk/target-sh4/op_helper.c        2008-09-01 19:35:29 UTC (rev 5123)
+++ trunk/target-sh4/op_helper.c        2008-09-01 22:11:56 UTC (rev 5124)
@@ -366,6 +366,16 @@
     return arg1;
 }
 
+static inline void set_t(void)
+{
+    env->sr |= SR_T;
+}
+
+static inline void clr_t(void)
+{
+    env->sr &= ~SR_T;
+}
+
 void helper_ld_fpscr(uint32_t val)
 {
     env->fpscr = val & 0x003fffff;
@@ -374,3 +384,141 @@
     else
        set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
 }
+
+uint32_t helper_fabs_FT(uint32_t t0)
+{
+    float32 ret = float32_abs(*(float32*)&t0);
+    return *(uint32_t*)(&ret);
+}
+
+uint64_t helper_fabs_DT(uint64_t t0)
+{
+    float64 ret = float64_abs(*(float64*)&t0);
+    return *(uint64_t*)(&ret);
+}
+
+uint32_t helper_fadd_FT(uint32_t t0, uint32_t t1)
+{
+    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)
+{
+    float64 ret = float64_add(*(float64*)&t0, *(float64*)&t1, &env->fp_status);
+    return *(uint64_t*)(&ret);
+}
+
+void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1)
+{
+    if (float32_compare(*(float32*)&t0, *(float32*)&t1, &env->fp_status) == 0)
+       set_t();
+    else
+       clr_t();
+}
+
+void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1)
+{
+    if (float64_compare(*(float64*)&t0, *(float64*)&t1, &env->fp_status) == 0)
+       set_t();
+    else
+       clr_t();
+}
+
+void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1)
+{
+    if (float32_compare(*(float32*)&t0, *(float32*)&t1, &env->fp_status) == 1)
+       set_t();
+    else
+       clr_t();
+}
+
+void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1)
+{
+    if (float64_compare(*(float64*)&t0, *(float64*)&t1, &env->fp_status) == 1)
+       set_t();
+    else
+       clr_t();
+}
+
+uint64_t helper_fcnvsd_FT_DT(uint32_t t0)
+{
+    float64 ret = float32_to_float64(*(float32*)&t0, &env->fp_status);
+    return *(uint64_t*)(&ret);
+}
+
+uint32_t helper_fcnvds_DT_FT(uint64_t t0)
+{
+    float32 ret = float64_to_float32(*(float64*)&t0, &env->fp_status);
+    return *(uint32_t*)(&ret);
+}
+
+uint32_t helper_fdiv_FT(uint32_t t0, uint32_t t1)
+{
+    float32 ret = float32_div(*(float32*)&t0, *(float32*)&t1, &env->fp_status);
+    return *(uint32_t*)(&ret);
+}
+
+uint64_t helper_fdiv_DT(uint64_t t0, uint64_t t1)
+{
+    float64 ret = float64_div(*(float64*)&t0, *(float64*)&t1, &env->fp_status);
+    return *(uint64_t*)(&ret);
+}
+
+uint32_t helper_float_FT(uint32_t t0)
+{
+    float32 ret = int32_to_float32(t0, &env->fp_status);
+    return *(uint32_t*)(&ret);
+}
+
+uint64_t helper_float_DT(uint32_t t0)
+{
+    float64 ret = int32_to_float64(t0, &env->fp_status);
+    return *(uint64_t*)(&ret);
+}
+
+uint32_t helper_fmul_FT(uint32_t t0, uint32_t t1)
+{
+    float32 ret = float32_mul(*(float32*)&t0, *(float32*)&t1, &env->fp_status);
+    return *(uint32_t*)(&ret);
+}
+
+uint64_t helper_fmul_DT(uint64_t t0, uint64_t t1)
+{
+    float64 ret = float64_mul(*(float64*)&t0, *(float64*)&t1, &env->fp_status);
+    return *(uint64_t*)(&ret);
+}
+
+uint32_t helper_fsqrt_FT(uint32_t t0)
+{
+    float32 ret = float32_sqrt(*(float32*)&t0, &env->fp_status);
+    return *(uint32_t*)(&ret);
+}
+
+uint64_t helper_fsqrt_DT(uint64_t t0)
+{
+    float64 ret = float64_sqrt(*(float64*)&t0, &env->fp_status);
+    return *(uint64_t*)(&ret);
+}
+
+uint32_t helper_fsub_FT(uint32_t t0, uint32_t t1)
+{
+    float32 ret = float32_sub(*(float32*)&t0, *(float32*)&t1, &env->fp_status);
+    return *(uint32_t*)(&ret);
+}
+
+uint64_t helper_fsub_DT(uint64_t t0, uint64_t t1)
+{
+    float64 ret = float64_sub(*(float64*)&t0, *(float64*)&t1, &env->fp_status);
+    return *(uint64_t*)(&ret);
+}
+
+uint32_t helper_ftrc_FT(uint32_t t0)
+{
+    return float32_to_int32_round_to_zero(*(float32*)&t0, &env->fp_status);
+}
+
+uint32_t helper_ftrc_DT(uint64_t t0)
+{
+    return float64_to_int32_round_to_zero(*(float64*)&t0, &env->fp_status);
+}

Deleted: trunk/target-sh4/op_mem.c
===================================================================
--- trunk/target-sh4/op_mem.c   2008-09-01 19:35:29 UTC (rev 5123)
+++ trunk/target-sh4/op_mem.c   2008-09-01 22:11:56 UTC (rev 5124)
@@ -1,38 +0,0 @@
-/*
- *  SH4 emulation
- *
- *  Copyright (c) 2005 Samuel Tardieu
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-void glue(op_ldfl_T0_FT0, MEMSUFFIX) (void) {
-    FT0 = glue(ldfl, MEMSUFFIX) (T0);
-    RETURN();
-}
-
-void glue(op_stfl_FT0_T1, MEMSUFFIX) (void) {
-    glue(stfl, MEMSUFFIX) (T1, FT0);
-    RETURN();
-}
-
-void glue(op_ldfq_T0_DT0, MEMSUFFIX) (void) {
-    DT0 = glue(ldfq, MEMSUFFIX) (T0);
-    RETURN();
-}
-
-void glue(op_stfq_DT0_T1, MEMSUFFIX) (void) {
-    glue(stfq, MEMSUFFIX) (T1, DT0);
-    RETURN();
-}

Modified: trunk/target-sh4/translate.c
===================================================================
--- trunk/target-sh4/translate.c        2008-09-01 19:35:29 UTC (rev 5123)
+++ trunk/target-sh4/translate.c        2008-09-01 22:11:56 UTC (rev 5124)
@@ -137,37 +137,6 @@
     done_init = 1;
 }
 
-#ifdef CONFIG_USER_ONLY
-
-#define GEN_OP_LD(width, reg) \
-  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
-    gen_op_ld##width##_T0_##reg##_raw(); \
-  }
-#define GEN_OP_ST(width, reg) \
-  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
-    gen_op_st##width##_##reg##_T1_raw(); \
-  }
-
-#else
-
-#define GEN_OP_LD(width, reg) \
-  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
-    if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
-    else gen_op_ld##width##_T0_##reg##_user();\
-  }
-#define GEN_OP_ST(width, reg) \
-  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
-    if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
-    else gen_op_st##width##_##reg##_T1_user();\
-  }
-
-#endif
-
-GEN_OP_LD(fl, FT0)
-GEN_OP_ST(fl, FT0)
-GEN_OP_LD(fq, DT0)
-GEN_OP_ST(fq, DT0)
-
 void cpu_dump_state(CPUState * env, FILE * f,
                    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
                    int flags)
@@ -361,6 +330,44 @@
     tcg_temp_free(tmp);
 }
 
+
+static inline void gen_load_fpr32(TCGv t, int reg)
+{
+    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
+}
+
+static inline void gen_load_fpr64(TCGv t, int reg)
+{
+    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32);
+    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
+
+    tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg]));
+    tcg_gen_extu_i32_i64(t, tmp1);
+    tcg_gen_shli_i64(t, t, 32);
+    tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg + 1]));
+    tcg_gen_extu_i32_i64(tmp2, tmp1);
+    tcg_temp_free(tmp1);
+    tcg_gen_or_i64(t, t, tmp2);
+    tcg_temp_free(tmp2);
+}
+
+static inline void gen_store_fpr32(TCGv t, int reg)
+{
+    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
+}
+
+static inline void gen_store_fpr64 (TCGv t, int reg)
+{
+    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
+
+    tcg_gen_trunc_i64_i32(tmp, t);
+    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg + 1]));
+    tcg_gen_shri_i64(t, t, 32);
+    tcg_gen_trunc_i64_i32(tmp, t);
+    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg]));
+    tcg_temp_free(tmp);
+}
+
 #define B3_0 (ctx->opcode & 0xf)
 #define B6_4 ((ctx->opcode >> 4) & 0x7)
 #define B7_4 ((ctx->opcode >> 4) & 0xf)
@@ -913,88 +920,115 @@
        return;
     case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
        if (ctx->fpscr & FPSCR_SZ) {
-           gen_op_fmov_drN_DT0(XREG(B7_4));
-           gen_op_fmov_DT0_drN(XREG(B11_8));
+           TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+           gen_load_fpr64(fp, XREG(B7_4));
+           gen_store_fpr64(fp, XREG(B11_8));
+           tcg_temp_free(fp);
        } else {
-           gen_op_fmov_frN_FT0(FREG(B7_4));
-           gen_op_fmov_FT0_frN(FREG(B11_8));
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           gen_load_fpr32(fp, FREG(B7_4));
+           gen_store_fpr32(fp, FREG(B11_8));
+           tcg_temp_free(fp);
        }
        return;
     case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
        if (ctx->fpscr & FPSCR_SZ) {
-           gen_op_fmov_drN_DT0(XREG(B7_4));
-           tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
-           gen_op_stfq_DT0_T1(ctx);
+           TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+           gen_load_fpr64(fp, XREG(B7_4));
+           tcg_gen_qemu_st64(fp, REG(B11_8), ctx->memidx);
+           tcg_temp_free(fp);
        } else {
-           gen_op_fmov_frN_FT0(FREG(B7_4));
-           tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
-           gen_op_stfl_FT0_T1(ctx);
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           gen_load_fpr32(fp, FREG(B7_4));
+           tcg_gen_qemu_st32(fp, REG(B11_8), ctx->memidx);
+           tcg_temp_free(fp);
        }
        return;
     case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
        if (ctx->fpscr & FPSCR_SZ) {
-           tcg_gen_mov_i32(cpu_T[0], REG(B7_4));
-           gen_op_ldfq_T0_DT0(ctx);
-           gen_op_fmov_DT0_drN(XREG(B11_8));
+           TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+           tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
+           gen_store_fpr64(fp, XREG(B11_8));
+           tcg_temp_free(fp);
        } else {
-           tcg_gen_mov_i32(cpu_T[0], REG(B7_4));
-           gen_op_ldfl_T0_FT0(ctx);
-           gen_op_fmov_FT0_frN(FREG(B11_8));
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
+           gen_store_fpr32(fp, FREG(B11_8));
+           tcg_temp_free(fp);
        }
        return;
     case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
        if (ctx->fpscr & FPSCR_SZ) {
-           tcg_gen_mov_i32(cpu_T[0], REG(B7_4));
-           gen_op_ldfq_T0_DT0(ctx);
-           gen_op_fmov_DT0_drN(XREG(B11_8));
-           tcg_gen_addi_i32(REG(B7_4),
-                            REG(B7_4), 8);
+           TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+           tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
+           gen_store_fpr64(fp, XREG(B11_8));
+           tcg_temp_free(fp);
+           tcg_gen_addi_i32(REG(B7_4),REG(B7_4), 8);
        } else {
-           tcg_gen_mov_i32(cpu_T[0], REG(B7_4));
-           gen_op_ldfl_T0_FT0(ctx);
-           gen_op_fmov_FT0_frN(FREG(B11_8));
-           tcg_gen_addi_i32(REG(B7_4),
-                            REG(B7_4), 4);
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
+           gen_store_fpr32(fp, FREG(B11_8));
+           tcg_temp_free(fp);
+           tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
        }
        return;
     case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
        if (ctx->fpscr & FPSCR_SZ) {
+           TCGv addr, fp;
+           addr = tcg_temp_new(TCG_TYPE_I32);
+           tcg_gen_subi_i32(addr, REG(B11_8), 8);
+           fp = tcg_temp_new(TCG_TYPE_I64);
+           gen_load_fpr64(fp, XREG(B7_4));
+           tcg_gen_qemu_st64(fp, addr, ctx->memidx);
+           tcg_temp_free(fp);
+           tcg_temp_free(addr);
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);
-           gen_op_fmov_drN_DT0(XREG(B7_4));
-           tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
-           tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 8);
-           gen_op_stfq_DT0_T1(ctx);
-           tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);
        } else {
+           TCGv addr, fp;
+           addr = tcg_temp_new(TCG_TYPE_I32);
+           tcg_gen_subi_i32(addr, REG(B11_8), 4);
+           fp = tcg_temp_new(TCG_TYPE_I32);
+           gen_load_fpr32(fp, FREG(B7_4));
+           tcg_gen_qemu_st32(fp, addr, ctx->memidx);
+           tcg_temp_free(fp);
+           tcg_temp_free(addr);
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
-           gen_op_fmov_frN_FT0(FREG(B7_4));
-           tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
-           tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
-           gen_op_stfl_FT0_T1(ctx);
-           tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
        }
        return;
     case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
-       tcg_gen_add_i32(cpu_T[0], REG(B7_4), REG(0));
-       if (ctx->fpscr & FPSCR_SZ) {
-           gen_op_ldfq_T0_DT0(ctx);
-           gen_op_fmov_DT0_drN(XREG(B11_8));
-       } else {
-           gen_op_ldfl_T0_FT0(ctx);
-           gen_op_fmov_FT0_frN(FREG(B11_8));
+       {
+           TCGv addr = tcg_temp_new(TCG_TYPE_I32);
+           tcg_gen_add_i32(addr, REG(B7_4), REG(0));
+           if (ctx->fpscr & FPSCR_SZ) {
+               TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+               tcg_gen_qemu_ld64(fp, addr, ctx->memidx);
+               gen_store_fpr64(fp, XREG(B11_8));
+               tcg_temp_free(fp);
+           } else {
+               TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+               tcg_gen_qemu_ld32u(fp, addr, ctx->memidx);
+               gen_store_fpr32(fp, FREG(B11_8));
+               tcg_temp_free(fp);
+           }
+           tcg_temp_free(addr);
        }
        return;
     case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
-       if (ctx->fpscr & FPSCR_SZ) {
-           gen_op_fmov_drN_DT0(XREG(B7_4));
-           tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
-           tcg_gen_add_i32(cpu_T[1], cpu_T[1], REG(0));
-           gen_op_stfq_DT0_T1(ctx);
-       } else {
-           gen_op_fmov_frN_FT0(FREG(B7_4));
-           tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
-           tcg_gen_add_i32(cpu_T[1], cpu_T[1], REG(0));
-           gen_op_stfl_FT0_T1(ctx);
+       {
+           TCGv addr = tcg_temp_new(TCG_TYPE_I32);
+           tcg_gen_add_i32(addr, REG(B11_8), REG(0));
+           if (ctx->fpscr & FPSCR_SZ) {
+               TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+               gen_load_fpr64(fp, XREG(B7_4));
+               tcg_gen_qemu_st64(fp, addr, ctx->memidx);
+               tcg_temp_free(fp);
+           } else {
+               TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+               gen_load_fpr32(fp, FREG(B7_4));
+               tcg_gen_qemu_st32(fp, addr, ctx->memidx);
+               tcg_temp_free(fp);
+           }
+           tcg_temp_free(addr);
        }
        return;
     case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
@@ -1003,44 +1037,72 @@
     case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
     case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
     case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
-       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));
-       }
-       else {
-           gen_op_fmov_frN_FT1(FREG(B7_4));
-           gen_op_fmov_frN_FT0(FREG(B11_8));
-       }
+       {
+           TCGv fp0, fp1;
 
-       switch (ctx->opcode & 0xf00f) {
-       case 0xf000:            /* fadd Rm,Rn */
-           ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
-           break;
-       case 0xf001:            /* fsub Rm,Rn */
-           ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
-           break;
-       case 0xf002:            /* fmul Rm,Rn */
-           ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
-           break;
-       case 0xf003:            /* fdiv Rm,Rn */
-           ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
-           break;
-       case 0xf004:            /* fcmp/eq Rm,Rn */
-           ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
-           return;
-       case 0xf005:            /* fcmp/gt Rm,Rn */
-           ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
-           return;
-       }
+           if (ctx->fpscr & FPSCR_PR) {
+               if (ctx->opcode & 0x0110)
+                   break; /* illegal instruction */
+               fp0 = tcg_temp_new(TCG_TYPE_I64);
+               fp1 = tcg_temp_new(TCG_TYPE_I64);
+               gen_load_fpr64(fp0, DREG(B11_8));
+               gen_load_fpr64(fp1, DREG(B7_4));
+           }
+           else {
+               fp0 = tcg_temp_new(TCG_TYPE_I32);
+               fp1 = tcg_temp_new(TCG_TYPE_I32);
+               gen_load_fpr32(fp0, FREG(B11_8));
+               gen_load_fpr32(fp1, FREG(B7_4));
+           }
 
-       if (ctx->fpscr & FPSCR_PR) {
-           gen_op_fmov_DT0_drN(DREG(B11_8));
+           switch (ctx->opcode & 0xf00f) {
+           case 0xf000:                /* fadd Rm,Rn */
+               if (ctx->fpscr & FPSCR_PR)
+                   tcg_gen_helper_1_2(helper_fadd_DT, fp0, fp0, fp1);
+               else
+                   tcg_gen_helper_1_2(helper_fadd_FT, fp0, fp0, fp1);
+               break;
+           case 0xf001:                /* fsub Rm,Rn */
+               if (ctx->fpscr & FPSCR_PR)
+                   tcg_gen_helper_1_2(helper_fsub_DT, fp0, fp0, fp1);
+               else
+                   tcg_gen_helper_1_2(helper_fsub_FT, fp0, fp0, fp1);
+               break;
+           case 0xf002:                /* fmul Rm,Rn */
+               if (ctx->fpscr & FPSCR_PR)
+                   tcg_gen_helper_1_2(helper_fmul_DT, fp0, fp0, fp1);
+               else
+                   tcg_gen_helper_1_2(helper_fmul_FT, fp0, fp0, fp1);
+               break;
+           case 0xf003:                /* fdiv Rm,Rn */
+               if (ctx->fpscr & FPSCR_PR)
+                   tcg_gen_helper_1_2(helper_fdiv_DT, fp0, fp0, fp1);
+               else
+                   tcg_gen_helper_1_2(helper_fdiv_FT, fp0, fp0, fp1);
+               break;
+           case 0xf004:                /* fcmp/eq Rm,Rn */
+               if (ctx->fpscr & FPSCR_PR)
+                   tcg_gen_helper_0_2(helper_fcmp_eq_DT, fp0, fp1);
+               else
+                   tcg_gen_helper_0_2(helper_fcmp_eq_FT, fp0, fp1);
+               return;
+           case 0xf005:                /* fcmp/gt Rm,Rn */
+               if (ctx->fpscr & FPSCR_PR)
+                   tcg_gen_helper_0_2(helper_fcmp_gt_DT, fp0, fp1);
+               else
+                   tcg_gen_helper_0_2(helper_fcmp_gt_FT, fp0, fp1);
+               return;
+           }
+
+           if (ctx->fpscr & FPSCR_PR) {
+               gen_store_fpr64(fp0, DREG(B11_8));
+           }
+           else {
+               gen_store_fpr32(fp0, FREG(B11_8));
+           }
+           tcg_temp_free(fp1);
+           tcg_temp_free(fp0);
        }
-       else {
-           gen_op_fmov_FT0_frN(FREG(B11_8));
-       }
        return;
     }
 
@@ -1481,35 +1543,53 @@
        }
        return;
     case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
-       gen_op_movl_fpul_FT0();
-       gen_op_fmov_FT0_frN(FREG(B11_8));
+       {
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           tcg_gen_mov_i32(fp, cpu_fpul);
+           gen_store_fpr32(fp, FREG(B11_8));
+           tcg_temp_free(fp);
+       }
        return;
     case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
-       gen_op_fmov_frN_FT0(FREG(B11_8));
-       gen_op_movl_FT0_fpul();
+       {
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           gen_load_fpr32(fp, FREG(B11_8));
+           tcg_gen_mov_i32(cpu_fpul, fp);
+           tcg_temp_free(fp);
+       }
        return;
     case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
        if (ctx->fpscr & FPSCR_PR) {
+           TCGv fp;
            if (ctx->opcode & 0x0100)
                break; /* illegal instruction */
-           gen_op_float_DT();
-           gen_op_fmov_DT0_drN(DREG(B11_8));
+           fp = tcg_temp_new(TCG_TYPE_I64);
+           tcg_gen_helper_1_1(helper_float_DT, fp, cpu_fpul);
+           gen_store_fpr64(fp, DREG(B11_8));
+           tcg_temp_free(fp);
        }
        else {
-           gen_op_float_FT();
-           gen_op_fmov_FT0_frN(FREG(B11_8));
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           tcg_gen_helper_1_1(helper_float_FT, fp, cpu_fpul);
+           gen_store_fpr32(fp, FREG(B11_8));
+           tcg_temp_free(fp);
        }
        return;
     case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
        if (ctx->fpscr & FPSCR_PR) {
+           TCGv fp;
            if (ctx->opcode & 0x0100)
                break; /* illegal instruction */
-           gen_op_fmov_drN_DT0(DREG(B11_8));
-           gen_op_ftrc_DT();
+           fp = tcg_temp_new(TCG_TYPE_I64);
+           gen_load_fpr64(fp, DREG(B11_8));
+           tcg_gen_helper_1_1(helper_ftrc_DT, cpu_fpul, fp);
+           tcg_temp_free(fp);
        }
        else {
-           gen_op_fmov_frN_FT0(FREG(B11_8));
-           gen_op_ftrc_FT();
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           gen_load_fpr32(fp, FREG(B11_8));
+           tcg_gen_helper_1_1(helper_ftrc_FT, cpu_fpul, fp);
+           tcg_temp_free(fp);
        }
        return;
     case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
@@ -1519,53 +1599,69 @@
        if (ctx->fpscr & FPSCR_PR) {
            if (ctx->opcode & 0x0100)
                break; /* illegal instruction */
-           gen_op_fmov_drN_DT0(DREG(B11_8));
-           gen_op_fabs_DT();
-           gen_op_fmov_DT0_drN(DREG(B11_8));
+           TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+           gen_load_fpr64(fp, DREG(B11_8));
+           tcg_gen_helper_1_1(helper_fabs_DT, fp, fp);
+           gen_store_fpr64(fp, DREG(B11_8));
+           tcg_temp_free(fp);
        } else {
-           gen_op_fmov_frN_FT0(FREG(B11_8));
-           gen_op_fabs_FT();
-           gen_op_fmov_FT0_frN(FREG(B11_8));
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           gen_load_fpr32(fp, FREG(B11_8));
+           tcg_gen_helper_1_1(helper_fabs_FT, fp, fp);
+           gen_store_fpr32(fp, FREG(B11_8));
+           tcg_temp_free(fp);
        }
        return;
     case 0xf06d: /* fsqrt FRn */
        if (ctx->fpscr & FPSCR_PR) {
            if (ctx->opcode & 0x0100)
                break; /* illegal instruction */
-           gen_op_fmov_drN_DT0(FREG(B11_8));
-           gen_op_fsqrt_DT();
-           gen_op_fmov_DT0_drN(FREG(B11_8));
+           TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+           gen_load_fpr64(fp, DREG(B11_8));
+           tcg_gen_helper_1_1(helper_fsqrt_DT, fp, fp);
+           gen_store_fpr64(fp, DREG(B11_8));
+           tcg_temp_free(fp);
        } else {
-           gen_op_fmov_frN_FT0(FREG(B11_8));
-           gen_op_fsqrt_FT();
-           gen_op_fmov_FT0_frN(FREG(B11_8));
+           TCGv fp = tcg_temp_new(TCG_TYPE_I32);
+           gen_load_fpr32(fp, FREG(B11_8));
+           tcg_gen_helper_1_1(helper_fsqrt_FT, fp, fp);
+           gen_store_fpr32(fp, FREG(B11_8));
+           tcg_temp_free(fp);
        }
        return;
     case 0xf07d: /* fsrra FRn */
        break;
     case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
        if (!(ctx->fpscr & FPSCR_PR)) {
-           tcg_gen_movi_i32(cpu_T[0], 0);
-           gen_op_fmov_T0_frN(FREG(B11_8));
+           TCGv val = tcg_const_i32(0);
+           gen_load_fpr32(val, FREG(B11_8));
+           tcg_temp_free(val);
            return;
        }
        break;
     case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
        if (!(ctx->fpscr & FPSCR_PR)) {
-           tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
-           gen_op_fmov_T0_frN(FREG(B11_8));
+           TCGv val = tcg_const_i32(0x3f800000);
+           gen_load_fpr32(val, FREG(B11_8));
+           tcg_temp_free(val);
            return;
        }
        break;
     case 0xf0ad: /* fcnvsd FPUL,DRn */
-       gen_op_movl_fpul_FT0();
-       gen_op_fcnvsd_FT_DT();
-       gen_op_fmov_DT0_drN(DREG(B11_8));
+       {
+           TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+           tcg_gen_helper_1_1(helper_fcnvsd_FT_DT, fp, cpu_fpul);
+           gen_store_fpr64(fp, DREG(B11_8));
+           tcg_temp_free(fp);
+       }
        return;
     case 0xf0bd: /* fcnvds DRn,FPUL */
-       gen_op_fmov_drN_DT0(DREG(B11_8));
-       gen_op_fcnvds_DT_FT();
-       gen_op_movl_FT0_fpul();
+       {
+           TCGv fp = tcg_temp_new(TCG_TYPE_I64);
+           gen_load_fpr64(fp, DREG(B11_8));
+           tcg_gen_helper_1_1(helper_fcnvds_DT_FT, cpu_fpul, fp);
+           tcg_temp_free(fp);
+       }
        return;
     }
 






reply via email to

[Prev in Thread] Current Thread [Next in Thread]