📄 ld-insn.c
字号:
if (f->width != refered_field->width) error (insn->line, "Conditional `%s' of field `%s' should be of size %s\n", cond->string, f->val_string, refered_field->width); } } } if (cond->field == NULL) error (insn->line, "Conditional `%s' of field `%s' not yet defined\n", cond->string, f->val_string); } } } } }}typedef enum{ unknown_record = 0, insn_record, /* default */ code_record, cache_record, compute_record, scratch_record, option_record, string_function_record, function_record, internal_record, define_record, include_record, model_processor_record, model_macro_record, model_data_record, model_static_record, model_function_record, model_internal_record,}insn_record_type;static const name_map insn_type_map[] = { {"option", option_record}, {"cache", cache_record}, {"compute", compute_record}, {"scratch", scratch_record}, {"define", define_record}, {"include", include_record}, {"%s", string_function_record}, {"function", function_record}, {"internal", internal_record}, {"model", model_processor_record}, {"model-macro", model_macro_record}, {"model-data", model_data_record}, {"model-static", model_static_record}, {"model-internal", model_internal_record}, {"model-function", model_function_record}, {NULL, insn_record},};static intrecord_is_old (table_entry *entry){ if (entry->nr_fields > record_type_field && strlen (entry->field[record_type_field]) == 0) return 1; return 0;}static insn_record_typerecord_type (table_entry *entry){ switch (entry->type) { case table_code_entry: return code_record; case table_colon_entry: if (record_is_old (entry)) { /* old-format? */ if (entry->nr_fields > old_record_type_field) { int i = name2i (entry->field[old_record_type_field], insn_type_map); return i; } else { return unknown_record; } } else if (entry->nr_fields > record_type_field && entry->field[0][0] == '\0') { /* new-format? */ int i = name2i (entry->field[record_type_field], insn_type_map); return i; } else return insn_record; /* default */ } return unknown_record;}static intrecord_prefix_is (table_entry *entry, char ch, int nr_fields){ if (entry->type != table_colon_entry) return 0; if (entry->nr_fields < nr_fields) return 0; if (entry->field[0][0] != ch && ch != '\0') return 0; return 1;}static table_entry *parse_model_data_record (insn_table *isa, table *file, table_entry *record, int nr_fields, model_data **list){ table_entry *model_record = record; table_entry *code_record = NULL; model_data *new_data; if (record->nr_fields < nr_fields) error (record->line, "Incorrect number of fields\n"); record = table_read (file); if (record->type == table_code_entry) { code_record = record; record = table_read (file); } /* create the new data record */ new_data = ZALLOC (model_data); new_data->line = model_record->line; filter_parse (&new_data->flags, model_record->field[record_filter_flags_field]); new_data->entry = model_record; new_data->code = code_record; /* append it if not filtered out */ if (!is_filtered_out (options.flags_filter, model_record->field[record_filter_flags_field]) && !is_filtered_out (options.model_filter, model_record->field[record_filter_models_field])) { while (*list != NULL) list = &(*list)->next; *list = new_data; } return record;}typedef enum{ insn_bit_size_option = 1, insn_specifying_widths_option, hi_bit_nr_option, flags_filter_option, model_filter_option, multi_sim_option, format_names_option, gen_delayed_branch, unknown_option,}option_names;static const name_map option_map[] = { {"insn-bit-size", insn_bit_size_option}, {"insn-specifying-widths", insn_specifying_widths_option}, {"hi-bit-nr", hi_bit_nr_option}, {"flags-filter", flags_filter_option}, {"model-filter", model_filter_option}, {"multi-sim", multi_sim_option}, {"format-names", format_names_option}, {"gen-delayed-branch", gen_delayed_branch}, {NULL, unknown_option},};static table_entry *parse_include_record (table *file, table_entry *record){ /* parse the include record */ if (record->nr_fields < nr_include_fields) error (record->line, "Incorrect nr fields for include 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_push (file, record->line, options.include, record->field[include_filename_field]); } /* nb: can't read next record until after the file has been pushed */ record = table_read (file); return record;}static table_entry *parse_option_record (table *file, table_entry *record){ table_entry *option_record; /* parse the option record */ option_record = record; if (record->nr_fields < nr_option_fields) error (record->line, "Incorrect nr of fields for option record\n"); record = table_read (file); /* process it */ if (!is_filtered_out (options.flags_filter, option_record->field[record_filter_flags_field]) && !is_filtered_out (options.model_filter, option_record->field[record_filter_models_field])) { char *name = option_record->field[option_name_field]; option_names option = name2i (name, option_map); char *value = option_record->field[option_value_field]; switch (option) { case insn_bit_size_option: { options.insn_bit_size = a2i (value); if (options.insn_bit_size < 0 || options.insn_bit_size > max_insn_bit_size) error (option_record->line, "Instruction bit size out of range\n"); if (options.hi_bit_nr != options.insn_bit_size - 1 && options.hi_bit_nr != 0) error (option_record->line, "insn-bit-size / hi-bit-nr conflict\n"); break; } case insn_specifying_widths_option: { options.insn_specifying_widths = a2i (value); break; } case hi_bit_nr_option: { options.hi_bit_nr = a2i (value); if (options.hi_bit_nr != 0 && options.hi_bit_nr != options.insn_bit_size - 1) error (option_record->line, "hi-bit-nr / insn-bit-size conflict\n"); break; } case flags_filter_option: { filter_parse (&options.flags_filter, value); break; } case model_filter_option: { filter_parse (&options.model_filter, value); break; } case multi_sim_option: { options.gen.multi_sim = a2i (value); break; } case format_names_option: { filter_parse (&options.format_name_filter, value); break; } case gen_delayed_branch: { options.gen.delayed_branch = a2i (value); break; } case unknown_option: { error (option_record->line, "Unknown option - %s\n", name); break; } } } return record;}static table_entry *parse_function_record (table *file, table_entry *record, function_entry ** list, function_entry ** list_entry, int is_internal, model_table *model){ function_entry *new_function; new_function = ZALLOC (function_entry); new_function->line = record->line; new_function->is_internal = is_internal; /* parse the function header */ if (record_is_old (record)) { if (record->nr_fields < nr_old_function_fields) error (record->line, "Missing fields from (old) function record\n"); new_function->type = record->field[old_function_typedef_field]; new_function->type = record->field[old_function_typedef_field]; if (record->nr_fields > old_function_param_field) new_function->param = record->field[old_function_param_field]; new_function->name = record->field[old_function_name_field]; } else { if (record->nr_fields < nr_function_fields) error (record->line, "Missing fields from function record\n"); filter_parse (&new_function->flags, record->field[record_filter_flags_field]); filter_parse (&new_function->models, record->field[record_filter_models_field]); new_function->type = record->field[function_typedef_field]; new_function->param = record->field[function_param_field]; new_function->name = record->field[function_name_field]; } record = table_read (file); /* parse any function-model records */ while (record != NULL && record_prefix_is (record, '*', nr_function_model_fields)) { 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 */ if (record->type == table_code_entry) { new_function->code = record; record = table_read (file); } /* insert it */ if (!filter_is_subset (options.flags_filter, new_function->flags)) { if (options.warn.discard) notify (new_function->line, "Discarding function %s - filter flags\n", new_function->name); } 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 %s - filter models\n", new_function->name); } else { while (*list != NULL) list = &(*list)->next; *list = new_function; if (list_entry != NULL) *list_entry = new_function; } /* done */ return record;}static voidparse_insn_model_record (table *file, table_entry *record, insn_entry * insn, model_table *model){ insn_model_entry **last_insn_model; insn_model_entry *new_insn_model = ZALLOC (insn_model_entry); /* parse it */ new_insn_model->line = record->line; if (record->nr_fields > insn_model_unit_data_field) new_insn_model->unit_data = record->field[insn_model_unit_data_field]; new_insn_model->insn = insn; /* parse the model names, verify that all were defined */ new_insn_model->names = NULL; filter_parse (&new_insn_model->names, record->field[insn_model_name_field] + 1 /*skip `*' */ ); if (new_insn_model->names == NULL) { /* No processor names - a generic model entry, enter it into all the non-empty fields */ int index; for (index = 0; index < model->nr_models; index++) if (insn->model[index] == 0) { insn->model[index] = new_insn_model; } /* also add the complete processor set to this processor's set */ filter_add (&insn->processors, model->processors); } else { /* Find the corresponding master model record for each name so that they can be linked in. */ int index; char *name = ""; while (1) { name = filter_next (new_insn_model->names, name); if (name == NULL) break; index = filter_is_member (model->processors, name) - 1; if (index < 0) { error (new_insn_model->line, "machine model `%s' undefined\n", name); } /* store it in the corresponding model array entry */ if (insn->model[index] != NULL && insn->model[index]->names != NULL) { warning (new_insn_model->line, "machine model `%s' previously defined\n", name); error (insn->model[index]->line, "earlier definition\n"); } insn->model[index] = new_insn_model; /* also add the name to the instructions processor set as an alternative lookup mechanism */ filter_parse (&insn->processors, name); } }#if 0 /* for some reason record the max length of any function unit field */ int len = strlen (insn_model_ptr->field[insn_model_fields]); if (model->max_model_fields_len < len) model->max_model_fields_len = len;#endif /* link it in */ last_insn_model = &insn->models; while ((*last_insn_model) != NULL) last_insn_model = &(*last_insn_model)->next; *last_insn_model = new_insn_model;}static voidparse_insn_mnemonic_record (table *file, table_entry *record, insn_entry * insn){ insn_mnemonic_entry **last_insn_mnemonic; insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry); /* parse it */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -