diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2008-08-12 13:13:38 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2008-08-12 13:13:38 +0000 |
commit | 88f091f5aec9a1d5a9deebe5cd743dcab2760d84 (patch) | |
tree | b25b470542b27fbf4f61b6021a4e127af758b12b /gcc | |
parent | 4230d0fe3258a221706f791c04683bffb982e4f3 (diff) | |
download | gcc-88f091f5aec9a1d5a9deebe5cd743dcab2760d84.zip gcc-88f091f5aec9a1d5a9deebe5cd743dcab2760d84.tar.gz gcc-88f091f5aec9a1d5a9deebe5cd743dcab2760d84.tar.bz2 |
real.c (spu_single_format): New variable.
ChangeLog:
* real.c (spu_single_format): New variable.
* real.h (spu_single_format): Declare.
* config/spu/spu.c (spu_override_options): Install SFmode format.
(spu_split_immediate): Use integer mode to operate on pieces of
floating-point values in all cases.
* config/spu/spu.md (UNSPEC_FLOAT_EXTEND, UNSPEC_FLOAT_TRUNCATE): New.
("extendsfdf2"): Use UNSPEC_FLOAT_EXTEND instead of FLOAT_EXTEND.
("truncdfsf2"): Use UNSPEC_FLOAT_TRUNCATE instead of FLOAT_TRUNCATE.
testsuite/ChangeLog:
* gcc.c-torture/execute/ieee/inf-2.c (testf): Skip on the SPU.
Co-Authored-By: Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
From-SVN: r139013
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/config/spu/spu.c | 22 | ||||
-rw-r--r-- | gcc/config/spu/spu.md | 8 | ||||
-rw-r--r-- | gcc/real.c | 30 | ||||
-rw-r--r-- | gcc/real.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c | 4 |
7 files changed, 75 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 42afad2..cbd499e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,18 @@ 2008-08-12 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + Trevor Smigiel <trevor_smigiel@playstation.sony.com> + + * real.c (spu_single_format): New variable. + * real.h (spu_single_format): Declare. + + * config/spu/spu.c (spu_override_options): Install SFmode format. + (spu_split_immediate): Use integer mode to operate on pieces of + floating-point values in all cases. + + * config/spu/spu.md (UNSPEC_FLOAT_EXTEND, UNSPEC_FLOAT_TRUNCATE): New. + ("extendsfdf2"): Use UNSPEC_FLOAT_EXTEND instead of FLOAT_EXTEND. + ("truncdfsf2"): Use UNSPEC_FLOAT_TRUNCATE instead of FLOAT_TRUNCATE. + +2008-08-12 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> * config/spu/spu.c (spu_safe_dma): Respect TARGET_SAFE_DMA. diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 230f4c0..1021a91 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -352,6 +352,8 @@ spu_override_options (void) else error ("Unknown architecture '%s'", &spu_tune_string[0]); } + + REAL_MODE_FORMAT (SFmode) = &spu_single_format; } /* Handle an attribute requiring a FUNCTION_DECL; arguments as in @@ -1519,10 +1521,18 @@ spu_split_immediate (rtx * ops) { unsigned char arrhi[16]; unsigned char arrlo[16]; - rtx to, hi, lo; + rtx to, temp, hi, lo; int i; + enum machine_mode imode = mode; + /* We need to do reals as ints because the constant used in the + IOR might not be a legitimate real constant. */ + imode = int_mode_for_mode (mode); constant_to_array (mode, ops[1], arrhi); - to = !can_create_pseudo_p () ? ops[0] : gen_reg_rtx (mode); + if (imode != mode) + to = simplify_gen_subreg (imode, ops[0], mode, 0); + else + to = ops[0]; + temp = !can_create_pseudo_p () ? to : gen_reg_rtx (imode); for (i = 0; i < 16; i += 4) { arrlo[i + 2] = arrhi[i + 2]; @@ -1530,11 +1540,11 @@ spu_split_immediate (rtx * ops) arrlo[i + 0] = arrlo[i + 1] = 0; arrhi[i + 2] = arrhi[i + 3] = 0; } - hi = array_to_constant (mode, arrhi); - lo = array_to_constant (mode, arrlo); - emit_move_insn (to, hi); + hi = array_to_constant (imode, arrhi); + lo = array_to_constant (imode, arrlo); + emit_move_insn (temp, hi); emit_insn (gen_rtx_SET - (VOIDmode, ops[0], gen_rtx_IOR (mode, to, lo))); + (VOIDmode, to, gen_rtx_IOR (imode, temp, lo))); return 1; } case IC_FSMBI2: diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md index c267efd..e50a65a 100644 --- a/gcc/config/spu/spu.md +++ b/gcc/config/spu/spu.md @@ -153,6 +153,8 @@ (UNSPEC_SPU_REALIGN_LOAD 49) (UNSPEC_SPU_MASK_FOR_LOAD 50) (UNSPEC_DFTSV 51) + (UNSPEC_FLOAT_EXTEND 52) + (UNSPEC_FLOAT_TRUNCATE 53) ]) (include "predicates.md") @@ -648,14 +650,16 @@ (define_insn "extendsfdf2" [(set (match_operand:DF 0 "spu_reg_operand" "=r") - (float_extend:DF (match_operand:SF 1 "spu_reg_operand" "r")))] + (unspec:DF [(match_operand:SF 1 "spu_reg_operand" "r")] + UNSPEC_FLOAT_EXTEND))] "" "fesd\t%0,%1" [(set_attr "type" "fpd")]) (define_insn "truncdfsf2" [(set (match_operand:SF 0 "spu_reg_operand" "=r") - (float_truncate:SF (match_operand:DF 1 "spu_reg_operand" "r")))] + (unspec:SF [(match_operand:DF 1 "spu_reg_operand" "r")] + UNSPEC_FLOAT_TRUNCATE))] "" "frds\t%0,%1" [(set_attr "type" "fpd")]) @@ -2862,6 +2862,36 @@ const struct real_format motorola_single_format = true, true }; + +/* SPU Single Precision (Extended-Range Mode) format is the same as IEEE + single precision with the following differences: + - Infinities are not supported. Instead MAX_FLOAT or MIN_FLOAT + are generated. + - NaNs are not supported. + - The range of non-zero numbers in binary is + (001)[1.]000...000 to (255)[1.]111...111. + - Denormals can be represented, but are treated as +0.0 when + used as an operand and are never generated as a result. + - -0.0 can be represented, but a zero result is always +0.0. + - the only supported rounding mode is trunction (towards zero). */ +const struct real_format spu_single_format = + { + encode_ieee_single, + decode_ieee_single, + 2, + 24, + 24, + -125, + 129, + 31, + 31, + false, + false, + true, + true, + false, + false + }; /* IEEE double-precision format. */ @@ -259,6 +259,7 @@ extern unsigned int real_hash (const REAL_VALUE_TYPE *); extern const struct real_format ieee_single_format; extern const struct real_format mips_single_format; extern const struct real_format motorola_single_format; +extern const struct real_format spu_single_format; extern const struct real_format ieee_double_format; extern const struct real_format mips_double_format; extern const struct real_format motorola_double_format; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d6f2811..8653a14 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-08-12 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * gcc.c-torture/execute/ieee/inf-2.c (testf): Skip on the SPU. + 2008-08-12 Jakub Jelinek <jakub@redhat.com> PR c++/36688 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c index 40270c0..1823b35 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c @@ -25,6 +25,9 @@ void test(double f, double i) void testf(float f, float i) { +#ifndef __SPU__ + /* The SPU single-precision floating point format does not support Inf. */ + if (f == __builtin_inff()) abort (); if (f == -__builtin_inff()) @@ -44,6 +47,7 @@ void testf(float f, float i) abort (); if (f < -__builtin_inff()) abort (); +#endif } void testl(long double f, long double i) |