* AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include "config.h"
#include <signal.h>
#ifdef HAVE_TIME_H
#include <time.h>
#include "gdb/sim-h8300.h"
#include "sys/stat.h"
#include "sys/types.h"
+#include "sim-options.h"
#ifndef SIGTRAP
# define SIGTRAP 5
int debug;
-host_callback *sim_callback;
-
-static SIM_OPEN_KIND sim_kind;
-static char *myname;
-
/* FIXME: Needs to live in header file.
This header should also include the things in remote-sim.h.
One could move this to remote-sim.h but this function isn't needed
/* 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;
/* Find the exact opcode/arg combo. */
for (q = h8_opcodes; q->name; q++)
{
- op_type *nib = q->data.nib;
+ const op_type *nib = q->data.nib;
unsigned int len = 0;
if ((q->available == AV_H8SX && !h8300sxmode) ||
#endif
/* Fill in the args. */
{
- op_type *args = q->args.nib;
+ const op_type *args = q->args.nib;
int hadone = 0;
int nargs;
p->literal = 0;
if (OP_KIND (q->how) == O_JSR ||
OP_KIND (q->how) == O_JMP)
- if (lvalue (sd, p->type, p->reg, &p->type))
+ if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
goto end;
}
else if ((x & MODE) == ABS)
p->literal = cst[opnum];
if (OP_KIND (q->how) == O_JSR ||
OP_KIND (q->how) == O_JMP)
- if (lvalue (sd, p->type, p->reg, &p->type))
+ if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
goto end;
}
else if ((x & MODE) == PCREL)
static unsigned char *breg[32];
static unsigned short *wreg[16];
-static unsigned int *lreg[18];
#define GET_B_REG(X) *(breg[X])
#define SET_B_REG(X, Y) (*(breg[X])) = (Y)
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;
break;
case X (OP_POSTINC, SB): /* Register indirect w/post-incr: byte. */
t = GET_L_REG (rn);
- t &= h8_get_mask (sd);
- r = GET_MEMORY_B (t);
+ r = GET_MEMORY_B (t & h8_get_mask (sd));
if (!twice)
t += 1;
- t = t & h8_get_mask (sd);
SET_L_REG (rn, t);
*val = r;
break;
case X (OP_POSTINC, SW): /* Register indirect w/post-incr: word. */
t = GET_L_REG (rn);
- t &= h8_get_mask (sd);
- r = GET_MEMORY_W (t);
+ r = GET_MEMORY_W (t & h8_get_mask (sd));
if (!twice)
t += 2;
- t = t & h8_get_mask (sd);
SET_L_REG (rn, t);
*val = r;
break;
case X (OP_POSTINC, SL): /* Register indirect w/post-incr: long. */
t = GET_L_REG (rn);
- t &= h8_get_mask (sd);
- r = GET_MEMORY_L (t);
+ r = GET_MEMORY_L (t & h8_get_mask (sd));
if (!twice)
t += 4;
- t = t & h8_get_mask (sd);
SET_L_REG (rn, t);
*val = r;
break;
case X (OP_POSTDEC, SB): /* Register indirect w/post-decr: byte. */
t = GET_L_REG (rn);
- t &= h8_get_mask (sd);
- r = GET_MEMORY_B (t);
+ r = GET_MEMORY_B (t & h8_get_mask (sd));
if (!twice)
t -= 1;
- t = t & h8_get_mask (sd);
SET_L_REG (rn, t);
*val = r;
break;
case X (OP_POSTDEC, SW): /* Register indirect w/post-decr: word. */
t = GET_L_REG (rn);
- t &= h8_get_mask (sd);
- r = GET_MEMORY_W (t);
+ r = GET_MEMORY_W (t & h8_get_mask (sd));
if (!twice)
t -= 2;
- t = t & h8_get_mask (sd);
SET_L_REG (rn, t);
*val = r;
break;
case X (OP_POSTDEC, SL): /* Register indirect w/post-decr: long. */
t = GET_L_REG (rn);
- t &= h8_get_mask (sd);
- r = GET_MEMORY_L (t);
+ r = GET_MEMORY_L (t & h8_get_mask (sd));
if (!twice)
t -= 4;
- t = t & h8_get_mask (sd);
SET_L_REG (rn, t);
*val = r;
break;
case X (OP_PREDEC, SB): /* Register indirect w/pre-decr: byte. */
t = GET_L_REG (rn) - 1;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
*val = GET_MEMORY_B (t);
break;
case X (OP_PREDEC, SW): /* Register indirect w/pre-decr: word. */
t = GET_L_REG (rn) - 2;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
*val = GET_MEMORY_W (t);
break;
case X (OP_PREDEC, SL): /* Register indirect w/pre-decr: long. */
t = GET_L_REG (rn) - 4;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
*val = GET_MEMORY_L (t);
break;
case X (OP_PREINC, SB): /* Register indirect w/pre-incr: byte. */
t = GET_L_REG (rn) + 1;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
*val = GET_MEMORY_B (t);
break;
case X (OP_PREINC, SW): /* Register indirect w/pre-incr: long. */
t = GET_L_REG (rn) + 2;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
*val = GET_MEMORY_W (t);
break;
case X (OP_PREINC, SL): /* Register indirect w/pre-incr: long. */
t = GET_L_REG (rn) + 4;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
*val = GET_MEMORY_L (t);
break;
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;
t = GET_L_REG (rn);
if (!twice)
t -= 1;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
SET_MEMORY_B (t, n);
break;
t = GET_L_REG (rn);
if (!twice)
t -= 2;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
SET_MEMORY_W (t, n);
break;
t = GET_L_REG (rn);
if (!twice)
t -= 4;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
SET_MEMORY_L (t, n);
break;
t = GET_L_REG (rn);
if (!twice)
t += 1;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
SET_MEMORY_B (t, n);
break;
t = GET_L_REG (rn);
if (!twice)
t += 2;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
SET_MEMORY_W (t, n);
break;
t = GET_L_REG (rn);
if (!twice)
t += 4;
- t &= h8_get_mask (sd);
SET_L_REG (rn, t);
+ t &= h8_get_mask (sd);
SET_MEMORY_L (t, n);
break;
case X (OP_POSTDEC, SB): /* Register indirect w/post-decr, byte. */
- t = GET_L_REG (rn) & h8_get_mask (sd);
- SET_MEMORY_B (t, n);
+ t = GET_L_REG (rn);
SET_L_REG (rn, t - 1);
+ t &= h8_get_mask (sd);
+ SET_MEMORY_B (t, n);
break;
case X (OP_POSTDEC, SW): /* Register indirect w/post-decr, word. */
- t = GET_L_REG (rn) & h8_get_mask (sd);
- SET_MEMORY_W (t, n);
+ t = GET_L_REG (rn);
SET_L_REG (rn, t - 2);
+ t &= h8_get_mask (sd);
+ SET_MEMORY_W (t, n);
break;
case X (OP_POSTDEC, SL): /* Register indirect w/post-decr, long. */
- t = GET_L_REG (rn) & h8_get_mask (sd);
- SET_MEMORY_L (t, n);
+ t = GET_L_REG (rn);
SET_L_REG (rn, t - 4);
+ t &= h8_get_mask (sd);
+ SET_MEMORY_L (t, n);
break;
case X (OP_POSTINC, SB): /* Register indirect w/post-incr, byte. */
- t = GET_L_REG (rn) & h8_get_mask (sd);
- SET_MEMORY_B (t, n);
+ t = GET_L_REG (rn);
SET_L_REG (rn, t + 1);
+ t &= h8_get_mask (sd);
+ SET_MEMORY_B (t, n);
break;
case X (OP_POSTINC, SW): /* Register indirect w/post-incr, word. */
- t = GET_L_REG (rn) & h8_get_mask (sd);
- SET_MEMORY_W (t, n);
+ t = GET_L_REG (rn);
SET_L_REG (rn, t + 2);
+ t &= h8_get_mask (sd);
+ SET_MEMORY_W (t, n);
break;
case X (OP_POSTINC, SL): /* Register indirect w/post-incr, long. */
- t = GET_L_REG (rn) & h8_get_mask (sd);
- SET_MEMORY_L (t, n);
+ t = GET_L_REG (rn);
SET_L_REG (rn, t + 4);
+ t &= h8_get_mask (sd);
+ SET_MEMORY_L (t, n);
break;
case X (OP_DISP, SB): /* Register indirect w/displacement, byte. */
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;
return store_1 (sd, arg, n, 1);
}
-static union
-{
- short int i;
- struct
- {
- char low;
- char high;
- }
- u;
-} littleendian;
-
/* Flag to be set whenever a new SIM_DESC object is created. */
static int init_pointers_needed = 1;
{
int i;
- littleendian.i = 1;
-
if (h8300smode && !h8300_normal_mode)
memory_size = H8300S_MSIZE;
else if (h8300hmode && !h8300_normal_mode)
/* `msize' must be a power of two. */
if ((memory_size & (memory_size - 1)) != 0)
{
- (*sim_callback->printf_filtered)
- (sim_callback,
+ sim_io_printf
+ (sd,
"init_pointers: bad memory size %d, defaulting to %d.\n",
memory_size, memory_size = H8300S_MSIZE);
}
}
if (wreg[i] == 0 || wreg[i + 8] == 0)
- (*sim_callback->printf_filtered) (sim_callback,
- "init_pointers: internal error.\n");
+ sim_io_printf (sd, "init_pointers: internal error.\n");
h8_set_reg (sd, i, 0);
- lreg[i] = h8_get_reg_buf (sd) + i;
}
- /* Note: sim uses pseudo-register ZERO as a zero register. */
- lreg[ZERO_REGNUM] = h8_get_reg_buf (sd) + ZERO_REGNUM;
init_pointers_needed = 0;
/* Initialize the seg registers. */
}
}
-/* Grotty global variable for use by control_c signal handler. */
-static SIM_DESC control_c_sim_desc;
-
-static void
-control_c (int sig)
-{
- sim_engine_set_run_state (control_c_sim_desc, sim_stopped, SIGINT);
-}
-
-int
-sim_stop (SIM_DESC sd)
-{
- /* FIXME: use a real signal value. */
- sim_engine_set_run_state (sd, sim_stopped, SIGINT);
- return 1;
-}
-
#define OBITOP(name, f, s, op) \
case O (name, SB): \
{ \
goto end; \
if (fetch (sd, &code->src, &tmp)) \
goto end; \
- m = 1 << tmp; \
+ m = 1 << (tmp & 7); \
op; \
if (s) \
if (store (sd, &code->dst,ea)) \
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 ();
- void (*prev) ();
- 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);
- control_c_sim_desc = sd;
- prev = signal (SIGINT, control_c);
-
- 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;
}
code->op3.literal = 0;
if (OP_KIND (code->src.type) == OP_INDEXB)
- code->dst.type = X (OP_REG, SB);
+ {
+ code->dst.type = X (OP_REG, SB);
+ code->dst.reg = code->op3.reg + 8;
+ }
else
code->dst.type = X (OP_REG, SW);
}
{
if (h8300smode)
h8_set_exr (sd, (trace << 7) | intMask);
- res = h8_get_exr (sd);
+ rd = h8_get_exr (sd);
}
else
goto illegal;
ind_arg_len = 0;
/* The size of the commandline argument. */
- ind_arg_len = strlen (h8_get_cmdline_arg (sd, i) + 1);
+ ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
/* The total size of the command line string. */
size_cmdline += ind_arg_len;
stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
/* Callback stat and return. */
- fstat_return = sim_callback->fstat (sim_callback, fd, &stat_rec);
+ fstat_return = sim_callback->to_fstat (sim_callback, fd,
+ &stat_rec);
/* Have stat_ptr point to starting of stat_rec. */
temp_stat_ptr = (char *) (&stat_rec);
/* Callback stat and return. */
stat_return =
- sim_callback->stat (sim_callback, filename, &stat_rec);
+ sim_callback->to_stat (sim_callback, filename, &stat_rec);
/* Have stat_ptr point to starting of stat_rec. */
temp_stat_ptr = (char *) (&stat_rec);
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):
fetch (sd, &code->dst, &rd))
goto end;
- /* FIXME: is this the right place to be doing sign extend? */
- if (OP_KIND (code->src.type) == OP_IMM &&
- (ea & 8) != 0)
- ea |= 0xfff0;
- else
- ea = SEXTSHORT (ea);
-
+ ea = SEXTSHORT (ea);
res = SEXTSHORT (ea * SEXTSHORT (rd));
n = res & 0x8000;
fetch (sd, &code->dst, &rd))
goto end;
- /* FIXME: is this the right place to be doing sign extend? */
- if (OP_KIND (code->src.type) == OP_IMM &&
- (ea & 8) != 0)
- ea |= 0xfffffff0;
-
res = ea * rd;
n = res & 0x80000000;
fetch (sd, &code->dst, &rd))
goto end;
- /* FIXME: is this the right place to be doing sign extend? */
- if (OP_KIND (code->src.type) == OP_IMM &&
- (ea & 8) != 0)
- ea |= 0xfffffff0;
-
/* Compute upper 32 bits of the 64-bit result. */
res = (((long long) ea) * ((long long) rd)) >> 32;
fetch (sd, &code->dst, &rd))
goto end;
- /* FIXME: is this the right place to be doing sign extend? */
- if (OP_KIND (code->src.type) == OP_IMM &&
- (ea & 8) != 0)
- ea |= 0xfffffff0;
- else
- ea = SEXTCHAR (ea);
-
+ ea = SEXTCHAR (ea);
res = ea * SEXTCHAR (rd);
n = res & 0x8000;
fetch (sd, &code->dst, &rd))
goto end;
- /* FIXME: is this the right place to be doing sign extend? */
- if (OP_KIND (code->src.type) == OP_IMM &&
- (ea & 8) != 0)
- ea |= 0xfff0;
- else
- ea = SEXTSHORT (ea);
-
+ ea = SEXTSHORT (ea);
res = ea * SEXTSHORT (rd & 0xffff);
n = res & 0x80000000;
fetch (sd, &code->dst, &rd))
goto end;
- /* FIXME: is this the right place to be doing sign extend? */
- if (OP_KIND (code->src.type) == OP_IMM &&
- (ea & 8) != 0)
- ea |= 0xfffffff0;
-
if (ea)
{
res = SEXTSHORT (rd) / SEXTSHORT (ea);
fetch (sd, &code->dst, &rd))
goto end;
- /* FIXME: is this the right place to be doing sign extend? */
- if (OP_KIND (code->src.type) == OP_IMM &&
- (ea & 8) != 0)
- ea |= 0xfffffff0;
-
if (ea)
{
res = rd / ea;
goto end;
rd = SEXTSHORT (rd);
-
- /* FIXME: is this the right place to be doing sign extend? */
- if (OP_KIND (code->src.type) == OP_IMM &&
- (ea & 8) != 0)
- ea |= 0xfffffff0;
- else
- ea = SEXTCHAR (ea);
+ ea = SEXTCHAR (ea);
if (ea)
{
fetch (sd, &code->dst, &rd))
goto end;
- /* FIXME: is this the right place to be doing sign extend? */
- if (OP_KIND (code->src.type) == OP_IMM &&
- (ea & 8) != 0)
- ea |= 0xfffffff0;
- else
- ea = SEXTSHORT (ea);
+ ea = SEXTSHORT (ea);
if (ea)
{
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_callback->printf_filtered) (sim_callback,
- "sim_resume: internal error.\n");
- sim_engine_set_run_state (sd, sim_stopped, SIGILL);
+ sim_io_printf (sd, "sim_resume: internal error.\n");
+ 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_exr (sd, (trace<<7) | intMask);
h8_set_mask (sd, oldmask);
- signal (SIGINT, prev);
}
-int
-sim_trace (SIM_DESC sd)
+void
+sim_engine_run (SIM_DESC sd,
+ int next_cpu_nr, /* ignore */
+ int nr_cpus, /* ignore */
+ int siggnal)
{
- /* FIXME: Unfinished. */
- (*sim_callback->printf_filtered) (sim_callback,
- "sim_trace: trace not supported.\n");
- return 1; /* Done. */
+ 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, unsigned char *buffer, int size)
+sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
{
int i;
return size;
}
-
-int
-sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
+static int
+h8300_reg_store (SIM_CPU *cpu, int rn, unsigned char *value, int length)
{
int longval;
int shortval;
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_callback->printf_filtered) (sim_callback,
- "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 -1;
+ return length;
}
-int
-sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
+static int
+h8300_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *buf, int length)
{
int v;
int longreg = 0;
- init_pointers (sd);
+ init_pointers (CPU_STATE (cpu));
if (!h8300smode && rn >= EXR_REGNUM)
rn++;
switch (rn)
{
default:
- (*sim_callback->printf_filtered) (sim_callback,
- "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;
-}
-
-void
-sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
-{
- sim_engine_get_run_state (sd, reason, sigrc);
-}
-
-/* FIXME: Rename to sim_set_mem_size. */
-
-void
-sim_size (int n)
-{
- /* Memory size is fixed. */
}
static void
double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
double virttime = h8_get_cycles (sd) / 10.0e6;
- (*sim_callback->printf_filtered) (sim_callback,
- "\n\n#instructions executed %10d\n",
- h8_get_insts (sd));
- (*sim_callback->printf_filtered) (sim_callback,
- "#cycles (v approximate) %10d\n",
- h8_get_cycles (sd));
- (*sim_callback->printf_filtered) (sim_callback,
- "#real time taken %10.4f\n",
- timetaken);
- (*sim_callback->printf_filtered) (sim_callback,
- "#virtual time taken %10.4f\n",
- virttime);
+ sim_io_printf (sd, "\n\n#instructions executed %10d\n", h8_get_insts (sd));
+ sim_io_printf (sd, "#cycles (v approximate) %10d\n", h8_get_cycles (sd));
+ sim_io_printf (sd, "#real time taken %10.4f\n", timetaken);
+ sim_io_printf (sd, "#virtual time taken %10.4f\n", virttime);
if (timetaken != 0.0)
- (*sim_callback->printf_filtered) (sim_callback,
- "#simulation ratio %10.4f\n",
- virttime / timetaken);
- (*sim_callback->printf_filtered) (sim_callback,
- "#compiles %10d\n",
- h8_get_compiles (sd));
- (*sim_callback->printf_filtered) (sim_callback,
- "#cache size %10d\n",
- sd->sim_cache_size);
+ sim_io_printf (sd, "#simulation ratio %10.4f\n", virttime / timetaken);
+ sim_io_printf (sd, "#compiles %10d\n", h8_get_compiles (sd));
+ sim_io_printf (sd, "#cache size %10d\n", sd->sim_cache_size);
#ifdef ADEBUG
/* This to be conditional on `what' (aka `verbose'),
for (i = 0; i < O_LAST; i++)
{
if (h8_get_stats (sd, i))
- (*sim_callback->printf_filtered) (sim_callback, "%d: %d\n",
- i, h8_get_stats (sd, i));
+ sim_io_printf (sd, "%d: %d\n", i, h8_get_stats (sd, i));
}
}
#endif
This function being replaced by a sim_open:ARGV configuration
option. */
+ h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
+
if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
h8300sxmode = 1;
h8300_normal_mode = 1;
}
+/* H8300-specific options.
+ TODO: These really should be merged into the common model modules. */
+typedef enum {
+ OPTION_H8300H,
+ OPTION_H8300S,
+ OPTION_H8300SX
+} H8300_OPTIONS;
+
+static SIM_RC
+h8300_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
+ char *arg, int is_command ATTRIBUTE_UNUSED)
+{
+ switch ((H8300_OPTIONS) opt)
+ {
+ case OPTION_H8300H:
+ set_h8300h (bfd_mach_h8300h);
+ break;
+ case OPTION_H8300S:
+ set_h8300h (bfd_mach_h8300s);
+ break;
+ case OPTION_H8300SX:
+ set_h8300h (bfd_mach_h8300sx);
+ break;
+
+ default:
+ /* We'll actually never get here; the caller handles the error
+ case. */
+ sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
+ return SIM_RC_FAIL;
+ }
+
+ return SIM_RC_OK;
+}
+
+static const OPTION h8300_options[] =
+{
+ { {"h8300h", no_argument, NULL, OPTION_H8300H},
+ 'h', NULL, "Indicate the CPU is H8/300H",
+ h8300_option_handler },
+ { {"h8300s", no_argument, NULL, OPTION_H8300S},
+ 'S', NULL, "Indicate the CPU is H8S",
+ h8300_option_handler },
+ { {"h8300sx", no_argument, NULL, OPTION_H8300SX},
+ 'x', NULL, "Indicate the CPU is H8SX",
+ h8300_option_handler },
+ { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
+};
+
+static sim_cia
+h8300_pc_get (sim_cpu *cpu)
+{
+ return cpu->pc;
+}
+
+static void
+h8300_pc_set (sim_cpu *cpu, sim_cia pc)
+{
+ cpu->pc = pc;
+}
+
/* Cover function of sim_state_free to free the cpu buffers as well. */
static void
sim_open (SIM_OPEN_KIND kind,
struct host_callback_struct *callback,
struct bfd *abfd,
- char **argv)
+ char * const *argv)
{
+ int i;
SIM_DESC sd;
sim_cpu *cpu;
sd = sim_state_alloc (kind, callback);
- sd->cpu = sim_cpu_alloc (sd, 0);
+
+ /* The cpu data is kept in a separately allocated chunk of memory. */
+ if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
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);
return 0;
}
- /* getopt will print the error message so we just have to exit if
- this fails. FIXME: Hmmm... in the case of gdb we need getopt
- to call print_filtered. */
+ if (sim_add_option_table (sd, NULL, h8300_options) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
+ /* The parser will print an error message for us, so we silently return. */
if (sim_parse_args (sd, argv) != SIM_RC_OK)
{
/* Uninstall the modules to avoid memory leaks,
return 0;
}
+ /* CPU specific initialization. */
+ for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+ {
+ SIM_CPU *cpu = STATE_CPU (sd, i);
+
+ CPU_REG_FETCH (cpu) = h8300_reg_fetch;
+ CPU_REG_STORE (cpu) = h8300_reg_store;
+ CPU_PC_FETCH (cpu) = h8300_pc_get;
+ CPU_PC_STORE (cpu) = h8300_pc_set;
+ }
+
/* sim_hw_configure (sd); */
/* FIXME: Much of the code in sim_load can be moved here. */
- sim_kind = kind;
- myname = argv[0];
- sim_callback = callback;
return sd;
}
-void
-sim_close (SIM_DESC sd, int quitting)
-{
- /* Nothing to do. */
-}
-
/* Called by gdb to load a program into memory. */
SIM_RC
-sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
+sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
{
bfd *prog_bfd;
if (abfd != NULL)
prog_bfd = abfd;
else
- prog_bfd = bfd_openr (prog, "coff-h8300");
+ prog_bfd = bfd_openr (prog, NULL);
if (prog_bfd != NULL)
{
/* Set the cpu type. We ignore failure from bfd_check_format
calloc (sizeof (char), memory_size));
h8_set_cache_idx_buf (sd, (unsigned short *)
calloc (sizeof (short), memory_size));
+ sd->memory_size = memory_size;
h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
/* `msize' must be a power of two. */
if ((memory_size & (memory_size - 1)) != 0)
{
- (*sim_callback->printf_filtered) (sim_callback,
- "sim_load: bad memory size.\n");
+ sim_io_printf (sd, "sim_load: bad memory size.\n");
return SIM_RC_FAIL;
}
h8_set_mask (sd, memory_size - 1);
- if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
- sim_kind == SIM_OPEN_DEBUG,
+ if (sim_load_file (sd, STATE_MY_NAME (sd), STATE_CALLBACK (sd), prog,
+ prog_bfd, STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG,
0, sim_write)
== NULL)
{
}
SIM_RC
-sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
+sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
+ char * const *argv, char * const *env)
{
int i = 0;
int len_arg = 0;
return SIM_RC_OK;
}
-
-void
-sim_do_command (SIM_DESC sd, char *cmd)
-{
- (*sim_callback->printf_filtered) (sim_callback,
- "This simulator does not accept any commands.\n");
-}
-
-void
-sim_set_callbacks (struct host_callback_struct *ptr)
-{
- sim_callback = ptr;
-}