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

📄 mloop.in

📁 这个是LINUX下的GDB调度工具的源码
💻 IN
📖 第 1 页 / 共 2 页
字号:
# Simulator main loop for frv. -*- C -*-# Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.# Contributed by Red Hat.## This file is part of the GNU Simulators.## 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, 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.# Syntax:# /bin/sh mainloop.in command## Command is one of:## init# support# extract-{simple,scache,pbb}# {full,fast}-exec-{simple,scache,pbb}## A target need only provide a "full" version of one of simple,scache,pbb.# If the target wants it can also provide a fast version of same.# It can't provide more than this.# ??? After a few more ports are done, revisit.# Will eventually need to machine generate a lot of this.case "x$1" inxsupport)cat <<EOFstatic INLINE const IDESC *extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, ARGBUF *abuf,         int fast_p){  const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);  if (! fast_p)    {      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);      @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);    }  return id;}static INLINE SEM_PCexecute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p){  SEM_PC vpc;  /* Force gr0 to zero before every insn.  */  @cpu@_h_gr_set (current_cpu, 0, 0);  if (fast_p)    {      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);    }  else    {      ARGBUF *abuf = &sc->argbuf;      const IDESC *idesc = abuf->idesc;#if WITH_SCACHE_PBB      int virtual_p = CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_VIRTUAL);#else      int virtual_p = 0;#endif      if (! virtual_p)	{	  /* FIXME: call x-before */	  if (ARGBUF_PROFILE_P (abuf))	    PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);	  /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */	  if (FRV_COUNT_CYCLES (current_cpu, ARGBUF_PROFILE_P (abuf)))	    {	      @cpu@_model_insn_before (current_cpu, sc->first_insn_p);	      model_insn = FRV_INSN_MODEL_PASS_1;	      if (idesc->timing->model_fn != NULL)		(*idesc->timing->model_fn) (current_cpu, sc);	    }	  else	    model_insn = FRV_INSN_NO_MODELING;	  TRACE_INSN_INIT (current_cpu, abuf, 1);	  TRACE_INSN (current_cpu, idesc->idata,		      (const struct argbuf *) abuf, abuf->addr);	}#if WITH_SCACHE      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);#else      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);#endif      if (! virtual_p)	{	  /* FIXME: call x-after */	  if (FRV_COUNT_CYCLES (current_cpu, ARGBUF_PROFILE_P (abuf)))	    {	      int cycles;	      if (idesc->timing->model_fn != NULL)		{		  model_insn = FRV_INSN_MODEL_PASS_2;		  cycles = (*idesc->timing->model_fn) (current_cpu, sc);		}	      else		cycles = 1;	      @cpu@_model_insn_after (current_cpu, sc->last_insn_p, cycles);	    }	  TRACE_INSN_FINI (current_cpu, abuf, 1);	}    }  return vpc;}static void@cpu@_parallel_write_init (SIM_CPU *current_cpu){  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);  CGEN_WRITE_QUEUE_CLEAR (q);  previous_vliw_pc = CPU_PC_GET(current_cpu);  frv_interrupt_state.f_ne_flags[0] = 0;  frv_interrupt_state.f_ne_flags[1] = 0;  frv_interrupt_state.imprecise_interrupt = NULL;}static void@cpu@_parallel_write_queued (SIM_CPU *current_cpu){  int i;  FRV_VLIW *vliw = CPU_VLIW (current_cpu);  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);  /* Loop over the queued writes, executing them. Set the pc to the address     of the insn which queued each write for the proper context in case an     interrupt is caused. Restore the proper pc after the writes are     completed.  */  IADDR save_pc = CPU_PC_GET (current_cpu);  IADDR new_pc  = save_pc;  int branch_taken = 0;  int limit = CGEN_WRITE_QUEUE_INDEX (q);  frv_interrupt_state.data_written.length = 0;  for (i = 0; i < limit; ++i)    {      CGEN_WRITE_QUEUE_ELEMENT *item = CGEN_WRITE_QUEUE_ELEMENT (q, i);      /* If an imprecise interrupt was generated, then, check whether the	 result should still be written.  */      if (frv_interrupt_state.imprecise_interrupt != NULL)	{	  /* Only check writes by the insn causing the exception.  */	  if (CGEN_WRITE_QUEUE_ELEMENT_IADDR (item)	      == frv_interrupt_state.imprecise_interrupt->vpc)	    {	      /* Execute writes of floating point operations resulting in		 overflow, underflow or inexact.  */	      if (frv_interrupt_state.imprecise_interrupt->kind		  == FRV_FP_EXCEPTION)		{		  if ((frv_interrupt_state.imprecise_interrupt		       ->u.fp_info.fsr_mask		       & ~(FSR_INEXACT | FSR_OVERFLOW | FSR_UNDERFLOW)))		    continue; /* Don't execute */		}	      /* Execute writes marked as 'forced'.  */	      else if (! (CGEN_WRITE_QUEUE_ELEMENT_FLAGS (item)			  & FRV_WRITE_QUEUE_FORCE_WRITE))		continue; /* Don't execute */	    }	}      /* Only execute the first branch on the queue.  */      if (CGEN_WRITE_QUEUE_ELEMENT_KIND (item) == CGEN_PC_WRITE          || CGEN_WRITE_QUEUE_ELEMENT_KIND (item) == CGEN_FN_PC_WRITE)	{	  if (branch_taken)	    continue;	  branch_taken = 1;	  if (CGEN_WRITE_QUEUE_ELEMENT_KIND (item) == CGEN_PC_WRITE)	    new_pc = item->kinds.pc_write.value;          else	    new_pc = item->kinds.fn_pc_write.value;	}      CPU_PC_SET (current_cpu, CGEN_WRITE_QUEUE_ELEMENT_IADDR (item));      frv_save_data_written_for_interrupts (current_cpu, item);      cgen_write_queue_element_execute (current_cpu, item);    }  /* Update the LR with the address of the next insn if the flag is set.     This flag gets set in frvbf_set_write_next_vliw_to_LR by the JMPL,     JMPIL and CALL insns.  */  if (frvbf_write_next_vliw_addr_to_LR)    {      frvbf_h_spr_set_handler (current_cpu, H_SPR_LR, save_pc);      frvbf_write_next_vliw_addr_to_LR = 0;    }  CPU_PC_SET (current_cpu, new_pc);  CGEN_WRITE_QUEUE_CLEAR (q);}void@cpu@_perform_writeback (SIM_CPU *current_cpu){  @cpu@_parallel_write_queued (current_cpu);}static unsigned cache_reqno = 0x80000000; /* Start value is for debugging.  */#if 0 /* experimental *//* FR400 has single prefetch.  */static voidfr400_simulate_insn_prefetch (SIM_CPU *current_cpu, IADDR vpc){  int cur_ix;  FRV_CACHE *cache;/* The cpu receives 8 bytes worth of insn data for each fetch aligned   on 8 byte boundary.  */#define FR400_FETCH_SIZE 8  cur_ix = LS;  vpc &= ~(FR400_FETCH_SIZE - 1);  cache = CPU_INSN_CACHE (current_cpu);  /* Request a load of the current address buffer, if necessary.  */  if (frv_insn_fetch_buffer[cur_ix].address != vpc)    {      frv_insn_fetch_buffer[cur_ix].address = vpc;      frv_insn_fetch_buffer[cur_ix].reqno = cache_reqno++;      if (FRV_COUNT_CYCLES (current_cpu, 1))	frv_cache_request_load (cache, frv_insn_fetch_buffer[cur_ix].reqno,				frv_insn_fetch_buffer[cur_ix].address,				UNIT_I0 + cur_ix);    }  /* Wait for the current address buffer to be loaded, if necessary.  */  if (FRV_COUNT_CYCLES (current_cpu, 1))    {      FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);      int wait;      /* Account for any branch penalty.  */      if (ps->branch_penalty > 0 && ! ps->past_first_p)	{	  frv_model_advance_cycles (current_cpu, ps->branch_penalty);	  frv_model_trace_wait_cycles (current_cpu, ps->branch_penalty,

⌨️ 快捷键说明

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