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

📄 gen.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    return new_field;  }}static voidgen_entry_insert_insn (gen_entry *table,		       insn_entry * old_insn,		       int new_word_nr,		       int new_nr_prefetched_words,		       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 */      gen_entry *new_entry = ZALLOC (gen_entry);      new_entry->sibling = (*entry);      (*entry) = new_entry;      table->nr_entries++;      /* fill it in */      new_entry->top = table->top;      new_entry->opcode_nr = new_opcode_nr;      new_entry->word_nr = new_word_nr;      new_entry->expanded_bits = new_bits;      new_entry->opcode_rule = table->opcode_rule->next;      new_entry->parent = table;      new_entry->nr_prefetched_words = new_nr_prefetched_words;    }  /* 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 */		    report_duplicate_insns);}static voidgen_entry_expand_opcode (gen_entry *table,			 insn_entry * instruction,			 int bit_nr, int opcode_nr, opcode_bits *bits){  if (bit_nr > table->opcode->last)    {      /* Only include the hardwired bit information with an entry IF         that entry (and hence its functions) are being duplicated.  */      if (options.trace.insn_expansion)	{	  print_gen_entry_path (table->opcode_rule->line, table, notify);	  notify (NULL, ": insert %d - %s.%s%s\n",		  opcode_nr,		  instruction->format_name,		  instruction->name,		  (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);	}      else	{	  gen_entry_insert_insn (table, instruction,				 table->opcode->word_nr,				 table->nr_prefetched_words, opcode_nr, NULL);	}    }  else    {      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);      int first_pos = ((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);	    gen_entry_expand_opcode (table, instruction,				     last_pos + 1,				     ((opcode_nr << width) | val), bits);	    break;	  }	default:	  {	    if (field->type == insn_field_reserved)	      gen_entry_expand_opcode (table, instruction,				       last_pos + 1,				       ((opcode_nr << width)), bits);	    else	      {		int val;		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 */		    int is_precluded;		    insn_field_cond *condition;		    for (condition = field->conditions, is_precluded = 0;			 condition != NULL && !is_precluded;			 condition = condition->next)		      {			switch (condition->type)			  {			  case insn_field_cond_value:			    {			      int value =				sub_val (condition->value, field->last,					 first_pos, last_pos);			      switch (condition->test)				{				case insn_field_cond_ne:				  if (value == val)				    is_precluded = 1;				  break;				case insn_field_cond_eq:				  if (value != val)				    is_precluded = 1;				  break;				}			      break;			    }			  case insn_field_cond_field:			    {			      int value = -1;			      opcode_bits *bit;			      gen_entry *t = NULL;			      /* Try to find a value for the			         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->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 */				      value = sub_val (bit->value, bit->last,						       condition->field->						       first,						       condition->field->						       last);				    }				}			      /* Try to find a value by looking			         through this and previous tables */			      if (bit == NULL)				{				  for (t = table;				       t->parent != NULL; t = t->parent)				    {				      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 */					  /* 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);					}				    }				}			      if (bit == NULL && t == NULL)				error (instruction->line,				       "Conditional `%s' of field `%s' isn't expanded",				       condition->string, field->val_string);			      switch (condition->test)				{				case insn_field_cond_ne:				  if (value == val)				    is_precluded = 1;				  break;				case insn_field_cond_eq:				  if (value != val)				    is_precluded = 1;				  break;				}			      break;			    }			  }		      }		    if (!is_precluded)		      {			/* Only add additional hardwired bit			   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);			  }			else			  {			    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);			  }		      }		  }	      }	  }	}    }}static voidgen_entry_insert_expanding (gen_entry *table, insn_entry * instruction){  gen_entry_expand_opcode (table,			   instruction,			   table->opcode->first, 0, table->expanded_bits);}static intinsns_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))	    return 0;	}    }  return 1;}static inttable_matches_path (gen_entry *table, decode_path_list *paths){  if (paths == NULL)    return 1;  while (paths != NULL)    {      gen_entry *entry = table;      decode_path *path = paths->path;      while (1)	{	  if (entry == NULL && path == NULL)	    return 1;	  if (entry == NULL || path == NULL)	    break;	  if (entry->opcode_nr != path->opcode_nr)	    break;	  entry = entry->parent;	  path = path->parent;	}      paths = paths->next;    }  return 0;}static intinsns_match_conditions (insn_list *insns, decode_cond *conditions){  if (conditions != NULL)    {      insn_list *i;      for (i = insns; i != NULL; i = i->next)	{	  decode_cond *cond;	  for (cond = conditions; cond != NULL; cond = cond->next)	    {	      int bit_nr;	      if (i->insn->nr_words <= cond->word_nr)		return 0;	      for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)		{		  if (!cond->mask[bit_nr])		    continue;		  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)		    return 0;		}	    }	}    }  return 1;}static intinsns_match_nr_words (insn_list *insns, int nr_words){  insn_list *i;  for (i = insns; i != NULL; i = i->next)    {      if (i->insn->nr_words < nr_words)	return 0;    }  return 1;}static intinsn_list_cmp (insn_list *l, insn_list *r){  while (1)    {      insn_entry *insn;      if (l == NULL && r == NULL)	return 0;      if (l == NULL)	return -1;      if (r == NULL)	return 1;      if (l->insn != r->insn)	return -1;		/* somewhat arbitrary at present */      /* skip this insn */      insn = l->insn;      while (l != NULL && l->insn == insn)	l = l->next;      while (r != NULL && r->insn == insn)	r = r->next;    }}static voidgen_entry_expand_insns (gen_entry *table){  decode_table *opcode_rule;  ASSERT (table->nr_insns >= 1);  /* determine a valid opcode */  for (opcode_rule = table->opcode_rule;       opcode_rule != NULL; opcode_rule = opcode_rule->next)    {      char *discard_reason;      if (table->top->model != NULL	  && opcode_rule->model_names != NULL	  && !filter_is_member (opcode_rule->model_names,				table->top->model->name))	{	  /* the rule isn't applicable to this processor */	  discard_reason = "wrong model";	}      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 */	  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 */	  discard_reason = "need duplication with nr-insns == 1";	}      else	if (!insns_match_format_names	    (table->insns, opcode_rule->format_names))	{	  discard_reason = "wrong format name";	}      else if (!insns_match_nr_words (table->insns, opcode_rule->word_nr + 1))	{	  discard_reason = "wrong nr words";	}      else if (!table_matches_path (table, opcode_rule->paths))	{	  discard_reason = "path failed";	}      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 */	    );	  if (table->opcode != NULL)	    {	      table->opcode_rule = opcode_rule;	      break;	    }	}      if (options.trace.rule_rejection)	{	  print_gen_entry_path (opcode_rule->line, table, notify);	  notify (NULL, ": rule discarded - %s\n", discard_reason);	}

⌨️ 快捷键说明

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