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

📄 gen.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
      }    (*cur_insn_ptr) = new_insn;  }  *nr_insns += 1;  return (*cur_insn_ptr);}extern voidgen_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 *entry;  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)    {      if (entry->entries != NULL && depth != 0)	{	  gen_entry_traverse_tree (file, entry, depth + 1,				   start, leaf, end, data);	}      else if (depth >= 0)	{	  if (leaf != NULL)	    {	      leaf (file, entry, depth, data);	    }	}    }  /* postfix */  if (end != NULL && depth >= 0)    {      end (file, table, depth, data);    }}/* create a list element containing a single gen_table entry */static gen_list *make_table (insn_table *isa, decode_table *rules, model_entry *model){  insn_entry *insn;  gen_list *entry = ZALLOC (gen_list);  entry->table = ZALLOC (gen_entry);  entry->table->top = entry;  entry->model = model;  entry->isa = isa;  for (insn = isa->insns; insn != NULL; insn = insn->next)    {      if (model == NULL	  || 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 */			    report_duplicate_insns);	}    }  entry->table->opcode_rule = rules;  return entry;}gen_table *make_gen_tables (insn_table *isa, decode_table *rules){  gen_table *gen = ZALLOC (gen_table);  gen->isa = isa;  gen->rules = rules;  if (options.gen.multi_sim)    {      gen_list **last = &gen->tables;      model_entry *model;      filter *processors;      if (options.model_filter != NULL)	processors = options.model_filter;      else	processors = isa->model->processors;      for (model = isa->model->models; model != NULL; model = model->next)	{	  if (filter_is_member (processors, model->name))	    {	      *last = make_table (isa, rules, model);	      last = &(*last)->next;	    }	}    }  else    {      gen->tables = make_table (isa, rules, NULL);    }  return gen;}/****************************************************************/#if 0typedef enum{  field_is_not_constant = 0,  field_constant_int = 1,  field_constant_reserved = 2,  field_constant_string = 3}constant_field_types;static constant_field_typesinsn_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 intinsns_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 */  /* 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 */	  break;	case insn_field_int:	  switch (rule->search)	    {	    case decode_find_strings:	      /* an integer isn't a string */	      return 1;	    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. */	      if (value < 0)		value = bit->value;	      else if (value != bit->value)		is_useless = 0;	      break;	    }	  break;	case insn_field_string:	  switch (rule->search)	    {	    case decode_find_strings:	      /* at least one string, keep checking */	      is_useless = 0;	      break;	    case decode_find_constants:	    case decode_find_mixed:	      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 */		return 1;	      break;	    }	}    }  /* 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)			{			  switch (condition->type)			    {			    case insn_field_cond_value:			      switch (condition->test)				{				case insn_field_cond_ne:				  if (((condition->value >> shift) & 1)				      == (unsigned) value)				    /* conditional field excludes the				       current value */				    is_useless = 0;				  break;				case insn_field_cond_eq:				  if (((condition->value >> shift) & 1)				      != (unsigned) 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;}/* go through a gen-table's list of instruction formats looking for a   range of bits that meet the decode table RULEs requirements */static opcode_field *gen_entry_find_opcode_field (insn_list *insns,			     decode_table *rule, int string_only){  opcode_field curr_opcode;  ASSERT (rule != NULL);  memset (&curr_opcode, 0, sizeof (curr_opcode));  curr_opcode.word_nr = rule->word_nr;  curr_opcode.first = rule->first;  curr_opcode.last = rule->last;  /* Try to reduce the size of first..last in accordance with the     decode rules */  while (curr_opcode.first <= rule->last)    {      if (insns_bit_useless (insns, rule, 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--;      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)    {      return NULL;    }  ASSERT (curr_opcode.last >= rule->first);  ASSERT (curr_opcode.first <= rule->last);  ASSERT (curr_opcode.first <= curr_opcode.last);  /* 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)    {      curr_opcode.first = rule->force_first;    }  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)    {      curr_opcode.last = options.insn_bit_size - 1;    }  /* handle any special cases */  switch (rule->type)    {    case normal_decode_rule:      /* let the above apply */      curr_opcode.nr_opcodes =	(1 << (curr_opcode.last - curr_opcode.first + 1));      break;    case boolean_rule:      curr_opcode.is_boolean = 1;      curr_opcode.boolean_constant = rule->constant;      curr_opcode.nr_opcodes = 2;      break;    }  {    opcode_field *new_field = ZALLOC (opcode_field);    memcpy (new_field, &curr_opcode, sizeof (opcode_field));

⌨️ 快捷键说明

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