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

📄 gen-icache.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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-semantics.h"#include "gen-idecode.h"#include "gen-icache.h"static voidprint_icache_function_header (lf *file,			      const char *basename,			      const char *format_name,			      opcode_bits *expanded_bits,			      int is_function_definition,			      int nr_prefetched_words){  lf_printf (file, "\n");  lf_print__function_type_function (file, print_icache_function_type,				    "EXTERN_ICACHE", " ");  print_function_name (file,		       basename, format_name, NULL,		       expanded_bits, function_name_prefix_icache);  lf_printf (file, "\n(");  print_icache_function_formal (file, nr_prefetched_words);  lf_printf (file, ")");  if (!is_function_definition)    lf_printf (file, ";");  lf_printf (file, "\n");}voidprint_icache_declaration (lf *file,			  insn_entry * insn,			  opcode_bits *expanded_bits,			  insn_opcodes *opcodes, int nr_prefetched_words){  print_icache_function_header (file,				insn->name,				insn->format_name,				expanded_bits,				0 /* is not function definition */ ,				nr_prefetched_words);}static voidprint_icache_extraction (lf *file,			 const char *format_name,			 cache_entry_type cache_type,			 const char *entry_name,			 const char *entry_type,			 const char *entry_expression,			 char *single_insn_field,			 line_ref *line,			 insn_field_entry *cur_field,			 opcode_bits *expanded_bits,			 icache_decl_type what_to_declare,			 icache_body_type what_to_do){  const char *expression;  opcode_bits *bits;  char *reason;  ASSERT (format_name != NULL);  ASSERT (entry_name != NULL);  /* figure out exactly what should be going on here */  switch (cache_type)    {    case scratch_value:      if ((what_to_do & put_values_in_icache)	  || what_to_do == do_not_use_icache)	{	  reason = "scratch";	  what_to_do = do_not_use_icache;	}      else	return;      break;    case compute_value:      if ((what_to_do & get_values_from_icache)	  || what_to_do == do_not_use_icache)	{	  reason = "compute";	  what_to_do = do_not_use_icache;	}      else	return;      break;    case cache_value:      if ((what_to_declare != undef_variables)	  || !(what_to_do & put_values_in_icache))	{	  reason = "cache";	  what_to_declare = ((what_to_do & put_values_in_icache)			     ? declare_variables : what_to_declare);	}      else	return;      break;    default:      abort ();			/* Bad switch.  */    }  /* For the type, default to a simple unsigned */  if (entry_type == NULL || strlen (entry_type) == 0)    entry_type = "unsigned";  /* look through the set of expanded sub fields to see if this field     has been given a constant value */  for (bits = expanded_bits; bits != NULL; bits = bits->next)    {      if (bits->field == cur_field)	break;    }  /* Define a storage area for the cache element */  switch (what_to_declare)    {    case undef_variables:      /* We've finished with the #define value - destory it */      lf_indent_suppress (file);      lf_printf (file, "#undef %s\n", entry_name);      return;    case define_variables:      /* Using direct access for this entry, clear any prior         definition, then define it */      lf_indent_suppress (file);      lf_printf (file, "#undef %s\n", entry_name);      /* Don't type cast pointer types! */      lf_indent_suppress (file);      if (strchr (entry_type, '*') != NULL)	lf_printf (file, "#define %s (", entry_name);      else	lf_printf (file, "#define %s ((%s) ", entry_name, entry_type);      break;    case declare_variables:      /* using variables to define the value */      if (line != NULL)	lf_print__line_ref (file, line);      lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name);      break;    }  /* define a value for that storage area as determined by what is in     the cache */  if (bits != NULL      && single_insn_field != NULL      && strcmp (entry_name, single_insn_field) == 0      && strcmp (entry_name, cur_field->val_string) == 0      && ((bits->opcode->is_boolean && bits->value == 0)	  || (!bits->opcode->is_boolean)))    {      /* The cache rule is specifying what to do with a simple         instruction field.         Because of instruction expansion, the field is either a         constant value or equal to the specified constant (boolean         comparison). (The latter indicated by bits->value == 0).         The case of a field not being equal to the specified boolean         value is handled later. */      expression = "constant field";      ASSERT (bits->field == cur_field);      if (bits->opcode->is_boolean)	{	  ASSERT (bits->value == 0);	  lf_printf (file, "%d", bits->opcode->boolean_constant);	}      else if (bits->opcode->last < bits->field->last)	{	  lf_printf (file, "%d",		     bits->value << (bits->field->last - bits->opcode->last));	}      else	{	  lf_printf (file, "%d", bits->value);	}    }  else if (bits != NULL	   && single_insn_field != NULL	   && strncmp (entry_name,		       single_insn_field,		       strlen (single_insn_field)) == 0	   && strncmp (entry_name + strlen (single_insn_field),		       "_is_",		       strlen ("_is_")) == 0	   && ((bits->opcode->is_boolean		&& ((unsigned)		    atol (entry_name + strlen (single_insn_field) +			  strlen ("_is_")) == bits->opcode->boolean_constant))	       || (!bits->opcode->is_boolean)))    {      /* The cache rule defines an entry for the comparison between a         single instruction field and a constant.  The value of the         comparison in someway matches that of the opcode field that         was made constant through expansion. */      expression = "constant compare";      if (bits->opcode->is_boolean)	{	  lf_printf (file, "%d /* %s == %d */",		     bits->value == 0,		     single_insn_field, bits->opcode->boolean_constant);	}      else if (bits->opcode->last < bits->field->last)	{	  lf_printf (file, "%d /* %s == %d */",		     (atol		      (entry_name + strlen (single_insn_field) +		       strlen ("_is_")) ==		      (bits->		       value << (bits->field->last - bits->opcode->last))),		     single_insn_field,		     (bits->		      value << (bits->field->last - bits->opcode->last)));	}      else	{	  lf_printf (file, "%d /* %s == %d */",		     (atol		      (entry_name + strlen (single_insn_field) +		       strlen ("_is_")) == bits->value), single_insn_field,		     bits->value);	}    }  else    {      /* put the field in the local variable, possibly also enter it         into the cache */      expression = "extraction";      /* handle the cache */      if ((what_to_do & get_values_from_icache)	  || (what_to_do & put_values_in_icache))	{	  lf_printf (file, "cache_entry->crack.%s.%s",		     format_name, entry_name);	  if (what_to_do & put_values_in_icache)	/* also put it in the cache? */	    {	      lf_printf (file, " = ");	    }	}      if ((what_to_do & put_values_in_icache)	  || what_to_do == do_not_use_icache)	{	  if (cur_field != NULL)	    {	      if (entry_expression != NULL && strlen (entry_expression) > 0)		error (line,		       "Instruction field entry with nonempty expression\n");	      if (cur_field->first == 0		  && cur_field->last == options.insn_bit_size - 1)		lf_printf (file, "(instruction_%d)", cur_field->word_nr);	      else if (cur_field->last == options.insn_bit_size - 1)		lf_printf (file, "MASKED%d (instruction_%d, %d, %d)",			   options.insn_bit_size,			   cur_field->word_nr,			   i2target (options.hi_bit_nr, cur_field->first),			   i2target (options.hi_bit_nr, cur_field->last));	      else		lf_printf (file, "EXTRACTED%d (instruction_%d, %d, %d)",			   options.insn_bit_size,			   cur_field->word_nr,			   i2target (options.hi_bit_nr, cur_field->first),			   i2target (options.hi_bit_nr, cur_field->last));	    }	  else	    {	      lf_printf (file, "%s", entry_expression);	    }	}    }  switch (what_to_declare)    {    case define_variables:      lf_printf (file, ")");      break;    case undef_variables:      break;    case declare_variables:      lf_printf (file, ";");      break;    }  ASSERT (reason != NULL && expression != NULL);  lf_printf (file, " /* %s - %s */\n", reason, expression);}voidprint_icache_body (lf *file,		   insn_entry * instruction,		   opcode_bits *expanded_bits,		   cache_entry *cache_rules,		   icache_decl_type what_to_declare,		   icache_body_type what_to_do, int nr_prefetched_words){  /* extract instruction fields */  lf_printf (file, "/* Extraction: %s\n", instruction->name);  lf_printf (file, "     ");  switch (what_to_declare)    {    case define_variables:      lf_printf (file, "#define");      break;    case declare_variables:      lf_printf (file, "declare");      break;    case undef_variables:      lf_printf (file, "#undef");      break;    }  lf_printf (file, " ");  switch (what_to_do)    {    case get_values_from_icache:      lf_printf (file, "get-values-from-icache");      break;    case put_values_in_icache:      lf_printf (file, "put-values-in-icache");      break;    case both_values_and_icache:      lf_printf (file, "get-values-from-icache|put-values-in-icache");      break;    case do_not_use_icache:      lf_printf (file, "do-not-use-icache");      break;    }  lf_printf (file, "\n     ");  print_insn_words (file, instruction);  lf_printf (file, " */\n");  /* pass zero - fetch from memory any missing instructions.     Some of the instructions will have already been fetched (in the     instruction array), others will still need fetching. */  switch (what_to_do)    {    case get_values_from_icache:      break;    case put_values_in_icache:    case both_values_and_icache:    case do_not_use_icache:      {	int word_nr;	switch (what_to_declare)	  {	  case undef_variables:	    break;	  case define_variables:	  case declare_variables:	    for (word_nr = nr_prefetched_words;		 word_nr < instruction->nr_words; word_nr++)	      {		/* FIXME - should be using print_icache_extraction? */		lf_printf (file,			   "%sinstruction_word instruction_%d UNUSED = ",			   options.module.global.prefix.l, word_nr);		lf_printf (file, "IMEM%d_IMMED (cia, %d)",			   options.insn_bit_size, word_nr);		lf_printf (file, ";\n");	      }	  }      }    }  /* if putting the instruction words in the cache, define references     for them */  if (options.gen.insn_in_icache)    {      /* FIXME: is the instruction_word type correct? */      print_icache_extraction (file, instruction->format_name, cache_value, "insn",	/* name */			       "instruction_word",	/* type */			       "instruction",	/* expression */			       NULL,	/* origin */			       NULL,	/* line */

⌨️ 快捷键说明

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