[soft-fp] Add support for various half-precision conversion routines

Message ID 1473263957-13858-1-git-send-email-james.greenhalgh@arm.com
State New, archived
Headers

Commit Message

James Greenhalgh Sept. 7, 2016, 3:59 p.m. UTC
  Hi,

This patch adds conversion routines required for _Float16 support in
AArch64.

These are one-step conversions to and from TImode and TFmode. We need
these on AArch64 regardless of presence of the ARMv8.2-A 16-bit floating-point
extensions, and conversion to and from DImode, which we can do natively
with the ARMv8.2-A extensions, but must emulate where they are not available.

I'm adding this to glibc as I'd like these functions imported in to GCC's
libgcc and this seems to be the upstream for that.

What I'm not clear about is whether this patch is sufficient on the glibc
side, or if I also need to wire something up in a Makefile over here?

I'm also not sure how soft-fp gets tested. These functions were tested as
part of work to enable _Float16 in GCC, so have been tested against the
suite added by Joseph Myers in
https://gcc.gnu.org/ml/gcc-patches/2016-08/msg01290.html . I know this is
a poor testing record, so any advice as to what testing is required for
soft-fp would be very much appreciated.

In the patch below, soft-fp/half.h is derived from soft-fp/single.h .
The conversion routines are derivatives of their respective SFmode
variants.

Thanks,
James

---
2016-09-07  James Greenhalgh  <james.greenhalgh@arm.com>

	* soft-fp/extendhftf2.c: New.
	* soft-fp/fixhfti.c: Likewise.
	* soft-fp/fixunshfti.c: Likewise.
	* soft-fp/floattihf.c: Likewise.
	* soft-fp/floatuntihf.c: Likewise.
	* soft-fp/half.h: Likewise.
  

Comments

Joseph Myers Sept. 7, 2016, 4:20 p.m. UTC | #1
On Wed, 7 Sep 2016, James Greenhalgh wrote:

> What I'm not clear about is whether this patch is sufficient on the glibc
> side, or if I also need to wire something up in a Makefile over here?

No, it's not expected to be wired up in a Makefile, and testing in GCC is 
appropriate in this case.

> In the patch below, soft-fp/half.h is derived from soft-fp/single.h .

You are, correctly, not including the various macros for arithmetic 
operations not using this code, but I think that means a comment to that 
effect as in <https://gcc.gnu.org/ml/gcc-patches/2009-04/msg01132.html> is 
appropriate.

> +#define _FP_FRACTBITS_H		(_FP_W_TYPE_SIZE / 2)

No, that's not right.  FRACTBITS needs to be the total number of bits in 
the internal representation of the mantissa, to work right with the CLZ 
macros.  So it must be _FP_W_TYPE_SIZE, because the representation is 
always a multiple of that.  I'd expect your present code to get extensions 
of HFmode subnormals to wider types wrong because of this.

> +#if _FP_W_TYPE_SIZE < 64
> +# define _FP_FRACTBITS_DW_H	(_FP_W_TYPE_SIZE)
> +#else
> +# define _FP_FRACTBITS_DW_H	(_FP_W_TYPE_SIZE / 2)
> +#endif

And then this must be _FP_W_TYPE_SIZE unconditionally as well (since a 
double-width multiplication result for fma can always fit in a single 
word).

> +#if _FP_W_TYPE_SIZE < 64
> +#define _FP_FRAC_HIGH_DW_H(X)	_FP_FRAC_HIGH_2 (X)
> +#else
> +#define _FP_FRAC_HIGH_DW_H(X)	_FP_FRAC_HIGH_1 (X)
> +#endif

And this should always use _FP_FRAC_HIGH_1 (though it's not actually used 
in the 1-word case).
  
Joseph Myers Sept. 7, 2016, 4:35 p.m. UTC | #2
On Wed, 7 Sep 2016, James Greenhalgh wrote:

> 2016-09-07  James Greenhalgh  <james.greenhalgh@arm.com>
> 
> 	* soft-fp/extendhftf2.c: New.
> 	* soft-fp/fixhfti.c: Likewise.
> 	* soft-fp/fixunshfti.c: Likewise.
> 	* soft-fp/floattihf.c: Likewise.
> 	* soft-fp/floatuntihf.c: Likewise.
> 	* soft-fp/half.h: Likewise.

This ChangeLog entry is missing trunctfhf2.c.

Your patch description refers to conversions to and from DImode, but they 
aren't in the patch.  One might also wonder whether a direct truncation 
from DFmode is relevant to avoid double rounding (and for that matter a 
conversion from SImode, to avoid going via DFmode; going via SFmode would 
involve double rounding).
  
James Greenhalgh Sept. 16, 2016, 10:27 a.m. UTC | #3
On Wed, Sep 07, 2016 at 04:35:25PM +0000, Joseph Myers wrote:
> On Wed, 7 Sep 2016, James Greenhalgh wrote:
> 
> > 2016-09-07  James Greenhalgh  <james.greenhalgh@arm.com>
> > 
> > 	* soft-fp/extendhftf2.c: New.
> > 	* soft-fp/fixhfti.c: Likewise.
> > 	* soft-fp/fixunshfti.c: Likewise.
> > 	* soft-fp/floattihf.c: Likewise.
> > 	* soft-fp/floatuntihf.c: Likewise.
> > 	* soft-fp/half.h: Likewise.
> 
> This ChangeLog entry is missing trunctfhf2.c.
> 
> Your patch description refers to conversions to and from DImode, but they 
> aren't in the patch.  One might also wonder whether a direct truncation 
> from DFmode is relevant to avoid double rounding (and for that matter a 
> conversion from SImode, to avoid going via DFmode; going via SFmode would 
> involve double rounding).

Hi Joseph,

An initial draft of this patch did implement these conversions. I thought
I had updated the ChangeLog, but clearly didn't. I pulled them out to get
the minimum number of new functions I needed for AArch64 support. After
https://gcc.gnu.org/ml/gcc-patches/2016-09/msg00704.html is approved,
the DI to HF conversion routines will not require a libgcc call (for AArch64).
Likewise DF to HF is handled by GCC proper.

However, as you've observed I will need to add more of these when I get on
to enabling _Float16 for AArch32, so if proposing them now would be prefered,
I'm happy to do that.

Thanks,
James
  
Joseph Myers Sept. 16, 2016, 5:12 p.m. UTC | #4
On Fri, 16 Sep 2016, James Greenhalgh wrote:

> Hi Joseph,
> 
> An initial draft of this patch did implement these conversions. I thought
> I had updated the ChangeLog, but clearly didn't. I pulled them out to get
> the minimum number of new functions I needed for AArch64 support. After
> https://gcc.gnu.org/ml/gcc-patches/2016-09/msg00704.html is approved,
> the DI to HF conversion routines will not require a libgcc call (for AArch64).
> Likewise DF to HF is handled by GCC proper.

But is DF to HF is handled *correctly* by GCC proper (avoiding double 
rounding), or is such a libgcc call actually needed to get correct 
conversions rather than going via SFmode (or is that double rounding issue 
only an issue for AArch32 or for older instruction set variants you're not 
dealing with in this patch)?

> However, as you've observed I will need to add more of these when I get on
> to enabling _Float16 for AArch32, so if proposing them now would be prefered,
> I'm happy to do that.

It's reasonable to include just the functions you need, as long as the 
write-up, the ChangeLog and the patch itself are consistent.
  

Patch

diff --git a/soft-fp/extendhftf2.c b/soft-fp/extendhftf2.c
new file mode 100644
index 0000000..6ff6438
--- /dev/null
+++ b/soft-fp/extendhftf2.c
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Return an IEEE half converted to IEEE quad
+   Copyright (C) 1997-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define FP_NO_EXACT_UNDERFLOW
+#include "soft-fp.h"
+#include "half.h"
+#include "quad.h"
+
+TFtype
+__extendhftf2 (HFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_H (A);
+  FP_DECL_Q (R);
+  TFtype r;
+
+  FP_INIT_EXCEPTIONS;
+  FP_UNPACK_RAW_H (A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_EXTEND (Q, H, 4, 1, R, A);
+#else
+  FP_EXTEND (Q, H, 2, 1, R, A);
+#endif
+  FP_PACK_RAW_Q (r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixhfti.c b/soft-fp/fixhfti.c
new file mode 100644
index 0000000..3610f4c
--- /dev/null
+++ b/soft-fp/fixhfti.c
@@ -0,0 +1,45 @@ 
+/* Software floating-point emulation.
+   Convert IEEE half to 128bit signed integer
+   Copyright (C) 2007-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "half.h"
+
+TItype
+__fixhfti (HFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_H (A);
+  UTItype r;
+
+  FP_INIT_EXCEPTIONS;
+  FP_UNPACK_RAW_H (A, a);
+  FP_TO_INT_H (r, A, TI_BITS, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixunshfti.c b/soft-fp/fixunshfti.c
new file mode 100644
index 0000000..30edbfe
--- /dev/null
+++ b/soft-fp/fixunshfti.c
@@ -0,0 +1,45 @@ 
+/* Software floating-point emulation.
+   Convert IEEE half to 128bit unsigned integer
+   Copyright (C) 2007-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "half.h"
+
+UTItype
+__fixunshfti (HFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_H (A);
+  UTItype r;
+
+  FP_INIT_EXCEPTIONS;
+  FP_UNPACK_RAW_H (A, a);
+  FP_TO_INT_H (r, A, TI_BITS, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/floattihf.c b/soft-fp/floattihf.c
new file mode 100644
index 0000000..74ac83a
--- /dev/null
+++ b/soft-fp/floattihf.c
@@ -0,0 +1,45 @@ 
+/* Software floating-point emulation.
+   Convert a 128bit signed integer to IEEE half
+   Copyright (C) 2007-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "half.h"
+
+HFtype
+__floattihf (TItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_H (A);
+  HFtype a;
+
+  FP_INIT_ROUNDMODE;
+  FP_FROM_INT_H (A, i, TI_BITS, UTItype);
+  FP_PACK_RAW_H (a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/soft-fp/floatuntihf.c b/soft-fp/floatuntihf.c
new file mode 100644
index 0000000..90e77c2
--- /dev/null
+++ b/soft-fp/floatuntihf.c
@@ -0,0 +1,45 @@ 
+/* Software floating-point emulation.
+   Convert a 128bit unsigned integer to IEEE half.
+   Copyright (C) 2007-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "half.h"
+
+HFtype
+__floatuntihf (UTItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_H (A);
+  HFtype a;
+
+  FP_INIT_ROUNDMODE;
+  FP_FROM_INT_H (A, i, TI_BITS, UTItype);
+  FP_PACK_RAW_H (a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/soft-fp/half.h b/soft-fp/half.h
new file mode 100644
index 0000000..deb4e60
--- /dev/null
+++ b/soft-fp/half.h
@@ -0,0 +1,177 @@ 
+/* Software floating-point emulation.
+   Definitions for IEEE Half Precision.
+   Copyright (C) 1997-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef SOFT_FP_HALF_H
+#define SOFT_FP_HALF_H	1
+
+#if _FP_W_TYPE_SIZE < 32
+# error "Here's a nickel kid.  Go buy yourself a real computer."
+#endif
+
+#define _FP_FRACTBITS_H		(_FP_W_TYPE_SIZE / 2)
+
+#if _FP_W_TYPE_SIZE < 64
+# define _FP_FRACTBITS_DW_H	(_FP_W_TYPE_SIZE)
+#else
+# define _FP_FRACTBITS_DW_H	(_FP_W_TYPE_SIZE / 2)
+#endif
+
+#define _FP_FRACBITS_H		11
+#define _FP_FRACXBITS_H		(_FP_FRACTBITS_H - _FP_FRACBITS_H)
+#define _FP_WFRACBITS_H		(_FP_WORKBITS + _FP_FRACBITS_H)
+#define _FP_WFRACXBITS_H	(_FP_FRACTBITS_H - _FP_WFRACBITS_H)
+#define _FP_EXPBITS_H		5
+#define _FP_EXPBIAS_H		15
+#define _FP_EXPMAX_H		31
+
+#define _FP_QNANBIT_H		((_FP_W_TYPE) 1 << (_FP_FRACBITS_H-2))
+#define _FP_QNANBIT_SH_H	((_FP_W_TYPE) 1 << (_FP_FRACBITS_H-2+_FP_WORKBITS))
+#define _FP_IMPLBIT_H		((_FP_W_TYPE) 1 << (_FP_FRACBITS_H-1))
+#define _FP_IMPLBIT_SH_H	((_FP_W_TYPE) 1 << (_FP_FRACBITS_H-1+_FP_WORKBITS))
+#define _FP_OVERFLOW_H		((_FP_W_TYPE) 1 << (_FP_WFRACBITS_H))
+
+#define _FP_WFRACBITS_DW_H	(2 * _FP_WFRACBITS_H)
+#define _FP_WFRACXBITS_DW_H	(_FP_FRACTBITS_DW_H - _FP_WFRACBITS_DW_H)
+#define _FP_HIGHBIT_DW_H	\
+  ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_H - 1) % _FP_W_TYPE_SIZE)
+
+/* The implementation of _FP_MUL_MEAT_H and _FP_DIV_MEAT_H should be
+   chosen by the target machine.  */
+
+typedef float HFtype __attribute__ ((mode (HF)));
+
+union _FP_UNION_H
+{
+  HFtype flt;
+  struct _FP_STRUCT_LAYOUT
+  {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign : 1;
+    unsigned exp  : _FP_EXPBITS_H;
+    unsigned frac : _FP_FRACBITS_H - (_FP_IMPLBIT_H != 0);
+#else
+    unsigned frac : _FP_FRACBITS_H - (_FP_IMPLBIT_H != 0);
+    unsigned exp  : _FP_EXPBITS_H;
+    unsigned sign : 1;
+#endif
+  } bits __attribute__ ((packed));
+};
+
+#define FP_DECL_H(X)		_FP_DECL (1, X)
+#define FP_UNPACK_RAW_H(X, val)	_FP_UNPACK_RAW_1 (H, X, (val))
+#define FP_UNPACK_RAW_HP(X, val)	_FP_UNPACK_RAW_1_P (H, X, (val))
+#define FP_PACK_RAW_H(val, X)	_FP_PACK_RAW_1 (H, (val), X)
+#define FP_PACK_RAW_HP(val, X)			\
+  do						\
+    {						\
+      if (!FP_INHIBIT_RESULTS)			\
+	_FP_PACK_RAW_1_P (H, (val), X);		\
+    }						\
+  while (0)
+
+#define FP_UNPACK_H(X, val)			\
+  do						\
+    {						\
+      _FP_UNPACK_RAW_1 (H, X, (val));		\
+      _FP_UNPACK_CANONICAL (H, 1, X);		\
+    }						\
+  while (0)
+
+#define FP_UNPACK_HP(X, val)			\
+  do						\
+    {						\
+      _FP_UNPACK_RAW_1_P (H, X, (val));		\
+      _FP_UNPACK_CANONICAL (H, 1, X);		\
+    }						\
+  while (0)
+
+#define FP_UNPACK_SEMIRAW_H(X, val)		\
+  do						\
+    {						\
+      _FP_UNPACK_RAW_1 (H, X, (val));		\
+      _FP_UNPACK_SEMIRAW (H, 1, X);		\
+    }						\
+  while (0)
+
+#define FP_UNPACK_SEMIRAW_HP(X, val)		\
+  do						\
+    {						\
+      _FP_UNPACK_RAW_1_P (H, X, (val));		\
+      _FP_UNPACK_SEMIRAW (H, 1, X);		\
+    }						\
+  while (0)
+
+#define FP_PACK_H(val, X)			\
+  do						\
+    {						\
+      _FP_PACK_CANONICAL (H, 1, X);		\
+      _FP_PACK_RAW_1 (H, (val), X);		\
+    }						\
+  while (0)
+
+#define FP_PACK_HP(val, X)			\
+  do						\
+    {						\
+      _FP_PACK_CANONICAL (H, 1, X);		\
+      if (!FP_INHIBIT_RESULTS)			\
+	_FP_PACK_RAW_1_P (H, (val), X);		\
+    }						\
+  while (0)
+
+#define FP_PACK_SEMIRAW_H(val, X)		\
+  do						\
+    {						\
+      _FP_PACK_SEMIRAW (H, 1, X);		\
+      _FP_PACK_RAW_1 (H, (val), X);		\
+    }						\
+  while (0)
+
+#define FP_PACK_SEMIRAW_HP(val, X)		\
+  do						\
+    {						\
+      _FP_PACK_SEMIRAW (H, 1, X);		\
+      if (!FP_INHIBIT_RESULTS)			\
+	_FP_PACK_RAW_1_P (H, (val), X);		\
+    }						\
+  while (0)
+
+#define FP_TO_INT_H(r, X, rsz, rsg)	_FP_TO_INT (H, 1, (r), X, (rsz), (rsg))
+#define FP_TO_INT_ROUND_H(r, X, rsz, rsg)	\
+  _FP_TO_INT_ROUND (H, 1, (r), X, (rsz), (rsg))
+#define FP_FROM_INT_H(X, r, rs, rt)	_FP_FROM_INT (H, 1, X, (r), (rs), rt)
+
+#define _FP_FRAC_HIGH_H(X)	_FP_FRAC_HIGH_1 (X)
+#define _FP_FRAC_HIGH_RAW_H(X)	_FP_FRAC_HIGH_1 (X)
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRAC_HIGH_DW_H(X)	_FP_FRAC_HIGH_2 (X)
+#else
+#define _FP_FRAC_HIGH_DW_H(X)	_FP_FRAC_HIGH_1 (X)
+#endif
+
+#endif /* !SOFT_FP_HALF_H */
diff --git a/soft-fp/trunctfhf2.c b/soft-fp/trunctfhf2.c
new file mode 100644
index 0000000..0500b14
--- /dev/null
+++ b/soft-fp/trunctfhf2.c
@@ -0,0 +1,52 @@ 
+/* Software floating-point emulation.
+   Truncate IEEE quad into IEEE half.
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "half.h"
+#include "quad.h"
+
+HFtype
+__trunctfhf2 (TFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q (A);
+  FP_DECL_H (R);
+  HFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_Q (A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_TRUNC (H, Q, 1, 4, R, A);
+#else
+  FP_TRUNC (H, Q, 1, 2, R, A);
+#endif
+  FP_PACK_SEMIRAW_H (r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}