Browse Source

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>
pull/213/head
Lucas Mateus Castro (alqotel) 4 years ago
committed by Daniel Henrique Barboza
parent
commit
62c9947fb7
  1. 1
      include/qemu/host-utils.h
  2. 51
      util/host-utils.c

1
include/qemu/host-utils.h

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

51
util/host-utils.c

@ -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…
Cancel
Save