Compare commits

..

4 Commits

Author SHA1 Message Date
Aurelien Jarno
9badf5579d target-mips: fix save_cpu_state() calls
The rule is:
- don't save PC if the exception is only triggered by softmmu.
- save PC if the exception can be triggered by an helper.

Fix a 64-bit kernel crash when loading modules.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit b835e919f0)
2011-01-24 20:52:19 +01:00
Aurelien Jarno
4a9048a914 target-sparc: fix udiv(cc) and sdiv(cc)
Since commit 5a4bb580cd, Xorg crashes on
a Debian Etch image. The commit itself is fine, but it triggers a bug
due to wrong computation of flags for udiv(cc) and sdiv(cc).

This patch only compute cc_src2 for the cc version of udiv/sdiv. It
also moves the update of cc_dst and cc_op to the helper, as it is
faster doing it here when there is already an helper.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 0fcec41eec)

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2010-12-28 23:18:37 +01:00
Aurelien Jarno
0282ff4d61 target-arm: fix bug in translation of REVSH
The translation of REVSH shifted the low byte 8 steps left before performing
an 8-bit sign extend, causing this part of the expression to alwas be 0.

Reported-by: Johan Bengtsson <teofrastius@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 1a855029af)

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2010-12-27 21:38:05 +01:00
Paul Brook
f0acb38015 Add missing dependency.
Teach Makefile that cmd.o depends on a generated header (specifically
config-host.h).

Signed-off-by: Paul Brook <paul@codesourcery.com>
(cherry picked from commit 6e14404aab)

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2010-12-26 00:06:30 +01:00
6 changed files with 60 additions and 32 deletions

View File

@@ -107,7 +107,7 @@ bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
######################################################################
qemu-img.o: qemu-img-cmds.h
qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o: $(GENERATED_HEADERS)
qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y)

View File

@@ -250,13 +250,9 @@ static void gen_rev16(TCGv var)
/* Byteswap low halfword and sign extend. */
static void gen_revsh(TCGv var)
{
TCGv tmp = new_tmp();
tcg_gen_shri_i32(tmp, var, 8);
tcg_gen_andi_i32(tmp, tmp, 0x00ff);
tcg_gen_shli_i32(var, var, 8);
tcg_gen_ext8s_i32(var, var);
tcg_gen_or_i32(var, var, tmp);
dead_tmp(tmp);
tcg_gen_ext16u_i32(var, var);
tcg_gen_bswap16_i32(var, var);
tcg_gen_ext16s_i32(var, var);
}
/* Unsigned bitfield extract. */

View File

@@ -1066,7 +1066,7 @@ static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
opn = "ld";
break;
case OPC_LLD:
save_cpu_state(ctx, 0);
save_cpu_state(ctx, 1);
op_ld_lld(t0, t0, ctx);
gen_store_gpr(t0, rt);
opn = "lld";
@@ -1086,7 +1086,7 @@ static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
opn = "ldr";
break;
case OPC_LDPC:
save_cpu_state(ctx, 1);
save_cpu_state(ctx, 0);
tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
gen_op_addr_add(ctx, t0, t0, t1);
op_ld_ld(t0, t0, ctx);
@@ -1095,7 +1095,7 @@ static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
break;
#endif
case OPC_LWPC:
save_cpu_state(ctx, 1);
save_cpu_state(ctx, 0);
tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
gen_op_addr_add(ctx, t0, t0, t1);
op_ld_lw(t0, t0, ctx);
@@ -1236,7 +1236,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
switch (opc) {
#if defined(TARGET_MIPS64)
case OPC_SCD:
save_cpu_state(ctx, 0);
save_cpu_state(ctx, 1);
op_st_scd(t1, t0, rt, ctx);
opn = "scd";
break;
@@ -9939,7 +9939,7 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
opn = "lwp";
break;
case SWP:
save_cpu_state(ctx, 1);
save_cpu_state(ctx, 0);
gen_load_gpr(t1, rd);
op_st_sw(t1, t0, ctx);
tcg_gen_movi_tl(t1, 4);
@@ -9960,7 +9960,7 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
opn = "ldp";
break;
case SDP:
save_cpu_state(ctx, 1);
save_cpu_state(ctx, 0);
gen_load_gpr(t1, rd);
op_st_sd(t1, t0, ctx);
tcg_gen_movi_tl(t1, 8);

View File

@@ -37,7 +37,9 @@ DEF_HELPER_0(save, void)
DEF_HELPER_0(restore, void)
DEF_HELPER_1(flush, void, tl)
DEF_HELPER_2(udiv, tl, tl, tl)
DEF_HELPER_2(udiv_cc, tl, tl, tl)
DEF_HELPER_2(sdiv, tl, tl, tl)
DEF_HELPER_2(sdiv_cc, tl, tl, tl)
DEF_HELPER_2(stdf, void, tl, int)
DEF_HELPER_2(lddf, void, tl, int)
DEF_HELPER_2(ldqf, void, tl, int)

View File

@@ -3300,8 +3300,9 @@ void helper_rett(void)
}
#endif
target_ulong helper_udiv(target_ulong a, target_ulong b)
static target_ulong helper_udiv_common(target_ulong a, target_ulong b, int cc)
{
int overflow = 0;
uint64_t x0;
uint32_t x1;
@@ -3314,16 +3315,31 @@ target_ulong helper_udiv(target_ulong a, target_ulong b)
x0 = x0 / x1;
if (x0 > 0xffffffff) {
env->cc_src2 = 1;
return 0xffffffff;
} else {
env->cc_src2 = 0;
return x0;
x0 = 0xffffffff;
overflow = 1;
}
if (cc) {
env->cc_dst = x0;
env->cc_src2 = overflow;
env->cc_op = CC_OP_DIV;
}
return x0;
}
target_ulong helper_sdiv(target_ulong a, target_ulong b)
target_ulong helper_udiv(target_ulong a, target_ulong b)
{
return helper_udiv_common(a, b, 0);
}
target_ulong helper_udiv_cc(target_ulong a, target_ulong b)
{
return helper_udiv_common(a, b, 1);
}
static target_ulong helper_sdiv_common(target_ulong a, target_ulong b, int cc)
{
int overflow = 0;
int64_t x0;
int32_t x1;
@@ -3336,12 +3352,26 @@ target_ulong helper_sdiv(target_ulong a, target_ulong b)
x0 = x0 / x1;
if ((int32_t) x0 != x0) {
env->cc_src2 = 1;
return x0 < 0? 0x80000000: 0x7fffffff;
} else {
env->cc_src2 = 0;
return x0;
x0 = x0 < 0 ? 0x80000000: 0x7fffffff;
overflow = 1;
}
if (cc) {
env->cc_dst = x0;
env->cc_src2 = overflow;
env->cc_op = CC_OP_DIV;
}
return x0;
}
target_ulong helper_sdiv(target_ulong a, target_ulong b)
{
return helper_sdiv_common(a, b, 0);
}
target_ulong helper_sdiv_cc(target_ulong a, target_ulong b)
{
return helper_sdiv_common(a, b, 1);
}
void helper_stdf(target_ulong addr, int mem_idx)

View File

@@ -3162,20 +3162,20 @@ static void disas_sparc_insn(DisasContext * dc)
#endif
case 0xe: /* udiv */
CHECK_IU_FEATURE(dc, DIV);
gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2);
if (xop & 0x10) {
tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
tcg_gen_movi_i32(cpu_cc_op, CC_OP_DIV);
gen_helper_udiv_cc(cpu_dst, cpu_src1, cpu_src2);
dc->cc_op = CC_OP_DIV;
} else {
gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2);
}
break;
case 0xf: /* sdiv */
CHECK_IU_FEATURE(dc, DIV);
gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2);
if (xop & 0x10) {
tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
tcg_gen_movi_i32(cpu_cc_op, CC_OP_DIV);
gen_helper_sdiv_cc(cpu_dst, cpu_src1, cpu_src2);
dc->cc_op = CC_OP_DIV;
} else {
gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2);
}
break;
default: