alpha.c (reg_or_const_int_operand): New.

* config/alpha/alpha.c (reg_or_const_int_operand): New.
        (some_operand, input_operand): Accept CONST_VECTOR.
        (alpha_extra_constraint): Add 'W'.
        (alpha_expand_zap_mask): New.
        (alpha_expand_builtin_vector_binop): New.
        (enum alpha_builtin): New.
        (zero_arg_builtins, one_arg_builtins, two_arg_builtins): New.
        (alpha_init_builtins, alpha_expand_builtin): New.
        (TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): New.
        * config/alpha/alpha.h (VECTOR_MODE_SUPPORTED_P): New.
        (PREDICATE_CODES): Update.
        * config/alpha/alpha-protos.h: Update.
        * config/alpha/alpha.md (UNSPEC_CMPBGE, UNSPEC_ZAP,
        UNSPEC_AMASK, UNSPEC_IMPLVER, UNSPEC_PERR, UNSPECV_RPCC): New.
        (movv8qi, movv8qi_fix, movv8qi_nofix): New.
        (movv4hi, movv4hi_fix, movv4hi_nofix): New.
        (movv2si, movv2si_fix, movv2si_nofix): New.
        (uminv8qi3, sminv8qi3, uminv4hi3, sminv4hi3): New.
        (umaxv8qi3, smaxv8qi3, umaxv4hi3, smaxv4hi3): New.
        (builtin_cmpbge, builtin_extql, builtin_extqh, builtin_zap,
        builtin_zap_1, builtin_zapnot, builtin_zapnot_1, builtin_amask,
        builtin_implver, builtin_rpcc, builtin_minub8, builtin_minsb8,
        builtin_minuw4, builtin_minsw4, builtin_maxub8, builtin_maxsb8,
        builtin_maxuw4, builtin_maxsw4, builtin_perr, builtin_pklb,
        pklb, builtin_pkwb, pkwb, builtin_unpkbl, unpkbl,
        builtin_unpkbw, unpkbw): New.
        * doc/extend.texi (Alpha Built-in Functions): New.

        * gcc.dg/alpha-base-1.c, gcc.dg/alpha-base-2.c: New.
        * gcc.dg/alpha-max-1.c, gcc.dg/alpha-max-2.c: New.

From-SVN: r54229
This commit is contained in:
Richard Henderson 2002-06-03 21:06:38 -07:00
parent 618939dec2
commit 6d8fd7bbd7
11 changed files with 1074 additions and 7 deletions

View File

@ -1,3 +1,34 @@
2002-06-03 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
Richard Henderson <rth@redhat.com>
* config/alpha/alpha.c (reg_or_const_int_operand): New.
(some_operand, input_operand): Accept CONST_VECTOR.
(alpha_extra_constraint): Add 'W'.
(alpha_expand_zap_mask): New.
(alpha_expand_builtin_vector_binop): New.
(enum alpha_builtin): New.
(zero_arg_builtins, one_arg_builtins, two_arg_builtins): New.
(alpha_init_builtins, alpha_expand_builtin): New.
(TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): New.
* config/alpha/alpha.h (VECTOR_MODE_SUPPORTED_P): New.
(PREDICATE_CODES): Update.
* config/alpha/alpha-protos.h: Update.
* config/alpha/alpha.md (UNSPEC_CMPBGE, UNSPEC_ZAP,
UNSPEC_AMASK, UNSPEC_IMPLVER, UNSPEC_PERR, UNSPECV_RPCC): New.
(movv8qi, movv8qi_fix, movv8qi_nofix): New.
(movv4hi, movv4hi_fix, movv4hi_nofix): New.
(movv2si, movv2si_fix, movv2si_nofix): New.
(uminv8qi3, sminv8qi3, uminv4hi3, sminv4hi3): New.
(umaxv8qi3, smaxv8qi3, umaxv4hi3, smaxv4hi3): New.
(builtin_cmpbge, builtin_extql, builtin_extqh, builtin_zap,
builtin_zap_1, builtin_zapnot, builtin_zapnot_1, builtin_amask,
builtin_implver, builtin_rpcc, builtin_minub8, builtin_minsb8,
builtin_minuw4, builtin_minsw4, builtin_maxub8, builtin_maxsb8,
builtin_maxuw4, builtin_maxsw4, builtin_perr, builtin_pklb,
pklb, builtin_pkwb, pkwb, builtin_unpkbl, unpkbl,
builtin_unpkbw, unpkbw): New.
* doc/extend.texi (Alpha Built-in Functions): New.
2002-06-03 Richard Henderson <rth@redhat.com>
* crtstuff.c (__EH_FRAME_BEGIN__): Conditionalize on

View File

@ -37,6 +37,7 @@ extern void alpha_output_lineno PARAMS ((FILE *, int));
extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_6bit_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_8bit_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_const_int_operand PARAMS ((rtx, enum machine_mode));
extern int cint8_operand PARAMS ((rtx, enum machine_mode));
extern int add_operand PARAMS ((rtx, enum machine_mode));
extern int sext_add_operand PARAMS ((rtx, enum machine_mode));
@ -122,6 +123,10 @@ extern void alpha_expand_unaligned_store PARAMS ((rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT));
extern int alpha_expand_block_move PARAMS ((rtx []));
extern int alpha_expand_block_clear PARAMS ((rtx []));
extern rtx alpha_expand_zap_mask PARAMS ((HOST_WIDE_INT));
extern void alpha_expand_builtin_vector_binop PARAMS ((rtx (*)(rtx, rtx, rtx),
enum machine_mode,
rtx, rtx, rtx));
extern rtx alpha_return_addr PARAMS ((int, rtx));
extern rtx alpha_gp_save_rtx PARAMS ((void));
extern void print_operand PARAMS ((FILE *, rtx, int));

View File

@ -142,6 +142,10 @@ static void alpha_expand_unaligned_load_words
PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
static void alpha_expand_unaligned_store_words
PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
static void alpha_init_builtins
PARAMS ((void));
static rtx alpha_expand_builtin
PARAMS ((tree, rtx, rtx, enum machine_mode, int));
static void alpha_sa_mask
PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
static int find_lo_sum
@ -278,6 +282,11 @@ static void unicosmk_unique_section PARAMS ((tree, int));
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS HAVE_AS_TLS
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS alpha_init_builtins
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN alpha_expand_builtin
struct gcc_target targetm = TARGET_INITIALIZER;
/* Parse target option strings. */
@ -610,6 +619,16 @@ reg_or_8bit_operand (op, mode)
|| register_operand (op, mode));
}
/* Return 1 if OP is a constant or any register. */
int
reg_or_const_int_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
return GET_CODE (op) == CONST_INT || register_operand (op, mode);
}
/* Return 1 if OP is an 8-bit constant. */
int
@ -813,8 +832,15 @@ some_operand (op, mode)
switch (GET_CODE (op))
{
case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
case SYMBOL_REF: case CONST: case HIGH:
case REG:
case MEM:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case LABEL_REF:
case SYMBOL_REF:
case CONST:
case HIGH:
return 1;
case SUBREG:
@ -893,7 +919,8 @@ input_operand (op, mode)
&& general_operand (op, mode));
case CONST_DOUBLE:
return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
case CONST_VECTOR:
return op == CONST0_RTX (mode);
case CONST_INT:
return mode == QImode || mode == HImode || add_operand (op, mode);
@ -1615,7 +1642,9 @@ alpha_extra_constraint (value, c)
return GET_CODE (value) == HIGH;
case 'U':
return TARGET_ABI_UNICOSMK && symbolic_operand (value, VOIDmode);
case 'W':
return (GET_CODE (value) == CONST_VECTOR
&& value == CONST0_RTX (GET_MODE (value)));
default:
return false;
}
@ -5147,6 +5176,74 @@ alpha_expand_block_clear (operands)
return 1;
}
/* Returns a mask so that zap(x, value) == x & mask. */
rtx
alpha_expand_zap_mask (value)
HOST_WIDE_INT value;
{
rtx result;
int i;
if (HOST_BITS_PER_WIDE_INT >= 64)
{
HOST_WIDE_INT mask = 0;
for (i = 7; i >= 0; --i)
{
mask <<= 8;
if (!((value >> i) & 1))
mask |= 0xff;
}
result = gen_int_mode (mask, DImode);
}
else if (HOST_BITS_PER_WIDE_INT == 32)
{
HOST_WIDE_INT mask_lo = 0, mask_hi = 0;
for (i = 7; i >= 4; --i)
{
mask_hi <<= 8;
if (!((value >> i) & 1))
mask_hi |= 0xff;
}
for (i = 3; i >= 0; --i)
{
mask_lo <<= 8;
if (!((value >> i) & 1))
mask_lo |= 0xff;
}
result = immed_double_const (mask_lo, mask_hi, DImode);
}
else
abort ();
return result;
}
void
alpha_expand_builtin_vector_binop (gen, mode, op0, op1, op2)
rtx (*gen) PARAMS ((rtx, rtx, rtx));
enum machine_mode mode;
rtx op0, op1, op2;
{
op0 = gen_lowpart (mode, op0);
if (op1 == const0_rtx)
op1 = CONST0_RTX (mode);
else
op1 = gen_lowpart (mode, op1);
if (op1 == const0_rtx)
op2 = CONST0_RTX (mode);
else
op2 = gen_lowpart (mode, op2);
emit_insn ((*gen) (op0, op1, op2));
}
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
@ -6261,6 +6358,211 @@ alpha_va_arg (valist, type)
return addr;
}
/* Builtins. */
enum alpha_builtin
{
ALPHA_BUILTIN_CMPBGE,
ALPHA_BUILTIN_EXTQL,
ALPHA_BUILTIN_EXTQH,
ALPHA_BUILTIN_ZAP,
ALPHA_BUILTIN_ZAPNOT,
ALPHA_BUILTIN_AMASK,
ALPHA_BUILTIN_IMPLVER,
ALPHA_BUILTIN_RPCC,
/* TARGET_MAX */
ALPHA_BUILTIN_MINUB8,
ALPHA_BUILTIN_MINSB8,
ALPHA_BUILTIN_MINUW4,
ALPHA_BUILTIN_MINSW4,
ALPHA_BUILTIN_MAXUB8,
ALPHA_BUILTIN_MAXSB8,
ALPHA_BUILTIN_MAXUW4,
ALPHA_BUILTIN_MAXSW4,
ALPHA_BUILTIN_PERR,
ALPHA_BUILTIN_PKLB,
ALPHA_BUILTIN_PKWB,
ALPHA_BUILTIN_UNPKBL,
ALPHA_BUILTIN_UNPKBW,
ALPHA_BUILTIN_max
};
struct alpha_builtin_def
{
const char *name;
enum alpha_builtin code;
unsigned int target_mask;
};
static struct alpha_builtin_def const zero_arg_builtins[] = {
{ "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER, 0 },
{ "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC, 0 }
};
static struct alpha_builtin_def const one_arg_builtins[] = {
{ "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK, 0 },
{ "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB, MASK_MAX },
{ "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB, MASK_MAX },
{ "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL, MASK_MAX },
{ "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW, MASK_MAX }
};
static struct alpha_builtin_def const two_arg_builtins[] = {
{ "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE, 0 },
{ "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL, 0 },
{ "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH, 0 },
{ "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP, 0 },
{ "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT, 0 },
{ "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8, MASK_MAX },
{ "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8, MASK_MAX },
{ "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4, MASK_MAX },
{ "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4, MASK_MAX },
{ "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8, MASK_MAX },
{ "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8, MASK_MAX },
{ "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4, MASK_MAX },
{ "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4, MASK_MAX },
{ "__builtin_alpha_perr", ALPHA_BUILTIN_PERR, MASK_MAX }
};
static void
alpha_init_builtins ()
{
const struct alpha_builtin_def *p;
tree ftype;
size_t i;
ftype = build_function_type (long_integer_type_node, void_list_node);
p = zero_arg_builtins;
for (i = 0; i < ARRAY_SIZE (zero_arg_builtins); ++i, ++p)
if ((target_flags & p->target_mask) == p->target_mask)
builtin_function (p->name, ftype, p->code, BUILT_IN_MD, NULL);
ftype = build_function_type (long_integer_type_node,
tree_cons (NULL_TREE,
long_integer_type_node,
void_list_node));
p = one_arg_builtins;
for (i = 0; i < ARRAY_SIZE (one_arg_builtins); ++i, ++p)
if ((target_flags & p->target_mask) == p->target_mask)
builtin_function (p->name, ftype, p->code, BUILT_IN_MD, NULL);
ftype = build_function_type (long_integer_type_node,
tree_cons (NULL_TREE,
long_integer_type_node,
tree_cons (NULL_TREE,
long_integer_type_node,
void_list_node)));
p = two_arg_builtins;
for (i = 0; i < ARRAY_SIZE (two_arg_builtins); ++i, ++p)
if ((target_flags & p->target_mask) == p->target_mask)
builtin_function (p->name, ftype, p->code, BUILT_IN_MD, NULL);
}
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
(and in mode MODE if that's convenient).
SUBTARGET may be used as the target for computing one of EXP's operands.
IGNORE is nonzero if the value is to be ignored. */
static rtx
alpha_expand_builtin (exp, target, subtarget, mode, ignore)
tree exp;
rtx target;
rtx subtarget ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
int ignore ATTRIBUTE_UNUSED;
{
static unsigned int const code_for_builtin[ALPHA_BUILTIN_max] = {
CODE_FOR_builtin_cmpbge,
CODE_FOR_builtin_extql,
CODE_FOR_builtin_extqh,
CODE_FOR_builtin_zap,
CODE_FOR_builtin_zapnot,
CODE_FOR_builtin_amask,
CODE_FOR_builtin_implver,
CODE_FOR_builtin_rpcc,
CODE_FOR_builtin_minub8,
CODE_FOR_builtin_minsb8,
CODE_FOR_builtin_minuw4,
CODE_FOR_builtin_minsw4,
CODE_FOR_builtin_maxub8,
CODE_FOR_builtin_maxsb8,
CODE_FOR_builtin_maxuw4,
CODE_FOR_builtin_maxsw4,
CODE_FOR_builtin_perr,
CODE_FOR_builtin_pklb,
CODE_FOR_builtin_pkwb,
CODE_FOR_builtin_unpkbl,
CODE_FOR_builtin_unpkbw,
};
#define MAX_ARGS 2
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
tree arglist = TREE_OPERAND (exp, 1);
enum insn_code icode;
rtx op[MAX_ARGS], pat;
int arity;
enum machine_mode tmode;
if (fcode >= ALPHA_BUILTIN_max)
internal_error ("bad builtin fcode");
icode = code_for_builtin[fcode];
if (icode == 0)
internal_error ("bad builtin fcode");
for (arglist = TREE_OPERAND (exp, 1), arity = 0;
arglist;
arglist = TREE_CHAIN (arglist), arity++)
{
const struct insn_operand_data *insn_op;
tree arg = TREE_VALUE (arglist);
if (arg == error_mark_node)
return NULL_RTX;
if (arity > MAX_ARGS)
return NULL_RTX;
op[arity] = expand_expr (arg, NULL_RTX, VOIDmode, 0);
insn_op = &insn_data[icode].operand[arity];
if (!(*insn_op->predicate) (op[arity], insn_op->mode))
op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
}
tmode = insn_data[icode].operand[0].mode;
if (!target
|| GET_MODE (target) != tmode
|| !(*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
switch (arity)
{
case 0:
pat = GEN_FCN (icode) (target);
break;
case 1:
pat = GEN_FCN (icode) (target, op[0]);
break;
case 2:
pat = GEN_FCN (icode) (target, op[0], op[1]);
break;
default:
abort ();
}
if (!pat)
return NULL_RTX;
emit_insn (pat);
return target;
}
/* This page contains routines that are used to determine what the function
prologue and epilogue code will do and write them out. */

View File

@ -615,6 +615,12 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \
: 1)
/* Value is 1 if MODE is a supported vector mode. */
#define VECTOR_MODE_SUPPORTED_P(MODE) \
(TARGET_MAX \
&& ((MODE) == V8QImode || (MODE) == V4HImode || (MODE) == V2SImode))
/* A C expression that is nonzero if a value of mode
MODE1 is accessible in mode MODE2 without copying.
@ -789,7 +795,9 @@ enum reg_class {
'T' is a HIGH.
'U' is a symbolic operand. */
'U' is a symbolic operand.
'W' is a vector zero. */
#define EXTRA_CONSTRAINT alpha_extra_constraint
@ -1923,6 +1931,7 @@ do { \
CONST_VECTOR}}, \
{"reg_or_6bit_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_const_int_operand", {SUBREG, REG, CONST_INT}}, \
{"cint8_operand", {CONST_INT}}, \
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
{"add_operand", {SUBREG, REG, CONST_INT}}, \
@ -1953,9 +1962,9 @@ do { \
{"gottp_symbolic_operand", {CONST}}, \
{"call_operand", {REG, SYMBOL_REF}}, \
{"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
SYMBOL_REF, CONST, LABEL_REF, HIGH}}, \
CONST_VECTOR, SYMBOL_REF, CONST, LABEL_REF, HIGH}},\
{"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
SYMBOL_REF, CONST, LABEL_REF, HIGH}}, \
CONST_VECTOR, SYMBOL_REF, CONST, LABEL_REF, HIGH}}, \
{"some_ni_operand", {SUBREG, REG, MEM}}, \
{"aligned_memory_operand", {MEM}}, \
{"unaligned_memory_operand", {MEM}}, \

View File

@ -49,6 +49,13 @@
(UNSPEC_DTPREL 19)
(UNSPEC_TPREL 20)
(UNSPEC_TP 21)
;; Builtins
(UNSPEC_CMPBGE 22)
(UNSPEC_ZAP 23)
(UNSPEC_AMASK 24)
(UNSPEC_IMPLVER 25)
(UNSPEC_PERR 26)
])
;; UNSPEC_VOLATILE:
@ -67,6 +74,7 @@
(UNSPECV_LDGP1 10)
(UNSPECV_PLDGP2 11) ; prologue ldgp
(UNSPECV_SET_TP 12)
(UNSPECV_RPCC 13)
])
;; Where necessary, the suffixes _le and _be are used to distinguish between
@ -6111,6 +6119,195 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
DONE;
})
;; Vector operations
(define_expand "movv8qi"
[(set (match_operand:V8QI 0 "nonimmediate_operand" "")
(match_operand:V8QI 1 "general_operand" ""))]
""
{
if (alpha_expand_mov (V8QImode, operands))
DONE;
})
(define_insn "*movv8qi_fix"
[(set (match_operand:V8QI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m,r,*f")
(match_operand:V8QI 1 "input_operand" "rW,m,rW,*fW,m,*f,*f,r"))]
"TARGET_FIX
&& (register_operand (operands[0], V8QImode)
|| reg_or_0_operand (operands[1], V8QImode))"
"@
bis $31,%r1,%0
ldq %0,%1
stq %r1,%0
cpys %R1,%R1,%0
ldt %0,%1
stt %R1,%0
ftoit %1,%0
itoft %1,%0"
[(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,ftoi,itof")])
(define_insn "*movv8qi_nofix"
[(set (match_operand:V8QI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m")
(match_operand:V8QI 1 "input_operand" "rW,m,rW,*fW,m,*f"))]
"! TARGET_FIX
&& (register_operand (operands[0], V8QImode)
|| reg_or_0_operand (operands[1], V8QImode))"
"@
bis $31,%r1,%0
ldq %0,%1
stq %r1,%0
cpys %R1,%R1,%0
ldt %0,%1
stt %R1,%0"
[(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
(define_expand "movv4hi"
[(set (match_operand:V4HI 0 "nonimmediate_operand" "")
(match_operand:V4HI 1 "general_operand" ""))]
""
{
if (alpha_expand_mov (V4HImode, operands))
DONE;
})
(define_insn "*movv4hi_fix"
[(set (match_operand:V4HI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m,r,*f")
(match_operand:V4HI 1 "input_operand" "rW,m,rW,*fW,m,*f,*f,r"))]
"TARGET_FIX
&& (register_operand (operands[0], V4HImode)
|| reg_or_0_operand (operands[1], V4HImode))"
"@
bis $31,%r1,%0
ldq %0,%1
stq %r1,%0
cpys %R1,%R1,%0
ldt %0,%1
stt %R1,%0
ftoit %1,%0
itoft %1,%0"
[(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,ftoi,itof")])
(define_insn "*movv4hi_nofix"
[(set (match_operand:V4HI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m")
(match_operand:V4HI 1 "input_operand" "rW,m,rW,*fW,m,*f"))]
"! TARGET_FIX
&& (register_operand (operands[0], V4HImode)
|| reg_or_0_operand (operands[1], V4HImode))"
"@
bis $31,%r1,%0
ldq %0,%1
stq %r1,%0
cpys %R1,%R1,%0
ldt %0,%1
stt %R1,%0"
[(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
(define_expand "movv2si"
[(set (match_operand:V2SI 0 "nonimmediate_operand" "")
(match_operand:V2SI 1 "general_operand" ""))]
""
{
if (alpha_expand_mov (V2SImode, operands))
DONE;
})
(define_insn "*movv2si_fix"
[(set (match_operand:V2SI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m,r,*f")
(match_operand:V2SI 1 "input_operand" "rW,m,rW,*fW,m,*f,*f,r"))]
"TARGET_FIX
&& (register_operand (operands[0], V2SImode)
|| reg_or_0_operand (operands[1], V2SImode))"
"@
bis $31,%r1,%0
ldq %0,%1
stq %r1,%0
cpys %R1,%R1,%0
ldt %0,%1
stt %R1,%0
ftoit %1,%0
itoft %1,%0"
[(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,ftoi,itof")])
(define_insn "*movv2si_nofix"
[(set (match_operand:V2SI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m")
(match_operand:V2SI 1 "input_operand" "rW,m,rW,*fW,m,*f"))]
"! TARGET_FIX
&& (register_operand (operands[0], V2SImode)
|| reg_or_0_operand (operands[1], V2SImode))"
"@
bis $31,%r1,%0
ldq %0,%1
stq %r1,%0
cpys %R1,%R1,%0
ldt %0,%1
stt %R1,%0"
[(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
(define_insn "uminv8qi3"
[(set (match_operand:V8QI 0 "register_operand" "=r")
(umin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
"minub8 %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_insn "sminv8qi3"
[(set (match_operand:V8QI 0 "register_operand" "=r")
(smin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
"minsb8 %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_insn "uminv4hi3"
[(set (match_operand:V4HI 0 "register_operand" "=r")
(umin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
"minuw4 %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_insn "sminv4hi3"
[(set (match_operand:V4HI 0 "register_operand" "=r")
(smin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
"minsw4 %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_insn "umaxv8qi3"
[(set (match_operand:V8QI 0 "register_operand" "=r")
(umax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
"maxub8 %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_insn "smaxv8qi3"
[(set (match_operand:V8QI 0 "register_operand" "=r")
(smax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
"maxsb8 %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_insn "umaxv4hi3"
[(set (match_operand:V4HI 0 "register_operand" "=r")
(umax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
"maxuw4 %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_insn "smaxv4hi3"
[(set (match_operand:V4HI 0 "register_operand" "=r")
(smax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
"maxsw4 %r1,%r2,%0"
[(set_attr "type" "mvi")])
;; Bit field extract patterns which use ext[wlq][lh]
(define_expand "extv"
@ -6779,7 +6976,397 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
else
return ".align %0 #realign";
})
;; Instructions to be emitted from __builtins.
(define_insn "builtin_cmpbge"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "reg_or_8bit_operand" "rI")]
UNSPEC_CMPBGE))]
""
"cmpbge %r1,%2,%0"
;; The EV6 data sheets list this as ILOG. OTOH, EV6 doesn't
;; actually differentiate between ILOG and ICMP in the schedule.
[(set_attr "type" "icmp")])
(define_expand "builtin_extql"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
if (WORDS_BIG_ENDIAN)
gen = gen_extxl_be;
else
gen = gen_extxl_le;
emit_insn ((*gen) (operands[0], operands[1], GEN_INT (64), operands[2]));
DONE;
})
(define_expand "builtin_extqh"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
rtx (*gen) PARAMS ((rtx, rtx, rtx));
if (WORDS_BIG_ENDIAN)
gen = gen_extqh_be;
else
gen = gen_extqh_le;
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
DONE;
})
(define_expand "builtin_zap"
[(set (match_operand:DI 0 "register_operand" "")
(and:DI (unspec:DI
[(match_operand:DI 2 "reg_or_const_int_operand" "")]
UNSPEC_ZAP)
(match_operand:DI 1 "reg_or_const_int_operand" "")))]
""
{
if (GET_CODE (operands[2]) == CONST_INT)
{
rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
if (operands[1] == const0_rtx)
{
emit_move_insn (operands[0], const0_rtx);
DONE;
}
if (operands[1] == constm1_rtx)
{
emit_move_insn (operands[0], operands[1]);
DONE;
}
operands[1] = force_reg (DImode, operands[1]);
emit_insn (gen_anddi3 (operands[0], operands[1], mask));
DONE;
}
operands[1] = force_reg (DImode, operands[1]);
operands[2] = gen_lowpart (QImode, operands[2]);
})
(define_insn "*builtin_zap_1"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
(and:DI (unspec:DI
[(match_operand:QI 2 "reg_or_const_int_operand" "n,n,r,r")]
UNSPEC_ZAP)
(match_operand:DI 1 "reg_or_const_int_operand" "n,r,J,r")))]
""
"@
#
#
bis $31,$31,%0
zap %r1,%2,%0"
[(set_attr "type" "shift,shift,ilog,shift")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(and:DI (unspec:DI
[(match_operand:QI 2 "const_int_operand" "")]
UNSPEC_ZAP)
(match_operand:DI 1 "const_int_operand" "")))]
""
[(const_int 0)]
{
rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
if (HOST_BITS_PER_WIDE_INT >= 64 || GET_CODE (mask) == CONST_INT)
operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
else
{
HOST_WIDE_INT c_lo = INTVAL (operands[1]);
HOST_WIDE_INT c_hi = (c_lo < 0 ? -1 : 0);
operands[1] = immed_double_const (c_lo & CONST_DOUBLE_LOW (mask),
c_hi & CONST_DOUBLE_HIGH (mask),
DImode);
}
emit_move_insn (operands[0], operands[1]);
DONE;
})
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(and:DI (unspec:DI
[(match_operand:QI 2 "const_int_operand" "")]
UNSPEC_ZAP)
(match_operand:DI 1 "register_operand" "")))]
""
[(set (match_dup 0)
(and:DI (match_dup 1) (match_dup 2)))]
{
operands[2] = alpha_expand_zap_mask (INTVAL (operands[2]));
if (operands[2] == const0_rtx)
{
emit_move_insn (operands[0], const0_rtx);
DONE;
}
if (operands[2] == constm1_rtx)
{
emit_move_insn (operands[0], operands[1]);
DONE;
}
})
(define_expand "builtin_zapnot"
[(set (match_operand:DI 0 "register_operand" "")
(and:DI (unspec:DI
[(not:QI (match_operand:QI 2 "reg_or_const_int_operand" ""))]
UNSPEC_ZAP)
(match_operand:DI 1 "reg_or_const_int_operand" "")))]
""
{
if (GET_CODE (operands[2]) == CONST_INT)
{
rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
if (operands[1] == const0_rtx)
{
emit_move_insn (operands[0], const0_rtx);
DONE;
}
if (operands[1] == constm1_rtx)
{
emit_move_insn (operands[0], operands[1]);
DONE;
}
operands[1] = force_reg (DImode, operands[1]);
emit_insn (gen_anddi3 (operands[0], operands[1], mask));
DONE;
}
operands[1] = force_reg (DImode, operands[1]);
operands[2] = gen_lowpart (QImode, operands[2]);
})
(define_insn "*builtin_zapnot_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (unspec:DI
[(not:QI (match_operand:QI 2 "register_operand" "r"))]
UNSPEC_ZAP)
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
""
"zapnot %r1,%2,%0"
[(set_attr "type" "shift")])
(define_insn "builtin_amask"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")]
UNSPEC_AMASK))]
""
"amask %1,%0"
[(set_attr "type" "ilog")])
(define_insn "builtin_implver"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(const_int 0)] UNSPEC_IMPLVER))]
""
"implver %0"
[(set_attr "type" "ilog")])
(define_insn "builtin_rpcc"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))]
""
"rpcc %0"
[(set_attr "type" "ilog")])
(define_expand "builtin_minub8"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_0_operand" "")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
operands[1], operands[2]);
DONE;
})
(define_expand "builtin_minsb8"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_0_operand" "")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
operands[1], operands[2]);
DONE;
})
(define_expand "builtin_minuw4"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_0_operand" "")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
operands[1], operands[2]);
DONE;
})
(define_expand "builtin_minsw4"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_0_operand" "")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
operands[1], operands[2]);
DONE;
})
(define_expand "builtin_maxub8"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_0_operand" "")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
operands[1], operands[2]);
DONE;
})
(define_expand "builtin_maxsb8"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_0_operand" "")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
operands[1], operands[2]);
DONE;
})
(define_expand "builtin_maxuw4"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_0_operand" "")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
operands[1], operands[2]);
DONE;
})
(define_expand "builtin_maxsw4"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_0_operand" "")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
operands[1], operands[2]);
DONE;
})
(define_insn "builtin_perr"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ")
(match_operand:DI 2 "reg_or_8bit_operand" "rJ")]
UNSPEC_PERR))]
"TARGET_MAX"
"perr %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_expand "builtin_pklb"
[(set (match_operand:DI 0 "register_operand" "")
(vec_concat:V8QI
(vec_concat:V4QI
(truncate:V2QI (match_operand:DI 1 "register_operand" ""))
(match_dup 2))
(match_dup 3)))]
"TARGET_MAX"
{
operands[0] = gen_lowpart (V8QImode, operands[0]);
operands[1] = gen_lowpart (V2SImode, operands[1]);
operands[2] = CONST0_RTX (V2QImode);
operands[3] = CONST0_RTX (V4QImode);
})
(define_insn "*pklb"
[(set (match_operand:V8QI 0 "register_operand" "=r")
(vec_concat:V8QI
(vec_concat:V4QI
(truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
(match_operand:V2QI 2 "const0_operand" ""))
(match_operand:V4QI 3 "const0_operand" "")))]
"TARGET_MAX"
"pklb %r1,%0"
[(set_attr "type" "mvi")])
(define_expand "builtin_pkwb"
[(set (match_operand:DI 0 "register_operand" "")
(vec_concat:V8QI
(truncate:V4QI (match_operand:DI 1 "register_operand" ""))
(match_dup 2)))]
"TARGET_MAX"
{
operands[0] = gen_lowpart (V8QImode, operands[0]);
operands[1] = gen_lowpart (V4HImode, operands[1]);
operands[2] = CONST0_RTX (V4QImode);
})
(define_insn "*pkwb"
[(set (match_operand:V8QI 0 "register_operand" "")
(vec_concat:V8QI
(truncate:V4QI (match_operand:V4HI 1 "register_operand" ""))
(match_operand:V4QI 2 "const0_operand" "")))]
"TARGET_MAX"
"pkwb %r1,%0"
[(set_attr "type" "mvi")])
(define_expand "builtin_unpkbl"
[(set (match_operand:DI 0 "register_operand" "")
(zero_extend:V2SI
(vec_select:V2QI (match_operand:DI 1 "register_operand" "")
(parallel [(const_int 0) (const_int 1)]))))]
"TARGET_MAX"
{
operands[0] = gen_lowpart (V2SImode, operands[0]);
operands[1] = gen_lowpart (V8QImode, operands[1]);
})
(define_insn "*unpkbl"
[(set (match_operand:V2SI 0 "register_operand" "=r")
(zero_extend:V2SI
(vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
(parallel [(const_int 0) (const_int 1)]))))]
"TARGET_MAX"
"unpkbl %r1,%0"
[(set_attr "type" "mvi")])
(define_expand "builtin_unpkbw"
[(set (match_operand:DI 0 "register_operand" "")
(zero_extend:V4HI
(vec_select:V4QI (match_operand:DI 1 "register_operand" "")
(parallel [(const_int 0)
(const_int 1)
(const_int 2)
(const_int 3)]))))]
"TARGET_MAX"
{
operands[0] = gen_lowpart (V4HImode, operands[0]);
operands[1] = gen_lowpart (V8QImode, operands[1]);
})
(define_insn "*unpkbw"
[(set (match_operand:V4HI 0 "register_operand" "=r")
(zero_extend:V4HI
(vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
(parallel [(const_int 0)
(const_int 1)
(const_int 2)
(const_int 3)]))))]
"TARGET_MAX"
"unpkbw %r1,%0"
[(set_attr "type" "mvi")])
;; The call patterns are at the end of the file because their
;; wildcard operand0 interferes with nice recognition.

View File

@ -4754,10 +4754,52 @@ to those machines. Generally these generate calls to specific machine
instructions, but allow the compiler to schedule those calls.
@menu
* Alpha Built-in Functions::
* X86 Built-in Functions::
* PowerPC AltiVec Built-in Functions::
@end menu
@node Alpha Built-in Functions
@subsection Alpha Built-in Functions
These built-in functions are available for the Alpha family of
processors, depending on the command-line switches used.
The following built-in functions are always available. They
all generate the machine instruction that is part of the name.
@example
long __builtin_alpha_implver (void)
long __builtin_alpha_rpcc (void)
long __builtin_alpha_amask (long)
long __builtin_alpha_cmpbge (long, long)
long __builtin_alpha_extql (long, long)
long __builtin_alpha_extqh (long, long)
long __builtin_alpha_zap (long, long)
long __builtin_alpha_zapnot (long, long)
@end example
The following built-in functions are always with @option{-mmax}
or @option{-mcpu=@var{cpu}} where @var{cpu} is @code{pca56} or
later. They all generate the machine instruction that is part
of the name.
@example
long __builtin_alpha_pklb (long)
long __builtin_alpha_pkwb (long)
long __builtin_alpha_unpkbl (long)
long __builtin_alpha_unpkbw (long)
long __builtin_alpha_minub8 (long, long)
long __builtin_alpha_minsb8 (long, long)
long __builtin_alpha_minuw4 (long, long)
long __builtin_alpha_minsw4 (long, long)
long __builtin_alpha_maxub8 (long, long)
long __builtin_alpha_maxsb8 (long, long)
long __builtin_alpha_maxuw4 (long, long)
long __builtin_alpha_maxsw4 (long, long)
long __builtin_alpha_perr (long, long)
@end example
@node X86 Built-in Functions
@subsection X86 Built-in Functions

View File

@ -1,3 +1,8 @@
2002-06-03 Richard Henderson <rth@redhat.com>
* gcc.dg/alpha-base-1.c, gcc.dg/alpha-base-2.c: New.
* gcc.dg/alpha-max-1.c, gcc.dg/alpha-max-2.c: New.
2002-06-02 Richard Henderson <rth@redhat.com>
* gcc.c-torture/execute/pure-1.c: Don't mark any of the

View File

@ -0,0 +1,49 @@
/* Test that the base isa builtins compile. */
/* { dg-do link { target alpha*-*-* } } */
/* { dg-options "-mcpu=ev4" } */
void test_BASE (long x, long y)
{
volatile long sink;
long z;
sink = __builtin_alpha_implver ();
sink = __builtin_alpha_rpcc ();
sink = __builtin_alpha_amask (-1);
sink = __builtin_alpha_amask (x);
sink = __builtin_alpha_cmpbge (x, y);
sink = __builtin_alpha_cmpbge (-1, x);
sink = __builtin_alpha_extql (x, y);
sink = __builtin_alpha_extqh (x, y);
}
void test_zap (long x, long y)
{
volatile long sink;
long z;
sink = __builtin_alpha_zap (x, y);
sink = __builtin_alpha_zap (x, 0xaa);
z = 0xaa;
sink = __builtin_alpha_zap (x, z);
z = 0;
sink = __builtin_alpha_zap (z, x);
sink = __builtin_alpha_zap (x, z);
}
void test_zapnot (long x, long y)
{
volatile long sink;
long z;
sink = __builtin_alpha_zapnot (x, y);
sink = __builtin_alpha_zapnot (x, 0xaa);
z = 0xaa;
sink = __builtin_alpha_zapnot (x, z);
z = 0;
sink = __builtin_alpha_zapnot (z, x);
sink = __builtin_alpha_zapnot (x, z);
}
int main() { return 0; }

View File

@ -0,0 +1,5 @@
/* Test that alpha-base-1.c compiles with optimization. */
/* { dg-do link { target alpha*-*-* } } */
/* { dg-options "-mcpu=ev4 -O2" } */
#include "alpha-base-1.c"

View File

@ -0,0 +1,27 @@
/* Test that the MAX isa builtins compile. */
/* { dg-do link { target alpha*-*-* } } */
/* { dg-options "-mmax" } */
void test_MAX (long x, long y)
{
volatile long sink;
sink = __builtin_alpha_pklb (x);
sink = __builtin_alpha_pkwb (x);
sink = __builtin_alpha_unpkbl (x);
sink = __builtin_alpha_unpkbw (x);
sink = __builtin_alpha_minub8 (0, x);
sink = __builtin_alpha_minub8 (1, x);
sink = __builtin_alpha_minub8 (x, y);
sink = __builtin_alpha_minsb8 (x, y);
sink = __builtin_alpha_minuw4 (x, y);
sink = __builtin_alpha_minsw4 (x, y);
sink = __builtin_alpha_maxub8 (x, y);
sink = __builtin_alpha_maxsb8 (x, y);
sink = __builtin_alpha_maxuw4 (x, y);
sink = __builtin_alpha_maxsw4 (x, y);
sink = __builtin_alpha_perr (x, y);
}
int main() { return 0; }

View File

@ -0,0 +1,5 @@
/* Test that alpha-max-1.c compiles with optimization. */
/* { dg-do link { target alpha*-*-* } } */
/* { dg-options "-mmax -O2" } */
#include "alpha-max-1.c"