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>
This commit is contained in:
Blue Swirl 2011-07-04 18:15:42 +00:00
parent 7922703623
commit 7a5e4488cd
4 changed files with 88 additions and 82 deletions

View File

@ -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);
}

View File

@ -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)

View File

@ -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);

View File

@ -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: