qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 5/8] Mips improvements


From: Thiemo Seufer
Subject: [Qemu-devel] [PATCH 5/8] Mips improvements
Date: Mon, 15 May 2006 02:28:03 +0100
User-agent: Mutt/1.5.11+cvs20060403

Hello All,

this patch splits the mfc0 operations in TB-inlined functions.


Thiemo


Index: qemu-work/target-mips/exec.h
===================================================================
--- qemu-work.orig/target-mips/exec.h   2006-05-07 23:49:06.000000000 +0100
+++ qemu-work/target-mips/exec.h        2006-05-07 23:49:09.000000000 +0100
@@ -59,7 +59,8 @@
 void do_msub (void);
 void do_msubu (void);
 #endif
-void do_mfc0(int reg, int sel);
+void do_mfc0_random(void);
+void do_mfc0_count(void);
 void do_mtc0(int reg, int sel);
 void do_tlbwi (void);
 void do_tlbwr (void);
Index: qemu-work/target-mips/op.c
===================================================================
--- qemu-work.orig/target-mips/op.c     2006-05-07 22:59:28.000000000 +0100
+++ qemu-work/target-mips/op.c  2006-05-07 23:49:09.000000000 +0100
@@ -550,9 +550,167 @@
 }
 
 /* CP0 functions */
-void op_mfc0 (void)
+void op_mfc0_index (void)
 {
-    CALL_FROM_TB2(do_mfc0, PARAM1, PARAM2);
+    T0 = env->CP0_index;
+    RETURN();
+}
+
+void op_mfc0_random (void)
+{
+    CALL_FROM_TB0(do_mfc0_random);
+    RETURN();
+}
+
+void op_mfc0_entrylo0 (void)
+{
+    T0 = env->CP0_EntryLo0;
+    RETURN();
+}
+
+void op_mfc0_entrylo1 (void)
+{
+    T0 = env->CP0_EntryLo1;
+    RETURN();
+}
+
+void op_mfc0_context (void)
+{
+    T0 = env->CP0_Context;
+    RETURN();
+}
+
+void op_mfc0_pagemask (void)
+{
+    T0 = env->CP0_PageMask;
+    RETURN();
+}
+
+void op_mfc0_wired (void)
+{
+    T0 = env->CP0_Wired;
+    RETURN();
+}
+
+void op_mfc0_badvaddr (void)
+{
+    T0 = env->CP0_BadVAddr;
+    RETURN();
+}
+
+void op_mfc0_count (void)
+{
+    CALL_FROM_TB0(do_mfc0_count);
+    RETURN();
+}
+
+void op_mfc0_entryhi (void)
+{
+    T0 = env->CP0_EntryHi;
+    RETURN();
+}
+
+void op_mfc0_compare (void)
+{
+    T0 = env->CP0_Compare;
+    RETURN();
+}
+
+void op_mfc0_status (void)
+{
+    T0 = env->CP0_Status;
+    if (env->hflags & MIPS_HFLAG_UM)
+        T0 |= (1 << CP0St_UM);
+    if (env->hflags & MIPS_HFLAG_ERL)
+        T0 |= (1 << CP0St_ERL);
+    if (env->hflags & MIPS_HFLAG_EXL)
+        T0 |= (1 << CP0St_EXL);
+    RETURN();
+}
+
+void op_mfc0_cause (void)
+{
+    T0 = env->CP0_Cause;
+    RETURN();
+}
+
+void op_mfc0_epc (void)
+{
+    T0 = env->CP0_EPC;
+    RETURN();
+}
+
+void op_mfc0_prid (void)
+{
+    T0 = env->CP0_PRid;
+    RETURN();
+}
+
+void op_mfc0_config0 (void)
+{
+    T0 = env->CP0_Config0;
+    RETURN();
+}
+
+void op_mfc0_config1 (void)
+{
+    T0 = env->CP0_Config1;
+    RETURN();
+}
+
+void op_mfc0_lladdr (void)
+{
+    T0 = env->CP0_LLAddr >> 4;
+    RETURN();
+}
+
+void op_mfc0_watchlo (void)
+{
+    T0 = env->CP0_WatchLo;
+    RETURN();
+}
+
+void op_mfc0_watchhi (void)
+{
+    T0 = env->CP0_WatchHi;
+    RETURN();
+}
+
+void op_mfc0_debug (void)
+{
+    T0 = env->CP0_Debug;
+    if (env->hflags & MIPS_HFLAG_DM)
+        T0 |= 1 << CP0DB_DM;
+    RETURN();
+}
+
+void op_mfc0_depc (void)
+{
+    T0 = env->CP0_DEPC;
+    RETURN();
+}
+
+void op_mfc0_taglo (void)
+{
+    T0 = env->CP0_TagLo;
+    RETURN();
+}
+
+void op_mfc0_datalo (void)
+{
+    T0 = env->CP0_DataLo;
+    RETURN();
+}
+
+void op_mfc0_errorepc (void)
+{
+    T0 = env->CP0_ErrorEPC;
+    RETURN();
+}
+
+void op_mfc0_desave (void)
+{
+    T0 = env->CP0_DESAVE;
     RETURN();
 }
 
Index: qemu-work/target-mips/op_helper.c
===================================================================
--- qemu-work.orig/target-mips/op_helper.c      2006-05-07 23:49:08.000000000 
+0100
+++ qemu-work/target-mips/op_helper.c   2006-05-07 23:49:09.000000000 +0100
@@ -131,10 +131,16 @@
 #endif
 
 #if defined(CONFIG_USER_ONLY) 
-void do_mfc0 (int reg, int sel)
+void do_mfc0_random (void)
 {
-    cpu_abort(env, "mfc0 reg=%d sel=%d\n", reg, sel);
+    cpu_abort(env, "mfc0 random\n");
 }
+
+void do_mfc0_count (void)
+{
+    cpu_abort(env, "mfc0 count\n");
+}
+
 void do_mtc0 (int reg, int sel)
 {
     cpu_abort(env, "mtc0 reg=%d sel=%d\n", reg, sel);
@@ -159,156 +165,18 @@
 {
     cpu_abort(env, "tlbr\n");
 }
+
 #else
 
 /* CP0 helpers */
-void do_mfc0 (int reg, int sel)
+void do_mfc0_random (void)
 {
-    const unsigned char *rn;
+    T0 = cpu_mips_get_random(env);
+}
 
-    if (sel != 0 && reg != 16 && reg != 28) {
-        rn = "invalid";
-        goto print;
-    }
-    switch (reg) {
-    case 0:
-        T0 = env->CP0_index;
-        rn = "Index";
-        break;
-    case 1:
-        T0 = cpu_mips_get_random(env);
-        rn = "Random";
-        break;
-    case 2:
-        T0 = env->CP0_EntryLo0;
-        rn = "EntryLo0";
-        break;
-    case 3:
-        T0 = env->CP0_EntryLo1;
-        rn = "EntryLo1";
-        break;
-    case 4:
-        T0 = env->CP0_Context;
-        rn = "Context";
-        break;
-    case 5:
-        T0 = env->CP0_PageMask;
-        rn = "PageMask";
-        break;
-    case 6:
-        T0 = env->CP0_Wired;
-        rn = "Wired";
-        break;
-    case 8:
-        T0 = env->CP0_BadVAddr;
-        rn = "BadVaddr";
-        break;
-    case 9:
-        T0 = cpu_mips_get_count(env);
-        rn = "Count";
-        break;
-    case 10:
-        T0 = env->CP0_EntryHi;
-        rn = "EntryHi";
-        break;
-    case 11:
-        T0 = env->CP0_Compare;
-        rn = "Compare";
-        break;
-    case 12:
-        T0 = env->CP0_Status;
-        if (env->hflags & MIPS_HFLAG_UM)
-            T0 |= (1 << CP0St_UM);
-        if (env->hflags & MIPS_HFLAG_ERL)
-            T0 |= (1 << CP0St_ERL);
-        if (env->hflags & MIPS_HFLAG_EXL)
-            T0 |= (1 << CP0St_EXL);
-        rn = "Status";
-        break;
-    case 13:
-        T0 = env->CP0_Cause;
-        rn = "Cause";
-        break;
-    case 14:
-        T0 = env->CP0_EPC;
-        rn = "EPC";
-        break;
-    case 15:
-        T0 = env->CP0_PRid;
-        rn = "PRid";
-        break;
-    case 16:
-        switch (sel) {
-        case 0:
-            T0 = env->CP0_Config0;
-            rn = "Config";
-            break;
-        case 1:
-            T0 = env->CP0_Config1;
-            rn = "Config1";
-            break;
-        default:
-            rn = "Unknown config register";
-            break;
-        }
-        break;
-    case 17:
-        T0 = env->CP0_LLAddr >> 4;
-        rn = "LLAddr";
-        break;
-    case 18:
-        T0 = env->CP0_WatchLo;
-        rn = "WatchLo";
-        break;
-    case 19:
-        T0 = env->CP0_WatchHi;
-        rn = "WatchHi";
-        break;
-    case 23:
-        T0 = env->CP0_Debug;
-        if (env->hflags & MIPS_HFLAG_DM)
-            T0 |= 1 << CP0DB_DM;
-        rn = "Debug";
-        break;
-    case 24:
-        T0 = env->CP0_DEPC;
-        rn = "DEPC";
-        break;
-    case 28:
-        switch (sel) {
-        case 0:
-            T0 = env->CP0_TagLo;
-            rn = "TagLo";
-            break;
-        case 1:
-            T0 = env->CP0_DataLo;
-            rn = "DataLo";
-            break;
-        default:
-            rn = "unknown sel";
-            break;
-        }
-        break;
-    case 30:
-        T0 = env->CP0_ErrorEPC;
-        rn = "ErrorEPC";
-        break;
-    case 31:
-        T0 = env->CP0_DESAVE;
-        rn = "DESAVE";
-        break;
-    default:
-        rn = "unknown";
-        break;
-    }
- print:
-#if defined MIPS_DEBUG_DISAS
-    if (loglevel & CPU_LOG_TB_IN_ASM) {
-        fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n",
-                env->PC, rn, T0, reg, sel);
-    }
-#endif
-    return;
+void do_mfc0_count (void)
+{
+    T0 = cpu_mips_get_count(env);
 }
 
 void do_mtc0 (int reg, int sel)
Index: qemu-work/target-mips/translate.c
===================================================================
--- qemu-work.orig/target-mips/translate.c      2006-05-07 23:49:07.000000000 
+0100
+++ qemu-work/target-mips/translate.c   2006-05-07 23:49:09.000000000 +0100
@@ -1175,6 +1175,155 @@
 }
 
 /* CP0 (MMU and control) */
+static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
+{
+    const unsigned char *rn;
+
+    if (sel != 0 && reg != 16 && reg != 28) {
+        rn = "invalid";
+        goto die;
+    }
+    switch (reg) {
+    case 0:
+        gen_op_mfc0_index();
+        rn = "Index";
+        break;
+    case 1:
+        gen_op_mfc0_random();
+        rn = "Random";
+        break;
+    case 2:
+        gen_op_mfc0_entrylo0();
+        rn = "EntryLo0";
+        break;
+    case 3:
+        gen_op_mfc0_entrylo1();
+        rn = "EntryLo1";
+        break;
+    case 4:
+        gen_op_mfc0_context();
+        rn = "Context";
+        break;
+    case 5:
+        gen_op_mfc0_pagemask();
+        rn = "PageMask";
+        break;
+    case 6:
+        gen_op_mfc0_wired();
+        rn = "Wired";
+        break;
+    case 8:
+        gen_op_mfc0_badvaddr();
+        rn = "BadVaddr";
+        break;
+    case 9:
+        gen_op_mfc0_count();
+        rn = "Count";
+        break;
+    case 10:
+        gen_op_mfc0_entryhi();
+        rn = "EntryHi";
+        break;
+    case 11:
+        gen_op_mfc0_compare();
+        rn = "Compare";
+        break;
+    case 12:
+        gen_op_mfc0_status();
+        rn = "Status";
+        break;
+    case 13:
+        gen_op_mfc0_cause();
+        rn = "Cause";
+        break;
+    case 14:
+        gen_op_mfc0_epc();
+        rn = "EPC";
+        break;
+    case 15:
+        gen_op_mfc0_prid();
+        rn = "PRid";
+        break;
+    case 16:
+        switch (sel) {
+        case 0:
+           gen_op_mfc0_config0();
+            rn = "Config";
+            break;
+        case 1:
+           gen_op_mfc0_config1();
+            rn = "Config1";
+            break;
+        default:
+            rn = "Unknown config register";
+            goto die;
+        }
+        break;
+    case 17:
+        gen_op_mfc0_lladdr();
+        rn = "LLAddr";
+        break;
+    case 18:
+        gen_op_mfc0_watchlo();
+        rn = "WatchLo";
+        break;
+    case 19:
+        gen_op_mfc0_watchhi();
+        rn = "WatchHi";
+        break;
+    case 23:
+        gen_op_mfc0_debug();
+        rn = "Debug";
+        break;
+    case 24:
+        gen_op_mfc0_depc();
+        rn = "DEPC";
+        break;
+    case 28:
+        switch (sel) {
+        case 0:
+            gen_op_mfc0_taglo();
+            rn = "TagLo";
+            break;
+        case 1:
+            gen_op_mfc0_datalo();
+            rn = "DataLo";
+            break;
+        default:
+            rn = "unknown sel";
+            goto die;
+        }
+        break;
+    case 30:
+        gen_op_mfc0_errorepc();
+        rn = "ErrorEPC";
+        break;
+    case 31:
+        gen_op_mfc0_desave();
+        rn = "DESAVE";
+        break;
+    default:
+        rn = "unknown";
+       goto die;
+    }
+#if defined MIPS_DEBUG_DISAS
+    if (loglevel & CPU_LOG_TB_IN_ASM) {
+        fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n",
+                env->PC, rn, T0, reg, sel);
+    }
+#endif
+    return;
+
+die:
+#if defined MIPS_DEBUG_DISAS
+    if (loglevel & CPU_LOG_TB_IN_ASM) {
+        fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n",
+                env->PC, rn, T0, reg, sel);
+    }
+#endif
+    generate_exception(ctx, EXCP_RI);
+}
+
 static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd)
 {
     const unsigned char *opn = "unk";
@@ -1195,7 +1344,7 @@
             /* Treat as NOP */
             return;
         }
-        gen_op_mfc0(rd, ctx->opcode & 0x7);
+        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
         gen_op_store_T0_gpr(rt);
         opn = "mfc0";
         break;




reply via email to

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