+2015-11-15 Mike Frysinger <vapier@gentoo.org>
+
+ * Makefile.in (SIM_OBJS): Add sim-reason.o, sim-resume.o, and
+ sim-stop.o.
+ * cr16_sim.h (struct _state): Delete exe and exception.
+ * interp.c (lookup_hash): Call sim_engine_halt instead of setting
+ State.exception.
+ (do_run): Delete unused s and func variables.
+ (stop_simulator, sim_stop, sim_stop_reason): Delete.
+ (sim_resume): Rename to ...
+ (step_once): ... this. Delete State.exception code and move
+ siggnal checking to sim_engine_run.
+ (sim_engine_run): New function.
+ * simops.c (EXCEPTION): Define.
+ (move_to_cr): Call EXCEPTION instead of setting State.exception.
+ (OP_1_4, OP_18_8, OP_10_10, OP_C0_8, OP_102_14, OP_148_14, OP_D_C,
+ OP_14_D, OP_15_D, OP_2C00_10, OP_16_D, OP_17_D, OP_31E_10, OP_6_10):
+ Likewise.
+ (OP_C_C): Likewise. Call sim_engine_halt instead of setting
+ State.exception.
+ (OP_0_20): Call sim_engine_halt instead of setting State.exception.
+
2015-11-15 Mike Frysinger <vapier@gentoo.org>
* Makefile.in (SIM_OBJS): Delete endian.o.
SIM_OBJS = \
$(SIM_NEW_COMMON_OBJS) \
sim-hload.o \
+ sim-reason.o \
sim-reg.o \
+ sim-resume.o \
+ sim-stop.o \
interp.o \
table.o \
simops.o
uint16 psw;
} trace;
- uint8 exe;
- int exception;
int pc_changed;
/* NOTE: everything below this line is not reset by
while ((ins & mask) != (BIN(h->opcode, h->mask)))
{
if (h->next == NULL)
- {
- State.exception = SIGILL;
- State.pc_changed = 1; /* Don't increment the PC. */
- return NULL;
- }
+ sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL);
h = h->next;
mask = (((1 << (32 - h->mask)) -1) << h->mask);
do_run (SIM_DESC sd, SIM_CPU *cpu, uint64 mcode)
{
host_callback *cr16_callback = STATE_CALLBACK (sd);
- struct simops *s= Simops;
struct hash_entry *h;
- char func[12]="\0";
+
#ifdef DEBUG
if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
(*cr16_callback->printf_filtered) (cr16_callback, "do_long 0x%x\n", mcode);
return sd;
}
-static int stop_simulator = 0;
-
-int
-sim_stop (SIM_DESC sd)
+static void
+step_once (SIM_DESC sd, SIM_CPU *cpu)
{
- stop_simulator = 1;
- return 1;
-}
+ uint32 curr_ins_size = 0;
+ uint64 mcode = RLW (PC);
+ State.pc_changed = 0;
+
+ curr_ins_size = do_run (sd, cpu, mcode);
+
+#if CR16_DEBUG
+ (*cr16_callback->printf_filtered) (cr16_callback, "INS: PC=0x%X, mcode=0x%X\n", PC, mcode);
+#endif
+
+ if (curr_ins_size == 0)
+ sim_engine_halt (sd, cpu, NULL, PC, sim_exited, GPR (2));
+ else if (!State.pc_changed)
+ SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */
+
+#if 0
+ /* Check for a breakpoint trap on this instruction. This
+ overrides any pending branches or loops */
+ if (PSR_DB && PC == DBS)
+ {
+ SET_BPC (PC);
+ SET_BPSR (PSR);
+ SET_PC (SDBT_VECTOR_START);
+ }
+#endif
+
+ /* Writeback all the DATA / PC changes */
+ SLOT_FLUSH ();
+}
-/* Run (or resume) the program. */
void
-sim_resume (SIM_DESC sd, int step, int siggnal)
+sim_engine_run (SIM_DESC sd,
+ int next_cpu_nr, /* ignore */
+ int nr_cpus, /* ignore */
+ int siggnal)
{
- SIM_CPU *cpu = STATE_CPU (sd, 0);
- uint32 curr_ins_size = 0;
- uint64 mcode;
+ sim_cpu *cpu;
-#ifdef DEBUG
-// (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
-#endif
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
- State.exception = 0;
- if (step)
- sim_stop (sd);
+ cpu = STATE_CPU (sd, 0);
switch (siggnal)
{
case 0:
break;
-#ifdef SIGBUS
- case SIGBUS:
-#endif
- case SIGSEGV:
+ case GDB_SIGNAL_BUS:
+ case GDB_SIGNAL_SEGV:
SET_PC (PC);
SET_PSR (PSR);
JMP (AE_VECTOR_START);
SLOT_FLUSH ();
break;
- case SIGILL:
+ case GDB_SIGNAL_ILL:
SET_PC (PC);
SET_PSR (PSR);
SET_HW_PSR ((PSR & (PSR_C_BIT)));
break;
}
- do
+ while (1)
{
- mcode = RLW (PC);
-
- State.pc_changed = 0;
-
- curr_ins_size = do_run (sd, cpu, mcode);
-
-#if CR16_DEBUG
- (*cr16_callback->printf_filtered) (cr16_callback, "INS: PC=0x%X, mcode=0x%X\n",PC,mcode);
-#endif
-
- if (!State.pc_changed)
- {
- if (curr_ins_size == 0)
- {
- State.exception = SIG_CR16_EXIT; /* exit trap */
- break;
- }
- else
- SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */
- }
-
-#if 0
- /* Check for a breakpoint trap on this instruction. This
- overrides any pending branches or loops */
- if (PSR_DB && PC == DBS)
- {
- SET_BPC (PC);
- SET_BPSR (PSR);
- SET_PC (SDBT_VECTOR_START);
- }
-#endif
-
- /* Writeback all the DATA / PC changes */
- SLOT_FLUSH ();
+ step_once (sd, cpu);
+ if (sim_events_tick (sd))
+ sim_events_process (sd);
}
- while ( !State.exception && !stop_simulator);
-
- if (step && !State.exception)
- State.exception = SIGTRAP;
}
SIM_RC
return SIM_RC_OK;
}
-void
-sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
-{
-/* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
-
- switch (State.exception)
- {
- case SIG_CR16_STOP: /* stop instruction */
- *reason = sim_stopped;
- *sigrc = 0;
- break;
-
- case SIG_CR16_EXIT: /* exit trap */
- *reason = sim_exited;
- *sigrc = GPR (2);
- break;
-
- case SIG_CR16_BUS:
- *reason = sim_stopped;
- *sigrc = GDB_SIGNAL_BUS;
- break;
-//
-// case SIG_CR16_IAD:
-// *reason = sim_stopped;
-// *sigrc = GDB_SIGNAL_IAD;
-// break;
-
- default: /* some signal */
- *reason = sim_stopped;
- if (stop_simulator && !State.exception)
- *sigrc = GDB_SIGNAL_INT;
- else
- *sigrc = State.exception;
- break;
- }
-
- stop_simulator = 0;
-}
-
static uint32
cr16_extract_unsigned_integer (unsigned char *addr, int len)
{
#include <sys/wait.h>
#endif
+#define EXCEPTION(sig) sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, sig)
+
enum op_types {
OP_VOID,
OP_CONSTANT3,
(*cr16_callback->printf_filtered)
(cr16_callback,
"ERROR at PC 0x%x: ST can only be set when FX is set.\n", PC);
- State.exception = SIGILL;
+ EXCEPTION (SIM_SIGILL);
#endif
/* keep an up-to-date psw around for tracing. */
State.trace.psw = (State.trace.psw & mask) | val;
if ((tmp < 0x000000) || (tmp > 0xFFFFFF))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
else
JMP (tmp);
if ((tmp < 0x000000) || (tmp > 0xFFFFFF))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
else
JMP (tmp);
if ((tmp < 0x000000) || (tmp > 0xFFFFFF))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
else
JMP (tmp);
if ((tmp < 0x000000) || (tmp > 0xFFFFFF))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
else
JMP (tmp);
if ((tmp < 0x000000) || (tmp > 0xFFFFFF))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
else
JMP (tmp);
if ((tmp < 0x0) || (tmp > 0xFFFFFF))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
else
JMP (tmp);
if ((tmp < 0x0) || (tmp > 0xFFFFFF))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
else
JMP (tmp);
trace_input ("loadm", OP_CONSTANT4, OP_VOID, OP_VOID);
if ((addr & 1))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
while (count)
trace_input ("loadm", OP_CONSTANT4, OP_VOID, OP_VOID);
if ((addr & 1))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
while (count)
trace_input ("nop", OP_VOID, OP_VOID, OP_VOID);
#if 0
- State.exception = SIGTRAP;
ins_type_counters[ (int)State.ins_type ]--; /* don't count nops as normal instructions */
switch (State.ins_type)
{
break;
}
-
+ EXCEPTION (SIM_SIGTRAP);
#endif
trace_output_void (sd);
}
trace_input ("storm", OP_CONSTANT4, OP_VOID, OP_VOID);
if ((addr & 1))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
while (count)
trace_input ("stormp", OP_CONSTANT4, OP_VOID, OP_VOID);
if ((addr & 1))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
while (count)
if (PARM1 == getpid ())
{
trace_output_void (sd);
- State.exception = PARM2;
+ EXCEPTION (PARM2);
}
else
{
trace_output_void (sd);
(*cr16_callback->printf_filtered) (cr16_callback, "Unknown signal %d\n", PARM2);
(*cr16_callback->flush_stdout) (cr16_callback);
- State.exception = SIGILL;
+ EXCEPTION (SIM_SIGILL);
}
else
{
case TARGET_SYS_kill:
trace_input ("<kill>", OP_REG, OP_REG, OP_VOID);
trace_output_void (sd);
- State.exception = PARM2;
+ EXCEPTION (PARM2);
break;
#endif
case TARGET_SYS_exit:
trace_input ("<exit>", OP_VOID, OP_VOID, OP_VOID);
- State.exception = SIG_CR16_EXIT;
trace_output_void (sd);
+ sim_engine_halt (sd, cpu, NULL, PC, sim_exited, GPR (2));
break;
case TARGET_SYS_unlink:
switch (a)
{
case TRAP_BREAKPOINT:
- State.exception = SIGTRAP;
tmp = (PC);
JMP(tmp);
trace_output_void (sd);
+ EXCEPTION (SIM_SIGTRAP);
break;
case SIGTRAP: /* supervisor call ? */
- State.exception = SIG_CR16_EXIT;
trace_output_void (sd);
+ sim_engine_halt (sd, cpu, NULL, PC, sim_exited, GPR (2));
break;
default:
cr16_callback->error (cr16_callback, "Unknown syscall %d", FUNC);
if ((tmp < 0x0) || (tmp > 0xFFFFFF))
{
- State.exception = SIG_CR16_BUS;
- State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void (sd);
- return;
+ EXCEPTION (SIM_SIGBUS);
}
else
JMP (tmp);
OP_6_10 (SIM_DESC sd, SIM_CPU *cpu)
{
trace_input ("wait", OP_VOID, OP_VOID, OP_VOID);
- State.exception = SIGTRAP;
trace_output_void (sd);
+ EXCEPTION (SIM_SIGTRAP);
}
/* ewait. */
OP_0_20 (SIM_DESC sd, SIM_CPU *cpu)
{
trace_input ("null", OP_VOID, OP_VOID, OP_VOID);
- State.exception = SIG_CR16_STOP;
+ sim_engine_halt (sd, cpu, NULL, PC, sim_exited, 0);
}