Performance results included in the following commit's log. Signed-off-by: Emilio G. Cota <c...@braap.org> --- include/fpu/hostfloat.h | 4 ++++ include/fpu/softfloat.h | 6 ++---- fpu/hostfloat.c | 36 ++++++++++++++++++++++++++++++++++++ fpu/softfloat.c | 34 ++++++++++++++++++++-------------- 4 files changed, 62 insertions(+), 18 deletions(-)
diff --git a/include/fpu/hostfloat.h b/include/fpu/hostfloat.h index b1e0689..aa555f6 100644 --- a/include/fpu/hostfloat.h +++ b/include/fpu/hostfloat.h @@ -17,6 +17,8 @@ float32 float32_mul(float32 a, float32 b, float_status *status); float32 float32_div(float32 a, float32 b, float_status *status); float32 float32_muladd(float32 a, float32 b, float32 c, int f, float_status *s); float32 float32_sqrt(float32 a, float_status *status); +int float32_compare(float32 a, float32 b, float_status *s); +int float32_compare_quiet(float32 a, float32 b, float_status *s); float64 float64_add(float64 a, float64 b, float_status *status); float64 float64_sub(float64 a, float64 b, float_status *status); @@ -24,5 +26,7 @@ float64 float64_mul(float64 a, float64 b, float_status *status); float64 float64_div(float64 a, float64 b, float_status *status); float64 float64_muladd(float64 a, float64 b, float64 c, int f, float_status *s); float64 float64_sqrt(float64 a, float_status *status); +int float64_compare(float64 a, float64 b, float_status *s); +int float64_compare_quiet(float64 a, float64 b, float_status *s); #endif /* HOSTFLOAT_H */ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 8d5a50a..cb57942 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -359,8 +359,7 @@ int float32_eq_quiet(float32, float32, float_status *status); int float32_le_quiet(float32, float32, float_status *status); int float32_lt_quiet(float32, float32, float_status *status); int float32_unordered_quiet(float32, float32, float_status *status); -int float32_compare(float32, float32, float_status *status); -int float32_compare_quiet(float32, float32, float_status *status); +int soft_float32_compare(float32, float32, bool is_quiet, float_status *status); float32 float32_min(float32, float32, float_status *status); float32 float32_max(float32, float32, float_status *status); float32 float32_minnum(float32, float32, float_status *status); @@ -498,8 +497,7 @@ int float64_eq_quiet(float64, float64, float_status *status); int float64_le_quiet(float64, float64, float_status *status); int float64_lt_quiet(float64, float64, float_status *status); int float64_unordered_quiet(float64, float64, float_status *status); -int float64_compare(float64, float64, float_status *status); -int float64_compare_quiet(float64, float64, float_status *status); +int soft_float64_compare(float64, float64, bool is_quiet, float_status *status); float64 float64_min(float64, float64, float_status *status); float64 float64_max(float64, float64, float_status *status); float64 float64_minnum(float64, float64, float_status *status); diff --git a/fpu/hostfloat.c b/fpu/hostfloat.c index 974bd57..139e419 100644 --- a/fpu/hostfloat.c +++ b/fpu/hostfloat.c @@ -290,3 +290,39 @@ GEN_FPU_FMA(float64_muladd, float64, double, fma, fabs, DBL_MIN) GEN_FPU_SQRT(float32_sqrt, float32, float, sqrtf) GEN_FPU_SQRT(float64_sqrt, float64, double, sqrt) #undef GEN_FPU_SQRT + +#define GEN_FPU_COMPARE(name, soft_t, host_t) \ + static inline __attribute__((always_inline)) int \ + fpu_ ## name(soft_t a, soft_t b, bool is_quiet, float_status *s) \ + { \ + soft_t ## _input_flush2(&a, &b, s); \ + if (unlikely(soft_t ## _is_any_nan(a) || \ + soft_t ## _is_any_nan(b))) { \ + return soft_ ## name(a, b, is_quiet, s); \ + } else { \ + host_t ha = soft_t ## _to_ ## host_t(a); \ + host_t hb = soft_t ## _to_ ## host_t(b); \ + \ + if (isgreater(ha, hb)) { \ + return float_relation_greater; \ + } \ + if (isless(ha, hb)) { \ + return float_relation_less; \ + } \ + return float_relation_equal; \ + } \ + } \ + \ + int name(soft_t a, soft_t b, float_status *s) \ + { \ + return fpu_ ## name(a, b, false, s); \ + } \ + \ + int name ## _quiet(soft_t a, soft_t b, float_status *s) \ + { \ + return fpu_ ## name(a, b, true, s); \ + } + +GEN_FPU_COMPARE(float32_compare, float32, float) +GEN_FPU_COMPARE(float64_compare, float64, double) +#undef GEN_FPU_COMPARE diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 096b658..1a32216 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1844,28 +1844,34 @@ static int compare_floats(FloatParts a, FloatParts b, bool is_quiet, } } -#define COMPARE(sz) \ -int float ## sz ## _compare(float ## sz a, float ## sz b, \ - float_status *s) \ +#define COMPARE(storage_class, sz) \ +storage_class int \ +soft_float ## sz ## _compare(float ## sz a, float ## sz b, \ + bool is_quiet, float_status *s) \ { \ FloatParts pa = float ## sz ## _unpack_canonical(a, s); \ FloatParts pb = float ## sz ## _unpack_canonical(b, s); \ - return compare_floats(pa, pb, false, s); \ -} \ -int float ## sz ## _compare_quiet(float ## sz a, float ## sz b, \ - float_status *s) \ -{ \ - FloatParts pa = float ## sz ## _unpack_canonical(a, s); \ - FloatParts pb = float ## sz ## _unpack_canonical(b, s); \ - return compare_floats(pa, pb, true, s); \ + return compare_floats(pa, pb, is_quiet, s); \ } -COMPARE(16) -COMPARE(32) -COMPARE(64) +COMPARE(static, 16) +COMPARE(, 32) +COMPARE(, 64) #undef COMPARE +int __attribute__((flatten)) +float16_compare(float16 a, float16 b, float_status *s) +{ + return soft_float16_compare(a, b, false, s); +} + +int __attribute__((flatten)) +float16_compare_quiet(float16 a, float16 b, float_status *s) +{ + return soft_float16_compare(a, b, true, s); +} + /* Multiply A by 2 raised to the power N. */ static FloatParts scalbn_decomposed(FloatParts a, int n, float_status *s) { -- 2.7.4