Revision 6ddbc6e4 target-arm/op_helper.c
b/target-arm/op_helper.c | ||
---|---|---|
369 | 369 |
return res; |
370 | 370 |
} |
371 | 371 |
|
372 |
/* Signed saturation. */ |
|
373 |
static inline uint32_t do_ssat(int32_t val, int shift) |
|
374 |
{ |
|
375 |
int32_t top; |
|
376 |
uint32_t mask; |
|
377 |
|
|
378 |
shift = PARAM1; |
|
379 |
top = val >> shift; |
|
380 |
mask = (1u << shift) - 1; |
|
381 |
if (top > 0) { |
|
382 |
env->QF = 1; |
|
383 |
return mask; |
|
384 |
} else if (top < -1) { |
|
385 |
env->QF = 1; |
|
386 |
return ~mask; |
|
387 |
} |
|
388 |
return val; |
|
389 |
} |
|
390 |
|
|
391 |
/* Unsigned saturation. */ |
|
392 |
static inline uint32_t do_usat(int32_t val, int shift) |
|
393 |
{ |
|
394 |
uint32_t max; |
|
395 |
|
|
396 |
shift = PARAM1; |
|
397 |
max = (1u << shift) - 1; |
|
398 |
if (val < 0) { |
|
399 |
env->QF = 1; |
|
400 |
return 0; |
|
401 |
} else if (val > max) { |
|
402 |
env->QF = 1; |
|
403 |
return max; |
|
404 |
} |
|
405 |
return val; |
|
406 |
} |
|
407 |
|
|
408 |
/* Signed saturate. */ |
|
409 |
uint32_t HELPER(ssat)(uint32_t x, uint32_t shift) |
|
410 |
{ |
|
411 |
return do_ssat(x, shift); |
|
412 |
} |
|
413 |
|
|
414 |
/* Dual halfword signed saturate. */ |
|
415 |
uint32_t HELPER(ssat16)(uint32_t x, uint32_t shift) |
|
416 |
{ |
|
417 |
uint32_t res; |
|
418 |
|
|
419 |
res = (uint16_t)do_ssat((int16_t)x, shift); |
|
420 |
res |= do_ssat(((int32_t)x) >> 16, shift) << 16; |
|
421 |
return res; |
|
422 |
} |
|
423 |
|
|
424 |
/* Unsigned saturate. */ |
|
425 |
uint32_t HELPER(usat)(uint32_t x, uint32_t shift) |
|
426 |
{ |
|
427 |
return do_usat(x, shift); |
|
428 |
} |
|
429 |
|
|
430 |
/* Dual halfword unsigned saturate. */ |
|
431 |
uint32_t HELPER(usat16)(uint32_t x, uint32_t shift) |
|
432 |
{ |
|
433 |
uint32_t res; |
|
434 |
|
|
435 |
res = (uint16_t)do_usat((int16_t)x, shift); |
|
436 |
res |= do_usat(((int32_t)x) >> 16, shift) << 16; |
|
437 |
return res; |
|
438 |
} |
Also available in: Unified diff