CVSROOT:        /sources/qemu
Module name:    qemu
Changes by:     Fabrice Bellard <bellard>       06/06/14 15:02:06

Modified files:
        target-sh4     : cpu.h exec.h op.c op_mem.c translate.c 

Log message:
        sh4 fmov et al instructions (amatus)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sh4/cpu.h?cvsroot=qemu&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sh4/exec.h?cvsroot=qemu&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sh4/op.c?cvsroot=qemu&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sh4/op_mem.c?cvsroot=qemu&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sh4/translate.c?cvsroot=qemu&r1=1.1&r2=1.2

Patches:
Index: cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/cpu.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- cpu.h       27 Apr 2006 21:00:31 -0000      1.1
+++ cpu.h       14 Jun 2006 15:02:05 -0000      1.2
@@ -27,6 +27,8 @@
 
 #include "cpu-defs.h"
 
+#include "softfloat.h"
+
 #define TARGET_PAGE_BITS 12    /* 4k XXXXX */
 
 #define SR_MD (1 << 30)
@@ -90,6 +92,10 @@
     uint32_t fpscr;            /* floating point status/control register */
     uint32_t fpul;             /* floating point communication register */
 
+    /* temporary float registers */
+    float32 ft0, ft1;
+    float64 dt0, dt1;
+
     /* Those belong to the specific unit (SH7750) but are handled here */
     uint32_t mmucr;            /* MMU control register */
     uint32_t pteh;             /* page table entry high register */

Index: exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/exec.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- exec.h      27 Apr 2006 21:00:31 -0000      1.1
+++ exec.h      14 Jun 2006 15:02:05 -0000      1.2
@@ -28,6 +28,11 @@
 register uint32_t T1 asm(AREG2);
 register uint32_t T2 asm(AREG3);
 
+#define FT0 (env->ft0)
+#define FT1 (env->ft1)
+#define DT0 (env->dt0)
+#define DT1 (env->dt1)
+
 #include "cpu.h"
 #include "exec-all.h"
 

Index: op.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/op.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- op.c        27 Apr 2006 21:00:31 -0000      1.1
+++ op.c        14 Jun 2006 15:02:05 -0000      1.2
@@ -228,6 +228,18 @@
     RETURN();
 }
 
+void OPPROTO op_frchg(void)
+{
+    env->fpscr ^= FPSCR_FR;
+    RETURN();
+}
+
+void OPPROTO op_fschg(void)
+{
+    env->fpscr ^= FPSCR_SZ;
+    RETURN();
+}
+
 void OPPROTO op_rte(void)
 {
     env->sr = env->ssr;
@@ -465,6 +477,18 @@
     RETURN();
 }
 
+void OPPROTO op_ldc_T0_sr(void)
+{
+    env->sr = T0 & 0x700083f3;
+    RETURN();
+}
+
+void OPPROTO op_stc_sr_T0(void)
+{
+    T0 = env->sr;
+    RETURN();
+}
+
 #define LDSTOPS(target,load,store) \
 void OPPROTO op_##load##_T0_##target (void) \
 { env ->target = T0;   RETURN(); \
@@ -473,7 +497,6 @@
 { T0 = env->target;   RETURN(); \
 } \
 
-LDSTOPS(sr, ldc, stc)
     LDSTOPS(gbr, ldc, stc)
     LDSTOPS(vbr, ldc, stc)
     LDSTOPS(ssr, ldc, stc)
@@ -483,6 +506,19 @@
     LDSTOPS(mach, lds, sts)
     LDSTOPS(macl, lds, sts)
     LDSTOPS(pr, lds, sts)
+    LDSTOPS(fpul, lds, sts)
+
+void OPPROTO op_lds_T0_fpscr(void)
+{
+    env->fpscr = T0 & 0x003fffff;
+    RETURN();
+}
+
+void OPPROTO op_sts_fpscr_T0(void)
+{
+    T0 = env->fpscr & 0x003fffff;
+    RETURN();
+}
 
 void OPPROTO op_movt_rN(void)
 {
@@ -659,6 +695,30 @@
     RETURN();
 }
 
+void OPPROTO op_fmov_frN_FT0(void)
+{
+    FT0 = *(float32 *)&env->fregs[PARAM1];
+    RETURN();
+}
+
+void OPPROTO op_fmov_drN_DT0(void)
+{
+    DT0 = *(float64 *)&env->fregs[PARAM1];
+    RETURN();
+}
+
+void OPPROTO op_fmov_FT0_frN(void)
+{
+    *(float32 *)&env->fregs[PARAM1] = FT0;
+    RETURN();
+}
+
+void OPPROTO op_fmov_DT0_drN(void)
+{
+    *(float64 *)&env->fregs[PARAM1] = DT0;
+    RETURN();
+}
+
 void OPPROTO op_dec1_rN(void)
 {
     env->gregs[PARAM1] -= 1;
@@ -677,6 +737,12 @@
     RETURN();
 }
 
+void OPPROTO op_dec8_rN(void)
+{
+    env->gregs[PARAM1] -= 4;
+    RETURN();
+}
+
 void OPPROTO op_inc1_rN(void)
 {
     env->gregs[PARAM1] += 1;
@@ -695,6 +761,12 @@
     RETURN();
 }
 
+void OPPROTO op_inc8_rN(void)
+{
+    env->gregs[PARAM1] += 4;
+    RETURN();
+}
+
 void OPPROTO op_add_T0_rN(void)
 {
     env->gregs[PARAM1] += T0;
@@ -779,6 +851,18 @@
     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();
+}
+
 void OPPROTO op_goto_tb0(void)
 {
     GOTO_TB(op_goto_tb0, PARAM1, 0);

Index: op_mem.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/op_mem.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- op_mem.c    27 Apr 2006 21:00:31 -0000      1.1
+++ op_mem.c    14 Jun 2006 15:02:05 -0000      1.2
@@ -56,3 +56,23 @@
     glue(stl, MEMSUFFIX) (T1, T0);
     RETURN();
 }
+
+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();
+}

Index: translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/translate.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- translate.c 27 Apr 2006 21:00:31 -0000      1.1
+++ translate.c 14 Jun 2006 15:02:05 -0000      1.2
@@ -54,6 +54,7 @@
     struct TranslationBlock *tb;
     target_ulong pc;
     uint32_t sr;
+    uint32_t fpscr;
     uint16_t opcode;
     uint32_t flags;
     int memidx;
@@ -63,46 +64,50 @@
 
 #ifdef CONFIG_USER_ONLY
 
-#define GEN_OP_LD(width) \
-  void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \
-    gen_op_ld##width##_T0_T0_raw(); \
-  }
-#define GEN_OP_ST(width) \
-  void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \
-    gen_op_st##width##_T0_T1_raw(); \
+#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) \
-  void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \
-    if (ctx->memidx) gen_op_ld##width##_T0_T0_kernel(); \
-    else gen_op_ld##width##_T0_T0_user();\
-  }
-#define GEN_OP_ST(width) \
-  void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \
-    if (ctx->memidx) gen_op_st##width##_T0_T1_kernel(); \
-    else gen_op_st##width##_T0_T1_user();\
+#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(ub)
-    GEN_OP_LD(b)
-    GEN_OP_ST(b)
-    GEN_OP_LD(uw)
-    GEN_OP_LD(w)
-    GEN_OP_ST(w)
-    GEN_OP_LD(l)
-    GEN_OP_ST(l)
+GEN_OP_LD(ub, T0)
+GEN_OP_LD(b, T0)
+GEN_OP_ST(b, T0)
+GEN_OP_LD(uw, T0)
+GEN_OP_LD(w, T0)
+GEN_OP_ST(w, T0)
+GEN_OP_LD(l, T0)
+GEN_OP_ST(l, T0)
+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)
 {
     int i;
-    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x\n",
-               env->pc, env->sr, env->pr);
+    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
+               env->pc, env->sr, env->pr, env->fpscr);
     for (i = 0; i < 24; i += 4) {
        cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
                    i, env->gregs[i], i + 1, env->gregs[i + 1],
@@ -242,6 +247,10 @@
 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
                ? (x) + 16 : (x))
 
+#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
+#define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1)
+#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
+
 #define CHECK_NOT_DELAY_SLOT \
   if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
   {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
@@ -286,10 +295,12 @@
        gen_op_sett();
        return;
     case 0xfbfb:               /* frchg */
-       assert(0);              /* XXXXX */
+       gen_op_frchg();
+       ctx->flags |= MODE_CHANGE;
        return;
     case 0xf3fb:               /* fschg */
-       assert(0);              /* XXXXX */
+       gen_op_fschg();
+       ctx->flags |= MODE_CHANGE;
        return;
     case 0x0009:               /* nop */
        return;
@@ -393,7 +404,7 @@
        gen_op_movl_rN_T1(REG(B11_8));
        gen_op_stl_T0_T1(ctx);
        return;
-    case 0x6004:               /* mov.l @Rm+,Rn */
+    case 0x6004:               /* mov.b @Rm+,Rn */
        gen_op_movl_rN_T0(REG(B7_4));
        gen_op_ldb_T0_T0(ctx);
        gen_op_movl_T0_rN(REG(B11_8));
@@ -643,6 +654,134 @@
        gen_op_movl_rN_T0(REG(B7_4));
        gen_op_xor_T0_rN(REG(B11_8));
        return;
+    case 0xf00c:               /* fmov {F,D,X}Rm,{F,D,X}Rn */
+       if (ctx->fpscr & FPSCR_PR) {
+           gen_op_fmov_drN_DT0(XREG(B7_4));
+           gen_op_fmov_DT0_drN(XREG(B11_8));
+       } else if (ctx->fpscr & FPSCR_SZ) {
+           if (ctx->opcode & 0x0110)
+               break; /* illegal instruction */
+           gen_op_fmov_drN_DT0(XREG(B7_4));
+           gen_op_fmov_DT0_drN(XREG(B11_8));
+       } else {
+           gen_op_fmov_frN_FT0(FREG(B7_4));
+           gen_op_fmov_FT0_frN(FREG(B11_8));
+       }
+       return;
+    case 0xf00a:               /* fmov {F,D,X}Rm,@Rn */
+       if (ctx->fpscr & FPSCR_PR) {
+           gen_op_fmov_drN_DT0(XREG(B7_4));
+           gen_op_movl_rN_T1(REG(B11_8));
+           gen_op_stfq_DT0_T1(ctx);
+       } else if (ctx->fpscr & FPSCR_SZ) {
+           if (ctx->opcode & 0x0010)
+               break; /* illegal instruction */
+           gen_op_fmov_drN_DT0(XREG(B7_4));
+           gen_op_movl_rN_T1(REG(B11_8));
+           gen_op_stfq_DT0_T1(ctx);
+       } else {
+           gen_op_fmov_frN_FT0(FREG(B7_4));
+           gen_op_movl_rN_T1(REG(B11_8));
+           gen_op_stfl_FT0_T1(ctx);
+       }
+       return;
+    case 0xf008:               /* fmov @Rm,{F,D,X}Rn */
+       if (ctx->fpscr & FPSCR_PR) {
+           gen_op_movl_rN_T0(REG(B7_4));
+           gen_op_ldfq_T0_DT0(ctx);
+           gen_op_fmov_DT0_drN(XREG(B11_8));
+       } else if (ctx->fpscr & FPSCR_SZ) {
+           if (ctx->opcode & 0x0100)
+               break; /* illegal instruction */
+           gen_op_movl_rN_T0(REG(B7_4));
+           gen_op_ldfq_T0_DT0(ctx);
+           gen_op_fmov_DT0_drN(XREG(B11_8));
+       } else {
+           gen_op_movl_rN_T0(REG(B7_4));
+           gen_op_ldfl_T0_FT0(ctx);
+           gen_op_fmov_FT0_frN(XREG(B11_8));
+       }
+       return;
+    case 0xf009:               /* fmov @Rm+,{F,D,X}Rn */
+       if (ctx->fpscr & FPSCR_PR) {
+           gen_op_movl_rN_T0(REG(B7_4));
+           gen_op_ldfq_T0_DT0(ctx);
+           gen_op_fmov_DT0_drN(XREG(B11_8));
+           gen_op_inc8_rN(REG(B7_4));
+       } else if (ctx->fpscr & FPSCR_SZ) {
+           if (ctx->opcode & 0x0100)
+               break; /* illegal instruction */
+           gen_op_movl_rN_T0(REG(B7_4));
+           gen_op_ldfq_T0_DT0(ctx);
+           gen_op_fmov_DT0_drN(XREG(B11_8));
+           gen_op_inc8_rN(REG(B7_4));
+       } else {
+           gen_op_movl_rN_T0(REG(B7_4));
+           gen_op_ldfl_T0_FT0(ctx);
+           gen_op_fmov_FT0_frN(XREG(B11_8));
+           gen_op_inc4_rN(REG(B7_4));
+       }
+       return;
+    case 0xf00b:               /* fmov {F,D,X}Rm,@-Rn */
+       if (ctx->fpscr & FPSCR_PR) {
+           gen_op_dec8_rN(REG(B11_8));
+           gen_op_fmov_drN_DT0(XREG(B7_4));
+           gen_op_movl_rN_T1(REG(B11_8));
+           gen_op_stfq_DT0_T1(ctx);
+       } else if (ctx->fpscr & FPSCR_SZ) {
+           if (ctx->opcode & 0x0100)
+               break; /* illegal instruction */
+           gen_op_dec8_rN(REG(B11_8));
+           gen_op_fmov_drN_DT0(XREG(B7_4));
+           gen_op_movl_rN_T1(REG(B11_8));
+           gen_op_stfq_DT0_T1(ctx);
+       } else {
+           gen_op_dec4_rN(REG(B11_8));
+           gen_op_fmov_frN_FT0(FREG(B7_4));
+           gen_op_movl_rN_T1(REG(B11_8));
+           gen_op_stfl_FT0_T1(ctx);
+       }
+       return;
+    case 0xf006:               /* fmov @(R0,Rm),{F,D,X}Rm */
+       if (ctx->fpscr & FPSCR_PR) {
+           gen_op_movl_rN_T0(REG(B7_4));
+           gen_op_add_rN_T0(REG(0));
+           gen_op_ldfq_T0_DT0(ctx);
+           gen_op_fmov_DT0_drN(XREG(B11_8));
+       } else if (ctx->fpscr & FPSCR_SZ) {
+           if (ctx->opcode & 0x0100)
+               break; /* illegal instruction */
+           gen_op_movl_rN_T0(REG(B7_4));
+           gen_op_add_rN_T0(REG(0));
+           gen_op_ldfq_T0_DT0(ctx);
+           gen_op_fmov_DT0_drN(XREG(B11_8));
+       } else {
+           gen_op_movl_rN_T0(REG(B7_4));
+           gen_op_add_rN_T0(REG(0));
+           gen_op_ldfl_T0_FT0(ctx);
+           gen_op_fmov_FT0_frN(XREG(B11_8));
+       }
+       return;
+    case 0xf007:               /* fmov {F,D,X}Rn,@(R0,Rn) */
+       if (ctx->fpscr & FPSCR_PR) {
+           gen_op_fmov_drN_DT0(XREG(B7_4));
+           gen_op_movl_rN_T1(REG(B11_8));
+           gen_op_add_rN_T1(REG(0));
+           gen_op_stfq_DT0_T1(ctx);
+       } else if (ctx->fpscr & FPSCR_SZ) {
+           if (ctx->opcode & 0x0010)
+               break; /* illegal instruction */
+           gen_op_fmov_drN_DT0(XREG(B7_4));
+           gen_op_movl_rN_T1(REG(B11_8));
+           gen_op_add_rN_T1(REG(0));
+           gen_op_stfq_DT0_T1(ctx);
+       } else {
+           gen_op_fmov_frN_FT0(FREG(B7_4));
+           gen_op_movl_rN_T1(REG(B11_8));
+           gen_op_add_rN_T1(REG(0));
+           gen_op_stfl_FT0_T1(ctx);
+       }
+       return;
     }
 
     switch (ctx->opcode & 0xff00) {
@@ -869,8 +1008,7 @@
     gen_op_stl_T0_T1 (ctx);                                    \
     return;
        LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
-            MODE_CHANGE;
-           )
+            MODE_CHANGE;)
            LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
            LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
            LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
@@ -879,6 +1017,9 @@
            LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
            LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
            LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
+       LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x0052, sts,)
+       LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x0062, sts, ctx->flags |=
+            MODE_CHANGE;)
     case 0x00c3:               /* movca.l R0,@Rm */
        gen_op_movl_rN_T0(REG(0));
        gen_op_movl_rN_T1(REG(B11_8));
@@ -944,6 +1085,14 @@
     case 0x401b:               /* tas.b @Rn */
        gen_op_tasb_rN(REG(B11_8));
        return;
+    case 0xf00d:               /* fsts FPUL,FRn */
+       gen_op_movl_fpul_FT0();
+       gen_op_fmov_FT0_frN(FREG(B11_8));
+       return;
+    case 0xf01d:               /* flds FRm.FPUL */
+       gen_op_fmov_frN_FT0(FREG(B11_8));
+       gen_op_movl_FT0_fpul();
+       return;
     }
 
     fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
@@ -969,6 +1118,7 @@
     ctx.flags = env->flags;
     old_flags = 0;
     ctx.sr = env->sr;
+    ctx.fpscr = env->fpscr;
     ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
     ctx.delayed_pc = env->delayed_pc;
     ctx.tb = tb;


_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to