Fix Sparc64 wrfprs, move VIS ops where they belong, more VIS ops
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 13 Apr 2007 15:49:56 +0000 (15:49 +0000)
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 13 Apr 2007 15:49:56 +0000 (15:49 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2656 c046a42c-6fe2-441c-8c8c-71466251a162

target-sparc/op.c
target-sparc/translate.c

index 96c8b2d..2c21b53 100644 (file)
@@ -1864,4 +1864,24 @@ void OPPROTO op_faligndata()
     tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
     (*((uint64_t *)&DT0)) = tmp;
 }
+
+void OPPROTO op_movl_FT0_0(void)
+{
+    (*((uint32_t *)&FT0)) = 0;
+}
+
+void OPPROTO op_movl_DT0_0(void)
+{
+    (*((uint64_t *)&DT0)) = 0;
+}
+
+void OPPROTO op_movl_FT0_1(void)
+{
+    (*((uint32_t *)&FT0)) = 0xffffffff;
+}
+
+void OPPROTO op_movl_DT0_1(void)
+{
+    (*((uint64_t *)&DT0)) = 0xffffffffffffffffULL;
+}
 #endif
index 19b10a2..20dffe0 100644 (file)
@@ -1931,7 +1931,13 @@ static void disas_sparc_insn(DisasContext * dc)
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
                                break;
                            case 0x6: /* V9 wrfprs */
+                               gen_op_xor_T1_T0();
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
+                                save_state(dc);
+                                gen_op_next_insn();
+                                gen_op_movl_T0_0();
+                                gen_op_exit_tb();
+                                dc->is_br = 1;
                                break;
                            case 0xf: /* V9 sir, nop if user */
 #if !defined(CONFIG_USER_ONLY)
@@ -2148,47 +2154,94 @@ static void disas_sparc_insn(DisasContext * dc)
                            gen_movl_T0_reg(rd);
                            break;
                        }
-                   case 0x36: /* UltraSparc shutdown, VIS */
-                       {
-                           int opf = GET_FIELD_SP(insn, 5, 13);
-                            rs1 = GET_FIELD(insn, 13, 17);
-                            rs2 = GET_FIELD(insn, 27, 31);
-
-                            switch (opf) {
-                            case 0x018: /* VIS I alignaddr */
-                                if (gen_trap_ifnofpu(dc))
-                                    goto jmp_insn;
-                                gen_movl_reg_T0(rs1);
-                                gen_movl_reg_T1(rs2);
-                                gen_op_alignaddr();
-                                gen_movl_T0_reg(rd);
-                                break;
-                            case 0x01a: /* VIS I alignaddrl */
-                                if (gen_trap_ifnofpu(dc))
-                                    goto jmp_insn;
-                                // XXX
-                                break;
-                            case 0x048: /* VIS I faligndata */
-                                if (gen_trap_ifnofpu(dc))
-                                    goto jmp_insn;
-                                gen_op_load_fpr_DT0(rs1);
-                                gen_op_load_fpr_DT1(rs2);
-                                gen_op_faligndata();
-                                gen_op_store_DT0_fpr(rd);
-                                break;
-                            default:
-                                goto illegal_insn;
-                            }
-                            break;
-                       }
 #endif
                    default:
                        goto illegal_insn;
                    }
                }
-            } else if (xop == 0x36 || xop == 0x37) { /* CPop1 & CPop2,
-                                                        V9 impdep1 &
-                                                        impdep2 */
+            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
+#ifdef TARGET_SPARC64
+                int opf = GET_FIELD_SP(insn, 5, 13);
+                rs1 = GET_FIELD(insn, 13, 17);
+                rs2 = GET_FIELD(insn, 27, 31);
+
+                switch (opf) {
+                case 0x018: /* VIS I alignaddr */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_movl_reg_T0(rs1);
+                    gen_movl_reg_T1(rs2);
+                    gen_op_alignaddr();
+                    gen_movl_T0_reg(rd);
+                    break;
+                case 0x01a: /* VIS I alignaddrl */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    // XXX
+                    break;
+                case 0x048: /* VIS I faligndata */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_op_load_fpr_DT0(rs1);
+                    gen_op_load_fpr_DT1(rs2);
+                    gen_op_faligndata();
+                    gen_op_store_DT0_fpr(rd);
+                    break;
+                case 0x060: /* VIS I fzero */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_op_movl_DT0_0();
+                    gen_op_store_DT0_fpr(rd);
+                    break;
+                case 0x061: /* VIS I fzeros */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_op_movl_FT0_0();
+                    gen_op_store_FT0_fpr(rd);
+                    break;
+                case 0x074: /* VIS I fsrc1 */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_op_load_fpr_DT0(rs1);
+                    gen_op_store_DT0_fpr(rd);
+                    break;
+                case 0x075: /* VIS I fsrc1s */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_op_load_fpr_FT0(rs1);
+                    gen_op_store_FT0_fpr(rd);
+                    break;
+                case 0x078: /* VIS I fsrc2 */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_op_load_fpr_DT0(rs2);
+                    gen_op_store_DT0_fpr(rd);
+                    break;
+                case 0x079: /* VIS I fsrc2s */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_op_load_fpr_FT0(rs2);
+                    gen_op_store_FT0_fpr(rd);
+                    break;
+                case 0x07e: /* VIS I fone */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_op_movl_DT0_1();
+                    gen_op_store_DT0_fpr(rd);
+                    break;
+                case 0x07f: /* VIS I fones */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+                    gen_op_movl_FT0_1();
+                    gen_op_store_FT0_fpr(rd);
+                    break;
+                default:
+                    goto illegal_insn;
+                }
+#else
+               goto ncp_insn;
+#endif
+            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
 #ifdef TARGET_SPARC64
                goto illegal_insn;
 #else
@@ -2995,8 +3048,8 @@ void cpu_dump_state(CPUState *env, FILE *f,
             cpu_fprintf(f, "\n");
     }
 #ifdef TARGET_SPARC64
-    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d\n",
-               env->pstate, GET_CCR(env), env->asi, env->tl);
+    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
+               env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
     cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
                env->cansave, env->canrestore, env->otherwin, env->wstate,
                env->cleanwin, NWINDOWS - 1 - env->cwp);