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

📄 e500.igen

📁 这个是LINUX下的GDB调度工具的源码
💻 IGEN
📖 第 1 页 / 共 5 页
字号:
# e500 core instructions, for PSIM, the PowerPC simulator.# Copyright 2003  Free Software Foundation, Inc.# Contributed by Red Hat Inc; developed under contract from Motorola.# Written by matthew green <mrg@redhat.com>.# 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, 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; see the file COPYING.  If not, write to# the Free Software Foundation, 59 Temple Place - Suite 330,# Boston, MA 02111-1307, USA.## e500 Core Complex Instructions#:cache:e500::signed_word *:rAh:RA:(cpu_registers(processor)->e500.gprh + RA):cache:e500::signed_word *:rSh:RS:(cpu_registers(processor)->e500.gprh + RS):cache:e500::signed_word *:rBh:RB:(cpu_registers(processor)->e500.gprh + RB)# Flags for model.h::model-macro:::	#define PPC_INSN_INT_SPR(OUT_MASK, IN_MASK, SPR) \		do { \		  if (CURRENT_MODEL_ISSUE > 0) \		    ppc_insn_int_spr(MY_INDEX, cpu_model(processor), OUT_MASK, IN_MASK, SPR); \		} while (0)# Schedule an instruction that takes 2 integer register and produces a special purpose output register plus an integer output registervoid::model-function::ppc_insn_int_spr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned nSPR	const unsigned32 int_mask = out_mask | in_mask;	model_busy *busy_ptr;	while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {	  if (WITH_TRACE && ppc_trace[trace_model])	    model_trace_busy_p(model_ptr, int_mask, 0, 0, nSPR);	  model_ptr->nr_stalls_data++;	  model_new_cycle(model_ptr);	}	busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);	busy_ptr->int_busy |= out_mask;	model_ptr->int_busy |= out_mask;	busy_ptr->spr_busy = nSPR;	model_ptr->spr_busy[nSPR] = 1;	busy_ptr->nr_writebacks = (PPC_ONE_BIT_SET_P(out_mask)) ? 3 : 2;	TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));## SPE Modulo Fractional Multiplication handling support#:function:e500::unsigned64:ev_multiply16_smf:signed16 a, signed16 b, int *sat	signed32 a32 = a, b32 = b, rv32;	rv32 = a * b;	*sat = (rv32 & (3<<30)) == (3<<30);	return (signed64)rv32 << 1;:function:e500::unsigned64:ev_multiply32_smf:signed32 a, signed32 b, int *sat	signed64 rv64, a64 = a, b64 = b;	rv64 = a64 * b64;	*sat = (rv64 & ((signed64)3<<62)) == ((signed64)3<<62);	/* Loses top sign bit.  */	return rv64 << 1;## SPE Saturation handling support#:function:e500::signed32:ev_multiply16_ssf:signed16 a, signed16 b, int *sat	signed32 rv32;	if (a == 0xffff8000 && b == 0xffff8000)	  {	    rv32 = 0x7fffffffL;	    * sat = 1;	    return rv32;	  }	else	  {	    signed32 a32 = a, b32 = b;	    	    rv32 = a * b;	    * sat = (rv32 & (3<<30)) == (3<<30);	    return (signed64)rv32 << 1;	  }:function:e500::signed64:ev_multiply32_ssf:signed32 a, signed32 b, int *sat	signed64 rv64;	if (a == 0x80000000 && b == 0x80000000)	  {	    rv64 = 0x7fffffffffffffffLL;	    * sat = 1;	    return rv64;	  }	else	  {	    signed64 a64 = a, b64 = b;	    rv64 = a64 * b64;	    *sat = (rv64 & ((signed64)3<<62)) == ((signed64)3<<62);	    /* Loses top sign bit.  */	    return rv64 << 1;	  }## SPE FP handling support#:function:e500::void:ev_check_guard:sim_fpu *a, int fg, int fx, cpu *processor	unsigned64 guard;	guard = sim_fpu_guard(a, 0);	if (guard & 1)	  EV_SET_SPEFSCR_BITS(fg);	if (guard & ~1)	  EV_SET_SPEFSCR_BITS(fx);:function:e500::void:booke_sim_fpu_32to:sim_fpu *dst, unsigned32 packed	sim_fpu_32to (dst, packed);	/* Set normally unused fields to allow booke arithmetic.  */	if (dst->class == sim_fpu_class_infinity)	  {	    dst->normal_exp = 128;	    dst->fraction = ((unsigned64)1 << 60);	  }	else if (dst->class == sim_fpu_class_qnan		 || dst->class == sim_fpu_class_snan)	  {	    dst->normal_exp = 128;	    /* This is set, but without the implicit bit, so we have to or	       in the implicit bit.  */	    dst->fraction |= ((unsigned64)1 << 60);	  }:function:e500::int:booke_sim_fpu_add:sim_fpu *d, sim_fpu *a, sim_fpu *b, int inv, int over, int under, cpu *processor	int invalid_operand, overflow_result, underflow_result;	int dest_exp;	invalid_operand = 0;	overflow_result = 0;	underflow_result = 0;	/* Treat NaN, Inf, and denorm like normal numbers, and signal invalid	   operand if it hasn't already been done.  */	if (EV_IS_INFDENORMNAN (a))	  {	    a->class = sim_fpu_class_number;	    EV_SET_SPEFSCR_BITS (inv);	    invalid_operand = 1;	  }	if (EV_IS_INFDENORMNAN (b))	  {	    b->class = sim_fpu_class_number;	    if (! invalid_operand)	      {		EV_SET_SPEFSCR_BITS (inv);		invalid_operand = 1;	      }	  }	sim_fpu_add (d, a, b);	dest_exp = booke_sim_fpu_exp (d);	/* If this is a denorm, force to zero, and signal underflow if	   we haven't already indicated invalid operand.  */	if (dest_exp <= -127)	  {	    int sign = d->sign;	    *d = sim_fpu_zero;	    d->sign = sign;	    if (! invalid_operand)	      {		EV_SET_SPEFSCR_BITS (under);		underflow_result = 1;	      }	  }	/* If this is Inf/NaN, force to pmax/nmax, and signal overflow if	   we haven't already indicated invalid operand.  */	else if (dest_exp >= 127)	  {	    int sign = d->sign;	    *d = sim_fpu_max32;	    d->sign = sign;	    if (! invalid_operand)	      {		EV_SET_SPEFSCR_BITS (over);		overflow_result = 1;	      }	  }	/* Destination sign is sign of operand with larger magnitude, or	   the sign of the first operand if operands have the same	   magnitude.  Thus if the result is zero, we force it to have	   the sign of the first operand.  */	else if (d->fraction == 0)	  d->sign = a->sign;	return invalid_operand || overflow_result || underflow_result;:function:e500::unsigned32:ev_fs_add:unsigned32 aa, unsigned32 bb, int inv, int over, int under, int fg, int fx, cpu *processor	sim_fpu a, b, d;	unsigned32 w;	int exception;	booke_sim_fpu_32to (&a, aa);	booke_sim_fpu_32to (&b, bb);	exception = booke_sim_fpu_add (&d, &a, &b, inv, over, under,				       processor);	sim_fpu_to32 (&w, &d);	if (! exception)	  ev_check_guard(&d, fg, fx, processor);	return w;:function:e500::unsigned32:ev_fs_sub:unsigned32 aa, unsigned32 bb, int inv, int over, int under, int fg, int fx, cpu *processor	sim_fpu a, b, d;	unsigned32 w;	int exception;	booke_sim_fpu_32to (&a, aa);	booke_sim_fpu_32to (&b, bb);	/* Invert sign of second operand, and add.  */	b.sign = ! b.sign;	exception = booke_sim_fpu_add (&d, &a, &b, inv, over, under,				       processor);	sim_fpu_to32 (&w, &d);	if (! exception)	  ev_check_guard(&d, fg, fx, processor);	return w;# sim_fpu_exp leaves the normal_exp field undefined for Inf and NaN.# The booke algorithms require exp values, so we fake them here.# fixme: It also apparently does the same for zero, but should not.:function:e500::unsigned32:booke_sim_fpu_exp:sim_fpu *x	int y = sim_fpu_is (x);	if (y == SIM_FPU_IS_PZERO || y == SIM_FPU_IS_NZERO)	  return 0;	else if (y == SIM_FPU_IS_SNAN || y == SIM_FPU_IS_QNAN		 || y == SIM_FPU_IS_NINF || y == SIM_FPU_IS_PINF)	  return 128;	else	  return sim_fpu_exp (x);:function:e500::unsigned32:ev_fs_mul:unsigned32 aa, unsigned32 bb, int inv, int over, int under, int fg, int fx, cpu *processor	sim_fpu a, b, d;	unsigned32 w;	int sa, sb, ea, eb, ei;	sim_fpu_32to (&a, aa);	sim_fpu_32to (&b, bb);	sa = sim_fpu_sign(&a);	sb = sim_fpu_sign(&b);	ea = booke_sim_fpu_exp(&a);	eb = booke_sim_fpu_exp(&b);	ei = ea + eb + 127;	if (sim_fpu_is_zero (&a) || sim_fpu_is_zero (&b))	  w = 0;	else if (sa == sb) {	  if (ei >= 254) {	    w = EV_PMAX;	    EV_SET_SPEFSCR_BITS(over);	  } else if (ei < 1) {	    d = sim_fpu_zero;	    sim_fpu_to32 (&w, &d);	    w &= 0x7fffffff;	/* Clear sign bit.  */	  } else {	    goto normal_mul;	  }	} else {	  if (ei >= 254) {	    w = EV_NMAX;	    EV_SET_SPEFSCR_BITS(over);	  } else if (ei < 1) {	    d = sim_fpu_zero;	    sim_fpu_to32 (&w, &d);	    w |= 0x80000000;	/* Set sign bit.  */	  } else {	normal_mul:	    if (EV_IS_INFDENORMNAN(&a) || EV_IS_INFDENORMNAN(&b))	      EV_SET_SPEFSCR_BITS(inv);	    sim_fpu_mul (&d, &a, &b);	    sim_fpu_to32 (&w, &d);	  }	}	return w;:function:e500::unsigned32:ev_fs_div:unsigned32 aa, unsigned32 bb, int inv, int over, int under, int dbz, int fg, int fx, cpu *processor	sim_fpu a, b, d;	unsigned32 w;	int sa, sb, ea, eb, ei;		sim_fpu_32to (&a, aa);	sim_fpu_32to (&b, bb);	sa = sim_fpu_sign(&a);	sb = sim_fpu_sign(&b);	ea = booke_sim_fpu_exp(&a);	eb = booke_sim_fpu_exp(&b);	ei = ea - eb + 127;	/* Special cases to handle behaviour of e500 hardware.	   cf case 107543.  */	if (sim_fpu_is_nan (&a) || sim_fpu_is_nan (&b)	  || sim_fpu_is_zero (&a) || sim_fpu_is_zero (&b))	{	  if (sim_fpu_is_snan (&a) || sim_fpu_is_snan (&b))	    {	      if (bb == 0x3f800000)	        w = EV_PMAX;	      else if (aa == 0x7fc00001)	        w = 0x3fbffffe;	      else	        goto normal_div;	    }	  else	    goto normal_div;	}	else if (sim_fpu_is_infinity (&a) && sim_fpu_is_infinity (&b))	{	  if (sa == sb)	    sim_fpu_32to (&d, 0x3f800000);	  else	    sim_fpu_32to (&d, 0xbf800000);	  sim_fpu_to32 (&w, &d);	}	else if (sa == sb) {	  if (ei > 254) {	    w = EV_PMAX;	    EV_SET_SPEFSCR_BITS(over);	  } else if (ei <= 1) {	    d = sim_fpu_zero;	    sim_fpu_to32 (&w, &d);	    w &= 0x7fffffff;	/* Clear sign bit.  */	  } else {	    goto normal_div;	  }	} else {	  if (ei > 254) {	    w = EV_NMAX;	    EV_SET_SPEFSCR_BITS(over);	  } else if (ei <= 1) {	    d = sim_fpu_zero;	    sim_fpu_to32 (&w, &d);	    w |= 0x80000000;	/* Set sign bit.  */	  } else {	normal_div:	    if (EV_IS_INFDENORMNAN(&a) || EV_IS_INFDENORMNAN(&b))	      EV_SET_SPEFSCR_BITS(inv);	    if (sim_fpu_is_zero (&b))	      {	        if (sim_fpu_is_zero (&a))	          EV_SET_SPEFSCR_BITS(dbz);	        else 	          EV_SET_SPEFSCR_BITS(inv);	        w = sa ? EV_NMAX : EV_PMAX;	      }	    else	      {	        sim_fpu_div (&d, &a, &b);	        sim_fpu_to32 (&w, &d);

⌨️ 快捷键说明

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