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

📄 frv.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Compute the result of the cut insns.  */SIfrvbf_media_cut (SIM_CPU *current_cpu, DI acc, SI cut_point){  /* The cut point is the lower 6 bits (signed) of what we are passed.  */  cut_point = cut_point << 26 >> 26;  /* The cut_point is relative to bit 40 of 64 bits.  */  if (cut_point >= 0)    return (acc << (cut_point + 24)) >> 32;  /* Extend the sign bit (bit 40) for negative cuts.  */  if (cut_point == -32)    return (acc << 24) >> 63; /* Special case for full shiftout.  */  return (acc << 24) >> (32 + -cut_point);}/* Compute the result of the cut insns.  */SIfrvbf_media_cut_ss (SIM_CPU *current_cpu, DI acc, SI cut_point){  /* The cut point is the lower 6 bits (signed) of what we are passed.  */  cut_point = cut_point << 26 >> 26;  if (cut_point >= 0)    {      /* The cut_point is relative to bit 40 of 64 bits.  */      DI shifted = acc << (cut_point + 24);      DI unshifted = shifted >> (cut_point + 24);      /* The result will be saturated if significant bits are shifted out.  */      if (unshifted != acc)	{	  if (acc < 0)	    return 0x80000000;	  return 0x7fffffff;	}    }  /* The result will not be saturated, so use the code for the normal cut.  */  return frvbf_media_cut (current_cpu, acc, cut_point);}/* Compute the result of int accumulator cut (SCUTSS).  */SIfrvbf_iacc_cut (SIM_CPU *current_cpu, DI acc, SI cut_point){  DI lower, upper;  /* The cut point is the lower 7 bits (signed) of what we are passed.  */  cut_point = cut_point << 25 >> 25;  /* Conceptually, the operation is on a 128-bit sign-extension of ACC.     The top bit of the return value corresponds to bit (63 - CUT_POINT)     of this 128-bit value.     Since we can't deal with 128-bit values very easily, convert the     operation into an equivalent 64-bit one.  */  if (cut_point < 0)    {      /* Avoid an undefined shift operation.  */      if (cut_point == -64)	acc >>= 63;      else	acc >>= -cut_point;      cut_point = 0;    }  /* Get the shifted but unsaturated result.  Set LOWER to the lowest     32 bits of the result and UPPER to the result >> 31.  */  if (cut_point < 32)    {      /* The cut loses the (32 - CUT_POINT) least significant bits.	 Round the result up if the most significant of these lost bits	 is 1.  */      lower = acc >> (32 - cut_point);      if (lower < 0x7fffffff)	if (acc & LSBIT64 (32 - cut_point - 1))	  lower++;      upper = lower >> 31;    }  else    {      lower = acc << (cut_point - 32);      upper = acc >> (63 - cut_point);    }  /* Saturate the result.  */  if (upper < -1)    return ~0x7fffffff;  else if (upper > 0)    return 0x7fffffff;  else    return lower;}/* Compute the result of shift-left-arithmetic-with-saturation (SLASS).  */SIfrvbf_shift_left_arith_saturate (SIM_CPU *current_cpu, SI arg1, SI arg2){  int neg_arg1;  /* FIXME: what to do with negative shift amt?  */  if (arg2 <= 0)    return arg1;  if (arg1 == 0)    return 0;  /* Signed shift by 31 or greater saturates by definition.  */  if (arg2 >= 31)    if (arg1 > 0)      return (SI) 0x7fffffff;    else      return (SI) 0x80000000;  /* OK, arg2 is between 1 and 31.  */  neg_arg1 = (arg1 < 0);  do {    arg1 <<= 1;    /* Check for sign bit change (saturation).  */    if (neg_arg1 && (arg1 >= 0))      return (SI) 0x80000000;    else if (!neg_arg1 && (arg1 < 0))      return (SI) 0x7fffffff;  } while (--arg2 > 0);  return arg1;}/* Simulate the media custom insns.  */voidfrvbf_media_cop (SIM_CPU *current_cpu, int cop_num){  /* The semantics of the insn are a nop, since it is implementation defined.     We do need to check whether it's implemented and set up for MTRAP     if it's not.  */  USI msr0 = GET_MSR (0);  if (GET_MSR_EMCI (msr0) == 0)    {      /* no interrupt queued at this time.  */      frv_set_mp_exception_registers (current_cpu, MTT_UNIMPLEMENTED_MPOP, 0);    }}/* Simulate the media average (MAVEH) insn.  */static HIdo_media_average (SIM_CPU *current_cpu, HI arg1, HI arg2){  SIM_DESC sd = CPU_STATE (current_cpu);  SI sum = (arg1 + arg2);  HI result = sum >> 1;  int rounding_value;  /* On fr4xx and fr550, check the rounding mode.  On other machines     rounding is always toward negative infinity and the result is     already correctly rounded.  */  switch (STATE_ARCHITECTURE (sd)->mach)    {      /* Need to check rounding mode. */    case bfd_mach_fr400:    case bfd_mach_fr450:    case bfd_mach_fr550:      /* Check whether rounding will be required.  Rounding will be required	 if the sum is an odd number.  */      rounding_value = sum & 1;      if (rounding_value)	{	  USI msr0 = GET_MSR (0);	  /* Check MSR0.SRDAV to determine which bits control the rounding.  */	  if (GET_MSR_SRDAV (msr0))	    {	      /* MSR0.RD controls rounding.  */	      switch (GET_MSR_RD (msr0))		{		case 0:		  /* Round to nearest.  */		  if (result >= 0)		    ++result;		  break;		case 1:		  /* Round toward 0. */		  if (result < 0)		    ++result;		  break;		case 2:		  /* Round toward positive infinity.  */		  ++result;		  break;		case 3:		  /* Round toward negative infinity.  The result is already		     correctly rounded.  */		  break;		default:		  abort ();		  break;		}	    }	  else	    {	      /* MSR0.RDAV controls rounding.  If set, round toward positive		 infinity.  Otherwise the result is already rounded correctly		 toward negative infinity.  */	      if (GET_MSR_RDAV (msr0))		++result;	    }	}      break;    default:      break;    }  return result;}SIfrvbf_media_average (SIM_CPU *current_cpu, SI reg1, SI reg2){  SI result;  result  = do_media_average (current_cpu, reg1 & 0xffff, reg2 & 0xffff);  result &= 0xffff;  result |= do_media_average (current_cpu, (reg1 >> 16) & 0xffff,			      (reg2 >> 16) & 0xffff) << 16;  return result;}/* Maintain a flag in order to know when to write the address of the next   VLIW instruction into the LR register.  Used by JMPL. JMPIL, and CALL.  */voidfrvbf_set_write_next_vliw_addr_to_LR (SIM_CPU *current_cpu, int value){  frvbf_write_next_vliw_addr_to_LR = value;}voidfrvbf_set_ne_index (SIM_CPU *current_cpu, int index){  USI NE_flags[2];  /* Save the target register so interrupt processing can set its NE flag     in the event of an exception.  */  frv_interrupt_state.ne_index = index;  /* Clear the NE flag of the target register. It will be reset if necessary     in the event of an exception.  */  GET_NE_FLAGS (NE_flags, H_SPR_FNER0);  CLEAR_NE_FLAG (NE_flags, index);  SET_NE_FLAGS (H_SPR_FNER0, NE_flags);}voidfrvbf_force_update (SIM_CPU *current_cpu){  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);  int ix = CGEN_WRITE_QUEUE_INDEX (q);  if (ix > 0)    {      CGEN_WRITE_QUEUE_ELEMENT *item = CGEN_WRITE_QUEUE_ELEMENT (q, ix - 1);      item->flags |= FRV_WRITE_QUEUE_FORCE_WRITE;    }}/* Condition code logic.  */enum cr_ops {  andcr, orcr, xorcr, nandcr, norcr, andncr, orncr, nandncr, norncr,  num_cr_ops};enum cr_result {cr_undefined, cr_undefined1, cr_false, cr_true};static enum cr_resultcr_logic[num_cr_ops][4][4] = {  /* andcr */  {    /*                undefined     undefined       false         true */    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* false     */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* true      */ {cr_undefined, cr_undefined, cr_false,     cr_true     }  },  /* orcr */  {    /*                undefined     undefined       false         true */    /* undefined */ {cr_undefined, cr_undefined, cr_false,     cr_true     },    /* undefined */ {cr_undefined, cr_undefined, cr_false,     cr_true     },    /* false     */ {cr_false,     cr_false,     cr_false,     cr_true     },    /* true      */ {cr_true,      cr_true,      cr_true,      cr_true     }  },  /* xorcr */  {    /*                undefined     undefined       false         true */    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* false     */ {cr_undefined, cr_undefined, cr_false,     cr_true     },    /* true      */ {cr_true,      cr_true,      cr_true,      cr_false    }  },  /* nandcr */  {    /*                undefined     undefined       false         true */    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* false     */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* true      */ {cr_undefined, cr_undefined, cr_true,      cr_false    }  },  /* norcr */  {    /*                undefined     undefined       false         true */    /* undefined */ {cr_undefined, cr_undefined, cr_true,      cr_false    },    /* undefined */ {cr_undefined, cr_undefined, cr_true,      cr_false    },    /* false     */ {cr_true,      cr_true,      cr_true,      cr_false    },    /* true      */ {cr_false,     cr_false,     cr_false,     cr_false    }  },  /* andncr */  {    /*                undefined     undefined       false         true */    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* false     */ {cr_undefined, cr_undefined, cr_false,     cr_true     },    /* true      */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined}  },  /* orncr */  {    /*                undefined     undefined       false         true */    /* undefined */ {cr_undefined, cr_undefined, cr_false,     cr_true     },    /* undefined */ {cr_undefined, cr_undefined, cr_false,     cr_true     },    /* false     */ {cr_true,      cr_true,      cr_true,      cr_true     },    /* true      */ {cr_false,     cr_false,     cr_false,     cr_true     }  },  /* nandncr */  {    /*                undefined     undefined       false         true */    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* undefined */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined},    /* false     */ {cr_undefined, cr_undefined, cr_true,      cr_false    },    /* true      */ {cr_undefined, cr_undefined, cr_undefined, cr_undefined}  },  /* norncr */  {    /*                undefined     undefined       false         true */    /* undefined */ {cr_undefined, cr_undefined, cr_true,      cr_false    },    /* undefined */ {cr_undefined, cr_undefined, cr_true,      cr_false    },    /* false     */ {cr_false,     cr_false,     cr_false,     cr_false    },    /* true      */ {cr_true,      cr_true,      cr_true,      cr_false    }  }};UQIfrvbf_cr_logic (SIM_CPU *current_cpu, SI operation, UQI arg1, UQI arg2){  return cr_logic[operation][arg1][arg2];}/* Cache Manipulation.  */voidfrvbf_insn_cache_preload (SIM_CPU *current_cpu, SI address, USI length, int lock){  /* If we need to count cycles, then the cache operation will be     initiated from the model profiling functions.     See frvbf_model_....  */  int hsr0 = GET_HSR0 ();  if (GET_HSR0_ICE (hsr0))    {      if (model_insn)	{	  CPU_LOAD_ADDRESS (current_cpu) = address;	  CPU_LOAD_LENGTH (current_cpu) = length;	  CPU_LOAD_LOCK (current_cpu) = lock;	}      else	{	  FRV_CACHE *cache = CPU_INSN_CACHE (current_cpu);	  frv_cache_preload (cache, address, length, lock);	}    }}voidfrvbf_data_cache_preload (SIM_CPU *current_cpu, SI address, USI length, int lock){  /* If we need to count cycles, then the cache operation will be     initiated from the model profiling functions.     See frvbf_model_....  */  int hsr0 = GET_HSR0 ();  if (GET_HSR0_DCE (hsr0))    {      if (model_insn)	{	  CPU_LOAD_ADDRESS (current_cpu) = address;	  CPU_LOAD_LENGTH (current_cpu) = length;	  CPU_LOAD_LOCK (current_cpu) = lock;	}      else	{	  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);	  frv_cache_preload (cache, address, length, lock);	}    }}voidfrvbf_insn_cache_unlock (SIM_CPU *current_cpu, SI address){  /* If we need to count cycles, then the cache operation will be     initiated from the model profiling functions.     See frvbf_model_....  */  int hsr0 = GET_HSR0 ();  if (GET_HSR0_ICE (hsr0))    {      if (model_insn)	CPU_LOAD_ADDRESS (current_cpu) = address;      else	{	  FRV_CACHE *cache = CPU_INSN_CACHE (current_cpu);	  frv_cache_unlock (cache, address);	}    }}voidfrvbf_data_cache_unlock (SIM_CPU *current_cpu, SI address){  /* If we need to count cycles, then the cache operation will be     initiated from the model profiling functions.     See frvbf_model_....  */  int hsr0 = GET_HSR0 ();  if (GET_HSR0_DCE (hsr0))    {      if (model_insn)	CPU_LOAD_ADDRESS (current_cpu) = address;      else	{	  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);	  frv_cache_unlock (cache, address);	}    }}voidfrvbf_insn_cache_invalidate (SIM_CPU *current_cpu, SI address, int all){  /* Make sure the insn was specified properly.  -1 will be passed for ALL     for a icei with A=0.  */  if (all == -1)    {      frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);      return;    }  /* If we need to count cycles, then the cache operation will be     initiated from the model profiling functions.     See frvbf_model_....  */  if (model_insn)    {      /* Record the all-entries flag for use in profiling.  */      FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);      ps->all_cache_entries = all;      CPU_LOAD_ADDRESS (current_cpu) = address;    }  else    {      FRV_CACHE *cache = CPU_INSN_CACHE (current_cpu);      if (all)	frv_cache_invalidate_all (cache, 0/* flush? */);      else	frv_cache_invalidate (cache, address, 0/* flush? */);    }}voidfrvbf_data_cache_invalidate (SIM_CPU *current_cpu, SI address, int all){  /* Make sure the insn was specified properly.  -1 will be passed for ALL     for a dcei with A=0.  */  if (all == -1)    {      frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);      return;    }  /* If we need to count cycles, then the cache operation will be     initiated from the model profiling functions.     See frvbf_model_....  */  if (model_insn)    {      /* Record the all-entries flag for use in profiling.  */      FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);      ps->all_cache_entries = all;      CPU_LOAD_ADDRESS (current_cpu) = address;    }  else    {      FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);      if (all)	frv_cache_invalidate_all (cache, 0/* flush? */);      else	frv_cache_invalidate (cache, address, 0/* flush? */);    }}voidfrvbf_data_cache_flush (SIM_CPU *current_cpu, SI address, int all){  /* Make sure the insn was specified properly.  -1 will be passed for ALL     for a dcef with A=0.  */  if (all == -1)    {      frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);      return;    }  /* If we need to count cycles, then the cache operation will be     initiated from the model profiling functions.     See frvbf_model_....  */  if (model_insn)    {      /* Record the all-entries flag for use in profiling.  */      FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);      ps->all_cache_entries = all;      CPU_LOAD_ADDRESS (current_cpu) = address;    }  else    {      FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);      if (all)	frv_cache_invalidate_all (cache, 1/* flush? */);      else	frv_cache_invalidate (cache, address, 1/* flush? */);    }}

⌨️ 快捷键说明

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