Commit 100c4561 by Aldy Hernandez

rs6000.c (altivec_init_builtins): Handle __builtin_altivec_abs*.

2002-02-06  Aldy Hernandez  <aldyh@redhat.com>

        * config/rs6000/rs6000.c (altivec_init_builtins): Handle
        __builtin_altivec_abs*.
        (bdesc_abs): New.

        * config/rs6000/rs6000.h (rs6000_builtins): Add
        ALTIVEC_BUILTIN_ABS*.

        * config/rs6000/altivec.h: Use const char for builtins expecting
        literals.
        (vec_abs): New versions for C and C++.
        (vec_abss): Same.

From-SVN: r49671
parent cddd8b72
......@@ -163,6 +163,7 @@ static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int
static rtx altivec_expand_builtin PARAMS ((tree, rtx));
static rtx altivec_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
static rtx altivec_expand_binop_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_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
......@@ -3402,6 +3403,19 @@ static const struct builtin_description_predicates bdesc_altivec_preds[] =
{ MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
};
/* ABS* opreations. */
static const struct builtin_description bdesc_abs[] =
{
{ MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
{ MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
{ MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
{ MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
{ MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
{ MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
{ MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
};
/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
foo (VECa). */
......@@ -3459,6 +3473,41 @@ altivec_expand_unop_builtin (icode, arglist, target)
}
static rtx
altivec_expand_abs_builtin (icode, arglist, target)
enum insn_code icode;
tree arglist;
rtx target;
{
rtx pat, scratch1, scratch2;
tree arg0 = TREE_VALUE (arglist);
rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
enum machine_mode tmode = insn_data[icode].operand[0].mode;
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
/* If we have invalid arguments, bail out before generating bad rtl. */
if (arg0 == error_mark_node)
return NULL_RTX;
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 = copy_to_mode_reg (mode0, op0);
scratch1 = gen_reg_rtx (mode0);
scratch2 = gen_reg_rtx (mode0);
pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
if (! pat)
return 0;
emit_insn (pat);
return target;
}
static rtx
altivec_expand_binop_builtin (icode, arglist, target)
enum insn_code icode;
tree arglist;
......@@ -3936,6 +3985,12 @@ altivec_expand_builtin (exp, target)
return NULL_RTX;
}
/* Expand abs* operations. */
d = (struct builtin_description *) bdesc_abs;
for (i = 0; i < sizeof (bdesc_abs) / sizeof *d; i++, d++)
if (d->code == fcode)
return altivec_expand_abs_builtin (d->icode, arglist, target);
/* Handle simple unary operations. */
d = (struct builtin_description *) bdesc_1arg;
for (i = 0; i < sizeof (bdesc_1arg) / sizeof *d; i++, d++)
......@@ -4322,6 +4377,18 @@ altivec_init_builtins (void)
tree_cons (NULL_TREE, V4SF_type_node,
endlink)));
tree v4si_ftype_v4si
= build_function_type (V4SI_type_node,
tree_cons (NULL_TREE, V4SI_type_node, endlink));
tree v8hi_ftype_v8hi
= build_function_type (V8HI_type_node,
tree_cons (NULL_TREE, V8HI_type_node, endlink));
tree v16qi_ftype_v16qi
= build_function_type (V16QI_type_node,
tree_cons (NULL_TREE, V16QI_type_node, endlink));
tree v8hi_ftype_v16qi_v16qi
= build_function_type (V8HI_type_node,
tree_cons (NULL_TREE, V16QI_type_node,
......@@ -4713,6 +4780,36 @@ altivec_init_builtins (void)
def_builtin (d->mask, d->name, type, d->code);
}
/* Initialize the abs* operators. */
d = (struct builtin_description *) bdesc_abs;
for (i = 0; i < sizeof (bdesc_abs) / sizeof *d; i++, d++)
{
enum machine_mode mode0;
tree type;
mode0 = insn_data[d->icode].operand[0].mode;
switch (mode0)
{
case V4SImode:
type = v4si_ftype_v4si;
break;
case V8HImode:
type = v8hi_ftype_v8hi;
break;
case V16QImode:
type = v16qi_ftype_v16qi;
break;
case V4SFmode:
type = v4sf_ftype_v4sf;
break;
default:
abort ();
}
def_builtin (d->mask, d->name, type, d->code);
}
/* Add the simple unary operators. */
d = (struct builtin_description *) bdesc_1arg;
for (i = 0; i < sizeof (bdesc_1arg) / sizeof *d; i++, d++)
......
......@@ -2971,5 +2971,12 @@ 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_ABSS_V4SI,
ALTIVEC_BUILTIN_ABSS_V8HI,
ALTIVEC_BUILTIN_ABSS_V16QI,
ALTIVEC_BUILTIN_ABS_V4SI,
ALTIVEC_BUILTIN_ABS_V4SF,
ALTIVEC_BUILTIN_ABS_V8HI,
ALTIVEC_BUILTIN_ABS_V16QI
};
......@@ -15033,6 +15033,7 @@
"TARGET_ALTIVEC"
"vspltb %0,%1,%2"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsplth"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
......@@ -15565,3 +15566,73 @@
"TARGET_ALTIVEC"
"stvewx %2,%0,%1"
[(set_attr "type" "vecstore")])
(define_insn "absv16qi2"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(abs:V16QI (match_operand:V16QI 1 "register_operand" "v")))
(clobber (match_scratch:V16QI 2 "=v"))
(clobber (match_scratch:V16QI 3 "=v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsububm %3,%2,%1\;vmaxsb %0,%1,%3"
[(set_attr "type" "altivec")
(set_attr "length" "12")])
(define_insn "absv8hi2"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(abs:V8HI (match_operand:V8HI 1 "register_operand" "v")))
(clobber (match_scratch:V8HI 2 "=v"))
(clobber (match_scratch:V8HI 3 "=v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubuhm %3,%2,%1\;vmaxsh %0,%1,%3"
[(set_attr "type" "altivec")
(set_attr "length" "12")])
(define_insn "absv4si2"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(abs:V4SI (match_operand:V4SI 1 "register_operand" "v")))
(clobber (match_scratch:V4SI 2 "=v"))
(clobber (match_scratch:V4SI 3 "=v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubuwm %3,%2,%1\;vmaxsw %0,%1,%3"
[(set_attr "type" "altivec")
(set_attr "length" "12")])
(define_insn "absv4sf2"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(abs:V4SF (match_operand:V4SF 1 "register_operand" "v")))
(clobber (match_scratch:V4SF 2 "=v"))
(clobber (match_scratch:V4SF 3 "=v"))]
"TARGET_ALTIVEC"
"vspltisw %2, -1\;vslw %3,%2,%2\;vandc %0,%1,%3"
[(set_attr "type" "altivec")
(set_attr "length" "12")])
(define_insn "altivec_abss_v16qi"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] 210))
(clobber (match_scratch:V16QI 2 "=v"))
(clobber (match_scratch:V16QI 3 "=v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubsbs %3,%2,%1\;vmaxsb %0,%1,%3"
[(set_attr "type" "altivec")
(set_attr "length" "12")])
(define_insn "altivec_abss_v8hi"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")] 211))
(clobber (match_scratch:V8HI 2 "=v"))
(clobber (match_scratch:V8HI 3 "=v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubshs %3,%2,%1\;vmaxsh %0,%1,%3"
[(set_attr "type" "altivec")
(set_attr "length" "12")])
(define_insn "altivec_abss_v4si"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")] 212))
(clobber (match_scratch:V4SI 2 "=v"))
(clobber (match_scratch:V4SI 3 "=v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubsws %3,%2,%1\;vmaxsw %0,%1,%3"
[(set_attr "type" "altivec")
(set_attr "length" "12")])
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