diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d5f725b4b5eab9d70192bd43296015d2e24fab0b..d6a9c4da70dd8f61b048955b9f7e608fac9c5731 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-11-01 David S. Miller <davem@davemloft.net> + + * config/sparc/sparc.c (sparc_expand_vcond): New function. + * config/sparc/sparc-protos.h (sparc_expand_vcond): Declare it. + * config/sparc/sparc.md (vcond<mode><mode>): New VIS3 expander. + (vconduv8qiv8qi): Likewise. + 2011-11-01 Alexandre Oliva <aoliva@redhat.com> PR debug/50869 diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 108e105cbeacbc3019e426f788e38d4e75f86530..b9a094e160a5b7e694b5da4058325989120c5c18 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -108,6 +108,7 @@ extern const char *output_v8plus_mult (rtx, rtx *, const char *); extern void sparc_expand_vector_init (rtx, rtx); extern void sparc_expand_vec_perm_bmask(enum machine_mode, rtx); extern bool sparc_expand_conditional_move (enum machine_mode, rtx *); +extern void sparc_expand_vcond (enum machine_mode, rtx *, int, int); #endif /* RTX_CODE */ #endif /* __SPARC_PROTOS_H__ */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index fd1b190d05dbaaef4360487559d3e161d85689e0..6431405b87fdf8a4ee6a280239de5ef6fb1ff670 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -11531,4 +11531,41 @@ sparc_expand_conditional_move (enum machine_mode mode, rtx *operands) return true; } +void +sparc_expand_vcond (enum machine_mode mode, rtx *operands, int ccode, int fcode) +{ + rtx mask, cop0, cop1, fcmp, cmask, bshuf, gsr; + enum rtx_code code = GET_CODE (operands[3]); + + mask = gen_reg_rtx (Pmode); + cop0 = operands[4]; + cop1 = operands[5]; + if (code == LT || code == GE) + { + rtx t; + + code = swap_condition (code); + t = cop0; cop0 = cop1; cop1 = t; + } + + gsr = gen_rtx_REG (DImode, SPARC_GSR_REG); + + fcmp = gen_rtx_UNSPEC (Pmode, + gen_rtvec (1, gen_rtx_fmt_ee (code, mode, cop0, cop1)), + fcode); + + cmask = gen_rtx_UNSPEC (DImode, + gen_rtvec (2, mask, gsr), + ccode); + + bshuf = gen_rtx_UNSPEC (mode, + gen_rtvec (3, operands[1], operands[2], gsr), + UNSPEC_BSHUFFLE); + + emit_insn (gen_rtx_SET (VOIDmode, mask, fcmp)); + emit_insn (gen_rtx_SET (VOIDmode, gsr, cmask)); + + emit_insn (gen_rtx_SET (VOIDmode, operands[0], bshuf)); +} + #include "gt-sparc.h" diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index fbd1a8719217bea0c29f54acd170a28331d734c0..592440389e5fc914ce1b9d4770187e25b7dca04f 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -8299,6 +8299,36 @@ [(set_attr "type" "fpmul") (set_attr "fptype" "double")]) +(define_expand "vcond<mode><mode>" + [(match_operand:GCM 0 "register_operand" "") + (match_operand:GCM 1 "register_operand" "") + (match_operand:GCM 2 "register_operand" "") + (match_operator 3 "" + [(match_operand:GCM 4 "register_operand" "") + (match_operand:GCM 5 "register_operand" "")])] + "TARGET_VIS3" +{ + sparc_expand_vcond (<MODE>mode, operands, + UNSPEC_CMASK<gcm_name>, + UNSPEC_FCMP); + DONE; +}) + +(define_expand "vconduv8qiv8qi" + [(match_operand:V8QI 0 "register_operand" "") + (match_operand:V8QI 1 "register_operand" "") + (match_operand:V8QI 2 "register_operand" "") + (match_operator 3 "" + [(match_operand:V8QI 4 "register_operand" "") + (match_operand:V8QI 5 "register_operand" "")])] + "TARGET_VIS3" +{ + sparc_expand_vcond (V8QImode, operands, + UNSPEC_CMASK8, + UNSPEC_FUCMP); + DONE; +}) + (define_insn "array8<P:mode>_vis" [(set (match_operand:P 0 "register_operand" "=r") (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")