spu.c (TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD): Defined.

* spu.c (TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD): Defined.
        (spu_init_builtins): Mark the SPU_MASK_FOR_LOAD builtin decl as read
        only.
        (spu_expand_builtin_1): Handle the SPU_MASK_FOR_LOAD builtin.
        (spu_builtin_mask_for_load): New.
        * spu-builtins.def (SPU_MASK_FOR_LOAD): Define new builtin.
        * spu.md (UNSPEC_SPU_REALIGN_LOAD, UNSPEC_SPU_MASK_FOR_LOAD):New.
        (vec_realign_load_<mode>, spu_lvsr): New.


Co-Authored-By: Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>

From-SVN: r119857
This commit is contained in:
Dorit Nuzman 2006-12-14 12:11:38 +00:00 committed by Dorit Nuzman
parent f4f7486bcf
commit bbea461bd9
6 changed files with 110 additions and 2 deletions

View File

@ -1,3 +1,15 @@
2006-12-14 Dorit Nuzman <dorit@il.ibm.com>
Trevor Smigiel <trevor_smigiel@playstation.sony.com>
* spu.c (TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD): Defined.
(spu_init_builtins): Mark the SPU_MASK_FOR_LOAD builtin decl as read
only.
(spu_expand_builtin_1): Handle the SPU_MASK_FOR_LOAD builtin.
(spu_builtin_mask_for_load): New.
* spu-builtins.def (SPU_MASK_FOR_LOAD): Define new builtin.
* spu.md (UNSPEC_SPU_REALIGN_LOAD, UNSPEC_SPU_MASK_FOR_LOAD):New.
(vec_realign_load_<mode>, spu_lvsr): New.
2006-12-13 Ian Lance Taylor <iant@google.com>
PR c++/19564

View File

@ -246,6 +246,7 @@ DEF_BUILTIN (SPU_CMPABSEQ, CODE_FOR_cmeq_v4sf, "spu_cmpabseq", B_INSN,
DEF_BUILTIN (SPU_CMPABSGT, CODE_FOR_cmgt_v4sf, "spu_cmpabsgt", B_INSN, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SF, SPU_BTI_V4SF))
DEF_BUILTIN (SPU_IDISABLE, CODE_FOR_spu_idisable, "spu_idisable", B_INSN, _A1(SPU_BTI_VOID))
DEF_BUILTIN (SPU_IENABLE, CODE_FOR_spu_ienable, "spu_ienable", B_INSN, _A1(SPU_BTI_VOID))
DEF_BUILTIN (SPU_MASK_FOR_LOAD, CODE_FOR_spu_lvsr, "spu_lvsr", B_INSN, _A2(SPU_BTI_V16QI, SPU_BTI_PTR))
/* definitions to support overloaded generic builtin functions: */

View File

@ -130,6 +130,7 @@ static void spu_init_libfuncs (void);
static bool spu_return_in_memory (tree type, tree fntype);
static void fix_range (const char *);
static void spu_encode_section_info (tree, rtx, int);
static tree spu_builtin_mask_for_load (void);
extern const char *reg_names[];
rtx spu_compare_op0, spu_compare_op1;
@ -248,6 +249,9 @@ const struct attribute_spec spu_attribute_table[];
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO spu_encode_section_info
#undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
#define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD spu_builtin_mask_for_load
struct gcc_target targetm = TARGET_INITIALIZER;
/* Sometimes certain combinations of command options do not make sense
@ -4288,6 +4292,8 @@ spu_init_builtins (void)
d->fndecl =
add_builtin_function (name, p, END_BUILTINS + i, BUILT_IN_MD,
NULL, NULL_TREE);
if (d->fcode == SPU_MASK_FOR_LOAD)
TREE_READONLY (d->fndecl) = 1;
}
}
@ -4843,6 +4849,31 @@ spu_expand_builtin_1 (struct spu_builtin_description *d,
i++;
}
if (d->fcode == SPU_MASK_FOR_LOAD)
{
enum machine_mode mode = insn_data[icode].operand[1].mode;
tree arg;
rtx addr, op, pat;
/* get addr */
arg = TREE_VALUE (arglist);
gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
addr = memory_address (mode, op);
/* negate addr */
op = gen_reg_rtx (GET_MODE (addr));
emit_insn (gen_rtx_SET (VOIDmode, op,
gen_rtx_NEG (GET_MODE (addr), addr)));
op = gen_rtx_MEM (mode, op);
pat = GEN_FCN (icode) (target, op);
if (!pat)
return 0;
emit_insn (pat);
return target;
}
/* Ignore align_hint, but still expand it's args in case they have
side effects. */
if (icode == CODE_FOR_spu_align_hint)
@ -4962,3 +4993,11 @@ spu_expand_builtin (tree exp,
abort ();
}
/* Implement targetm.vectorize.builtin_mask_for_load. */
static tree
spu_builtin_mask_for_load (void)
{
struct spu_builtin_description *d = &spu_builtins[SPU_MASK_FOR_LOAD];
gcc_assert (d);
return d->fndecl;
}

View File

@ -142,7 +142,10 @@
(UNSPEC_MTSPR 45)
(UNSPEC_RDCH 46)
(UNSPEC_RCHCNT 47)
(UNSPEC_WRCH 48)])
(UNSPEC_WRCH 48)
(UNSPEC_SPU_REALIGN_LOAD 49)
(UNSPEC_SPU_MASK_FOR_LOAD 50)
])
(include "predicates.md")
(include "constraints.md")
@ -3374,3 +3377,53 @@ selb\t%0,%4,%0,%3"
emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
DONE;
}")
(define_expand "vec_realign_load_<mode>"
[(set (match_operand:ALL 0 "register_operand" "=r")
(unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
(match_operand:ALL 2 "register_operand" "r")
(match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
""
"
{
emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
DONE;
}")
(define_expand "spu_lvsr"
[(set (match_operand:V16QI 0 "register_operand" "")
(unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
""
"
{
rtx addr;
rtx offset = gen_reg_rtx (V8HImode);
rtx addr_bits = gen_reg_rtx (SImode);
rtx addr_bits_vec = gen_reg_rtx (V8HImode);
rtx splatqi = gen_reg_rtx (TImode);
rtx result = gen_reg_rtx (V8HImode);
unsigned char arr[16] = {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
unsigned char arr2[16] = {
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
emit_move_insn (offset, array_to_constant (V8HImode, arr));
emit_move_insn (splatqi, array_to_constant (TImode, arr2));
gcc_assert (GET_CODE (operands[1]) == MEM);
addr = force_reg (Pmode, XEXP (operands[1], 0));
emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
/* offset - (addr & 0xF)
It is safe to use a single sfh, because each byte of offset is > 15 and
each byte of addr is <= 15. */
emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
emit_move_insn (operands[0], result);
DONE;
}")

View File

@ -1,3 +1,7 @@
2006-12-14 Dorit Nuzman <dorit@il.ibm.com>
* lib/target-supports.exp (vect_no_align): Remove spu.
2006-12-13 Ian Lance Taylor <iant@google.com>
PR c++/19564

View File

@ -1789,7 +1789,6 @@ proc check_effective_target_vect_no_align { } {
} else {
set et_vect_no_align_saved 0
if { [istarget mipsisa64*-*-*]
|| [istarget spu-*-*]
|| [istarget sparc*-*-*]
|| [istarget ia64-*-*] } {
set et_vect_no_align_saved 1