qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH, MIPS] Disable 64-bit instructions on 32-bit CPU


From: Aurelien Jarno
Subject: [Qemu-devel] [PATCH, MIPS] Disable 64-bit instructions on 32-bit CPU
Date: Sun, 24 Jun 2007 01:05:04 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

Hi,

Since yesterday, it is possible to ask qemu-system-mips64(el) to emulate
32-bit only CPU. The patch below improve that by disabling 64-bit
instructions on those emulated CPU.

Bye,
Aurelien


Index: target-mips/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/helper.c,v
retrieving revision 1.43
diff -u -d -p -r1.43 helper.c
--- target-mips/helper.c        23 Jun 2007 18:04:11 -0000      1.43
+++ target-mips/helper.c        23 Jun 2007 22:52:34 -0000
@@ -369,7 +369,8 @@ void do_interrupt (CPUState *env)
         }
     enter_debug_mode:
         env->hflags |= MIPS_HFLAG_DM;
-        env->hflags |= MIPS_HFLAG_64;
+        if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
+            env->hflags |= MIPS_HFLAG_64;
         env->hflags &= ~MIPS_HFLAG_UM;
         /* EJTAG probe trap enable is not implemented... */
         if (!(env->CP0_Status & (1 << CP0St_EXL)))
@@ -395,7 +396,8 @@ void do_interrupt (CPUState *env)
             env->CP0_ErrorEPC = env->PC;
         }
         env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
-        env->hflags |= MIPS_HFLAG_64;
+        if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
+            env->hflags |= MIPS_HFLAG_64;
         env->hflags &= ~MIPS_HFLAG_UM;
         if (!(env->CP0_Status & (1 << CP0St_EXL)))
             env->CP0_Cause &= ~(1 << CP0Ca_BD);
@@ -494,7 +496,8 @@ void do_interrupt (CPUState *env)
                 env->CP0_Cause &= ~(1 << CP0Ca_BD);
             }
             env->CP0_Status |= (1 << CP0St_EXL);
-            env->hflags |= MIPS_HFLAG_64;
+            if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
+                env->hflags |= MIPS_HFLAG_64;
             env->hflags &= ~MIPS_HFLAG_UM;
         }
         env->hflags &= ~MIPS_HFLAG_BMASK;
Index: target-mips/op.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op.c,v
retrieving revision 1.67
diff -u -d -p -r1.67 op.c
--- target-mips/op.c    23 Jun 2007 18:04:11 -0000      1.67
+++ target-mips/op.c    23 Jun 2007 22:52:34 -0000
@@ -1358,9 +1358,10 @@ void op_mtc0_status (void)
         (val & (1 << CP0St_UM)))
         env->hflags |= MIPS_HFLAG_UM;
 #ifdef TARGET_MIPS64
-    if ((env->hflags & MIPS_HFLAG_UM) &&
+    if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) ||
+        ((env->hflags & MIPS_HFLAG_UM) &&
         !(val & (1 << CP0St_PX)) &&
-        !(val & (1 << CP0St_UX)))
+        !(val & (1 << CP0St_UX))))
         env->hflags &= ~MIPS_HFLAG_64;
 #endif
     if (val & (1 << CP0St_CU1))
@@ -2318,9 +2319,10 @@ void op_eret (void)
         (env->CP0_Status & (1 << CP0St_UM)))
         env->hflags |= MIPS_HFLAG_UM;
 #ifdef TARGET_MIPS64
-    if ((env->hflags & MIPS_HFLAG_UM) &&
+    if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) ||
+        ((env->hflags & MIPS_HFLAG_UM) &&
         !(env->CP0_Status & (1 << CP0St_PX)) &&
-        !(env->CP0_Status & (1 << CP0St_UX)))
+        !(env->CP0_Status & (1 << CP0St_UX))))
         env->hflags &= ~MIPS_HFLAG_64;
 #endif
     if (loglevel & CPU_LOG_EXEC)
@@ -2341,9 +2343,10 @@ void op_deret (void)
         (env->CP0_Status & (1 << CP0St_UM)))
         env->hflags |= MIPS_HFLAG_UM;
 #ifdef TARGET_MIPS64
-    if ((env->hflags & MIPS_HFLAG_UM) &&
+    if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) ||
+        ((env->hflags & MIPS_HFLAG_UM) &&
         !(env->CP0_Status & (1 << CP0St_PX)) &&
-        !(env->CP0_Status & (1 << CP0St_UX)))
+        !(env->CP0_Status & (1 << CP0St_UX))))
         env->hflags &= ~MIPS_HFLAG_64;
 #endif
     if (loglevel & CPU_LOG_EXEC)
Index: target-mips/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/translate.c,v
retrieving revision 1.93
diff -u -d -p -r1.93 translate.c
--- target-mips/translate.c     2 Jun 2007 00:25:12 -0000       1.93
+++ target-mips/translate.c     23 Jun 2007 22:52:34 -0000
@@ -2225,6 +2225,8 @@ static void gen_mfc0 (CPUState *env, Dis
         switch (sel) {
         case 0:
 #ifdef TARGET_MIPS64
+           if (!(ctx->hflags & MIPS_HFLAG_64))
+               goto die;
             gen_op_mfc0_xcontext();
             rn = "XContext";
             break;
@@ -2781,6 +2783,8 @@ static void gen_mtc0 (CPUState *env, Dis
         switch (sel) {
         case 0:
 #ifdef TARGET_MIPS64
+           if (!(ctx->hflags & MIPS_HFLAG_64))
+               goto die;
             gen_op_mtc0_xcontext();
             rn = "XContext";
             break;
@@ -3331,11 +3335,9 @@ static void gen_dmfc0 (CPUState *env, Di
     case 20:
         switch (sel) {
         case 0:
-#ifdef TARGET_MIPS64
             gen_op_dmfc0_xcontext();
             rn = "XContext";
             break;
-#endif
         default:
             goto die;
         }
@@ -3878,11 +3880,9 @@ static void gen_dmtc0 (CPUState *env, Di
     case 20:
         switch (sel) {
         case 0:
-#ifdef TARGET_MIPS64
             gen_op_mtc0_xcontext();
             rn = "XContext";
             break;
-#endif
         default:
             goto die;
         }
@@ -4107,6 +4107,8 @@ static void gen_cp0 (CPUState *env, Disa
         break;
 #ifdef TARGET_MIPS64
     case OPC_DMFC0:
+        if (!(ctx->hflags & MIPS_HFLAG_64))
+            generate_exception(ctx, EXCP_RI);
         if (rt == 0) {
             /* Treat as NOP */
             return;
@@ -4116,6 +4118,8 @@ static void gen_cp0 (CPUState *env, Disa
         opn = "dmfc0";
         break;
     case OPC_DMTC0:
+        if (!(ctx->hflags & MIPS_HFLAG_64))
+            generate_exception(ctx, EXCP_RI);
         GEN_LOAD_REG_TN(T0, rt);
         gen_dmtc0(env,ctx, rd, ctx->opcode & 0x7);
         opn = "dmtc0";
@@ -6183,11 +6187,7 @@ void cpu_reset (CPUMIPSState *env)
     } else {
         env->CP0_ErrorEPC = env->PC;
     }
-#ifdef TARGET_MIPS64
-    env->hflags = MIPS_HFLAG_64;
-#else
     env->hflags = 0;
-#endif
     env->PC = (int32_t)0xBFC00000;
     env->CP0_Wired = 0;
     /* SMP not implemented */
Index: target-mips/translate_init.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/translate_init.c,v
retrieving revision 1.17
diff -u -d -p -r1.17 translate_init.c
--- target-mips/translate_init.c        23 Jun 2007 18:04:12 -0000      1.17
+++ target-mips/translate_init.c        23 Jun 2007 22:52:34 -0000
@@ -88,7 +88,6 @@ static mips_def_t mips_defs[] =
         .SYNCI_Step = 32,
         .CCRes = 2,
         .Status_rw_bitmask = 0x3278FF17,
-        .SEGBITS = 32,
     },
     {
         .name = "4KEcR1",
@@ -100,7 +99,6 @@ static mips_def_t mips_defs[] =
         .SYNCI_Step = 32,
         .CCRes = 2,
         .Status_rw_bitmask = 0x3278FF17,
-        .SEGBITS = 32,
     },
     {
         .name = "4KEc",
@@ -112,7 +110,6 @@ static mips_def_t mips_defs[] =
         .SYNCI_Step = 32,
         .CCRes = 2,
         .Status_rw_bitmask = 0x3278FF17,
-        .SEGBITS = 32,
     },
     {
         .name = "24Kc",
@@ -124,7 +121,6 @@ static mips_def_t mips_defs[] =
         .SYNCI_Step = 32,
         .CCRes = 2,
         .Status_rw_bitmask = 0x3278FF17,
-        .SEGBITS = 32,
     },
     {
         .name = "24Kf",
@@ -138,7 +134,6 @@ static mips_def_t mips_defs[] =
         .Status_rw_bitmask = 0x3678FF17,
         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
                     (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
-        .SEGBITS = 32,
     },
 #ifdef TARGET_MIPS64
     {
@@ -285,8 +280,15 @@ int cpu_mips_register (CPUMIPSState *env
     env->Status_rw_bitmask = def->Status_rw_bitmask;
     env->fcr0 = def->CP1_fcr0;
 #ifdef TARGET_MIPS64
-    env->SEGBITS = def->SEGBITS;
-    env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1);
+    if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
+    {      
+        env->hflags |= MIPS_HFLAG_64;
+        env->SEGBITS = def->SEGBITS;
+        env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1);
+    } else {
+        env->SEGBITS = 32;
+        env->SEGMask = 0xFFFFFFFF;
+    }
 #endif
 #ifdef CONFIG_USER_ONLY
     if (env->CP0_Config1 & (1 << CP0C1_FP))

-- 
  .''`.  Aurelien Jarno             | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   address@hidden         | address@hidden
   `-    people.debian.org/~aurel32 | www.aurel32.net




reply via email to

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