I really wanted to make this work using the define_expand rtl to generate the pattern, but I ran into two problems:
1) In addition to mode "GCM", we also need to iterate over "P" mode for the sake of the rtl of fpcmp and cmask. So we'd get dups in the insn output files. 2) I couldn't substitute the mode attribute "<gcm_name>" into the cmask unspec code. ie. UNSPEC_CMASK<gcm_name> didn't work. Anyways, at least there is one expander function shared between the signed and unsigned cases. Committed to trunk. gcc/ * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180733 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/config/sparc/sparc-protos.h | 1 + gcc/config/sparc/sparc.c | 37 +++++++++++++++++++++++++++++++++++++ gcc/config/sparc/sparc.md | 30 ++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 0 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d5f725b..d6a9c4d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-11-01 David S. Miller <da...@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 <aol...@redhat.com> PR debug/50869 diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 108e105..b9a094e 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 fd1b190..6431405 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 fbd1a87..5924403 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") -- 1.7.6.401.g6a319