diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-04-16 11:51:19 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-04-16 11:51:19 +0000 |
commit | 007ac6faed12abdd4113e2460ba4464aacb7f4dd (patch) | |
tree | cfa23fa5dee1e51be8d7d34285a984f69270417b /target-mips | |
parent | 585c88d5af67be5bf74a557b5365bb91a998de7b (diff) |
target-mips: fix call to check_*() functions
check_*() functions may in fine call generate_exception(), which ends
by a call to tcg_gen_exit_tb(). As a consequence, we have to make sure
that no TCG temp variables are crossing a check_*() function.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7127 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips')
-rw-r--r-- | target-mips/translate.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index 003e9c6870..293bf7e5f3 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -6382,10 +6382,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32(); + if (ctx->opcode & (1 << 6)) { + check_cop1x(ctx); + } + gen_load_fpr32(fp0, fs); gen_load_fpr32(fp1, ft); if (ctx->opcode & (1 << 6)) { - check_cop1x(ctx); gen_cmpabs_s(func-48, fp0, fp1, cc); opn = condnames_abs[func-48]; } else { @@ -6744,16 +6747,17 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, { TCGv_i64 fp0 = tcg_temp_new_i64(); TCGv_i64 fp1 = tcg_temp_new_i64(); + if (ctx->opcode & (1 << 6)) { + check_cop1x(ctx); + } + check_cp1_registers(ctx, fs | ft); gen_load_fpr64(ctx, fp0, fs); gen_load_fpr64(ctx, fp1, ft); if (ctx->opcode & (1 << 6)) { - check_cop1x(ctx); - check_cp1_registers(ctx, fs | ft); gen_cmpabs_d(func-48, fp0, fp1, cc); opn = condnames_abs[func-48]; } else { - check_cp1_registers(ctx, fs | ft); gen_cmp_d(func-48, fp0, fp1, cc); opn = condnames[func-48]; } @@ -7222,6 +7226,22 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int store = 0; TCGv t0 = tcg_temp_new(); + switch (opc) { + case OPC_LWXC1: + case OPC_SWXC1: + check_cop1x(ctx); + break; + case OPC_LDXC1: + case OPC_SDXC1: + check_cop1x(ctx); + check_cp1_registers(ctx, fd); + break; + case OPC_LUXC1: + case OPC_SUXC1: + check_cp1_64bitmode(ctx); + break; + } + if (base == 0) { gen_load_gpr(t0, index); } else if (index == 0) { @@ -7235,7 +7255,6 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, save_cpu_state(ctx, 0); switch (opc) { case OPC_LWXC1: - check_cop1x(ctx); { TCGv_i32 fp0 = tcg_temp_new_i32(); @@ -7247,8 +7266,6 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, opn = "lwxc1"; break; case OPC_LDXC1: - check_cop1x(ctx); - check_cp1_registers(ctx, fd); { TCGv_i64 fp0 = tcg_temp_new_i64(); @@ -7259,7 +7276,6 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, opn = "ldxc1"; break; case OPC_LUXC1: - check_cp1_64bitmode(ctx); tcg_gen_andi_tl(t0, t0, ~0x7); { TCGv_i64 fp0 = tcg_temp_new_i64(); @@ -7271,7 +7287,6 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, opn = "luxc1"; break; case OPC_SWXC1: - check_cop1x(ctx); { TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv t1 = tcg_temp_new(); @@ -7286,8 +7301,6 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, store = 1; break; case OPC_SDXC1: - check_cop1x(ctx); - check_cp1_registers(ctx, fs); { TCGv_i64 fp0 = tcg_temp_new_i64(); @@ -7299,7 +7312,6 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, store = 1; break; case OPC_SUXC1: - check_cp1_64bitmode(ctx); tcg_gen_andi_tl(t0, t0, ~0x7); { TCGv_i64 fp0 = tcg_temp_new_i64(); |