{ 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
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);
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);
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);
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);
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);
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);
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);
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,
= 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,
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,
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 ();
/* 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
"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")])