From: Aldy Hernandez Date: Thu, 10 Jan 2002 02:51:02 +0000 (+0000) Subject: rs6000.c (altivec_expand_builtin): Add support for mtvscr, dssall, mfvscr, dss, lvsl... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=95385cbb585d1e4b094a354dae4856373be887c2;p=gcc.git rs6000.c (altivec_expand_builtin): Add support for mtvscr, dssall, mfvscr, dss, lvsl, lvsr, dstt, dst, dstst, dststt. * config/rs6000/rs6000.c (altivec_expand_builtin): Add support for mtvscr, dssall, mfvscr, dss, lvsl, lvsr, dstt, dst, dstst, dststt. (altivec_init_builtins): Same. (altivec_expand_unop_builtin): Return NULL_RTX on error. (altivec_expand_binop_builtin): Same. (altivec_expand_ternop_builtin): Same. (bdesc_dst): New. * config/rs6000/rs6000.md ("altivec_mtvscr"): New. ("altivec_vctuxs"): Fix typo. ("altivec_vnmsubfp"): Same. ("altivec_dssall"): New. ("altivec_mfvscr"): New. ("altivec_dss"): New. ("altivec_lvsl"): New. ("altivec_lvsr"): New. ("altivec_dstt"): New. ("altivec_dstst"): New. ("altivec_dststt"): New. ("altivec_dst"): New. * config/rs6000/rs6000.h (rs6000_builtins): Add mtvscr, dssall, mfvscr, dss, lvsl, lvsr, dstt, dstst, dststt, dst. From-SVN: r48708 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8909c4a58d5..c30acc70ca5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2002-01-08 Aldy Hernandez + + * testuite/gcc.dg/altivec-4.c: Add test for mtvscr, dssall, + mfvscr, dss, lvsl, lvsr, dstt, dstst, dststt, dst. + + * config/rs6000/rs6000.c (altivec_expand_builtin): Add support for + mtvscr, dssall, mfvscr, dss, lvsl, lvsr, dstt, dst, dstst, dststt. + (altivec_init_builtins): Same. + (altivec_expand_unop_builtin): Return NULL_RTX on error. + (altivec_expand_binop_builtin): Same. + (altivec_expand_ternop_builtin): Same. + (bdesc_dst): New. + + * config/rs6000/rs6000.md ("altivec_mtvscr"): New. + ("altivec_vctuxs"): Fix typo. + ("altivec_vnmsubfp"): Same. + ("altivec_dssall"): New. + ("altivec_mfvscr"): New. + ("altivec_dss"): New. + ("altivec_lvsl"): New. + ("altivec_lvsr"): New. + ("altivec_dstt"): New. + ("altivec_dstst"): New. + ("altivec_dststt"): New. + ("altivec_dst"): New. + + * config/rs6000/rs6000.h (rs6000_builtins): Add mtvscr, dssall, + mfvscr, dss, lvsl, lvsr, dstt, dstst, dststt, dst. + 2002-01-09 Richard Henderson * config/alpha/alpha.md (prologue_mcount): Remove lituse_jsr reloc. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6466bb2c4f1..b8b0453bfb2 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1,6 +1,6 @@ /* Subroutines used for code generation on IBM RS/6000. Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001 Free Software Foundation, Inc. + 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GNU CC. @@ -3240,6 +3240,16 @@ static const struct builtin_description bdesc_3arg[] = { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF }, }; +/* DST operations: void foo (void *, const int, const char). */ + +static const struct builtin_description bdesc_dst[] = +{ + { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST }, + { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT }, + { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST }, + { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT } +}; + /* Simple binary operations: VECc = foo (VECa, VECb). */ static const struct builtin_description bdesc_2arg[] = @@ -3410,7 +3420,7 @@ altivec_expand_unop_builtin (icode, arglist, target) /* If we got invalid arguments bail out before generating bad rtl. */ if (arg0 == error_mark_node) - return target; + return NULL_RTX; if (target == 0 || GET_MODE (target) != tmode @@ -3444,7 +3454,7 @@ altivec_expand_binop_builtin (icode, arglist, target) /* If we got invalid arguments bail out before generating bad rtl. */ if (arg0 == error_mark_node || arg1 == error_mark_node) - return target; + return NULL_RTX; if (target == 0 || GET_MODE (target) != tmode @@ -3485,7 +3495,7 @@ altivec_expand_ternop_builtin (icode, arglist, target) if (arg0 == error_mark_node || arg1 == error_mark_node || arg2 == error_mark_node) - return target; + return NULL_RTX; if (target == 0 || GET_MODE (target) != tmode @@ -3516,9 +3526,9 @@ altivec_expand_builtin (exp, target) enum insn_code icode; tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); tree arglist = TREE_OPERAND (exp, 1); - tree arg0, arg1; - rtx op0, op1, pat; - enum machine_mode tmode, mode0, mode1; + tree arg0, arg1, arg2; + rtx op0, op1, op2, pat; + enum machine_mode tmode, mode0, mode1, mode2; unsigned int fcode = DECL_FUNCTION_CODE (fndecl); switch (fcode) @@ -3622,9 +3632,8 @@ altivec_expand_builtin (exp, target) op1 = copy_to_mode_reg (mode1, op1); pat = GEN_FCN (icode) (op0, op1); - if (! pat) - return 0; - emit_insn (pat); + if (pat) + emit_insn (pat); return NULL_RTX; case ALTIVEC_BUILTIN_ST_INTERNAL_8hi: @@ -3642,9 +3651,8 @@ altivec_expand_builtin (exp, target) op1 = copy_to_mode_reg (mode1, op1); pat = GEN_FCN (icode) (op0, op1); - if (! pat) - return 0; - emit_insn (pat); + if (pat) + emit_insn (pat); return NULL_RTX; case ALTIVEC_BUILTIN_ST_INTERNAL_4si: @@ -3662,9 +3670,8 @@ altivec_expand_builtin (exp, target) op1 = copy_to_mode_reg (mode1, op1); pat = GEN_FCN (icode) (op0, op1); - if (! pat) - return 0; - emit_insn (pat); + if (pat) + emit_insn (pat); return NULL_RTX; case ALTIVEC_BUILTIN_ST_INTERNAL_4sf: @@ -3682,12 +3689,103 @@ altivec_expand_builtin (exp, target) op1 = copy_to_mode_reg (mode1, op1); pat = GEN_FCN (icode) (op0, op1); + if (pat) + emit_insn (pat); + return NULL_RTX; + + case ALTIVEC_BUILTIN_MFVSCR: + icode = CODE_FOR_altivec_mfvscr; + tmode = insn_data[icode].operand[0].mode; + + if (target == 0 + || GET_MODE (target) != tmode + || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) + target = gen_reg_rtx (tmode); + + pat = GEN_FCN (icode) (target); if (! pat) return 0; emit_insn (pat); + return target; + + case ALTIVEC_BUILTIN_MTVSCR: + icode = CODE_FOR_altivec_mtvscr; + arg0 = TREE_VALUE (arglist); + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); + mode0 = insn_data[icode].operand[0].mode; + + /* If we got invalid arguments bail out before generating bad rtl. */ + if (arg0 == error_mark_node) + return NULL_RTX; + + if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) + op0 = copy_to_mode_reg (mode0, op0); + + pat = GEN_FCN (icode) (op0); + if (pat) + emit_insn (pat); + return NULL_RTX; + + case ALTIVEC_BUILTIN_DSSALL: + emit_insn (gen_altivec_dssall ()); + return NULL_RTX; + + case ALTIVEC_BUILTIN_DSS: + icode = CODE_FOR_altivec_dss; + arg0 = TREE_VALUE (arglist); + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); + mode0 = insn_data[icode].operand[0].mode; + + /* If we got invalid arguments bail out before generating bad rtl. */ + if (arg0 == error_mark_node) + return NULL_RTX; + + if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) + op0 = copy_to_mode_reg (mode0, op0); + + emit_insn (gen_altivec_dss (op0)); return NULL_RTX; } + /* Handle DST variants. */ + d = (struct builtin_description *) bdesc_dst; + for (i = 0; i < sizeof (bdesc_dst) / sizeof *d; i++, d++) + if (d->code == fcode) + { + arg0 = TREE_VALUE (arglist); + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); + mode0 = insn_data[d->icode].operand[0].mode; + mode1 = insn_data[d->icode].operand[1].mode; + mode2 = insn_data[d->icode].operand[2].mode; + + /* Invalid arguments, bail out before generating bad rtl. */ + if (arg0 == error_mark_node + || arg1 == error_mark_node + || arg2 == error_mark_node) + return NULL_RTX; + + if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0)) + op0 = copy_to_mode_reg (mode0, op0); + if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1)) + op1 = copy_to_mode_reg (mode1, op1); + + if (GET_CODE (op2) != CONST_INT || INTVAL (op2) > 3) + { + error ("argument 3 of `%s' must be a 2-bit literal", d->name); + return NULL_RTX; + } + + pat = GEN_FCN (d->icode) (op0, op1, op2); + if (pat != 0) + emit_insn (pat); + + return NULL_RTX; + } + /* Handle simple unary operations. */ d = (struct builtin_description *) bdesc_1arg; for (i = 0; i < sizeof (bdesc_1arg) / sizeof *d; i++, d++) @@ -3700,6 +3798,14 @@ altivec_expand_builtin (exp, target) if (d->code == fcode) return altivec_expand_binop_builtin (d->icode, arglist, target); + /* LVS* are funky. We initialized them differently. */ + if (fcode == ALTIVEC_BUILTIN_LVSL) + return altivec_expand_binop_builtin (CODE_FOR_altivec_lvsl, + arglist, target); + if (fcode == ALTIVEC_BUILTIN_LVSR) + return altivec_expand_binop_builtin (CODE_FOR_altivec_lvsr, + arglist, target); + /* Handle simple ternary operations. */ d = (struct builtin_description *) bdesc_3arg; for (i = 0; i < sizeof (bdesc_3arg) / sizeof *d; i++, d++) @@ -3746,6 +3852,7 @@ altivec_init_builtins (void) tree endlink = void_list_node; tree pint_type_node = build_pointer_type (integer_type_node); + tree pvoid_type_node = build_pointer_type (void_type_node); 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); @@ -3820,6 +3927,15 @@ altivec_init_builtins (void) = build_function_type (V8HI_type_node, tree_cons (NULL_TREE, V16QI_type_node, endlink)); + /* void foo (void *, int, char/literal). */ + tree void_ftype_pvoid_int_char + = build_function_type (void_type_node, + tree_cons (NULL_TREE, pvoid_type_node, + tree_cons (NULL_TREE, integer_type_node, + tree_cons (NULL_TREE, + char_type_node, + endlink)))); + /* void foo (int *, V4SI). */ tree void_ftype_pint_v4si = build_function_type (void_type_node, @@ -3845,6 +3961,30 @@ altivec_init_builtins (void) tree_cons (NULL_TREE, V4SF_type_node, endlink))); + /* void foo (V4SI). */ + tree void_ftype_v4si + = build_function_type (void_type_node, + tree_cons (NULL_TREE, V4SI_type_node, + endlink)); + + /* void foo (char). */ + tree void_ftype_qi + = build_function_type (void_type_node, + tree_cons (NULL_TREE, char_type_node, + endlink)); + + /* void foo (void). */ + tree void_ftype_void + = build_function_type (void_type_node, + tree_cons (NULL_TREE, void_type_node, + endlink)); + + /* vshort foo (void). */ + tree v8hi_ftype_void + = build_function_type (V8HI_type_node, + tree_cons (NULL_TREE, void_type_node, + endlink)); + tree v4si_ftype_v4si_v4si = build_function_type (V4SI_type_node, tree_cons (NULL_TREE, V4SI_type_node, @@ -4045,6 +4185,12 @@ altivec_init_builtins (void) tree_cons (NULL_TREE, V16QI_type_node, endlink))); + tree v16qi_ftype_int_pvoid + = build_function_type (V16QI_type_node, + tree_cons (NULL_TREE, integer_type_node, + tree_cons (NULL_TREE, pvoid_type_node, + endlink))); + tree int_ftype_v8hi_v8hi = build_function_type (integer_type_node, tree_cons (NULL_TREE, V8HI_type_node, @@ -4059,6 +4205,12 @@ altivec_init_builtins (void) def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi, ALTIVEC_BUILTIN_ST_INTERNAL_8hi); def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pchar, ALTIVEC_BUILTIN_LD_INTERNAL_16qi); def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi, ALTIVEC_BUILTIN_ST_INTERNAL_16qi); + def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR); + def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR); + def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL); + def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS); + def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSL); + def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSR); /* Add the simple ternary operators. */ d = (struct builtin_description *) bdesc_3arg; @@ -4153,6 +4305,11 @@ altivec_init_builtins (void) def_builtin (d->mask, d->name, type, d->code); } + /* Add the DST variants. */ + d = (struct builtin_description *) bdesc_dst; + for (i = 0; i < sizeof (bdesc_dst) / sizeof *d; i++, d++) + def_builtin (d->mask, d->name, void_ftype_pvoid_int_char, d->code); + /* Add the simple binary operators. */ d = (struct builtin_description *) bdesc_2arg; for (i = 0; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 854ab9b6062..36e9e9900b3 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2967,5 +2967,15 @@ enum rs6000_builtins ALTIVEC_BUILTIN_VCMPGTSW_P, ALTIVEC_BUILTIN_VCMPGTUB_P, ALTIVEC_BUILTIN_VCMPGTUH_P, - ALTIVEC_BUILTIN_VCMPGTUW_P + ALTIVEC_BUILTIN_VCMPGTUW_P, + ALTIVEC_BUILTIN_MTVSCR, + ALTIVEC_BUILTIN_MFVSCR, + ALTIVEC_BUILTIN_DSSALL, + ALTIVEC_BUILTIN_DSS, + ALTIVEC_BUILTIN_LVSL, + ALTIVEC_BUILTIN_LVSR, + ALTIVEC_BUILTIN_DSTT, + ALTIVEC_BUILTIN_DSTST, + ALTIVEC_BUILTIN_DSTSTT, + ALTIVEC_BUILTIN_DST }; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 84880eaf11a..364a7e7dc90 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -14268,7 +14268,7 @@ (match_operand:V4SF 2 "register_operand" "v")) (match_operand:V4SF 3 "register_operand" "v")))] "TARGET_ALTIVEC" - "vmmsubfp %0,%1,%2,%3" + "vnmsubfp %0,%1,%2,%3" [(set_attr "type" "vecfloat")]) @@ -15142,7 +15142,7 @@ (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") (match_operand:QI 2 "immediate_operand" "i")] 153))] "TARGET_ALTIVEC" - "vctusx %0, %1, %2" + "vctuxs %0, %1, %2" [(set_attr "type" "vecfloat")]) (define_insn "altivec_vctsxs" @@ -15399,4 +15399,77 @@ (match_operand:V8HI 2 "register_operand" "v")] 185))] "TARGET_ALTIVEC" "vcmpgtsh. %0,%1,%2" -[(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmp")]) + +(define_insn "altivec_mtvscr" + [(unspec [(match_operand:V4SI 0 "register_operand" "v")] 186)] + "TARGET_ALTIVEC" + "mtvscr %0" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_mfvscr" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(const_int 0)] 187))] + "TARGET_ALTIVEC" + "mfvscr %0" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dssall" + [(unspec [(const_int 0)] 188)] + "TARGET_ALTIVEC" + "dssall" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dss" + [(unspec [(match_operand:QI 0 "immediate_operand" "i")] 189)] + "TARGET_ALTIVEC" + "dss %0" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dst" + [(unspec [(match_operand:SI 0 "register_operand" "b") + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "i")] 190)] + "TARGET_ALTIVEC" + "dst %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dstt" + [(unspec [(match_operand:SI 0 "register_operand" "b") + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "i")] 191)] + "TARGET_ALTIVEC" + "dstt %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dstst" + [(unspec [(match_operand:SI 0 "register_operand" "b") + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "i")] 192)] + "TARGET_ALTIVEC" + "dstst %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dststt" + [(unspec [(match_operand:SI 0 "register_operand" "b") + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "i")] 193)] + "TARGET_ALTIVEC" + "dststt %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_lvsl" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")] 194))] + "TARGET_ALTIVEC" + "lvsl %0,%1,%2" + [(set_attr "type" "vecload")]) + +(define_insn "altivec_lvsr" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")] 195))] + "TARGET_ALTIVEC" + "lvsr %0,%1,%2" + [(set_attr "type" "vecload")])