aboutsummaryrefslogtreecommitdiff
path: root/fpu/softfloat-parts.c.inc
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2020-11-14 19:20:36 -0800
committerRichard Henderson <richard.henderson@linaro.org>2021-06-03 13:59:34 -0700
commit6eb169b89a509321c985346cea278d758108ada5 (patch)
tree5456ea10fbb8fa5ad2e6da094ae7e26ffe58557a /fpu/softfloat-parts.c.inc
parentceebc129e51ea3aa8dc81321046ed42432c49511 (diff)
softfloat: Move compare_floats to softfloat-parts.c.inc
Rename to parts$N_compare. Rename all of the intermediate functions to ftype_do_compare. Rename the hard-float functions to ftype_hs_compare. Convert float128 to FloatParts128. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'fpu/softfloat-parts.c.inc')
-rw-r--r--fpu/softfloat-parts.c.inc57
1 files changed, 57 insertions, 0 deletions
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index b9094768db..3dacb5b4f0 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1018,3 +1018,60 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
}
return cmp < 0 ? b : a;
}
+
+/*
+ * Floating point compare
+ */
+static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b,
+ float_status *s, bool is_quiet)
+{
+ int ab_mask = float_cmask(a->cls) | float_cmask(b->cls);
+ int cmp;
+
+ if (likely(ab_mask == float_cmask_normal)) {
+ if (a->sign != b->sign) {
+ goto a_sign;
+ }
+ if (a->exp != b->exp) {
+ cmp = a->exp < b->exp ? -1 : 1;
+ } else {
+ cmp = frac_cmp(a, b);
+ }
+ if (a->sign) {
+ cmp = -cmp;
+ }
+ return cmp;
+ }
+
+ if (unlikely(ab_mask & float_cmask_anynan)) {
+ if (!is_quiet || (ab_mask & float_cmask_snan)) {
+ float_raise(float_flag_invalid, s);
+ }
+ return float_relation_unordered;
+ }
+
+ if (ab_mask & float_cmask_zero) {
+ if (ab_mask == float_cmask_zero) {
+ return float_relation_equal;
+ } else if (a->cls == float_class_zero) {
+ goto b_sign;
+ } else {
+ goto a_sign;
+ }
+ }
+
+ if (ab_mask == float_cmask_inf) {
+ if (a->sign == b->sign) {
+ return float_relation_equal;
+ }
+ } else if (b->cls == float_class_inf) {
+ goto b_sign;
+ } else {
+ g_assert(a->cls == float_class_inf);
+ }
+
+ a_sign:
+ return a->sign ? float_relation_less : float_relation_greater;
+ b_sign:
+ return b->sign ? float_relation_greater : float_relation_less;
+}