diff gcc/genattrtab.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
line wrap: on
line diff
--- a/gcc/genattrtab.c	Thu Oct 25 07:37:49 2018 +0900
+++ b/gcc/genattrtab.c	Thu Feb 13 11:34:05 2020 +0900
@@ -1,5 +1,5 @@
 /* Generate code from machine description to compute values of attributes.
-   Copyright (C) 1991-2018 Free Software Foundation, Inc.
+   Copyright (C) 1991-2020 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GCC.
@@ -133,9 +133,10 @@
    `struct insn_def'.  This is done to allow attribute definitions to occur
    anywhere in the file.  */
 
-struct insn_def
+class insn_def
 {
-  struct insn_def *next;	/* Next insn in chain.  */
+public:
+  class insn_def *next;	/* Next insn in chain.  */
   rtx def;			/* The DEFINE_...  */
   int insn_code;		/* Instruction number.  */
   int insn_index;		/* Expression number in file, for errors.  */
@@ -151,7 +152,7 @@
 struct insn_ent
 {
   struct insn_ent *next;	/* Next in chain.  */
-  struct insn_def *def;		/* Instruction definition.  */
+  class insn_def *def;		/* Instruction definition.  */
 };
 
 /* Each value of an attribute (either constant or computed) is assigned a
@@ -169,11 +170,12 @@
 
 /* Structure for each attribute.  */
 
-struct attr_desc
+class attr_desc
 {
+public:
   char *name;			/* Name of attribute.  */
   const char *enum_name;	/* Enum name for DEFINE_ENUM_NAME.  */
-  struct attr_desc *next;	/* Next attribute.  */
+  class attr_desc *next;	/* Next attribute.  */
   struct attr_value *first_value; /* First value of this attribute.  */
   struct attr_value *default_val; /* Default value for this attribute.  */
   file_location loc;		/* Where in the .md files it occurs.  */
@@ -184,10 +186,11 @@
 
 /* Structure for each DEFINE_DELAY.  */
 
-struct delay_desc
+class delay_desc
 {
+public:
   rtx def;			/* DEFINE_DELAY expression.  */
-  struct delay_desc *next;	/* Next DEFINE_DELAY.  */
+  class delay_desc *next;	/* Next DEFINE_DELAY.  */
   file_location loc;		/* Where in the .md files it occurs.  */
   int num;			/* Number of DEFINE_DELAY, starting at 1.  */
 };
@@ -196,7 +199,7 @@
 {
   struct attr_value *av;
   struct insn_ent *ie;
-  struct attr_desc *attr;
+  class attr_desc *attr;
   struct attr_value_list *next;
 };
 
@@ -204,9 +207,9 @@
 
 /* This one is indexed by the first character of the attribute name.  */
 #define MAX_ATTRS_INDEX 256
-static struct attr_desc *attrs[MAX_ATTRS_INDEX];
-static struct insn_def *defs;
-static struct delay_desc *delays;
+static class attr_desc *attrs[MAX_ATTRS_INDEX];
+static class insn_def *defs;
+static class delay_desc *delays;
 struct attr_value_list **insn_code_values;
 
 /* Other variables.  */
@@ -257,7 +260,7 @@
 static char *attr_printf           (unsigned int, const char *, ...)
   ATTRIBUTE_PRINTF_2;
 static rtx make_numeric_value      (int);
-static struct attr_desc *find_attr (const char **, int);
+static class attr_desc *find_attr (const char **, int);
 static rtx mk_attr_alt             (alternative_mask);
 static char *next_comma_elt	   (const char **);
 static rtx insert_right_side	   (enum rtx_code, rtx, rtx, int, int);
@@ -266,24 +269,24 @@
 static void make_internal_attr     (const char *, rtx, int);
 static void insert_insn_ent        (struct attr_value *, struct insn_ent *);
 static void walk_attr_value	   (rtx);
-static int max_attr_value	   (rtx, int*);
-static int min_attr_value	   (rtx, int*);
-static int or_attr_value	   (rtx, int*);
+static int max_attr_value	   (rtx);
+static int min_attr_value	   (rtx);
+static unsigned int attr_value_alignment (rtx);
 static rtx simplify_test_exp	   (rtx, int, int);
 static rtx simplify_test_exp_in_temp (rtx, int, int);
 static rtx copy_rtx_unchanging	   (rtx);
 static bool attr_alt_subset_p      (rtx, rtx);
 static bool attr_alt_subset_of_compl_p (rtx, rtx);
 static void clear_struct_flag      (rtx);
-static void write_attr_valueq	   (FILE *, struct attr_desc *, const char *);
-static struct attr_value *find_most_used  (struct attr_desc *);
-static void write_attr_set	   (FILE *, struct attr_desc *, int, rtx,
+static void write_attr_valueq	   (FILE *, class attr_desc *, const char *);
+static struct attr_value *find_most_used  (class attr_desc *);
+static void write_attr_set	   (FILE *, class attr_desc *, int, rtx,
 				    const char *, const char *, rtx,
 				    int, int, unsigned int);
-static void write_attr_case	   (FILE *, struct attr_desc *,
+static void write_attr_case	   (FILE *, class attr_desc *,
 				    struct attr_value *,
 				    int, const char *, const char *, int, rtx);
-static void write_attr_value	   (FILE *, struct attr_desc *, rtx);
+static void write_attr_value	   (FILE *, class attr_desc *, rtx);
 static void write_upcase	   (FILE *, const char *);
 static void write_indent	   (FILE *, int);
 static rtx identity_fn		   (rtx);
@@ -844,7 +847,7 @@
    Return a perhaps modified replacement expression for the value.  */
 
 static rtx
-check_attr_value (file_location loc, rtx exp, struct attr_desc *attr)
+check_attr_value (file_location loc, rtx exp, class attr_desc *attr)
 {
   struct attr_value *av;
   const char *p;
@@ -954,7 +957,7 @@
 
     case ATTR:
       {
-	struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
+	class attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
 	if (attr2 == NULL)
 	  error_at (loc, "unknown attribute `%s' in ATTR",
 		    XSTR (exp, 0));
@@ -988,7 +991,7 @@
    It becomes a COND with each test being (eq_attr "alternative" "n") */
 
 static rtx
-convert_set_attr_alternative (rtx exp, struct insn_def *id)
+convert_set_attr_alternative (rtx exp, class insn_def *id)
 {
   int num_alt = id->num_alternatives;
   rtx condexp;
@@ -1024,7 +1027,7 @@
    list of values is given, convert to SET_ATTR_ALTERNATIVE first.  */
 
 static rtx
-convert_set_attr (rtx exp, struct insn_def *id)
+convert_set_attr (rtx exp, class insn_def *id)
 {
   rtx newexp;
   const char *name_ptr;
@@ -1058,8 +1061,8 @@
 static void
 check_defs (void)
 {
-  struct insn_def *id;
-  struct attr_desc *attr;
+  class insn_def *id;
+  class attr_desc *attr;
   int i;
   rtx value;
 
@@ -1116,7 +1119,7 @@
    value.  LOC is the location to use for error reporting.  */
 
 static rtx
-make_canonical (file_location loc, struct attr_desc *attr, rtx exp)
+make_canonical (file_location loc, class attr_desc *attr, rtx exp)
 {
   int i;
   rtx newexp;
@@ -1223,7 +1226,7 @@
    alternatives.  LOC is the location to use for error reporting.  */
 
 static struct attr_value *
-get_attr_value (file_location loc, rtx value, struct attr_desc *attr,
+get_attr_value (file_location loc, rtx value, class attr_desc *attr,
 		int insn_code)
 {
   struct attr_value *av;
@@ -1273,7 +1276,7 @@
 static void
 expand_delays (void)
 {
-  struct delay_desc *delay;
+  class delay_desc *delay;
   rtx condexp;
   rtx newexp;
   int i;
@@ -1359,11 +1362,11 @@
    the attribute.  */
 
 static void
-fill_attr (struct attr_desc *attr)
+fill_attr (class attr_desc *attr)
 {
   struct attr_value *av;
   struct insn_ent *ie;
-  struct insn_def *id;
+  class insn_def *id;
   int i;
   rtx value;
 
@@ -1488,7 +1491,7 @@
   static rtx (*const address_fn[]) (rtx)
     = {max_fn, min_fn, one_fn, identity_fn};
   size_t i;
-  struct attr_desc *length_attr, *new_attr;
+  class attr_desc *length_attr, *new_attr;
   struct attr_value *av, *new_av;
   struct insn_ent *ie, *new_ie;
 
@@ -1550,42 +1553,37 @@
 static rtx
 max_fn (rtx exp)
 {
-  int unknown;
-  return make_numeric_value (max_attr_value (exp, &unknown));
+  return make_numeric_value (max_attr_value (exp));
 }
 
 static rtx
 min_fn (rtx exp)
 {
-  int unknown;
-  return make_numeric_value (min_attr_value (exp, &unknown));
+  return make_numeric_value (min_attr_value (exp));
 }
 
 static void
 write_length_unit_log (FILE *outf)
 {
-  struct attr_desc *length_attr = find_attr (&length_str, 0);
+  class attr_desc *length_attr = find_attr (&length_str, 0);
   struct attr_value *av;
   struct insn_ent *ie;
   unsigned int length_unit_log, length_or;
-  int unknown = 0;
 
   if (length_attr)
     {
-      length_or = or_attr_value (length_attr->default_val->value, &unknown);
+      length_or = attr_value_alignment (length_attr->default_val->value);
       for (av = length_attr->first_value; av; av = av->next)
 	for (ie = av->first_insn; ie; ie = ie->next)
-	  length_or |= or_attr_value (av->value, &unknown);
-    }
-
-  if (length_attr == NULL || unknown)
-    length_unit_log = 0;
-  else
-    {
+	  length_or |= attr_value_alignment (av->value);
+
       length_or = ~length_or;
       for (length_unit_log = 0; length_or & 1; length_or >>= 1)
 	length_unit_log++;
     }
+  else
+    length_unit_log = 0;
+
   fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
 }
 
@@ -1926,7 +1924,7 @@
    corresponding to INSN_CODE and INSN_INDEX.  */
 
 static rtx
-evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value,
+evaluate_eq_attr (rtx exp, class attr_desc *attr, rtx value,
 		  int insn_code, int insn_index)
 {
   rtx orexp, andexp;
@@ -2419,7 +2417,7 @@
 simplify_test_exp (rtx exp, int insn_code, int insn_index)
 {
   rtx left, right;
-  struct attr_desc *attr;
+  class attr_desc *attr;
   struct attr_value *av;
   struct insn_ent *ie;
   struct attr_value_list *iv;
@@ -2760,7 +2758,7 @@
    otherwise return 0.  */
 
 static int
-tests_attr_p (rtx p, struct attr_desc *attr)
+tests_attr_p (rtx p, class attr_desc *attr)
 {
   const char *fmt;
   int i, ie, j, je;
@@ -2801,18 +2799,18 @@
    attr_desc pointers), and return the size of that array.  */
 
 static int
-get_attr_order (struct attr_desc ***ret)
+get_attr_order (class attr_desc ***ret)
 {
   int i, j;
   int num = 0;
-  struct attr_desc *attr;
-  struct attr_desc **all, **sorted;
+  class attr_desc *attr;
+  class attr_desc **all, **sorted;
   char *handled;
   for (i = 0; i < MAX_ATTRS_INDEX; i++)
     for (attr = attrs[i]; attr; attr = attr->next)
       num++;
-  all = XNEWVEC (struct attr_desc *, num);
-  sorted = XNEWVEC (struct attr_desc *, num);
+  all = XNEWVEC (class attr_desc *, num);
+  sorted = XNEWVEC (class attr_desc *, num);
   handled = XCNEWVEC (char, num);
   num = 0;
   for (i = 0; i < MAX_ATTRS_INDEX; i++)
@@ -2860,7 +2858,7 @@
   if (DEBUG)
     for (j = 0; j < num; j++)
       {
-	struct attr_desc *attr2;
+	class attr_desc *attr2;
 	struct attr_value *av;
 
 	attr = sorted[j];
@@ -2891,14 +2889,14 @@
 static void
 optimize_attrs (int num_insn_codes)
 {
-  struct attr_desc *attr;
+  class attr_desc *attr;
   struct attr_value *av;
   struct insn_ent *ie;
   rtx newexp;
   int i;
   struct attr_value_list *ivbuf;
   struct attr_value_list *iv;
-  struct attr_desc **topsort;
+  class attr_desc **topsort;
   int topnum;
 
   /* For each insn code, make a list of all the insn_ent's for it,
@@ -3046,7 +3044,7 @@
 /* Add attribute value NAME to the beginning of ATTR's list.  */
 
 static void
-add_attr_value (struct attr_desc *attr, const char *name)
+add_attr_value (class attr_desc *attr, const char *name)
 {
   struct attr_value *av;
 
@@ -3066,7 +3064,7 @@
 {
   struct enum_type *et;
   struct enum_value *ev;
-  struct attr_desc *attr;
+  class attr_desc *attr;
   const char *name_ptr;
   char *p;
   rtx def = info->def;
@@ -3197,10 +3195,10 @@
 static void
 gen_insn (md_rtx_info *info)
 {
-  struct insn_def *id;
+  class insn_def *id;
   rtx def = info->def;
 
-  id = oballoc (struct insn_def);
+  id = oballoc (class insn_def);
   id->next = defs;
   defs = id;
   id->def = def;
@@ -3245,7 +3243,7 @@
 static void
 gen_delay (md_rtx_info *info)
 {
-  struct delay_desc *delay;
+  class delay_desc *delay;
   int i;
 
   rtx def = info->def;
@@ -3264,7 +3262,7 @@
 	have_annul_false = 1;
     }
 
-  delay = oballoc (struct delay_desc);
+  delay = oballoc (class delay_desc);
   delay->def = def;
   delay->num = ++num_delays;
   delay->next = delays;
@@ -3291,7 +3289,7 @@
 {
   int i;
   const char *name;
-  struct attr_desc *attr;
+  class attr_desc *attr;
 
   if (exp == NULL)
     return;
@@ -3371,7 +3369,7 @@
 {
   int comparison_operator = 0;
   RTX_CODE code;
-  struct attr_desc *attr;
+  class attr_desc *attr;
 
   if (emit_parens)
     fprintf (outf, "(");
@@ -3753,11 +3751,12 @@
   return attrs_cached;
 }
 
-/* Given an attribute value, return the maximum CONST_STRING argument
-   encountered.  Set *UNKNOWNP and return INT_MAX if the value is unknown.  */
+/* Given an attribute value expression, return the maximum value that
+   might be evaluated.  Return INT_MAX if the value can't be
+   calculated by this function.  */
 
 static int
-max_attr_value (rtx exp, int *unknownp)
+max_attr_value (rtx exp)
 {
   int current_max;
   int i, n;
@@ -3768,25 +3767,61 @@
       current_max = atoi (XSTR (exp, 0));
       break;
 
+    case CONST_INT:
+      current_max = INTVAL (exp);
+      break;
+
+    case PLUS:
+      current_max = max_attr_value (XEXP (exp, 0));
+      if (current_max != INT_MAX)
+	{
+	  n = current_max;
+	  current_max = max_attr_value (XEXP (exp, 1));
+	  if (current_max != INT_MAX)
+	    current_max += n;
+	}
+      break;
+
+    case MINUS:
+      current_max = max_attr_value (XEXP (exp, 0));
+      if (current_max != INT_MAX)
+	{
+	  n = current_max;
+	  current_max = min_attr_value (XEXP (exp, 1));
+	  if (current_max != INT_MAX)
+	    current_max = n - current_max;
+	}
+      break;
+
+    case MULT:
+      current_max = max_attr_value (XEXP (exp, 0));
+      if (current_max != INT_MAX)
+	{
+	  n = current_max;
+	  current_max = max_attr_value (XEXP (exp, 1));
+	  if (current_max != INT_MAX)
+	    current_max *= n;
+	}
+      break;
+
     case COND:
-      current_max = max_attr_value (XEXP (exp, 1), unknownp);
+      current_max = max_attr_value (XEXP (exp, 1));
       for (i = 0; i < XVECLEN (exp, 0); i += 2)
 	{
-	  n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
+	  n = max_attr_value (XVECEXP (exp, 0, i + 1));
 	  if (n > current_max)
 	    current_max = n;
 	}
       break;
 
     case IF_THEN_ELSE:
-      current_max = max_attr_value (XEXP (exp, 1), unknownp);
-      n = max_attr_value (XEXP (exp, 2), unknownp);
+      current_max = max_attr_value (XEXP (exp, 1));
+      n = max_attr_value (XEXP (exp, 2));
       if (n > current_max)
 	current_max = n;
       break;
 
     default:
-      *unknownp = 1;
       current_max = INT_MAX;
       break;
     }
@@ -3794,11 +3829,15 @@
   return current_max;
 }
 
-/* Given an attribute value, return the minimum CONST_STRING argument
-   encountered.  Set *UNKNOWNP and return 0 if the value is unknown.  */
+/* Given an attribute value expression, return the minimum value that
+   might be evaluated.  Return INT_MAX if the value can't be
+   calculated by this function.  Note that when this function can
+   calculate one value inside IF_THEN_ELSE or some but not all values
+   inside COND, then it returns the minimum among those values it can
+   calculate.  */
 
 static int
-min_attr_value (rtx exp, int *unknownp)
+min_attr_value (rtx exp)
 {
   int current_min;
   int i, n;
@@ -3809,25 +3848,61 @@
       current_min = atoi (XSTR (exp, 0));
       break;
 
+    case CONST_INT:
+      current_min = INTVAL (exp);
+      break;
+
+    case PLUS:
+      current_min = min_attr_value (XEXP (exp, 0));
+      if (current_min != INT_MAX)
+	{
+	  n = current_min;
+	  current_min = min_attr_value (XEXP (exp, 1));
+	  if (current_min != INT_MAX)
+	    current_min += n;
+	}
+      break;
+
+    case MINUS:
+      current_min = min_attr_value (XEXP (exp, 0));
+      if (current_min != INT_MAX)
+	{
+	  n = current_min;
+	  current_min = max_attr_value (XEXP (exp, 1));
+	  if (current_min != INT_MAX)
+	    current_min = n - current_min;
+	}
+      break;
+
+    case MULT:
+      current_min = min_attr_value (XEXP (exp, 0));
+      if (current_min != INT_MAX)
+	{
+	  n = current_min;
+	  current_min = min_attr_value (XEXP (exp, 1));
+	  if (current_min != INT_MAX)
+	    current_min *= n;
+	}
+      break;
+
     case COND:
-      current_min = min_attr_value (XEXP (exp, 1), unknownp);
+      current_min = min_attr_value (XEXP (exp, 1));
       for (i = 0; i < XVECLEN (exp, 0); i += 2)
 	{
-	  n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
+	  n = min_attr_value (XVECEXP (exp, 0, i + 1));
 	  if (n < current_min)
 	    current_min = n;
 	}
       break;
 
     case IF_THEN_ELSE:
-      current_min = min_attr_value (XEXP (exp, 1), unknownp);
-      n = min_attr_value (XEXP (exp, 2), unknownp);
+      current_min = min_attr_value (XEXP (exp, 1));
+      n = min_attr_value (XEXP (exp, 2));
       if (n < current_min)
 	current_min = n;
       break;
 
     default:
-      *unknownp = 1;
       current_min = INT_MAX;
       break;
     }
@@ -3835,14 +3910,14 @@
   return current_min;
 }
 
-/* Given an attribute value, return the result of ORing together all
-   CONST_STRING arguments encountered.  Set *UNKNOWNP and return -1
-   if the numeric value is not known.  */
-
-static int
-or_attr_value (rtx exp, int *unknownp)
+/* Given an attribute value expression, return the alignment of values.
+   Return 0 if EXP is known to be zero, and 1 if the value can't be
+   calculated by this function.  */
+
+static unsigned int
+attr_value_alignment (rtx exp)
 {
-  int current_or;
+  unsigned int current_or;
   int i;
 
   switch (GET_CODE (exp))
@@ -3851,24 +3926,38 @@
       current_or = atoi (XSTR (exp, 0));
       break;
 
+    case CONST_INT:
+      current_or = INTVAL (exp);
+      break;
+
+    case PLUS:
+    case MINUS:
+      current_or = attr_value_alignment (XEXP (exp, 0));
+      current_or |= attr_value_alignment (XEXP (exp, 1));
+      break;
+
+    case MULT:
+      current_or = attr_value_alignment (XEXP (exp, 0));
+      current_or *= attr_value_alignment (XEXP (exp, 1));
+      break;
+
     case COND:
-      current_or = or_attr_value (XEXP (exp, 1), unknownp);
+      current_or = attr_value_alignment (XEXP (exp, 1));
       for (i = 0; i < XVECLEN (exp, 0); i += 2)
-	current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
+	current_or |= attr_value_alignment (XVECEXP (exp, 0, i + 1));
       break;
 
     case IF_THEN_ELSE:
-      current_or = or_attr_value (XEXP (exp, 1), unknownp);
-      current_or |= or_attr_value (XEXP (exp, 2), unknownp);
+      current_or = attr_value_alignment (XEXP (exp, 1));
+      current_or |= attr_value_alignment (XEXP (exp, 2));
       break;
 
     default:
-      *unknownp = 1;
-      current_or = -1;
+      current_or = 1;
       break;
     }
 
-  return current_or;
+  return current_or & -current_or;
 }
 
 /* Scan an attribute value, possibly a conditional, and record what actions
@@ -3953,7 +4042,7 @@
 /* Write out a function to obtain the attribute for a given INSN.  */
 
 static void
-write_attr_get (FILE *outf, struct attr_desc *attr)
+write_attr_get (FILE *outf, class attr_desc *attr)
 {
   struct attr_value *av, *common_av;
   int i, j;
@@ -4010,7 +4099,7 @@
     if ((attrs_seen_more_than_once & (1U << i)) != 0)
       {
 	const char *name = cached_attrs[i];
-	struct attr_desc *cached_attr;
+	class attr_desc *cached_attr;
 	if (i != j)
 	  cached_attrs[j] = name;
 	cached_attr = find_attr (&name, 0);
@@ -4074,7 +4163,7 @@
    and ";").  */
 
 static void
-write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value,
+write_attr_set (FILE *outf, class attr_desc *attr, int indent, rtx value,
 		const char *prefix, const char *suffix, rtx known_true,
 		int insn_code, int insn_index, unsigned int attrs_cached)
 {
@@ -4202,7 +4291,7 @@
 /* Write out the computation for one attribute value.  */
 
 static void
-write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
+write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av,
 		 int write_case_lines, const char *prefix, const char *suffix,
 		 int indent, rtx known_true)
 {
@@ -4266,7 +4355,7 @@
 /* Utilities to write in various forms.  */
 
 static void
-write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
+write_attr_valueq (FILE *outf, class attr_desc *attr, const char *s)
 {
   if (attr->is_numeric)
     {
@@ -4286,7 +4375,7 @@
 }
 
 static void
-write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
+write_attr_value (FILE *outf, class attr_desc *attr, rtx value)
 {
   int op;
 
@@ -4306,7 +4395,7 @@
 
     case ATTR:
       {
-	struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
+	class attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
 	if (attr->enum_name)
 	  fprintf (outf, "(enum %s)", attr->enum_name);
 	else if (!attr->is_numeric)
@@ -4336,11 +4425,21 @@
       goto do_operator;
 
     do_operator:
+      fprintf (outf, "(");
       write_attr_value (outf, attr, XEXP (value, 0));
-      fputc (' ', outf);
-      fputc (op,  outf);
-      fputc (' ', outf);
+      fprintf (outf, " %c ", op);
       write_attr_value (outf, attr, XEXP (value, 1));
+      fprintf (outf, ")");
+      break;
+
+    case IF_THEN_ELSE:
+      fprintf (outf, "(");
+      write_test_expr (outf, XEXP (value, 0), 0, 0, false);
+      fprintf (outf, " ? ");
+      write_attr_value (outf, attr, XEXP (value, 1));
+      fprintf (outf, " : ");
+      write_attr_value (outf, attr, XEXP (value, 2));
+      fprintf (outf, ")");
       break;
 
     default:
@@ -4404,11 +4503,11 @@
 static void
 write_eligible_delay (FILE *outf, const char *kind)
 {
-  struct delay_desc *delay;
+  class delay_desc *delay;
   int max_slots;
   char str[50];
   const char *pstr;
-  struct attr_desc *attr;
+  class attr_desc *attr;
   struct attr_value *av, *common_av;
   int i;
 
@@ -4540,14 +4639,14 @@
   return attr_string (start, *pstr - start);
 }
 
-/* Return a `struct attr_desc' pointer for a given named attribute.  If CREATE
+/* Return a `class attr_desc' pointer for a given named attribute.  If CREATE
    is nonzero, build a new attribute, if one does not exist.  *NAME_P is
    replaced by a pointer to a canonical copy of the string.  */
 
-static struct attr_desc *
+static class attr_desc *
 find_attr (const char **name_p, int create)
 {
-  struct attr_desc *attr;
+  class attr_desc *attr;
   int index;
   const char *name = *name_p;
 
@@ -4572,7 +4671,7 @@
   if (! create)
     return NULL;
 
-  attr = oballoc (struct attr_desc);
+  attr = oballoc (class attr_desc);
   attr->name = DEF_ATTR_STRING (name);
   attr->enum_name = 0;
   attr->first_value = attr->default_val = NULL;
@@ -4590,7 +4689,7 @@
 static void
 make_internal_attr (const char *name, rtx value, int special)
 {
-  struct attr_desc *attr;
+  class attr_desc *attr;
 
   attr = find_attr (&name, 1);
   gcc_assert (!attr->default_val);
@@ -4605,7 +4704,7 @@
 /* Find the most used value of an attribute.  */
 
 static struct attr_value *
-find_most_used (struct attr_desc *attr)
+find_most_used (class attr_desc *attr)
 {
   struct attr_value *av;
   struct attr_value *most_used;
@@ -4660,7 +4759,7 @@
 static void
 write_const_num_delay_slots (FILE *outf)
 {
-  struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
+  class attr_desc *attr = find_attr (&num_delay_slots_str, 0);
   struct attr_value *av;
 
   if (attr)
@@ -4716,7 +4815,7 @@
   struct insn_reserv *decl = oballoc (struct insn_reserv);
   rtx def = info->def;
 
-  struct attr_desc attr = { };
+  class attr_desc attr = { };
 
   attr.name = DEF_ATTR_STRING (XSTR (def, 0));
   attr.loc = info->loc;
@@ -4833,10 +4932,10 @@
 
 /* Try to find a const attribute (usually cpu or tune) that is used
    in all define_insn_reservation conditions.  */
-static struct attr_desc *
+static class attr_desc *
 find_tune_attr (rtx exp)
 {
-  struct attr_desc *attr;
+  class attr_desc *attr;
 
   switch (GET_CODE (exp))
     {
@@ -4880,7 +4979,7 @@
   int i;
   struct insn_reserv *decl;
   rtx code_exp, lats_exp, byps_exp;
-  struct attr_desc *tune_attr;
+  class attr_desc *tune_attr;
 
   if (n_insn_reservs == 0)
     return;
@@ -5146,8 +5245,8 @@
 int
 main (int argc, const char **argv)
 {
-  struct attr_desc *attr;
-  struct insn_def *id;
+  class attr_desc *attr;
+  class insn_def *id;
   int i;
 
   progname = "genattrtab";