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

📄 armemu.c

📁 这是Skyeye 0.9 版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		/* LDR register offset, no write-back, down, pre indexed.  */
		LHPREDOWN ();
	      /* Continue with remaining instruction decode.  */
#endif
	      if (DESTReg == 15)
		{
		  /* TSTP reg */
#ifdef MODE32
		  state->Cpsr = GETSPSR (state->Bank);
		  ARMul_CPSRAltered (state);
#else
		  rhs = DPRegRHS;
		  temp = LHS & rhs;
		  SETR15PSR (temp);
#endif
		}
	      else
		{
		  /* TST reg */
		  rhs = DPSRegRHS;
		  dest = LHS & rhs;
		  ARMul_NegZero (state, dest);
		}
	      break;

	    case 0x12:		/* TEQ reg and MSR reg to CPSR (ARM6).  */
	      if (state->is_v5)
		{
		  if (BITS (4, 7) == 3)
		    {
		      /* BLX(2) */
		      ARMword temp;

		      if (TFLAG)
			temp = (pc + 2) | 1;
		      else
			temp = pc + 4;

		      WriteR15Branch (state, state->Reg[RHSReg]);
		      state->Reg[14] = temp;
		      break;
		    }
		}

	      if (state->is_v5e)
		{
		  if (BIT (4) == 0 && BIT (7) == 1
		      && (BIT (5) == 0 || BITS (12, 15) == 0))
		    {
		      /* ElSegundo SMLAWy/SMULWy insn.  */
		      unsigned long long op1 = state->Reg[BITS (0, 3)];
		      unsigned long long op2 = state->Reg[BITS (8, 11)];
		      unsigned long long result;

		      if (BIT (6))
			op2 >>= 16;
		      if (op1 & 0x80000000)
			op1 -= 1ULL << 32;
		      op2 &= 0xFFFF;
		      if (op2 & 0x8000)
			op2 -= 65536;
		      result = (op1 * op2) >> 16;

		      if (BIT (5) == 0)
			{
			  ARMword Rn = state->Reg[BITS (12, 15)];

			  if (AddOverflow (result, Rn, result + Rn))
			    SETS;
			  result += Rn;
			}
		      state->Reg[BITS (16, 19)] = result;
		      break;
		    }

		  if (BITS (4, 11) == 5)
		    {
		      /* ElSegundo QSUB insn.  */
		      ARMword op1 = state->Reg[BITS (0, 3)];
		      ARMword op2 = state->Reg[BITS (16, 19)];
		      ARMword result = op1 - op2;

		      if (SubOverflow (op1, op2, result))
			{
			  result = POS (result) ? 0x80000000 : 0x7fffffff;
			  SETS;
			}

		      state->Reg[BITS (12, 15)] = result;
		      break;
		    }
		}
#ifdef MODET
	      if (BITS (4, 11) == 0xB)
		{
		  /* STRH register offset, write-back, down, pre indexed.  */
		  SHPREDOWNWB ();
		  break;
		}
	      if (BITS (4, 27) == 0x12FFF1)
		{
		  /* BX */
		  WriteR15Branch (state, state->Reg[RHSReg]);
		  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 (state->is_v5)
		{
		  if (BITS (4, 7) == 0x7)
		    {
		      ARMword value;
		      extern int SWI_vector_installed;

		      /* Hardware is allowed to optionally override this
		         instruction and treat it as a breakpoint.  Since
		         this is a simulator not hardware, we take the position
		         that if a SWI vector was not installed, then an Abort
		         vector was probably not installed either, and so
		         normally this instruction would be ignored, even if an
		         Abort is generated.  This is a bad thing, since GDB
		         uses this instruction for its breakpoints (at least in
		         Thumb mode it does).  So intercept the instruction here
		         and generate a breakpoint SWI instead.  */
		      if (!SWI_vector_installed)
			ARMul_OSHandleSWI (state, SWI_Breakpoint);
		      else
			{
			  /* BKPT - normally this will cause an abort, but on the
			     XScale we must check the DCSR.  */
			  XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT,
					      pc);
			  if (!XScale_debug_moe
			      (state, ARMul_CP14_R10_MOE_BT))
			    break;
			}

		      /* Force the next instruction to be refetched.  */
		      state->NextInstr = RESUME;
		      break;
		    }
		}
	      if (DESTReg == 15)
		{
		  /* MSR reg to CPSR.  */
		  UNDEF_MSRPC;
		  temp = DPRegRHS;
#ifdef MODET
		  /* Don't allow TBIT to be set by MSR.  */
		  temp &= ~TBIT;
#endif
		  ARMul_FixCPSR (state, instr, temp);
		}
	      else
		UNDEF_Test;

	      break;

	    case 0x13:		/* TEQP reg */
#ifdef MODET
	      if ((BITS (4, 11) & 0xF9) == 0x9)
		/* LDR register offset, write-back, down, pre indexed.  */
		LHPREDOWNWB ();
	      /* Continue with remaining instruction decode.  */
#endif
	      if (DESTReg == 15)
		{
		  /* TEQP reg */
#ifdef MODE32
		  state->Cpsr = GETSPSR (state->Bank);
		  ARMul_CPSRAltered (state);
#else
		  rhs = DPRegRHS;
		  temp = LHS ^ rhs;
		  SETR15PSR (temp);
#endif
		}
	      else
		{
		  /* TEQ Reg.  */
		  rhs = DPSRegRHS;
		  dest = LHS ^ rhs;
		  ARMul_NegZero (state, dest);
		}
	      break;

	    case 0x14:		/* CMP reg and MRS SPSR and SWP byte.  */
	      if (state->is_v5e)
		{
		  if (BIT (4) == 0 && BIT (7) == 1)
		    {
		      /* ElSegundo SMLALxy insn.  */
		      unsigned long long op1 = state->Reg[BITS (0, 3)];
		      unsigned long long op2 = state->Reg[BITS (8, 11)];
		      unsigned long long dest;
		      unsigned long long result;

		      if (BIT (5))
			op1 >>= 16;
		      if (BIT (6))
			op2 >>= 16;
		      op1 &= 0xFFFF;
		      if (op1 & 0x8000)
			op1 -= 65536;
		      op2 &= 0xFFFF;
		      if (op2 & 0x8000)
			op2 -= 65536;

		      dest =
			(unsigned long long) state->Reg[BITS (16, 19)] << 32;
		      dest |= state->Reg[BITS (12, 15)];
		      dest += op1 * op2;
		      state->Reg[BITS (12, 15)] = dest;
		      state->Reg[BITS (16, 19)] = dest >> 32;
		      break;
		    }

		  if (BITS (4, 11) == 5)
		    {
		      /* ElSegundo QDADD insn.  */
		      ARMword op1 = state->Reg[BITS (0, 3)];
		      ARMword op2 = state->Reg[BITS (16, 19)];
		      ARMword op2d = op2 + op2;
		      ARMword result;

		      if (AddOverflow (op2, op2, op2d))
			{
			  SETS;
			  op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
			}

		      result = op1 + op2d;
		      if (AddOverflow (op1, op2d, result))
			{
			  SETS;
			  result = POS (result) ? 0x80000000 : 0x7fffffff;
			}

		      state->Reg[BITS (12, 15)] = result;
		      break;
		    }
		}
#ifdef MODET
	      if (BITS (4, 7) == 0xB)
		{
		  /* STRH immediate offset, no write-back, down, pre indexed.  */
		  SHPREDOWN ();
		  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, 11) == 9)
		{
		  /* SWP */
		  UNDEF_SWPPC;
		  temp = LHS;
		  BUSUSEDINCPCS;
#ifndef MODE32
		  if (VECTORACCESS (temp) || ADDREXCEPT (temp))
		    {
		      INTERNALABORT (temp);
		      (void) ARMul_LoadByte (state, temp);
		      (void) ARMul_LoadByte (state, temp);
		    }
		  else
#endif
		    DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]);
		  if (state->abortSig || state->Aborted)
		    TAKEABORT;
		}
	      else if ((BITS (0, 11) == 0) && (LHSReg == 15))
		{
		  /* MRS SPSR */
		  UNDEF_MRSPC;
		  DEST = GETSPSR (state->Bank);
		}
	      else
		UNDEF_Test;

	      break;

	    case 0x15:		/* CMPP reg.  */
#ifdef MODET
	      if ((BITS (4, 7) & 0x9) == 0x9)
		/* LDR immediate offset, no write-back, down, pre indexed.  */
		LHPREDOWN ();
	      /* Continue with remaining instruction decode.  */
#endif
	      if (DESTReg == 15)
		{
		  /* CMPP reg.  */
#ifdef MODE32
		  state->Cpsr = GETSPSR (state->Bank);
		  ARMul_CPSRAltered (state);
#else
		  rhs = DPRegRHS;
		  temp = LHS - rhs;
		  SETR15PSR (temp);
#endif
		}
	      else
		{
		  /* CMP reg.  */
		  lhs = LHS;
		  rhs = DPRegRHS;
		  dest = lhs - rhs;
		  ARMul_NegZero (state, dest);
		  if ((lhs >= rhs) || ((rhs | lhs) >> 31))
		    {
		      ARMul_SubCarry (state, lhs, rhs, dest);
		      ARMul_SubOverflow (state, lhs, rhs, dest);
		    }
		  else
		    {
		      CLEARC;
		      CLEARV;
		    }
		}
	      break;

	    case 0x16:		/* CMN reg and MSR reg to SPSR */
	      if (state->is_v5e)
		{
		  if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0)
		    {
		      /* ElSegundo SMULxy insn.  */
		      ARMword op1 = state->Reg[BITS (0, 3)];
		      ARMword op2 = state->Reg[BITS (8, 11)];
		      ARMword Rn = state->Reg[BITS (12, 15)];

		      if (BIT (5))
			op1 >>= 16;
		      if (BIT (6))
			op2 >>= 16;
		      op1 &= 0xFFFF;
		      op2 &= 0xFFFF;
		      if (op1 & 0x8000)
			op1 -= 65536;
		      if (op2 & 0x8000)
			op2 -= 65536;

		      state->Reg[BITS (16, 19)] = op1 * op2;
		      break;
		    }

		  if (BITS (4, 11) == 5)
		    {
		      /* ElSegundo QDSUB insn.  */
		      ARMword op1 = state->Reg[BITS (0, 3)];
		      ARMword op2 = state->Reg[BITS (16, 19)];
		      ARMword op2d = op2 + op2;
		      ARMword result;

		      if (AddOverflow (op2, op2, op2d))
			{
			  SETS;
			  op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
			}

		      result = op1 - op2d;
		      if (SubOverflow (op1, op2d, result))
			{
			  SETS;
			  result = POS (result) ? 0x80000000 : 0x7fffffff;
			}

		      state->Reg[BITS (12, 15)] = result;
		      break;
		    }
		}

	      if (state->is_v5)
		{
		  if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF)
		    {
		      /* ARM5 CLZ insn.  */
		      ARMword op1 = state->Reg[BITS (0, 3)];
		      int result = 32;

		      if (op1)
			for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1)
			  result++;

		      state->Reg[BITS (12, 15)] = result;
		      break;
		    }
		}
#ifdef MODET
	      if (BITS (4, 7) == 0xB)
		{
		  /* STRH immediate offset, write-back, down, pre indexed.  */
		  SHPREDOWNWB ();
		  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 (DESTReg == 15)
		{
		  /* MSR */
		  UNDEF_MSRPC;
		  ARMul_FixSPSR (state, instr, DPRegRHS);
		}
	      else
		{
		  UNDEF_Test;
		}
	      break;

	    case 0x17:		/* CMNP reg */
#ifdef MODET
	      if ((BITS (4, 7) & 0x9) == 0x9)
		/* LDR immediate offset, write-back, down, pre indexed.  */
		LHPREDOWNWB ();
	      /* Continue with remaining instruction decoding.  */
#endif
	      if (DESTReg == 15)
		{
#ifdef MODE32
		  state->Cpsr = GETSPSR (state->Bank);
		  ARMul_CPSRAltered (state);
#else
		  rhs = DPRegRHS;
		  temp = LHS + rhs;
		  SETR15PSR (temp);
#endif
		  break;
		}
	      else
		{
		  /* CMN reg.  */
		  lhs = LHS;
		  rhs = DPRegRHS;
		  dest = lhs + rhs;
		  ASSIGNZ (dest == 0);
		  if ((lhs | rhs) >> 30)
		    {
		      /* Possible C,V,N to set.  */
		      ASSIGNN (NEG (dest));
		      ARMul_AddCarry (state, lhs, rhs, dest);
		      ARMul_AddOverflow (state, lhs, rhs, dest);
		    }
		  else
		    {
		      CLEARN;
		      CLEARC;
		      CLEARV;
		    }
		}
	      break;

	    case 0x18:		/* ORR reg */
#ifdef MODET
	      if (BITS (4, 11) == 0xB)
		{
		  /* STRH register offset, no write-back, up, pre indexed.  */
		  SHPREUP ();
		  break;
		}
	      if (BITS (4, 7) == 0xD)
		{
		  Handle_Load_Double (state, instr);
		  break;
		}
	      if (BITS (4, 7) == 0xF)
		{
		  Handle_Store_Double (state, instr);
		  break;
		}
#endif
	      rhs = DPRegRHS;
	      dest = LHS | rhs;
	      WRITEDEST (dest);
	      break;

	    case 0x19:		/* ORRS reg */
#ifdef MODET
	      if ((BITS (4, 11) & 0xF9) == 0x9)
		/* LDR register offset, no write-back, up, pre indexed.  */
		LHPREUP ();

⌨️ 快捷键说明

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