mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-22 14:10:06 +08:00
Allow non-constant arguments to conversion intrinsics.
* spu-protos.h (exp2_immediate_p, spu_gen_exp2): Declare. * predicates.md (spu_inv_exp2_operand, spu_exp2_operand): New. * spu.c (print_operand): Handle 'v' and 'w'. (exp2_immediate_p, spu_gen_exp2): Define. * spu-builtins.def (spu_convts, spu_convtu, spu_convtf_0, spu_convtf_1): Update parameter descriptions. * spu-builtins.md (spu_csflt, spu_cuflt, spu_cflts, spu_cfltu): Update. * constraints.md ('v', 'w'): New. * spu.md (UNSPEC_CSFLT, UNSPEC_CFLTS, UNSPEC_CUFLT, UNSPEC_CFLTU): Remove. (i2f, I2F): New define_mode_attr. (floatsisf2, floatv4siv4sf2, fix_truncsfsi2, fix_truncv4sfv4si2, floatunssisf2, floatunsv4siv4sf2, fixuns_truncsfsi2, fixuns_truncv4sfv4si2): Update to use mode attribute. (float<mode><i2f>2_mul, float<mode><i2f>2_div, fix_trunc<mode><f2i>2_mul, floatuns<mode><i2f>2_mul, floatuns<mode><i2f>2_div, fixuns_trunc<mode><f2i>2_mul): New patterns for combine. * gcc.target/spu/intrinsics-3.c: Update tests. From-SVN: r146849
This commit is contained in:
parent
5f39ad476c
commit
5345cf689e
@ -1,3 +1,26 @@
|
||||
2009-04-27 Trevor Smigiel <trevor_smigiel@playstation.sony.com>
|
||||
|
||||
Allow non-constant arguments to conversion intrinsics.
|
||||
* spu-protos.h (exp2_immediate_p, spu_gen_exp2): Declare.
|
||||
* predicates.md (spu_inv_exp2_operand, spu_exp2_operand): New.
|
||||
* spu.c (print_operand): Handle 'v' and 'w'.
|
||||
(exp2_immediate_p, spu_gen_exp2): Define.
|
||||
* spu-builtins.def (spu_convts, spu_convtu, spu_convtf_0,
|
||||
spu_convtf_1): Update parameter descriptions.
|
||||
* spu-builtins.md (spu_csflt, spu_cuflt, spu_cflts, spu_cfltu):
|
||||
Update.
|
||||
* constraints.md ('v', 'w'): New.
|
||||
* spu.md (UNSPEC_CSFLT, UNSPEC_CFLTS, UNSPEC_CUFLT, UNSPEC_CFLTU):
|
||||
Remove.
|
||||
(i2f, I2F): New define_mode_attr.
|
||||
(floatsisf2, floatv4siv4sf2, fix_truncsfsi2, fix_truncv4sfv4si2,
|
||||
floatunssisf2, floatunsv4siv4sf2, fixuns_truncsfsi2,
|
||||
fixuns_truncv4sfv4si2): Update to use mode attribute.
|
||||
(float<mode><i2f>2_mul, float<mode><i2f>2_div,
|
||||
fix_trunc<mode><f2i>2_mul, floatuns<mode><i2f>2_mul,
|
||||
floatuns<mode><i2f>2_div, fixuns_trunc<mode><f2i>2_mul): New
|
||||
patterns for combine.
|
||||
|
||||
2009-04-27 Steven Bosscher <steven@gcc.gnu.org>
|
||||
|
||||
* dbgcnt.def (cprop1, cprop2, gcse, jump_bypass): Remove
|
||||
|
@ -16,8 +16,14 @@
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;; GCC standard constraints: g, i, m, n, o, p, r, s, E-H, I-P, V, X
|
||||
;; unused for SPU: E-H, L, Q, d, e, h, q, t-z
|
||||
;; ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
;; GCC: ffffiiiiiiii x x x x xxxx xx
|
||||
;; SPU: xxxx xxx xxxx xxxx x xxx xx x xxx xx
|
||||
;; FREE: ffff i a a a a a aa aaa
|
||||
;; x - used
|
||||
;; a - available
|
||||
;; i - available for integer immediates
|
||||
;; f - available for floating point immediates
|
||||
|
||||
;; For most immediate constraints we have 3 variations to deal with the
|
||||
;; fact const_int has no mode. One variation treats const_int as 32 bit,
|
||||
@ -159,4 +165,15 @@
|
||||
&& INTVAL (XEXP (op, 0)) >= 0
|
||||
&& INTVAL (XEXP (op, 0)) <= 0x3ffff")))
|
||||
|
||||
|
||||
;; Floating-point constant constraints.
|
||||
|
||||
(define_constraint "v"
|
||||
"Floating point power of 2 with exponent in [0..127]"
|
||||
(and (match_code "const_double,const_vector")
|
||||
(match_test "exp2_immediate_p (op, VOIDmode, 0, 127)")))
|
||||
|
||||
(define_constraint "w"
|
||||
"Floating point power of 2 with exponent in [-126..0]"
|
||||
(and (match_code "const_double,const_vector")
|
||||
(match_test "exp2_immediate_p (op, VOIDmode, -126, 0)")))
|
||||
|
@ -104,3 +104,13 @@
|
||||
(ior (match_test "GET_MODE (XEXP (op, 0)) == HImode")
|
||||
(match_test "GET_MODE (XEXP (op, 0)) == SImode"))))
|
||||
|
||||
(define_predicate "spu_inv_exp2_operand"
|
||||
(and (match_code "const_double,const_vector")
|
||||
(and (match_operand 0 "immediate_operand")
|
||||
(match_test "exp2_immediate_p (op, mode, -126, 0)"))))
|
||||
|
||||
(define_predicate "spu_exp2_operand"
|
||||
(and (match_code "const_double,const_vector")
|
||||
(and (match_operand 0 "immediate_operand")
|
||||
(match_test "exp2_immediate_p (op, mode, 0, 127)"))))
|
||||
|
||||
|
@ -235,8 +235,8 @@ DEF_BUILTIN (SI_FROM_PTR, CODE_FOR_spu_convert, "si_from_ptr", B_INSN,
|
||||
|
||||
/* definitions to support generic builtin functions: */
|
||||
|
||||
DEF_BUILTIN (SPU_CONVTS, CODE_FOR_spu_cflts, "spu_convts", B_INSN, _A3(SPU_BTI_V4SI, SPU_BTI_V4SF, SPU_BTI_U7))
|
||||
DEF_BUILTIN (SPU_CONVTU, CODE_FOR_spu_cfltu, "spu_convtu", B_INSN, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SF, SPU_BTI_U7))
|
||||
DEF_BUILTIN (SPU_CONVTS, CODE_FOR_spu_cflts, "spu_convts", B_INSN, _A3(SPU_BTI_V4SI, SPU_BTI_V4SF, SPU_BTI_INTSI))
|
||||
DEF_BUILTIN (SPU_CONVTU, CODE_FOR_spu_cfltu, "spu_convtu", B_INSN, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SF, SPU_BTI_INTSI))
|
||||
DEF_BUILTIN (SPU_ROUNDTF, CODE_FOR_spu_frds, "spu_roundtf", B_INSN, _A2(SPU_BTI_V4SF, SPU_BTI_V2DF))
|
||||
DEF_BUILTIN (SPU_MULH, CODE_FOR_spu_mpyh, "spu_mulh", B_INSN, _A3(SPU_BTI_V4SI, SPU_BTI_V8HI, SPU_BTI_V8HI))
|
||||
DEF_BUILTIN (SPU_MULSR, CODE_FOR_spu_mpys, "spu_mulsr", B_INSN, _A3(SPU_BTI_V4SI, SPU_BTI_V8HI, SPU_BTI_V8HI))
|
||||
@ -257,8 +257,8 @@ DEF_BUILTIN (SPU_TESTSV, CODE_FOR_dftsv, "spu_testsv", B_INSN,
|
||||
/* definitions to support overloaded generic builtin functions: */
|
||||
|
||||
DEF_BUILTIN (SPU_CONVTF, CODE_FOR_nothing, "spu_convtf", B_OVERLOAD, _A1(SPU_BTI_VOID))
|
||||
DEF_BUILTIN (SPU_CONVTF_0, CODE_FOR_spu_cuflt, "spu_convtf_0", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_UV4SI, SPU_BTI_U7))
|
||||
DEF_BUILTIN (SPU_CONVTF_1, CODE_FOR_spu_csflt, "spu_convtf_1", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SI, SPU_BTI_U7))
|
||||
DEF_BUILTIN (SPU_CONVTF_0, CODE_FOR_spu_cuflt, "spu_convtf_0", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_UV4SI, SPU_BTI_UINTSI))
|
||||
DEF_BUILTIN (SPU_CONVTF_1, CODE_FOR_spu_csflt, "spu_convtf_1", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SI, SPU_BTI_UINTSI))
|
||||
DEF_BUILTIN (SPU_EXTEND, CODE_FOR_nothing, "spu_extend", B_OVERLOAD, _A1(SPU_BTI_VOID))
|
||||
DEF_BUILTIN (SPU_EXTEND_0, CODE_FOR_spu_xsbh, "spu_extend_0", B_INTERNAL, _A2(SPU_BTI_V8HI, SPU_BTI_V16QI))
|
||||
DEF_BUILTIN (SPU_EXTEND_1, CODE_FOR_spu_xshw, "spu_extend_1", B_INTERNAL, _A2(SPU_BTI_V4SI, SPU_BTI_V8HI))
|
||||
|
@ -527,37 +527,119 @@
|
||||
[(set_attr "type" "br")])
|
||||
|
||||
;; float convert
|
||||
(define_insn "spu_csflt"
|
||||
(define_expand "spu_csflt"
|
||||
[(set (match_operand:V4SF 0 "spu_reg_operand")
|
||||
(unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand")
|
||||
(match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
|
||||
""
|
||||
{
|
||||
if (GET_CODE (operands[2]) == CONST_INT
|
||||
&& (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
|
||||
{
|
||||
error ("spu_convtf expects an integer literal in the range [0, 127].");
|
||||
operands[2] = force_reg (SImode, operands[2]);
|
||||
}
|
||||
if (GET_CODE (operands[2]) != CONST_INT)
|
||||
{
|
||||
rtx exp2;
|
||||
rtx cnv = gen_reg_rtx (V4SFmode);
|
||||
rtx scale = gen_reg_rtx (SImode);
|
||||
rtx op2 = force_reg (SImode, operands[2]);
|
||||
rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1));
|
||||
emit_insn (gen_subsi3 (scale, const1_rtx, op2));
|
||||
exp2 = spu_gen_exp2 (V4SFmode, scale);
|
||||
emit_insn (gen_floatv4siv4sf2_mul (cnv, operands[1], m1));
|
||||
emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
|
||||
emit_insn (gen_floatv4siv4sf2_div (operands[0], operands[1], exp2));
|
||||
}
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "spu_cflts"
|
||||
[(set (match_operand:V4SI 0 "spu_reg_operand")
|
||||
(unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand")
|
||||
(match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
|
||||
""
|
||||
{
|
||||
rtx exp2;
|
||||
if (GET_CODE (operands[2]) == CONST_INT
|
||||
&& (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
|
||||
{
|
||||
error ("spu_convts expects an integer literal in the range [0, 127].");
|
||||
operands[2] = force_reg (SImode, operands[2]);
|
||||
}
|
||||
exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
|
||||
if (GET_CODE (operands[2]) != CONST_INT)
|
||||
{
|
||||
rtx mul = gen_reg_rtx (V4SFmode);
|
||||
emit_insn (gen_mulv4sf3 (mul, operands[1], exp2));
|
||||
emit_insn (gen_fix_truncv4sfv4si2 (operands[0], mul));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_fix_truncv4sfv4si2_mul (operands[0], operands[1], exp2));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "spu_cuflt"
|
||||
[(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
|
||||
(unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
|
||||
(match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CSFLT ))]
|
||||
(unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand")
|
||||
(match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
|
||||
""
|
||||
"csflt\t%0,%1,%2"
|
||||
[(set_attr "type" "fp7")])
|
||||
{
|
||||
if (GET_CODE (operands[2]) == CONST_INT
|
||||
&& (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
|
||||
{
|
||||
error ("spu_convtf expects an integer literal in the range [0, 127].");
|
||||
operands[2] = force_reg (SImode, operands[2]);
|
||||
}
|
||||
if (GET_CODE (operands[2]) != CONST_INT)
|
||||
{
|
||||
rtx exp2;
|
||||
rtx cnv = gen_reg_rtx (V4SFmode);
|
||||
rtx scale = gen_reg_rtx (SImode);
|
||||
rtx op2 = force_reg (SImode, operands[2]);
|
||||
rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1));
|
||||
emit_insn (gen_subsi3 (scale, const1_rtx, op2));
|
||||
exp2 = spu_gen_exp2 (V4SFmode, scale);
|
||||
emit_insn (gen_floatunsv4siv4sf2_mul (cnv, operands[1], m1));
|
||||
emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
|
||||
emit_insn (gen_floatunsv4siv4sf2_div (operands[0], operands[1], exp2));
|
||||
}
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "spu_cflts"
|
||||
[(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
|
||||
(unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
|
||||
(match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTS ))]
|
||||
(define_expand "spu_cfltu"
|
||||
[(set (match_operand:V4SI 0 "spu_reg_operand")
|
||||
(unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand")
|
||||
(match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
|
||||
""
|
||||
"cflts\t%0,%1,%2"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "spu_cuflt"
|
||||
[(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
|
||||
(unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
|
||||
(match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CUFLT ))]
|
||||
""
|
||||
"cuflt\t%0,%1,%2"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "spu_cfltu"
|
||||
[(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
|
||||
(unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
|
||||
(match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTU ))]
|
||||
""
|
||||
"cfltu\t%0,%1,%2"
|
||||
[(set_attr "type" "fp7")])
|
||||
{
|
||||
rtx exp2;
|
||||
if (GET_CODE (operands[2]) == CONST_INT
|
||||
&& (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
|
||||
{
|
||||
error ("spu_convtu expects an integer literal in the range [0, 127].");
|
||||
operands[2] = force_reg (SImode, operands[2]);
|
||||
}
|
||||
exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
|
||||
if (GET_CODE (operands[2]) != CONST_INT)
|
||||
{
|
||||
rtx mul = gen_reg_rtx (V4SFmode);
|
||||
emit_insn (gen_mulv4sf3 (mul, operands[1], exp2));
|
||||
emit_insn (gen_fixuns_truncv4sfv4si2 (operands[0], mul));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_fixuns_truncv4sfv4si2_mul (operands[0], operands[1], exp2));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "spu_frds"
|
||||
[(set (match_operand:V4SF 0 "spu_reg_operand" "")
|
||||
|
@ -51,6 +51,8 @@ extern int logical_immediate_p (rtx op, enum machine_mode mode);
|
||||
extern int iohl_immediate_p (rtx op, enum machine_mode mode);
|
||||
extern int arith_immediate_p (rtx op, enum machine_mode mode,
|
||||
HOST_WIDE_INT low, HOST_WIDE_INT high);
|
||||
extern bool exp2_immediate_p (rtx op, enum machine_mode mode, int low,
|
||||
int high);
|
||||
extern int spu_constant_address_p (rtx x);
|
||||
extern int spu_legitimate_constant_p (rtx x);
|
||||
extern int spu_legitimate_address (enum machine_mode mode, rtx x,
|
||||
@ -75,6 +77,7 @@ extern rtx gen_cpat_const (rtx * ops);
|
||||
extern void constant_to_array (enum machine_mode mode, rtx x,
|
||||
unsigned char *arr);
|
||||
extern rtx array_to_constant (enum machine_mode mode, unsigned char *arr);
|
||||
extern rtx spu_gen_exp2 (enum machine_mode mode, rtx x);
|
||||
extern void spu_allocate_stack (rtx op0, rtx op1);
|
||||
extern void spu_restore_stack_nonlocal (rtx op0, rtx op1);
|
||||
extern void spu_restore_stack_block (rtx op0, rtx op1);
|
||||
|
@ -1586,6 +1586,13 @@ print_operand (FILE * file, rtx x, int code)
|
||||
output_addr_const (file, GEN_INT (val));
|
||||
return;
|
||||
|
||||
case 'v':
|
||||
case 'w':
|
||||
constant_to_array (mode, x, arr);
|
||||
val = (((arr[0] << 1) + (arr[1] >> 7)) & 0xff) - 127;
|
||||
output_addr_const (file, GEN_INT (code == 'w' ? -val : val));
|
||||
return;
|
||||
|
||||
case 0:
|
||||
if (xcode == REG)
|
||||
fprintf (file, "%s", reg_names[REGNO (x)]);
|
||||
@ -1598,7 +1605,7 @@ print_operand (FILE * file, rtx x, int code)
|
||||
return;
|
||||
|
||||
/* unused letters
|
||||
o qr uvw yz
|
||||
o qr u yz
|
||||
AB OPQR UVWXYZ */
|
||||
default:
|
||||
output_operand_lossage ("invalid %%xn code");
|
||||
@ -3495,6 +3502,58 @@ arith_immediate_p (rtx op, enum machine_mode mode,
|
||||
return val >= low && val <= high;
|
||||
}
|
||||
|
||||
/* TRUE when op is an immediate and an exact power of 2, and given that
|
||||
OP is 2^scale, scale >= LOW && scale <= HIGH. When OP is a vector,
|
||||
all entries must be the same. */
|
||||
bool
|
||||
exp2_immediate_p (rtx op, enum machine_mode mode, int low, int high)
|
||||
{
|
||||
enum machine_mode int_mode;
|
||||
HOST_WIDE_INT val;
|
||||
unsigned char arr[16];
|
||||
int bytes, i, j;
|
||||
|
||||
gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
|
||||
|| GET_CODE (op) == CONST_VECTOR);
|
||||
|
||||
if (GET_CODE (op) == CONST_VECTOR
|
||||
&& !const_vector_immediate_p (op))
|
||||
return 0;
|
||||
|
||||
if (GET_MODE (op) != VOIDmode)
|
||||
mode = GET_MODE (op);
|
||||
|
||||
constant_to_array (mode, op, arr);
|
||||
|
||||
if (VECTOR_MODE_P (mode))
|
||||
mode = GET_MODE_INNER (mode);
|
||||
|
||||
bytes = GET_MODE_SIZE (mode);
|
||||
int_mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
|
||||
|
||||
/* Check that bytes are repeated. */
|
||||
for (i = bytes; i < 16; i += bytes)
|
||||
for (j = 0; j < bytes; j++)
|
||||
if (arr[j] != arr[i + j])
|
||||
return 0;
|
||||
|
||||
val = arr[0];
|
||||
for (j = 1; j < bytes; j++)
|
||||
val = (val << 8) | arr[j];
|
||||
|
||||
val = trunc_int_for_mode (val, int_mode);
|
||||
|
||||
/* Currently, we only handle SFmode */
|
||||
gcc_assert (mode == SFmode);
|
||||
if (mode == SFmode)
|
||||
{
|
||||
int exp = (val >> 23) - 127;
|
||||
return val > 0 && (val & 0x007fffff) == 0
|
||||
&& exp >= low && exp <= high;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We accept:
|
||||
- any 32-bit constant (SImode, SFmode)
|
||||
- any constant that can be generated with fsmbi (any mode)
|
||||
@ -6364,4 +6423,36 @@ spu_section_type_flags (tree decl, const char *name, int reloc)
|
||||
return default_section_type_flags (decl, name, reloc);
|
||||
}
|
||||
|
||||
/* Generate a constant or register which contains 2^SCALE. We assume
|
||||
the result is valid for MODE. Currently, MODE must be V4SFmode and
|
||||
SCALE must be SImode. */
|
||||
rtx
|
||||
spu_gen_exp2 (enum machine_mode mode, rtx scale)
|
||||
{
|
||||
gcc_assert (mode == V4SFmode);
|
||||
gcc_assert (GET_MODE (scale) == SImode || GET_CODE (scale) == CONST_INT);
|
||||
if (GET_CODE (scale) != CONST_INT)
|
||||
{
|
||||
/* unsigned int exp = (127 + scale) << 23;
|
||||
__vector float m = (__vector float) spu_splats (exp); */
|
||||
rtx reg = force_reg (SImode, scale);
|
||||
rtx exp = gen_reg_rtx (SImode);
|
||||
rtx mul = gen_reg_rtx (mode);
|
||||
emit_insn (gen_addsi3 (exp, reg, GEN_INT (127)));
|
||||
emit_insn (gen_ashlsi3 (exp, exp, GEN_INT (23)));
|
||||
emit_insn (gen_spu_splats (mul, gen_rtx_SUBREG (GET_MODE_INNER (mode), exp, 0)));
|
||||
return mul;
|
||||
}
|
||||
else
|
||||
{
|
||||
HOST_WIDE_INT exp = 127 + INTVAL (scale);
|
||||
unsigned char arr[16];
|
||||
arr[0] = arr[4] = arr[8] = arr[12] = exp >> 1;
|
||||
arr[1] = arr[5] = arr[9] = arr[13] = exp << 7;
|
||||
arr[2] = arr[6] = arr[10] = arr[14] = 0;
|
||||
arr[3] = arr[7] = arr[11] = arr[15] = 0;
|
||||
return array_to_constant (mode, arr);
|
||||
}
|
||||
}
|
||||
|
||||
#include "gt-spu.h"
|
||||
|
@ -136,10 +136,6 @@
|
||||
(UNSPEC_HEQ 31)
|
||||
(UNSPEC_HGT 32)
|
||||
(UNSPEC_HLGT 33)
|
||||
(UNSPEC_CSFLT 34)
|
||||
(UNSPEC_CFLTS 35)
|
||||
(UNSPEC_CUFLT 36)
|
||||
(UNSPEC_CFLTU 37)
|
||||
(UNSPEC_STOP 38)
|
||||
(UNSPEC_STOPD 39)
|
||||
(UNSPEC_SET_INTR 40)
|
||||
@ -231,6 +227,10 @@
|
||||
(DF "di") (V2DF "v2di")])
|
||||
(define_mode_attr F2I [(SF "SI") (V4SF "V4SI")
|
||||
(DF "DI") (V2DF "V2DI")])
|
||||
(define_mode_attr i2f [(SI "sf") (V4SI "v4sf")
|
||||
(DI "df") (V2DI "v2df")])
|
||||
(define_mode_attr I2F [(SI "SF") (V4SI "V4SF")
|
||||
(DI "DF") (V2DI "V2DF")])
|
||||
|
||||
(define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")])
|
||||
|
||||
@ -594,60 +594,81 @@
|
||||
|
||||
;; float conversions
|
||||
|
||||
(define_insn "floatsisf2"
|
||||
[(set (match_operand:SF 0 "spu_reg_operand" "=r")
|
||||
(float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
|
||||
(define_insn "float<mode><i2f>2"
|
||||
[(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
|
||||
(float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
|
||||
""
|
||||
"csflt\t%0,%1,0"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "floatv4siv4sf2"
|
||||
[(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
|
||||
(float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
|
||||
""
|
||||
"csflt\t%0,%1,0"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "fix_truncsfsi2"
|
||||
[(set (match_operand:SI 0 "spu_reg_operand" "=r")
|
||||
(fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
|
||||
(define_insn "fix_trunc<mode><f2i>2"
|
||||
[(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
|
||||
(fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
|
||||
""
|
||||
"cflts\t%0,%1,0"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "fix_truncv4sfv4si2"
|
||||
[(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
|
||||
(fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
|
||||
""
|
||||
"cflts\t%0,%1,0"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "floatunssisf2"
|
||||
[(set (match_operand:SF 0 "spu_reg_operand" "=r")
|
||||
(unsigned_float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
|
||||
(define_insn "floatuns<mode><i2f>2"
|
||||
[(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
|
||||
(unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
|
||||
""
|
||||
"cuflt\t%0,%1,0"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "floatunsv4siv4sf2"
|
||||
[(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
|
||||
(unsigned_float:V4SF (match_operand:V4SI 1 "spu_reg_operand" "r")))]
|
||||
""
|
||||
"cuflt\t%0,%1,0"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "fixuns_truncsfsi2"
|
||||
[(set (match_operand:SI 0 "spu_reg_operand" "=r")
|
||||
(unsigned_fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
|
||||
(define_insn "fixuns_trunc<mode><f2i>2"
|
||||
[(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
|
||||
(unsigned_fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
|
||||
""
|
||||
"cfltu\t%0,%1,0"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "fixuns_truncv4sfv4si2"
|
||||
[(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
|
||||
(unsigned_fix:V4SI (match_operand:V4SF 1 "spu_reg_operand" "r")))]
|
||||
(define_insn "float<mode><i2f>2_mul"
|
||||
[(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
|
||||
(mult:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
|
||||
(match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
|
||||
""
|
||||
"cfltu\t%0,%1,0"
|
||||
"csflt\t%0,%1,%w2"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "float<mode><i2f>2_div"
|
||||
[(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
|
||||
(div:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
|
||||
(match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
|
||||
""
|
||||
"csflt\t%0,%1,%v2"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
|
||||
(define_insn "fix_trunc<mode><f2i>2_mul"
|
||||
[(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
|
||||
(fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
|
||||
(match_operand:VSF 2 "spu_exp2_operand" "v"))))]
|
||||
""
|
||||
"cflts\t%0,%1,%v2"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "floatuns<mode><i2f>2_mul"
|
||||
[(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
|
||||
(mult:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
|
||||
(match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
|
||||
""
|
||||
"cuflt\t%0,%1,%w2"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "floatuns<mode><i2f>2_div"
|
||||
[(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
|
||||
(div:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
|
||||
(match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
|
||||
""
|
||||
"cuflt\t%0,%1,%v2"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "fixuns_trunc<mode><f2i>2_mul"
|
||||
[(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
|
||||
(unsigned_fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
|
||||
(match_operand:VSF 2 "spu_exp2_operand" "v"))))]
|
||||
""
|
||||
"cfltu\t%0,%1,%v2"
|
||||
[(set_attr "type" "fp7")])
|
||||
|
||||
(define_insn "extendsfdf2"
|
||||
|
@ -1,3 +1,8 @@
|
||||
2009-04-27 Trevor Smigiel <trevor_smigiel@playstation.sony.com>
|
||||
|
||||
Allow non-constant arguments to conversion intrinsics.
|
||||
* gcc.target/spu/intrinsics-3.c: Update tests.
|
||||
|
||||
2009-04-27 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/39928
|
||||
|
@ -19,3 +19,24 @@ void f3 (vec_float4 *in)
|
||||
{
|
||||
vec_uint4 out = spu_convtu (in[0], 128); /* { dg-error "expects an integer literal in the range" "0, 127" }*/
|
||||
}
|
||||
|
||||
/* Test that these intrinsics accept non-literal arguments */
|
||||
void f4 (vec_uint4 *in, int n)
|
||||
{
|
||||
vec_float4 out = spu_convtf (in[0], n);
|
||||
}
|
||||
|
||||
void f5 (vec_int4 *in, int n)
|
||||
{
|
||||
vec_float4 out = spu_convtf (in[0], n);
|
||||
}
|
||||
|
||||
void f6 (vec_float4 *in, int n)
|
||||
{
|
||||
vec_int4 out = spu_convts (in[0], n);
|
||||
}
|
||||
|
||||
void f7 (vec_float4 *in, int n)
|
||||
{
|
||||
vec_uint4 out = spu_convtu (in[0], n);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user