mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-26 21:10:42 +00:00
host-utils: Implemented signed 256-by-128 division
Based on already existing QEMU implementation created a signed 256 bit by 128 bit division needed to implement the vector divide extended signed quadword instruction from PowerISA 3.1 Signed-off-by: Lucas Mateus Castro (alqotel) <lucas.araujo@eldorado.org.br> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220525134954.85056-6-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
parent
4724bbd284
commit
62c9947fb7
@ -851,4 +851,5 @@ static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
|
||||
}
|
||||
|
||||
Int128 divu256(Int128 *plow, Int128 *phigh, Int128 divisor);
|
||||
Int128 divs256(Int128 *plow, Int128 *phigh, Int128 divisor);
|
||||
#endif
|
||||
|
@ -395,3 +395,54 @@ Int128 divu256(Int128 *plow, Int128 *phigh, Int128 divisor)
|
||||
return rem;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Signed 256-by-128 division.
|
||||
* Returns quotient via plow and phigh.
|
||||
* Also returns the remainder via the function return value.
|
||||
*/
|
||||
Int128 divs256(Int128 *plow, Int128 *phigh, Int128 divisor)
|
||||
{
|
||||
bool neg_quotient = false, neg_remainder = false;
|
||||
Int128 unsig_hi = *phigh, unsig_lo = *plow;
|
||||
Int128 rem;
|
||||
|
||||
if (!int128_nonneg(*phigh)) {
|
||||
neg_quotient = !neg_quotient;
|
||||
neg_remainder = !neg_remainder;
|
||||
|
||||
if (!int128_nz(unsig_lo)) {
|
||||
unsig_hi = int128_neg(unsig_hi);
|
||||
} else {
|
||||
unsig_hi = int128_not(unsig_hi);
|
||||
unsig_lo = int128_neg(unsig_lo);
|
||||
}
|
||||
}
|
||||
|
||||
if (!int128_nonneg(divisor)) {
|
||||
neg_quotient = !neg_quotient;
|
||||
|
||||
divisor = int128_neg(divisor);
|
||||
}
|
||||
|
||||
rem = divu256(&unsig_lo, &unsig_hi, divisor);
|
||||
|
||||
if (neg_quotient) {
|
||||
if (!int128_nz(unsig_lo)) {
|
||||
*phigh = int128_neg(unsig_hi);
|
||||
*plow = int128_zero();
|
||||
} else {
|
||||
*phigh = int128_not(unsig_hi);
|
||||
*plow = int128_neg(unsig_lo);
|
||||
}
|
||||
} else {
|
||||
*phigh = unsig_hi;
|
||||
*plow = unsig_lo;
|
||||
}
|
||||
|
||||
if (neg_remainder) {
|
||||
return int128_neg(rem);
|
||||
} else {
|
||||
return rem;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user