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:
parent
4230d0fe32
commit
88f091f5ae
@ -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")])
|
||||
|
30
gcc/real.c
30
gcc/real.c
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user