aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorDorit Nuzman <dorit@il.ibm.com>2006-12-20 14:07:38 +0000
committerDorit Nuzman <dorit@gcc.gnu.org>2006-12-20 14:07:38 +0000
commitc882a2c2384d367d612ab1ce12030d6900d216c9 (patch)
tree081393dfa2fc920ca7ba8c26ccdaa57ce77a0082 /gcc/config
parent71f77fd790b55c7d6b831d76665bdf26a65fad2b (diff)
downloadgcc-c882a2c2384d367d612ab1ce12030d6900d216c9.zip
gcc-c882a2c2384d367d612ab1ce12030d6900d216c9.tar.gz
gcc-c882a2c2384d367d612ab1ce12030d6900d216c9.tar.bz2
spu.md (vec_widen_umult_hi_v8hi): New.
* config/spu/spu.md (vec_widen_umult_hi_v8hi): New. (vec_widen_umult_lo_v8hi, vec_widen_smult_hi_v8hi): New. (vec_widen_smult_lo_v8hi): New. * config/spu/spu.c (TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN): Defined. (TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD): Defined. (spu_builtin_mul_widen_even, spu_builtin_mul_widen_odd): New. From-SVN: r120073
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/spu/spu.c43
-rw-r--r--gcc/config/spu/spu.md112
2 files changed, 155 insertions, 0 deletions
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index 83bfdc8..58a34a8 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -130,6 +130,8 @@ 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_mul_widen_even (tree);
+static tree spu_builtin_mul_widen_odd (tree);
static tree spu_builtin_mask_for_load (void);
extern const char *reg_names[];
@@ -249,6 +251,12 @@ 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_MUL_WIDEN_EVEN
+#define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN spu_builtin_mul_widen_even
+
+#undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
+#define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD spu_builtin_mul_widen_odd
+
#undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
#define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD spu_builtin_mask_for_load
@@ -4993,6 +5001,41 @@ spu_expand_builtin (tree exp,
abort ();
}
+/* Implement targetm.vectorize.builtin_mul_widen_even. */
+static tree
+spu_builtin_mul_widen_even (tree type)
+{
+ struct spu_builtin_description *d;
+ switch (TYPE_MODE (type))
+ {
+ case V8HImode:
+ if (TYPE_UNSIGNED (type))
+ return spu_builtins[SPU_MULE_0].fndecl;
+ else
+ return spu_builtins[SPU_MULE_1].fndecl;
+ break;
+ default:
+ return NULL_TREE;
+ }
+}
+
+/* Implement targetm.vectorize.builtin_mul_widen_odd. */
+static tree
+spu_builtin_mul_widen_odd (tree type)
+{
+ switch (TYPE_MODE (type))
+ {
+ case V8HImode:
+ if (TYPE_UNSIGNED (type))
+ return spu_builtins[SPU_MULO_1].fndecl;
+ else
+ return spu_builtins[SPU_MULO_0].fndecl;
+ break;
+ default:
+ return NULL_TREE;
+ }
+}
+
/* Implement targetm.vectorize.builtin_mask_for_load. */
static tree
spu_builtin_mask_for_load (void)
diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md
index 60f00fb..7978361 100644
--- a/gcc/config/spu/spu.md
+++ b/gcc/config/spu/spu.md
@@ -3378,6 +3378,118 @@ selb\t%0,%4,%0,%3"
DONE;
}")
+(define_expand "vec_widen_umult_hi_v8hi"
+ [(set (match_operand:V4SI 0 "register_operand" "=r")
+ (mult:V4SI
+ (zero_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 1 "register_operand" "r")
+ (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
+ (zero_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 2 "register_operand" "r")
+ (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
+ ""
+ "
+{
+ rtx ve = gen_reg_rtx (V4SImode);
+ rtx vo = gen_reg_rtx (V4SImode);
+ rtx mask = gen_reg_rtx (TImode);
+ unsigned char arr[16] = {
+ 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+ 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
+
+ emit_move_insn (mask, array_to_constant (TImode, arr));
+ emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
+ emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
+ emit_insn (gen_shufb (operands[0], ve, vo, mask));
+ DONE;
+}")
+
+(define_expand "vec_widen_umult_lo_v8hi"
+ [(set (match_operand:V4SI 0 "register_operand" "=r")
+ (mult:V4SI
+ (zero_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 1 "register_operand" "r")
+ (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
+ (zero_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 2 "register_operand" "r")
+ (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
+ ""
+ "
+{
+ rtx ve = gen_reg_rtx (V4SImode);
+ rtx vo = gen_reg_rtx (V4SImode);
+ rtx mask = gen_reg_rtx (TImode);
+ unsigned char arr[16] = {
+ 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
+
+ emit_move_insn (mask, array_to_constant (TImode, arr));
+ emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
+ emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
+ emit_insn (gen_shufb (operands[0], ve, vo, mask));
+ DONE;
+}")
+
+(define_expand "vec_widen_smult_hi_v8hi"
+ [(set (match_operand:V4SI 0 "register_operand" "=r")
+ (mult:V4SI
+ (sign_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 1 "register_operand" "r")
+ (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
+ (sign_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 2 "register_operand" "r")
+ (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
+ ""
+ "
+{
+ rtx ve = gen_reg_rtx (V4SImode);
+ rtx vo = gen_reg_rtx (V4SImode);
+ rtx mask = gen_reg_rtx (TImode);
+ unsigned char arr[16] = {
+ 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+ 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
+
+ emit_move_insn (mask, array_to_constant (TImode, arr));
+ emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
+ emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
+ emit_insn (gen_shufb (operands[0], ve, vo, mask));
+ DONE;
+}")
+
+(define_expand "vec_widen_smult_lo_v8hi"
+ [(set (match_operand:V4SI 0 "register_operand" "=r")
+ (mult:V4SI
+ (sign_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 1 "register_operand" "r")
+ (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
+ (sign_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 2 "register_operand" "r")
+ (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
+ ""
+ "
+{
+ rtx ve = gen_reg_rtx (V4SImode);
+ rtx vo = gen_reg_rtx (V4SImode);
+ rtx mask = gen_reg_rtx (TImode);
+ unsigned char arr[16] = {
+ 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
+
+ emit_move_insn (mask, array_to_constant (TImode, arr));
+ emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
+ emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
+ emit_insn (gen_shufb (operands[0], ve, vo, 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")