aboutsummaryrefslogtreecommitdiff
path: root/fpu/softfloat-parts-addsub.c.inc
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2020-10-22 15:22:55 -0700
committerRichard Henderson <richard.henderson@linaro.org>2021-05-16 07:13:51 -0500
commitda10a9074a630c1b1cfa9df5f510bbfdd3f7d327 (patch)
treee73126150dad6c83486acaa1d20383877d94e65b /fpu/softfloat-parts-addsub.c.inc
parentcb3ad0365fb17f679c69057f384f1f4928c19647 (diff)
softfloat: Move addsub_floats to softfloat-parts.c.inc
In preparation for implementing multiple sizes. Rename to parts_addsub, split out parts_add/sub_normal for future reuse with muladd. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'fpu/softfloat-parts-addsub.c.inc')
-rw-r--r--fpu/softfloat-parts-addsub.c.inc62
1 files changed, 62 insertions, 0 deletions
diff --git a/fpu/softfloat-parts-addsub.c.inc b/fpu/softfloat-parts-addsub.c.inc
new file mode 100644
index 0000000000..ae5c1017c5
--- /dev/null
+++ b/fpu/softfloat-parts-addsub.c.inc
@@ -0,0 +1,62 @@
+/*
+ * Floating point arithmetic implementation
+ *
+ * The code in this source file is derived from release 2a of the SoftFloat
+ * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
+ * some later contributions) are provided under that license, as detailed below.
+ * It has subsequently been modified by contributors to the QEMU Project,
+ * so some portions are provided under:
+ * the SoftFloat-2a license
+ * the BSD license
+ * GPL-v2-or-later
+ *
+ * Any future contributions to this file after December 1st 2014 will be
+ * taken to be licensed under the Softfloat-2a license unless specifically
+ * indicated otherwise.
+ */
+
+static void partsN(add_normal)(FloatPartsN *a, FloatPartsN *b)
+{
+ int exp_diff = a->exp - b->exp;
+
+ if (exp_diff > 0) {
+ frac_shrjam(b, exp_diff);
+ } else if (exp_diff < 0) {
+ frac_shrjam(a, -exp_diff);
+ a->exp = b->exp;
+ }
+
+ if (frac_add(a, a, b)) {
+ frac_shrjam(a, 1);
+ a->frac_hi |= DECOMPOSED_IMPLICIT_BIT;
+ a->exp += 1;
+ }
+}
+
+static bool partsN(sub_normal)(FloatPartsN *a, FloatPartsN *b)
+{
+ int exp_diff = a->exp - b->exp;
+ int shift;
+
+ if (exp_diff > 0) {
+ frac_shrjam(b, exp_diff);
+ frac_sub(a, a, b);
+ } else if (exp_diff < 0) {
+ a->exp = b->exp;
+ a->sign ^= 1;
+ frac_shrjam(a, -exp_diff);
+ frac_sub(a, b, a);
+ } else if (frac_sub(a, a, b)) {
+ /* Overflow means that A was less than B. */
+ frac_neg(a);
+ a->sign ^= 1;
+ }
+
+ shift = frac_normalize(a);
+ if (likely(shift < N)) {
+ a->exp -= shift;
+ return true;
+ }
+ a->cls = float_class_zero;
+ return false;
+}