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

📄 maverick.c

📁 这是Skyeye 0.9 版本的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data);

      /* 32bit ints should be sign extended to 64bits when loaded.  */
      mv_setReg64int (DEST_REG, (long long) data);

      return ARMul_DONE;
    }
}

unsigned
DSPSTC4 (ARMul_State * state ATTRIBUTE_UNUSED,
	 unsigned type, ARMword instr, ARMword * data)
{
  static unsigned words;

  if (type != ARMul_DATA)
    {
      words = 0;
      return ARMul_DONE;
    }

  if (BIT (22))
    {
      /* It's a long access, get two words.  */
      /* cfstrd */
      printfdbg ("cfstrd\n");

      if (words == 0)
	{
	  if (state->bigendSig)
	    *data = (ARMword) DSPregs[DEST_REG].upper.i;
	  else
	    *data = (ARMword) DSPregs[DEST_REG].lower.i;
	}
      else
	{
	  if (state->bigendSig)
	    *data = (ARMword) DSPregs[DEST_REG].lower.i;
	  else
	    *data = (ARMword) DSPregs[DEST_REG].upper.i;
	}

      ++words;

      if (words == 2)
	{
	  printfdbg ("\tmem = mvd%d = %g\n", DEST_REG,
		     mv_getRegDouble (DEST_REG));

	  return ARMul_DONE;
	}
      else
	return ARMul_INC;
    }
  else
    {
      /* Get just one word.  */
      /* cfstrs */
      printfdbg ("cfstrs mvf%d <-- %f\n", DEST_REG,
		 DSPregs[DEST_REG].upper.f);

      *data = (ARMword) DSPregs[DEST_REG].upper.i;

      return ARMul_DONE;
    }
}

unsigned
DSPSTC5 (ARMul_State * state ATTRIBUTE_UNUSED,
	 unsigned type, ARMword instr, ARMword * data)
{
  static unsigned words;

  if (type != ARMul_DATA)
    {
      words = 0;
      return ARMul_DONE;
    }

  if (BIT (22))
    {
      /* It's a long access, store two words.  */
      /* cfstr64 */
      printfdbg ("cfstr64\n");

      if (words == 0)
	{
	  if (state->bigendSig)
	    *data = (ARMword) DSPregs[DEST_REG].upper.i;
	  else
	    *data = (ARMword) DSPregs[DEST_REG].lower.i;
	}
      else
	{
	  if (state->bigendSig)
	    *data = (ARMword) DSPregs[DEST_REG].lower.i;
	  else
	    *data = (ARMword) DSPregs[DEST_REG].upper.i;
	}

      ++words;

      if (words == 2)
	{
	  printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG,
		     mv_getReg64int (DEST_REG));

	  return ARMul_DONE;
	}
      else
	return ARMul_INC;
    }
  else
    {
      /* Store just one word.  */
      /* cfstr32 */
      *data = (ARMword) DSPregs[DEST_REG].lower.i;

      printfdbg ("cfstr32 MEM = %d\n", (int) *data);

      return ARMul_DONE;
    }
}

unsigned
DSPCDP4 (ARMul_State * state, unsigned type, ARMword instr)
{
  int opcode2;

  opcode2 = BITS (5, 7);

  switch (BITS (20, 21))
    {
    case 0:
      switch (opcode2)
	{
	case 0:		/* cfcpys */
	  printfdbg ("cfcpys mvf%d = mvf%d = %f\n",
		     DEST_REG, SRC1_REG, DSPregs[SRC1_REG].upper.f);
	  DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f;
	  break;

	case 1:		/* cfcpyd */
	  printfdbg ("cfcpyd mvd%d = mvd%d = %g\n",
		     DEST_REG, SRC1_REG, mv_getRegDouble (SRC1_REG));
	  mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG));
	  break;

	case 2:		/* cfcvtds */
	  printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n",
		     DEST_REG, SRC1_REG, (float) mv_getRegDouble (SRC1_REG));
	  DSPregs[DEST_REG].upper.f = (float) mv_getRegDouble (SRC1_REG);
	  break;

	case 3:		/* cfcvtsd */
	  printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n",
		     DEST_REG, SRC1_REG, (double) DSPregs[SRC1_REG].upper.f);
	  mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].upper.f);
	  break;

	case 4:		/* cfcvt32s */
	  printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n",
		     DEST_REG, SRC1_REG, (float) DSPregs[SRC1_REG].lower.i);
	  DSPregs[DEST_REG].upper.f = (float) DSPregs[SRC1_REG].lower.i;
	  break;

	case 5:		/* cfcvt32d */
	  printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n",
		     DEST_REG, SRC1_REG, (double) DSPregs[SRC1_REG].lower.i);
	  mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].lower.i);
	  break;

	case 6:		/* cfcvt64s */
	  printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n",
		     DEST_REG, SRC1_REG, (float) mv_getReg64int (SRC1_REG));
	  DSPregs[DEST_REG].upper.f = (float) mv_getReg64int (SRC1_REG);
	  break;

	case 7:		/* cfcvt64d */
	  printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n",
		     DEST_REG, SRC1_REG, (double) mv_getReg64int (SRC1_REG));
	  mv_setRegDouble (DEST_REG, (double) mv_getReg64int (SRC1_REG));
	  break;
	}
      break;

    case 1:
      switch (opcode2)
	{
	case 0:		/* cfmuls */
	  printfdbg ("cfmuls mvf%d = mvf%d = %f\n",
		     DEST_REG,
		     SRC1_REG,
		     DSPregs[SRC1_REG].upper.f * DSPregs[SRC2_REG].upper.f);

	  DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
	    * DSPregs[SRC2_REG].upper.f;
	  break;

	case 1:		/* cfmuld */
	  printfdbg ("cfmuld mvd%d = mvd%d = %g\n",
		     DEST_REG,
		     SRC1_REG,
		     mv_getRegDouble (SRC1_REG) * mv_getRegDouble (SRC2_REG));

	  mv_setRegDouble (DEST_REG,
			   mv_getRegDouble (SRC1_REG)
			   * mv_getRegDouble (SRC2_REG));
	  break;

	default:
	  fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
	  cirrus_not_implemented ("unknown");
	  break;
	}
      break;

    case 3:
      switch (opcode2)
	{
	case 0:		/* cfabss */
	  DSPregs[DEST_REG].upper.f = (DSPregs[SRC1_REG].upper.f < 0.0F ?
				       -DSPregs[SRC1_REG].upper.f
				       : DSPregs[SRC1_REG].upper.f);
	  printfdbg ("cfabss mvf%d = |mvf%d| = %f\n",
		     DEST_REG, SRC1_REG, DSPregs[DEST_REG].upper.f);
	  break;

	case 1:		/* cfabsd */
	  mv_setRegDouble (DEST_REG,
			   (mv_getRegDouble (SRC1_REG) < 0.0 ?
			    -mv_getRegDouble (SRC1_REG)
			    : mv_getRegDouble (SRC1_REG)));
	  printfdbg ("cfabsd mvd%d = |mvd%d| = %g\n",
		     DEST_REG, SRC1_REG, mv_getRegDouble (DEST_REG));
	  break;

	case 2:		/* cfnegs */
	  DSPregs[DEST_REG].upper.f = -DSPregs[SRC1_REG].upper.f;
	  printfdbg ("cfnegs mvf%d = -mvf%d = %f\n",
		     DEST_REG, SRC1_REG, DSPregs[DEST_REG].upper.f);
	  break;

	case 3:		/* cfnegd */
	  mv_setRegDouble (DEST_REG, -mv_getRegDouble (SRC1_REG));
	  printfdbg ("cfnegd mvd%d = -mvd%d = %g\n",
		     DEST_REG, mv_getRegDouble (DEST_REG));
	  break;

	case 4:		/* cfadds */
	  DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
	    + DSPregs[SRC2_REG].upper.f;
	  printfdbg ("cfadds mvf%d = mvf%d + mvf%d = %f\n",
		     DEST_REG, SRC1_REG, SRC2_REG, DSPregs[DEST_REG].upper.f);
	  break;

	case 5:		/* cfaddd */
	  mv_setRegDouble (DEST_REG,
			   mv_getRegDouble (SRC1_REG)
			   + mv_getRegDouble (SRC2_REG));
	  printfdbg ("cfaddd: mvd%d = mvd%d + mvd%d = %g\n",
		     DEST_REG,
		     SRC1_REG, SRC2_REG, mv_getRegDouble (DEST_REG));
	  break;

	case 6:		/* cfsubs */
	  DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
	    - DSPregs[SRC2_REG].upper.f;
	  printfdbg ("cfsubs: mvf%d = mvf%d - mvf%d = %f\n",
		     DEST_REG, SRC1_REG, SRC2_REG, DSPregs[DEST_REG].upper.f);
	  break;

	case 7:		/* cfsubd */
	  mv_setRegDouble (DEST_REG,
			   mv_getRegDouble (SRC1_REG)
			   - mv_getRegDouble (SRC2_REG));
	  printfdbg ("cfsubd: mvd%d = mvd%d - mvd%d = %g\n",
		     DEST_REG,
		     SRC1_REG, SRC2_REG, mv_getRegDouble (DEST_REG));
	  break;
	}
      break;

    default:
      fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
      cirrus_not_implemented ("unknown");
      break;
    }

  return ARMul_DONE;
}

unsigned
DSPCDP5 (ARMul_State * state, unsigned type, ARMword instr)
{
  int opcode2;
  char shift;

  opcode2 = BITS (5, 7);

  /* Shift constants are 7bit signed numbers in bits 0..3|5..7.  */
  shift = BITS (0, 3) | (BITS (5, 7)) << 4;
  if (shift & 0x40)
    shift |= 0xc0;

  switch (BITS (20, 21))
    {
    case 0:
      /* cfsh32 */
      printfdbg ("cfsh32 %s amount=%d\n", shift < 0 ? "right" : "left",
		 shift);
      if (shift < 0)
	/* Negative shift is a right shift.  */
	DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -shift;
      else
	/* Positive shift is a left shift.  */
	DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i << shift;
      break;

    case 1:
      switch (opcode2)
	{
	case 0:		/* cfmul32 */
	  DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
	    * DSPregs[SRC2_REG].lower.i;
	  printfdbg ("cfmul32 mvfx%d = mvfx%d * mvfx%d = %d\n",
		     DEST_REG, SRC1_REG, SRC2_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 1:		/* cfmul64 */
	  mv_setReg64int (DEST_REG,
			  mv_getReg64int (SRC1_REG)
			  * mv_getReg64int (SRC2_REG));
	  printfdbg ("cfmul64 mvdx%d = mvdx%d * mvdx%d = %lld\n",
		     DEST_REG, SRC1_REG, SRC2_REG, mv_getReg64int (DEST_REG));
	  break;

	case 2:		/* cfmac32 */
	  DSPregs[DEST_REG].lower.i
	    += DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
	  printfdbg ("cfmac32 mvfx%d += mvfx%d * mvfx%d = %d\n",
		     DEST_REG, SRC1_REG, SRC2_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 3:		/* cfmsc32 */
	  DSPregs[DEST_REG].lower.i
	    -= DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
	  printfdbg ("cfmsc32 mvfx%d -= mvfx%d * mvfx%d = %d\n",
		     DEST_REG, SRC1_REG, SRC2_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 4:		/* cfcvts32 */
	  /* fixme: this should round */
	  DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
	  printfdbg ("cfcvts32 mvfx%d = mvf%d = %d\n",
		     DEST_REG, SRC1_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 5:		/* cfcvtd32 */
	  /* fixme: this should round */
	  DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
	  printfdbg ("cfcvtd32 mvdx%d = mvd%d = %d\n",
		     DEST_REG, SRC1_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 6:		/* cftruncs32 */
	  DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
	  printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n",
		     DEST_REG, SRC1_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 7:		/* cftruncd32 */
	  DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
	  printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n",
		     DEST_REG, SRC1_REG, DSPregs[DEST_REG].lower.i);
	  break;
	}
      break;

    case 2:
      /* cfsh64 */
      printfdbg ("cfsh64\n");

      if (shift < 0)
	/* Negative shift is a right shift.  */
	mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG) >> -shift);
      else
	/* Positive shift is a left shift.  */
	mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG) << shift);
      printfdbg ("\t%llx\n", mv_getReg64int (DEST_REG));
      break;

    case 3:
      switch (opcode2)
	{
	case 0:		/* cfabs32 */
	  DSPregs[DEST_REG].lower.i = (DSPregs[SRC1_REG].lower.i < 0
				       ? -DSPregs[SRC1_REG].lower.
				       i : DSPregs[SRC1_REG].lower.i);
	  printfdbg ("cfabs32 mvfx%d = |mvfx%d| = %d\n", DEST_REG, SRC1_REG,
		     SRC2_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 1:		/* cfabs64 */
	  mv_setReg64int (DEST_REG,
			  (mv_getReg64int (SRC1_REG) < 0
			   ? -mv_getReg64int (SRC1_REG)
			   : mv_getReg64int (SRC1_REG)));
	  printfdbg ("cfabs64 mvdx%d = |mvdx%d| = %lld\n",
		     DEST_REG, SRC1_REG, SRC2_REG, mv_getReg64int (DEST_REG));
	  break;

	case 2:		/* cfneg32 */
	  DSPregs[DEST_REG].lower.i = -DSPregs[SRC1_REG].lower.i;
	  printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n",
		     DEST_REG, SRC1_REG, SRC2_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 3:		/* cfneg64 */
	  mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG));
	  printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n",
		     DEST_REG, SRC1_REG, SRC2_REG, mv_getReg64int (DEST_REG));
	  break;

	case 4:		/* cfadd32 */
	  DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
	    + DSPregs[SRC2_REG].lower.i;
	  printfdbg ("cfadd32 mvfx%d = mvfx%d + mvfx%d = %d\n",
		     DEST_REG, SRC1_REG, SRC2_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 5:		/* cfadd64 */
	  mv_setReg64int (DEST_REG,
			  mv_getReg64int (SRC1_REG)
			  + mv_getReg64int (SRC2_REG));
	  printfdbg ("cfadd64 mvdx%d = mvdx%d + mvdx%d = %lld\n",
		     DEST_REG, SRC1_REG, SRC2_REG, mv_getReg64int (DEST_REG));
	  break;

	case 6:		/* cfsub32 */
	  DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
	    - DSPregs[SRC2_REG].lower.i;
	  printfdbg ("cfsub32 mvfx%d = mvfx%d - mvfx%d = %d\n",
		     DEST_REG, SRC1_REG, SRC2_REG, DSPregs[DEST_REG].lower.i);
	  break;

	case 7:		/* cfsub64 */
	  mv_setReg64int (DEST_REG,
			  mv_getReg64int (SRC1_REG)
			  - mv_getReg64int (SRC2_REG));
	  printfdbg ("cfsub64 mvdx%d = mvdx%d - mvdx%d = %d\n",
		     DEST_REG, SRC1_REG, SRC2_REG, mv_getReg64int (DEST_REG));
	  break;
	}
      break;

    default:
      fprintf (stderr, "unknown opcode in DSPCDP5 0x%x\n", instr);
      cirrus_not_implemented ("unknown");
      break;
    }

  return ARMul_DONE;
}

unsigned
DSPCDP6 (ARMul_State * state, unsigned type, ARMword instr)
{
  int opcode2;

  opcode2 = BITS (5, 7);

  switch (BITS (20, 21))
    {
    case 0:
      /* cfmadd32 */
      cirrus_not_implemented ("cfmadd32");
      break;

    case 1:
      /* cfmsub32 */
      cirrus_not_implemented ("cfmsub32");
      break;

    case 2:
      /* cfmadda32 */
      cirrus_not_implemented ("cfmadda32");
      break;

    case 3:
      /* cfmsuba32 */
      cirrus_not_implemented ("cfmsuba32");
      break;

    default:
      fprintf (stderr, "unknown opcode in DSPCDP6 0x%x\n", instr);
    }

  return ARMul_DONE;
}

/* Conversion functions.

   32-bit integers are stored in the LOWER half of a 64-bit physical
   register.

   Single precision floats are stored in the UPPER half of a 64-bit
   physical register.  */

static double
mv_getRegDouble (int regnum)
{
  reg_conv.ints[lsw_float_index] = DSPregs[regnum].upper.i;
  reg_conv.ints[msw_float_index] = DSPregs[regnum].lower.i;
  return reg_conv.d;
}

static void
mv_setRegDouble (int regnum, double val)
{
  reg_conv.d = val;
  DSPregs[regnum].upper.i = reg_conv.ints[lsw_float_index];
  DSPregs[regnum].lower.i = reg_conv.ints[msw_float_index];
}

static long long
mv_getReg64int (int regnum)
{
  reg_conv.ints[lsw_int_index] = DSPregs[regnum].lower.i;
  reg_conv.ints[msw_int_index] = DSPregs[regnum].upper.i;
  return reg_conv.ll;
}

static void
mv_setReg64int (int regnum, long long val)
{
  reg_conv.ll = val;
  DSPregs[regnum].lower.i = reg_conv.ints[lsw_int_index];
  DSPregs[regnum].upper.i = reg_conv.ints[msw_int_index];
}

/* Compute LSW in a double and a long long.  */

void
mv_compute_host_endianness (ARMul_State * state)
{
  static union
  {
    long long ll;
    long ints[2];
    long i;
    double d;
    float floats[2];
    float f;
  } conv;

  /* Calculate where's the LSW in a 64bit int.  */
  conv.ll = 45;

  if (conv.ints[0] == 0)
    {
      msw_int_index = 0;
      lsw_int_index = 1;
    }
  else
    {
      assert (conv.ints[1] == 0);
      msw_int_index = 1;
      lsw_int_index = 0;
    }

  /* Calculate where's the LSW in a double.  */
  conv.d = 3.0;

  if (conv.ints[0] == 0)
    {
      msw_float_index = 0;
      lsw_float_index = 1;
    }
  else
    {
      assert (conv.ints[1] == 0);
      msw_float_index = 1;
      lsw_float_index = 0;
    }

  printfdbg ("lsw_int_index   %d\n", lsw_int_index);
  printfdbg ("lsw_float_index %d\n", lsw_float_index);
}

⌨️ 快捷键说明

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