From 7a5e4488cd1d0e80500be4781010ac4873a9585b Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Mon, 4 Jul 2011 18:15:42 +0000 Subject: 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 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'target-sparc/helper.c') diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 7a25605fa7..5f8cf314f1 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); +} -- cgit v1.2.3