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

📄 profile-fr400.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* frv simulator fr400 dependent profiling code.   Copyright (C) 2001 Free Software Foundation, Inc.   Contributed by Red HatThis file is part of the GNU simulators.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public License alongwith this program; if not, write to the Free Software Foundation, Inc.,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/#define WANT_CPU#define WANT_CPU_FRVBF#include "sim-main.h"#include "bfd.h"#if WITH_PROFILE_MODEL_P#include "profile.h"#include "profile-fr400.h"/* These functions get and set flags representing the use of   registers/resources.  */static void set_use_not_fp_load (SIM_CPU *, INT);static void set_use_not_media_p4 (SIM_CPU *, INT);static void set_use_not_media_p6 (SIM_CPU *, INT);static void set_acc_use_not_media_p2 (SIM_CPU *, INT);static void set_acc_use_not_media_p4 (SIM_CPU *, INT);voidfr400_reset_gr_flags (SIM_CPU *cpu, INT fr){  set_use_not_gr_complex (cpu, fr);}voidfr400_reset_fr_flags (SIM_CPU *cpu, INT fr){  set_use_not_fp_load  (cpu, fr);  set_use_not_media_p4 (cpu, fr);  set_use_not_media_p6 (cpu, fr);}voidfr400_reset_acc_flags (SIM_CPU *cpu, INT acc){  set_acc_use_not_media_p2 (cpu, acc);  set_acc_use_not_media_p4 (cpu, acc);}static voidset_use_is_fp_load (SIM_CPU *cpu, INT fr, INT fr_double){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (fr != -1)    {      fr400_reset_fr_flags (cpu, fr);      d->cur_fp_load |= (((DI)1) << fr);    }  if (fr_double != -1)    {      fr400_reset_fr_flags (cpu, fr_double);      d->cur_fp_load |= (((DI)1) << fr_double);      if (fr_double < 63)	{	  fr400_reset_fr_flags (cpu, fr_double + 1);	  d->cur_fp_load |= (((DI)1) << (fr_double + 1));	}    }}static voidset_use_not_fp_load (SIM_CPU *cpu, INT fr){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (fr != -1)    d->cur_fp_load &= ~(((DI)1) << fr);}static intuse_is_fp_load (SIM_CPU *cpu, INT fr){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (fr != -1)    return (d->prev_fp_load >> fr) & 1;  return 0;}static voidset_acc_use_is_media_p2 (SIM_CPU *cpu, INT acc){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (acc != -1)    {      fr400_reset_acc_flags (cpu, acc);      d->cur_acc_p2 |= (((DI)1) << acc);    }}static voidset_acc_use_not_media_p2 (SIM_CPU *cpu, INT acc){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (acc != -1)    d->cur_acc_p2 &= ~(((DI)1) << acc);}static intacc_use_is_media_p2 (SIM_CPU *cpu, INT acc){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (acc != -1)    return d->cur_acc_p2 & (((DI)1) << acc);  return 0;}static voidset_use_is_media_p4 (SIM_CPU *cpu, INT fr){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (fr != -1)    {      fr400_reset_fr_flags (cpu, fr);      d->cur_fr_p4 |= (((DI)1) << fr);    }}static voidset_use_not_media_p4 (SIM_CPU *cpu, INT fr){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (fr != -1)    d->cur_fr_p4 &= ~(((DI)1) << fr);}static intuse_is_media_p4 (SIM_CPU *cpu, INT fr){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (fr != -1)    return d->cur_fr_p4 & (((DI)1) << fr);  return 0;}static voidset_acc_use_is_media_p4 (SIM_CPU *cpu, INT acc){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (acc != -1)    {      fr400_reset_acc_flags (cpu, acc);      d->cur_acc_p4 |= (((DI)1) << acc);    }}static voidset_acc_use_not_media_p4 (SIM_CPU *cpu, INT acc){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (acc != -1)    d->cur_acc_p4 &= ~(((DI)1) << acc);}static intacc_use_is_media_p4 (SIM_CPU *cpu, INT acc){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (acc != -1)    return d->cur_acc_p4 & (((DI)1) << acc);  return 0;}static voidset_use_is_media_p6 (SIM_CPU *cpu, INT fr){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (fr != -1)    {      fr400_reset_fr_flags (cpu, fr);      d->cur_fr_p6 |= (((DI)1) << fr);    }}static voidset_use_not_media_p6 (SIM_CPU *cpu, INT fr){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (fr != -1)    d->cur_fr_p6 &= ~(((DI)1) << fr);}static intuse_is_media_p6 (SIM_CPU *cpu, INT fr){  MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);  if (fr != -1)    return d->cur_fr_p6 & (((DI)1) << fr);  return 0;}/* Initialize cycle counting for an insn.   FIRST_P is non-zero if this is the first insn in a set of parallel   insns.  */voidfr400_model_insn_before (SIM_CPU *cpu, int first_p){  if (first_p)    {      MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);      FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);      ps->cur_gr_complex = ps->prev_gr_complex;      d->cur_fp_load = d->prev_fp_load;      d->cur_fr_p4 = d->prev_fr_p4;      d->cur_fr_p6 = d->prev_fr_p6;      d->cur_acc_p2 = d->prev_acc_p2;      d->cur_acc_p4 = d->prev_acc_p4;    }}/* Record the cycles computed for an insn.   LAST_P is non-zero if this is the last insn in a set of parallel insns,   and we update the total cycle count.   CYCLES is the cycle count of the insn.  */voidfr400_model_insn_after (SIM_CPU *cpu, int last_p, int cycles){  if (last_p)    {      MODEL_FR400_DATA *d = CPU_MODEL_DATA (cpu);      FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu);      ps->prev_gr_complex = ps->cur_gr_complex;      d->prev_fp_load = d->cur_fp_load;      d->prev_fr_p4 = d->cur_fr_p4;      d->prev_fr_p6 = d->cur_fr_p6;      d->prev_acc_p2 = d->cur_acc_p2;      d->prev_acc_p4 = d->cur_acc_p4;    }}intfrvbf_model_fr400_u_exec (SIM_CPU *cpu, const IDESC *idesc,			    int unit_num, int referenced){  return idesc->timing->units[unit_num].done;}intfrvbf_model_fr400_u_integer (SIM_CPU *cpu, const IDESC *idesc,			     int unit_num, int referenced,			     INT in_GRi, INT in_GRj, INT out_GRk,			     INT out_ICCi_1){  /* Modelling for this unit is the same as for fr500.  */  return frvbf_model_fr500_u_integer (cpu, idesc, unit_num, referenced,				      in_GRi, in_GRj, out_GRk, out_ICCi_1);}intfrvbf_model_fr400_u_imul (SIM_CPU *cpu, const IDESC *idesc,			  int unit_num, int referenced,			  INT in_GRi, INT in_GRj, INT out_GRk, INT out_ICCi_1){  /* Modelling for this unit is the same as for fr500.  */  return frvbf_model_fr500_u_imul (cpu, idesc, unit_num, referenced,				   in_GRi, in_GRj, out_GRk, out_ICCi_1);}intfrvbf_model_fr400_u_idiv (SIM_CPU *cpu, const IDESC *idesc,			  int unit_num, int referenced,			  INT in_GRi, INT in_GRj, INT out_GRk, INT out_ICCi_1){  int cycles;  FRV_VLIW *vliw;  int slot;  /* icc0-icc4 are the upper 4 fields of the CCR.  */  if (out_ICCi_1 >= 0)    out_ICCi_1 += 4;  vliw = CPU_VLIW (cpu);  slot = vliw->next_slot - 1;  slot = (*vliw->current_vliw)[slot] - UNIT_I0;  if (model_insn == FRV_INSN_MODEL_PASS_1)    {      /* The entire VLIW insn must wait if there is a dependency on a register	 which is not ready yet.	 The latency of the registers may be less than previously recorded,	 depending on how they were used previously.	 See Table 13-8 in the LSI.  */      if (in_GRi != out_GRk && in_GRi >= 0)	{	  if (use_is_gr_complex (cpu, in_GRi))	    decrease_GR_busy (cpu, in_GRi, 1);	}      if (in_GRj != out_GRk && in_GRj != in_GRi && in_GRj >= 0)	{	  if (use_is_gr_complex (cpu, in_GRj))	    decrease_GR_busy (cpu, in_GRj, 1);	}      vliw_wait_for_GR (cpu, in_GRi);      vliw_wait_for_GR (cpu, in_GRj);      vliw_wait_for_GR (cpu, out_GRk);      vliw_wait_for_CCR (cpu, out_ICCi_1);      vliw_wait_for_idiv_resource (cpu, slot);      handle_resource_wait (cpu);      load_wait_for_GR (cpu, in_GRi);      load_wait_for_GR (cpu, in_GRj);      load_wait_for_GR (cpu, out_GRk);      trace_vliw_wait_cycles (cpu);      return 0;    }  /* GRk has a latency of 19 cycles!  */  cycles = idesc->timing->units[unit_num].done;  update_GR_latency (cpu, out_GRk, cycles + 19);  set_use_is_gr_complex (cpu, out_GRk);  /* ICCi_1 has a latency of 18 cycles.  */  update_CCR_latency (cpu, out_ICCi_1, cycles + 18);  /* the idiv resource has a latency of 18 cycles!  */  update_idiv_resource_latency (cpu, slot, cycles + 18);  return cycles;}intfrvbf_model_fr400_u_branch (SIM_CPU *cpu, const IDESC *idesc,			    int unit_num, int referenced,			    INT in_GRi, INT in_GRj,			    INT in_ICCi_2, INT in_ICCi_3){#define BRANCH_PREDICTED(ps) ((ps)->branch_hint & 2)  FRV_PROFILE_STATE *ps;  int cycles;  if (model_insn == FRV_INSN_MODEL_PASS_1)    {      /* Modelling for this unit is the same as for fr500 in pass 1.  */      return frvbf_model_fr500_u_branch (cpu, idesc, unit_num, referenced,					 in_GRi, in_GRj, in_ICCi_2, in_ICCi_3);    }  cycles = idesc->timing->units[unit_num].done;  /* Compute the branch penalty, based on the the prediction and the out     come.  When counting branches taken or not taken, don't consider branches     after the first taken branch in a vliw insn.  */  ps = CPU_PROFILE_STATE (cpu);  if (! ps->vliw_branch_taken)    {      int penalty;      /* (1 << 4): The pc is the 5th element in inputs, outputs.	 ??? can be cleaned up */      PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);      int taken = (referenced & (1 << 4)) != 0;      if (taken)	{	  ++PROFILE_MODEL_TAKEN_COUNT (p);	  ps->vliw_branch_taken = 1;	  if (BRANCH_PREDICTED (ps))	    penalty = 1;	  else	    penalty = 3;	}      else	{	  ++PROFILE_MODEL_UNTAKEN_COUNT (p);	  if (BRANCH_PREDICTED (ps))	    penalty = 3;	  else	    penalty = 0;	}      if (penalty > 0)	{	  /* Additional 1 cycle penalty if the branch address is not 8 byte	     aligned.  */	  if (ps->branch_address & 7)	    ++penalty;	  update_branch_penalty (cpu, penalty);	  PROFILE_MODEL_CTI_STALL_CYCLES (p) += penalty;	}    }  return cycles;}intfrvbf_model_fr400_u_trap (SIM_CPU *cpu, const IDESC *idesc,			  int unit_num, int referenced,			  INT in_GRi, INT in_GRj,			  INT in_ICCi_2, INT in_FCCi_2){  /* Modelling for this unit is the same as for fr500.  */  return frvbf_model_fr500_u_trap (cpu, idesc, unit_num, referenced,				   in_GRi, in_GRj, in_ICCi_2, in_FCCi_2);}intfrvbf_model_fr400_u_check (SIM_CPU *cpu, const IDESC *idesc,			   int unit_num, int referenced,			   INT in_ICCi_3, INT in_FCCi_3){  /* Modelling for this unit is the same as for fr500.  */  return frvbf_model_fr500_u_check (cpu, idesc, unit_num, referenced,				    in_ICCi_3, in_FCCi_3);}intfrvbf_model_fr400_u_set_hilo (SIM_CPU *cpu, const IDESC *idesc,			     int unit_num, int referenced,			     INT out_GRkhi, INT out_GRklo){  /* Modelling for this unit is the same as for fr500.  */  return frvbf_model_fr500_u_set_hilo (cpu, idesc, unit_num, referenced,				       out_GRkhi, out_GRklo);}intfrvbf_model_fr400_u_gr_load (SIM_CPU *cpu, const IDESC *idesc,			     int unit_num, int referenced,			     INT in_GRi, INT in_GRj,			     INT out_GRk, INT out_GRdoublek){  /* Modelling for this unit is the same as for fr500.  */  return frvbf_model_fr500_u_gr_load (cpu, idesc, unit_num, referenced,				      in_GRi, in_GRj, out_GRk, out_GRdoublek);}intfrvbf_model_fr400_u_gr_store (SIM_CPU *cpu, const IDESC *idesc,			      int unit_num, int referenced,			      INT in_GRi, INT in_GRj,			      INT in_GRk, INT in_GRdoublek){  /* Modelling for this unit is the same as for fr500.  */  return frvbf_model_fr500_u_gr_store (cpu, idesc, unit_num, referenced,				       in_GRi, in_GRj, in_GRk, in_GRdoublek);}intfrvbf_model_fr400_u_fr_load (SIM_CPU *cpu, const IDESC *idesc,			     int unit_num, int referenced,			     INT in_GRi, INT in_GRj,			     INT out_FRk, INT out_FRdoublek){  int cycles;  if (model_insn == FRV_INSN_MODEL_PASS_1)    {      /* Pass 1 is the same as for fr500.  */      return frvbf_model_fr500_u_fr_load (cpu, idesc, unit_num, referenced,					  in_GRi, in_GRj, out_FRk,					  out_FRdoublek);    }  cycles = idesc->timing->units[unit_num].done;  /* The latency of FRk for a load will depend on how long it takes to retrieve     the the data from the cache or memory.  */  update_FR_latency_for_load (cpu, out_FRk, cycles);  update_FRdouble_latency_for_load (cpu, out_FRdoublek, cycles);  set_use_is_fp_load (cpu, out_FRk, out_FRdoublek);  return cycles;}intfrvbf_model_fr400_u_fr_store (SIM_CPU *cpu, const IDESC *idesc,			      int unit_num, int referenced,			      INT in_GRi, INT in_GRj,			      INT in_FRk, INT in_FRdoublek){  int cycles;  if (model_insn == FRV_INSN_MODEL_PASS_1)    {      /* The entire VLIW insn must wait if there is a dependency on a register	 which is not ready yet.	 The latency of the registers may be less than previously recorded,	 depending on how they were used previously.	 See Table 13-8 in the LSI.  */      if (in_GRi >= 0)	{	  if (use_is_gr_complex (cpu, in_GRi))	    decrease_GR_busy (cpu, in_GRi, 1);	}      if (in_GRj != in_GRi && in_GRj >= 0)	{	  if (use_is_gr_complex (cpu, in_GRj))	    decrease_GR_busy (cpu, in_GRj, 1);	}      if (in_FRk >= 0)	{	  if (use_is_media_p4 (cpu, in_FRk) || use_is_media_p6 (cpu, in_FRk))	    decrease_FR_busy (cpu, in_FRk, 1);	  else	    enforce_full_fr_latency (cpu, in_FRk);	}      vliw_wait_for_GR (cpu, in_GRi);      vliw_wait_for_GR (cpu, in_GRj);      vliw_wait_for_FR (cpu, in_FRk);      vliw_wait_for_FRdouble (cpu, in_FRdoublek);      handle_resource_wait (cpu);      load_wait_for_GR (cpu, in_GRi);      load_wait_for_GR (cpu, in_GRj);      load_wait_for_FR (cpu, in_FRk);      load_wait_for_FRdouble (cpu, in_FRdoublek);      trace_vliw_wait_cycles (cpu);      return 0;    }  cycles = idesc->timing->units[unit_num].done;  return cycles;

⌨️ 快捷键说明

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