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 divu256(Int128 *plow, Int128 *phigh, Int128 divisor);
|
||||||
|
Int128 divs256(Int128 *plow, Int128 *phigh, Int128 divisor);
|
||||||
#endif
|
#endif
|
||||||
|
@ -395,3 +395,54 @@ Int128 divu256(Int128 *plow, Int128 *phigh, Int128 divisor)
|
|||||||
return rem;
|
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