]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
soft-fp: Use temporary variable in FP_FRAC_SUB_3/FP_FRAC_SUB_4
authorZong Li <zong@andestech.com>
Thu, 1 Nov 2018 17:34:39 +0000 (17:34 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Thu, 1 Nov 2018 17:34:39 +0000 (17:34 +0000)
In FRAC_SUB_3(R, X, Y) and FRAC_SUB_4(R,, X, Y), it reference both
the X[N] and X[N] after R[N] have been set. If one of the X and Y is
the same address with R, the result of the calculation is wrong,
because the value of the original X and Y are overwritten.

In glibc, there are two places use FRAC_SUB and occurs the overlap.
The first is _FP_DIV_MEAT_N_loop in op-common.h, it uses the source
_FP_DIV_MEAT_N_loop_u as the destination. This macro only be used
when N is one(_FP_DIV_MEAT_1_loop) and then the _FP_FRAC_SUB_##wc
extend to _FP_FRAC_SUB_1 in this macro. so it also work because
_FP_FRAC_SUB_1 has no overlap problem in its implementation.
The second places is _FP_DIV_MEAT_4_udiv, the original value of X##_f[0]
is overwritten before the calculatation.

In FRAC_SUB_1 and FRAC_SUB_2, there don't refer the source after
destination have been set, so they have no problem.

After this modification, we can pass the soft floating testing of glibc
testsuites on RV32.

* soft-fp/op-4.h (_FP_FRAC_SUB_3, _FP_FRAC_SUB_4): Use temporary
variable to avoid overlap arguments.

ChangeLog
soft-fp/op-4.h

index 83a28dbb2f4936bb8b5b85418a88f585da22011d..3bbd5628c3e211174b4be75c8416658363e68331 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-01  Zong Li  <zong@andestech.com>
+
+       * soft-fp/op-4.h (_FP_FRAC_SUB_3, _FP_FRAC_SUB_4): Use temporary
+       variable to avoid overlap arguments.
+
 2018-11-01  Joseph Myers  <joseph@codesourcery.com>
 
        * posix/bug-regex22.c (main): Use puts with distinct error
index 01b87d01a117aa3f2ebb4c7074cfe36c3326a1ea..b429801687200d2dcb4d30a9fa7e82b88fbbc0c6 100644 (file)
 #endif
 
 #ifndef __FP_FRAC_SUB_3
-# define __FP_FRAC_SUB_3(r2, r1, r0, x2, x1, x0, y2, y1, y0)   \
-  do                                                           \
-    {                                                          \
-      _FP_W_TYPE __FP_FRAC_SUB_3_c1, __FP_FRAC_SUB_3_c2;       \
-      r0 = x0 - y0;                                            \
-      __FP_FRAC_SUB_3_c1 = r0 > x0;                            \
-      r1 = x1 - y1;                                            \
-      __FP_FRAC_SUB_3_c2 = r1 > x1;                            \
-      r1 -= __FP_FRAC_SUB_3_c1;                                        \
-      __FP_FRAC_SUB_3_c2 |= __FP_FRAC_SUB_3_c1 && (y1 == x1);  \
-      r2 = x2 - y2 - __FP_FRAC_SUB_3_c2;                       \
-    }                                                          \
+# define __FP_FRAC_SUB_3(r2, r1, r0, x2, x1, x0, y2, y1, y0)    \
+  do                                                            \
+    {                                                           \
+      _FP_W_TYPE __FP_FRAC_SUB_3_tmp[2];                        \
+      _FP_W_TYPE __FP_FRAC_SUB_3_c1, __FP_FRAC_SUB_3_c2;        \
+      __FP_FRAC_SUB_3_tmp[0] = x0 - y0;                         \
+      __FP_FRAC_SUB_3_c1 = __FP_FRAC_SUB_3_tmp[0] > x0;         \
+      __FP_FRAC_SUB_3_tmp[1] = x1 - y1;                         \
+      __FP_FRAC_SUB_3_c2 = __FP_FRAC_SUB_3_tmp[1] > x1;         \
+      __FP_FRAC_SUB_3_tmp[1] -= __FP_FRAC_SUB_3_c1;             \
+      __FP_FRAC_SUB_3_c2 |= __FP_FRAC_SUB_3_c1 && (y1 == x1);   \
+      r2 = x2 - y2 - __FP_FRAC_SUB_3_c2;                        \
+      r1 = __FP_FRAC_SUB_3_tmp[1];                              \
+      r0 = __FP_FRAC_SUB_3_tmp[0];                              \
+    }                                                           \
   while (0)
 #endif
 
 #ifndef __FP_FRAC_SUB_4
 # define __FP_FRAC_SUB_4(r3, r2, r1, r0, x3, x2, x1, x0, y3, y2, y1, y0) \
-  do                                                                   \
-    {                                                                  \
-      _FP_W_TYPE __FP_FRAC_SUB_4_c1, __FP_FRAC_SUB_4_c2;               \
-      _FP_W_TYPE __FP_FRAC_SUB_4_c3;                                   \
-      r0 = x0 - y0;                                                    \
-      __FP_FRAC_SUB_4_c1 = r0 > x0;                                    \
-      r1 = x1 - y1;                                                    \
-      __FP_FRAC_SUB_4_c2 = r1 > x1;                                    \
-      r1 -= __FP_FRAC_SUB_4_c1;                                                \
-      __FP_FRAC_SUB_4_c2 |= __FP_FRAC_SUB_4_c1 && (y1 == x1);          \
-      r2 = x2 - y2;                                                    \
-      __FP_FRAC_SUB_4_c3 = r2 > x2;                                    \
-      r2 -= __FP_FRAC_SUB_4_c2;                                                \
-      __FP_FRAC_SUB_4_c3 |= __FP_FRAC_SUB_4_c2 && (y2 == x2);          \
-      r3 = x3 - y3 - __FP_FRAC_SUB_4_c3;                               \
-    }                                                                  \
+  do                                                                     \
+    {                                                                    \
+      _FP_W_TYPE __FP_FRAC_SUB_4_tmp[3];                                 \
+      _FP_W_TYPE __FP_FRAC_SUB_4_c1, __FP_FRAC_SUB_4_c2;                 \
+      _FP_W_TYPE __FP_FRAC_SUB_4_c3;                                     \
+      __FP_FRAC_SUB_4_tmp[0] = x0 - y0;                                  \
+      __FP_FRAC_SUB_4_c1 = __FP_FRAC_SUB_4_tmp[0] > x0;                  \
+      __FP_FRAC_SUB_4_tmp[1] = x1 - y1;                                  \
+      __FP_FRAC_SUB_4_c2 = __FP_FRAC_SUB_4_tmp[1] > x1;                  \
+      __FP_FRAC_SUB_4_tmp[1] -= __FP_FRAC_SUB_4_c1;                      \
+      __FP_FRAC_SUB_4_c2 |= __FP_FRAC_SUB_4_c1 && (y1 == x1);            \
+      __FP_FRAC_SUB_4_tmp[2] = x2 - y2;                                  \
+      __FP_FRAC_SUB_4_c3 = __FP_FRAC_SUB_4_tmp[2] > x2;                  \
+      __FP_FRAC_SUB_4_tmp[2] -= __FP_FRAC_SUB_4_c2;                      \
+      __FP_FRAC_SUB_4_c3 |= __FP_FRAC_SUB_4_c2 && (y2 == x2);            \
+      r3 = x3 - y3 - __FP_FRAC_SUB_4_c3;                                 \
+      r2 = __FP_FRAC_SUB_4_tmp[2];                                       \
+      r1 = __FP_FRAC_SUB_4_tmp[1];                                       \
+      r0 = __FP_FRAC_SUB_4_tmp[0];                                       \
+    }                                                                    \
   while (0)
 #endif