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

📄 gen-engine.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-idecode.h"#include "gen-engine.h"#include "gen-icache.h"#include "gen-semantics.h"static voidprint_engine_issue_prefix_hook (lf *file){  lf_printf (file, "\n");  lf_indent_suppress (file);  lf_printf (file, "#if defined (ENGINE_ISSUE_PREFIX_HOOK)\n");  lf_printf (file, "ENGINE_ISSUE_PREFIX_HOOK();\n");  lf_indent_suppress (file);  lf_printf (file, "#endif\n");  lf_printf (file, "\n");}static voidprint_engine_issue_postfix_hook (lf *file){  lf_printf (file, "\n");  lf_indent_suppress (file);  lf_printf (file, "#if defined (ENGINE_ISSUE_POSTFIX_HOOK)\n");  lf_printf (file, "ENGINE_ISSUE_POSTFIX_HOOK();\n");  lf_indent_suppress (file);  lf_printf (file, "#endif\n");  lf_printf (file, "\n");}static voidprint_run_body (lf *file, gen_entry *table){  /* Output the function to execute real code:     Unfortunatly, there are multiple cases to consider vis:     <icache> X <smp>     Consequently this function is written in multiple different ways */  lf_printf (file, "{\n");  lf_indent (file, +2);  if (!options.gen.smp)    {      lf_printf (file, "%sinstruction_address cia;\n",		 options.module.global.prefix.l);    }  lf_printf (file, "int current_cpu = next_cpu_nr;\n");  if (options.gen.icache)    {      lf_printf (file, "/* flush the icache of a possible break insn */\n");      lf_printf (file, "{\n");      lf_printf (file, "  int cpu_nr;\n");      lf_printf (file, "  for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");      lf_printf (file, "    cpu_flush_icache (STATE_CPU (sd, cpu_nr));\n");      lf_printf (file, "}\n");    }  if (!options.gen.smp)    {      lf_putstr (file, "\/* CASE 1: NO SMP (with or with out instruction cache).\n\\n\In this case, we can take advantage of the fact that the current\n\instruction address (CIA) does not need to be read from / written to\n\the CPU object after the execution of an instruction.\n\\n\Instead, CIA is only saved when the main loop exits.  This occures\n\when either sim_engine_halt or sim_engine_restart is called.  Both of\n\these functions save the current instruction address before halting /\n\restarting the simulator.\n\\n\As a variation, there may also be support for an instruction cracking\n\cache. */\n\\n\");      lf_putstr (file, "\n");      lf_putstr (file, "/* prime the main loop */\n");      lf_putstr (file, "SIM_ASSERT (current_cpu == 0);\n");      lf_putstr (file, "SIM_ASSERT (nr_cpus == 1);\n");      lf_putstr (file, "cia = CIA_GET (CPU);\n");      lf_putstr (file, "\n");      lf_putstr (file, "while (1)\n");      lf_putstr (file, "  {\n");      lf_indent (file, +4);      lf_printf (file, "%sinstruction_address nia;\n",		 options.module.global.prefix.l);      lf_printf (file, "\n");      if (!options.gen.icache)	{	  lf_printf (file,		     "%sinstruction_word instruction_0 = IMEM%d (cia);\n",		     options.module.global.prefix.l, options.insn_bit_size);	  print_engine_issue_prefix_hook (file);	  print_idecode_body (file, table, "nia = ");	  print_engine_issue_postfix_hook (file);	}      else	{	  lf_putstr (file, "idecode_cache *cache_entry =\n");	  lf_putstr (file, "  cpu_icache_entry (cpu, cia);\n");	  lf_putstr (file, "if (cache_entry->address == cia)\n");	  lf_putstr (file, "  {\n");	  lf_indent (file, -4);	  lf_putstr (file, "/* cache hit */\n");	  lf_putstr (file,		     "idecode_semantic *const semantic = cache_entry->semantic;\n");	  lf_putstr (file, "cia = semantic (cpu, cache_entry, cia);\n");	  /* tail */	  lf_indent (file, -4);	  lf_putstr (file, "  }\n");	  lf_putstr (file, "else\n");	  lf_putstr (file, "  {\n");	  lf_indent (file, +4);	  lf_putstr (file, "/* cache miss */\n");	  if (!options.gen.semantic_icache)	    {	      lf_putstr (file, "idecode_semantic *semantic;\n");	    }	  lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n",		     options.insn_bit_size);	  lf_putstr (file, "if (WITH_MON != 0)\n");	  lf_putstr (file,		     "  mon_event (mon_event_icache_miss, cpu, cia);\n");	  if (options.gen.semantic_icache)	    {	      lf_putstr (file, "{\n");	      lf_indent (file, +2);	      print_engine_issue_prefix_hook (file);	      print_idecode_body (file, table, "nia =");	      print_engine_issue_postfix_hook (file);	      lf_indent (file, -2);	      lf_putstr (file, "}\n");	    }	  else	    {	      print_engine_issue_prefix_hook (file);	      print_idecode_body (file, table, "semantic =");	      lf_putstr (file, "nia = semantic (cpu, cache_entry, cia);\n");	      print_engine_issue_postfix_hook (file);	    }	  lf_indent (file, -4);	  lf_putstr (file, "  }\n");	}      /* update the cpu if necessary */      switch (options.gen.nia)	{	case nia_is_cia_plus_one:	  lf_printf (file, "\n");	  lf_printf (file, "/* Update the instruction address */\n");	  lf_printf (file, "cia = nia;\n");	  break;	case nia_is_void:	case nia_is_invalid:	  ERROR ("engine gen when NIA complex");	}      /* events */      lf_putstr (file, "\n");      lf_putstr (file, "/* process any events */\n");      lf_putstr (file, "if (sim_events_tick (sd))\n");      lf_putstr (file, "  {\n");      lf_putstr (file, "    CIA_SET (CPU, cia);\n");      lf_putstr (file, "    sim_events_process (sd);\n");      lf_putstr (file, "    cia = CIA_GET (CPU);\n");      lf_putstr (file, "  }\n");      lf_indent (file, -4);      lf_printf (file, "  }\n");    }  if (options.gen.smp)    {      lf_putstr (file, "\/* CASE 2: SMP (With or without ICACHE)\n\\n\The complexity here comes from needing to correctly halt the simulator\n\when it is aborted.  For instance, if cpu0 requests a restart then\n\cpu1 will normally be the next cpu that is run.  Cpu0 being restarted\n\after all the other CPU's and the event queue have been processed */\n\\n\");      lf_putstr (file, "\n");      lf_printf (file,		 "/* have ensured that the event queue is NOT next */\n");      lf_printf (file, "SIM_ASSERT (current_cpu >= 0);\n");      lf_printf (file, "SIM_ASSERT (current_cpu <= nr_cpus - 1);\n");      lf_printf (file, "SIM_ASSERT (nr_cpus <= MAX_NR_PROCESSORS);\n");      lf_putstr (file, "\n");      lf_putstr (file, "while (1)\n");      lf_putstr (file, "  {\n");      lf_indent (file, +4);      lf_putstr (file, "sim_cpu *cpu = STATE_CPU (sd, current_cpu);\n");      lf_putstr (file, "instruction_address cia = CIA_GET (cpu);\n");      lf_putstr (file, "\n");      if (!options.gen.icache)	{	  lf_printf (file, "instruction_word instruction_0 = IMEM%d (cia);\n",		     options.insn_bit_size);	  print_engine_issue_prefix_hook (file);	  print_idecode_body (file, table, "cia =");	  lf_putstr (file, "CIA_SET (cpu, cia);\n");	  print_engine_issue_postfix_hook (file);	}      if (options.gen.icache)	{	  lf_putstr (file, "engine_cache *cache_entry =\n");	  lf_putstr (file, "  cpu_icache_entry(processor, cia);\n");	  lf_putstr (file, "\n");	  lf_putstr (file, "if (cache_entry->address == cia) {\n");	  {	    lf_indent (file, +2);	    lf_putstr (file, "\n");	    lf_putstr (file, "/* cache hit */\n");	    lf_putstr (file,		       "engine_semantic *semantic = cache_entry->semantic;\n");	    lf_putstr (file,		       "cia = semantic(processor, cache_entry, cia);\n");	    /* tail */	    lf_putstr (file, "cpu_set_program_counter(processor, cia);\n");	    lf_putstr (file, "\n");	    lf_indent (file, -2);	  }	  lf_putstr (file, "}\n");	  lf_putstr (file, "else {\n");	  {	    lf_indent (file, +2);	    lf_putstr (file, "\n");	    lf_putstr (file, "/* cache miss */\n");	    if (!options.gen.semantic_icache)	      {		lf_putstr (file, "engine_semantic *semantic;\n");	      }	    lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n",		       options.insn_bit_size);	    lf_putstr (file, "if (WITH_MON != 0)\n");	    lf_putstr (file,		       "  mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");	    if (options.gen.semantic_icache)	      {		lf_putstr (file, "{\n");		lf_indent (file, +2);		print_engine_issue_prefix_hook (file);		print_idecode_body (file, table, "cia =");		print_engine_issue_postfix_hook (file);		lf_indent (file, -2);		lf_putstr (file, "}\n");	      }	    else	      {		print_engine_issue_prefix_hook (file);		print_idecode_body (file, table, "semantic = ");		lf_putstr (file,			   "cia = semantic(processor, cache_entry, cia);\n");		print_engine_issue_postfix_hook (file);	      }	    /* tail */	    lf_putstr (file, "cpu_set_program_counter(processor, cia);\n");	    lf_putstr (file, "\n");	    lf_indent (file, -2);	  }	  lf_putstr (file, "}\n");	}      lf_putstr (file, "\n");      lf_putstr (file, "current_cpu += 1;\n");      lf_putstr (file, "if (current_cpu == nr_cpus)\n");      lf_putstr (file, "  {\n");      lf_putstr (file, "    if (sim_events_tick (sd))\n");      lf_putstr (file, "      {\n");      lf_putstr (file, "        sim_events_process (sd);\n");      lf_putstr (file, "      }\n");      lf_putstr (file, "    current_cpu = 0;\n");      lf_putstr (file, "  }\n");      /* tail */      lf_indent (file, -4);      lf_putstr (file, "  }\n");    }  lf_indent (file, -2);  lf_putstr (file, "}\n");}/****************************************************************/#if 0static voidprint_jump (lf *file, int is_tail){  if (!options.gen.smp)    {      lf_putstr (file, "if (event_queue_tick (sd))\n");      lf_putstr (file, "  {\n");      lf_putstr (file, "    CPU_CIA (processor) = nia;\n");      lf_putstr (file, "    sim_events_process (sd);\n");      lf_putstr (file, "  }\n");      lf_putstr (file, "}\n");    }  if (options.gen.smp)    {      if (is_tail)	lf_putstr (file, "cpu_set_program_counter(processor, nia);\n");      lf_putstr (file, "current_cpu += 1;\n");      lf_putstr (file, "if (current_cpu >= nr_cpus)\n");      lf_putstr (file, "  {\n");      lf_putstr (file, "    if (sim_events_tick (sd))\n");      lf_putstr (file, "      {\n");      lf_putstr (file, "        sim_events_process (sd);\n");      lf_putstr (file, "      }\n");      lf_putstr (file, "    current_cpu = 0;\n");      lf_putstr (file, "  }\n");      lf_putstr (file, "processor = processors[current_cpu];\n");      lf_putstr (file, "nia = cpu_get_program_counter(processor);\n");    }  if (options.gen.icache)    {      lf_putstr (file, "cache_entry = cpu_icache_entry(processor, nia);\n");      lf_putstr (file, "if (cache_entry->address == nia) {\n");      lf_putstr (file, "  /* cache hit */\n");      lf_putstr (file, "  goto *cache_entry->semantic;\n");      lf_putstr (file, "}\n");      if (is_tail)	{	  lf_putstr (file, "goto cache_miss;\n");	}    }  if (!options.gen.icache && is_tail)    {      lf_printf (file, "goto engine;\n");    }

⌨️ 快捷键说明

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