/* CPU data object: */
-static int
-sim_state_initialize (SIM_DESC sd, sim_cpu *cpu)
-{
- /* FIXME: not really necessary, since sim_cpu_alloc calls zalloc. */
-
- memset (&cpu->regs, 0, sizeof(cpu->regs));
- cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
- cpu->pc = 0;
- cpu->delayed_branch = 0;
- cpu->memory = NULL;
- cpu->eightbit = NULL;
- cpu->mask = 0;
-
- /* Initialize local simulator state. */
- sd->sim_cache = NULL;
- sd->sim_cache_size = 0;
- sd->cache_idx = NULL;
- sd->cache_top = 0;
- sd->memory_size = 0;
- sd->compiles = 0;
-#ifdef ADEBUG
- memset (&cpu->stats, 0, sizeof (cpu->stats));
-#endif
- return 0;
-}
-
static unsigned int
h8_get_pc (SIM_DESC sd)
{
static unsigned int
lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
{
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+
if (val == NULL) /* Paranoia. */
return -1;
*val = X (OP_MEM, SP);
break;
default:
- sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
+ sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
return -1;
}
return 0;
static int
fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
{
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
int rn = arg->reg;
int abs = arg->literal;
int r;
case X (OP_MEM, SB): /* Why isn't this implemented? */
default:
- sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
+ sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
return -1;
}
return 0; /* Success. */
static int
store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
{
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
int rn = arg->reg;
int abs = arg->literal;
int t;
case X (OP_MEM, SW): /* Why isn't this implemented? */
case X (OP_MEM, SL): /* Why isn't this implemented? */
default:
- sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
+ sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
return -1;
}
return 0;
goto next; \
}
-void
-sim_resume (SIM_DESC sd, int step, int siggnal)
+static void
+step_once (SIM_DESC sd, SIM_CPU *cpu)
{
- static int init1;
int cycles = 0;
int insts = 0;
int tick_start = get_now ();
- int poll_count = 0;
int res;
int tmp;
int rd;
int c, nz, v, n, u, h, ui, intMaskBit;
int trace, intMask;
int oldmask;
- enum sim_stop reason;
- int sigrc;
host_callback *sim_callback = STATE_CALLBACK (sd);
init_pointers (sd);
- if (step)
- {
- sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
- }
- else
- {
- sim_engine_set_run_state (sd, sim_running, 0);
- }
-
pc = h8_get_pc (sd);
/* The PC should never be odd. */
if (pc & 0x1)
{
- sim_engine_set_run_state (sd, sim_stopped, SIGBUS);
+ sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGBUS);
return;
}
goto end;
case O (O_ILL, SB): /* illegal */
- sim_engine_set_run_state (sd, sim_stopped, SIGILL);
+ sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
goto end;
case O (O_SLEEP, SN): /* sleep */
SIM_WIFEXITED (h8_get_reg (sd, 0)))
{
/* This trap comes from _exit, not from gdb. */
- sim_engine_set_run_state (sd, sim_exited,
- SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
+ sim_engine_halt (sd, cpu, NULL, pc, sim_exited,
+ SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
}
#if 0
/* Unfortunately this won't really work, because
else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
{
/* Pass the stop signal up to gdb. */
- sim_engine_set_run_state (sd, sim_stopped,
- SIM_WSTOPSIG (h8_get_reg (sd, 0)));
+ sim_engine_halt (sd, cpu, NULL, pc, sim_stopped,
+ SIM_WSTOPSIG (h8_get_reg (sd, 0)));
}
#endif
else
{
/* Treat it as a sigtrap. */
- sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
+ sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
}
goto end;
goto end;
case O (O_BPT, SN):
- sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
+ sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
goto end;
case O (O_BSETEQ, SB):
default:
illegal:
- sim_engine_set_run_state (sd, sim_stopped, SIGILL);
+ sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
goto end;
}
sim_io_printf (sd, "sim_resume: internal error.\n");
- sim_engine_set_run_state (sd, sim_stopped, SIGILL);
+ sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
goto end;
setc:
else
pc = code->next_pc;
- end:
-
- if (--poll_count < 0)
- {
- poll_count = POLL_QUIT_INTERVAL;
- if ((*sim_callback->poll_quit) != NULL
- && (*sim_callback->poll_quit) (sim_callback))
- sim_engine_set_run_state (sd, sim_stopped, SIGINT);
- }
- sim_engine_get_run_state (sd, &reason, &sigrc);
- } while (reason == sim_running);
+ } while (0);
+ end:
h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
h8_set_insts (sd, h8_get_insts (sd) + insts);
h8_set_mask (sd, oldmask);
}
+void
+sim_engine_run (SIM_DESC sd,
+ int next_cpu_nr, /* ignore */
+ int nr_cpus, /* ignore */
+ int siggnal)
+{
+ sim_cpu *cpu;
+
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+ cpu = STATE_CPU (sd, 0);
+
+ while (1)
+ {
+ step_once (sd, cpu);
+ if (sim_events_tick (sd))
+ sim_events_process (sd);
+ }
+}
+
int
sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
{
static int
h8300_reg_store (SIM_CPU *cpu, int rn, unsigned char *value, int length)
{
- SIM_DESC sd = CPU_STATE (cpu);
int longval;
int shortval;
int intval;
shortval = (value[0] << 8) | (value[1]);
intval = h8300hmode ? longval : shortval;
- init_pointers (sd);
+ init_pointers (CPU_STATE (cpu));
switch (rn)
{
case PC_REGNUM:
if(h8300_normal_mode)
- h8_set_pc (sd, shortval); /* PC for Normal mode is 2 bytes */
+ cpu->pc = shortval; /* PC for Normal mode is 2 bytes */
else
- h8_set_pc (sd, intval);
+ cpu->pc = intval;
break;
default:
- sim_io_printf (sd, "sim_store_register: bad regnum %d.\n", rn);
+ return -1;
case R0_REGNUM:
case R1_REGNUM:
case R2_REGNUM:
case R5_REGNUM:
case R6_REGNUM:
case R7_REGNUM:
- h8_set_reg (sd, rn, intval);
- break;
case CCR_REGNUM:
- h8_set_ccr (sd, intval);
- break;
case EXR_REGNUM:
- h8_set_exr (sd, intval);
- break;
case SBR_REGNUM:
- h8_set_sbr (sd, intval);
- break;
case VBR_REGNUM:
- h8_set_vbr (sd, intval);
- break;
case MACH_REGNUM:
- h8_set_mach (sd, intval);
- break;
case MACL_REGNUM:
- h8_set_macl (sd, intval);
+ cpu->regs[rn] = intval;
break;
case CYCLE_REGNUM:
- h8_set_cycles (sd, longval);
- break;
-
case INST_REGNUM:
- h8_set_insts (sd, longval);
- break;
-
case TICK_REGNUM:
- h8_set_ticks (sd, longval);
+ cpu->regs[rn] = longval;
break;
}
return length;
static int
h8300_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *buf, int length)
{
- SIM_DESC sd = CPU_STATE (cpu);
int v;
int longreg = 0;
- init_pointers (sd);
+ init_pointers (CPU_STATE (cpu));
if (!h8300smode && rn >= EXR_REGNUM)
rn++;
switch (rn)
{
default:
- sim_io_printf (sd, "sim_fetch_register: bad regnum %d.\n", rn);
- v = 0;
+ return -1;
+ case PC_REGNUM:
+ v = cpu->pc;
break;
case CCR_REGNUM:
- v = h8_get_ccr (sd);
- break;
case EXR_REGNUM:
- v = h8_get_exr (sd);
- break;
- case PC_REGNUM:
- v = h8_get_pc (sd);
- break;
case SBR_REGNUM:
- v = h8_get_sbr (sd);
- break;
case VBR_REGNUM:
- v = h8_get_vbr (sd);
- break;
case MACH_REGNUM:
- v = h8_get_mach (sd);
- break;
case MACL_REGNUM:
- v = h8_get_macl (sd);
- break;
case R0_REGNUM:
case R1_REGNUM:
case R2_REGNUM:
case R5_REGNUM:
case R6_REGNUM:
case R7_REGNUM:
- v = h8_get_reg (sd, rn);
+ v = cpu->regs[rn];
break;
case CYCLE_REGNUM:
- v = h8_get_cycles (sd);
- longreg = 1;
- break;
case TICK_REGNUM:
- v = h8_get_ticks (sd);
- longreg = 1;
- break;
case INST_REGNUM:
- v = h8_get_insts (sd);
+ v = cpu->regs[rn];
longreg = 1;
break;
+ case ZERO_REGNUM:
+ v = 0;
+ break;
}
/* In Normal mode PC is 2 byte, but other registers are 4 byte */
if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
buf[1] = v >> 16;
buf[2] = v >> 8;
buf[3] = v >> 0;
+ return 4;
}
else
{
buf[0] = v >> 8;
buf[1] = v;
+ return 2;
}
- return -1;
}
static void
cpu = STATE_CPU (sd, 0);
SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
- sim_state_initialize (sd, cpu);
+ cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
/* sim_cpu object is new, so some initialization is needed. */
init_pointers_needed = 1;
- /* For compatibility (FIXME: is this right?). */
- current_alignment = NONSTRICT_ALIGNMENT;
- current_target_byte_order = BIG_ENDIAN;
-
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
free_state (sd);