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:
parent
618939dec2
commit
6d8fd7bbd7
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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}}, \
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
49
gcc/testsuite/gcc.dg/alpha-base-1.c
Normal file
49
gcc/testsuite/gcc.dg/alpha-base-1.c
Normal 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; }
|
5
gcc/testsuite/gcc.dg/alpha-base-2.c
Normal file
5
gcc/testsuite/gcc.dg/alpha-base-2.c
Normal 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"
|
27
gcc/testsuite/gcc.dg/alpha-max-1.c
Normal file
27
gcc/testsuite/gcc.dg/alpha-max-1.c
Normal 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; }
|
5
gcc/testsuite/gcc.dg/alpha-max-2.c
Normal file
5
gcc/testsuite/gcc.dg/alpha-max-2.c
Normal 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"
|
Loading…
x
Reference in New Issue
Block a user