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

📄 gen-idecode.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* The IGEN simulator generator for GDB, the GNU Debugger.   Copyright 2002 Free Software Foundation, Inc.   Contributed by Andrew Cagney.   This file is part of GDB.   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 "igen.h"#include "ld-insn.h"#include "ld-decode.h"#include "gen.h"#include "gen-idecode.h"#include "gen-icache.h"#include "gen-semantics.h"static voidlf_print_opcodes (lf *file, gen_entry *table){  if (table !=NULL)    {      while (1)	{	  ASSERT (table->opcode != NULL);	  lf_printf (file, "_%d_%d",		     table->opcode->first, table->opcode->last);	  if (table->parent == NULL)	    break;	  lf_printf (file, "__%d", table->opcode_nr);	  table = table->parent;	}    }}static voidprint_idecode_ifetch (lf *file,		      int previous_nr_prefetched_words,		      int current_nr_prefetched_words){  int word_nr;  for (word_nr = previous_nr_prefetched_words;       word_nr < current_nr_prefetched_words; word_nr++)    {      lf_printf (file,		 "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",		 word_nr, options.insn_bit_size, word_nr);    }}/****************************************************************/static voidlf_print_table_name (lf *file, gen_entry *table){  lf_printf (file, "idecode_table");  lf_print_opcodes (file, table);}static voidprint_idecode_table (lf *file, gen_entry *entry, const char *result){  lf_printf (file, "/* prime the search */\n");  lf_printf (file, "idecode_table_entry *table = ");  lf_print_table_name (file, entry);  lf_printf (file, ";\n");  lf_printf (file, "int opcode = EXTRACTED%d (instruction, %d, %d);\n",	     options.insn_bit_size,	     i2target (options.hi_bit_nr, entry->opcode->first),	     i2target (options.hi_bit_nr, entry->opcode->last));  lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n");  lf_printf (file, "\n");  lf_printf (file, "/* iterate until a leaf */\n");  lf_printf (file, "while (1) {\n");  lf_printf (file, "  signed shift = table_entry->shift;\n");  lf_printf (file, "if (shift == function_entry) break;\n");  lf_printf (file, "  if (shift >= 0) {\n");  lf_printf (file, "    table = ((idecode_table_entry*)\n");  lf_printf (file, "             table_entry->function_or_table);\n");  lf_printf (file, "    opcode = ((instruction & table_entry->mask)\n");  lf_printf (file, "              >> shift);\n");  lf_printf (file, "    table_entry = table + opcode;\n");  lf_printf (file, "  }\n");  lf_printf (file, "  else {\n");  lf_printf (file, "    /* must be a boolean */\n");  lf_printf (file, "    ASSERT(table_entry->shift == boolean_entry);\n");  lf_printf (file, "    opcode = ((instruction & table_entry->mask)\n");  lf_printf (file, "              != table_entry->value);\n");  lf_printf (file, "    table = ((idecode_table_entry*)\n");  lf_printf (file, "             table_entry->function_or_table);\n");  lf_printf (file, "    table_entry = table + opcode;\n");  lf_printf (file, "  }\n");  lf_printf (file, "}\n");  lf_printf (file, "\n");  lf_printf (file, "/* call the leaf code */\n");  if (options.gen.code == generate_jumps)    {      lf_printf (file, "goto *table_entry->function_or_table;\n");    }  else    {      lf_printf (file, "%s ", result);      if (options.gen.icache)	{	  lf_printf (file,		     "(((idecode_icache*)table_entry->function_or_table)\n");	  lf_printf (file, "  (");	  print_icache_function_actual (file, 1);	  lf_printf (file, "));\n");	}      else	{	  lf_printf (file,		     "((idecode_semantic*)table_entry->function_or_table)\n");	  lf_printf (file, "  (");	  print_semantic_function_actual (file, 1);	  lf_printf (file, ");\n");	}    }}static voidprint_idecode_table_start (lf *file, gen_entry *table, int depth, void *data){  ASSERT (depth == 0);  /* start of the table */  if (table->opcode_rule->gen == array_gen)    {      lf_printf (file, "\n");      lf_printf (file, "static idecode_table_entry ");      lf_print_table_name (file, table);      lf_printf (file, "[] = {\n");    }}static voidprint_idecode_table_leaf (lf *file, gen_entry *entry, int depth, void *data){  gen_entry *master_entry;  ASSERT (entry->parent != NULL);  ASSERT (depth == 0);  if (entry->combined_parent == NULL)    master_entry = entry;  else    master_entry = entry->combined_parent;  /* add an entry to the table */  if (entry->parent->opcode_rule->gen == array_gen)    {      lf_printf (file, "  /*%d*/ { ", entry->opcode_nr);      if (entry->opcode == NULL)	{	  ASSERT (entry->nr_insns == 1);	  /* table leaf entry */	  lf_printf (file, "function_entry, 0, 0, ");	  if (options.gen.code == generate_jumps)	    {	      lf_printf (file, "&&");	    }	  print_function_name (file,			       entry->insns->insn->name,			       entry->insns->insn->format_name,			       NULL,			       master_entry->expanded_bits,			       (options.gen.icache				? function_name_prefix_icache				: function_name_prefix_semantics));	}      else if (entry->opcode_rule->gen == switch_gen	       || entry->opcode_rule->gen == goto_switch_gen	       || entry->opcode_rule->gen == padded_switch_gen)	{	  /* table calling switch statement */	  lf_printf (file, "function_entry, 0, 0, ");	  if (options.gen.code == generate_jumps)	    {	      lf_printf (file, "&&");	    }	  lf_print_table_name (file, entry);	}      else if (entry->opcode->is_boolean)	{	  /* table `calling' boolean table */	  lf_printf (file, "boolean_entry, ");	  lf_printf (file, "MASK32(%d, %d), ",		     i2target (options.hi_bit_nr, entry->opcode->first),		     i2target (options.hi_bit_nr, entry->opcode->last));	  lf_printf (file, "INSERTED32(%d, %d, %d), ",		     entry->opcode->boolean_constant,		     i2target (options.hi_bit_nr, entry->opcode->first),		     i2target (options.hi_bit_nr, entry->opcode->last));	  lf_print_table_name (file, entry);	}      else	{	  /* table `calling' another table */	  lf_printf (file, "%d, ",		     options.insn_bit_size - entry->opcode->last - 1);	  lf_printf (file, "MASK%d(%d,%d), ", options.insn_bit_size,		     i2target (options.hi_bit_nr, entry->opcode->first),		     i2target (options.hi_bit_nr, entry->opcode->last));	  lf_printf (file, "0, ");	  lf_print_table_name (file, entry);	}      lf_printf (file, " },\n");    }}static voidprint_idecode_table_end (lf *file, gen_entry *table, int depth, void *data){  ASSERT (depth == 0);  if (table->opcode_rule->gen == array_gen)    {      lf_printf (file, "};\n");    }}/****************************************************************/static voidprint_goto_switch_name (lf *file, gen_entry *entry){  lf_printf (file, "case_");  if (entry->opcode == NULL)    {      print_function_name (file,			   entry->insns->insn->name,			   entry->insns->insn->format_name,			   NULL,			   entry->expanded_bits,			   (options.gen.icache			    ? function_name_prefix_icache			    : function_name_prefix_semantics));    }  else    {      lf_print_table_name (file, entry);    }}static voidprint_goto_switch_table_leaf (lf *file,			      gen_entry *entry, int depth, void *data){  ASSERT (entry->parent != NULL);  ASSERT (depth == 0);  ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen);  ASSERT (entry->parent->opcode);  lf_printf (file, "/* %d */ &&", entry->opcode_nr);  if (entry->combined_parent != NULL)    print_goto_switch_name (file, entry->combined_parent);  else    print_goto_switch_name (file, entry);  lf_printf (file, ",\n");}static voidprint_goto_switch_break (lf *file, gen_entry *entry){  lf_printf (file, "goto break_");  lf_print_table_name (file, entry->parent);  lf_printf (file, ";\n");}static voidprint_goto_switch_table (lf *file, gen_entry *table){  lf_printf (file, "const static void *");  lf_print_table_name (file, table);  lf_printf (file, "[] = {\n");  lf_indent (file, +2);  gen_entry_traverse_tree (file, table, 0, NULL /*start */ ,			   print_goto_switch_table_leaf, NULL /*end */ ,			   NULL /*data */ );  lf_indent (file, -2);  lf_printf (file, "};\n");}void print_idecode_switch (lf *file, gen_entry *table, const char *result);static voidprint_idecode_switch_start (lf *file, gen_entry *table, int depth, void *data){  /* const char *result = data; */  ASSERT (depth == 0);  ASSERT (table->opcode_rule->gen == switch_gen	  || table->opcode_rule->gen == goto_switch_gen	  || table->opcode_rule->gen == padded_switch_gen);  if (table->opcode->is_boolean      || table->opcode_rule->gen == switch_gen      || table->opcode_rule->gen == padded_switch_gen)    {      lf_printf (file, "switch (EXTRACTED%d (instruction_%d, %d, %d))\n",		 options.insn_bit_size,		 table->opcode_rule->word_nr,		 i2target (options.hi_bit_nr, table->opcode->first),		 i2target (options.hi_bit_nr, table->opcode->last));      lf_indent (file, +2);      lf_printf (file, "{\n");    }  else if (table->opcode_rule->gen == goto_switch_gen)    {      if (table->parent != NULL	  && (table->parent->opcode_rule->gen == switch_gen	      || table->parent->opcode_rule->gen == goto_switch_gen	      || table->parent->opcode_rule->gen == padded_switch_gen))	{	  lf_printf (file, "{\n");	  lf_indent (file, +2);	}      print_goto_switch_table (file, table);      lf_printf (file, "ASSERT (EXTRACTED%d (instruction_%d, %d, %d)\n",		 options.insn_bit_size,		 table->opcode->word_nr,		 i2target (options.hi_bit_nr, table->opcode->first),		 i2target (options.hi_bit_nr, table->opcode->last));      lf_printf (file, "        < (sizeof (");      lf_print_table_name (file, table);      lf_printf (file, ") / sizeof(void*)));\n");      lf_printf (file, "goto *");      lf_print_table_name (file, table);      lf_printf (file, "[EXTRACTED%d (instruction_%d, %d, %d)];\n",		 options.insn_bit_size,		 table->opcode->word_nr,		 i2target (options.hi_bit_nr, table->opcode->first),		 i2target (options.hi_bit_nr, table->opcode->last));    }  else    {      ASSERT ("bad switch" == NULL);    }}static voidprint_idecode_switch_leaf (lf *file, gen_entry *entry, int depth, void *data){  const char *result = data;  ASSERT (entry->parent != NULL);  ASSERT (depth == 0);  ASSERT (entry->parent->opcode_rule->gen == switch_gen	  || entry->parent->opcode_rule->gen == goto_switch_gen	  || entry->parent->opcode_rule->gen == padded_switch_gen);  ASSERT (entry->parent->opcode);  /* skip over any instructions combined into another entry */  if (entry->combined_parent != NULL)    return;  if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0)    {      /* case: boolean false target */      lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant);    }  else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0)    {      /* case: boolean true case */      lf_printf (file, "default:\n");    }  else if (entry->parent->opcode_rule->gen == switch_gen	   || entry->parent->opcode_rule->gen == padded_switch_gen)    {      /* case: <opcode-nr> - switch */      gen_entry *cob;      for (cob = entry; cob != NULL; cob = cob->combined_next)	lf_printf (file, "case %d:\n", cob->opcode_nr);    }  else if (entry->parent->opcode_rule->gen == goto_switch_gen)    {      /* case: <opcode-nr> - goto-switch */      print_goto_switch_name (file, entry);      lf_printf (file, ":\n");    }  else    {      ERROR ("bad switch");    }  lf_printf (file, "  {\n");  lf_indent (file, +4);  {    if (entry->opcode == NULL)      {	/* switch calling leaf */	ASSERT (entry->nr_insns == 1);	print_idecode_ifetch (file, entry->nr_prefetched_words,			      entry->insns->semantic->nr_prefetched_words);	switch (options.gen.code)	  {	  case generate_jumps:	    lf_printf (file, "goto ");	    break;	  case generate_calls:	    lf_printf (file, "%s", result);	    break;

⌨️ 快捷键说明

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