X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=sim%2Figen%2Fgen.c;h=45ad181ac7a5461336e3750af2fcb2bf1150215b;hb=27e4fac77ea57b288ac1e08d936d9a8fdc01a1ee;hp=bd10f20808468fc5ee1efc262521fe52d8e645ad;hpb=07c2bd1455fe6833b4af26fd750e66d182f3f4bc;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/igen/gen.c b/sim/igen/gen.c index bd10f20808..45ad181ac7 100644 --- a/sim/igen/gen.c +++ b/sim/igen/gen.c @@ -1,22 +1,23 @@ -/* This file is part of the program psim. +/* The IGEN simulator generator for GDB, the GNU Debugger. - Copyright (C) 1994-1997, Andrew Cagney + Copyright 2002-2019 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + Contributed by Andrew Cagney. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #include "misc.h" @@ -30,22 +31,16 @@ #include "gen.h" static insn_uint -sub_val (insn_uint val, - int val_last_pos, - int first_pos, - int last_pos) +sub_val (insn_uint val, int val_last_pos, int first_pos, int last_pos) { return ((val >> (val_last_pos - last_pos)) - & (((insn_uint)1 << (last_pos - first_pos + 1)) - 1)); + & (((insn_uint) 1 << (last_pos - first_pos + 1)) - 1)); } static void -update_depth (lf *file, - gen_entry *entry, - int depth, - void *data) +update_depth (lf *file, gen_entry *entry, int depth, void *data) { - int *max_depth = (int*)data; + int *max_depth = (int *) data; if (*max_depth < depth) *max_depth = depth; } @@ -55,21 +50,15 @@ int gen_entry_depth (gen_entry *table) { int depth = 0; - gen_entry_traverse_tree (NULL, - table, - 1, - NULL, /*start*/ - update_depth, - NULL, /*end*/ - &depth); /* data */ + gen_entry_traverse_tree (NULL, table, 1, NULL, /*start */ + update_depth, NULL, /*end */ + &depth); /* data */ return depth; } static void -print_gen_entry_path (line_ref *line, - gen_entry *table, - error_func *print) +print_gen_entry_path (line_ref *line, gen_entry *table, error_func *print) { if (table->parent == NULL) { @@ -88,8 +77,7 @@ print_gen_entry_path (line_ref *line, static void print_gen_entry_insns (gen_entry *table, error_func *print, - char *first_message, - char *next_message) + char *first_message, char *next_message) { insn_list *i; char *message; @@ -98,10 +86,7 @@ print_gen_entry_insns (gen_entry *table, { insn_entry *insn = i->insn; print_gen_entry_path (insn->line, table, print); - print (NULL, ": %s.%s %s\n", - insn->format_name, - insn->name, - message); + print (NULL, ": %s.%s %s\n", insn->format_name, insn->name, message); if (next_message != NULL) message = next_message; } @@ -115,14 +100,12 @@ insn_field_cmp (insn_word_entry *l, insn_word_entry *r) { int bit_nr; if (l == NULL && r == NULL) - return 0; /* all previous fields the same */ + return 0; /* all previous fields the same */ if (l == NULL) - return -1; /* left shorter than right */ + return -1; /* left shorter than right */ if (r == NULL) - return +1; /* left longer than right */ - for (bit_nr = 0; - bit_nr < options.insn_bit_size; - bit_nr++) + return +1; /* left longer than right */ + for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) { if (l->bit[bit_nr]->field->type != insn_field_string) continue; @@ -135,38 +118,48 @@ insn_field_cmp (insn_word_entry *l, insn_word_entry *r) if (0) printf ("%s%s%s VS %s%s%s\n", l->bit[bit_nr]->field->val_string, - l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq ? "=" : "!", - l->bit[bit_nr]->field->conditions->string, + l->bit[bit_nr]->field->conditions->test == + insn_field_cond_eq ? "=" : "!", + l->bit[bit_nr]->field->conditions->string, r->bit[bit_nr]->field->val_string, - r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq ? "=" : "!", + r->bit[bit_nr]->field->conditions->test == + insn_field_cond_eq ? "=" : "!", r->bit[bit_nr]->field->conditions->string); if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq - && r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq) + && r->bit[bit_nr]->field->conditions->test == + insn_field_cond_eq) { - if (l->bit[bit_nr]->field->conditions->type == insn_field_cond_field - && r->bit[bit_nr]->field->conditions->type == insn_field_cond_field) + if (l->bit[bit_nr]->field->conditions->type == + insn_field_cond_field + && r->bit[bit_nr]->field->conditions->type == + insn_field_cond_field) /* somewhat arbitrary */ { int cmp = strcmp (l->bit[bit_nr]->field->conditions->string, - r->bit[bit_nr]->field->conditions->string); + r->bit[bit_nr]->field->conditions-> + string); if (cmp != 0) return cmp; else continue; } - if (l->bit[bit_nr]->field->conditions->type == insn_field_cond_field) + if (l->bit[bit_nr]->field->conditions->type == + insn_field_cond_field) return +1; - if (r->bit[bit_nr]->field->conditions->type == insn_field_cond_field) + if (r->bit[bit_nr]->field->conditions->type == + insn_field_cond_field) return -1; /* The case of both fields having constant values should have - already have been handled because such fields are converted - into normal constant fields. */ + already have been handled because such fields are converted + into normal constant fields, but we must not make this + an assert, as we wouldn't gracefully handle an (invalid) + duplicate insn description. */ continue; } if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq) - return +1; /* left = only */ + return +1; /* left = only */ if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq) - return -1; /* right = only */ + return -1; /* right = only */ /* FIXME: Need to some what arbitrarily order conditional lists */ continue; } @@ -183,14 +176,12 @@ insn_word_cmp (insn_word_entry *l, insn_word_entry *r) { int bit_nr; if (l == NULL && r == NULL) - return 0; /* all previous fields the same */ + return 0; /* all previous fields the same */ if (l == NULL) - return -1; /* left shorter than right */ + return -1; /* left shorter than right */ if (r == NULL) - return +1; /* left longer than right */ - for (bit_nr = 0; - bit_nr < options.insn_bit_size; - bit_nr++) + return +1; /* left longer than right */ + for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) { if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask) return -1; @@ -208,30 +199,29 @@ insn_word_cmp (insn_word_entry *l, insn_word_entry *r) /* same as strcmp */ static int -opcode_bit_cmp (opcode_bits *l, - opcode_bits *r) +opcode_bit_cmp (opcode_bits *l, opcode_bits *r) { if (l == NULL && r == NULL) - return 0; /* all previous bits the same */ + return 0; /* all previous bits the same */ if (l == NULL) - return -1; /* left shorter than right */ + return -1; /* left shorter than right */ if (r == NULL) - return +1; /* left longer than right */ + return +1; /* left longer than right */ /* most significant word */ if (l->field->word_nr < r->field->word_nr) - return +1; /* left has more significant word */ + return +1; /* left has more significant word */ if (l->field->word_nr > r->field->word_nr) - return -1; /* right has more significant word */ + return -1; /* right has more significant word */ /* most significant bit? */ if (l->first < r->first) - return +1; /* left as more significant bit */ + return +1; /* left as more significant bit */ if (l->first > r->first) - return -1; /* right as more significant bit */ + return -1; /* right as more significant bit */ /* nr bits? */ if (l->last < r->last) - return +1; /* left as less bits */ + return +1; /* left as less bits */ if (l->last > r->last) - return -1; /* right as less bits */ + return -1; /* right as less bits */ /* value? */ if (l->value < r->value) return -1; @@ -243,14 +233,13 @@ opcode_bit_cmp (opcode_bits *l, /* same as strcmp */ static int -opcode_bits_cmp (opcode_bits *l, - opcode_bits *r) +opcode_bits_cmp (opcode_bits *l, opcode_bits *r) { while (1) { int cmp; if (l == NULL && r == NULL) - return 0; /* all previous bits the same */ + return 0; /* all previous bits the same */ cmp = opcode_bit_cmp (l, r); if (cmp != 0) return cmp; @@ -264,9 +253,7 @@ static opcode_bits * new_opcode_bits (opcode_bits *old_bits, int value, int first, - int last, - insn_field_entry *field, - opcode_field *opcode) + int last, insn_field_entry *field, opcode_field *opcode) { opcode_bits *new_bits = ZALLOC (opcode_bits); new_bits->field = field; @@ -274,7 +261,7 @@ new_opcode_bits (opcode_bits *old_bits, new_bits->first = first; new_bits->last = last; new_bits->opcode = opcode; - + if (old_bits != NULL) { opcode_bits *new_list; @@ -283,12 +270,11 @@ new_opcode_bits (opcode_bits *old_bits, old_bits->value, old_bits->first, old_bits->last, - old_bits->field, - old_bits->opcode); + old_bits->field, old_bits->opcode); while (*last != NULL) { int cmp = opcode_bit_cmp (new_bits, *last); - if (cmp < 0) /* new < new_list */ + if (cmp < 0) /* new < new_list */ { break; } @@ -308,18 +294,31 @@ new_opcode_bits (opcode_bits *old_bits, } } +/* Same as strcmp(). */ +static int +name_cmp (const char *l, const char *r) +{ + if (l == NULL && r == NULL) + return 0; + if (l != NULL && r == NULL) + return -1; + if (l == NULL && r != NULL) + return +1; + return strcmp (l, r); +} - -typedef enum { +typedef enum +{ merge_duplicate_insns, report_duplicate_insns, -} duplicate_insn_actions; +} +duplicate_insn_actions; static insn_list * insn_list_insert (insn_list **cur_insn_ptr, int *nr_insns, - insn_entry *insn, + insn_entry * insn, opcode_bits *expanded_bits, opcode_field *opcodes, int nr_prefetched_words, @@ -351,18 +350,60 @@ insn_list_insert (insn_list **cur_insn_ptr, else if (cmp > 0) continue; + if (duplicate_action == merge_duplicate_insns) + { + /* key#4: If we're going to merge duplicates, also sort + according to the format_name. Two instructions with + identical decode patterns, but different names, are + considered different when merging. Duplicates are only + important when creating a decode table (implied by + report_duplicate_insns) as such a table only has the + instruction's bit code as a way of differentiating + between instructions. */ + int cmp = name_cmp (insn->format_name, + (*cur_insn_ptr)->insn->format_name); + if (cmp < 0) + break; + else if (cmp > 0) + continue; + } + + if (duplicate_action == merge_duplicate_insns) + { + /* key#5: If we're going to merge duplicates, also sort + according to the name. See comment above for + format_name. */ + int cmp = name_cmp (insn->name, (*cur_insn_ptr)->insn->name); + if (cmp < 0) + break; + else if (cmp > 0) + continue; + } + /* duplicate keys, report problem */ switch (duplicate_action) { case report_duplicate_insns: - /* two instructions with the same constant field - values across all words and bits */ + /* It would appear that we have two instructions with the + same constant field values across all words and bits. + This error can also occure when insn_field_cmp() is + failing to differentiate between two instructions that + differ only in their conditional fields. */ warning (insn->line, "Two instructions with identical constant fields\n"); error ((*cur_insn_ptr)->insn->line, - "Location of second (duplicated?) instruction\n"); + "Location of duplicate instruction\n"); case merge_duplicate_insns: /* Add the opcode path to the instructions list */ + if (options.trace.insn_insertion) + { + notify ((*cur_insn_ptr)->insn->line, + "%s.%s: insert merge %s.%s\n", + (*cur_insn_ptr)->insn->format_name, + (*cur_insn_ptr)->insn->name, + insn->format_name, + insn->name); + } if (opcodes != NULL) { insn_opcodes **last = &(*cur_insn_ptr)->opcodes; @@ -380,10 +421,17 @@ insn_list_insert (insn_list **cur_insn_ptr, } } - + /* create a new list entry and insert it */ { insn_list *new_insn = ZALLOC (insn_list); + if (options.trace.insn_insertion) + { + notify (insn->line, + "%s.%s: insert new\n", + insn->format_name, + insn->name); + } new_insn->insn = insn; new_insn->expanded_bits = expanded_bits; new_insn->next = (*cur_insn_ptr); @@ -395,7 +443,7 @@ insn_list_insert (insn_list **cur_insn_ptr, } (*cur_insn_ptr) = new_insn; } - + *nr_insns += 1; return (*cur_insn_ptr); @@ -406,27 +454,24 @@ extern void gen_entry_traverse_tree (lf *file, gen_entry *table, int depth, - gen_entry_handler *start, - gen_entry_handler *leaf, - gen_entry_handler *end, - void *data) + gen_entry_handler * start, + gen_entry_handler * leaf, + gen_entry_handler * end, void *data) { gen_entry *entry; - - ASSERT (table != NULL); + + ASSERT (table !=NULL); ASSERT (table->opcode != NULL); ASSERT (table->nr_entries > 0); ASSERT (table->entries != 0); - + /* prefix */ if (start != NULL && depth >= 0) { start (file, table, depth, data); } /* infix leaves */ - for (entry = table->entries; - entry != NULL; - entry = entry->sibling) + for (entry = table->entries; entry != NULL; entry = entry->sibling) { if (entry->entries != NULL && depth != 0) { @@ -453,9 +498,7 @@ gen_entry_traverse_tree (lf *file, /* create a list element containing a single gen_table entry */ static gen_list * -make_table (insn_table *isa, - decode_table *rules, - model_entry *model) +make_table (insn_table *isa, decode_table *rules, model_entry *model) { insn_entry *insn; gen_list *entry = ZALLOC (gen_list); @@ -469,12 +512,9 @@ make_table (insn_table *isa, || insn->processors == NULL || filter_is_member (insn->processors, model->name)) { - insn_list_insert (&entry->table->insns, - &entry->table->nr_insns, - insn, - NULL, /* expanded_bits - none yet */ - NULL, /* opcodes - none yet */ - 0, /* nr_prefetched_words - none yet */ + insn_list_insert (&entry->table->insns, &entry->table->nr_insns, insn, NULL, /* expanded_bits - none yet */ + NULL, /* opcodes - none yet */ + 0, /* nr_prefetched_words - none yet */ report_duplicate_insns); } } @@ -484,8 +524,7 @@ make_table (insn_table *isa, gen_table * -make_gen_tables (insn_table *isa, - decode_table *rules) +make_gen_tables (insn_table *isa, decode_table *rules) { gen_table *gen = ZALLOC (gen_table); gen->isa = isa; @@ -499,9 +538,7 @@ make_gen_tables (insn_table *isa, processors = options.model_filter; else processors = isa->model->processors; - for (model = isa->model->models; - model != NULL; - model = model->next) + for (model = isa->model->models; model != NULL; model = model->next) { if (filter_is_member (processors, model->name)) { @@ -516,61 +553,18 @@ make_gen_tables (insn_table *isa, } return gen; } - - -/****************************************************************/ - -#if 0 -typedef enum { - field_is_not_constant = 0, - field_constant_int = 1, - field_constant_reserved = 2, - field_constant_string = 3 -} constant_field_types; - -static constant_field_types -insn_field_is_constant (insn_field *field, - decode_table *rule) -{ - switch (field->type) - { - case insn_field_int: - /* field is an integer */ - return field_constant_int; - case insn_field_reserved: - /* field is `/' and treating that as a constant */ - if (rule->with_zero_reserved) - return field_constant_reserved; - else - return field_is_not_constant; - case insn_field_wild: - return field_is_not_constant; /* never constant */ - case insn_field_string: - /* field, though variable, is on the list of forced constants */ - if (filter_is_member (rule->constant_field_names, field->val_string)) - return field_constant_string; - else - return field_is_not_constant; - } - ERROR ("Internal error"); - return field_is_not_constant; -} -#endif /****************************************************************/ - /* Is the bit, according to the decode rule, identical across all the instructions? */ static int -insns_bit_useless (insn_list *insns, - decode_table *rule, - int bit_nr) +insns_bit_useless (insn_list *insns, decode_table *rule, int bit_nr) { insn_list *entry; int value = -1; - int is_useless = 1; /* cleared if something actually found */ + int is_useless = 1; /* cleared if something actually found */ /* check the instructions for some constant value in at least one of the bit fields */ @@ -596,9 +590,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. The first time through the - value is saved, the second time through (if the - values differ) it is marked as useful. */ + 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) @@ -619,6 +613,18 @@ insns_bit_useless (insn_list *insns, bit->field->val_string)) /* a string field forced to constant? */ is_useless = 0; + else if (bit->field->conditions != NULL + && bit->field->conditions->test == insn_field_cond_eq + && bit->field->conditions->type == insn_field_cond_value) + { + int shift = bit->field->last - bit_nr; + int bitvalue = (bit->field->conditions->value >> shift) & 1; + + if (value < 0) + value = bitvalue; + else if (value != bitvalue) + is_useless = 0; + } else if (rule->search == decode_find_constants) /* the string field isn't constant */ return 1; @@ -655,14 +661,13 @@ insns_bit_useless (insn_list *insns, break; case decode_find_mixed: /* string field with conditions. If this condition - eliminates the value then the compare is useful */ + 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) + condition != NULL; condition = condition->next) { switch (condition->type) { @@ -673,14 +678,14 @@ insns_bit_useless (insn_list *insns, if (((condition->value >> shift) & 1) == (unsigned) value) /* conditional field excludes the - current value */ + current value */ is_useless = 0; break; case insn_field_cond_eq: if (((condition->value >> shift) & 1) != (unsigned) value) /* conditional field requires the - current value */ + current value */ is_useless = 0; break; } @@ -705,8 +710,7 @@ insns_bit_useless (insn_list *insns, static opcode_field * gen_entry_find_opcode_field (insn_list *insns, - decode_table *rule, - int string_only) + decode_table *rule, int string_only) { opcode_field curr_opcode; ASSERT (rule != NULL); @@ -722,83 +726,18 @@ gen_entry_find_opcode_field (insn_list *insns, while (curr_opcode.first <= rule->last) { if (insns_bit_useless (insns, rule, curr_opcode.first)) - curr_opcode.first ++; + curr_opcode.first++; else break; } while (curr_opcode.last >= rule->first) { if (insns_bit_useless (insns, rule, curr_opcode.last)) - curr_opcode.last --; + curr_opcode.last--; else break; } - -#if 0 - for (entry = insns; entry != NULL; entry = entry->next) - { - insn_word_entry *fields = entry->insn->word[rule->word_nr]; - opcode_field new_opcode; - - ASSERT (fields != NULL); - - /* find a start point for the opcode field */ - new_opcode.first = rule->first; - while (new_opcode.first <= rule->last - && (!string_only - || (insn_field_is_constant(fields->bit[new_opcode.first], rule) - != field_constant_string)) - && (string_only - || (insn_field_is_constant(fields->bit[new_opcode.first], rule) - == field_is_not_constant))) - { - int new_first = fields->bit[new_opcode.first]->last + 1; - ASSERT (new_first > new_opcode.first); - new_opcode.first = new_first; - } - ASSERT(new_opcode.first > rule->last - || (string_only - && insn_field_is_constant(fields->bit[new_opcode.first], - rule) == field_constant_string) - || (!string_only - && insn_field_is_constant(fields->bit[new_opcode.first], - rule))); - - /* find the end point for the opcode field */ - new_opcode.last = rule->last; - while (new_opcode.last >= rule->first - && (!string_only - || insn_field_is_constant(fields->bit[new_opcode.last], - rule) != field_constant_string) - && (string_only - || !insn_field_is_constant(fields->bit[new_opcode.last], - rule))) - { - int new_last = fields->bit[new_opcode.last]->first - 1; - ASSERT (new_last < new_opcode.last); - new_opcode.last = new_last; - } - ASSERT(new_opcode.last < rule->first - || (string_only - && insn_field_is_constant(fields->bit[new_opcode.last], - rule) == field_constant_string) - || (!string_only - && insn_field_is_constant(fields->bit[new_opcode.last], - rule))); - - /* now see if our current opcode needs expanding to include the - interesting fields within this instruction */ - if (new_opcode.first <= rule->last - && curr_opcode.first > new_opcode.first) - curr_opcode.first = new_opcode.first; - if (new_opcode.last >= rule->first - && curr_opcode.last < new_opcode.last) - curr_opcode.last = new_opcode.last; - - } -#endif - /* did the final opcode field end up being empty? */ if (curr_opcode.first > curr_opcode.last) { @@ -810,21 +749,18 @@ gen_entry_find_opcode_field (insn_list *insns, /* Ensure that, for the non string only case, the opcode includes the range forced_first .. forced_last */ - if (!string_only - && curr_opcode.first > rule->force_first) + if (!string_only && curr_opcode.first > rule->force_first) { curr_opcode.first = rule->force_first; } - if (!string_only - && curr_opcode.last < rule->force_last) + if (!string_only && curr_opcode.last < rule->force_last) { curr_opcode.last = rule->force_last; } /* For the string only case, force just the lower bound (so that the shift can be eliminated) */ - if (string_only - && rule->force_last == options.insn_bit_size - 1) + if (string_only && rule->force_last == options.insn_bit_size - 1) { curr_opcode.last = options.insn_bit_size - 1; } @@ -854,20 +790,19 @@ gen_entry_find_opcode_field (insn_list *insns, static void gen_entry_insert_insn (gen_entry *table, - insn_entry *old_insn, + insn_entry * old_insn, int new_word_nr, int new_nr_prefetched_words, - int new_opcode_nr, - opcode_bits *new_bits) + int new_opcode_nr, opcode_bits *new_bits) { gen_entry **entry = &table->entries; - + /* find the new table for this entry */ while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr) { entry = &(*entry)->sibling; } - + if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr) { /* insert the missing entry */ @@ -886,22 +821,17 @@ gen_entry_insert_insn (gen_entry *table, } /* ASSERT new_bits == cur_entry bits */ ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr); - insn_list_insert (&(*entry)->insns, - &(*entry)->nr_insns, - old_insn, - NULL, /* expanded_bits - only in final list */ - NULL, /* opcodes - only in final list */ - new_nr_prefetched_words, /* for this table */ + insn_list_insert (&(*entry)->insns, &(*entry)->nr_insns, old_insn, NULL, /* expanded_bits - only in final list */ + NULL, /* opcodes - only in final list */ + new_nr_prefetched_words, /* for this table */ report_duplicate_insns); } static void gen_entry_expand_opcode (gen_entry *table, - insn_entry *instruction, - int bit_nr, - int opcode_nr, - opcode_bits *bits) + insn_entry * instruction, + int bit_nr, int opcode_nr, opcode_bits *bits) { if (bit_nr > table->opcode->last) { @@ -914,21 +844,20 @@ gen_entry_expand_opcode (gen_entry *table, opcode_nr, instruction->format_name, instruction->name, - (table->opcode_rule->with_duplicates ? " (duplicated)" : "")); + (table->opcode_rule-> + with_duplicates ? " (duplicated)" : "")); } if (table->opcode_rule->with_duplicates) { gen_entry_insert_insn (table, instruction, table->opcode->word_nr, - table->nr_prefetched_words, - opcode_nr, bits); + table->nr_prefetched_words, opcode_nr, bits); } else { gen_entry_insert_insn (table, instruction, table->opcode->word_nr, - table->nr_prefetched_words, - opcode_nr, NULL); + table->nr_prefetched_words, opcode_nr, NULL); } } else @@ -936,23 +865,19 @@ 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) { case insn_field_int: { int val; - val = sub_val (field->val_int, field->last, - first_pos, last_pos); + val = sub_val (field->val_int, field->last, first_pos, last_pos); gen_entry_expand_opcode (table, instruction, last_pos + 1, - ((opcode_nr << width) | val), - bits); + ((opcode_nr << width) | val), bits); break; } default: @@ -960,18 +885,15 @@ gen_entry_expand_opcode (gen_entry *table, if (field->type == insn_field_reserved) gen_entry_expand_opcode (table, instruction, last_pos + 1, - ((opcode_nr << width)), - bits); + ((opcode_nr << width)), bits); else { int val; - int last_val = (table->opcode->is_boolean - ? 2 - : (1 << width)); + int last_val = (table->opcode->is_boolean ? 2 : (1 << width)); for (val = 0; val < last_val; val++) { /* check to see if the value has been precluded - (by a conditional) in some way */ + (by a conditional) in some way */ int is_precluded; insn_field_cond *condition; for (condition = field->conditions, is_precluded = 0; @@ -982,8 +904,9 @@ gen_entry_expand_opcode (gen_entry *table, { case insn_field_cond_value: { - int value = sub_val (condition->value, field->last, - first_pos, last_pos); + int value = + sub_val (condition->value, field->last, + first_pos, last_pos); switch (condition->test) { case insn_field_cond_ne: @@ -999,45 +922,66 @@ gen_entry_expand_opcode (gen_entry *table, } case insn_field_cond_field: { - int value; + int value = -1; opcode_bits *bit; - gen_entry *t; + gen_entry *t = NULL; /* Try to find a value for the - conditional by looking back through - the previously defined bits for the - specified conditional field */ - for (bit = bits; - bit != NULL; - bit = bit->next) + conditional by looking back through + the previously defined bits for one + that covers the designated + conditional field */ + for (bit = bits; bit != NULL; bit = bit->next) { - if (bit->field == condition->field - && (bit->last - bit->first + 1 == condition->field->width)) + if (bit->field->word_nr == + condition->field->word_nr + && bit->first <= condition->field->first + && bit->last >= condition->field->last) { /* the bit field fully specified - the conditional field's value */ + the conditional field's value */ value = sub_val (bit->value, bit->last, - first_pos, last_pos); - break; + condition->field-> + first, + condition->field-> + last); } } /* Try to find a value by looking - through this and previous tables */ + through this and previous tables */ if (bit == NULL) { for (t = table; - t->parent != NULL; - t = t->parent) + t->parent != NULL; t = t->parent) { - if (t->parent->opcode->word_nr != condition->field->word_nr) - continue; - if (t->parent->opcode->first <= condition->field->first - && t->parent->opcode->last >= condition->field->last) + if (t->parent->opcode->word_nr == + condition->field->word_nr + && t->parent->opcode->first <= + condition->field->first + && t->parent->opcode->last >= + condition->field->last) { /* the table entry fully - specified the condition - field's value */ - value = sub_val (t->opcode_nr, t->parent->opcode->last, - first_pos, last_pos); + specified the condition + field's value */ + /* extract the field's value + from the opcode */ + value = + sub_val (t->opcode_nr, + t->parent->opcode->last, + condition->field->first, + condition->field->last); + /* this is a requirement of + a conditonal field + refering to another field */ + ASSERT ((condition->field->first - + condition->field->last) == + (first_pos - last_pos)); + printf + ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n", + value, t->opcode_nr, + t->parent->opcode->last, + condition->field->first, + condition->field->last); } } } @@ -1063,25 +1007,26 @@ gen_entry_expand_opcode (gen_entry *table, if (!is_precluded) { /* Only add additional hardwired bit - information if the entry is not going to - later be combined */ + information if the entry is not going to + later be combined */ if (table->opcode_rule->with_combine) { gen_entry_expand_opcode (table, instruction, last_pos + 1, - ((opcode_nr << width) | val), - bits); + ((opcode_nr << width) | + val), bits); } else { - opcode_bits *new_bits = new_opcode_bits (bits, val, - first_pos, last_pos, - field, - table->opcode); + opcode_bits *new_bits = + new_opcode_bits (bits, val, + first_pos, last_pos, + field, + table->opcode); gen_entry_expand_opcode (table, instruction, last_pos + 1, - ((opcode_nr << width) | val), - new_bits); + ((opcode_nr << width) | + val), new_bits); } } } @@ -1092,28 +1037,24 @@ gen_entry_expand_opcode (gen_entry *table, } static void -gen_entry_insert_expanding (gen_entry *table, - insn_entry *instruction) +gen_entry_insert_expanding (gen_entry *table, insn_entry * instruction) { gen_entry_expand_opcode (table, instruction, - table->opcode->first, - 0, - table->expanded_bits); + table->opcode->first, 0, table->expanded_bits); } static int -insns_match_format_names (insn_list *insns, - filter *format_names) +insns_match_format_names (insn_list *insns, filter *format_names) { if (format_names != NULL) { insn_list *i; for (i = insns; i != NULL; i = i->next) { - if ( i->insn->format_name != NULL - && !filter_is_member (format_names, i->insn->format_name)) + if (i->insn->format_name != NULL + && !filter_is_member (format_names, i->insn->format_name)) return 0; } } @@ -1121,8 +1062,7 @@ insns_match_format_names (insn_list *insns, } static int -table_matches_path (gen_entry *table, - decode_path_list *paths) +table_matches_path (gen_entry *table, decode_path_list *paths) { if (paths == NULL) return 1; @@ -1148,8 +1088,7 @@ table_matches_path (gen_entry *table, static int -insns_match_conditions (insn_list *insns, - decode_cond *conditions) +insns_match_conditions (insn_list *insns, decode_cond *conditions) { if (conditions != NULL) { @@ -1169,8 +1108,7 @@ insns_match_conditions (insn_list *insns, if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask) return 0; if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value - == cond->value[bit_nr]) - == !cond->is_equal) + == cond->value[bit_nr]) == !cond->is_equal) return 0; } } @@ -1180,8 +1118,7 @@ insns_match_conditions (insn_list *insns, } static int -insns_match_nr_words (insn_list *insns, - int nr_words) +insns_match_nr_words (insn_list *insns, int nr_words) { insn_list *i; for (i = insns; i != NULL; i = i->next) @@ -1193,8 +1130,7 @@ insns_match_nr_words (insn_list *insns, } static int -insn_list_cmp (insn_list *l, - insn_list *r) +insn_list_cmp (insn_list *l, insn_list *r) { while (1) { @@ -1206,7 +1142,7 @@ insn_list_cmp (insn_list *l, if (r == NULL) return 1; if (l->insn != r->insn) - return -1; /* somewhat arbitrary at present */ + return -1; /* somewhat arbitrary at present */ /* skip this insn */ insn = l->insn; while (l != NULL && l->insn == insn) @@ -1223,12 +1159,11 @@ gen_entry_expand_insns (gen_entry *table) { decode_table *opcode_rule; - ASSERT(table->nr_insns >= 1); - + ASSERT (table->nr_insns >= 1); + /* determine a valid opcode */ for (opcode_rule = table->opcode_rule; - opcode_rule != NULL; - opcode_rule = opcode_rule->next) + opcode_rule != NULL; opcode_rule = opcode_rule->next) { char *discard_reason; if (table->top->model != NULL @@ -1242,17 +1177,19 @@ gen_entry_expand_insns (gen_entry *table) else if (table->nr_insns == 1 && opcode_rule->conditions == NULL) { /* for safety, require a pre-codition when attempting to - apply a rule to a single instruction */ + apply a rule to a single instruction */ discard_reason = "need pre-condition when nr-insn == 1"; } else if (table->nr_insns == 1 && !opcode_rule->with_duplicates) { /* Little point in expanding a single instruction when we're - not duplicating the semantic functions that this table - calls */ + not duplicating the semantic functions that this table + calls */ discard_reason = "need duplication with nr-insns == 1"; } - else if (!insns_match_format_names (table->insns, opcode_rule->format_names)) + else + if (!insns_match_format_names + (table->insns, opcode_rule->format_names)) { discard_reason = "wrong format name"; } @@ -1264,18 +1201,18 @@ gen_entry_expand_insns (gen_entry *table) { discard_reason = "path failed"; } - else if (!insns_match_conditions (table->insns, opcode_rule->conditions)) + else + if (!insns_match_conditions (table->insns, opcode_rule->conditions)) { discard_reason = "condition failed"; } else { discard_reason = "no opcode field"; - table->opcode = - gen_entry_find_opcode_field (table->insns, - opcode_rule, - table->nr_insns == 1/*string-only*/ - ); + table->opcode = gen_entry_find_opcode_field (table->insns, + opcode_rule, + table->nr_insns == 1 /*string-only */ + ); if (table->opcode != NULL) { table->opcode_rule = opcode_rule; @@ -1289,7 +1226,7 @@ gen_entry_expand_insns (gen_entry *table) notify (NULL, ": rule discarded - %s\n", discard_reason); } } - + /* did we find anything */ if (opcode_rule == NULL) { @@ -1309,7 +1246,8 @@ gen_entry_expand_insns (gen_entry *table) this table to function */ if (table->parent == NULL) table->nr_prefetched_words = table->opcode_rule->word_nr + 1; - else if (table->opcode_rule->word_nr + 1 > table->parent->nr_prefetched_words) + else if (table->opcode_rule->word_nr + 1 > + table->parent->nr_prefetched_words) table->nr_prefetched_words = table->opcode_rule->word_nr + 1; else table->nr_prefetched_words = table->parent->nr_prefetched_words; @@ -1317,7 +1255,7 @@ gen_entry_expand_insns (gen_entry *table) /* back link what we found to its parent */ if (table->parent != NULL) { - ASSERT(table->parent->opcode != NULL); + ASSERT (table->parent->opcode != NULL); table->opcode->parent = table->parent->opcode; } @@ -1332,8 +1270,7 @@ gen_entry_expand_insns (gen_entry *table) i2target (options.hi_bit_nr, table->opcode->last), i2target (options.hi_bit_nr, table->opcode_rule->first), i2target (options.hi_bit_nr, table->opcode_rule->last), - table->opcode->nr_opcodes, - table->nr_entries); + table->opcode->nr_opcodes, table->nr_entries); } /* expand the raw instructions according to the opcode */ @@ -1345,8 +1282,7 @@ gen_entry_expand_insns (gen_entry *table) { print_gen_entry_path (table->opcode_rule->line, table, notify); notify (NULL, ": expand - %s.%s\n", - entry->insn->format_name, - entry->insn->name); + entry->insn->format_name, entry->insn->name); } gen_entry_insert_expanding (table, entry->insn); } @@ -1361,14 +1297,13 @@ gen_entry_expand_insns (gen_entry *table) insn_list *l; print_gen_entry_path (table->opcode_rule->line, entry, notify); notify (NULL, ": %d - entries %d -", - entry->opcode_nr, - entry->nr_insns); + entry->opcode_nr, entry->nr_insns); for (l = entry->insns; l != NULL; l = l->next) notify (NULL, " %s.%s", l->insn->format_name, l->insn->name); notify (NULL, "\n"); } } - + /* perform a combine pass if needed */ if (table->opcode_rule->with_combine) { @@ -1402,9 +1337,9 @@ gen_entry_expand_insns (gen_entry *table) insn_list *l; gen_entry *duplicate; nr_unique++; - print_gen_entry_path (table->opcode_rule->line, entry, notify); - for (duplicate = entry->combined_next; - duplicate != NULL; + print_gen_entry_path (table->opcode_rule->line, entry, + notify); + for (duplicate = entry->combined_next; duplicate != NULL; duplicate = duplicate->combined_next) { notify (NULL, "+%d", duplicate->opcode_nr); @@ -1413,42 +1348,42 @@ gen_entry_expand_insns (gen_entry *table) for (l = entry->insns; l != NULL; l = l->next) { notify (NULL, " %s.%s", - l->insn->format_name, - l->insn->name); + l->insn->format_name, l->insn->name); } notify (NULL, "\n"); } } print_gen_entry_path (table->opcode_rule->line, table, notify); - notify (NULL, ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n", - table->opcode->word_nr, - i2target (options.hi_bit_nr, table->opcode->first), + notify (NULL, + ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n", + table->opcode->word_nr, i2target (options.hi_bit_nr, + table->opcode->first), i2target (options.hi_bit_nr, table->opcode->last), i2target (options.hi_bit_nr, table->opcode_rule->first), i2target (options.hi_bit_nr, table->opcode_rule->last), - table->opcode->nr_opcodes, - table->nr_entries, - nr_unique); + table->opcode->nr_opcodes, table->nr_entries, nr_unique); } } - + /* Check that the rule did more than re-arange the order of the instructions */ { - gen_entry *entry; - for (entry = table->entries; entry != NULL; entry = entry->sibling) - { - if (entry->combined_parent == NULL) - { - if (insn_list_cmp (table->insns, entry->insns) == 0) - { - print_gen_entry_path (table->opcode_rule->line, table, warning); - warning (NULL, ": Applying rule just copied all instructions\n"); - print_gen_entry_insns (entry, warning, "Copied", NULL); - error (NULL, ""); - } - } - } + gen_entry *entry; + for (entry = table->entries; entry != NULL; entry = entry->sibling) + { + if (entry->combined_parent == NULL) + { + if (insn_list_cmp (table->insns, entry->insns) == 0) + { + print_gen_entry_path (table->opcode_rule->line, table, + warning); + warning (NULL, + ": Applying rule just copied all instructions\n"); + print_gen_entry_insns (entry, warning, "Copied", NULL); + error (NULL, ""); + } + } + } } /* if some form of expanded table, fill in the missing dots */ @@ -1468,10 +1403,7 @@ gen_entry_expand_insns (gen_entry *table) if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr) { /* missing - insert it under our feet at *entry */ - gen_entry_insert_insn (table, - table->top->isa->illegal_insn, - table->opcode->word_nr, - 0, /* nr_prefetched_words == 0 for invalid */ + gen_entry_insert_insn (table, table->top->isa->illegal_insn, table->opcode->word_nr, 0, /* nr_prefetched_words == 0 for invalid */ opcode_nr, NULL); ASSERT ((*entry) != NULL); ASSERT ((*entry)->opcode_nr == opcode_nr); @@ -1483,7 +1415,7 @@ gen_entry_expand_insns (gen_entry *table) opcode_nr++; } /* oops, will have pointed the first illegal insn back to - its self. Fix this */ + its self. Fix this */ if (illegals != NULL) illegals->combined_parent = NULL; } @@ -1498,7 +1430,7 @@ gen_entry_expand_insns (gen_entry *table) expand entries that haven't been combined. */ { gen_entry *entry; - for (entry = table->entries; entry != NULL; entry = entry->sibling) + for (entry = table->entries; entry != NULL; entry = entry->sibling) { if (entry->combined_parent == NULL) { @@ -1524,12 +1456,9 @@ gen_tables_expand_insns (gen_table *gen) worked. */ static void -make_gen_semantics_list (lf *file, - gen_entry *entry, - int depth, - void *data) +make_gen_semantics_list (lf *file, gen_entry *entry, int depth, void *data) { - gen_table *gen = (gen_table*) data; + gen_table *gen = (gen_table *) data; insn_list *insn; /* Not interested in an entrie that have been combined into some other entry at the same level */ @@ -1559,14 +1488,12 @@ gen_tables_expand_semantics (gen_table *gen) gen_list *entry; for (entry = gen->tables; entry != NULL; entry = entry->next) { - gen_entry_traverse_tree (NULL, - entry->table, - 1, /* depth */ - NULL, /* start-handler */ - make_gen_semantics_list, /* leaf-handler */ - NULL, /* end-handler */ - gen); /* data */ - } + gen_entry_traverse_tree (NULL, entry->table, 1, /* depth */ + NULL, /* start-handler */ + make_gen_semantics_list, /* leaf-handler */ + NULL, /* end-handler */ + gen); /* data */ + } } @@ -1577,34 +1504,30 @@ gen_tables_expand_semantics (gen_table *gen) static void dump_opcode_field (lf *file, char *prefix, - opcode_field *field, - char *suffix, - int levels) + opcode_field *field, char *suffix, int levels) { lf_printf (file, "%s(opcode_field *) 0x%lx", prefix, (long) field); - if (levels && field != NULL) { - lf_indent (file, +1); - lf_printf (file, "\n(first %d)", field->first); - lf_printf (file, "\n(last %d)", field->last); - lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes); - lf_printf (file, "\n(is_boolean %d)", field->is_boolean); - lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant); - dump_opcode_field(file, "\n(parent ", field->parent, ")", levels - 1); - lf_indent (file, -1); - } + if (levels && field != NULL) + { + lf_indent (file, +1); + lf_printf (file, "\n(first %d)", field->first); + lf_printf (file, "\n(last %d)", field->last); + lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes); + lf_printf (file, "\n(is_boolean %d)", field->is_boolean); + lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant); + dump_opcode_field (file, "\n(parent ", field->parent, ")", levels - 1); + lf_indent (file, -1); + } lf_printf (file, "%s", suffix); } static void dump_opcode_bits (lf *file, - char *prefix, - opcode_bits *bits, - char *suffix, - int levels) + char *prefix, opcode_bits *bits, char *suffix, int levels) { lf_printf (file, "%s(opcode_bits *) 0x%lx", prefix, (long) bits); - + if (levels && bits != NULL) { lf_indent (file, +1); @@ -1620,28 +1543,25 @@ dump_opcode_bits (lf *file, static void -dump_insn_list (lf *file, - char *prefix, - insn_list *entry, - char *suffix) +dump_insn_list (lf *file, char *prefix, insn_list *entry, char *suffix) { lf_printf (file, "%s(insn_list *) 0x%lx", prefix, (long) entry); - if (entry != NULL) { - lf_indent (file, +1); - dump_insn_entry (file, "\n(insn ", entry->insn, ")"); - lf_printf (file, "\n(next 0x%lx)", (long) entry->next); - lf_indent (file, -1); - } + if (entry != NULL) + { + lf_indent (file, +1); + dump_insn_entry (file, "\n(insn ", entry->insn, ")"); + lf_printf (file, "\n(next 0x%lx)", (long) entry->next); + lf_indent (file, -1); + } lf_printf (file, "%s", suffix); } static void dump_insn_word_entry_list_entries (lf *file, - char *prefix, - insn_list *entry, - char *suffix) + char *prefix, + insn_list *entry, char *suffix) { lf_printf (file, "%s", prefix); while (entry != NULL) @@ -1655,39 +1575,37 @@ dump_insn_word_entry_list_entries (lf *file, static void dump_gen_entry (lf *file, - char *prefix, - gen_entry *table, - char *suffix, - int levels) + char *prefix, gen_entry *table, char *suffix, int levels) { lf_printf (file, "%s(gen_entry *) 0x%lx", prefix, (long) table); - if (levels && table != NULL) { - - lf_indent (file, +1); - lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr); - lf_printf (file, "\n(word_nr %d)", table->word_nr); - dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")", -1); - lf_printf (file, "\n(nr_insns %d)", table->nr_insns); - dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns, ")"); - dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")"); - dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0); - lf_printf (file, "\n(nr_entries %d)", table->nr_entries); - dump_gen_entry (file, "\n(entries ", table->entries, ")", table->nr_entries); - dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1); - dump_gen_entry (file, "\n(parent ", table->parent, ")", 0); - lf_indent (file, -1); - } + if (levels && table !=NULL) + { + + lf_indent (file, +1); + lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr); + lf_printf (file, "\n(word_nr %d)", table->word_nr); + dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")", + -1); + lf_printf (file, "\n(nr_insns %d)", table->nr_insns); + dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns, + ")"); + dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")"); + dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0); + lf_printf (file, "\n(nr_entries %d)", table->nr_entries); + dump_gen_entry (file, "\n(entries ", table->entries, ")", + table->nr_entries); + dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1); + dump_gen_entry (file, "\n(parent ", table->parent, ")", 0); + lf_indent (file, -1); + } lf_printf (file, "%s", suffix); } static void dump_gen_list (lf *file, - char *prefix, - gen_list *entry, - char *suffix, - int levels) + char *prefix, gen_list *entry, char *suffix, int levels) { while (entry != NULL) { @@ -1701,10 +1619,7 @@ dump_gen_list (lf *file, static void dump_gen_table (lf *file, - char *prefix, - gen_table *gen, - char *suffix, - int levels) + char *prefix, gen_table *gen, char *suffix, int levels) { lf_printf (file, "%s(gen_table *) 0x%lx", prefix, (long) gen); lf_printf (file, "\n(isa (insn_table *) 0x%lx)", (long) gen->isa); @@ -1717,8 +1632,7 @@ dump_gen_table (lf *file, igen_options options; int -main (int argc, - char **argv) +main (int argc, char **argv) { decode_table *decode_rules; insn_table *instructions; @@ -1726,16 +1640,17 @@ main (int argc, lf *l; if (argc != 7) - error (NULL, "Usage: insn \n"); + error (NULL, + "Usage: insn \n"); INIT_OPTIONS (options); filter_parse (&options.flags_filter, argv[1]); - options.hi_bit_nr = a2i(argv[2]); - options.insn_bit_size = a2i(argv[3]); - options.insn_specifying_widths = a2i(argv[4]); - ASSERT(options.hi_bit_nr < options.insn_bit_size); + options.hi_bit_nr = a2i (argv[2]); + options.insn_bit_size = a2i (argv[3]); + options.insn_specifying_widths = a2i (argv[4]); + ASSERT (options.hi_bit_nr < options.insn_bit_size); instructions = load_insn_table (argv[6], NULL); decode_rules = load_decode_table (argv[5]);