Index: gcc/config/rs6000/altivec.md =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/rs6000/altivec.md,v retrieving revision 1.22 diff -Idpatel.pbxuser -c -3 -p -r1.22 altivec.md *** gcc/config/rs6000/altivec.md 18 Aug 2004 16:33:02 -0000 1.22 --- gcc/config/rs6000/altivec.md 15 Sep 2004 21:22:37 -0000 *************** *** 23,28 **** --- 23,49 ---- [(UNSPEC_VSPLTISW 141) (UNSPEC_VSPLTISH 140) (UNSPEC_VSPLTISB 139) + (UNSPEC_VCMPBFP 50) + (UNSPEC_VCMPEQUB 51) + (UNSPEC_VCMPEQUH 52) + (UNSPEC_VCMPEQUW 53) + (UNSPEC_VCMPEQFP 54) + (UNSPEC_VCMPGEFP 55) + (UNSPEC_VCMPGTUB 56) + (UNSPEC_VCMPGTSB 57) + (UNSPEC_VCMPGTUH 58) + (UNSPEC_VCMPGTSH 59) + (UNSPEC_VCMPGTUW 60) + (UNSPEC_VCMPGTSW 61) + (UNSPEC_VCMPGTFP 62) + (UNSPEC_VSEL4SI 159) + (UNSPEC_VSEL4SF 160) + (UNSPEC_VSEL8HI 161) + (UNSPEC_VSEL16QI 162) + (UNSPEC_VCOND_V4SI 301) + (UNSPEC_VCOND_V4SF 302) + (UNSPEC_VCOND_V8HI 303) + (UNSPEC_VCOND_V16QI 304) ]) ;; Generic LVX load instruction. *************** *** 496,502 **** (define_insn "altivec_vcmpbfp" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") ! (match_operand:V4SF 2 "register_operand" "v")] 50))] "TARGET_ALTIVEC" "vcmpbfp %0,%1,%2" [(set_attr "type" "veccmp")]) --- 517,524 ---- (define_insn "altivec_vcmpbfp" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") ! (match_operand:V4SF 2 "register_operand" "v")] ! UNSPEC_VCMPBFP))] "TARGET_ALTIVEC" "vcmpbfp %0,%1,%2" [(set_attr "type" "veccmp")]) *************** *** 504,510 **** (define_insn "altivec_vcmpequb" [(set (match_operand:V16QI 0 "register_operand" "=v") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") ! (match_operand:V16QI 2 "register_operand" "v")] 51))] "TARGET_ALTIVEC" "vcmpequb %0,%1,%2" [(set_attr "type" "vecsimple")]) --- 526,533 ---- (define_insn "altivec_vcmpequb" [(set (match_operand:V16QI 0 "register_operand" "=v") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") ! (match_operand:V16QI 2 "register_operand" "v")] ! UNSPEC_VCMPEQUB))] "TARGET_ALTIVEC" "vcmpequb %0,%1,%2" [(set_attr "type" "vecsimple")]) *************** *** 512,518 **** (define_insn "altivec_vcmpequh" [(set (match_operand:V8HI 0 "register_operand" "=v") (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") ! (match_operand:V8HI 2 "register_operand" "v")] 52))] "TARGET_ALTIVEC" "vcmpequh %0,%1,%2" [(set_attr "type" "vecsimple")]) --- 535,542 ---- (define_insn "altivec_vcmpequh" [(set (match_operand:V8HI 0 "register_operand" "=v") (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") ! (match_operand:V8HI 2 "register_operand" "v")] ! UNSPEC_VCMPEQUH))] "TARGET_ALTIVEC" "vcmpequh %0,%1,%2" [(set_attr "type" "vecsimple")]) *************** *** 520,526 **** (define_insn "altivec_vcmpequw" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") ! (match_operand:V4SI 2 "register_operand" "v")] 53))] "TARGET_ALTIVEC" "vcmpequw %0,%1,%2" [(set_attr "type" "vecsimple")]) --- 544,551 ---- (define_insn "altivec_vcmpequw" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") ! (match_operand:V4SI 2 "register_operand" "v")] ! UNSPEC_VCMPEQUW))] "TARGET_ALTIVEC" "vcmpequw %0,%1,%2" [(set_attr "type" "vecsimple")]) *************** *** 528,534 **** (define_insn "altivec_vcmpeqfp" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") ! (match_operand:V4SF 2 "register_operand" "v")] 54))] "TARGET_ALTIVEC" "vcmpeqfp %0,%1,%2" [(set_attr "type" "veccmp")]) --- 553,560 ---- (define_insn "altivec_vcmpeqfp" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") ! (match_operand:V4SF 2 "register_operand" "v")] ! UNSPEC_VCMPEQFP))] "TARGET_ALTIVEC" "vcmpeqfp %0,%1,%2" [(set_attr "type" "veccmp")]) *************** *** 536,542 **** (define_insn "altivec_vcmpgefp" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") ! (match_operand:V4SF 2 "register_operand" "v")] 55))] "TARGET_ALTIVEC" "vcmpgefp %0,%1,%2" [(set_attr "type" "veccmp")]) --- 562,569 ---- (define_insn "altivec_vcmpgefp" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") ! (match_operand:V4SF 2 "register_operand" "v")] ! UNSPEC_VCMPGEFP))] "TARGET_ALTIVEC" "vcmpgefp %0,%1,%2" [(set_attr "type" "veccmp")]) *************** *** 544,550 **** (define_insn "altivec_vcmpgtub" [(set (match_operand:V16QI 0 "register_operand" "=v") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") ! (match_operand:V16QI 2 "register_operand" "v")] 56))] "TARGET_ALTIVEC" "vcmpgtub %0,%1,%2" [(set_attr "type" "vecsimple")]) --- 571,578 ---- (define_insn "altivec_vcmpgtub" [(set (match_operand:V16QI 0 "register_operand" "=v") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") ! (match_operand:V16QI 2 "register_operand" "v")] ! UNSPEC_VCMPGTUB))] "TARGET_ALTIVEC" "vcmpgtub %0,%1,%2" [(set_attr "type" "vecsimple")]) *************** *** 552,558 **** (define_insn "altivec_vcmpgtsb" [(set (match_operand:V16QI 0 "register_operand" "=v") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") ! (match_operand:V16QI 2 "register_operand" "v")] 57))] "TARGET_ALTIVEC" "vcmpgtsb %0,%1,%2" [(set_attr "type" "vecsimple")]) --- 580,587 ---- (define_insn "altivec_vcmpgtsb" [(set (match_operand:V16QI 0 "register_operand" "=v") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") ! (match_operand:V16QI 2 "register_operand" "v")] ! UNSPEC_VCMPGTSB))] "TARGET_ALTIVEC" "vcmpgtsb %0,%1,%2" [(set_attr "type" "vecsimple")]) *************** *** 560,566 **** (define_insn "altivec_vcmpgtuh" [(set (match_operand:V8HI 0 "register_operand" "=v") (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") ! (match_operand:V8HI 2 "register_operand" "v")] 58))] "TARGET_ALTIVEC" "vcmpgtuh %0,%1,%2" [(set_attr "type" "vecsimple")]) --- 589,596 ---- (define_insn "altivec_vcmpgtuh" [(set (match_operand:V8HI 0 "register_operand" "=v") (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") ! (match_operand:V8HI 2 "register_operand" "v")] ! UNSPEC_VCMPGTUH))] "TARGET_ALTIVEC" "vcmpgtuh %0,%1,%2" [(set_attr "type" "vecsimple")]) *************** *** 568,574 **** (define_insn "altivec_vcmpgtsh" [(set (match_operand:V8HI 0 "register_operand" "=v") (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") ! (match_operand:V8HI 2 "register_operand" "v")] 59))] "TARGET_ALTIVEC" "vcmpgtsh %0,%1,%2" [(set_attr "type" "vecsimple")]) --- 598,605 ---- (define_insn "altivec_vcmpgtsh" [(set (match_operand:V8HI 0 "register_operand" "=v") (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") ! (match_operand:V8HI 2 "register_operand" "v")] ! UNSPEC_VCMPGTSH))] "TARGET_ALTIVEC" "vcmpgtsh %0,%1,%2" [(set_attr "type" "vecsimple")]) *************** *** 576,582 **** (define_insn "altivec_vcmpgtuw" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") ! (match_operand:V4SI 2 "register_operand" "v")] 60))] "TARGET_ALTIVEC" "vcmpgtuw %0,%1,%2" [(set_attr "type" "vecsimple")]) --- 607,614 ---- (define_insn "altivec_vcmpgtuw" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") ! (match_operand:V4SI 2 "register_operand" "v")] ! UNSPEC_VCMPGTUW))] "TARGET_ALTIVEC" "vcmpgtuw %0,%1,%2" [(set_attr "type" "vecsimple")]) *************** *** 584,590 **** (define_insn "altivec_vcmpgtsw" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") ! (match_operand:V4SI 2 "register_operand" "v")] 61))] "TARGET_ALTIVEC" "vcmpgtsw %0,%1,%2" [(set_attr "type" "vecsimple")]) --- 616,623 ---- (define_insn "altivec_vcmpgtsw" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") ! (match_operand:V4SI 2 "register_operand" "v")] ! UNSPEC_VCMPGTSW))] "TARGET_ALTIVEC" "vcmpgtsw %0,%1,%2" [(set_attr "type" "vecsimple")]) *************** *** 592,598 **** (define_insn "altivec_vcmpgtfp" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") ! (match_operand:V4SF 2 "register_operand" "v")] 62))] "TARGET_ALTIVEC" "vcmpgtfp %0,%1,%2" [(set_attr "type" "veccmp")]) --- 625,632 ---- (define_insn "altivec_vcmpgtfp" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") ! (match_operand:V4SF 2 "register_operand" "v")] ! UNSPEC_VCMPGTFP))] "TARGET_ALTIVEC" "vcmpgtfp %0,%1,%2" [(set_attr "type" "veccmp")]) *************** *** 1640,1650 **** "vrefp %0,%1" [(set_attr "type" "vecfloat")]) (define_insn "altivec_vsel_4si" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") (match_operand:V4SI 2 "register_operand" "v") ! (match_operand:V4SI 3 "register_operand" "v")] 159))] "TARGET_ALTIVEC" "vsel %0,%1,%2,%3" [(set_attr "type" "vecperm")]) --- 1674,1753 ---- "vrefp %0,%1" [(set_attr "type" "vecfloat")]) + (define_expand "vcondv4si" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "comparison_operator" "") + (match_operand:V4SI 2 "register_operand" "v") + (match_operand:V4SI 3 "register_operand" "v") + (match_operand:SI 4 "" "")] UNSPEC_VCOND_V4SI))] + "TARGET_ALTIVEC" + " + { + if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], + operands[3], operands[4])) + DONE; + else + FAIL; + } + ") + + (define_expand "vcondv4sf" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SI 1 "comparison_operator" "") + (match_operand:V4SF 2 "register_operand" "v") + (match_operand:V4SF 3 "register_operand" "v") + (match_operand:SI 4 "" "")] UNSPEC_VCOND_V4SF))] + "TARGET_ALTIVEC" + " + { + if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], + operands[3], operands[4])) + DONE; + else + FAIL; + } + ") + + (define_expand "vcondv8hi" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V4SI 1 "comparison_operator" "") + (match_operand:V8HI 2 "register_operand" "v") + (match_operand:V8HI 3 "register_operand" "v") + (match_operand:SI 4 "" "")] UNSPEC_VCOND_V8HI))] + "TARGET_ALTIVEC" + " + { + if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], + operands[3], operands[4])) + DONE; + else + FAIL; + } + ") + + (define_expand "vcondv16qi" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V4SI 1 "comparison_operator" "") + (match_operand:V16QI 2 "register_operand" "v") + (match_operand:V16QI 3 "register_operand" "v") + (match_operand:SI 4 "" "")] UNSPEC_VCOND_V16QI))] + "TARGET_ALTIVEC" + " + { + if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], + operands[3], operands[4])) + DONE; + else + FAIL; + } + ") + (define_insn "altivec_vsel_4si" [(set (match_operand:V4SI 0 "register_operand" "=v") (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") (match_operand:V4SI 2 "register_operand" "v") ! (match_operand:V4SI 3 "register_operand" "v")] ! UNSPEC_VSEL4SI))] "TARGET_ALTIVEC" "vsel %0,%1,%2,%3" [(set_attr "type" "vecperm")]) *************** *** 1653,1659 **** [(set (match_operand:V4SF 0 "register_operand" "=v") (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") (match_operand:V4SF 2 "register_operand" "v") ! (match_operand:V4SI 3 "register_operand" "v")] 160))] "TARGET_ALTIVEC" "vsel %0,%1,%2,%3" [(set_attr "type" "vecperm")]) --- 1756,1763 ---- [(set (match_operand:V4SF 0 "register_operand" "=v") (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") (match_operand:V4SF 2 "register_operand" "v") ! (match_operand:V4SI 3 "register_operand" "v")] ! UNSPEC_VSEL4SF))] "TARGET_ALTIVEC" "vsel %0,%1,%2,%3" [(set_attr "type" "vecperm")]) *************** *** 1662,1668 **** [(set (match_operand:V8HI 0 "register_operand" "=v") (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") (match_operand:V8HI 2 "register_operand" "v") ! (match_operand:V8HI 3 "register_operand" "v")] 161))] "TARGET_ALTIVEC" "vsel %0,%1,%2,%3" [(set_attr "type" "vecperm")]) --- 1766,1773 ---- [(set (match_operand:V8HI 0 "register_operand" "=v") (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") (match_operand:V8HI 2 "register_operand" "v") ! (match_operand:V8HI 3 "register_operand" "v")] ! UNSPEC_VSEL8HI))] "TARGET_ALTIVEC" "vsel %0,%1,%2,%3" [(set_attr "type" "vecperm")]) *************** *** 1671,1677 **** [(set (match_operand:V16QI 0 "register_operand" "=v") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") (match_operand:V16QI 2 "register_operand" "v") ! (match_operand:V16QI 3 "register_operand" "v")] 162))] "TARGET_ALTIVEC" "vsel %0,%1,%2,%3" [(set_attr "type" "vecperm")]) --- 1776,1783 ---- [(set (match_operand:V16QI 0 "register_operand" "=v") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") (match_operand:V16QI 2 "register_operand" "v") ! (match_operand:V16QI 3 "register_operand" "v")] ! UNSPEC_VSEL16QI))] "TARGET_ALTIVEC" "vsel %0,%1,%2,%3" [(set_attr "type" "vecperm")]) Index: gcc/config/rs6000/rs6000-protos.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v retrieving revision 1.88 diff -Idpatel.pbxuser -c -3 -p -r1.88 rs6000-protos.h *** gcc/config/rs6000/rs6000-protos.h 21 Aug 2004 01:39:58 -0000 1.88 --- gcc/config/rs6000/rs6000-protos.h 15 Sep 2004 21:22:37 -0000 *************** extern char * output_cbranch (rtx, const *** 124,129 **** --- 124,130 ---- extern char * output_e500_flip_eq_bit (rtx, rtx); extern rtx rs6000_emit_set_const (rtx, enum machine_mode, rtx, int); extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx); + extern int rs6000_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx); extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx); extern void output_toc (FILE *, rtx, int, enum machine_mode); extern void rs6000_initialize_trampoline (rtx, rtx, rtx); Index: gcc/config/rs6000/rs6000.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v retrieving revision 1.709 diff -Idpatel.pbxuser -c -3 -p -r1.709 rs6000.c *** gcc/config/rs6000/rs6000.c 14 Sep 2004 04:05:38 -0000 1.709 --- gcc/config/rs6000/rs6000.c 15 Sep 2004 21:22:38 -0000 *************** static tree rs6000_build_builtin_va_list *** 754,760 **** --- 754,766 ---- static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *); static bool rs6000_must_pass_in_stack (enum machine_mode, tree); static bool rs6000_vector_mode_supported_p (enum machine_mode); + static int get_vec_cmp_insn (enum rtx_code, enum machine_mode, enum machine_mode); + static rtx rs6000_emit_vector_compare (rtx, int, enum machine_mode); + static int get_vsel_insn (enum machine_mode); + static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx, int); + + const int INSN_NOT_AVAILABLE = -1; static enum machine_mode rs6000_eh_return_filter_mode (void); /* Hash table stuff for keeping track of TOC entries. */ *************** output_e500_flip_eq_bit (rtx dst, rtx sr *** 11079,11084 **** --- 11085,11259 ---- return string; } + /* Return insn index for the vector compare instruction for given CODE, + and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is + not available. */ + + static int + get_vec_cmp_insn (enum rtx_code code, + enum machine_mode dest_mode, + enum machine_mode op_mode) + { + if (!TARGET_ALTIVEC) + return INSN_NOT_AVAILABLE; + + switch (code) + { + case EQ: + if (dest_mode == V16QImode && op_mode == V16QImode) + return UNSPEC_VCMPEQUB; + if (dest_mode == V8HImode && op_mode == V8HImode) + return UNSPEC_VCMPEQUH; + if (dest_mode == V4SImode && op_mode == V4SImode) + return UNSPEC_VCMPEQUW; + if (dest_mode == V4SImode && op_mode == V4SFmode) + return UNSPEC_VCMPEQFP; + break; + case GE: + if (dest_mode == V4SImode && op_mode == V4SFmode) + return UNSPEC_VCMPGEFP; + case GT: + if (dest_mode == V16QImode && op_mode == V16QImode) + return UNSPEC_VCMPGTSB; + if (dest_mode == V8HImode && op_mode == V8HImode) + return UNSPEC_VCMPGTSH; + if (dest_mode == V4SImode && op_mode == V4SImode) + return UNSPEC_VCMPGTSW; + if (dest_mode == V4SImode && op_mode == V4SFmode) + return UNSPEC_VCMPGTFP; + break; + case GTU: + if (dest_mode == V16QImode && op_mode == V16QImode) + return UNSPEC_VCMPGTUB; + if (dest_mode == V8HImode && op_mode == V8HImode) + return UNSPEC_VCMPGTUH; + if (dest_mode == V4SImode && op_mode == V4SImode) + return UNSPEC_VCMPGTUW; + break; + default: + break; + } + return INSN_NOT_AVAILABLE; + } + + /* Emit vector compare using VEC_CMP_INSN and DEST_MODE. */ + + static rtx + rs6000_emit_vector_compare (rtx cond, int vec_cmp_insn, + enum machine_mode dest_mode) + { + + rtx mask = gen_reg_rtx (dest_mode); + rtx op0 = XEXP (cond, 0); + rtx op1 = XEXP (cond, 1); + + #ifdef ENABLE_CHECKING + if (GET_MODE (op0) != GET_MODE (op1)) + abort (); + #endif + + emit_insn (gen_rtx_fmt_ee (SET, + VOIDmode, + mask, + gen_rtx_fmt_Ei (UNSPEC, dest_mode, + gen_rtvec (2, op0, op1), + vec_cmp_insn))); + return mask; + } + + /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if + valid insn doesn exist for given mode. */ + + static int + get_vsel_insn (enum machine_mode mode) + { + switch (mode) + { + case V4SImode: + return UNSPEC_VSEL4SI; + break; + case V4SFmode: + return UNSPEC_VSEL4SF; + break; + case V8HImode: + return UNSPEC_VSEL8HI; + break; + case V16QImode: + return UNSPEC_VSEL16QI; + break; + default: + return INSN_NOT_AVAILABLE; + break; + } + return INSN_NOT_AVAILABLE; + } + + /* Emit vector select insn where DEST is destination using + operands OP1, OP2 and MASK. Use VSEL_INSN_INDEX as insn index. */ + + static void + rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask, + int vsel_insn_index) + { + rtx t, temp; + enum machine_mode mode, dest_mode; + + mode = GET_MODE (dest); + if (mode == V4SImode || mode == V4SFmode) + dest_mode = V4SImode; + else + dest_mode = mode; + + temp = gen_reg_rtx (dest_mode); + + t = gen_rtx_fmt_ee (SET, VOIDmode, temp, + gen_rtx_fmt_Ei (UNSPEC, dest_mode, + gen_rtvec (3, op1, op2, mask), + vsel_insn_index)); + emit_insn (t); + emit_move_insn (dest, temp); + return; + } + + /* Emit vector conditional expression. + DEST is destination. COND is condition and OP1 and OP2 are two operands. + CHECK decides if insn is to be emitted or not. */ + + int + rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2, rtx cond, rtx check) + { + enum machine_mode op_mode = GET_MODE (op1); /* does it matter which op is used? */ + enum machine_mode dest_mode = GET_MODE (dest); + rtx mask; + enum rtx_code rcode = GET_CODE (cond); + int vec_cmp_insn, vec_sel_insn; + + if (!TARGET_ALTIVEC) + return 0; + + vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode); + if (vec_cmp_insn == INSN_NOT_AVAILABLE) + { + if (check == const1_rtx) + return 0; + else + abort (); + } + vec_sel_insn = get_vsel_insn (GET_MODE (dest)); + if (vec_sel_insn == INSN_NOT_AVAILABLE) + { + if (check == const1_rtx) + return 0; + else + abort (); + } + + mask = rs6000_emit_vector_compare (cond, vec_cmp_insn, dest_mode); + rs6000_emit_vector_select (dest, op1, op2, mask, vec_sel_insn); + + return 1; + } + /* Emit a conditional move: move TRUE_COND to DEST if OP of the operands of the last comparison is nonzero/true, FALSE_COND if it is zero/false. Return 0 if the hardware has no such operation. */