The define_subst support made it syntactically possible to add
attributes to a define_expand, but until now they had been ignored
by genattrtab.c.  This patch allows define_expands to have
"code,alternative" attributes but raises an error for general
"insn" attributes.   (Insn attributes would create a chicken-and-egg
problem because you'd need to call the expander to get the insn.)

The point is to allow define_expands to have preferred_for_size
and preferred_for_speed attributes.

Tested as described in the covering note.

gcc/
        * genattrtab.c (insn_def): Add max_type field.
        (check_defs): Check that the type of a define_expand attribute
        is acceptable.
        (gen_insn): Handle DEFINE_EXPAND.  Initialize the max_type field.
        (main): Handle DEFINE_EXPAND.

diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index 6f797bf..42f6dc5 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -142,6 +142,7 @@ struct insn_def
   file_location loc;           /* Where in the .md files it occurs.  */
   int num_alternatives;                /* Number of alternatives.  */
   int vec_idx;                 /* Index of attribute vector in `def'.  */
+  attr_type max_type;          /* Maximum allowable type.  */
 };
 
 /* Once everything has been read in, we store in each attribute value a list
@@ -1167,6 +1168,14 @@ check_defs (void)
                        XSTR (XEXP (value, 0), 0));
              continue;
            }
+         if (id->max_type < attr->type)
+           {
+             error_at (id->loc, "`%s's cannot have %s attribute `%s'",
+                       GET_RTX_NAME (GET_CODE (id->def)),
+                       get_attr_type_name (attr->type),
+                       attr->name);
+             continue;
+           }
 
          XVECEXP (id->def, id->vec_idx, i) = value;
          XEXP (value, 1) = check_attr_value (id->loc, XEXP (value, 1), attr);
@@ -3283,6 +3292,14 @@ gen_insn (md_rtx_info *info)
 
   switch (GET_CODE (def))
     {
+    case DEFINE_EXPAND:
+      id->insn_code = info->index;
+      id->insn_index = insn_index_number;
+      id->num_alternatives = 1;
+      id->vec_idx = 4;
+      id->max_type = AT_CODE_ALT;
+      break;
+
     case DEFINE_INSN:
       id->insn_code = info->index;
       id->insn_index = insn_index_number;
@@ -3290,6 +3307,7 @@ gen_insn (md_rtx_info *info)
       if (id->num_alternatives == 0)
        id->num_alternatives = 1;
       id->vec_idx = 4;
+      id->max_type = AT_INSN;
       break;
 
     case DEFINE_PEEPHOLE:
@@ -3299,6 +3317,7 @@ gen_insn (md_rtx_info *info)
       if (id->num_alternatives == 0)
        id->num_alternatives = 1;
       id->vec_idx = 3;
+      id->max_type = AT_INSN;
       break;
 
     case DEFINE_ASM_ATTRIBUTES:
@@ -3306,6 +3325,7 @@ gen_insn (md_rtx_info *info)
       id->insn_index = -1;
       id->num_alternatives = 1;
       id->vec_idx = 0;
+      id->max_type = AT_INSN;
       got_define_asm_attributes = 1;
       break;
 
@@ -5266,6 +5286,7 @@ main (int argc, char **argv)
     {
       switch (GET_CODE (info.def))
        {
+       case DEFINE_EXPAND:
        case DEFINE_INSN:
        case DEFINE_PEEPHOLE:
        case DEFINE_ASM_ATTRIBUTES:

Reply via email to