[v3,2/2] soft-fp: Add inplementation for 128 bit self-contained

Message ID f5f7f69c0d34e9eb97a598636a73eb2bd26c05f3.1541048728.git.zongbox@gmail.com
State New, archived
Headers

Commit Message

Zong Li Nov. 1, 2018, 5:10 a.m. UTC
  Here only add the implementation when building the RV32 port.

These macros are used when the following situations occur at the same
time: soft-fp fma, ldbl-128 and 32-bit _FP_W_TYPE_SIZE. The RISC-V
32-bit port is the first port which use all three together.

This is the building flow about the situation:
When building soft-fp/s_fmal.c, there uses the FP_FMA_Q in __fmal.
The _FP_W_TYPE_SIZE is defined to 32-bit in sysdeps/riscv/sfp-machine.h,
so the FP_FMA_Q was defined to _FP_FMA (Q, 4, 8, R, X, Y, Z) in
soft-fp/quad.h.

Something in the soft-fp/quad.h:
 #if _FP_W_TYPE_SIZE < 64
    # define FP_FMA_Q(R, X, Y, Z)    _FP_FMA (Q, 4, 8, R, X, Y, Z)
 #else
    # define FP_FMA_Q(R, X, Y, Z)    _FP_FMA (Q, 2, 4, R, X, Y, Z)
 #endif

Finally, in _FP_FMA (fs, wc, dwc, R, X, Y, Z), it will use the
_FP_FRAC_HIGHBIT_DW_##dwc macro, and it will be expanded to
_FP_FRAC_HIGHBIT_DW_8, but the _FP_FRAC_HIGHBIT_DW_8 is not be
implemented in soft-fp/op-8.h. there is only _FP_FRAC_HIGHBIT_DW_1,
_FP_FRAC_HIGHBIT_DW_2 and _FP_FRAC_HIGHBIT_DW_4 in the
soft-fp/op-*.h.

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

	* soft-fp/op-8.h (_FP_FRAC_SET_8, _FP_FRAC_ADD_8, _FP_FRAC_SUB_8)
	(_FP_FRAC_CLZ_8, _FP_MINFRAC_8, _FP_FRAC_NEGP_8, _FP_FRAC_ZEROP_8)
	(_FP_FRAC_HIGHBIT_DW_8, _FP_FRAC_COPY_4_8, _FP_FRAC_COPY_8_4)
	(__FP_FRAC_SET_8): Add implementation for RV32 use.
---
 ChangeLog      |  4 +++
 soft-fp/op-8.h | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+)
  

Comments

Joseph Myers Nov. 1, 2018, 6:22 p.m. UTC | #1
Thanks, committed.
  
Kito Cheng Nov. 2, 2018, 9:22 a.m. UTC | #2
Hi Joseph:

(Apology if you revive this mail twice, I forgot change to plain text
mode in my gmail)

This patch and patch for soft-fp/op-4.h[1] also needed for libgcc
(libgcc/soft-fp/op-4.h, libgcc/soft-fp/op-8.h), could you commit those
two patches to gcc too?

Thanks :)

[1] https://www.sourceware.org/ml/libc-alpha/2018-11/msg00010.html

On Fri, Nov 2, 2018 at 2:22 AM Joseph Myers <joseph@codesourcery.com> wrote:
>> Thanks, committed.
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
  
Joseph Myers Nov. 2, 2018, 1:19 p.m. UTC | #3
On Fri, 2 Nov 2018, Kito Cheng wrote:

> This patch and patch for soft-fp/op-4.h[1] also needed for libgcc
> (libgcc/soft-fp/op-4.h, libgcc/soft-fp/op-8.h), could you commit those
> two patches to gcc too?

I advise testing and proposing a GCC patch to update *all* the files 
coming from soft-fp to their current versions in glibc (not just these two 
patches).
  
Kito Cheng Nov. 3, 2018, 3:15 a.m. UTC | #4
Hi Joseph:

> I advise testing and proposing a GCC patch to update *all* the files
> coming from soft-fp to their current versions in glibc (not just these two
> patches).

Sounds good to me, I've compare the soft-float folder in gcc and
glibc, fortunately here is only 4 difference,
list of changes in glibc/soft-fp in following section, including its
corresponding git sha1, I don't list file changes
which only update copyright years.

I can testing following changes on riscv* and nds32 target, but I am
not sure should we also test other arch before send a patch?

soft-fp/op-4.h
  - soft-fp: Use temporary variable in FP_FRAC_SUB_3/FP_FRAC_SUB_4
    - ff48ea6787526d7e669af93ce2681b911d39675c
soft-fp/op-8.h
  - soft-fp: Add implementation for 128 bit self-contained
    - af1d5782c1e3a635fdd13d6688be64de7759857c
soft-fp/op-common.h
- Add FP_TRUNC_COOKED
- Add narrowing multiply functions.
   - 69a01461ee1417578d2ba20aac935828b50f1118

soft-fp/extended.h
soft-fp/half.h
soft-fp/single.h
soft-fp/double.h
soft-fp/quad.h
- __attribute__ ((packed)) removed
  - Do not use packed structures in soft-fp.
    - 049375e2b5fc707436fd5d80337c253beededb2d
  
Joseph Myers Nov. 5, 2018, 4:17 p.m. UTC | #5
On Sat, 3 Nov 2018, Kito Cheng wrote:

> I can testing following changes on riscv* and nds32 target, but I am
> not sure should we also test other arch before send a patch?

I think testing on one architecture suffices - but the patch must update 
*all* soft-fp files in GCC that come from glibc with copies of the glibc 
versions, so that they become byte-identical to the glibc versions again - 
not just the files with changes other than copyright dates.
  
Kito Cheng Nov. 6, 2018, 5:54 a.m. UTC | #6
Hi Joseph:

> I think testing on one architecture suffices - but the patch must update
> *all* soft-fp files in GCC that come from glibc with copies of the glibc
> versions, so that they become byte-identical to the glibc versions again -
> not just the files with changes other than copyright dates.

Ok, I'll prepare patch and running testing in next few days, just one more
question, here is 2 files not exist in current gcc's soft-fp, Makefile
and testit.c,
should we also copy those 2 files even it's unused for gcc to make sure
it's byte-identical with glibc version?

Thanks :)
On Tue, Nov 6, 2018 at 12:17 AM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Sat, 3 Nov 2018, Kito Cheng wrote:
>
> > I can testing following changes on riscv* and nds32 target, but I am
> > not sure should we also test other arch before send a patch?
>
> I think testing on one architecture suffices - but the patch must update
> *all* soft-fp files in GCC that come from glibc with copies of the glibc
> versions, so that they become byte-identical to the glibc versions again -
> not just the files with changes other than copyright dates.
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
  
Joseph Myers Nov. 6, 2018, 5:21 p.m. UTC | #7
On Tue, 6 Nov 2018, Kito Cheng wrote:

> Hi Joseph:
> 
> > I think testing on one architecture suffices - but the patch must update
> > *all* soft-fp files in GCC that come from glibc with copies of the glibc
> > versions, so that they become byte-identical to the glibc versions again -
> > not just the files with changes other than copyright dates.
> 
> Ok, I'll prepare patch and running testing in next few days, just one more
> question, here is 2 files not exist in current gcc's soft-fp, Makefile
> and testit.c,
> should we also copy those 2 files even it's unused for gcc to make sure
> it's byte-identical with glibc version?

No.  It's the subset of files that are present in both places that should 
be byte-identical between them.
  

Patch

diff --git a/ChangeLog b/ChangeLog
index 0cced2b..5c41833 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@ 
 
 	* soft-fp/op-4.h (_FP_FRAC_SUB_3, _FP_FRAC_SUB_4): Use temporary
 	variable to avoid overlap arguments.
+	* soft-fp/op-8.h (_FP_FRAC_SET_8, _FP_FRAC_ADD_8, _FP_FRAC_SUB_8)
+	(_FP_FRAC_CLZ_8, _FP_MINFRAC_8, _FP_FRAC_NEGP_8, _FP_FRAC_ZEROP_8)
+	(_FP_FRAC_HIGHBIT_DW_8, _FP_FRAC_COPY_4_8, _FP_FRAC_COPY_8_4)
+	(__FP_FRAC_SET_8): Add implementation for RV32 use.
 
 2018-10-31  Samuel Thibault  <samuel.thibault@ens-lyon.org>
 
diff --git a/soft-fp/op-8.h b/soft-fp/op-8.h
index ffed258..4871c49 100644
--- a/soft-fp/op-8.h
+++ b/soft-fp/op-8.h
@@ -35,6 +35,7 @@ 
 /* We need just a few things from here for op-4, if we ever need some
    other macros, they can be added.  */
 #define _FP_FRAC_DECL_8(X)	_FP_W_TYPE X##_f[8]
+#define _FP_FRAC_SET_8(X, I)    __FP_FRAC_SET_8 (X, I)
 #define _FP_FRAC_HIGH_8(X)	(X##_f[7])
 #define _FP_FRAC_LOW_8(X)	(X##_f[0])
 #define _FP_FRAC_WORD_8(X, w)	(X##_f[w])
@@ -147,4 +148,91 @@ 
     }									\
   while (0)
 
+#define _FP_FRAC_ADD_8(R, X, Y)                                             \
+  do                                                                        \
+    {                                                                       \
+      _FP_W_TYPE _FP_FRAC_ADD_8_c = 0;                                      \
+      _FP_I_TYPE _FP_FRAC_ADD_8_i;                                          \
+      for (_FP_FRAC_ADD_8_i = 0; _FP_FRAC_ADD_8_i < 8; ++_FP_FRAC_ADD_8_i)  \
+        {                                                                   \
+          R##_f[_FP_FRAC_ADD_8_i]                                           \
+            = (X##_f[_FP_FRAC_ADD_8_i] + Y##_f[_FP_FRAC_ADD_8_i]            \
+               + _FP_FRAC_ADD_8_c);                                         \
+          _FP_FRAC_ADD_8_c                                                  \
+            = (_FP_FRAC_ADD_8_c                                             \
+               ? R##_f[_FP_FRAC_ADD_8_i] <= X##_f[_FP_FRAC_ADD_8_i]         \
+               : R##_f[_FP_FRAC_ADD_8_i] < X##_f[_FP_FRAC_ADD_8_i]);        \
+        }                                                                   \
+    }                                                                       \
+  while (0)
+
+#define _FP_FRAC_SUB_8(R, X, Y)                                             \
+  do                                                                        \
+    {                                                                       \
+      _FP_W_TYPE _FP_FRAC_SUB_8_tmp[8];                                     \
+      _FP_W_TYPE _FP_FRAC_SUB_8_c = 0;                                      \
+      _FP_I_TYPE _FP_FRAC_SUB_8_i;                                          \
+      for (_FP_FRAC_SUB_8_i = 0; _FP_FRAC_SUB_8_i < 8; ++_FP_FRAC_SUB_8_i)  \
+        {                                                                   \
+          _FP_FRAC_SUB_8_tmp[_FP_FRAC_SUB_8_i]                              \
+            = (X##_f[_FP_FRAC_SUB_8_i] - Y##_f[_FP_FRAC_SUB_8_i]            \
+               - _FP_FRAC_SUB_8_c);                                         \
+          _FP_FRAC_SUB_8_c                                                  \
+            = (_FP_FRAC_SUB_8_c                                             \
+               ? (_FP_FRAC_SUB_8_tmp[_FP_FRAC_SUB_8_i]                      \
+                  >= X##_f[_FP_FRAC_SUB_8_i])                               \
+               : (_FP_FRAC_SUB_8_tmp[_FP_FRAC_SUB_8_i]                      \
+                  > X##_f[_FP_FRAC_SUB_8_i]));                              \
+        }                                                                   \
+      for (_FP_FRAC_SUB_8_i = 0; _FP_FRAC_SUB_8_i < 8; ++_FP_FRAC_SUB_8_i)  \
+        R##_f[_FP_FRAC_SUB_8_i] = _FP_FRAC_SUB_8_tmp[_FP_FRAC_SUB_8_i];     \
+    }                                                                       \
+  while (0)
+
+#define _FP_FRAC_CLZ_8(R, X)                                                \
+  do                                                                        \
+    {                                                                       \
+      _FP_I_TYPE _FP_FRAC_CLZ_8_i;                                          \
+      for (_FP_FRAC_CLZ_8_i = 7; _FP_FRAC_CLZ_8_i > 0; _FP_FRAC_CLZ_8_i--)  \
+        if (X##_f[_FP_FRAC_CLZ_8_i])                                        \
+          break;                                                            \
+      __FP_CLZ ((R), X##_f[_FP_FRAC_CLZ_8_i]);                              \
+      (R) += _FP_W_TYPE_SIZE * (7 - _FP_FRAC_CLZ_8_i);                      \
+    }                                                                       \
+  while (0)
+
+#define _FP_MINFRAC_8   0, 0, 0, 0, 0, 0, 0, 1
+
+#define _FP_FRAC_NEGP_8(X)      ((_FP_WS_TYPE) X##_f[7] < 0)
+#define _FP_FRAC_ZEROP_8(X)                                             \
+  ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]                           \
+    | X##_f[4] | X##_f[5] | X##_f[6] | X##_f[7]) == 0)
+#define _FP_FRAC_HIGHBIT_DW_8(fs, X)                                    \
+  (_FP_FRAC_HIGH_DW_##fs (X) & _FP_HIGHBIT_DW_##fs)
+
+#define _FP_FRAC_COPY_4_8(D, S)                           \
+  do                                                      \
+    {                                                     \
+      D##_f[0] = S##_f[0];                                \
+      D##_f[1] = S##_f[1];                                \
+      D##_f[2] = S##_f[2];                                \
+      D##_f[3] = S##_f[3];                                \
+    }                                                     \
+  while (0)
+
+#define _FP_FRAC_COPY_8_4(D, S)                           \
+  do                                                      \
+    {                                                     \
+      D##_f[0] = S##_f[0];                                \
+      D##_f[1] = S##_f[1];                                \
+      D##_f[2] = S##_f[2];                                \
+      D##_f[3] = S##_f[3];                                \
+      D##_f[4] = D##_f[5] = D##_f[6] = D##_f[7]= 0;       \
+    }                                                     \
+  while (0)
+
+#define __FP_FRAC_SET_8(X, I7, I6, I5, I4, I3, I2, I1, I0)             \
+  (X##_f[7] = I7, X##_f[6] = I6, X##_f[5] = I5, X##_f[4] = I4,         \
+   X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
+
 #endif /* !SOFT_FP_OP_8_H */