diff options
author | Richard Henderson <rth@twiddle.net> | 2012-08-20 14:02:02 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-01-05 12:00:29 -0800 |
commit | 891452e5e274967ffb87d10791620154f2cdc303 (patch) | |
tree | 3c5e90f9da1e7e0ec6c060d6f3dd91bb876d78c6 /target-s390x/int_helper.c | |
parent | c61aad6943cd77046e47cdb5beedad9d035d2216 (diff) |
target-s390: Convert DIVIDE
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-s390x/int_helper.c')
-rw-r--r-- | target-s390x/int_helper.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c index 17c4771e41..80e17f5b1f 100644 --- a/target-s390x/int_helper.c +++ b/target-s390x/int_helper.c @@ -37,32 +37,51 @@ uint64_t HELPER(mul128)(CPUS390XState *env, uint64_t v1, uint64_t v2) return reth; } -/* 128 -> 64/64 unsigned division */ -void HELPER(dlg)(CPUS390XState *env, uint32_t r1, uint64_t v2) +/* 64/32 -> 32 signed division */ +int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b) +{ + env->retxl = a % (int32_t)b; + return a / (int32_t)b; +} + +/* 64/32 -> 32 unsigned division */ +uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b) { - uint64_t divisor = v2; + env->retxl = a % (uint32_t)b; + return a / (uint32_t)b; +} - if (!env->regs[r1]) { +/* 64/64 -> 64 signed division */ +int64_t HELPER(divs64)(CPUS390XState *env, int64_t a, int64_t b) +{ + env->retxl = a % b; + return a / b; +} + +/* 128 -> 64/64 unsigned division */ +uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al, + uint64_t b) +{ + uint64_t ret; + if (ah == 0) { /* 64 -> 64/64 case */ - env->regs[r1] = env->regs[r1 + 1] % divisor; - env->regs[r1 + 1] = env->regs[r1 + 1] / divisor; - return; + env->retxl = al % b; + ret = al / b; } else { + /* ??? Move i386 idivq helper to host-utils. */ #if HOST_LONG_BITS == 64 && defined(__GNUC__) /* assuming 64-bit hosts have __uint128_t */ - __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) | - (env->regs[r1 + 1]); - __uint128_t quotient = dividend / divisor; - __uint128_t remainder = dividend % divisor; - - env->regs[r1 + 1] = quotient; - env->regs[r1] = remainder; + __uint128_t a = ((__uint128_t)ah << 64) | al; + __uint128_t q = a / b; + env->retxl = a % b; + ret = q; #else /* 32-bit hosts would need special wrapper functionality - just abort if we encounter such a case; it's very unlikely anyways. */ cpu_abort(env, "128 -> 64/64 division not implemented\n"); #endif } + return ret; } /* absolute value 32-bit */ |