diff options
author | aldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-06-28 17:32:12 +0000 |
---|---|---|
committer | aldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-06-28 17:32:12 +0000 |
commit | ae1526b250c483e155ba69764a909da26bf072bd (patch) | |
tree | a9ec3ba166e956354de8ba9ebfc35d311b0a2898 /gcc/config/rs6000 | |
parent | 21f3b542078ab025e7ea311655b86416764481ff (diff) | |
download | ppe42-gcc-ae1526b250c483e155ba69764a909da26bf072bd.tar.gz ppe42-gcc-ae1526b250c483e155ba69764a909da26bf072bd.zip |
2002-06-27 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/rs6000.c (altivec_expand_builtin): Move
lvx/stv/dst builtins...
(altivec_expand_ld_builtin): ...to here.
(altivec_expand_st_builtin): ...here.
(altivec_expand_dst_builtin): ...and here (respectively).
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55067 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 359 |
1 files changed, 173 insertions, 186 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index b57d85c1a3d..48c8748b847 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -192,6 +192,9 @@ static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx)); static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int)); static void altivec_init_builtins PARAMS ((void)); static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *)); +static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *)); +static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *)); +static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *)); static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx)); static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx)); static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree)); @@ -3888,189 +3891,213 @@ rs6000_expand_ternop_builtin (icode, arglist, target) return target; } -/* Expand the builtin in EXP and store the result in TARGET. Store - true in *EXPANDEDP if we found a builtin to expand. */ +/* Expand the lvx builtins. */ static rtx -altivec_expand_builtin (exp, target, expandedp) +altivec_expand_ld_builtin (exp, target, expandedp) tree exp; rtx target; bool *expandedp; { - struct builtin_description *d; - struct builtin_description_predicates *dp; - size_t i; - enum insn_code icode; tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); tree arglist = TREE_OPERAND (exp, 1); - tree arg0, arg1, arg2; - rtx op0, op1, op2, pat; - enum machine_mode tmode, mode0, mode1, mode2; unsigned int fcode = DECL_FUNCTION_CODE (fndecl); - - *expandedp = true; + tree arg0; + enum machine_mode tmode, mode0; + rtx pat, target, op0; + enum insn_code icode; switch (fcode) { case ALTIVEC_BUILTIN_LD_INTERNAL_16qi: icode = CODE_FOR_altivec_lvx_16qi; - arg0 = TREE_VALUE (arglist); - op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); - tmode = insn_data[icode].operand[0].mode; - mode0 = insn_data[icode].operand[1].mode; - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - - pat = GEN_FCN (icode) (target, op0); - if (! pat) - return 0; - emit_insn (pat); - return target; - + break; case ALTIVEC_BUILTIN_LD_INTERNAL_8hi: icode = CODE_FOR_altivec_lvx_8hi; - arg0 = TREE_VALUE (arglist); - op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); - tmode = insn_data[icode].operand[0].mode; - mode0 = insn_data[icode].operand[1].mode; + break; + case ALTIVEC_BUILTIN_LD_INTERNAL_4si: + icode = CODE_FOR_altivec_lvx_4si; + break; + case ALTIVEC_BUILTIN_LD_INTERNAL_4sf: + icode = CODE_FOR_altivec_lvx_4sf; + break; + default: + *expandedp = false; + return NULL_RTX; + } - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); + *expandedp = true; - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); + arg0 = TREE_VALUE (arglist); + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); + tmode = insn_data[icode].operand[0].mode; + mode0 = insn_data[icode].operand[1].mode; - pat = GEN_FCN (icode) (target, op0); - if (! pat) - return 0; - emit_insn (pat); - return target; + if (target == 0 + || GET_MODE (target) != tmode + || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) + target = gen_reg_rtx (tmode); - case ALTIVEC_BUILTIN_LD_INTERNAL_4si: - icode = CODE_FOR_altivec_lvx_4si; - arg0 = TREE_VALUE (arglist); - op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); - tmode = insn_data[icode].operand[0].mode; - mode0 = insn_data[icode].operand[1].mode; + if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) + op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - 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, op0); + if (! pat) + return 0; + emit_insn (pat); + return target; +} - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); +/* Expand the stvx builtins. */ +static rtx +altivec_expand_st_builtin (exp, target, expandedp) + tree exp; + rtx target; + bool *expandedp; +{ + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + tree arglist = TREE_OPERAND (exp, 1); + unsigned int fcode = DECL_FUNCTION_CODE (fndecl); + tree arg0, arg1; + enum machine_mode mode0, mode1; + rtx pat, target, op0, op1; + enum insn_code icode; - pat = GEN_FCN (icode) (target, op0); - if (! pat) - return 0; - emit_insn (pat); - return target; + switch (fcode) + { + case ALTIVEC_BUILTIN_ST_INTERNAL_16qi: + icode = CODE_FOR_altivec_stvx_16qi; + break; + case ALTIVEC_BUILTIN_ST_INTERNAL_8hi: + icode = CODE_FOR_altivec_stvx_8hi; + break; + case ALTIVEC_BUILTIN_ST_INTERNAL_4si: + icode = CODE_FOR_altivec_stvx_4si; + break; + case ALTIVEC_BUILTIN_ST_INTERNAL_4sf: + icode = CODE_FOR_altivec_stvx_4sf; + break; + default: + *expandedp = false; + return NULL_RTX; + } - case ALTIVEC_BUILTIN_LD_INTERNAL_4sf: - icode = CODE_FOR_altivec_lvx_4sf; - arg0 = TREE_VALUE (arglist); - op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); - tmode = insn_data[icode].operand[0].mode; - mode0 = insn_data[icode].operand[1].mode; + arg0 = TREE_VALUE (arglist); + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); + mode0 = insn_data[icode].operand[0].mode; + mode1 = insn_data[icode].operand[1].mode; - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); + if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) + op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); + if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) + op1 = copy_to_mode_reg (mode1, op1); - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); + pat = GEN_FCN (icode) (op0, op1); + if (pat) + emit_insn (pat); - pat = GEN_FCN (icode) (target, op0); - if (! pat) - return 0; - emit_insn (pat); - return target; + *expandedp = true; + return NULL_RTX; +} - case ALTIVEC_BUILTIN_ST_INTERNAL_16qi: - icode = CODE_FOR_altivec_stvx_16qi; - arg0 = TREE_VALUE (arglist); - arg1 = TREE_VALUE (TREE_CHAIN (arglist)); - op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); - op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; +/* Expand the dst builtins. */ +static rtx +altivec_expand_dst_builtin (exp, target, expandedp) + tree exp; + rtx target; + bool *expandedp; +{ + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + tree arglist = TREE_OPERAND (exp, 1); + unsigned int fcode = DECL_FUNCTION_CODE (fndecl); + tree arg0, arg1, arg2; + enum machine_mode mode0, mode1, mode2; + rtx pat, target, op0, op1, op2; + struct builtin_description *d; + int i; - if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); + *expandedp = false; - pat = GEN_FCN (icode) (op0, op1); - if (pat) - emit_insn (pat); - return NULL_RTX; + /* Handle DST variants. */ + d = (struct builtin_description *) bdesc_dst; + for (i = 0; i < ARRAY_SIZE (bdesc_dst); 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; - case ALTIVEC_BUILTIN_ST_INTERNAL_8hi: - icode = CODE_FOR_altivec_stvx_8hi; - arg0 = TREE_VALUE (arglist); - arg1 = TREE_VALUE (TREE_CHAIN (arglist)); - op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); - op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; + /* Invalid arguments, bail out before generating bad rtl. */ + if (arg0 == error_mark_node + || arg1 == error_mark_node + || arg2 == error_mark_node) + return const0_rtx; - if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); + if (TREE_CODE (arg2) != INTEGER_CST + || TREE_INT_CST_LOW (arg2) & ~0x3) + { + error ("argument to `%s' must be a 2-bit unsigned literal", d->name); + return const0_rtx; + } - pat = GEN_FCN (icode) (op0, op1); - if (pat) - emit_insn (pat); - 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); - case ALTIVEC_BUILTIN_ST_INTERNAL_4si: - icode = CODE_FOR_altivec_stvx_4si; - arg0 = TREE_VALUE (arglist); - arg1 = TREE_VALUE (TREE_CHAIN (arglist)); - op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); - op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; + pat = GEN_FCN (d->icode) (op0, op1, op2); + if (pat != 0) + emit_insn (pat); - if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); + *expandedp = true; + return NULL_RTX; + } - pat = GEN_FCN (icode) (op0, op1); - if (pat) - emit_insn (pat); - return NULL_RTX; + return NULL_RTX; +} - case ALTIVEC_BUILTIN_ST_INTERNAL_4sf: - icode = CODE_FOR_altivec_stvx_4sf; - arg0 = TREE_VALUE (arglist); - arg1 = TREE_VALUE (TREE_CHAIN (arglist)); - op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); - op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; +/* Expand the builtin in EXP and store the result in TARGET. Store + true in *EXPANDEDP if we found a builtin to expand. */ +static rtx +altivec_expand_builtin (exp, target, expandedp) + tree exp; + rtx target; + bool *expandedp; +{ + struct builtin_description *d; + struct builtin_description_predicates *dp; + size_t i; + enum insn_code icode; + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + tree arglist = TREE_OPERAND (exp, 1); + tree arg0, arg1, arg2; + rtx op0, op1, op2, pat; + enum machine_mode tmode, mode0, mode1, mode2; + unsigned int fcode = DECL_FUNCTION_CODE (fndecl); - if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); + target = altivec_expand_ld_builtin (exp, target, expandedp); + if (*expandedp) + return target; - pat = GEN_FCN (icode) (op0, op1); - if (pat) - emit_insn (pat); - return NULL_RTX; + target = altivec_expand_st_builtin (exp, target, expandedp); + if (*expandedp) + return target; + + target = altivec_expand_dst_builtin (exp, target, expandedp); + if (*expandedp) + return target; + + *expandedp = true; + switch (fcode) + { case ALTIVEC_BUILTIN_STVX: return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist); case ALTIVEC_BUILTIN_STVEBX: @@ -4081,7 +4108,7 @@ altivec_expand_builtin (exp, target, expandedp) return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist); case ALTIVEC_BUILTIN_STVXL: return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist); - + case ALTIVEC_BUILTIN_MFVSCR: icode = CODE_FOR_altivec_mfvscr; tmode = insn_data[icode].operand[0].mode; @@ -4114,7 +4141,7 @@ altivec_expand_builtin (exp, target, expandedp) if (pat) emit_insn (pat); return NULL_RTX; - + case ALTIVEC_BUILTIN_DSSALL: emit_insn (gen_altivec_dssall ()); return NULL_RTX; @@ -4143,46 +4170,6 @@ altivec_expand_builtin (exp, target, expandedp) return NULL_RTX; } - /* Handle DST variants. */ - d = (struct builtin_description *) bdesc_dst; - for (i = 0; i < ARRAY_SIZE (bdesc_dst); 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 const0_rtx; - - if (TREE_CODE (arg2) != INTEGER_CST - || TREE_INT_CST_LOW (arg2) & ~0x3) - { - error ("argument to `%s' must be a 2-bit unsigned literal", d->name); - return const0_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); - - pat = GEN_FCN (d->icode) (op0, op1, op2); - if (pat != 0) - emit_insn (pat); - - return NULL_RTX; - } - /* Expand abs* operations. */ d = (struct builtin_description *) bdesc_abs; for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++) |