From c3dac5728b56079f8ca9968d71b13963a20b8aa7 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Blue Swirl Date: Mon, 4 Jul 2011 18:15:42 +0000 Subject: [PATCH 3/9] Sparc: avoid AREG0 for division op helpers Make [su]div{,cc} helpers take a parameter for CPUState instead of relying on global env. Move the functions to helper.c. Reviewed-by: Richard Henderson Signed-off-by: Blue Swirl --- target-sparc/helper.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++ target-sparc/helper.h | 8 ++-- target-sparc/op_helper.c | 74 -------------------------------------------- target-sparc/translate.c | 12 +++++-- 4 files changed, 88 insertions(+), 82 deletions(-) diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 7a25605..5f8cf31 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -919,3 +919,79 @@ void helper_tick_set_limit(void *opaque, uint64_t limit) #endif } #endif + +static target_ulong helper_udiv_common(CPUState *env, target_ulong a, + target_ulong b, int cc) +{ + int overflow = 0; + uint64_t x0; + uint32_t x1; + + x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32); + x1 = (b & 0xffffffff); + + if (x1 == 0) { + helper_raise_exception(env, TT_DIV_ZERO); + } + + x0 = x0 / x1; + if (x0 > 0xffffffff) { + 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_udiv(CPUState *env, target_ulong a, target_ulong b) +{ + return helper_udiv_common(env, a, b, 0); +} + +target_ulong helper_udiv_cc(CPUState *env, target_ulong a, target_ulong b) +{ + return helper_udiv_common(env, a, b, 1); +} + +static target_ulong helper_sdiv_common(CPUState *env, target_ulong a, + target_ulong b, int cc) +{ + int overflow = 0; + int64_t x0; + int32_t x1; + + x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32); + x1 = (b & 0xffffffff); + + if (x1 == 0) { + helper_raise_exception(env, TT_DIV_ZERO); + } + + x0 = x0 / x1; + if ((int32_t) x0 != 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(CPUState *env, target_ulong a, target_ulong b) +{ + return helper_sdiv_common(env, a, b, 0); +} + +target_ulong helper_sdiv_cc(CPUState *env, target_ulong a, target_ulong b) +{ + return helper_sdiv_common(env, a, b, 1); +} diff --git a/target-sparc/helper.h b/target-sparc/helper.h index 943b4ba..615ddef 100644 --- a/target-sparc/helper.h +++ b/target-sparc/helper.h @@ -35,10 +35,10 @@ DEF_HELPER_2(check_align, void, tl, i32) DEF_HELPER_1(debug, void, env) DEF_HELPER_1(save, void, env) DEF_HELPER_1(restore, void, env) -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_3(udiv, tl, env, tl, tl) +DEF_HELPER_3(udiv_cc, tl, env, tl, tl) +DEF_HELPER_3(sdiv, tl, env, tl, tl) +DEF_HELPER_3(sdiv_cc, tl, env, tl, tl) DEF_HELPER_2(stdf, void, tl, int) DEF_HELPER_2(lddf, void, tl, int) DEF_HELPER_2(ldqf, void, tl, int) diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index e0a13fd..0f77ebf 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -2195,80 +2195,6 @@ target_ulong helper_casx_asi(target_ulong addr, target_ulong val1, } #endif /* TARGET_SPARC64 */ -static target_ulong helper_udiv_common(target_ulong a, target_ulong b, int cc) -{ - int overflow = 0; - uint64_t x0; - uint32_t x1; - - x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32); - x1 = (b & 0xffffffff); - - if (x1 == 0) { - helper_raise_exception(env, TT_DIV_ZERO); - } - - x0 = x0 / x1; - if (x0 > 0xffffffff) { - 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_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; - - x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32); - x1 = (b & 0xffffffff); - - if (x1 == 0) { - helper_raise_exception(env, TT_DIV_ZERO); - } - - x0 = x0 / x1; - if ((int32_t) x0 != 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) { helper_check_align(addr, 7); diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 714808b..383fd9c 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -3271,19 +3271,23 @@ static void disas_sparc_insn(DisasContext * dc) case 0xe: /* udiv */ CHECK_IU_FEATURE(dc, DIV); if (xop & 0x10) { - gen_helper_udiv_cc(cpu_dst, cpu_src1, cpu_src2); + gen_helper_udiv_cc(cpu_dst, cpu_env, cpu_src1, + cpu_src2); dc->cc_op = CC_OP_DIV; } else { - gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2); + gen_helper_udiv(cpu_dst, cpu_env, cpu_src1, + cpu_src2); } break; case 0xf: /* sdiv */ CHECK_IU_FEATURE(dc, DIV); if (xop & 0x10) { - gen_helper_sdiv_cc(cpu_dst, cpu_src1, cpu_src2); + gen_helper_sdiv_cc(cpu_dst, cpu_env, cpu_src1, + cpu_src2); dc->cc_op = CC_OP_DIV; } else { - gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2); + gen_helper_sdiv(cpu_dst, cpu_env, cpu_src1, + cpu_src2); } break; default: -- 1.7.2.5