target-ppc: Add ISA2.06 divdeu[o] Instructions

This patch adds the Divide Doubleword Extended Unsigned
instructions.  This instruction requires dividing a 128-bit
value by a 64 bit value.  Since 128 bit integer division is
not supported in TCG, a helper is used.  An architecture
independent 128-bit division routine is added to host-utils.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
[agraf: use ||]
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Tom Musta 2014-01-07 10:05:51 -06:00 committed by Alexander Graf
parent a824bc191a
commit 98d1eb2748
5 changed files with 101 additions and 0 deletions

View file

@ -86,4 +86,42 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
}
*phigh = rh;
}
/* Unsigned 128x64 division. Returns 1 if overflow (divide by zero or */
/* quotient exceeds 64 bits). Otherwise returns quotient via plow and */
/* remainder via phigh. */
int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
{
uint64_t dhi = *phigh;
uint64_t dlo = *plow;
unsigned i;
uint64_t carry = 0;
if (divisor == 0) {
return 1;
} else if (dhi == 0) {
*plow = dlo / divisor;
*phigh = dlo % divisor;
return 0;
} else if (dhi > divisor) {
return 1;
} else {
for (i = 0; i < 64; i++) {
carry = dhi >> 63;
dhi = (dhi << 1) | (dlo >> 63);
if (carry || (dhi >= divisor)) {
dhi -= divisor;
carry = 1;
} else {
carry = 0;
}
dlo = (dlo << 1) | carry;
}
*plow = dlo;
*phigh = dhi;
return 0;
}
}
#endif /* !CONFIG_INT128 */