mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-08-26 22:23:12 -04:00
host-utils: Introduce signed saturation primitives
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
a93d477899
commit
1649553313
2 changed files with 64 additions and 16 deletions
|
|
@ -1109,10 +1109,7 @@ void HELPER(gvec_ssadd32)(void *d, void *a, void *b, uint32_t desc)
|
|||
for (i = 0; i < oprsz; i += sizeof(int32_t)) {
|
||||
int32_t ai = *(int32_t *)(a + i);
|
||||
int32_t bi = *(int32_t *)(b + i);
|
||||
int32_t di;
|
||||
if (sadd32_overflow(ai, bi, &di)) {
|
||||
di = (di < 0 ? INT32_MAX : INT32_MIN);
|
||||
}
|
||||
int32_t di = sadd32_saturate(ai, bi);
|
||||
*(int32_t *)(d + i) = di;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
|
|
@ -1126,10 +1123,7 @@ void HELPER(gvec_ssadd64)(void *d, void *a, void *b, uint32_t desc)
|
|||
for (i = 0; i < oprsz; i += sizeof(int64_t)) {
|
||||
int64_t ai = *(int64_t *)(a + i);
|
||||
int64_t bi = *(int64_t *)(b + i);
|
||||
int64_t di;
|
||||
if (sadd64_overflow(ai, bi, &di)) {
|
||||
di = (di < 0 ? INT64_MAX : INT64_MIN);
|
||||
}
|
||||
int64_t di = sadd64_saturate(ai, bi);
|
||||
*(int64_t *)(d + i) = di;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
|
|
@ -1177,10 +1171,7 @@ void HELPER(gvec_sssub32)(void *d, void *a, void *b, uint32_t desc)
|
|||
for (i = 0; i < oprsz; i += sizeof(int32_t)) {
|
||||
int32_t ai = *(int32_t *)(a + i);
|
||||
int32_t bi = *(int32_t *)(b + i);
|
||||
int32_t di;
|
||||
if (ssub32_overflow(ai, bi, &di)) {
|
||||
di = (di < 0 ? INT32_MAX : INT32_MIN);
|
||||
}
|
||||
int32_t di = ssub32_saturate(ai, bi);
|
||||
*(int32_t *)(d + i) = di;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
|
|
@ -1194,10 +1185,7 @@ void HELPER(gvec_sssub64)(void *d, void *a, void *b, uint32_t desc)
|
|||
for (i = 0; i < oprsz; i += sizeof(int64_t)) {
|
||||
int64_t ai = *(int64_t *)(a + i);
|
||||
int64_t bi = *(int64_t *)(b + i);
|
||||
int64_t di;
|
||||
if (ssub64_overflow(ai, bi, &di)) {
|
||||
di = (di < 0 ? INT64_MAX : INT64_MIN);
|
||||
}
|
||||
int64_t di = ssub64_saturate(ai, bi);
|
||||
*(int64_t *)(d + i) = di;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
|
|
|
|||
|
|
@ -606,6 +606,66 @@ static inline bool umul64_overflow(uint64_t x, uint64_t y, uint64_t *ret)
|
|||
return __builtin_mul_overflow(x, y, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* sadd32_saturate - addition with saturation
|
||||
* @x, @y: addends
|
||||
*
|
||||
* Computes @x + @y, and saturates rathern than truncating the result.
|
||||
*/
|
||||
static inline int32_t sadd32_saturate(int32_t x, int32_t y)
|
||||
{
|
||||
int32_t ret;
|
||||
if (sadd32_overflow(x, y, &ret)) {
|
||||
ret = y < 0 ? INT32_MIN : INT32_MAX;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sadd64_saturate - addition with saturation
|
||||
* @x, @y: addends
|
||||
*
|
||||
* Computes @x + @y, and saturates rathern than truncating the result.
|
||||
*/
|
||||
static inline int64_t sadd64_saturate(int64_t x, int64_t y)
|
||||
{
|
||||
int64_t ret;
|
||||
if (sadd64_overflow(x, y, &ret)) {
|
||||
ret = y < 0 ? INT64_MIN : INT64_MAX;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ssub32_saturate - subtraction with saturation
|
||||
* @x, @y: addends
|
||||
*
|
||||
* Computes @x + @y, and saturates rathern than truncating the result.
|
||||
*/
|
||||
static inline bool ssub32_saturate(int32_t x, int32_t y)
|
||||
{
|
||||
int32_t ret;
|
||||
if (ssub32_overflow(x, y, &ret)) {
|
||||
ret = x < 0 ? INT32_MAX : INT32_MIN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ssub64_saturate - subtraction with saturation
|
||||
* @x, @y: addends
|
||||
*
|
||||
* Computes @x + @y, and saturates rathern than truncating the result.
|
||||
*/
|
||||
static inline bool ssub64_saturate(int64_t x, int64_t y)
|
||||
{
|
||||
int64_t ret;
|
||||
if (ssub64_overflow(x, y, &ret)) {
|
||||
ret = x < 0 ? INT64_MAX : INT64_MIN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unsigned 128x64 multiplication.
|
||||
* Returns true if the result got truncated to 128 bits.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue