Skip to content

Commit

Permalink
softfloat: Add float to 16bit integer conversions.
Browse files Browse the repository at this point in the history
ARMv8 requires support for converting 32 and 64bit floating point
values to signed and unsigned 16bit integers.

Signed-off-by: Will Newton <[email protected]>
[PMM: updated not to incorrectly set Inexact for Invalid inputs]
Signed-off-by: Peter Maydell <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
  • Loading branch information
Will Newton authored and pm215 committed Jan 8, 2014
1 parent 38970ef commit f581bf5
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
80 changes: 80 additions & 0 deletions fpu/softfloat.c
Original file line number Diff line number Diff line change
Expand Up @@ -6491,6 +6491,46 @@ uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
return res;
}

int_fast16_t float32_to_int16(float32 a STATUS_PARAM)
{
int32_t v;
int_fast16_t res;
int old_exc_flags = get_float_exception_flags(status);

v = float32_to_int32(a STATUS_VAR);
if (v < -0x8000) {
res = -0x8000;
} else if (v > 0x7fff) {
res = 0x7fff;
} else {
return v;
}

set_float_exception_flags(old_exc_flags, status);
float_raise(float_flag_invalid STATUS_VAR);
return res;
}

uint_fast16_t float32_to_uint16(float32 a STATUS_PARAM)
{
int32_t v;
uint_fast16_t res;
int old_exc_flags = get_float_exception_flags(status);

v = float32_to_int32(a STATUS_VAR);
if (v < 0) {
res = 0;
} else if (v > 0xffff) {
res = 0xffff;
} else {
return v;
}

set_float_exception_flags(old_exc_flags, status);
float_raise(float_flag_invalid STATUS_VAR);
return res;
}

uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM)
{
int64_t v;
Expand Down Expand Up @@ -6545,6 +6585,46 @@ uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
return res;
}

int_fast16_t float64_to_int16(float64 a STATUS_PARAM)
{
int64_t v;
int_fast16_t res;
int old_exc_flags = get_float_exception_flags(status);

v = float64_to_int32(a STATUS_VAR);
if (v < -0x8000) {
res = -0x8000;
} else if (v > 0x7fff) {
res = 0x7fff;
} else {
return v;
}

set_float_exception_flags(old_exc_flags, status);
float_raise(float_flag_invalid STATUS_VAR);
return res;
}

uint_fast16_t float64_to_uint16(float64 a STATUS_PARAM)
{
int64_t v;
uint_fast16_t res;
int old_exc_flags = get_float_exception_flags(status);

v = float64_to_int32(a STATUS_VAR);
if (v < 0) {
res = 0;
} else if (v > 0xffff) {
res = 0xffff;
} else {
return v;
}

set_float_exception_flags(old_exc_flags, status);
float_raise(float_flag_invalid STATUS_VAR);
return res;
}

uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM)
{
int64_t v;
Expand Down
4 changes: 4 additions & 0 deletions include/fpu/softfloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ extern const float16 float16_default_nan;
/*----------------------------------------------------------------------------
| Software IEC/IEEE single-precision conversion routines.
*----------------------------------------------------------------------------*/
int_fast16_t float32_to_int16(float32 STATUS_PARAM);
uint_fast16_t float32_to_uint16(float32 STATUS_PARAM);
int_fast16_t float32_to_int16_round_to_zero(float32 STATUS_PARAM);
uint_fast16_t float32_to_uint16_round_to_zero(float32 STATUS_PARAM);
int32 float32_to_int32( float32 STATUS_PARAM );
Expand Down Expand Up @@ -371,6 +373,8 @@ extern const float32 float32_default_nan;
/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision conversion routines.
*----------------------------------------------------------------------------*/
int_fast16_t float64_to_int16(float64 STATUS_PARAM);
uint_fast16_t float64_to_uint16(float64 STATUS_PARAM);
int_fast16_t float64_to_int16_round_to_zero(float64 STATUS_PARAM);
uint_fast16_t float64_to_uint16_round_to_zero(float64 STATUS_PARAM);
int32 float64_to_int32( float64 STATUS_PARAM );
Expand Down

0 comments on commit f581bf5

Please sign in to comment.