Beispiel #1
0
/* compute <val1> / <val2> */
static struct eval_value_t
f_div(struct eval_value_t val1, struct eval_value_t val2)
{
  enum eval_type_t et;
  struct eval_value_t val;

  /* symbols are not allowed in arithmetic expressions */
  if (val1.type == et_symbol || val2.type == et_symbol)
    {
      eval_error = ERR_BADEXPR;
      return err_value;
    }

  /* get result type, and perform operation in that type */
  et = result_type(val1.type, val2.type);
  switch (et)
    {
    case et_double:
      val.type = et_double;
      val.value.as_double = eval_as_double(val1) / eval_as_double(val2);
      break;
    case et_float:
      val.type = et_float;
      val.value.as_float = eval_as_float(val1) / eval_as_float(val2);
      break;
#ifdef HOST_HAS_QWORD
    case et_qword:
      val.type = et_qword;
      val.value.as_qword = eval_as_qword(val1) / eval_as_qword(val2);
      break;
    case et_sqword:
      val.type = et_sqword;
      val.value.as_sqword = eval_as_sqword(val1) / eval_as_sqword(val2);
      break;
#endif /* HOST_HAS_QWORD */
    case et_addr:
      val.type = et_addr;
      val.value.as_addr = eval_as_addr(val1) / eval_as_addr(val2);
      break;
    case et_uint:
      val.type = et_uint;
      val.value.as_uint = eval_as_uint(val1) / eval_as_uint(val2);
      break;
    case et_int:
      val.type = et_int;
      val.value.as_int = eval_as_int(val1) / eval_as_int(val2);
      break;
    default:
      panic("bogus expression type");
    }

  return val;
}
Beispiel #2
0
char *						/* err str, NULL for no err */
md_reg_obj(struct regs_t *regs,			/* registers to access */
	   int is_write,			/* access type */
	   enum md_reg_type rt,			/* reg bank to probe */
	   int reg,				/* register number */
	   struct eval_value_t *val)		/* input, output */
{
  switch (rt)
    {
    case rt_gpr:
      if (reg < 0 || reg >= MD_NUM_IREGS)
	return "register number out of range";

      if (!is_write)
	{
	  val->type = et_quad;
	  val->value.as_quad = regs->regs_R[reg];
	}
      else
	regs->regs_R[reg] = eval_as_quad(*val);
      break;

    case rt_lpr:
      if (reg < 0 || reg >= MD_NUM_FREGS)
	return "register number out of range";

      if (!is_write)
	{
	  val->type = et_quad;
	  val->value.as_quad = regs->regs_F.q[reg];
	}
      else
	regs->regs_F.q[reg] = eval_as_quad(*val);
      break;

    case rt_fpr:
      if (reg < 0 || reg >= MD_NUM_FREGS)
	return "register number out of range";

      if (!is_write)
	{
	  val->type = et_double;
	  val->value.as_double = regs->regs_F.d[reg];
	}
      else
	regs->regs_F.d[reg] = eval_as_double(*val);
      break;

    case rt_ctrl:
      switch (reg)
	{
	case /* FPCR */0:
	  if (!is_write)
	    {
	      val->type = et_quad;
	      val->value.as_quad = regs->regs_C.fpcr;
	    }
	  else
	    regs->regs_C.fpcr = eval_as_quad(*val);
	  break;

	case /* UNIQ */1:
	  if (!is_write)
	    {
	      val->type = et_quad;
	      val->value.as_quad = regs->regs_C.uniq;
	    }
	  else
	    regs->regs_C.uniq = eval_as_quad(*val);
	  break;

	default:
	  return "register number out of range";
	}
      break;

    case rt_PC:
      if (!is_write)
	{
	  val->type = et_addr;
	  val->value.as_addr = regs->regs_PC;
	}
      else
	regs->regs_PC = eval_as_addr(*val);
      break;

    case rt_NPC:
      if (!is_write)
	{
	  val->type = et_addr;
	  val->value.as_addr = regs->regs_NPC;
	}
      else
	regs->regs_NPC = eval_as_addr(*val);
      break;

    default:
      panic("bogus register bank");
    }

  /* no error */
  return NULL;
}
Beispiel #3
0
char *						/* err str, NULL for no err */
md_reg_obj(struct regs_t *regs,			/* registers to access */
	   int is_write,			/* access type */
	   enum md_reg_type rt,			/* reg bank to probe */
	   int reg,				/* register number */
	   struct eval_value_t *val)		/* input, output */
{
  switch (rt)
    {
    case rt_gpr:
      if (reg < 0 || reg >= MD_NUM_IREGS)
	return "register number out of range";

      if (!is_write)
	{
	  val->type = et_uint;
	  val->value.as_uint = regs->regs_R[reg];
	}
      else
	regs->regs_R[reg] = eval_as_uint(*val);
      break;

    case rt_lpr:
      if (reg < 0 || reg >= MD_NUM_FREGS)
	return "register number out of range";

      if (!is_write)
	{
	  val->type = et_uint;
	  val->value.as_uint = regs->regs_F.l[reg];
	}
      else
	regs->regs_F.l[reg] = eval_as_uint(*val);
      break;

    case rt_fpr:
      if (reg < 0 || reg >= MD_NUM_FREGS)
	return "register number out of range";

      if (!is_write)
	{
	  val->type = et_float;
	  val->value.as_float = regs->regs_F.f[reg];
	}
      else
	regs->regs_F.f[reg] = eval_as_float(*val);
      break;

    case rt_dpr:
      if (reg < 0 || reg >= MD_NUM_FREGS/2)
	return "register number out of range";

      if (!is_write)
	{
	  val->type = et_double;
	  val->value.as_double = regs->regs_F.d[reg];
	}
      else
	regs->regs_F.d[reg] = eval_as_double(*val);
      break;

    case rt_ctrl:
      switch (reg)
	{
	case /* HI */0:
	  if (!is_write)
	    {
	      val->type = et_uint;
	      val->value.as_uint = regs->regs_C.hi;
	    }
	  else
	    regs->regs_C.hi = eval_as_uint(*val);
	  break;

	case /* LO */1:
	  if (!is_write)
	    {
	      val->type = et_uint;
	      val->value.as_uint = regs->regs_C.lo;
	    }
	  else
	    regs->regs_C.lo = eval_as_uint(*val);
	  break;

	case /* FCC */2:
	  if (!is_write)
	    {
	      val->type = et_int;
	      val->value.as_int = regs->regs_C.fcc;
	    }
	  else
	    regs->regs_C.fcc = eval_as_uint(*val);
	  break;

	default:
	  return "register number out of range";
	}
      break;

    case rt_PC:
      if (!is_write)
	{
	  val->type = et_addr;
	  val->value.as_addr = regs->regs_PC;
	}
      else
	regs->regs_PC = eval_as_addr(*val);
      break;

    case rt_NPC:
      if (!is_write)
	{
	  val->type = et_addr;
	  val->value.as_addr = regs->regs_NPC;
	}
      else
	regs->regs_NPC = eval_as_addr(*val);
      break;

    default:
      panic("bogus register bank");
    }

  /* no error */
  return NULL;
}