📄 ld-insn.c
字号:
new_insn_mnemonic->line = record->line; ASSERT (record->nr_fields > insn_mnemonic_format_field); new_insn_mnemonic->format = record->field[insn_mnemonic_format_field]; ASSERT (new_insn_mnemonic->format[0] == '"'); if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] != '"') error (new_insn_mnemonic->line, "Missing closing double quote in mnemonic field\n"); if (record->nr_fields > insn_mnemonic_condition_field) new_insn_mnemonic->condition = record->field[insn_mnemonic_condition_field]; new_insn_mnemonic->insn = insn; /* insert it */ last_insn_mnemonic = &insn->mnemonics; while ((*last_insn_mnemonic) != NULL) last_insn_mnemonic = &(*last_insn_mnemonic)->next; insn->nr_mnemonics++; *last_insn_mnemonic = new_insn_mnemonic;}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){ table *file = table_open (file_name); table_entry *record = table_read (file); insn_table *isa = ZALLOC (insn_table); model_table *model = ZALLOC (model_table); isa->model = model; isa->caches = cache; while (record != NULL) { switch (record_type (record)) { case include_record: { record = parse_include_record (file, record); break; } case option_record: { if (isa->insns != NULL) error (record->line, "Option after first instruction\n"); record = parse_option_record (file, record); break; } case string_function_record: { function_entry *function = NULL; record = parse_function_record (file, record, &isa->functions, &function, 0 /*is-internal */ , model); /* convert a string function record into an internal function */ if (function != NULL) { char *name = NZALLOC (char, (strlen ("str_") + strlen (function->name) + 1)); strcat (name, "str_"); strcat (name, function->name); function->name = name; function->type = "const char *"; } break; } case function_record: /* function record */ { record = parse_function_record (file, record, &isa->functions, NULL, 0 /*is-internal */ , model); break; } case internal_record: { /* only insert it into the function list if it is unknown */ function_entry *function = NULL; record = parse_function_record (file, record, &isa->functions, &function, 1 /*is-internal */ , model); /* check what was inserted to see if a pseudo-instruction entry also needs to be created */ if (function != NULL) { insn_entry **insn = NULL; if (strcmp (function->name, "illegal") == 0) { /* illegal function save it away */ if (isa->illegal_insn != NULL) { warning (function->line, "Multiple illegal instruction definitions\n"); error (isa->illegal_insn->line, "Location of first illegal instruction\n"); } else insn = &isa->illegal_insn; } if (insn != NULL) { *insn = ZALLOC (insn_entry); (*insn)->line = function->line; (*insn)->name = function->name; (*insn)->code = function->code; } } break; } case scratch_record: /* cache macro records */ case cache_record: case compute_record: { cache_entry *new_cache; /* parse the cache record */ if (record->nr_fields < nr_cache_fields) error (record->line, "Incorrect nr of fields for scratch/cache/compute record\n"); /* create it */ new_cache = ZALLOC (cache_entry); new_cache->line = record->line; filter_parse (&new_cache->flags, record->field[record_filter_flags_field]); filter_parse (&new_cache->models, record->field[record_filter_models_field]); new_cache->type = record->field[cache_typedef_field]; new_cache->name = record->field[cache_name_field]; filter_parse (&new_cache->original_fields, record->field[cache_original_fields_field]); new_cache->expression = record->field[cache_expression_field]; /* insert it but only if not filtered out */ if (!filter_is_subset (options.flags_filter, new_cache->flags)) { notify (new_cache->line, "Discarding cache entry %s - filter flags\n", new_cache->name); } else if (is_filtered_out (options.model_filter, record-> field[record_filter_models_field])) { notify (new_cache->line, "Discarding cache entry %s - filter models\n", new_cache->name); } else { cache_entry **last; last = &isa->caches; while (*last != NULL) last = &(*last)->next; *last = new_cache; } /* advance things */ record = table_read (file); break; } /* model records */ case model_processor_record: { model_entry *new_model; /* parse the model */ if (record->nr_fields < nr_model_processor_fields) error (record->line, "Incorrect nr of fields for model record\n"); if (isa->insns != NULL) error (record->line, "Model appears after first instruction\n"); new_model = ZALLOC (model_entry); filter_parse (&new_model->flags, record->field[record_filter_flags_field]); new_model->line = record->line; new_model->name = record->field[model_name_field]; new_model->full_name = record->field[model_full_name_field]; new_model->unit_data = record->field[model_unit_data_field]; /* only insert it if not filtered out */ if (!filter_is_subset (options.flags_filter, new_model->flags)) { notify (new_model->line, "Discarding processor model %s - filter flags\n", new_model->name); } else if (is_filtered_out (options.model_filter, record-> field[record_filter_models_field])) { notify (new_model->line, "Discarding processor model %s - filter models\n", new_model->name); } else if (filter_is_member (model->processors, new_model->name)) { error (new_model->line, "Duplicate processor model %s\n", new_model->name); } else { model_entry **last; last = &model->models; while (*last != NULL) last = &(*last)->next; *last = new_model; /* count it */ model->nr_models++; filter_parse (&model->processors, new_model->name); } /* advance things */ record = table_read (file); } break; case model_macro_record: record = parse_model_data_record (isa, file, record, nr_model_macro_fields, &model->macros); break; case model_data_record: record = parse_model_data_record (isa, file, record, nr_model_data_fields, &model->data); break; case model_static_record: record = parse_function_record (file, record, &model->statics, NULL, 0 /*is internal */ , model); break; case model_internal_record: record = parse_function_record (file, record, &model->internals, NULL, 1 /*is internal */ , model); break; case model_function_record: record = parse_function_record (file, record, &model->functions, NULL, 0 /*is internal */ , model); break; case insn_record: /* instruction records */ { insn_entry *new_insn; char *format; /* parse the instruction */ if (record->nr_fields < nr_insn_fields) error (record->line, "Incorrect nr of fields for insn record\n"); new_insn = ZALLOC (insn_entry); new_insn->line = record->line; filter_parse (&new_insn->flags, record->field[record_filter_flags_field]); /* save the format field. Can't parse it until after the filter-out checks. Could be filtered out because the format is invalid */ format = record->field[insn_word_field]; new_insn->format_name = record->field[insn_format_name_field]; if (options.format_name_filter != NULL && !filter_is_member (options.format_name_filter, new_insn->format_name)) error (new_insn->line, "Unreconized instruction format name `%s'\n", new_insn->format_name); filter_parse (&new_insn->options, record->field[insn_options_field]); new_insn->name = record->field[insn_name_field]; record = table_read (file); /* Parse any model/assember records */ new_insn->nr_models = model->nr_models; new_insn->model = NZALLOC (insn_model_entry *, model->nr_models + 1); while (record != NULL) { if (record_prefix_is (record, '*', nr_insn_model_fields)) parse_insn_model_record (file, record, new_insn, model); else if (record_prefix_is (record, '"', nr_insn_mnemonic_fields)) parse_insn_mnemonic_record (file, record, new_insn); else break; /* advance */ record = table_read (file); } /* Parse the code record */ if (record != NULL && record->type == table_code_entry) { new_insn->code = record; record = table_read (file); } else if (options.warn.unimplemented) notify (new_insn->line, "unimplemented\n"); /* insert it */ if (!filter_is_subset (options.flags_filter, new_insn->flags)) { if (options.warn.discard) notify (new_insn->line, "Discarding instruction %s (flags-filter)\n", new_insn->name); } else if (new_insn->processors != NULL && options.model_filter != NULL && !filter_is_common (options.model_filter, new_insn->processors)) { /* only discard an instruction based in the processor model when both the instruction and the options are nonempty */ if (options.warn.discard) notify (new_insn->line, "Discarding instruction %s (processor-model)\n", new_insn->name); } else { insn_entry **last; /* finish the parsing */ parse_insn_words (new_insn, format); /* append it */ last = &isa->insns; while (*last) last = &(*last)->next; *last = new_insn; /* update global isa counters */ isa->nr_insns++; if (isa->max_nr_words < new_insn->nr_words) isa->max_nr_words = new_insn->nr_words; filter_add (&isa->flags, new_insn->flags); filter_add (&isa->options, new_insn->options); } break; } case define_record: record = parse_macro_record (file, record); break; case unknown_record: case code_record: error (record->line, "Unknown or unexpected entry\n"); } } return isa;}voidprint_insn_words (lf *file, insn_entry * insn){ insn_word_entry *word = insn->words; if (word != NULL) { while (1) { insn_field_entry *field = word->first; while (1) { if (options.insn_specifying_widths) lf_printf (file, "%d.", field->width); else 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; case insn_field_reserved: lf_printf (file, "/"); break; case insn_field_wild: lf_printf (file, "*"); break; case insn_field_string: lf_printf (file, "%s", field->val_string); break; } if (field == word->last) break; field = field->next; lf_printf (file, ","); } word = word->next; if (word == NULL) break; lf_printf (file, "+"); } }}voidfunction_entry_traverse (lf *file, function_entry * functions, function_entry_handler * handler, void *data){ function_entry *function; for (function = functions; function != NULL; function = function->next) { handler (file, function, data); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -