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

📄 armemu.c

📁 这是Skyeye 0.9 版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		    {
		      myinstrnum++;
		      if (myinstrnum >= skyeye_config.log.length)
			{
			  myinstrnum = 0;
			  fflush (skyeye_logfd);
			  fseek (skyeye_logfd, 0L, SEEK_SET);
			}
		    }
		}
	      //SKYEYE_OUTREGS(skyeye_logfd);
	      //SKYEYE_OUTMOREREGS(skyeye_logfd);
	    }
	}
#if 0				/* Enable this for a helpful bit of debugging when tracing is needed.  */
      fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
      if (instr == 0)
	abort ();
#endif
#if 0				/* Enable this code to help track down stack alignment bugs.  */
      {
	static ARMword old_sp = -1;

	if (old_sp != state->Reg[13])
	  {
	    old_sp = state->Reg[13];
	    fprintf (stderr, "pc: %08x: SP set to %08x%s\n",
		     pc & ~1, old_sp, (old_sp % 8) ? " [UNALIGNED!]" : "");
	  }
      }
#endif

      if (state->Exception)
	{
	  /* Any exceptions ?  */
	  if (state->NresetSig == LOW)
	    {
	      ARMul_Abort (state, ARMul_ResetV);

	      /*added energy_prof statement by ksh in 2004-11-26 */
	      //chy 2005-07-28 for standalone
	      //ARMul_do_energy(state,instr,pc);
	      break;
	    }
	  else if (!state->NfiqSig && !FFLAG)
	    {
	      ARMul_Abort (state, ARMul_FIQV);
	      /*added energy_prof statement by ksh in 2004-11-26 */
	      //chy 2005-07-28 for standalone
	      //ARMul_do_energy(state,instr,pc);
	      break;
	    }
	  else if (!state->NirqSig && !IFLAG)
	    {
	      ARMul_Abort (state, ARMul_IRQV);
	      /*added energy_prof statement by ksh in 2004-11-26 */
	      //chy 2005-07-28 for standalone
	      //ARMul_do_energy(state,instr,pc);
	      break;
	    }
	}

//teawater add for arm2x86 2005.04.26-------------------------------------------
      if (state->tea_pc)
	{
	  int i;

	  if (state->tea_reg_fd)
	    {
	      fprintf (state->tea_reg_fd, "\n");
	      for (i = 0; i < 15; i++)
		{
		  fprintf (state->tea_reg_fd, "%x,", state->Reg[i]);
		}
	      fprintf (state->tea_reg_fd, "%x,", pc);
	      state->Cpsr = ARMul_GetCPSR (state);
	      fprintf (state->tea_reg_fd, "%x\n", state->Cpsr);
	    }
	  else
	    {
	      printf ("\n");
	      for (i = 0; i < 15; i++)
		{
		  printf ("%x,", state->Reg[i]);
		}
	      printf ("%x,", pc);
	      state->Cpsr = ARMul_GetCPSR (state);
	      printf ("%x\n", state->Cpsr);
	    }
	}
//AJ2D--------------------------------------------------------------------------

      if (state->CallDebug > 0)
	{
	  instr = ARMul_Debug (state, pc, instr);
	  if (state->Emulate < ONCE)
	    {
	      state->NextInstr = RESUME;
	      break;
	    }
	  if (state->Debug)
	    {
	      fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n", pc,
		       instr, state->Mode);
	      (void) fgetc (stdin);
	    }
	}
      else if (state->Emulate < ONCE)
	{
	  state->NextInstr = RESUME;
	  break;
	}
      io_do_cycle (state);
      state->NumInstrs++;

#ifdef MODET
      /* Provide Thumb instruction decoding. If the processor is in Thumb
         mode, then we can simply decode the Thumb instruction, and map it
         to the corresponding ARM instruction (by directly loading the
         instr variable, and letting the normal ARM simulator
         execute). There are some caveats to ensure that the correct
         pipelined PC value is used when executing Thumb code, and also for
         dealing with the BL instruction.  */
      if (TFLAG)
	{
	  ARMword new;

	  /* Check if in Thumb mode.  */
	  switch (ARMul_ThumbDecode (state, pc, instr, &new))
	    {
	    case t_undefined:
	      /* This is a Thumb instruction.  */
	      ARMul_UndefInstr (state, instr);
	      goto donext;

	    case t_branch:
	      /* Already processed.  */
	      goto donext;

	    case t_decoded:
	      /* ARM instruction available.  */
	      instr = new;
	      /* So continue instruction decoding.  */
	      break;
	    default:
	      break;
	    }
	}
#endif

      /* Check the condition codes.  */
      if ((temp = TOPBITS (28)) == AL)
	/* Vile deed in the need for speed.  */
	goto mainswitch;

      /* Check the condition code.  */
      switch ((int) TOPBITS (28))
	{
	case AL:
	  temp = TRUE;
	  break;
	case NV:
	  if (state->is_v5)
	    {
	      if (BITS (25, 27) == 5)	/* BLX(1) */
		{
		  ARMword dest;

		  state->Reg[14] = pc + 4;

		  /* Force entry into Thumb mode.  */
		  dest = pc + 8 + 1;
		  if (BIT (23))
		    dest += (NEGBRANCH + (BIT (24) << 1));
		  else
		    dest += POSBRANCH + (BIT (24) << 1);

		  WriteR15Branch (state, dest);
		  goto donext;
		}
	      else if ((instr & 0xFC70F000) == 0xF450F000)
		/* The PLD instruction.  Ignored.  */
		goto donext;
	      else if (((instr & 0xfe500f00) == 0xfc100100)
		       || ((instr & 0xfe500f00) == 0xfc000100))
		/* wldrw and wstrw are unconditional.  */
		goto mainswitch;
	      else
		/* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2.  */
		ARMul_UndefInstr (state, instr);
	    }
	  temp = FALSE;
	  break;
	case EQ:
	  temp = ZFLAG;
	  break;
	case NE:
	  temp = !ZFLAG;
	  break;
	case VS:
	  temp = VFLAG;
	  break;
	case VC:
	  temp = !VFLAG;
	  break;
	case MI:
	  temp = NFLAG;
	  break;
	case PL:
	  temp = !NFLAG;
	  break;
	case CS:
	  temp = CFLAG;
	  break;
	case CC:
	  temp = !CFLAG;
	  break;
	case HI:
	  temp = (CFLAG && !ZFLAG);
	  break;
	case LS:
	  temp = (!CFLAG || ZFLAG);
	  break;
	case GE:
	  temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
	  break;
	case LT:
	  temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
	  break;
	case GT:
	  temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG));
	  break;
	case LE:
	  temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
	  break;
	}			/* cc check */

//chy 2003-08-24 now #if 0 .... #endif  process cp14, cp15.reg14, I disable it...
#if 0
      /* Handle the Clock counter here.  */
      if (state->is_XScale)
	{
	  ARMword cp14r0;
	  int ok;

	  ok = state->CPRead[14] (state, 0, &cp14r0);

	  if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE))
	    {
	      unsigned long newcycles, nowtime = ARMul_Time (state);

	      newcycles = nowtime - state->LastTime;
	      state->LastTime = nowtime;

	      if (cp14r0 & ARMul_CP14_R0_CCD)
		{
		  if (state->CP14R0_CCD == -1)
		    state->CP14R0_CCD = newcycles;
		  else
		    state->CP14R0_CCD += newcycles;

		  if (state->CP14R0_CCD >= 64)
		    {
		      newcycles = 0;

		      while (state->CP14R0_CCD >= 64)
			state->CP14R0_CCD -= 64, newcycles++;

		      goto check_PMUintr;
		    }
		}
	      else
		{
		  ARMword cp14r1;
		  int do_int = 0;

		  state->CP14R0_CCD = -1;
		check_PMUintr:
		  cp14r0 |= ARMul_CP14_R0_FLAG2;
		  (void) state->CPWrite[14] (state, 0, cp14r0);

		  ok = state->CPRead[14] (state, 1, &cp14r1);

		  /* Coded like this for portability.  */
		  while (ok && newcycles)
		    {
		      if (cp14r1 == 0xffffffff)
			{
			  cp14r1 = 0;
			  do_int = 1;
			}
		      else
			cp14r1++;

		      newcycles--;
		    }

		  (void) state->CPWrite[14] (state, 1, cp14r1);

		  if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2))
		    {
		      ARMword temp;

		      if (state->CPRead[13] (state, 8, &temp)
			  && (temp & ARMul_CP13_R8_PMUS))
			ARMul_Abort (state, ARMul_FIQV);
		      else
			ARMul_Abort (state, ARMul_IRQV);
		    }
		}
	    }
	}

      /* Handle hardware instructions breakpoints here.  */
      if (state->is_XScale)
	{
	  if ((pc | 3) == (read_cp15_reg (14, 0, 8) | 2)
	      || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2))
	    {
	      if (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB))
		ARMul_OSHandleSWI (state, SWI_Breakpoint);
	    }
	}
#endif

      /* Actual execution of instructions begins here.  */
      /* If the condition codes don't match, stop here.  */
      if (temp)
	{
	mainswitch:

	  if (state->is_XScale)
	    {
	      if (BIT (20) == 0 && BITS (25, 27) == 0)
		{
		  if (BITS (4, 7) == 0xD)
		    {
		      /* XScale Load Consecutive insn.  */
		      ARMword temp = GetLS7RHS (state, instr);
		      ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
		      ARMword addr = BIT (24) ? temp2 : LHS;

		      if (BIT (12))
			ARMul_UndefInstr (state, instr);
		      else if (addr & 7)
			/* Alignment violation.  */
			ARMul_Abort (state, ARMul_DataAbortV);
		      else
			{
			  int wb = BIT (21) || (!BIT (24));

			  state->Reg[BITS (12, 15)] =
			    ARMul_LoadWordN (state, addr);
			  state->Reg[BITS (12, 15) + 1] =
			    ARMul_LoadWordN (state, addr + 4);
			  if (wb)
			    LSBase = temp2;
			}

		      goto donext;
		    }
		  else if (BITS (4, 7) == 0xF)
		    {
		      /* XScale Store Consecutive insn.  */
		      ARMword temp = GetLS7RHS (state, instr);
		      ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
		      ARMword addr = BIT (24) ? temp2 : LHS;

		      if (BIT (12))
			ARMul_UndefInstr (state, instr);
		      else if (addr & 7)
			/* Alignment violation.  */
			ARMul_Abort (state, ARMul_DataAbortV);
		      else
			{
			  ARMul_StoreWordN (state, addr,
					    state->Reg[BITS (12, 15)]);
			  ARMul_StoreWordN (state, addr + 4,
					    state->Reg[BITS (12, 15) + 1]);

			  if (BIT (21) || !BIT (24))
			    LSBase = temp2;
			}

		      goto donext;
		    }
		}
	      //chy 2003-09-03 TMRRC(iwmmxt.c) and MRA has the same decoded instr????
	      //Now, I commit iwmmxt process, may be future, I will change it!!!! 
	      //if (ARMul_HandleIwmmxt (state, instr))
	      //        goto donext;
	    }

	  switch ((int) BITS (20, 27))
	    {
	      /* Data Processing Register RHS Instructions.  */

	    case 0x00:		/* AND reg and MUL */
#ifdef MODET
	      if (BITS (4, 11) == 0xB)
		{
		  /* STRH register offset, no write-back, down, post indexed.  */
		  SHDOWNWB ();
		  break;
		}
	      if (BITS (4, 7) == 0xD)
		{
		  Handle_Load_Double (state, instr);
		  break;
		}
	      if (BITS (4, 7) == 0xF)
		{
		  Handle_Store_Double (state, instr);
		  break;
		}
#endif
	      if (BITS (4, 7) == 9)
		{
		  /* MUL */
		  rhs = state->Reg[MULRHSReg];
		  if (MULLHSReg == MULDESTReg)
		    {
		      UNDEF_MULDestEQOp1;
		      state->Reg[MULDESTReg] = 0;
		    }
		  else if (MULDESTReg != 15)
		    state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs;
		  else
		    UNDEF_MULPCDest;

		  for (dest = 0, temp = 0; dest < 32; dest++)
		    if (rhs & (1L << dest))
		      temp = dest;

		  /* Mult takes this many/2 I cycles.  */
		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
		}
	      else
		{
		  /* AND reg.  */
		  rhs = DPRegRHS;
		  dest = LHS & rhs;
		  WRITEDEST (dest);
		}
	      break;

	    case 0x01:		/* ANDS reg and MULS */
#ifdef MODET
	      if ((BITS (4, 11) & 0xF9) == 0x9)
		/* LDR register offset, no write-back, down, post indexed.  */
		LHPOSTDOWN ();
	      /* Fall through to rest of decoding.  */
#endif
	      if (BITS (4, 7) == 9)
		{
		  /* MULS */
		  rhs = state->Reg[MULRHSReg];

		  if (MULLHSReg == MULDESTReg)
		    {
		      UNDEF_MULDestEQOp1;
		      state->Reg[MULDESTReg] = 0;
		      CLEARN;
		      SETZ;
		    }
		  else if (MULDESTReg != 15)
		    {
		      dest = state->Reg[MULLHSReg] * rhs;
		      ARMul_NegZero (state, dest);
		      state->Reg[MULDESTReg] = dest;
		    }
		  else
		    UNDEF_MULPCDest;

		  for (dest = 0, temp = 0; dest < 32; dest++)
		    if (rhs & (1L << dest))
		      temp = dest;

		  /* Mult takes this many/2 I cycles.  */
		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
		}
	      else
		{
		  /* ANDS reg.  */
		  rhs = DPSRegRHS;
		  dest = LHS & rhs;
		  WRITESDEST (dest);
		}
	      break;

	    case 0x02:		/* EOR reg and MLA */
#ifdef MODET
	      if (BITS (4, 11) == 0xB)
		{
		  /* STRH register offset, write-back, down, post indexed.  */
		  SHDOWNWB ();
		  break;
		}
#endif
	      if (BITS (4, 7) == 9)
		{		/* MLA */
		  rhs = state->Reg[MULRHSReg];
		  if (MULLHSReg == MULDESTReg)
		    {
		      UNDEF_MULDestEQOp1;
		      state->Reg[MULDESTReg] = state->Reg[MULACCReg];

⌨️ 快捷键说明

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