qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH, MIPS64] 64-bit addressing fixes


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH, MIPS64] 64-bit addressing fixes
Date: Sat, 26 May 2007 23:15:40 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

On Mon, May 21, 2007 at 04:52:05PM +0300, Blue Swirl wrote:
> I don't know MIPS, but perhaps you could try this trick used in Sparc:
> static inline void gen_jmp_im(target_ulong pc)
> {
> #ifdef TARGET_SPARC64
>    if (pc == (uint32_t)pc) {
>        gen_op_jmp_im(pc);
>    } else {
>        gen_op_jmp_im64(pc >> 32, pc);
>    }
> #else
>    gen_op_jmp_im(pc);
> #endif
> }
> 

Here is a new patch using the same trick as the one used in Sparc. It
renders the code clearer. Sorry for the delay.

Index: target-mips/op.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op.c,v
retrieving revision 1.62
diff -u -d -p -r1.62 op.c
--- target-mips/op.c    23 May 2007 08:24:25 -0000      1.62
+++ target-mips/op.c    26 May 2007 21:12:05 -0000
@@ -976,6 +976,14 @@ void op_save_btarget (void)
     RETURN();
 }
 
+#ifdef TARGET_MIPS64
+void op_save_btarget64 (void)
+{
+    env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
+    RETURN();
+}
+#endif
+
 /* Conditional branch */
 void op_set_bcond (void)
 {
@@ -2409,6 +2417,14 @@ void op_save_pc (void)
     RETURN();
 }
 
+#ifdef TARGET_MIPS64
+void op_save_pc64 (void)
+{
+    env->PC = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
+    RETURN();
+}
+#endif
+
 void op_interrupt_restart (void)
 {
     if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
Index: target-mips/op_template.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op_template.c,v
retrieving revision 1.5
diff -u -d -p -r1.5 op_template.c
--- target-mips/op_template.c   29 Apr 2007 21:19:03 -0000      1.5
+++ target-mips/op_template.c   26 May 2007 21:12:05 -0000
@@ -68,4 +68,20 @@ SET_RESET(T1, _T1)
 SET_RESET(T2, _T2)
 
 #undef SET_RESET
+
+#ifdef TARGET_MIPS64
+#define SET64(treg, tregname)                               \
+    void glue(op_set64, tregname)(void)                     \
+    {                                                       \
+        treg = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; \
+        RETURN();                                           \
+    }
+
+SET64(T0, _T0)
+SET64(T1, _T1)
+SET64(T2, _T2)
+
+#undef SET64
+
+#endif
 #endif
Index: target-mips/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/translate.c,v
retrieving revision 1.87
diff -u -d -p -r1.87 translate.c
--- target-mips/translate.c     23 May 2007 08:24:25 -0000      1.87
+++ target-mips/translate.c     26 May 2007 21:12:05 -0000
@@ -569,6 +569,18 @@ do {                                    
     }                                                                         \
 } while (0)
 
+#ifdef TARGET_MIPS64
+#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
+do {                                                                          \
+    if (Imm == 0) {                                                           \
+        glue(gen_op_reset_, Tn)();                                            \
+    } else if ((int32_t)Imm == Imm) {                                         \
+        glue(gen_op_set_, Tn)(Imm);                                           \
+    } else {                                                                  \
+        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
+    }                                                                         \
+} while (0)
+#else
 #define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
 do {                                                                          \
     if (Imm == 0) {                                                           \
@@ -577,6 +589,7 @@ do {                                    
         glue(gen_op_set_, Tn)(Imm);                                           \
     }                                                                         \
 } while (0)
+#endif
 
 #define GEN_STORE_TN_REG(Rn, Tn)                                              \
 do {                                                                          \
@@ -595,6 +608,32 @@ do {                                    
     glue(gen_op_store_fpr_, FTn)(Fn);                                         \
 } while (0)
 
+static inline void gen_save_pc(target_ulong pc)
+{
+#ifdef TARGET_MIPS64
+    if (pc == (int32_t)pc) {
+        gen_op_save_pc(pc);
+    } else {
+        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
+    }
+#else
+    gen_op_save_pc(pc);
+#endif
+}
+
+static inline void gen_save_btarget(target_ulong btarget)
+{
+#ifdef TARGET_MIPS64
+    if (btarget == (int32_t)btarget) {
+        gen_op_save_btarget(btarget);
+    } else {
+        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
+    }
+#else
+    gen_op_save_btarget(btarget);
+#endif
+}
+
 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
 {
 #if defined MIPS_DEBUG_DISAS
@@ -604,7 +643,7 @@ static inline void save_cpu_state (Disas
     }
 #endif
     if (do_save_pc && ctx->pc != ctx->saved_pc) {
-        gen_op_save_pc(ctx->pc);
+        gen_save_pc(ctx->pc);
         ctx->saved_pc = ctx->pc;
     }
     if (ctx->hflags != ctx->saved_hflags) {
@@ -621,7 +660,7 @@ static inline void save_cpu_state (Disas
             /* bcond was already saved by the BL insn */
             /* fall through */
         case MIPS_HFLAG_B:
-            gen_op_save_btarget(ctx->btarget);
+            gen_save_btarget(ctx->btarget);
             break;
         }
     }
@@ -946,7 +985,7 @@ static void gen_arith_imm (DisasContext 
         GEN_LOAD_IMM_TN(T1, uimm);
         break;
     case OPC_LUI:
-        GEN_LOAD_IMM_TN(T0, uimm << 16);
+        GEN_LOAD_IMM_TN(T0, imm << 16);
         break;
     case OPC_SLL:
     case OPC_SRA:
@@ -1491,10 +1530,10 @@ static inline void gen_goto_tb(DisasCont
             gen_op_goto_tb0(TBPARAM(tb));
         else
             gen_op_goto_tb1(TBPARAM(tb));
-        gen_op_save_pc(dest);
+        gen_save_pc(dest);
         gen_op_set_T0((long)tb + n);
     } else {
-        gen_op_save_pc(dest);
+        gen_save_pc(dest);
         gen_op_reset_T0();
     }
     gen_op_exit_tb();
@@ -1556,7 +1595,7 @@ static void gen_compute_branch (DisasCon
     case OPC_J:
     case OPC_JAL:
         /* Jump to immediate */
-        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset;
+        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
         break;
     case OPC_JR:
     case OPC_JALR:
@@ -1602,12 +1641,12 @@ static void gen_compute_branch (DisasCon
             MIPS_DEBUG("bnever (NOP)");
             return;
         case OPC_BLTZAL:  /* 0 < 0           */
-            gen_op_set_T0(ctx->pc + 8);
+            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
             gen_op_store_T0_gpr(31);
             MIPS_DEBUG("bnever and link");
             return;
         case OPC_BLTZALL: /* 0 < 0 likely */
-            gen_op_set_T0(ctx->pc + 8);
+            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
             gen_op_store_T0_gpr(31);
             /* Skip the instruction in the delay slot */
             MIPS_DEBUG("bnever, link and skip");
@@ -1732,9 +1771,10 @@ static void gen_compute_branch (DisasCon
     }
     MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
                blink, ctx->hflags, btarget);
+
     ctx->btarget = btarget;
     if (blink > 0) {
-        gen_op_set_T0(ctx->pc + 8);
+        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
         gen_op_store_T0_gpr(blink);
     }
 }
-- 
  .''`.  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]