Exemplo n.º 1
0
int arm_execute( int cycles )
{
	data32_t pc;
	data32_t insn;

	arm_ICount = cycles;
	do
	{

#ifdef MAME_DEBUG
		if (mame_debug)
			MAME_Debug();
#endif

		/* load instruction */
		pc = R15;
		insn = READ32( pc & ADDRESS_MASK );

		switch (insn >> INSN_COND_SHIFT)
		{
		case COND_EQ:
			if (Z_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_NE:
			if (Z_IS_SET(pc)) goto L_Next;
			break;
		case COND_CS:
			if (C_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_CC:
			if (C_IS_SET(pc)) goto L_Next;
			break;
		case COND_MI:
			if (N_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_PL:
			if (N_IS_SET(pc)) goto L_Next;
			break;
		case COND_VS:
			if (V_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_VC:
			if (V_IS_SET(pc)) goto L_Next;
			break;
		case COND_HI:
			if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next;
			break;
		case COND_LS:
			if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_GE:
			if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */
			break;
		case COND_LT:
			if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next;
			break;
		case COND_GT:
			if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next;
			break;
		case COND_LE:
			if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next;
			break;
		case COND_NV:
			goto L_Next;
		}
		/* Condition satisfied, so decode the instruction */
		if ((insn & 0x0fc000f0u) == 0x00000090u)	/* Multiplication */
		{
			HandleMul(insn);
			R15 += 4;
		}
		else if (!(insn & 0x0c000000u)) /* Data processing */
		{
			HandleALU(insn);
		}
		else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */
		{
			HandleMemSingle(insn);
			R15 += 4;
		}
		else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */
		{
			HandleMemBlock(insn);
			R15 += 4;
		}
		else if ((insn & 0x0e000000u) == 0x0a000000u)	/* Branch */
		{
			HandleBranch(insn);
		}
		else if ((insn & 0x0f000000u) == 0x0f000000u)	/* Software interrupt */
		{
			pc=R15+4;
			R15 = eARM_MODE_SVC;	/* Set SVC mode so PC is saved to correct R14 bank */
			SetRegister( 14, pc );	/* save PC */
			R15 = (pc&PSR_MASK)|0x8|eARM_MODE_SVC|(pc&MODE_MASK);
		}
		else /* Undefined */
		{
			logerror("%08x:  Undefined instruction\n",R15);
		L_Next:
			arm_ICount -= S_CYCLE;
			R15 += 4;
		}

		arm_ICount -= 3;
	} while( arm_ICount > 0 );

	return cycles - arm_ICount;
} /* arm_execute */
Exemplo n.º 2
0
/// <summary>
/// Exception handler
/// </summary>
/// <param name="ExceptionInfo">The exception information</param>
/// <returns>Handling status</returns>
LONG TraceHook::VecHandlerP( PEXCEPTION_POINTERS ExceptionInfo )
{
    auto exptContex = ExceptionInfo->ContextRecord;
    auto exptRecord = ExceptionInfo->ExceptionRecord;
    auto exptCode   = exptRecord->ExceptionCode;

    // TODO: Somehow determine current hook context
    HookContext* ctx = &_contexts.begin()->second;

    // Check if exception should be handled
    if (exptCode != EXCEPTION_SINGLE_STEP && exptCode != EXCEPTION_ACCESS_VIOLATION)
    {
        return EXCEPTION_CONTINUE_SEARCH;
    }
    else if (exptCode == EXCEPTION_ACCESS_VIOLATION && (ctx->state == TS_Step || ctx->state == TS_StepInto))
    {
        if ((exptRecord->ExceptionInformation[1] & ADDR_MASK) != (ctx->breakValue & ADDR_MASK))
            return EXCEPTION_CONTINUE_SEARCH;

        // Pointer accessed by non-target address 
        if (ctx->checkIP != 0 && exptContex->NIP != ctx->checkIP)
        {
            exptContex->EFlags |= SingleStep;

            RestorePtr( *ctx, ExceptionInfo );
            return EXCEPTION_CONTINUE_EXECUTION;
        }
    }
    
    switch (ctx->state)
    {
        // Start of tracing
        case TS_Start:
            {
                ctx->state = ctx->tracePath[ctx->stateIdx].action;

                RestorePtr( *ctx, ExceptionInfo );
                return VecHandlerP( ExceptionInfo );
            }
            break;

        // Single step
        case TS_Step:
            {
                // Function call occurred. Queue break on return.
                if (CheckBranching( *ctx, exptContex->NIP, exptContex->NSP ))
                {
                    // Target function reached
                    if (ctx->hooks.count( exptContex->NIP ))
                    {
                        HandleBranch( *ctx, exptContex );
                        return EXCEPTION_CONTINUE_EXECUTION;
                    }
                    else
                    {
                        ctx->state = TS_WaitReturn;
                        BreakOnReturn( exptContex->NSP );
                    }
                }
                // Step further
                else
                    exptContex->EFlags |= SingleStep;
            }
            break;

        // Step out from function
        case TS_StepOut:
            {
                // Get current stack frame
                vecStackFrames frames;
                StackBacktrace( exptContex->NIP, exptContex->NSP, frames, 1 );

                if (frames.size() > 1)
                {
                    ctx->stateIdx++;
                    ctx->state = TS_WaitReturn;
                    BreakOnReturn( frames.back().first );
                }
            }
            break;

        // Step into specific function
        case TS_StepInto:
            {
                // Check if step into path function has occurred
                if (CheckBranching( *ctx, exptContex->NIP, exptContex->NSP ))
                {
                    if (exptContex->NIP == ctx->tracePath[ctx->stateIdx].arg)
                    {
                        ctx->stateIdx++;
                        ctx->state = ctx->tracePath[ctx->stateIdx].action;
                    }
                }

                exptContex->EFlags |= SingleStep;
            }
            break;

        // Break on 'ret' instruction
        case TS_WaitReturn:
            {
                exptContex->NIP &= HIGHEST_BIT_UNSET;

                // Restore stack for x64
            #ifdef USE64
                *(uintptr_t*)exptContex->NSP &= HIGHEST_BIT_UNSET;
            #endif // USE64

                // Continue stepping
                exptContex->EFlags |= SingleStep;
                ctx->state = ctx->tracePath[ctx->stateIdx].action;
            }
            break;

        default:
            break;
    }

    ctx->lastIP = exptContex->NIP;
    ctx->lastSP = exptContex->NSP;
    
    return EXCEPTION_CONTINUE_EXECUTION;
}
Exemplo n.º 3
0
void arm_cpu_device::execute_run()
{
	UINT32 pc;
	UINT32 insn;

	do
	{
		debugger_instruction_hook(this, R15 & ADDRESS_MASK);

		/* load instruction */
		pc = R15;
		insn = m_direct->read_decrypted_dword( pc & ADDRESS_MASK );

		switch (insn >> INSN_COND_SHIFT)
		{
		case COND_EQ:
			if (Z_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_NE:
			if (Z_IS_SET(pc)) goto L_Next;
			break;
		case COND_CS:
			if (C_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_CC:
			if (C_IS_SET(pc)) goto L_Next;
			break;
		case COND_MI:
			if (N_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_PL:
			if (N_IS_SET(pc)) goto L_Next;
			break;
		case COND_VS:
			if (V_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_VC:
			if (V_IS_SET(pc)) goto L_Next;
			break;
		case COND_HI:
			if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next;
			break;
		case COND_LS:
			if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_GE:
			if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */
			break;
		case COND_LT:
			if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next;
			break;
		case COND_GT:
			if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next;
			break;
		case COND_LE:
			if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next;
			break;
		case COND_NV:
			goto L_Next;
		}
		/* Condition satisfied, so decode the instruction */
		if ((insn & 0x0fc000f0u) == 0x00000090u)    /* Multiplication */
		{
			HandleMul(insn);
			R15 += 4;
		}
		else if (!(insn & 0x0c000000u)) /* Data processing */
		{
			HandleALU(insn);
		}
		else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */
		{
			HandleMemSingle(insn);
			R15 += 4;
		}
		else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */
		{
			HandleMemBlock(insn);
			R15 += 4;
		}
		else if ((insn & 0x0e000000u) == 0x0a000000u)   /* Branch */
		{
			HandleBranch(insn);
		}
		else if ((insn & 0x0f000000u) == 0x0e000000u)   /* Coprocessor */
		{
			if (m_copro_type == ARM_COPRO_TYPE_VL86C020)
				HandleCoProVL86C020(insn);
			else
				HandleCoPro(insn);

			R15 += 4;
		}
		else if ((insn & 0x0f000000u) == 0x0f000000u)   /* Software interrupt */
		{
			pc=R15+4;
			R15 = eARM_MODE_SVC;    /* Set SVC mode so PC is saved to correct R14 bank */
			SetRegister( 14, pc );    /* save PC */
			R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK);
			m_icount -= 2 * S_CYCLE + N_CYCLE;
		}
		else /* Undefined */
		{
			logerror("%08x:  Undefined instruction\n",R15);
		L_Next:
			m_icount -= S_CYCLE;
			R15 += 4;
		}

		arm_check_irq_state();

	} while( m_icount > 0 );
} /* arm_execute */
Exemplo n.º 4
0
static CPU_EXECUTE( arm )
{
	UINT32 pc;
	UINT32 insn;
	ARM_REGS *cpustate = get_safe_token(device);

	cpustate->icount = cycles;
	do
	{
		debugger_instruction_hook(device, R15 & ADDRESS_MASK);

		/* load instruction */
		pc = R15;
		insn = memory_decrypted_read_dword( cpustate->program, pc & ADDRESS_MASK );

		switch (insn >> INSN_COND_SHIFT)
		{
		case COND_EQ:
			if (Z_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_NE:
			if (Z_IS_SET(pc)) goto L_Next;
			break;
		case COND_CS:
			if (C_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_CC:
			if (C_IS_SET(pc)) goto L_Next;
			break;
		case COND_MI:
			if (N_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_PL:
			if (N_IS_SET(pc)) goto L_Next;
			break;
		case COND_VS:
			if (V_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_VC:
			if (V_IS_SET(pc)) goto L_Next;
			break;
		case COND_HI:
			if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next;
			break;
		case COND_LS:
			if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_GE:
			if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */
			break;
		case COND_LT:
			if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next;
			break;
		case COND_GT:
			if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next;
			break;
		case COND_LE:
			if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next;
			break;
		case COND_NV:
			goto L_Next;
		}
		/* Condition satisfied, so decode the instruction */
		if ((insn & 0x0fc000f0u) == 0x00000090u)	/* Multiplication */
		{
			HandleMul(cpustate, insn);
			R15 += 4;
		}
		else if (!(insn & 0x0c000000u)) /* Data processing */
		{
			HandleALU(cpustate, insn);
		}
		else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */
		{
			HandleMemSingle(cpustate, insn);
			R15 += 4;
		}
		else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */
		{
			HandleMemBlock(cpustate, insn);
			R15 += 4;
		}
		else if ((insn & 0x0e000000u) == 0x0a000000u)	/* Branch */
		{
			HandleBranch(cpustate, insn);
		}
		else if ((insn & 0x0f000000u) == 0x0e000000u)	/* Coprocessor */
		{
			HandleCoPro(cpustate, insn);
			R15 += 4;
		}
		else if ((insn & 0x0f000000u) == 0x0f000000u)	/* Software interrupt */
		{
			pc=R15+4;
			R15 = eARM_MODE_SVC;	/* Set SVC mode so PC is saved to correct R14 bank */
			SetRegister( cpustate, 14, pc );	/* save PC */
			R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK);
			cpustate->icount -= 2 * S_CYCLE + N_CYCLE;
		}
		else /* Undefined */
		{
			logerror("%08x:  Undefined instruction\n",R15);
		L_Next:
			cpustate->icount -= S_CYCLE;
			R15 += 4;
		}

		arm_check_irq_state(cpustate);

	} while( cpustate->icount > 0 );

	return cycles - cpustate->icount;
} /* arm_execute */
Exemplo n.º 5
0
void arm2_execute_run(int tube_cycles)
{
#ifdef TRACE
  int i;
#endif
  UINT32 pc;
  UINT32 insn;
  //int m_icount = number;

  do
  {
    //debugger_instruction_hook(this, R15 & ADDRESS_MASK);

    /* load instruction */
    pc = R15;
#ifdef INCLUDE_DEBUGGER
      if (arm2_debug_enabled)
      {
         debug_preexec(&arm2_cpu_debug, pc & ADDRESS_MASK);
      }
#endif
    insn = cpu_read32( pc & ADDRESS_MASK );

#ifdef TRACE
    if ((pc & ADDRESS_MASK) == 0xa060)
    {
      m_trace = 1;
    }
    if (m_trace)
    {
      printf("%08X %08X ", pc, insn);
      for (i = eR0; i <= eR7; i++)
      {
        printf("%08X ", m_sArmRegister[i]);
      }
      if(darm_armv7_disasm(&d, insn) == 0 && darm_str2(&d, &str, 0) == 0)
      {
        printf("%s\r\n", str.total);
      }
      else
      {
        printf("***\r\n");
      }
    }
    if ((pc & ADDRESS_MASK) == 0xa0c0)
    {
      m_trace = 0;
    }
    if ((pc & ADDRESS_MASK) == 0xa2ac)
    {
      m_trace = 0;
    }
    if ((insn & 0x0D900000) == 0x01000000)
    {
      printf("S bit not set in %08x at %08x\r\n", insn, pc & ADDRESS_MASK);
      insn |= INSN_S;
    }
#endif
    switch (insn >> INSN_COND_SHIFT)
    {
      case COND_EQ:
      if (Z_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_NE:
      if (Z_IS_SET(pc)) goto L_Next;
      break;
      case COND_CS:
      if (C_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_CC:
      if (C_IS_SET(pc)) goto L_Next;
      break;
      case COND_MI:
      if (N_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_PL:
      if (N_IS_SET(pc)) goto L_Next;
      break;
      case COND_VS:
      if (V_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_VC:
      if (V_IS_SET(pc)) goto L_Next;
      break;
      case COND_HI:
      if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next;
      break;
      case COND_LS:
      if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_GE:
      if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */
      break;
      case COND_LT:
      if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next;
      break;
      case COND_GT:
      if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next;
      break;
      case COND_LE:
      if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next;
      break;
      case COND_NV:
      goto L_Next;
    }
    /* Condition satisfied, so decode the instruction */
    if ((insn & 0x0fc000f0u) == 0x00000090u) /* Multiplication */
    {
      HandleMul(insn);
      R15 += 4;
    }
    else if (!(insn & 0x0c000000u)) /* Data processing */
    {
      HandleALU(insn);
    }
    else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */
    {
      HandleMemSingle(insn);
      R15 += 4;
    }
    else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */
    {
      HandleMemBlock(insn);
      R15 += 4;
    }
    else if ((insn & 0x0e000000u) == 0x0a000000u) /* Branch */
    {
      HandleBranch(insn);
    }
    else if ((insn & 0x0f000000u) == 0x0e000000u) /* Coprocessor */
    {
      if (m_copro_type == ARM_COPRO_TYPE_VL86C020)
      HandleCoProVL86C020(insn);
      else
      HandleCoPro(insn);

      R15 += 4;
    }
    else if ((insn & 0x0f000000u) == 0x0f000000u) /* Software interrupt */
    {
      pc=R15+4;
      R15 = eARM_MODE_SVC; /* Set SVC mode so PC is saved to correct R14 bank */
      SetRegister( 14, pc ); /* save PC */
      R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK);
      CYCLE_COUNT(2 * S_CYCLE + N_CYCLE);
    }
    else /* Undefined */
    {
      logerror("%08x:  Undefined instruction\n",R15);
      L_Next:
      CYCLE_COUNT(S_CYCLE);
      R15 += 4;
    }

    //arm2_check_irq_state();

    tubeUseCycles(1); 
    } while (tubeContinueRunning());
  //while( m_icount > 0 );
  //while (number--);
} /* arm_execute */
Exemplo n.º 6
0
int ArmRun( int cycles )
{
	UINT32 pc;
	UINT32 insn;

	arm_icount = cycles;
	arm.ArmLeftCycles = cycles;

	do
	{
		/* load instruction */
		pc = R15;
		insn = Arm_program_opcode_dword_32le( pc & ADDRESS_MASK );

		switch (insn >> INSN_COND_SHIFT)
		{
		case COND_EQ:
			if (Z_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_NE:
			if (Z_IS_SET(pc)) goto L_Next;
			break;
		case COND_CS:
			if (C_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_CC:
			if (C_IS_SET(pc)) goto L_Next;
			break;
		case COND_MI:
			if (N_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_PL:
			if (N_IS_SET(pc)) goto L_Next;
			break;
		case COND_VS:
			if (V_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_VC:
			if (V_IS_SET(pc)) goto L_Next;
			break;
		case COND_HI:
			if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next;
			break;
		case COND_LS:
			if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next;
			break;
		case COND_GE:
			if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */
			break;
		case COND_LT:
			if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next;
			break;
		case COND_GT:
			if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next;
			break;
		case COND_LE:
			if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next;
			break;
		case COND_NV:
			goto L_Next;
		}
		/* Condition satisfied, so decode the instruction */
		if ((insn & 0x0fc000f0u) == 0x00000090u)	/* Multiplication */
		{
			HandleMul(insn);
			R15 += 4;
		}
		else if (!(insn & 0x0c000000u)) /* Data processing */
		{
			HandleALU(insn);
		}
		else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */
		{
			HandleMemSingle(insn);
			R15 += 4;
		}
		else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */
		{
			HandleMemBlock(insn);
			R15 += 4;
		}
		else if ((insn & 0x0e000000u) == 0x0a000000u)	/* Branch */
		{
			HandleBranch(insn);
		}
		else if ((insn & 0x0f000000u) == 0x0e000000u)	/* Coprocessor */
		{
			HandleCoPro(insn);
			R15 += 4;
		}
		else if ((insn & 0x0f000000u) == 0x0f000000u)	/* Software interrupt */
		{
			pc=R15+4;
			R15 = eARM_MODE_SVC;	/* Set SVC mode so PC is saved to correct R14 bank */
			SetRegister( 14, pc );	/* save PC */
			R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK);
			change_pc(pc&ADDRESS_MASK);
			arm_icount -= 2 * S_CYCLE + N_CYCLE;
		}
		else /* Undefined */
		{
			L_Next:
			arm_icount -= S_CYCLE;
			R15 += 4;
		}

		arm_check_irq_state();

	} while( arm_icount > 0 );

	arm.ArmTotalCycles += (cycles - arm_icount);

	return cycles - arm_icount;
} /* arm_execute */