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

📄 armemu.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		  CLEARV;		}	      WRITESDEST (dest);	      break;	    case 0x0a:		/* ADC reg */#ifdef MODET	      if (BITS (4, 11) == 0xB)		{		  /* STRH register offset, write-back, up, post-indexed.  */		  SHUPWB ();		  break;		}	      if (BITS (4, 7) == 0x9)		{		  /* MULL */		  /* 32x32=64 */		  ARMul_Icycles (state,				 MultiplyAdd64 (state, instr, LUNSIGNED,						LDEFAULT), 0L);		  break;		}#endif	      rhs = DPRegRHS;	      dest = LHS + rhs + CFLAG;	      WRITEDEST (dest);	      break;	    case 0x0b:		/* ADCS reg */#ifdef MODET	      if ((BITS (4, 11) & 0xF9) == 0x9)		/* LDR register offset, write-back, up, post indexed.  */		LHPOSTUP ();	      /* Fall through to remaining instruction decoding.  */	      if (BITS (4, 7) == 0x9)		{		  /* MULL */		  /* 32x32=64 */		  ARMul_Icycles (state,				 MultiplyAdd64 (state, instr, LUNSIGNED,						LSCC), 0L);		  break;		}#endif	      lhs = LHS;	      rhs = DPRegRHS;	      dest = lhs + rhs + CFLAG;	      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;		}	      WRITESDEST (dest);	      break;	    case 0x0c:		/* SBC reg */#ifdef MODET	      if (BITS (4, 7) == 0xB)		{		  /* STRH immediate offset, no write-back, up post indexed.  */		  SHUPWB ();		  break;		}	      if (BITS (4, 7) == 0xD)		{		  Handle_Load_Double (state, instr);		  break;		}	      if (BITS (4, 7) == 0xF)		{		  Handle_Store_Double (state, instr);		  break;		}	      if (BITS (4, 7) == 0x9)		{		  /* MULL */		  /* 32x32=64 */		  ARMul_Icycles (state,				 Multiply64 (state, instr, LSIGNED, LDEFAULT),				 0L);		  break;		}#endif	      rhs = DPRegRHS;	      dest = LHS - rhs - !CFLAG;	      WRITEDEST (dest);	      break;	    case 0x0d:		/* SBCS reg */#ifdef MODET	      if ((BITS (4, 7) & 0x9) == 0x9)		/* LDR immediate offset, no write-back, up, post indexed.  */		LHPOSTUP ();	      if (BITS (4, 7) == 0x9)		{		  /* MULL */		  /* 32x32=64 */		  ARMul_Icycles (state,				 Multiply64 (state, instr, LSIGNED, LSCC),				 0L);		  break;		}#endif	      lhs = LHS;	      rhs = DPRegRHS;	      dest = lhs - rhs - !CFLAG;	      if ((lhs >= rhs) || ((rhs | lhs) >> 31))		{		  ARMul_SubCarry (state, lhs, rhs, dest);		  ARMul_SubOverflow (state, lhs, rhs, dest);		}	      else		{		  CLEARC;		  CLEARV;		}	      WRITESDEST (dest);	      break;	    case 0x0e:		/* RSC reg */#ifdef MODET	      if (BITS (4, 7) == 0xB)		{		  /* STRH immediate offset, write-back, up, post indexed.  */		  SHUPWB ();		  break;		}	      if (BITS (4, 7) == 0x9)		{		  /* MULL */		  /* 32x32=64 */		  ARMul_Icycles (state,				 MultiplyAdd64 (state, instr, LSIGNED,						LDEFAULT), 0L);		  break;		}#endif	      rhs = DPRegRHS;	      dest = rhs - LHS - !CFLAG;	      WRITEDEST (dest);	      break;	    case 0x0f:		/* RSCS reg */#ifdef MODET	      if ((BITS (4, 7) & 0x9) == 0x9)		/* LDR immediate offset, write-back, up, post indexed.  */		LHPOSTUP ();	      /* Fall through to remaining instruction decoding.  */	      if (BITS (4, 7) == 0x9)		{		  /* MULL */		  /* 32x32=64 */		  ARMul_Icycles (state,				 MultiplyAdd64 (state, instr, LSIGNED, LSCC),				 0L);		  break;		}#endif	      lhs = LHS;	      rhs = DPRegRHS;	      dest = rhs - lhs - !CFLAG;	      if ((rhs >= lhs) || ((rhs | lhs) >> 31))		{		  ARMul_SubCarry (state, rhs, lhs, dest);		  ARMul_SubOverflow (state, rhs, lhs, dest);		}	      else		{		  CLEARC;		  CLEARV;		}	      WRITESDEST (dest);	      break;	    case 0x10:		/* TST reg and MRS CPSR and SWP word.  */	      if (state->is_v5e)		{		  if (BIT (4) == 0 && BIT (7) == 1)		    {		      /* ElSegundo SMLAxy 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;		      op1 *= op2;		      		      if (AddOverflow (op1, Rn, op1 + Rn))			SETS;		      state->Reg[BITS (16, 19)] = op1 + Rn;		      break;		    }		  if (BITS (4, 11) == 5)		    {		      /* ElSegundo QADD insn.  */		      ARMword op1 = state->Reg[BITS (0, 3)];		      ARMword op2 = state->Reg[BITS (16, 19)];		      ARMword result = op1 + op2;		      if (AddOverflow (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, 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_LoadWordN (state, temp);		      (void) ARMul_LoadWordN (state, temp);		    }		  else#endif		    dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]);		  if (temp & 3)		    DEST = ARMul_Align (state, temp, dest);		  else		    DEST = dest;		  if (state->abortSig || state->Aborted)		    TAKEABORT;		}	      else if ((BITS (0, 11) == 0) && (LHSReg == 15))		{		/* MRS CPSR */		  UNDEF_MRSPC;		  DEST = ECC | EINT | EMODE;		}	      else		{		  UNDEF_Test;		}	      break;	    case 0x11:		/* TSTP reg */#ifdef MODET	      if ((BITS (4, 11) & 0xF9) == 0x9)		/* 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;

⌨️ 快捷键说明

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