Add support for instruction word conditionals of the form `XXX!YYY'
authorAndrew Cagney <cagney@redhat.com>
Tue, 14 Apr 1998 00:00:15 +0000 (00:00 +0000)
committerAndrew Cagney <cagney@redhat.com>
Tue, 14 Apr 1998 00:00:15 +0000 (00:00 +0000)
and XXX=YYY'.  See mn10300 for examples.

sim/igen/ChangeLog
sim/igen/gen.c
sim/igen/igen.c
sim/igen/igen.h
sim/igen/ld-insn.c

index c62353b0e75b6d3b69f7028949560928800ad3fb..537c7864e7a54a62ddd2443291f3f551292012db 100644 (file)
@@ -1,3 +1,41 @@
+Tue Apr 14 08:44:53 1998  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * igen.h (struct igen_trace_options): Add members insn_expansion
+       and insn_insertion.
+
+       * igen.c (main): Add options -Gtrace-insn-expansion,
+       -Gtrace-insn-insertion and -Gtrace-all.
+
+       * gen.c (gen_entry_expand_insns): Trace each instruction as it is
+       selected for expansion.
+       (gen_entry_expand_opcode): Trace each expanded instruction as it
+       is inserted into the table.
+       
+Mon Apr 13 19:21:47 1998  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * ld-insn.c (parse_insn_word): Parse conditional operators.
+       (parse_insn_word): Verify field conditionals.
+
+       * ld-insn.h: Extend syntax to allow macros and field equality.
+       (struct insn_field_cond): Rename insn_field_exclusion, add type.
+
+       * gen.c (gen_entry_expand_opcode): Check type of conditional.
+       (insns_bit_useless): Ditto.
+
+       * ld-insn.c (parse_macro_record): New function.
+
+Mon Apr 13 22:37:47 1998  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * ld-insn.h (enum insn_field_type): Add insn_field_invalid.
+
+       * ld-insn.c (parse_insn_word): Check instruction field type
+       correctly initialized.
+       (print_insn_words): Ditto.
+       (insn_field_type_to_str): Ditto.
+       (dump_insn_field): Ditto.
+
+       * gen.c (insns_bit_useless): Ditto.
+
 Fri Apr  3 18:08:16 1998  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * gen.h, igen.c (print_include_inline, print_includes,
index 927f16500adf780503a864153455eb6838ab6555..f630b9f1739bbb6f0c17f6b52f089acec1020ccc 100644 (file)
@@ -73,8 +73,8 @@ print_gen_entry_path (line_ref *line,
 {
   if (table->parent == NULL)
     {
-      if (table->top->processor != NULL)
-       print (line, "%s", table->top->processor);
+      if (table->top->model != NULL)
+       print (line, "%s", table->top->model->name);
       else
        print (line, "");
     }
@@ -282,9 +282,9 @@ insn_list_insert (insn_list **cur_insn_ptr,
                  /* two instructions with the same constant field
                     values across all words and bits */
                  warning (insn->line,
-                          "Location of second (duplicated?) instruction");
+                          "Two instructions with identical constant fields\n");
                  error ((*cur_insn_ptr)->insn->line,
-                        "Two instructions with identical constant fields\n");
+                        "Location of second (duplicated?) instruction\n");
                case merge_duplicate_insns:
                  /* Add the opcode path to the instructions list */
                  if (opcodes != NULL)
@@ -382,19 +382,19 @@ gen_entry_traverse_tree (lf *file,
 static gen_list *
 make_table (insn_table *isa,
            decode_table *rules,
-           char *processor)
+           model_entry *model)
 {
   insn_entry *insn;
   gen_list *entry = ZALLOC (gen_list);
   entry->table = ZALLOC (gen_entry);
   entry->table->top = entry;
-  entry->processor = processor;
+  entry->model = model;
   entry->isa = isa;
   for (insn = isa->insns; insn != NULL; insn = insn->next)
     {
-      if (processor == NULL
+      if (model == NULL
          || insn->processors == NULL
-         || filter_is_member (insn->processors, processor))
+         || filter_is_member (insn->processors, model->name))
        {
          insn_list_insert (&entry->table->insns,
                            &entry->table->nr_insns,
@@ -420,18 +420,21 @@ make_gen_tables (insn_table *isa,
   if (options.gen.multi_sim)
     {
       gen_list **last = &gen->tables;
-      char *processor;
+      model_entry *model;
       filter *processors;
       if (options.model_filter != NULL)
        processors = options.model_filter;
       else
        processors = isa->model->processors;
-      for (processor = filter_next (processors, "");
-          processor != NULL;
-          processor = filter_next (processors, processor))
+      for (model = isa->model->models;
+          model != NULL;
+          model = model->next)
        {
-         *last = make_table (isa, rules, processor);
-         last = &(*last)->next;
+         if (filter_is_member (processors, model->name))
+           {
+             *last = make_table (isa, rules, model);
+             last = &(*last)->next;
+           }
        }
     }
   else
@@ -495,12 +498,18 @@ insns_bit_useless (insn_list *insns,
   insn_list *entry;
   int value = -1;
   int is_useless = 1; /* cleared if something actually found */
+
+  /* check the instructions for some constant value in at least one of
+     the bit fields */
   for (entry = insns; entry != NULL; entry = entry->next)
     {
       insn_word_entry *word = entry->insn->word[rule->word_nr];
       insn_bit_entry *bit = word->bit[bit_nr];
       switch (bit->field->type)
        {
+       case insn_field_invalid:
+         ASSERT (0);
+         break;
        case insn_field_wild:
        case insn_field_reserved:
          /* neither useless or useful - ignore */
@@ -514,7 +523,9 @@ insns_bit_useless (insn_list *insns,
            case decode_find_constants:
            case decode_find_mixed:
              /* an integer is useful if its value isn't the same
-                 between all instructions? */
+                 between all instructions.  The first time through the
+                 value is saved, the second time through (if the
+                 values differ) it is marked as useful. */
              if (value < 0)
                value = bit->value;
              else if (value != bit->value)
@@ -531,9 +542,9 @@ insns_bit_useless (insn_list *insns,
              break;
            case decode_find_constants:
            case decode_find_mixed:
-             /* a string field forced to constant */
              if (filter_is_member (rule->constant_field_names,
                                    bit->field->val_string))
+               /* a string field forced to constant? */
                is_useless = 0;
              else if (rule->search == decode_find_constants)
                /* the string field isn't constant */
@@ -542,6 +553,77 @@ insns_bit_useless (insn_list *insns,
            }
        }
     }
+
+  /* Given only one constant value has been found, check through all
+     the instructions to see if at least one conditional makes it
+     usefull */
+  if (value >= 0 && is_useless)
+    {
+      for (entry = insns; entry != NULL; entry = entry->next)
+       {
+         insn_word_entry *word = entry->insn->word[rule->word_nr];
+         insn_bit_entry *bit = word->bit[bit_nr];
+         switch (bit->field->type)
+           {
+           case insn_field_invalid:
+             ASSERT (0);
+             break;
+           case insn_field_wild:
+           case insn_field_reserved:
+           case insn_field_int:
+             /* already processed */
+             break;
+           case insn_field_string:
+             switch (rule->search)
+               {
+               case decode_find_strings:
+               case decode_find_constants:
+                 /* already processed */
+                 break;
+               case decode_find_mixed:
+                 /* string field with conditions.  If this condition
+                     eliminates the value then the compare is useful */
+                 if (bit->field->conditions != NULL)
+                   {
+                     insn_field_cond *condition;
+                     int shift = bit->field->last - bit_nr;
+                     for (condition = bit->field->conditions;
+                          condition != NULL;
+                          condition = condition->next)
+                       {
+                       printf ("useless %s%s\n",
+                               (condition->type == insn_field_cond_eq ? "=" : "!"),
+                               condition->string);
+                         switch (condition->type)
+                           {
+                           case insn_field_cond_value:
+                             switch (condition->test)
+                               {
+                               case insn_field_cond_ne:
+                                 if (((condition->value >> shift) & 1) == value)
+                                   /* conditional field excludes the
+                                       current value */
+                                   is_useless = 0;
+                                 break;
+                               case insn_field_cond_eq:
+                                 if (((condition->value >> shift) & 1) != value)
+                                   /* conditional field requires the
+                                       current value */
+                                   is_useless = 0;
+                                 break;
+                               }
+                             break;
+                           case insn_field_cond_field:
+                             /* are these handled separatly? */
+                             break;
+                           }
+                       }
+                   }
+               }
+           }
+       }
+    }
+
   return is_useless;
 }
 
@@ -753,6 +835,15 @@ gen_entry_expand_opcode (gen_entry *table,
     {
       /* Only include the hardwired bit information with an entry IF
          that entry (and hence its functions) are being duplicated.  */
+      if (options.trace.insn_expansion)
+       {
+         print_gen_entry_path (table->opcode_rule->line, table, notify);
+         notify (NULL, ": insert %d - %s.%s%s\n",
+                 opcode_nr,
+                 instruction->format_name,
+                 instruction->name,
+                 (table->opcode_rule->with_duplicates ? " (duplicated)" : ""));
+       }
       if (table->opcode_rule->with_duplicates)
        {
          gen_entry_insert_insn (table, instruction,
@@ -762,6 +853,10 @@ gen_entry_expand_opcode (gen_entry *table,
        }
       else
        {
+         if (options.trace.insn_insertion)
+           {
+             
+           }
          gen_entry_insert_insn (table, instruction,
                                 table->opcode->word_nr,
                                 table->nr_prefetched_words,
@@ -773,9 +868,11 @@ gen_entry_expand_opcode (gen_entry *table,
       insn_word_entry *word = instruction->word[table->opcode->word_nr];
       insn_field_entry *field = word->bit[bit_nr]->field;
       int last_pos = ((field->last < table->opcode->last)
-                     ? field->last : table->opcode->last);
+                     ? field->last
+                     : table->opcode->last);
       int first_pos = ((field->first > table->opcode->first)
-                      ? field->first : table->opcode->first);
+                      ? field->first
+                      : table->opcode->first);
       int width = last_pos - first_pos + 1;
       switch (field->type)
        {
@@ -800,21 +897,77 @@ gen_entry_expand_opcode (gen_entry *table,
              {
                int val;
                int last_val = (table->opcode->is_boolean
-                               ? 2 : (1 << width));
+                               ? 2
+                               : (1 << width));
                for (val = 0; val < last_val; val++)
                  {
-                   /* check to see if the value has been limited */
-                   insn_field_exclusion *exclusion;
-                   for (exclusion = field->exclusions;
-                        exclusion != NULL;
-                        exclusion = exclusion->next)
+                   /* check to see if the value has been precluded
+                       (by a conditional) in some way */
+                   int is_precluded;
+                   insn_field_cond *condition;
+                   for (condition = field->conditions, is_precluded = 0;
+                        condition != NULL && !is_precluded;
+                        condition = condition->next)
                      {
-                       int value = sub_val (exclusion->value, field,
-                                            first_pos, last_pos);
-                       if (value == val)
-                         break;
+                       switch (condition->type)
+                         {
+                         case insn_field_cond_value:
+                           {
+                             int value = sub_val (condition->value, field,
+                                                  first_pos, last_pos);
+                             switch (condition->test)
+                               {
+                               case insn_field_cond_ne:
+                                 if (value == val)
+                                   is_precluded = 1;
+                                 break;
+                               case insn_field_cond_eq:
+                                 if (value != val)
+                                   is_precluded = 1;
+                                 break;
+                               }
+                             break;
+                           }
+                         case insn_field_cond_field:
+                           {
+                             int value;
+                             /* Find a value for the conditional by
+                                 looking back through the previously
+                                 defined bits for the specified
+                                 conditonal field */
+                             opcode_bits *bit = bits;
+                             for (bit = bits;
+                                  bit != NULL;
+                                  bit = bit->next)
+                               {
+                                 if (bit->field == condition->field
+                                     && (bit->last - bit->first + 1 == condition->field->width))
+                                   /* the bit field fully specified
+                                       the conditional field's value */
+                                   break;
+                               }
+                             if (bit == NULL)
+                               error (instruction->line,
+                                      "Conditional `%s' of field `%s' isn't expanded",
+                                      condition->string, field->val_string);
+                             value = sub_val (bit->value, field,
+                                              first_pos, last_pos);
+                             switch (condition->test)
+                               {
+                               case insn_field_cond_ne:
+                                 if (value == val)
+                                   is_precluded = 1;
+                                 break;
+                               case insn_field_cond_eq:
+                                 if (value != val)
+                                   is_precluded = 1;
+                                 break;
+                               }
+                             break;
+                           }
+                         }
                      }
-                   if (exclusion == NULL)
+                   if (!is_precluded)
                      {
                        /* Only add additional hardwired bit
                            information if the entry is not going to
@@ -985,10 +1138,10 @@ gen_entry_expand_insns (gen_entry *table)
        opcode_rule = opcode_rule->next)
     {
       char *discard_reason;
-      if (table->top->processor != NULL
+      if (table->top->model != NULL
          && opcode_rule->model_names != NULL
          && !filter_is_member (opcode_rule->model_names,
-                               table->top->processor))
+                               table->top->model->name))
        {
          /* the rule isn't applicable to this processor */
          discard_reason = "wrong model";
@@ -1075,15 +1228,7 @@ gen_entry_expand_insns (gen_entry *table)
       table->opcode->parent = table->parent->opcode;
     }
 
-  /* expand the raw instructions according to the opcode */
-  {
-    insn_list *entry;
-    for (entry = table->insns; entry != NULL; entry = entry->next)
-      {
-       gen_entry_insert_expanding (table, entry->insn);
-      }
-  }
-
+  /* report the rule being used to expand the instructions */
   if (options.trace.rule_selection)
     {
       print_gen_entry_path (table->opcode_rule->line, table, notify);
@@ -1098,6 +1243,22 @@ gen_entry_expand_insns (gen_entry *table)
              table->nr_entries);
     }
 
+  /* expand the raw instructions according to the opcode */
+  {
+    insn_list *entry;
+    for (entry = table->insns; entry != NULL; entry = entry->next)
+      {
+       if (options.trace.insn_expansion)
+         {
+           print_gen_entry_path (table->opcode_rule->line, table, notify);
+           notify (NULL, ": expand - %s.%s\n",
+                   entry->insn->format_name,
+                   entry->insn->name);
+         }
+       gen_entry_insert_expanding (table, entry->insn);
+      }
+  }
+
   /* dump the results */
   if (options.trace.entries)
     {
index fd9b20d9360e56f47639287ad8006977bf5b7449..4a95f2fbb632d89cfca6c062bd86506d36e18ced 100644 (file)
@@ -1101,14 +1101,17 @@ main (int argc,
       printf ("\t trace-entries          - report entries after a rules application\n");
       printf ("\t trace-rule-rejection   - report each rule as rejected\n");
       printf ("\t trace-rule-selection   - report each rule as selected\n");
+      printf ("\t trace-insn-insertion   - report each instruction as it is inserted into a decode table\n");
+      printf ("\t trace-rule-expansion   - report each instruction as it is expanded (before insertion into a decode table)\n");
+      printf ("\t trace-all              - enable all trace options\n");
       printf ("\n");
-      printf ("\t field-widths          - instruction formats specify widths (depreciated)\n");
-      printf ("\t                         By default, an instruction format specifies bit\n");
-      printf ("\t                         positions\n");
-      printf ("\t                         This option can now be set directly in the\n");
-      printf ("\t                         instruction table\n");
-      printf ("\t jumps                 - use jumps instead of function calls\n");
-      printf ("\t omit-line-numbers     - do not include line number information in the output\n");
+      printf ("\t field-widths           - instruction formats specify widths (depreciated)\n");
+      printf ("\t                          By default, an instruction format specifies bit\n");
+      printf ("\t                          positions\n");
+      printf ("\t                          This option can now be set directly in the\n");
+      printf ("\t                          instruction table\n");
+      printf ("\t jumps                  - use jumps instead of function calls\n");
+      printf ("\t omit-line-numbers      - do not include line number information in the output\n");
       printf ("\n");
       printf ("Input options:\n");
       printf ("\n");
@@ -1426,6 +1429,10 @@ main (int argc,
              {
                options.gen.nia = nia_is_void;
              }
+           else if (strcmp (argp, "trace-all") == 0)
+             {
+               memset (&options.trace, enable_p, sizeof (options.trace));
+             }
            else if (strcmp (argp, "trace-combine") == 0)
              {
                options.trace.combine = enable_p;
@@ -1442,6 +1449,14 @@ main (int argc,
              {
                options.trace.rule_selection = enable_p;
              }
+           else if (strcmp (argp, "trace-insn-insertion") == 0)
+             {
+               options.trace.insn_insertion = enable_p;
+             }
+           else if (strcmp (argp, "trace-insn-expansion") == 0)
+             {
+               options.trace.insn_expansion = enable_p;
+             }
            else if (strcmp (argp, "jumps") == 0)
              {
                options.gen.code = generate_jumps;
index 7aa70efc007965b111e0bb0f8035007bbc1f2920..6977e0674eaafe6003187532b5adc1d5ee651432 100644 (file)
@@ -86,6 +86,8 @@ typedef struct _igen_trace_options igen_trace_options;
 struct _igen_trace_options {
   int rule_selection;
   int rule_rejection;
+  int insn_insertion;
+  int insn_expansion;
   int entries;
   int combine;
 };
index ca57306933030b07f5a9e641ac91238ca400d777..2fc6cf3187f26d1da07712c6e737586ae975a5a4 100644 (file)
@@ -118,36 +118,69 @@ parse_insn_word (line_ref *line,
     if (strlen_val == 0)
       error (line, "Empty value field\n");
     
-    /* break out any conditional fields - { "!" <value> } */
-    while (*chp == '!')
+    /* break out any conditional fields - { [ "!" | "=" [ <value> | <field-name> } */
+    while (*chp == '!' || *chp == '=')
       {
        char *start;
+       char *end;
        int len;
-       insn_field_exclusion *new_exclusion = ZALLOC (insn_field_exclusion);
-       insn_field_exclusion **last;
+       insn_field_cond *new_cond = ZALLOC (insn_field_cond);
+       insn_field_cond **last;
        
-       /* what type of conditional field */
+       /* determine the conditional test */
+       switch (*chp)
+         {
+         case '=':
+           new_cond->test = insn_field_cond_eq;
+           break;
+         case '!':
+           new_cond->test = insn_field_cond_ne;
+           break;
+         default:
+           ASSERT (0);
+         }
+         
+       /* save the value */
        chp++; 
        chp = skip_spaces (chp);
-       /* the value */
        start = chp;
-       chp = skip_digits (chp);
-       len = chp - start;
+       chp = skip_to_separator (chp, "+,:");
+       end = back_spaces (start, chp);
+       len = end - start;
        if (len == 0)
          error (line, "Missing or invalid conditional value\n");
-       /* fill in the entry */
-       new_exclusion->string = NZALLOC (char, len + 1);
-       strncpy (new_exclusion->string, start, len);
-       new_exclusion->value = a2i (new_exclusion->string);
+       new_cond->string = NZALLOC (char, len + 1);
+       strncpy (new_cond->string, start, len);
+
+       /* determine the conditional type */
+       if (isdigit (*start))
+         {
+           /* [ "!" | "=" ] <value> */
+           new_cond->type = insn_field_cond_value;
+           new_cond->value = a2i (new_cond->string);
+         }
+       else
+         {
+           /* [ "!" | "=" ] <field>  - check field valid */
+           new_cond->type = insn_field_cond_field;
+           /* new_cond->field is determined in later */
+         }
+         
+       /* Only a single `=' is permitted. */
+       if ((new_cond->test == insn_field_cond_eq
+            && new_field->conditions != NULL)
+           || (new_field->conditions != NULL
+               && new_field->conditions->test == insn_field_cond_eq))
+         error (line, "Only single conditional when `=' allowed\n");
+
        /* insert it */
-       last = &new_field->exclusions;
+       last = &new_field->conditions;
        while (*last != NULL)
          last = &(*last)->next;
-       *last = new_exclusion;
-       chp = skip_spaces (chp);
+       *last = new_cond;
       }
 
-    /* NOW verify that the field ws finished */
+    /* NOW verify that the field was finished */
     if (*chp == ',')
       {
        chp = skip_spaces (chp + 1);
@@ -156,7 +189,7 @@ parse_insn_word (line_ref *line,
       }
     else if (*chp != '\0')
       {
-       error (line, "Missing field separator");
+       error (line, "Missing field separator\n");
       }
 
     /* copy the value */
@@ -203,8 +236,8 @@ parse_insn_word (line_ref *line,
        filter_parse (&word->field_names, new_field->val_string);
       }
     if (new_field->type != insn_field_string
-       && new_field->exclusions != NULL)
-      error (line, "Exclusions only apply to name fields\n");
+       && new_field->conditions != NULL)
+      error (line, "Conditionals can only be applied to named fields\n");
 
     /* the copy the position */
     new_field->pos_string = NZALLOC (char, strlen_pos + 1);
@@ -281,6 +314,9 @@ parse_insn_word (line_ref *line,
            word->bit[i]->field = field;
            switch (field->type)
              {
+             case insn_field_invalid:
+               ASSERT (0);
+               break;
              case insn_field_int:
                word->bit[i]->mask = 1;
                word->bit[i]->value = ((field->val_int
@@ -295,6 +331,51 @@ parse_insn_word (line_ref *line,
       }
   }
 
+  /* go over all fields that have conditionals refering to other
+     fields.  Link the fields up.  Verify that the two fields have the
+     same size. Verify that the two fields are different */
+  {
+    insn_field_entry *f;
+    for (f = word->first;
+        f->last < options.insn_bit_size;
+        f = f->next)
+      {
+       insn_field_cond *cond;
+       for (cond = f->conditions;
+            cond != NULL;
+            cond = cond->next)
+         {
+           if (cond->type == insn_field_cond_field)
+             {
+               insn_field_entry *field;
+               if (strcmp (cond->string, f->val_string) == 0)
+                 error (line, "Conditional of field `%s' refers to its self\n",
+                        f->val_string);
+               for (field = word->first;
+                    field != NULL;
+                    field = field->next)
+                 {
+                   if (field->type == insn_field_string
+                       && strcmp (field->val_string, cond->string) == 0)
+                     {
+                       /* found field being refered to by conditonal */
+                       cond->field = field;
+                       /* check refered to and this field are the
+                           same size */
+                       if (f->width != field->width)
+                         error (line, "Conditional `%s' of field `%s' has different size\n",
+                                field->width, f->width);
+                       break;
+                     }
+                 }
+               if (cond->field == NULL)
+                 error (line, "Condition field refers to non-existant field `%s'\n",
+                        cond->string);
+             }
+         }
+      }
+  }
+
   return word;
 }
 
@@ -635,7 +716,8 @@ parse_function_record (table *file,
                       table_entry *record,
                       function_entry **list,
                       function_entry **list_entry,
-                      int is_internal)
+                      int is_internal,
+                      model_table *model)
 {
   function_entry *new_function;
   new_function = ZALLOC (function_entry);
@@ -669,8 +751,12 @@ parse_function_record (table *file,
   while (record != NULL
         && record_prefix_is (record, '*', nr_function_model_fields))
     {
-      filter_parse (&new_function->models,
-                   record->field[function_model_name_field] + 1 /*skip `*'*/);
+      char *model_name = record->field[function_model_name_field] + 1; /*skip `*'*/
+      filter_parse (&new_function->models, model_name);
+      if (!filter_is_subset (model->processors, new_function->models))
+       {
+         error (record->line, "machine model `%s' undefined\n", model_name);
+       }
       record = table_read (file);
     }
   /* parse the function body */
@@ -683,12 +769,15 @@ parse_function_record (table *file,
   if (!filter_is_subset (options.flags_filter, new_function->flags))
     {
       if (options.warn.discard)
-       notify (new_function->line, "Discarding function entry - filter flags\n");
+       notify (new_function->line, "Discarding function %s - filter flags\n",
+               new_function->name);
     }
-  else if (!filter_is_subset (options.model_filter, new_function->models))
+  else if (new_function->models != NULL
+          && !filter_is_common (options.model_filter, new_function->models))
     {
       if (options.warn.discard)
-       notify (new_function->line, "Discarding function entry - filter models\n");
+       notify (new_function->line, "Discarding function %s - filter models\n",
+               new_function->name);
     }
   else
     {
@@ -803,6 +892,34 @@ parse_insn_mnemonic_record (table *file,
 }
 
 
+static table_entry *
+parse_macro_record (table *file,
+                   table_entry *record)
+{
+#if 1
+  error (record->line, "Macros are not implemented");
+#else
+  /* parse the define record */
+  if (record->nr_fields < nr_define_fields)
+    error (record->line, "Incorrect nr fields for define record\n");
+  /* process it */
+  if (!is_filtered_out (options.flags_filter,
+                       record->field[record_filter_flags_field])
+      && !is_filtered_out (options.model_filter,
+                          record->field[record_filter_models_field]))
+    {
+      table_define (file,
+                   record->line,
+                   record->field[macro_name_field],
+                   record->field[macro_args_field],
+                   record->field[macro_expr_field]);
+    }  
+  record = table_read (file);
+#endif
+  return record;
+}
+
+
 insn_table *
 load_insn_table (char *file_name,
                 cache_entry *cache)
@@ -842,7 +959,8 @@ load_insn_table (char *file_name,
            record = parse_function_record (file, record,
                                            &isa->functions,
                                            &function,
-                                           0/*is-internal*/);
+                                           0/*is-internal*/,
+                                           model);
            /* convert a string function record into an internal function */
            if (function != NULL)
              {
@@ -863,7 +981,8 @@ load_insn_table (char *file_name,
            record = parse_function_record (file, record,
                                            &isa->functions,
                                            NULL,
-                                           0/*is-internal*/);
+                                           0/*is-internal*/,
+                                           model);
            break;
          }
 
@@ -874,7 +993,8 @@ load_insn_table (char *file_name,
            record = parse_function_record (file, record,
                                            &isa->functions,
                                            &function,
-                                           1/*is-internal*/);
+                                           1/*is-internal*/,
+                                           model);
            /* check what was inserted to see if a pseudo-instruction
                entry also needs to be created */
            if (function != NULL)
@@ -1015,21 +1135,24 @@ load_insn_table (char *file_name,
          record = parse_function_record (file, record,
                                          &model->statics,
                                          NULL,
-                                         0/*is internal*/);
+                                         0/*is internal*/,
+                                         model);
          break;
          
        case model_internal_record:
          record = parse_function_record (file, record,
                                          &model->internals,
                                          NULL,
-                                         1/*is internal*/);
+                                         1/*is internal*/,
+                                         model);
          break;
          
        case model_function_record:
          record = parse_function_record (file, record,
                                          &model->functions,
                                          NULL,
-                                         0/*is internal*/);
+                                         0/*is internal*/,
+                                         model);
          break;
          
        case insn_record: /* instruction records */
@@ -1118,8 +1241,11 @@ load_insn_table (char *file_name,
            break;
          }
       
-       case unknown_record:
        case define_record:
+         record = parse_macro_record (file, record);
+         break;
+
+       case unknown_record:
        case code_record:
          error (record->line, "Unknown or unexpected entry\n");
 
@@ -1148,6 +1274,9 @@ print_insn_words (lf *file,
                lf_printf (file, "%d.", i2target (options.hi_bit_nr, field->first));
              switch (field->type)
                {
+               case insn_field_invalid:
+                 ASSERT (0);
+                 break;
                case insn_field_int:
                  lf_printf (file, "0x%lx", (long) field->val_int);
                  break;
@@ -1397,6 +1526,7 @@ insn_field_type_to_str (insn_field_type type)
 {
   switch (type)
     {
+    case insn_field_invalid: ASSERT (0); return "(invalid)";
     case insn_field_int: return "int";
     case insn_field_reserved: return "reserved";
     case insn_field_wild: return "wild";
@@ -1423,6 +1553,9 @@ dump_insn_field (lf *file,
       lf_printf (file, "%s(type %s)", sep, insn_field_type_to_str (field->type));
       switch (field->type)
        {
+       case insn_field_invalid:
+         ASSERT (0);
+         break;
        case insn_field_int:
          lf_printf (file, "%s(val 0x%lx)", sep, (long) field->val_int);
          break;
This page took 0.036198 seconds and 4 git commands to generate.