OSDN Git Service

* config/alpha/alpha.c (reg_or_const_int_operand): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 4 Jun 2002 04:06:38 +0000 (04:06 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 4 Jun 2002 04:06:38 +0000 (04:06 +0000)
        (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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54229 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/alpha/alpha-protos.h
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/alpha-base-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/alpha-base-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/alpha-max-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/alpha-max-2.c [new file with mode: 0644]

index 498c121..fcbc473 100644 (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
index d02af4c..8f5d2d8 100644 (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));
index 91cbc12..ab02990 100644 (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;
 \f
 /* 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));
+}
 \f
 /* 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;
 }
 \f
+/* 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;
+}
+\f
 /* This page contains routines that are used to determine what the function
    prologue and epilogue code will do and write them out.  */
 
index a969a6c..8d47493 100644 (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}},                                 \
index d5d22a2..a63ba9c 100644 (file)
    (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;
 })
 \f
+;; 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")])
+\f
 ;; 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";
 })
+\f
+;; 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")])
+\f
 ;; The call patterns are at the end of the file because their
 ;; wildcard operand0 interferes with nice recognition.
 
index 4b8d496..88786e4 100644 (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
 
index be89ca3..87b8d1c 100644 (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 
diff --git a/gcc/testsuite/gcc.dg/alpha-base-1.c b/gcc/testsuite/gcc.dg/alpha-base-1.c
new file mode 100644 (file)
index 0000000..bca7409
--- /dev/null
@@ -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; }
diff --git a/gcc/testsuite/gcc.dg/alpha-base-2.c b/gcc/testsuite/gcc.dg/alpha-base-2.c
new file mode 100644 (file)
index 0000000..895cdb0
--- /dev/null
@@ -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"
diff --git a/gcc/testsuite/gcc.dg/alpha-max-1.c b/gcc/testsuite/gcc.dg/alpha-max-1.c
new file mode 100644 (file)
index 0000000..5d670e6
--- /dev/null
@@ -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; }
diff --git a/gcc/testsuite/gcc.dg/alpha-max-2.c b/gcc/testsuite/gcc.dg/alpha-max-2.c
new file mode 100644 (file)
index 0000000..5e1ea05
--- /dev/null
@@ -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"