qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH] target-mips: Correct 32-bit address space wrapping


From: Maciej W. Rozycki
Subject: [Qemu-devel] [PATCH] target-mips: Correct 32-bit address space wrapping
Date: Wed, 19 Nov 2014 17:29:00 +0000
User-agent: Alpine 1.10 (DEB 962 2008-03-14)

Make sure the address space is unconditionally wrapped on 32-bit 
processors, that is ones that do not implement at least the MIPS III 
ISA.

Also make MIPS16 SAVE and RESTORE instructions use address calculation 
rather than plain arithmetic operations for stack pointer manipulation 
so that their semantics for stack accesses follows the architecture 
specification.  That in particular applies to user software run on 
64-bit processors with the CP0.Status.UX bit clear where the address 
space is wrapped to 32 bits.

Signed-off-by: Maciej W. Rozycki <address@hidden>
---
Hi,

 This change was also tested by running full GCC, G++ and glibc 
mips-linux-gnu toolchain test suites under Linux (Debian Wheezy) run in 
QEMU in the system emulation mode, for the following multilibs:

-EB
-EB -mips16
-EB -mmicromips
-EB -mabi=n32
-EB -mabi=64

and the -EL variants of same.  Of these standard MIPS o32 testing was 
run on a 24Kf processor and n64/n32 testing was run on a 5KEf processor, 
using a 32-bit and a 64-bit kernel respectively.  MIPS16 o32 testing was 
run on an artificial 5KEf-mips16 processor -- like a real 5KEf one, but 
with the MIPS16 ASE enabled, and a 64-bit kernel.  Finally microMIPS o32 
testing was run on an artificial 24Kf-micromips processor -- like a real 
24Kf one, but with the microMIPS ASE enabled, and a 32-bit kernel built 
as microMIPS code itself.

 The original test result counts were as follows:

Result           Count
ERROR               20
FAIL               300
PASS           1732076
XPASS              335
XFAIL             6527
UNRESOLVED          26
UNSUPPORTED      50854
Total          1790138

After the change they were:

Result           Count
ERROR               20
FAIL               298
PASS           1732078
XPASS              336
XFAIL             6526
UNRESOLVED          26
UNSUPPORTED      50854
Total          1790138

The changes in results were as follows:

PASS  -> FAIL:  qemu-n32-el/glibc.sum:    nptl/tst-cancel17
FAIL  -> PASS:  qemu-micromips/glibc.sum: nptl/tst-cancel17
FAIL  -> PASS:  qemu-micromips/glibc.sum: nptl/tst-setuid3
FAIL  -> PASS:  qemu-mips16-el/glibc.sum: nptl/tst-cancelx17
XFAIL -> XPASS: qemu-micromips/glibc.sum: nptl/tst-cancel7

-- as you can see glibc results continue fluctuating although this time 
they are slightly better than originally.

 Please apply.

  Maciej

qemu-mips32-addr.diff
Index: qemu-git-trunk/target-mips/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-mips/cpu.h       2014-11-12 07:41:26.597542010 
+0000
+++ qemu-git-trunk/target-mips/cpu.h    2014-11-12 07:41:26.597542010 +0000
@@ -843,10 +843,12 @@ static inline void compute_hflags(CPUMIP
         env->hflags |= MIPS_HFLAG_64;
     }
 
-    if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
-        !(env->CP0_Status & (1 << CP0St_UX))) {
+    if (!(env->insn_flags & ISA_MIPS3)) {
         env->hflags |= MIPS_HFLAG_AWRAP;
-    } else if (env->insn_flags & ISA_MIPS32R6) {
+    } else if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
+               !(env->CP0_Status & (1 << CP0St_UX))) {
+        env->hflags |= MIPS_HFLAG_AWRAP;
+    } else if (env->insn_flags & ISA_MIPS64R6) {
         /* Address wrapping for Supervisor and Kernel is specified in R6 */
         if ((((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) &&
              !(env->CP0_Status & (1 << CP0St_SX))) ||
Index: qemu-git-trunk/target-mips/translate.c
===================================================================
--- qemu-git-trunk.orig/target-mips/translate.c 2014-11-12 07:41:26.597542010 
+0000
+++ qemu-git-trunk/target-mips/translate.c      2014-11-12 07:41:26.597542010 
+0000
@@ -10724,6 +10724,7 @@ static void gen_mips16_save (DisasContex
 {
     TCGv t0 = tcg_temp_new();
     TCGv t1 = tcg_temp_new();
+    TCGv t2 = tcg_temp_new();
     int args, astatic;
 
     switch (aregs) {
@@ -10782,7 +10783,8 @@ static void gen_mips16_save (DisasContex
     gen_load_gpr(t0, 29);
 
 #define DECR_AND_STORE(reg) do {                                 \
-        tcg_gen_subi_tl(t0, t0, 4);                              \
+        tcg_gen_movi_tl(t2, -4);                                 \
+        gen_op_addr_add(ctx, t0, t0, t2);                        \
         gen_load_gpr(t1, reg);                                   \
         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
     } while (0)
@@ -10866,9 +10868,11 @@ static void gen_mips16_save (DisasContex
     }
 #undef DECR_AND_STORE
 
-    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
+    tcg_gen_movi_tl(t2, -framesize);
+    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
     tcg_temp_free(t0);
     tcg_temp_free(t1);
+    tcg_temp_free(t2);
 }
 
 static void gen_mips16_restore (DisasContext *ctx,
@@ -10879,11 +10883,14 @@ static void gen_mips16_restore (DisasCon
     int astatic;
     TCGv t0 = tcg_temp_new();
     TCGv t1 = tcg_temp_new();
+    TCGv t2 = tcg_temp_new();
 
-    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
+    tcg_gen_movi_tl(t2, framesize);
+    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
 
 #define DECR_AND_LOAD(reg) do {                            \
-        tcg_gen_subi_tl(t0, t0, 4);                        \
+        tcg_gen_movi_tl(t2, -4);                           \
+        gen_op_addr_add(ctx, t0, t0, t2);                  \
         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
         gen_store_gpr(t1, reg);                            \
     } while (0)
@@ -10967,9 +10974,11 @@ static void gen_mips16_restore (DisasCon
     }
 #undef DECR_AND_LOAD
 
-    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
+    tcg_gen_movi_tl(t2, framesize);
+    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
     tcg_temp_free(t0);
     tcg_temp_free(t1);
+    tcg_temp_free(t2);
 }
 
 static void gen_addiupc (DisasContext *ctx, int rx, int imm,



reply via email to

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