[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,
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH] target-mips: Correct 32-bit address space wrapping,
Maciej W. Rozycki <=