⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ld-insn.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  This file is part of the program psim.    Copyright 1994, 1995, 1996, 2003 Andrew Cagney    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.    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.     */#include "misc.h"#include "lf.h"#include "table.h"#include "filter.h"#include "ld-decode.h"#include "ld-cache.h"#include "ld-insn.h"#include "igen.h"static voidupdate_depth(insn_table *entry,	     lf *file,	     void *data,	     insn *instruction,	     int depth){  int *max_depth = (int*)data;  if (*max_depth < depth)    *max_depth = depth;}intinsn_table_depth(insn_table *table){  int depth = 0;  insn_table_traverse_tree(table,			   NULL,			   &depth,			   1,			   NULL, /*start*/			   update_depth,			   NULL, /*end*/			   NULL); /*padding*/  return depth;}static insn_fields *parse_insn_format(table_entry *entry,		  char *format){  char *chp;  insn_fields *fields = ZALLOC(insn_fields);  /* create a leading sentinal */  fields->first = ZALLOC(insn_field);  fields->first->first = -1;  fields->first->last = -1;  fields->first->width = 0;  /* and a trailing sentinal */  fields->last = ZALLOC(insn_field);  fields->last->first = insn_bit_size;  fields->last->last = insn_bit_size;  fields->last->width = 0;  /* link them together */  fields->first->next = fields->last;  fields->last->prev = fields->first;  /* now work through the formats */  chp = format;  while (*chp != '\0') {    char *start_pos;    char *start_val;    int strlen_val;    int strlen_pos;    insn_field *new_field;    /* sanity check */    if (!isdigit(*chp)) {      error("%s:%d: missing position field at `%s'\n",	    entry->file_name, entry->line_nr, chp);    }    /* break out the bit position */    start_pos = chp;    while (isdigit(*chp))      chp++;    strlen_pos = chp - start_pos;    if (*chp == '.' && strlen_pos > 0)      chp++;    else {      error("%s:%d: missing field value at %s\n",	    entry->file_name, entry->line_nr, chp);      break;    }    /* break out the value */    start_val = chp;    while ((*start_val == '/' && *chp == '/')	   || (isdigit(*start_val) && isdigit(*chp))	   || (isalpha(*start_val) && (isalnum(*chp) || *chp == '_')))      chp++;    strlen_val = chp - start_val;    if (*chp == ',')      chp++;    else if (*chp != '\0' || strlen_val == 0) {      error("%s:%d: missing field terminator at %s\n",	    entry->file_name, entry->line_nr, chp);      break;    }    /* create a new field and insert it */    new_field = ZALLOC(insn_field);    new_field->next = fields->last;    new_field->prev = fields->last->prev;    new_field->next->prev = new_field;    new_field->prev->next = new_field;    /* the value */    new_field->val_string = (char*)zalloc(strlen_val+1);    strncpy(new_field->val_string, start_val, strlen_val);    if (isdigit(*new_field->val_string)) {      new_field->val_int = a2i(new_field->val_string);      new_field->is_int = 1;    }    else if (new_field->val_string[0] == '/') {      new_field->is_slash = 1;    }    else {      new_field->is_string = 1;    }        /* the pos */    new_field->pos_string = (char*)zalloc(strlen_pos+1);    strncpy(new_field->pos_string, start_pos, strlen_pos);    new_field->first = target_a2i(hi_bit_nr, new_field->pos_string);    new_field->last = new_field->next->first - 1; /* guess */    new_field->width = new_field->last - new_field->first + 1; /* guess */    new_field->prev->last = new_field->first-1; /*fix*/    new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/  }  /* fiddle first/last so that the sentinals `disapear' */  ASSERT(fields->first->last < 0);  ASSERT(fields->last->first >= insn_bit_size);  fields->first = fields->first->next;  fields->last = fields->last->prev;  /* now go over this again, pointing each bit position at a field     record */  {    int i;    insn_field *field;    field = fields->first;    for (i = 0; i < insn_bit_size; i++) {      while (field->last < i)	field = field->next;      fields->bits[i] = field;    }  }  /* go over each of the fields, and compute a `value' for the insn */  {    insn_field *field;    fields->value = 0;    for (field = fields->first;	 field->last < insn_bit_size;	 field = field->next) {      fields->value <<= field->width;      if (field->is_int)	fields->value |= field->val_int;    }  }  return fields;}voidparse_include_entry (table *file,                     table_entry *file_entry,		     filter *filters,		     table_include *includes){  /* parse the include file_entry */  if (file_entry->nr_fields < 4)    error ("Incorrect nr fields for include record\n");  /* process it */  if (!is_filtered_out(file_entry->fields[include_flags], filters))    {      table_push (file, includes,                file_entry->fields[include_path],		file_entry->nr_fields, file_entry->nr_fields);    }}static voidmodel_table_insert(insn_table *table,		   table_entry *file_entry){  int len;  /* create a new model */  model *new_model = ZALLOC(model);  new_model->name = file_entry->fields[model_identifer];  new_model->printable_name = file_entry->fields[model_name];  new_model->insn_default = file_entry->fields[model_default];  while (*new_model->insn_default && isspace(*new_model->insn_default))    new_model->insn_default++;  len = strlen(new_model->insn_default);  if (max_model_fields_len < len)    max_model_fields_len = len;  /* append it to the end of the model list */  if (last_model)    last_model->next = new_model;  else    models = new_model;  last_model = new_model;}static voidmodel_table_insert_specific(insn_table *table,			    table_entry *file_entry,			    insn **start_ptr,			    insn **end_ptr){  insn *ptr = ZALLOC(insn);  ptr->file_entry = file_entry;  if (*end_ptr)    (*end_ptr)->next = ptr;  else    (*start_ptr) = ptr;  (*end_ptr) = ptr;}static voidinsn_table_insert_function(insn_table *table,			   table_entry *file_entry){  /* create a new function */  insn *new_function = ZALLOC(insn);  new_function->file_entry = file_entry;  /* append it to the end of the function list */  if (table->last_function)    table->last_function->next = new_function;  else    table->functions = new_function;  table->last_function = new_function;}extern voidinsn_table_insert_insn(insn_table *table,		       table_entry *file_entry,		       insn_fields *fields){  insn **ptr_to_cur_insn = &table->insns;  insn *cur_insn = *ptr_to_cur_insn;  table_model_entry *insn_model_ptr;  model *model_ptr;  /* create a new instruction */  insn *new_insn = ZALLOC(insn);  new_insn->file_entry = file_entry;  new_insn->fields = fields;  /* Check out any model information returned to make sure the model     is correct.  */  for(insn_model_ptr = file_entry->model_first; insn_model_ptr; insn_model_ptr = insn_model_ptr->next) {    char *name = insn_model_ptr->fields[insn_model_name];    int len = strlen (insn_model_ptr->fields[insn_model_fields]);    while (len > 0 && isspace(*insn_model_ptr->fields[insn_model_fields])) {      len--;      insn_model_ptr->fields[insn_model_fields]++;    }    if (max_model_fields_len < len)      max_model_fields_len = len;    for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {      if (strcmp(name, model_ptr->printable_name) == 0) {	/* Replace the name field with that of the global model, so that when we	   want to print it out, we can just compare pointers.  */	insn_model_ptr->fields[insn_model_name] = model_ptr->printable_name;	break;      }    }    if (!model_ptr)      error("%s:%d: machine model `%s' was not known about\n",	    file_entry->file_name, file_entry->line_nr, name);  }  /* insert it according to the order of the fields */  while (cur_insn != NULL	 && new_insn->fields->value >= cur_insn->fields->value) {    ptr_to_cur_insn = &cur_insn->next;    cur_insn = *ptr_to_cur_insn;  }  new_insn->next = cur_insn;  *ptr_to_cur_insn = new_insn;  table->nr_insn++;}insn_table *load_insn_table(const char *file_name,		decode_table *decode_rules,		filter *filters,		table_include *includes,		cache_table **cache_rules){  table *file = table_open(file_name, nr_insn_table_fields, nr_insn_model_table_fields);  insn_table *table = ZALLOC(insn_table);  table_entry *file_entry;  table->opcode_rule = decode_rules;  while ((file_entry = table_entry_read(file)) != NULL) {    if (it_is("function", file_entry->fields[insn_flags])	|| it_is("internal", file_entry->fields[insn_flags])) {      insn_table_insert_function(table, file_entry);    }    else if ((it_is("function", file_entry->fields[insn_form])	      || it_is("internal", file_entry->fields[insn_form]))	     && !is_filtered_out(file_entry->fields[insn_flags], filters)) {      /* Ok, this is evil.  Need to convert a new style function into         an old style function.  Construct an old style table and then         copy it back.  */      char *fields[nr_insn_table_fields];      memset (fields, 0, sizeof fields);      fields[insn_flags] = file_entry->fields[insn_form];      fields[function_type] = file_entry->fields[insn_name];      fields[function_name] = file_entry->fields[insn_comment];      fields[function_param] = file_entry->fields[insn_field_6];      memcpy (file_entry->fields, fields,	      sizeof (fields[0]) * file_entry->nr_fields);      insn_table_insert_function(table, file_entry);#if 0      ":" "..."       ":" <filter-flags>       ":" <filter-models>       ":" <typedef>       ":" <name>       [ ":" <parameter-list> ]       <nl>       [ <function-model> ]       <code-block>#endif    }	         else if (it_is("model", file_entry->fields[insn_flags])) {      model_table_insert(table, file_entry);    }    else if (it_is("model-macro", file_entry->fields[insn_flags])) {      model_table_insert_specific(table, file_entry, &model_macros, &last_model_macro);    }    else if (it_is("model-function", file_entry->fields[insn_flags])) {      model_table_insert_specific(table, file_entry, &model_functions, &last_model_function);    }    else if (it_is("model-internal", file_entry->fields[insn_flags])) {      model_table_insert_specific(table, file_entry, &model_internal, &last_model_internal);    }    else if (it_is("model-static", file_entry->fields[insn_flags])) {      model_table_insert_specific(table, file_entry, &model_static, &last_model_static);    }    else if (it_is("model-data", file_entry->fields[insn_flags])) {      model_table_insert_specific(table, file_entry, &model_data, &last_model_data);    }    else if (it_is("include", file_entry->fields[insn_form])             && !is_filtered_out(file_entry->fields[insn_flags], filters)) {      parse_include_entry (file, file_entry, filters, includes);    }    else if ((it_is("cache", file_entry->fields[insn_form])	      || it_is("compute", file_entry->fields[insn_form])	      || it_is("scratch", file_entry->fields[insn_form]))	     && !is_filtered_out(file_entry->fields[insn_flags], filters)) {      append_cache_rule (cache_rules,			 file_entry->fields[insn_form], /* type */			 file_entry->fields[cache_name],			 file_entry->fields[cache_derived_name],			 file_entry->fields[cache_type_def],			 file_entry->fields[cache_expression],			 file_entry);    }    else {      insn_fields *fields;      /* skip instructions that aren't relevant to the mode */      if (is_filtered_out(file_entry->fields[insn_flags], filters)) {	fprintf(stderr, "Dropping %s - %s\n",		file_entry->fields[insn_name],		file_entry->fields[insn_flags]);      }      else {	/* create/insert the new instruction */	fields = parse_insn_format(file_entry,				   file_entry->fields[insn_format]);	insn_table_insert_insn(table, file_entry, fields);      }    }  }  return table;}extern voidinsn_table_traverse_tree(insn_table *table,			 lf *file,			 void *data,			 int depth,			 leaf_handler *start,			 insn_handler *leaf,			 leaf_handler *end,			 padding_handler *padding){  insn_table *entry;  int entry_nr;    ASSERT(table != NULL	 && table->opcode != NULL	 && table->nr_entries > 0	 && table->entries != 0);  if (start != NULL && depth >= 0)    start(table, file, data, depth);  for (entry_nr = 0, entry = table->entries;       entry_nr < (table->opcode->is_boolean		   ? 2		   : (1 << (table->opcode->last - table->opcode->first + 1)));       entry_nr ++) {    if (entry == NULL	|| (!table->opcode->is_boolean	    && entry_nr < entry->opcode_nr)) {      if (padding != NULL && depth >= 0)	padding(table, file, data, depth, entry_nr);    }    else {      ASSERT(entry != NULL && (entry->opcode_nr == entry_nr			       || table->opcode->is_boolean));      if (entry->opcode != NULL && depth != 0) {	insn_table_traverse_tree(entry, file, data, depth+1,				 start, leaf, end, padding);      }      else if (depth >= 0) {	if (leaf != NULL)	  leaf(entry, file, data, entry->insns, depth);      }      entry = entry->sibling;    }  }  if (end != NULL && depth >= 0)    end(table, file, data, depth);}extern voidinsn_table_traverse_function(insn_table *table,			     lf *file,			     void *data,			     function_handler *leaf){  insn *function;  for (function = table->functions;       function != NULL;       function = function->next) {    leaf(table, file, data, function->file_entry);  }}extern voidinsn_table_traverse_insn(insn_table *table,			 lf *file,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -