This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] SPU float format: Round towards zero


On Mon, Aug 4, 2008 at 9:29 PM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
> Hello,
>
> this patch addresses a second feature of SPU single-precision floating-point:
> all operations round towards zero.
>
> I've added a new element of the real_format structure to express this
> property.  This is taken into account in round_for_format for the standard
> arithmetic operations, and in builtins.c when choosing the rounding mode
> to use for the MPFR library for compile-time computations.
>
> One problem with always round towards zero is generation of floating-point
> constants like __FLT_MIN__.  To ensure that when parsing the decimal
> representation of such constants back in while using round-towards-zero,
> the correct value in the target binary floating-point format results,
> we have to round *away* from zero when generating the decimal value.
>
> This patch fixes this using the method suggested by Joseph Myers here:
> http://gcc.gnu.org/ml/gcc-patches/2007-11/msg00082.html
>
> In addition, it turned out that the SPU back-end didn't always follow
> round-towards-zero itself: for DImode to SFmode conversions, the default
> libgcc routine was used (which implements round-to-nearest).  The patch
> adds inline implementations of those conversions that round towards zero,
> as already specified in the SPU Language Extensions specification.
>
> Finally, a number of test cases implicitly (or explicitly) tested
> for the round-to-nearest behavious.  This patch also fixes those
> tests to check for round-towards-zero on the SPU.
>
> Tested on spu-elf on mainline and 4.3, fixes the following FAILs:
>
> FAIL: gcc.c-torture/execute/conversion.c execution,  -O0
> FAIL: gcc.c-torture/execute/conversion.c execution,  -O1
> FAIL: gcc.c-torture/execute/floatunsisf-1.c execution,  -O0
> FAIL: gcc.c-torture/execute/floatunsisf-1.c execution,  -O1
> FAIL: gcc.c-torture/execute/floatunsisf-1.c execution,  -O2
> FAIL: gcc.c-torture/execute/floatunsisf-1.c execution,  -O3 -fomit-frame-pointer
> FAIL: gcc.c-torture/execute/floatunsisf-1.c execution,  -O3 -g
> FAIL: gcc.c-torture/execute/floatunsisf-1.c execution,  -Os
>
> OK to commit?

The middle-end parts are ok with ...

> Bye,
> Ulrich
>
>
> ChangeLog:
>
>        * real.h (struct real_format): New member round_towards_zero.
>        * real.c (round_for_format): Respect fmt->round_towards_zero.
>        (ieee_single_format, mips_single_format, motorola_single_format,
>        spu_single_format, ieee_double_format, mips_double_format,
>        motorola_double_format, ieee_extended_motorola_format,
>        ieee_extended_intel_96_format, ieee_extended_intel_128_format,
>        ieee_extended_intel_96_round_53_format, ibm_extended_format,
>        mips_extended_format, ieee_quad_format, mips_quad_format,
>        vax_f_format, vax_d_format, vax_g_format): Initialize it.
>        * config/pdp11/pdp11.c (pdp11_f_format, pdp11_d_format): Likewise.
>
>        * builtins.s (do_mpfr_arg1): Consider round_towards_zero member of
>        real_format to choose rounding mode when calling MPFR functions.
>        (do_mpfr_arg2, do_mpfr_arg3, do_mpfr_sincos): Likewise.
>        (do_mpfr_bessel_n, do_mpfr_remquo, do_mpfr_lgamma_r): Likewise.
>
>        * real.h (real_to_decimal_for_mode): Add prototype.
>        * real.c (real_to_decimal_for_mode): Renames old real_to_decimal.
>        Respect target rounding mode when generating decimal representation.
>        (real_to_decimal): New stub for backwards compatibility.
>        * c-cppbuiltin.c (builtin_define_with_hex_fp_value): Use
>        real_to_decimal_for_mode instead of real_to_decimal.
>
>        * config/spu/spu.md ("floatdisf2", "floatunsdisf2"): New.

...
> @@ -1716,6 +1740,24 @@ real_to_decimal (char *str, const REAL_V
>
>   /* Append the exponent.  */
>   sprintf (last, "e%+d", dec_exp);
> +
> +  /* Verify that we can read the original value back in.  */
> +  if (mode != VOIDmode)
> +    {
> +      real_from_string (&r, str);
> +      real_convert (&r, mode, &r);
> +      gcc_assert (real_identical (&r, r_orig));
> +    }

This verification wrapped inside #if ENABLE_CHECKING.

Thanks,
Richard.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]