Fix indexed FP load/store instructions.
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 20 May 2007 01:36:29 +0000 (01:36 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 20 May 2007 01:36:29 +0000 (01:36 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2837 c046a42c-6fe2-441c-8c8c-71466251a162

target-mips/op.c
target-mips/op_mem.c
target-mips/translate.c

index 8c0c687..9ba0050 100644 (file)
@@ -3,6 +3,7 @@
  * 
  *  Copyright (c) 2004-2005 Jocelyn Mayer
  *  Copyright (c) 2006 Marius Groeger (FPU operations)
+ *  Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
index f0eebc0..f9fc69c 100644 (file)
@@ -220,35 +220,13 @@ void glue(op_sdc1, MEMSUFFIX) (void)
     glue(stq, MEMSUFFIX)(T0, DT0);
     RETURN();
 }
-void glue(op_lwxc1, MEMSUFFIX) (void)
-{
-    WT0 = glue(ldl, MEMSUFFIX)(T0 + T1);
-    RETURN();
-}
-void glue(op_swxc1, MEMSUFFIX) (void)
-{
-    glue(stl, MEMSUFFIX)(T0 + T1, WT0);
-    RETURN();
-}
-void glue(op_ldxc1, MEMSUFFIX) (void)
-{
-    DT0 = glue(ldq, MEMSUFFIX)(T0 + T1);
-    RETURN();
-}
-void glue(op_sdxc1, MEMSUFFIX) (void)
-{
-    glue(stq, MEMSUFFIX)(T0 + T1, DT0);
-    RETURN();
-}
 void glue(op_luxc1, MEMSUFFIX) (void)
 {
-    /* XXX: is defined as unaligned */
-    DT0 = glue(ldq, MEMSUFFIX)(T0 + T1);
+    DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7);
     RETURN();
 }
 void glue(op_suxc1, MEMSUFFIX) (void)
 {
-    /* XXX: is defined as unaligned */
-    glue(stq, MEMSUFFIX)(T0 + T1, DT0);
+    glue(stq, MEMSUFFIX)(T0 & ~0x7, DT0);
     RETURN();
 }
index 075be1e..03f802a 100644 (file)
@@ -711,10 +711,6 @@ OP_LD_TABLE(wc1);
 OP_ST_TABLE(wc1);
 OP_LD_TABLE(dc1);
 OP_ST_TABLE(dc1);
-OP_LD_TABLE(wxc1);
-OP_ST_TABLE(wxc1);
-OP_LD_TABLE(dxc1);
-OP_ST_TABLE(dxc1);
 OP_LD_TABLE(uxc1);
 OP_ST_TABLE(uxc1);
 
@@ -1092,7 +1088,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
         return;
     }
     GEN_STORE_TN_REG(rt, T0);
-    MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
+    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
 }
 
 /* Arithmetic */
@@ -5242,25 +5238,36 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
 
 /* Coprocessor 3 (FPU) */
 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
-                           int base, int index)
+                           int fs, int base, int index)
 {
     const char *opn = "extended float load/store";
+    int store = 0;
 
     /* All of those work only on 64bit FPUs. */
     gen_op_cp1_64bitmode();
-    GEN_LOAD_REG_TN(T0, base);
-    GEN_LOAD_REG_TN(T1, index);
+    if (base == 0) {
+        if (index == 0)
+            gen_op_reset_T0();
+        else
+            GEN_LOAD_REG_TN(T0, index);
+    } else if (index == 0) {
+        GEN_LOAD_REG_TN(T0, base);
+    } else {
+        GEN_LOAD_REG_TN(T0, base);
+        GEN_LOAD_REG_TN(T1, index);
+        gen_op_addr_add();
+    }
     /* Don't do NOP if destination is zero: we must perform the actual
      * memory access
      */
     switch (opc) {
     case OPC_LWXC1:
-        op_ldst(lwxc1);
+        op_ldst(lwc1);
         GEN_STORE_FTN_FREG(fd, WT0);
         opn = "lwxc1";
         break;
     case OPC_LDXC1:
-        op_ldst(ldxc1);
+        op_ldst(ldc1);
         GEN_STORE_FTN_FREG(fd, DT0);
         opn = "ldxc1";
         break;
@@ -5270,26 +5277,30 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
         opn = "luxc1";
         break;
     case OPC_SWXC1:
-        GEN_LOAD_FREG_FTN(WT0, fd);
-        op_ldst(swxc1);
+        GEN_LOAD_FREG_FTN(WT0, fs);
+        op_ldst(swc1);
         opn = "swxc1";
+        store = 1;
         break;
     case OPC_SDXC1:
-        GEN_LOAD_FREG_FTN(DT0, fd);
-        op_ldst(sdxc1);
+        GEN_LOAD_FREG_FTN(DT0, fs);
+        op_ldst(sdc1);
         opn = "sdxc1";
+        store = 1;
         break;
     case OPC_SUXC1:
-        GEN_LOAD_FREG_FTN(DT0, fd);
+        GEN_LOAD_FREG_FTN(DT0, fs);
         op_ldst(suxc1);
         opn = "suxc1";
+        store = 1;
         break;
     default:
         MIPS_INVAL(opn);
         generate_exception(ctx, EXCP_RI);
         return;
     }
-    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[fd],regnames[index], regnames[base]);
+    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
+               regnames[index], regnames[base]);
 }
 
 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
@@ -5882,7 +5893,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
             case OPC_SWXC1:
             case OPC_SDXC1:
             case OPC_SUXC1:
-                gen_flt3_ldst(ctx, op1, sa, rs, rt);
+                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
                 break;
             case OPC_PREFX:
                 /* treat as noop */