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
This commit is contained in:
Aldy Hernandez 2002-01-10 02:51:02 +00:00 committed by Aldy Hernandez
parent e4ac76b4f1
commit 95385cbb58
4 changed files with 289 additions and 20 deletions

View file

@ -1,3 +1,32 @@
2002-01-08 Aldy Hernandez <aldyh@redhat.com>
* 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 <rth@redhat.com>
* config/alpha/alpha.md (prologue_mcount): Remove lituse_jsr reloc.

View file

@ -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++)

View file

@ -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
};

View file

@ -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")])