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

📄 gen.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    }  /* did we find anything */  if (opcode_rule == NULL)    {      /* the decode table failed, this set of instructions haven't         been uniquely identified */      if (table->nr_insns > 1)	{	  print_gen_entry_insns (table, warning,				 "was not uniquely decoded",				 "decodes to the same entry");	  error (NULL, "");	}      return;    }  /* Determine the number of words that must have been prefetched for     this table to function */  if (table->parent == NULL)    table->nr_prefetched_words = table->opcode_rule->word_nr + 1;  else if (table->opcode_rule->word_nr + 1 >	   table->parent->nr_prefetched_words)    table->nr_prefetched_words = table->opcode_rule->word_nr + 1;  else    table->nr_prefetched_words = table->parent->nr_prefetched_words;  /* back link what we found to its parent */  if (table->parent != NULL)    {      ASSERT (table->parent->opcode != NULL);      table->opcode->parent = table->parent->opcode;    }  /* report the rule being used to expand the instructions */  if (options.trace.rule_selection)    {      print_gen_entry_path (table->opcode_rule->line, table, notify);      notify (NULL,	      ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",	      table->opcode->word_nr,	      i2target (options.hi_bit_nr, table->opcode->first),	      i2target (options.hi_bit_nr, table->opcode->last),	      i2target (options.hi_bit_nr, table->opcode_rule->first),	      i2target (options.hi_bit_nr, table->opcode_rule->last),	      table->opcode->nr_opcodes, table->nr_entries);    }  /* expand the raw instructions according to the opcode */  {    insn_list *entry;    for (entry = table->insns; entry != NULL; entry = entry->next)      {	if (options.trace.insn_expansion)	  {	    print_gen_entry_path (table->opcode_rule->line, table, notify);	    notify (NULL, ": expand - %s.%s\n",		    entry->insn->format_name, entry->insn->name);	  }	gen_entry_insert_expanding (table, entry->insn);      }  }  /* dump the results */  if (options.trace.entries)    {      gen_entry *entry;      for (entry = table->entries; entry != NULL; entry = entry->sibling)	{	  insn_list *l;	  print_gen_entry_path (table->opcode_rule->line, entry, notify);	  notify (NULL, ": %d - entries %d -",		  entry->opcode_nr, entry->nr_insns);	  for (l = entry->insns; l != NULL; l = l->next)	    notify (NULL, " %s.%s", l->insn->format_name, l->insn->name);	  notify (NULL, "\n");	}    }  /* perform a combine pass if needed */  if (table->opcode_rule->with_combine)    {      gen_entry *entry;      for (entry = table->entries; entry != NULL; entry = entry->sibling)	{	  if (entry->combined_parent == NULL)	    {	      gen_entry **last = &entry->combined_next;	      gen_entry *alt;	      for (alt = entry->sibling; alt != NULL; alt = alt->sibling)		{		  if (alt->combined_parent == NULL		      && insn_list_cmp (entry->insns, alt->insns) == 0)		    {		      alt->combined_parent = entry;		      *last = alt;		      last = &alt->combined_next;		    }		}	    }	}      if (options.trace.combine)	{	  int nr_unique = 0;	  gen_entry *entry;	  for (entry = table->entries; entry != NULL; entry = entry->sibling)	    {	      if (entry->combined_parent == NULL)		{		  insn_list *l;		  gen_entry *duplicate;		  nr_unique++;		  print_gen_entry_path (table->opcode_rule->line, entry,					notify);		  for (duplicate = entry->combined_next; duplicate != NULL;		       duplicate = duplicate->combined_next)		    {		      notify (NULL, "+%d", duplicate->opcode_nr);		    }		  notify (NULL, ": entries %d -", entry->nr_insns);		  for (l = entry->insns; l != NULL; l = l->next)		    {		      notify (NULL, " %s.%s",			      l->insn->format_name, l->insn->name);		    }		  notify (NULL, "\n");		}	    }	  print_gen_entry_path (table->opcode_rule->line, table, notify);	  notify (NULL,		  ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",		  table->opcode->word_nr, i2target (options.hi_bit_nr,						    table->opcode->first),		  i2target (options.hi_bit_nr, table->opcode->last),		  i2target (options.hi_bit_nr, table->opcode_rule->first),		  i2target (options.hi_bit_nr, table->opcode_rule->last),		  table->opcode->nr_opcodes, table->nr_entries, nr_unique);	}    }  /* Check that the rule did more than re-arange the order of the     instructions */  {    gen_entry *entry;    for (entry = table->entries; entry != NULL; entry = entry->sibling)      {	if (entry->combined_parent == NULL)	  {	    if (insn_list_cmp (table->insns, entry->insns) == 0)	      {		print_gen_entry_path (table->opcode_rule->line, table,				      warning);		warning (NULL,			 ": Applying rule just copied all instructions\n");		print_gen_entry_insns (entry, warning, "Copied", NULL);		error (NULL, "");	      }	  }      }  }  /* if some form of expanded table, fill in the missing dots */  switch (table->opcode_rule->gen)    {    case padded_switch_gen:    case array_gen:    case goto_switch_gen:      if (!table->opcode->is_boolean)	{	  gen_entry **entry = &table->entries;	  gen_entry *illegals = NULL;	  gen_entry **last_illegal = &illegals;	  int opcode_nr = 0;	  while (opcode_nr < table->opcode->nr_opcodes)	    {	      if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr)		{		  /* missing - insert it under our feet at *entry */		  gen_entry_insert_insn (table, table->top->isa->illegal_insn, table->opcode->word_nr, 0,	/* nr_prefetched_words == 0 for invalid */					 opcode_nr, NULL);		  ASSERT ((*entry) != NULL);		  ASSERT ((*entry)->opcode_nr == opcode_nr);		  (*last_illegal) = *entry;		  (*last_illegal)->combined_parent = illegals;		  last_illegal = &(*last_illegal)->combined_next;		}	      entry = &(*entry)->sibling;	      opcode_nr++;	    }	  /* oops, will have pointed the first illegal insn back to	     its self.  Fix this */	  if (illegals != NULL)	    illegals->combined_parent = NULL;	}      break;    case switch_gen:    case invalid_gen:      /* ignore */      break;    }  /* and do the same for the newly created sub entries but *only*     expand entries that haven't been combined. */  {    gen_entry *entry;    for (entry = table->entries; entry != NULL; entry = entry->sibling)      {	if (entry->combined_parent == NULL)	  {	    gen_entry_expand_insns (entry);	  }      }  }}voidgen_tables_expand_insns (gen_table *gen){  gen_list *entry;  for (entry = gen->tables; entry != NULL; entry = entry->next)    {      gen_entry_expand_insns (entry->table);    }}/* create a list of all the semantic functions that need to be   generated.  Eliminate any duplicates. Verify that the decode stage   worked. */static voidmake_gen_semantics_list (lf *file, gen_entry *entry, int depth, void *data){  gen_table *gen = (gen_table *) data;  insn_list *insn;  /* Not interested in an entrie that have been combined into some     other entry at the same level */  if (entry->combined_parent != NULL)    return;  /* a leaf should contain exactly one instruction. If not the decode     stage failed. */  ASSERT (entry->nr_insns == 1);  /* Enter this instruction into the list of semantic functions. */  insn = insn_list_insert (&gen->semantics, &gen->nr_semantics,			   entry->insns->insn,			   entry->expanded_bits,			   entry->parent->opcode,			   entry->insns->nr_prefetched_words,			   merge_duplicate_insns);  /* point the table entry at the real semantic function */  ASSERT (insn != NULL);  entry->insns->semantic = insn;}voidgen_tables_expand_semantics (gen_table *gen){  gen_list *entry;  for (entry = gen->tables; entry != NULL; entry = entry->next)    {      gen_entry_traverse_tree (NULL, entry->table, 1,	/* depth */			       NULL,	/* start-handler */			       make_gen_semantics_list,	/* leaf-handler */			       NULL,	/* end-handler */			       gen);	/* data */    }}#ifdef MAINstatic voiddump_opcode_field (lf *file,		   char *prefix,		   opcode_field *field, char *suffix, int levels){  lf_printf (file, "%s(opcode_field *) 0x%lx", prefix, (long) field);  if (levels && field != NULL)    {      lf_indent (file, +1);      lf_printf (file, "\n(first %d)", field->first);      lf_printf (file, "\n(last %d)", field->last);      lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes);      lf_printf (file, "\n(is_boolean %d)", field->is_boolean);      lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant);      dump_opcode_field (file, "\n(parent ", field->parent, ")", levels - 1);      lf_indent (file, -1);    }  lf_printf (file, "%s", suffix);}static voiddump_opcode_bits (lf *file,		  char *prefix, opcode_bits *bits, char *suffix, int levels){  lf_printf (file, "%s(opcode_bits *) 0x%lx", prefix, (long) bits);  if (levels && bits != NULL)    {      lf_indent (file, +1);      lf_printf (file, "\n(value %d)", bits->value);      dump_opcode_field (file, "\n(opcode ", bits->opcode, ")", 0);      dump_insn_field (file, "\n(field ", bits->field, ")");      dump_opcode_bits (file, "\n(next ", bits->next, ")", levels - 1);      lf_indent (file, -1);    }  lf_printf (file, "%s", suffix);}static voiddump_insn_list (lf *file, char *prefix, insn_list *entry, char *suffix){  lf_printf (file, "%s(insn_list *) 0x%lx", prefix, (long) entry);  if (entry != NULL)    {      lf_indent (file, +1);      dump_insn_entry (file, "\n(insn ", entry->insn, ")");      lf_printf (file, "\n(next 0x%lx)", (long) entry->next);      lf_indent (file, -1);    }  lf_printf (file, "%s", suffix);}static voiddump_insn_word_entry_list_entries (lf *file,				   char *prefix,				   insn_list *entry, char *suffix){  lf_printf (file, "%s", prefix);  while (entry != NULL)    {      dump_insn_list (file, "\n(", entry, ")");      entry = entry->next;    }  lf_printf (file, "%s", suffix);}static voiddump_gen_entry (lf *file,		char *prefix, gen_entry *table, char *suffix, int levels){  lf_printf (file, "%s(gen_entry *) 0x%lx", prefix, (long) table);  if (levels && table !=NULL)    {      lf_indent (file, +1);      lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr);      lf_printf (file, "\n(word_nr %d)", table->word_nr);      dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")",			-1);      lf_printf (file, "\n(nr_insns %d)", table->nr_insns);      dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns,					 ")");      dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")");      dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0);      lf_printf (file, "\n(nr_entries %d)", table->nr_entries);      dump_gen_entry (file, "\n(entries ", table->entries, ")",		      table->nr_entries);      dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1);      dump_gen_entry (file, "\n(parent ", table->parent, ")", 0);      lf_indent (file, -1);    }  lf_printf (file, "%s", suffix);}static voiddump_gen_list (lf *file,	       char *prefix, gen_list *entry, char *suffix, int levels){  while (entry != NULL)    {      lf_printf (file, "%s(gen_list *) 0x%lx", prefix, (long) entry);      dump_gen_entry (file, "\n(", entry->table, ")", levels);      lf_printf (file, "\n(next (gen_list *) 0x%lx)", (long) entry->next);      lf_printf (file, "%s", suffix);    }}static voiddump_gen_table (lf *file,		char *prefix, gen_table *gen, char *suffix, int levels){  lf_printf (file, "%s(gen_table *) 0x%lx", prefix, (long) gen);  lf_printf (file, "\n(isa (insn_table *) 0x%lx)", (long) gen->isa);  lf_printf (file, "\n(rules (decode_table *) 0x%lx)", (long) gen->rules);  dump_gen_list (file, "\n(", gen->tables, ")", levels);  lf_printf (file, "%s", suffix);}igen_options options;intmain (int argc, char **argv){  decode_table *decode_rules;  insn_table *instructions;  gen_table *gen;  lf *l;  if (argc != 7)    error (NULL,	   "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");  INIT_OPTIONS (options);  filter_parse (&options.flags_filter, argv[1]);  options.hi_bit_nr = a2i (argv[2]);  options.insn_bit_size = a2i (argv[3]);  options.insn_specifying_widths = a2i (argv[4]);  ASSERT (options.hi_bit_nr < options.insn_bit_size);  instructions = load_insn_table (argv[6], NULL);  decode_rules = load_decode_table (argv[5]);  gen = make_gen_tables (instructions, decode_rules);  gen_tables_expand_insns (gen);  l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");  dump_gen_table (l, "(", gen, ")\n", -1);  return 0;}#endif

⌨️ 快捷键说明

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