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

📄 gen-idecode.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  This file is part of the program psim.    Copyright 1994, 1995, 1996, 1997, 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"#include "gen-idecode.h"#include "gen-icache.h"#include "gen-semantics.h"static voidlf_print_opcodes(lf *file,		 insn_table *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 voidlf_print_table_name(lf *file,		    insn_table *table){  lf_printf(file, "idecode_table");  lf_print_opcodes(file, table);}static voidprint_idecode_table(lf *file,		    insn_table *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 = EXTRACTED32(instruction, %d, %d);\n",	    i2target(hi_bit_nr, entry->opcode->first),	    i2target(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 ((code & generate_jumps)) {    lf_printf(file, "goto *table_entry->function_or_table;\n");  }  else {    lf_printf(file, "%s ", result);    if ((code & generate_with_icache)) {      lf_printf(file, "(((idecode_icache*)table_entry->function_or_table)\n");      lf_printf(file, "  (%s));\n", ICACHE_FUNCTION_ACTUAL);    }    else {      lf_printf(file, "((idecode_semantic*)table_entry->function_or_table)\n");      lf_printf(file, "  (%s);\n", SEMANTIC_FUNCTION_ACTUAL);    }  }}static voidprint_idecode_table_start(insn_table *table,			  lf *file,			  void *data,			  int depth){  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(insn_table *entry,			 lf *file,			 void *data,			 insn *instruction,			 int depth){  ASSERT(entry->parent != NULL);  ASSERT(depth == 0);  /* 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) {      /* table leaf entry */      lf_printf(file, "function_entry, 0, 0, ");      if ((code & generate_jumps))	lf_printf(file, "&&");      print_function_name(file,			  entry->insns->file_entry->fields[insn_name],			  entry->expanded_bits,			  ((code & generate_with_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 ((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(hi_bit_nr, entry->opcode->first),		i2target(hi_bit_nr, entry->opcode->last));      lf_printf(file, "INSERTED32(%d, %d, %d), ",		entry->opcode->boolean_constant,		i2target(hi_bit_nr, entry->opcode->first),		i2target(hi_bit_nr, entry->opcode->last));      lf_print_table_name(file, entry);    }    else {      /* table `calling' another table */      lf_printf(file, "%d, ", insn_bit_size - entry->opcode->last - 1);      lf_printf(file, "MASK32(%d,%d), ",		i2target(hi_bit_nr, entry->opcode->first),		i2target(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(insn_table *table,			lf *file,			void *data,			int depth){  ASSERT(depth == 0);  if (table->opcode_rule->gen == array_gen) {    lf_printf(file, "};\n");  }}static voidprint_idecode_table_padding(insn_table *table,			    lf *file,			    void *data,			    int depth,			    int opcode_nr){  ASSERT(depth == 0);  if (table->opcode_rule->gen == array_gen) {    lf_printf(file, "  /*%d*/ { function_entry, 0, 0, ", opcode_nr);    if ((code & generate_jumps))      lf_printf(file, "&&");    lf_printf(file, "%s_illegal },\n",	      ((code & generate_with_icache) ? "icache" : "semantic"));  }}/****************************************************************/static voidprint_goto_switch_name(lf *file,		       insn_table *entry){  lf_printf(file, "case_");  if (entry->opcode == NULL)    print_function_name(file,			entry->insns->file_entry->fields[insn_name],			entry->expanded_bits,			((code & generate_with_icache)			 ? function_name_prefix_icache			 : function_name_prefix_semantics));  else    lf_print_table_name(file, entry);}static voidprint_goto_switch_table_leaf(insn_table *entry,			     lf *file,			     void *data,			     insn *instruction,			     int depth){  ASSERT(entry->parent != NULL);  ASSERT(depth == 0);  ASSERT(entry->parent->opcode_rule->gen == goto_switch_gen);  ASSERT(entry->parent->opcode);  lf_printf(file, "&&");  print_goto_switch_name(file, entry);  lf_printf(file, ",\n");}static voidprint_goto_switch_table_padding(insn_table *table,				lf *file,				void *data,				int depth,				int opcode_nr){  ASSERT(depth == 0);  ASSERT(table->opcode_rule->gen == goto_switch_gen);  lf_printf(file, "&&illegal_");  lf_print_table_name(file, table);  lf_printf(file, ",\n");}static voidprint_goto_switch_break(lf *file,			insn_table *entry){  lf_printf(file, "goto break_");  lf_print_table_name(file, entry->parent);  lf_printf(file, ";\n");}static voidprint_goto_switch_table(lf *file,			insn_table *table){  lf_printf(file, "const static void *");  lf_print_table_name(file, table);  lf_printf(file, "[] = {\n");  lf_indent(file, +2);  insn_table_traverse_tree(table,			   file, NULL/*data*/,			   0,			   NULL/*start*/,			   print_goto_switch_table_leaf,			   NULL/*end*/,			   print_goto_switch_table_padding);  lf_indent(file, -2);  lf_printf(file, "};\n");}void print_idecode_switch(lf *file,  insn_table *table, const char *result);static voididecode_switch_start(insn_table *table,		     lf *file,		     void *data,		     int depth){  /* 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 (EXTRACTED32(instruction, %d, %d)) {\n",	      i2target(hi_bit_nr, table->opcode->first),	      i2target(hi_bit_nr, table->opcode->last));  }  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(EXTRACTED32(instruction, %d, %d)\n",	      i2target(hi_bit_nr, table->opcode->first),	      i2target(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, "[EXTRACTED32(instruction, %d, %d)];\n",	      i2target(hi_bit_nr, table->opcode->first),	      i2target(hi_bit_nr, table->opcode->last));  }  else {    ASSERT("bad switch" == NULL);  }}static voididecode_switch_leaf(insn_table *entry,		    lf *file,		    void *data,		    insn *instruction,		    int depth){  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);  if (entry->parent->opcode->is_boolean      && entry->opcode_nr == 0) {    /* 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) {    /* 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) {

⌨️ 快捷键说明

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