aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2002-01-07 20:43:18 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2002-01-07 20:43:18 +0000
commit20e267130303233419490f5e849367e7cf6a5974 (patch)
tree21a802b08d849908f1883b4c4defbf54ff293b39 /gcc
parent4dd57c18061b32137907024ee21cf115f34228a4 (diff)
downloadgcc-20e267130303233419490f5e849367e7cf6a5974.zip
gcc-20e267130303233419490f5e849367e7cf6a5974.tar.gz
gcc-20e267130303233419490f5e849367e7cf6a5974.tar.bz2
rs6000.c (altivec_expand_ternop_builtin): Don't die on invalid arguments.
2002-01-07 Aldy Hernandez <aldyh@redhat.com> * rs6000.c (altivec_expand_ternop_builtin): Don't die on invalid arguments. (altivec_expand_binop_builtin): Same. (altivec_expand_unop_builtin): Same. (print_operand): Fix typo. (bdesc_1arg): Add vupk* variants. * rs6000.h (rs6000_builtins): Add vupk* enums. * rs6000.md: Add altivec_vupk* variants. From-SVN: r48611
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/rs6000/rs6000.c50
-rw-r--r--gcc/config/rs6000/rs6000.h8
-rw-r--r--gcc/config/rs6000/rs6000.md42
4 files changed, 104 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 16081a0..7aa7478 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2002-01-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * rs6000.c (altivec_expand_ternop_builtin): Don't die on invalid
+ arguments.
+ (altivec_expand_binop_builtin): Same.
+ (altivec_expand_unop_builtin): Same.
+ (print_operand): Fix typo.
+ (bdesc_1arg): Add vupk* variants.
+
+ * rs6000.h (rs6000_builtins): Add vupk* enums.
+
+ * rs6000.md: Add altivec_vupk* variants.
+
2002-01-07 Joseph S. Myers <jsm28@cam.ac.uk>
* doc/gcc.texi, doc/gccint.texi, doc/cppinternals.texi,
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 618d3d2..4be53b7 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3375,6 +3375,12 @@ static const struct builtin_description bdesc_1arg[] =
{ MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
{ MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
{ MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
+ { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
+ { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
+ { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
+ { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
+ { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
+ { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
};
static rtx
@@ -3389,7 +3395,11 @@ altivec_expand_unop_builtin (icode, arglist, target)
enum machine_mode tmode = insn_data[icode].operand[0].mode;
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
- if (! target
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node)
+ return target;
+
+ if (target != 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
@@ -3419,7 +3429,11 @@ altivec_expand_binop_builtin (icode, arglist, target)
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
enum machine_mode mode1 = insn_data[icode].operand[2].mode;
- if (! target
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node || arg1 == error_mark_node)
+ return target;
+
+ if (target != 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
@@ -3454,7 +3468,13 @@ altivec_expand_ternop_builtin (icode, arglist, target)
enum machine_mode mode1 = insn_data[icode].operand[2].mode;
enum machine_mode mode2 = insn_data[icode].operand[3].mode;
- if (! target
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node
+ || arg1 == error_mark_node
+ || arg2 == error_mark_node)
+ return target;
+
+ if (target != 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
@@ -3497,7 +3517,7 @@ altivec_expand_builtin (exp, target)
tmode = insn_data[icode].operand[0].mode;
mode0 = insn_data[icode].operand[1].mode;
- if (! target
+ if (target != 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
@@ -3518,7 +3538,7 @@ altivec_expand_builtin (exp, target)
tmode = insn_data[icode].operand[0].mode;
mode0 = insn_data[icode].operand[1].mode;
- if (! target
+ if (target != 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
@@ -3539,7 +3559,7 @@ altivec_expand_builtin (exp, target)
tmode = insn_data[icode].operand[0].mode;
mode0 = insn_data[icode].operand[1].mode;
- if (! target
+ if (target != 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
@@ -3560,7 +3580,7 @@ altivec_expand_builtin (exp, target)
tmode = insn_data[icode].operand[0].mode;
mode0 = insn_data[icode].operand[1].mode;
- if (! target
+ if (target != 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
@@ -3716,6 +3736,7 @@ altivec_init_builtins (void)
tree pshort_type_node = build_pointer_type (short_integer_type_node);
tree pchar_type_node = build_pointer_type (char_type_node);
tree pfloat_type_node = build_pointer_type (float_type_node);
+
tree v4sf_ftype_v4sf_v4sf_v16qi
= build_function_type (V4SF_type_node,
tree_cons (NULL_TREE, V4SF_type_node,
@@ -3781,6 +3802,11 @@ altivec_init_builtins (void)
= build_function_type (V4SF_type_node,
tree_cons (NULL_TREE, pfloat_type_node, endlink));
+ /* V8HI foo (V16QI). */
+ tree v8hi_ftype_v16qi
+ = build_function_type (V8HI_type_node,
+ tree_cons (NULL_TREE, V16QI_type_node, endlink));
+
/* void foo (int *, V4SI). */
tree void_ftype_pint_v4si
= build_function_type (void_type_node,
@@ -3978,6 +4004,10 @@ altivec_init_builtins (void)
tree_cons (NULL_TREE, V4SI_type_node,
endlink)));
+ tree v4si_ftype_v8hi
+ = build_function_type (V4SI_type_node,
+ tree_cons (NULL_TREE, V8HI_type_node, endlink));
+
tree int_ftype_v4si_v4si
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, V4SI_type_node,
@@ -4239,6 +4269,10 @@ altivec_init_builtins (void)
type = v16qi_ftype_char;
else if (mode0 == V4SFmode && mode1 == V4SFmode)
type = v4sf_ftype_v4sf;
+ else if (mode0 == V8HImode && mode1 == V16QImode)
+ type = v8hi_ftype_v16qi;
+ else if (mode0 == V4SImode && mode1 == V8HImode)
+ type = v4si_ftype_v8hi;
else
abort ();
@@ -5525,7 +5559,7 @@ print_operand (file, x, code)
/* If X is a constant integer whose low-order 5 bits are zero,
write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
in the AIX assembler where "sri" with a zero shift count
- write a trash instruction. */
+ writes a trash instruction. */
if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
putc ('l', file);
else
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 0ed3b2b..840613a 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2954,5 +2954,11 @@ enum rs6000_builtins
ALTIVEC_BUILTIN_VSLDOI_16QI,
ALTIVEC_BUILTIN_VSLDOI_8HI,
ALTIVEC_BUILTIN_VSLDOI_4SI,
- ALTIVEC_BUILTIN_VSLDOI_4SF
+ ALTIVEC_BUILTIN_VSLDOI_4SF,
+ ALTIVEC_BUILTIN_VUPKHSB,
+ ALTIVEC_BUILTIN_VUPKHPX,
+ ALTIVEC_BUILTIN_VUPKHSH,
+ ALTIVEC_BUILTIN_VUPKLSB,
+ ALTIVEC_BUILTIN_VUPKLPX,
+ ALTIVEC_BUILTIN_VUPKLSH
};
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index bf41db8..79c52c2 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -15230,3 +15230,45 @@
"TARGET_ALTIVEC"
"vsldoi %0, %1, %2, %3"
[(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupkhsb"
+ [(set (match_operand:V8HI 0 "register_operand" "=v")
+ (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 167))]
+ "TARGET_ALTIVEC"
+ "vupkhsb %0, %1"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupkhpx"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 168))]
+ "TARGET_ALTIVEC"
+ "vupkhpx %0, %1"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupkhsh"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 169))]
+ "TARGET_ALTIVEC"
+ "vupkhsh %0, %1"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupklsb"
+ [(set (match_operand:V8HI 0 "register_operand" "=v")
+ (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 170))]
+ "TARGET_ALTIVEC"
+ "vupklsb %0, %1"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupklpx"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 171))]
+ "TARGET_ALTIVEC"
+ "vupklpx %0, %1"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vupklsh"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 172))]
+ "TARGET_ALTIVEC"
+ "vupklsh %0, %1"
+ [(set_attr "type" "vecperm")])