2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-03-22 19:11:18 +08:00

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
This commit is contained in:
Ulrich Weigand 2008-08-12 13:13:38 +00:00 committed by Ulrich Weigand
parent 4230d0fe32
commit 88f091f5ae
7 changed files with 75 additions and 8 deletions
gcc
ChangeLog
config/spu
real.creal.h
testsuite
ChangeLog
gcc.c-torture/execute/ieee

@ -1,3 +1,17 @@
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.

@ -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:

@ -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;

@ -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

@ -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)