Commit 3a9b8c7e by Aldy Hernandez Committed by Aldy Hernandez

rs6000.c (altivec_expand_builtin): Move lvx/stv/dst builtins...

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).

From-SVN: r55067
parent 5f9dc214
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).
2002-06-28 Bob Wilson <bob.wilson@acm.org> 2002-06-28 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.h (RETURN_IN_MEMORY): Update comment. * config/xtensa/xtensa.h (RETURN_IN_MEMORY): Update comment.
......
...@@ -192,6 +192,9 @@ static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx)); ...@@ -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 rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
static void altivec_init_builtins PARAMS ((void)); static void altivec_init_builtins PARAMS ((void));
static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *)); 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_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_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree)); static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
...@@ -3888,189 +3891,213 @@ rs6000_expand_ternop_builtin (icode, arglist, target) ...@@ -3888,189 +3891,213 @@ rs6000_expand_ternop_builtin (icode, arglist, target)
return target; return target;
} }
/* Expand the builtin in EXP and store the result in TARGET. Store /* Expand the lvx builtins. */
true in *EXPANDEDP if we found a builtin to expand. */
static rtx static rtx
altivec_expand_builtin (exp, target, expandedp) altivec_expand_ld_builtin (exp, target, expandedp)
tree exp; tree exp;
rtx target; rtx target;
bool *expandedp; 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 fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1); 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); unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
tree arg0;
*expandedp = true; enum machine_mode tmode, mode0;
rtx pat, target, op0;
enum insn_code icode;
switch (fcode) switch (fcode)
{ {
case ALTIVEC_BUILTIN_LD_INTERNAL_16qi: case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
icode = CODE_FOR_altivec_lvx_16qi; icode = CODE_FOR_altivec_lvx_16qi;
arg0 = TREE_VALUE (arglist); break;
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;
case ALTIVEC_BUILTIN_LD_INTERNAL_8hi: case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
icode = CODE_FOR_altivec_lvx_8hi; icode = CODE_FOR_altivec_lvx_8hi;
arg0 = TREE_VALUE (arglist); break;
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
tmode = insn_data[icode].operand[0].mode; icode = CODE_FOR_altivec_lvx_4si;
mode0 = insn_data[icode].operand[1].mode; break;
case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
icode = CODE_FOR_altivec_lvx_4sf;
break;
default:
*expandedp = false;
return NULL_RTX;
}
if (target == 0 *expandedp = true;
|| 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)) arg0 = TREE_VALUE (arglist);
op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); 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 (target == 0
if (! pat) || GET_MODE (target) != tmode
return 0; || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
emit_insn (pat); target = gen_reg_rtx (tmode);
return target;
case ALTIVEC_BUILTIN_LD_INTERNAL_4si: if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
icode = CODE_FOR_altivec_lvx_4si; 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;
if (target == 0 pat = GEN_FCN (icode) (target, op0);
|| GET_MODE (target) != tmode if (! pat)
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode)) return 0;
target = gen_reg_rtx (tmode); emit_insn (pat);
return target;
}
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) /* Expand the stvx builtins. */
op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); 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); switch (fcode)
if (! pat) {
return 0; case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
emit_insn (pat); icode = CODE_FOR_altivec_stvx_16qi;
return target; 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: arg0 = TREE_VALUE (arglist);
icode = CODE_FOR_altivec_lvx_4sf; arg1 = TREE_VALUE (TREE_CHAIN (arglist));
arg0 = TREE_VALUE (arglist); op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
tmode = insn_data[icode].operand[0].mode; mode0 = insn_data[icode].operand[0].mode;
mode0 = insn_data[icode].operand[1].mode; mode1 = insn_data[icode].operand[1].mode;
if (target == 0 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
|| GET_MODE (target) != tmode op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode)) if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
target = gen_reg_rtx (tmode); op1 = copy_to_mode_reg (mode1, op1);
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) pat = GEN_FCN (icode) (op0, op1);
op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); if (pat)
emit_insn (pat);
pat = GEN_FCN (icode) (target, op0); *expandedp = true;
if (! pat) return NULL_RTX;
return 0; }
emit_insn (pat);
return target;
case ALTIVEC_BUILTIN_ST_INTERNAL_16qi: /* Expand the dst builtins. */
icode = CODE_FOR_altivec_stvx_16qi; static rtx
arg0 = TREE_VALUE (arglist); altivec_expand_dst_builtin (exp, target, expandedp)
arg1 = TREE_VALUE (TREE_CHAIN (arglist)); tree exp;
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); rtx target;
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); bool *expandedp;
mode0 = insn_data[icode].operand[0].mode; {
mode1 = insn_data[icode].operand[1].mode; 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)) *expandedp = false;
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);
pat = GEN_FCN (icode) (op0, op1); /* Handle DST variants. */
if (pat) d = (struct builtin_description *) bdesc_dst;
emit_insn (pat); for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
return NULL_RTX; 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: /* Invalid arguments, bail out before generating bad rtl. */
icode = CODE_FOR_altivec_stvx_8hi; if (arg0 == error_mark_node
arg0 = TREE_VALUE (arglist); || arg1 == error_mark_node
arg1 = TREE_VALUE (TREE_CHAIN (arglist)); || arg2 == error_mark_node)
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); return const0_rtx;
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
mode0 = insn_data[icode].operand[0].mode;
mode1 = insn_data[icode].operand[1].mode;
if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) if (TREE_CODE (arg2) != INTEGER_CST
op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); || TREE_INT_CST_LOW (arg2) & ~0x3)
if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) {
op1 = copy_to_mode_reg (mode1, op1); error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
return const0_rtx;
}
pat = GEN_FCN (icode) (op0, op1); if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
if (pat) op0 = copy_to_mode_reg (mode0, op0);
emit_insn (pat); if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
return NULL_RTX; op1 = copy_to_mode_reg (mode1, op1);
case ALTIVEC_BUILTIN_ST_INTERNAL_4si: pat = GEN_FCN (d->icode) (op0, op1, op2);
icode = CODE_FOR_altivec_stvx_4si; if (pat != 0)
arg0 = TREE_VALUE (arglist); emit_insn (pat);
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 (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) *expandedp = true;
op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); return NULL_RTX;
if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) }
op1 = copy_to_mode_reg (mode1, op1);
pat = GEN_FCN (icode) (op0, op1); return NULL_RTX;
if (pat) }
emit_insn (pat);
return NULL_RTX;
case ALTIVEC_BUILTIN_ST_INTERNAL_4sf: /* Expand the builtin in EXP and store the result in TARGET. Store
icode = CODE_FOR_altivec_stvx_4sf; true in *EXPANDEDP if we found a builtin to expand. */
arg0 = TREE_VALUE (arglist); static rtx
arg1 = TREE_VALUE (TREE_CHAIN (arglist)); altivec_expand_builtin (exp, target, expandedp)
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); tree exp;
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); rtx target;
mode0 = insn_data[icode].operand[0].mode; bool *expandedp;
mode1 = insn_data[icode].operand[1].mode; {
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)) target = altivec_expand_ld_builtin (exp, target, expandedp);
op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); if (*expandedp)
if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) return target;
op1 = copy_to_mode_reg (mode1, op1);
pat = GEN_FCN (icode) (op0, op1); target = altivec_expand_st_builtin (exp, target, expandedp);
if (pat) if (*expandedp)
emit_insn (pat); return target;
return NULL_RTX;
target = altivec_expand_dst_builtin (exp, target, expandedp);
if (*expandedp)
return target;
*expandedp = true;
switch (fcode)
{
case ALTIVEC_BUILTIN_STVX: case ALTIVEC_BUILTIN_STVX:
return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist); return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
case ALTIVEC_BUILTIN_STVEBX: case ALTIVEC_BUILTIN_STVEBX:
...@@ -4081,7 +4108,7 @@ altivec_expand_builtin (exp, target, expandedp) ...@@ -4081,7 +4108,7 @@ altivec_expand_builtin (exp, target, expandedp)
return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist); return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
case ALTIVEC_BUILTIN_STVXL: case ALTIVEC_BUILTIN_STVXL:
return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist); return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
case ALTIVEC_BUILTIN_MFVSCR: case ALTIVEC_BUILTIN_MFVSCR:
icode = CODE_FOR_altivec_mfvscr; icode = CODE_FOR_altivec_mfvscr;
tmode = insn_data[icode].operand[0].mode; tmode = insn_data[icode].operand[0].mode;
...@@ -4114,7 +4141,7 @@ altivec_expand_builtin (exp, target, expandedp) ...@@ -4114,7 +4141,7 @@ altivec_expand_builtin (exp, target, expandedp)
if (pat) if (pat)
emit_insn (pat); emit_insn (pat);
return NULL_RTX; return NULL_RTX;
case ALTIVEC_BUILTIN_DSSALL: case ALTIVEC_BUILTIN_DSSALL:
emit_insn (gen_altivec_dssall ()); emit_insn (gen_altivec_dssall ());
return NULL_RTX; return NULL_RTX;
...@@ -4143,46 +4170,6 @@ altivec_expand_builtin (exp, target, expandedp) ...@@ -4143,46 +4170,6 @@ altivec_expand_builtin (exp, target, expandedp)
return NULL_RTX; 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. */ /* Expand abs* operations. */
d = (struct builtin_description *) bdesc_abs; d = (struct builtin_description *) bdesc_abs;
for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++) for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment