diff options
author | Blue Swirl <blauwirbel@gmail.com> | 2011-07-04 18:15:42 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2011-10-26 17:18:52 +0000 |
commit | 7a5e4488cd1d0e80500be4781010ac4873a9585b (patch) | |
tree | 07c16246818715be34b696320469c7136c9ebf5f /target-sparc | |
parent | 7922703623a989b59ce7f7b57a3c8ebe5c0f6b53 (diff) | |
download | qemu-7a5e4488cd1d0e80500be4781010ac4873a9585b.zip qemu-7a5e4488cd1d0e80500be4781010ac4873a9585b.tar.gz qemu-7a5e4488cd1d0e80500be4781010ac4873a9585b.tar.bz2 |
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 <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-sparc')
-rw-r--r-- | target-sparc/helper.c | 76 | ||||
-rw-r--r-- | target-sparc/helper.h | 8 | ||||
-rw-r--r-- | target-sparc/op_helper.c | 74 | ||||
-rw-r--r-- | 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: |