Re: [PATCH], Add PowerPC ISA 3.0 IEEE 128-bit floating point round to odd built-in functions

2017-10-03 Thread Segher Boessenkool
On Tue, Oct 03, 2017 at 04:15:23PM -0400, Michael Meissner wrote:
> Here is the patch to add the round to odd instructions using separate UNSPEC
> names instead of putting the operation into the unspec.
> 
> I have done a bootstrap and check on a little endian power8 system and there
> were no regressions.  Can I check this into the trunk?

This looks fine.  Okay for trunk.  Thanks!


Segher


> 2017-10-03  Michael Meissner  
> 
>   * config/rs6000/rs6000-builtin.def (BU_FLOAT128_2_HW): Define new
>   helper macro for IEEE float128 hardware built-in functions.
>   (SQRTF128_ODD): Add built-in functions with the round-to-odd
>   semantics.
>   (TRUNCF128_ODD): Likewise.
>   (ADDF128_ODD): Likewise.
>   (SUBF128_ODD): Likewise.
>   (MULF128_ODD): Likewise.
>   (DIVF128_ODD): Likewise.
>   (FMAF128_ODD): Likewise.
>   * config/rs6000/rs6000.md (UNSPEC_ROUND_TO_ODD): Rename to
>   UNSPEC_TRUNC_ROUND_TO_ODD.
>   (UNSPEC_TRUNC_ROUND_TO_ODD): Likewise.
>   (UNSPEC_ADD_ROUND_TO_ODD): New unspec codes for the IEEE 128-bit
>   floating point round to odd instructions.
>   (UNSPEC_SUB_ROUND_TO_ODD): Likewise.
>   (UNSPEC_MUL_ROUND_TO_ODD): Likewise.
>   (UNSPEC_DIV_ROUND_TO_ODD): Likewise.
>   (UNSPEC_FMA_ROUND_TO_ODD): Likewise.
>   (UNSPEC_SQRT_ROUND_TO_ODD): Likewise.
>   (truncsf2_hw): Change the truncate with round to odd
>   expansion to use UNSPEC_TRUNC_ROUND_TO_ODD.
>   (add3_odd): Add insns for IEEE 128-bit floating point round
>   to odd hardware instructions.
>   (sub3_odd): Likewise.
>   (mul3_odd): Likewise.
>   (div3_odd): Likewise.
>   (sqrt2_odd): Likewise.
>   (fma4_odd): Likewise.
>   (fms4_odd): Likewise.
>   (nfma4_odd): Likewise.
>   (nfms4_odd): Likewise.
>   (truncdf2_odd): Change the truncate with round to odd
>   expansion to use UNSPEC_TRUNC_ROUND_TO_ODD. Add a generator
>   function.
>   * doc/extend.texi (PowerPC built-in functions): Update documentation
>   for existing IEEE float128-bit built-in functions.  Add built-in
>   functions that generate the IEEE 128-bit floating point round to
>   odd instructions.


Re: [PATCH], Add PowerPC ISA 3.0 IEEE 128-bit floating point round to odd built-in functions

2017-10-03 Thread Michael Meissner
Here is the patch to add the round to odd instructions using separate UNSPEC
names instead of putting the operation into the unspec.

I have done a bootstrap and check on a little endian power8 system and there
were no regressions.  Can I check this into the trunk?

[gcc]
2017-10-03  Michael Meissner  

* config/rs6000/rs6000-builtin.def (BU_FLOAT128_2_HW): Define new
helper macro for IEEE float128 hardware built-in functions.
(SQRTF128_ODD): Add built-in functions with the round-to-odd
semantics.
(TRUNCF128_ODD): Likewise.
(ADDF128_ODD): Likewise.
(SUBF128_ODD): Likewise.
(MULF128_ODD): Likewise.
(DIVF128_ODD): Likewise.
(FMAF128_ODD): Likewise.
* config/rs6000/rs6000.md (UNSPEC_ROUND_TO_ODD): Rename to
UNSPEC_TRUNC_ROUND_TO_ODD.
(UNSPEC_TRUNC_ROUND_TO_ODD): Likewise.
(UNSPEC_ADD_ROUND_TO_ODD): New unspec codes for the IEEE 128-bit
floating point round to odd instructions.
(UNSPEC_SUB_ROUND_TO_ODD): Likewise.
(UNSPEC_MUL_ROUND_TO_ODD): Likewise.
(UNSPEC_DIV_ROUND_TO_ODD): Likewise.
(UNSPEC_FMA_ROUND_TO_ODD): Likewise.
(UNSPEC_SQRT_ROUND_TO_ODD): Likewise.
(truncsf2_hw): Change the truncate with round to odd
expansion to use UNSPEC_TRUNC_ROUND_TO_ODD.
(add3_odd): Add insns for IEEE 128-bit floating point round
to odd hardware instructions.
(sub3_odd): Likewise.
(mul3_odd): Likewise.
(div3_odd): Likewise.
(sqrt2_odd): Likewise.
(fma4_odd): Likewise.
(fms4_odd): Likewise.
(nfma4_odd): Likewise.
(nfms4_odd): Likewise.
(truncdf2_odd): Change the truncate with round to odd
expansion to use UNSPEC_TRUNC_ROUND_TO_ODD. Add a generator
function.
* doc/extend.texi (PowerPC built-in functions): Update documentation
for existing IEEE float128-bit built-in functions.  Add built-in
functions that generate the IEEE 128-bit floating point round to
odd instructions.

[gcc/testsuite]
2017-10-03  Michael Meissner  

* gcc.target/powerpc/float128-odd.c: New test.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000-builtin.def
===
--- gcc/config/rs6000/rs6000-builtin.def(revision 253358)
+++ gcc/config/rs6000/rs6000-builtin.def(working copy)
@@ -686,6 +686,14 @@
 | RS6000_BTC_UNARY),   \
CODE_FOR_ ## ICODE) /* ICODE */
 
+#define BU_FLOAT128_2_HW(ENUM, NAME, ATTR, ICODE)   \
+  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,  /* ENUM */  \
+   "__builtin_" NAME,  /* NAME */  \
+   RS6000_BTM_FLOAT128_HW, /* MASK */  \
+   (RS6000_BTC_ ## ATTR/* ATTR */  \
+| RS6000_BTC_BINARY),  \
+   CODE_FOR_ ## ICODE) /* ICODE */
+
 #define BU_FLOAT128_3_HW(ENUM, NAME, ATTR, ICODE)   \
   RS6000_BUILTIN_3 (MISC_BUILTIN_ ## ENUM,  /* ENUM */  \
"__builtin_" NAME,  /* NAME */  \
@@ -2365,11 +2373,19 @@ BU_P9_OVERLOAD_2 (CMPEQB,   "byte_in_set")
 BU_FLOAT128_1 (FABSQ,  "fabsq",   CONST, abskf2)
 BU_FLOAT128_2 (COPYSIGNQ,  "copysignq",   CONST, copysignkf3)
 
-/* 1 and 3 argument IEEE 128-bit floating point functions that require ISA 3.0
-   hardware.  These functions use the new 'f128' suffix.  Eventually these
-   should be folded into the common built-in function handling. */
-BU_FLOAT128_1_HW (SQRTF128,"sqrtf128", CONST, sqrtkf2)
-BU_FLOAT128_3_HW (FMAF128, "fmaf128",  CONST, fmakf4_hw)
+/* 1, 2, and 3 argument IEEE 128-bit floating point functions that require ISA
+   3.0 hardware.  These functions use the new 'f128' suffix.  Eventually the
+   standard functions should be folded into the common built-in function
+   handling. */
+BU_FLOAT128_1_HW (SQRTF128, "sqrtf128",   CONST, sqrtkf2)
+BU_FLOAT128_1_HW (SQRTF128_ODD, "sqrtf128_round_to_odd",  CONST, 
sqrtkf2_odd)
+BU_FLOAT128_1_HW (TRUNCF128_ODD, "truncf128_round_to_odd", CONST, 
trunckfdf2_odd)
+BU_FLOAT128_2_HW (ADDF128_ODD,  "addf128_round_to_odd",   CONST, addkf3_odd)
+BU_FLOAT128_2_HW (SUBF128_ODD,  "subf128_round_to_odd",   CONST, subkf3_odd)
+BU_FLOAT128_2_HW (MULF128_ODD,  "mulf128_round_to_odd",   CONST, mulkf3_odd)
+BU_FLOAT128_2_HW (DIVF128_ODD,  "divf128_round_to_odd",   CONST, divkf3_odd)
+BU_FLOAT128_3_HW (FMAF128,  "fmaf128",CONST, fmakf4_hw)

Re: [PATCH], Add PowerPC ISA 3.0 IEEE 128-bit floating point round to odd built-in functions

2017-10-02 Thread Segher Boessenkool
Hi!

On Mon, Oct 02, 2017 at 02:01:57PM -0400, Michael Meissner wrote:
> On Fri, Sep 29, 2017 at 12:10:07PM -0500, Segher Boessenkool wrote:
> > On Thu, Sep 28, 2017 at 06:34:23PM -0400, Michael Meissner wrote:
> > > --- gcc/config/rs6000/rs6000.md   (revision 253267)
> > > +++ gcc/config/rs6000/rs6000.md   (working copy)
> > > @@ -14505,7 +14505,9 @@ (define_insn_and_split "truncsf2_h
> > >"#"
> > >"&& 1"
> > >[(set (match_dup 2)
> > > - (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
> > > + (unspec:DF [(float_truncate:DF
> > > +  (match_dup 1))]
> > > +UNSPEC_ROUND_TO_ODD))
> > > (set (match_dup 0)
> > >   (float_truncate:SF (match_dup 2)))]
> > >  {
> > 
> > I don't think this is correct.  It says to first truncate the f128 to DF,
> > and then round it to odd; I think you want to do the truncation with
> > round-to-odd rounding mode already.
> > 
> > > +(define_insn "mul3_odd"
> > > +  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
> > > + (unspec:IEEE128
> > > +  [(mult:IEEE128
> > > +(match_operand:IEEE128 1 "altivec_register_operand" "v")
> > > +(match_operand:IEEE128 2 "altivec_register_operand" "v"))]
> > > +  UNSPEC_ROUND_TO_ODD))]
> > > +  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)"
> > > +  "xsmulqpo %0,%1,%2"
> > > +  [(set_attr "type" "vecfloat")
> > > +   (set_attr "size" "128")])
> > 
> > Similar here (and everywhere else): it does an f128 mul, so rounding
> > with whatever rounding mode is current, and *then* it rounds to odd.

> > Everything else looks fine, but that unspec thing needs fixing.  Can be
> > later, things will likely work for now, so okay for trunk.  Thanks.
> > 
> > How do other ports deal with this?  Insns with a specific rounding mode?
> > Have a separate unspec for every operation?  Not very nice either :-(
> 
> I just want to do the minimal work so the glibc people can use this
> instruction, but I am not that motivated to go back and modify it further.  
> So,
> I would prefer to do it right before committing it, unless you want to refine
> it.
> 
> As I see it, there are 2 ways to encode the RTL:
> 
> 1)Use one UNSPEC name, and add the operation inside of the spec;

But this is incorrect as far as I see: it does not correctly describe
what the instruction does.

> 2)Add separate UNSPEC's for each operation.
> 
> Either one is fine with me.  If you would prefer separate names, I can do it.

Yes please.

Thanks,


Segher


Re: [PATCH], Add PowerPC ISA 3.0 IEEE 128-bit floating point round to odd built-in functions

2017-10-02 Thread Michael Meissner
On Fri, Sep 29, 2017 at 12:10:07PM -0500, Segher Boessenkool wrote:
> Hi Mike,
> 
> On Thu, Sep 28, 2017 at 06:34:23PM -0400, Michael Meissner wrote:
> > This patch addss built-in functions on PowerPC ISA 3.0 (power9) that allow 
> > the
> > user to access the round to odd IEEE 128-bit floating point instructions.
> 
> > --- gcc/config/rs6000/rs6000.md (revision 253267)
> > +++ gcc/config/rs6000/rs6000.md (working copy)
> > @@ -14505,7 +14505,9 @@ (define_insn_and_split "truncsf2_h
> >"#"
> >"&& 1"
> >[(set (match_dup 2)
> > -   (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
> > +   (unspec:DF [(float_truncate:DF
> > +(match_dup 1))]
> > +  UNSPEC_ROUND_TO_ODD))
> > (set (match_dup 0)
> > (float_truncate:SF (match_dup 2)))]
> >  {
> 
> I don't think this is correct.  It says to first truncate the f128 to DF,
> and then round it to odd; I think you want to do the truncation with
> round-to-odd rounding mode already.
> 
> > +(define_insn "mul3_odd"
> > +  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
> > +   (unspec:IEEE128
> > +[(mult:IEEE128
> > +  (match_operand:IEEE128 1 "altivec_register_operand" "v")
> > +  (match_operand:IEEE128 2 "altivec_register_operand" "v"))]
> > +UNSPEC_ROUND_TO_ODD))]
> > +  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)"
> > +  "xsmulqpo %0,%1,%2"
> > +  [(set_attr "type" "vecfloat")
> > +   (set_attr "size" "128")])
> 
> Similar here (and everywhere else): it does an f128 mul, so rounding
> with whatever rounding mode is current, and *then* it rounds to odd.
> 
> > +(define_insn "sqrt2_odd"
> > +  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
> > +   (unspec:IEEE128
> > +[(sqrt:IEEE128
> > +  (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
> > +UNSPEC_ROUND_TO_ODD))]
> > +  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)"
> > +   "xssqrtqpo %0,%1"
> 
> (One space too many here).
> 
> Everything else looks fine, but that unspec thing needs fixing.  Can be
> later, things will likely work for now, so okay for trunk.  Thanks.
> 
> How do other ports deal with this?  Insns with a specific rounding mode?
> Have a separate unspec for every operation?  Not very nice either :-(

I just want to do the minimal work so the glibc people can use this
instruction, but I am not that motivated to go back and modify it further.  So,
I would prefer to do it right before committing it, unless you want to refine
it.

As I see it, there are 2 ways to encode the RTL:

1)  Use one UNSPEC name, and add the operation inside of the spec;

2)  Add separate UNSPEC's for each operation.

Either one is fine with me.  If you would prefer separate names, I can do it.

In theory we could do something like define_subst, but that is a large time
waster to learn how to do it for 8 specialized instructions.

Similarly, I don't see the need for doing more general support, until we have
more data types and more rounding modes.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797



Re: [PATCH], Add PowerPC ISA 3.0 IEEE 128-bit floating point round to odd built-in functions

2017-10-02 Thread Segher Boessenkool
On Fri, Sep 29, 2017 at 08:42:45PM +, Joseph Myers wrote:
> On Fri, 29 Sep 2017, Joseph Myers wrote:
> 
> > On Fri, 29 Sep 2017, Segher Boessenkool wrote:
> > 
> > > How do other ports deal with this?  Insns with a specific rounding mode?
> > > Have a separate unspec for every operation?  Not very nice either :-(
> > 
> > Well, ideally you'd have a machine-independent representation of constant 
> > rounding modes that could be used with the TS 18661-1 FENV_ROUND pragma, 
> > respectively FENV_DEC_ROUND for decimal floating point (as the standard 
> > machine-independent way of accessing such a facility at the C language 
> > level - you'd then need to extend it to handle round-to-odd, but given the 
> > basic facility, accepting additional rounding mode names with it should be 
> > easy).  But I don't know what that would look like in either GIMPLE or 
> > RTL, and I'd certainly expect it to be a large project (quite likely 
> > depending on other large projects to handle dynamic rounding modes 
> > properly through optimizers).  So you probably can't do much better than 
> > lots of unspecs and machine-specific built-in functions at present.
> 
> (But the answer to your question seems to be that AVX512 uses something 
> involving UNSPEC_EMBEDDED_ROUNDING.)

Thanks.

So this seems to be the same as Mike's patch does.  I was hoping for a
nifty trick, not another huge project :-)  Oh well.


Segher


Re: [PATCH], Add PowerPC ISA 3.0 IEEE 128-bit floating point round to odd built-in functions

2017-09-29 Thread Joseph Myers
On Fri, 29 Sep 2017, Joseph Myers wrote:

> On Fri, 29 Sep 2017, Segher Boessenkool wrote:
> 
> > How do other ports deal with this?  Insns with a specific rounding mode?
> > Have a separate unspec for every operation?  Not very nice either :-(
> 
> Well, ideally you'd have a machine-independent representation of constant 
> rounding modes that could be used with the TS 18661-1 FENV_ROUND pragma, 
> respectively FENV_DEC_ROUND for decimal floating point (as the standard 
> machine-independent way of accessing such a facility at the C language 
> level - you'd then need to extend it to handle round-to-odd, but given the 
> basic facility, accepting additional rounding mode names with it should be 
> easy).  But I don't know what that would look like in either GIMPLE or 
> RTL, and I'd certainly expect it to be a large project (quite likely 
> depending on other large projects to handle dynamic rounding modes 
> properly through optimizers).  So you probably can't do much better than 
> lots of unspecs and machine-specific built-in functions at present.

(But the answer to your question seems to be that AVX512 uses something 
involving UNSPEC_EMBEDDED_ROUNDING.)

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH], Add PowerPC ISA 3.0 IEEE 128-bit floating point round to odd built-in functions

2017-09-29 Thread Joseph Myers
On Fri, 29 Sep 2017, Segher Boessenkool wrote:

> How do other ports deal with this?  Insns with a specific rounding mode?
> Have a separate unspec for every operation?  Not very nice either :-(

Well, ideally you'd have a machine-independent representation of constant 
rounding modes that could be used with the TS 18661-1 FENV_ROUND pragma, 
respectively FENV_DEC_ROUND for decimal floating point (as the standard 
machine-independent way of accessing such a facility at the C language 
level - you'd then need to extend it to handle round-to-odd, but given the 
basic facility, accepting additional rounding mode names with it should be 
easy).  But I don't know what that would look like in either GIMPLE or 
RTL, and I'd certainly expect it to be a large project (quite likely 
depending on other large projects to handle dynamic rounding modes 
properly through optimizers).  So you probably can't do much better than 
lots of unspecs and machine-specific built-in functions at present.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH], Add PowerPC ISA 3.0 IEEE 128-bit floating point round to odd built-in functions

2017-09-29 Thread Segher Boessenkool
Hi Mike,

On Thu, Sep 28, 2017 at 06:34:23PM -0400, Michael Meissner wrote:
> This patch addss built-in functions on PowerPC ISA 3.0 (power9) that allow the
> user to access the round to odd IEEE 128-bit floating point instructions.

> --- gcc/config/rs6000/rs6000.md   (revision 253267)
> +++ gcc/config/rs6000/rs6000.md   (working copy)
> @@ -14505,7 +14505,9 @@ (define_insn_and_split "truncsf2_h
>"#"
>"&& 1"
>[(set (match_dup 2)
> - (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
> + (unspec:DF [(float_truncate:DF
> +  (match_dup 1))]
> +UNSPEC_ROUND_TO_ODD))
> (set (match_dup 0)
>   (float_truncate:SF (match_dup 2)))]
>  {

I don't think this is correct.  It says to first truncate the f128 to DF,
and then round it to odd; I think you want to do the truncation with
round-to-odd rounding mode already.

> +(define_insn "mul3_odd"
> +  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
> + (unspec:IEEE128
> +  [(mult:IEEE128
> +(match_operand:IEEE128 1 "altivec_register_operand" "v")
> +(match_operand:IEEE128 2 "altivec_register_operand" "v"))]
> +  UNSPEC_ROUND_TO_ODD))]
> +  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)"
> +  "xsmulqpo %0,%1,%2"
> +  [(set_attr "type" "vecfloat")
> +   (set_attr "size" "128")])

Similar here (and everywhere else): it does an f128 mul, so rounding
with whatever rounding mode is current, and *then* it rounds to odd.

> +(define_insn "sqrt2_odd"
> +  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
> + (unspec:IEEE128
> +  [(sqrt:IEEE128
> +(match_operand:IEEE128 1 "altivec_register_operand" "v"))]
> +  UNSPEC_ROUND_TO_ODD))]
> +  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)"
> +   "xssqrtqpo %0,%1"

(One space too many here).

Everything else looks fine, but that unspec thing needs fixing.  Can be
later, things will likely work for now, so okay for trunk.  Thanks.

How do other ports deal with this?  Insns with a specific rounding mode?
Have a separate unspec for every operation?  Not very nice either :-(


Segher


[PATCH], Add PowerPC ISA 3.0 IEEE 128-bit floating point round to odd built-in functions

2017-09-28 Thread Michael Meissner
This patch addss built-in functions on PowerPC ISA 3.0 (power9) that allow the
user to access the round to odd IEEE 128-bit floating point instructions.

I have checked it on a little endian power8 system doing a bootstrap and make
check.  There were no regressions in the testsuite.  I verified that the new
test (float128-odd.c) did run sucessfully.  Can I check this patch into the
trunk?

[gcc]
2017-09-28  Michael Meissner  

* config/rs6000/rs6000-builtin.def (BU_FLOAT128_2_HW): Define new
helper macro for IEEE float128 hardware built-in functions.
(SQRTF128_ODD): Add built-in functions with the round-to-odd
semantics.
(TRUNCF128_ODD): Likewise.
(ADDF128_ODD): Likewise.
(SUBF128_ODD): Likewise.
(MULF128_ODD): Likewise.
(DIVF128_ODD): Likewise.
(FMAF128_ODD): Likewise.
* config/rs6000/rs6000.md (truncsf2_hw): Change the truncate
with round to odd expansion to use float_truncate:DF inside of the
UNSPEC to better document what the insn does.
(add3_odd): Add insns for IEEE 128-bit floating point round
to odd hardware instructions.
(sub3_odd): Likewise.
(mul3_odd): Likewise.
(div3_odd): Likewise.
(sqrt2_odd): Likewise.
(fma4_odd): Likewise.
(fms4_odd): Likewise.
(nfma4_odd): Likewise.
(nfms4_odd): Likewise.
(truncdf2_odd): Change insn format to make it more readable,
and add a generator function.
* doc/extend.texi (PowerPC built-in functions): Update documentation
for existing IEEE float128-bit built-in functions.  Add built-in
functions that generate the IEEE 128-bit floating point round to
odd instructions.

[gcc/testsuite]
2017-09-28  Michael Meissner  

* gcc.target/powerpc/float128-odd.c: New test.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000-builtin.def
===
--- gcc/config/rs6000/rs6000-builtin.def(revision 253267)
+++ gcc/config/rs6000/rs6000-builtin.def(working copy)
@@ -686,6 +686,14 @@
 | RS6000_BTC_UNARY),   \
CODE_FOR_ ## ICODE) /* ICODE */
 
+#define BU_FLOAT128_2_HW(ENUM, NAME, ATTR, ICODE)   \
+  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,  /* ENUM */  \
+   "__builtin_" NAME,  /* NAME */  \
+   RS6000_BTM_FLOAT128_HW, /* MASK */  \
+   (RS6000_BTC_ ## ATTR/* ATTR */  \
+| RS6000_BTC_BINARY),  \
+   CODE_FOR_ ## ICODE) /* ICODE */
+
 #define BU_FLOAT128_3_HW(ENUM, NAME, ATTR, ICODE)   \
   RS6000_BUILTIN_3 (MISC_BUILTIN_ ## ENUM,  /* ENUM */  \
"__builtin_" NAME,  /* NAME */  \
@@ -2365,11 +2373,19 @@ BU_P9_OVERLOAD_2 (CMPEQB,   "byte_in_set")
 BU_FLOAT128_1 (FABSQ,  "fabsq",   CONST, abskf2)
 BU_FLOAT128_2 (COPYSIGNQ,  "copysignq",   CONST, copysignkf3)
 
-/* 1 and 3 argument IEEE 128-bit floating point functions that require ISA 3.0
-   hardware.  These functions use the new 'f128' suffix.  Eventually these
-   should be folded into the common built-in function handling. */
-BU_FLOAT128_1_HW (SQRTF128,"sqrtf128", CONST, sqrtkf2)
-BU_FLOAT128_3_HW (FMAF128, "fmaf128",  CONST, fmakf4_hw)
+/* 1, 2, and 3 argument IEEE 128-bit floating point functions that require ISA
+   3.0 hardware.  These functions use the new 'f128' suffix.  Eventually the
+   standard functions should be folded into the common built-in function
+   handling. */
+BU_FLOAT128_1_HW (SQRTF128, "sqrtf128",   CONST, sqrtkf2)
+BU_FLOAT128_1_HW (SQRTF128_ODD, "sqrtf128_round_to_odd",  CONST, 
sqrtkf2_odd)
+BU_FLOAT128_1_HW (TRUNCF128_ODD, "truncf128_round_to_odd", CONST, 
trunckfdf2_odd)
+BU_FLOAT128_2_HW (ADDF128_ODD,  "addf128_round_to_odd",   CONST, addkf3_odd)
+BU_FLOAT128_2_HW (SUBF128_ODD,  "subf128_round_to_odd",   CONST, subkf3_odd)
+BU_FLOAT128_2_HW (MULF128_ODD,  "mulf128_round_to_odd",   CONST, mulkf3_odd)
+BU_FLOAT128_2_HW (DIVF128_ODD,  "divf128_round_to_odd",   CONST, divkf3_odd)
+BU_FLOAT128_3_HW (FMAF128,  "fmaf128",CONST, fmakf4_hw)
+BU_FLOAT128_3_HW (FMAF128_ODD,  "fmaf128_round_to_odd",   CONST, fmakf4_odd)
 
 /* 1 argument crypto functions.  */
 BU_CRYPTO_1 (VSBOX,"vsbox",  CONST, crypto_vsbox)
Index: gcc/config/rs6000/rs6000.md
===
--- gcc/config/rs6000/rs6000.md (revision