/*
- * Simulator for the Hitachi H8/300 architecture.
+ * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
*
* Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
*
* 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
#define X(op, size) (op * 4 + size)
-#define SP (h8300hmode ? SL : SW)
+#define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
#define h8_opcodes ops
#define DEFINE_TABLE
/* 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)
{
h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4) \
| (N << 3) | (Z << 2) | (V << 1) | C)
+#define GETSR(SD) \
+ /* Get Status Register (flags). */ \
+ c = (h8_get_ccr (sd) >> 0) & 1; \
+ v = (h8_get_ccr (sd) >> 1) & 1; \
+ nz = !((h8_get_ccr (sd) >> 2) & 1); \
+ n = (h8_get_ccr (sd) >> 3) & 1; \
+ u = (h8_get_ccr (sd) >> 4) & 1; \
+ h = (h8_get_ccr (sd) >> 5) & 1; \
+ ui = ((h8_get_ccr (sd) >> 6) & 1); \
+ intMaskBit = (h8_get_ccr (sd) >> 7) & 1
+
+
#ifdef __CHAR_IS_SIGNED__
#define SEXTCHAR(x) ((char) (x))
#endif
int h8300hmode = 0;
int h8300smode = 0;
+int h8300_normal_mode = 0;
int h8300sxmode = 0;
static int memory_size;
case L_32:
return SL;
case L_P:
- return h8300hmode ? SL : SW;
+ return (h8300hmode && !h8300_normal_mode)? SL : SW;
}
return 0;
}
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
cmdline_location()
{
- if (h8300smode)
+ if (h8300smode && !h8300_normal_mode)
return 0xffff00L;
- else if (h8300hmode)
+ else if (h8300hmode && !h8300_normal_mode)
return 0x2ff00L;
else
return 0xff00L;
/* 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) ||
+ (q->available == AV_H8S && !h8300smode) ||
(q->available == AV_H8H && !h8300hmode))
continue;
+ cst[0] = cst[1] = cst[2] = 0;
+ reg[0] = reg[1] = reg[2] = 0;
+ rdisp[0] = rdisp[1] = rdisp[2] = 0;
+
while (1)
{
op_type looking_for = *nib;
(looking_for & MODE) == INDEXB ||
(looking_for & MODE) == INDEXW ||
(looking_for & MODE) == INDEXL)
-
{
switch (looking_for & SIZE)
{
case L_2:
cst[opnum] = thisnib & 3;
-
- /* DISP2 special treatment. */
- if ((looking_for & MODE) == DISP)
- {
- switch (OP_SIZE (q->how)) {
- default: break;
- case SW:
- cst[opnum] *= 2;
- break;
- case SL:
- cst[opnum] *= 4;
- break;
- }
- }
break;
case L_8:
cst[opnum] = SEXTCHAR (data[len / 2]);
(looking_for & SIZE) == L_16U)
{
cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
- if ((looking_for & SIZE) != L_16U)
+ /* Immediates are always unsigned. */
+ if ((looking_for & SIZE) != L_16U &&
+ (looking_for & MODE) != IMM)
cst[opnum] = (short) cst[opnum]; /* Sign extend. */
}
else if (looking_for & ABSJMP)
{
cst[opnum] = data[1];
}
+ else if ((looking_for & MODE) == VECIND)
+ {
+ if(h8300_normal_mode)
+ cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
+ else
+ cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
+ cst[opnum] += h8_get_vbr (sd); /* Add vector base reg. */
+ }
else if ((looking_for & SIZE) == L_32)
{
int i = len / 2;
cst[opnum] = data[len / 2] & 0xff;
}
}
+ else if ((looking_for & SIZE) == L_2)
+ {
+ cst[opnum] = thisnib & 3;
+ }
else if ((looking_for & SIZE) == L_3 ||
(looking_for & SIZE) == L_3NZ)
{
#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)
else
p->reg = ZERO_REGNUM;;
}
- else if ((x & MODE) == MEMIND)
+ else if ((x & MODE) == MEMIND ||
+ (x & MODE) == VECIND)
{
/* Size doesn't matter. */
p->type = X (OP_MEM, SB);
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)
p->type = X (OP_IMM, SP);
p->literal = cst[opnum];
}
- else if ((x & MODE) == INDEXB ||
- (x & MODE) == INDEXW ||
- (x & MODE) == INDEXL ||
- (x & MODE) == DISP)
+ else if ((x & MODE) == INDEXB)
{
- /* Use the instruction to determine
- the operand size. */
- switch (x & MODE) {
- case INDEXB:
- p->type = X (OP_INDEXB, OP_SIZE (q->how));
- break;
- case INDEXW:
- p->type = X (OP_INDEXW, OP_SIZE (q->how));
- break;
- case INDEXL:
- p->type = X (OP_INDEXL, OP_SIZE (q->how));
- break;
- case DISP:
- p->type = X (OP_DISP, OP_SIZE (q->how));
- break;
- }
-
+ p->type = X (OP_INDEXB, OP_SIZE (q->how));
+ p->literal = cst[opnum];
+ p->reg = rdisp[opnum];
+ }
+ else if ((x & MODE) == INDEXW)
+ {
+ p->type = X (OP_INDEXW, OP_SIZE (q->how));
+ p->literal = cst[opnum];
+ p->reg = rdisp[opnum];
+ }
+ else if ((x & MODE) == INDEXL)
+ {
+ p->type = X (OP_INDEXL, OP_SIZE (q->how));
p->literal = cst[opnum];
p->reg = rdisp[opnum];
}
+ else if ((x & MODE) == DISP)
+ {
+ /* Yuck -- special for mova args. */
+ if (strncmp (q->name, "mova", 4) == 0 &&
+ (x & SIZE) == L_2)
+ {
+ /* Mova can have a DISP2 dest, with an
+ INDEXB or INDEXW src. The multiplier
+ for the displacement value is determined
+ by the src operand, not by the insn. */
+
+ switch (OP_KIND (dst->src.type))
+ {
+ case OP_INDEXB:
+ p->type = X (OP_DISP, SB);
+ p->literal = cst[opnum];
+ break;
+ case OP_INDEXW:
+ p->type = X (OP_DISP, SW);
+ p->literal = cst[opnum] * 2;
+ break;
+ default:
+ goto fail;
+ }
+ }
+ else
+ {
+ p->type = X (OP_DISP, OP_SIZE (q->how));
+ p->literal = cst[opnum];
+ /* DISP2 is special. */
+ if ((x & SIZE) == L_2)
+ switch (OP_SIZE (q->how))
+ {
+ case SB: break;
+ case SW: p->literal *= 2; break;
+ case SL: p->literal *= 4; break;
+ }
+ }
+ p->reg = rdisp[opnum];
+ }
else if (x & CTRL)
{
switch (reg[opnum])
p->type = OP_EXR;
}
else
- printf ("Hmmmm %x...\n", x);
+ printf ("Hmmmm 0x%x...\n", x);
args++;
}
return;
}
else
- printf ("Don't understand %x \n", looking_for);
+ printf ("Don't understand 0x%x \n", looking_for);
}
len++;
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)
+ if (h8300smode && !h8300_normal_mode)
memory_size = H8300S_MSIZE;
- else if (h8300hmode)
+ else if (h8300hmode && !h8300_normal_mode)
memory_size = H8300H_MSIZE;
else
memory_size = H8300_MSIZE;
/* `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;
}
/* Get Status Register (flags). */
- c = (h8_get_ccr (sd) >> 0) & 1;
- v = (h8_get_ccr (sd) >> 1) & 1;
- nz = !((h8_get_ccr (sd) >> 2) & 1);
- n = (h8_get_ccr (sd) >> 3) & 1;
- u = (h8_get_ccr (sd) >> 4) & 1;
- h = (h8_get_ccr (sd) >> 5) & 1;
- ui = ((h8_get_ccr (sd) >> 6) & 1);
- intMaskBit = (h8_get_ccr (sd) >> 7) & 1;
+ GETSR (sd);
if (h8300smode) /* Get exr. */
{
}
oldmask = h8_get_mask (sd);
- if (!h8300hmode)
+ if (!h8300hmode || h8300_normal_mode)
h8_set_mask (sd, 0xffff);
do
{
(mova/b, mova/w, mova/l).
4) Add literal value of 1st argument (src).
5) Store result in 3rd argument (op3).
+ */
+
+ /* Alas, since this is the only instruction with 3 arguments,
+ decode doesn't handle them very well. Some fix-up is required.
+
+ a) The size of dst is determined by whether src is
+ INDEXB or INDEXW. */
+ if (OP_KIND (code->src.type) == OP_INDEXB)
+ code->dst.type = X (OP_KIND (code->dst.type), SB);
+ else if (OP_KIND (code->src.type) == OP_INDEXW)
+ code->dst.type = X (OP_KIND (code->dst.type), SW);
+
+ /* b) If op3 == null, then this is the short form of the insn.
+ Dst is the dispreg of src, and op3 is the 32-bit form
+ of the same register.
*/
+
+ if (code->op3.type == 0)
+ {
+ /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
+ We get to compose dst and op3 as follows:
+
+ op3 is a 32-bit register, ID == src.reg.
+ dst is the same register, but 8 or 16 bits
+ depending on whether src is INDEXB or INDEXW.
+ */
+
+ code->op3.type = X (OP_REG, SL);
+ code->op3.reg = code->src.reg;
+ code->op3.literal = 0;
+
+ if (OP_KIND (code->src.type) == OP_INDEXB)
+ {
+ code->dst.type = X (OP_REG, SB);
+ code->dst.reg = code->op3.reg + 8;
+ }
+ else
+ code->dst.type = X (OP_REG, SW);
+ }
+
if (fetch (sd, &code->dst, &ea))
goto end;
goto end;
goto just_flags_log32;
- case O (O_MOVMD, SB): /* movsd.b */
+ case O (O_MOVMD, SB): /* movmd.b */
ea = GET_W_REG (4);
if (ea == 0)
ea = 0x10000;
}
goto next;
- case O (O_MOVMD, SW): /* movsd.b */
+ case O (O_MOVMD, SW): /* movmd.w */
ea = GET_W_REG (4);
if (ea == 0)
ea = 0x10000;
}
goto next;
- case O (O_MOVMD, SL): /* movsd.b */
+ case O (O_MOVMD, SL): /* movmd.l */
ea = GET_W_REG (4);
if (ea == 0)
ea = 0x10000;
{
if (h8300smode)
h8_set_exr (sd, (trace << 7) | intMask);
- res = h8_get_exr (sd);
+ rd = h8_get_exr (sd);
}
else
goto illegal;
/* Setting char_ptr_size to the sizeof (char *) on the different
architectures. */
- if (h8300hmode || h8300smode)
+ if ((h8300hmode || h8300smode) && !h8300_normal_mode)
{
char_ptr_size = 4;
}
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;
for (i = 0; i < no_of_args; i++)
{
/* Saving the argv pointer. */
- if (h8300hmode || h8300smode)
+ if ((h8300hmode || h8300smode) && !h8300_normal_mode)
{
SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
}
/* Required by POSIX, Setting 0x0 at the end of the list of argv
pointers. */
- if (h8300hmode || h8300smode)
+ if ((h8300hmode || h8300smode) && !h8300_normal_mode)
{
SET_MEMORY_L (old_sp, 0x0);
}
/* Setting filename_ptr to first argument of open, */
/* and trying to get mode. */
- if (h8300sxmode || h8300hmode || h8300smode)
+ if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
{
filename_ptr = GET_L_REG (0);
mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
int read_return = 0; /* Return value from callback to
read. */
- fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
- buf_size = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
+ fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
+ buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
char_ptr = (char *) malloc (sizeof (char) * buf_size);
int write_return; /* Return value from callback to write. */
int i = 0; /* Loop counter */
- fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
- char_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
- len = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
+ fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
+ char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
+ len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
/* Allocating space for the characters to be written. */
ptr = (char *) malloc (sizeof (char) * len);
int origin; /* Origin */
int lseek_return; /* Return value from callback to lseek. */
- fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
- offset = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
- origin = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
+ fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
+ offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
+ origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
/* Callback lseek and return offset. */
lseek_return =
int fd; /* File descriptor */
int close_return; /* Return value from callback to close. */
- fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
+ fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
/* Callback close and return. */
close_return = sim_callback->close (sim_callback, fd);
int stat_ptr; /* Pointer to stat record. */
char *temp_stat_ptr; /* Temporary stat_rec pointer. */
- fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
+ fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
/* Setting stat_ptr to second argument of stat. */
- stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
+ 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);
int i = 0; /* Loop Counter */
/* Setting filename_ptr to first argument of open. */
- filename_ptr = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
+ filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
/* Trying to find the length of the filename. */
temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
/* Setting stat_ptr to second argument of stat. */
/* stat_ptr = h8_get_reg (sd, 1); */
- stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
+ stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
/* 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);
if (fetch2 (sd, &code->dst, &rd))
goto end;
- if (code->src.type == X (OP_IMM, SB))
+ if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
+ ea = 1; /* unary op */
+ else /* binary op */
fetch (sd, &code->src, &ea);
- else
- ea = 1;
if (code->opcode == O (O_SHLL, SB))
{
if (fetch2 (sd, &code->dst, &rd))
goto end;
- if (code->src.type == X (OP_IMM, SW))
- fetch (sd, &code->src, &ea);
+ if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
+ ea = 1; /* unary op */
else
- ea = 1;
+ fetch (sd, &code->src, &ea);
if (code->opcode == O (O_SHLL, SW))
{
if (fetch2 (sd, &code->dst, &rd))
goto end;
- if (code->src.type == X (OP_IMM, SL))
- fetch (sd, &code->src, &ea);
+ if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
+ ea = 1; /* unary op */
else
- ea = 1;
+ fetch (sd, &code->src, &ea);
if (code->opcode == O (O_SHLL, SL))
{
case O (O_JMP, SL):
case O (O_JMP, SB): /* jmp */
case O (O_JMP, SW):
- {
- fetch (sd, &code->src, &pc);
- goto end;
- }
+ fetch (sd, &code->src, &pc);
+ goto end;
case O (O_JSR, SN):
case O (O_JSR, SL):
case O (O_JSR, SB): /* jsr, jump to subroutine */
case O (O_JSR, SW):
- {
- int tmp;
- if (fetch (sd, &code->src, &pc))
- goto end;
- call:
- tmp = h8_get_reg (sd, SP_REGNUM);
+ if (fetch (sd, &code->src, &pc))
+ goto end;
+ call:
+ tmp = h8_get_reg (sd, SP_REGNUM);
- if (h8300hmode)
- {
- tmp -= 4;
- SET_MEMORY_L (tmp, code->next_pc);
- }
- else
- {
- tmp -= 2;
- SET_MEMORY_W (tmp, code->next_pc);
- }
- h8_set_reg (sd, SP_REGNUM, tmp);
+ if (h8300hmode && !h8300_normal_mode)
+ {
+ tmp -= 4;
+ SET_MEMORY_L (tmp, code->next_pc);
+ }
+ else
+ {
+ tmp -= 2;
+ SET_MEMORY_W (tmp, code->next_pc);
+ }
+ h8_set_reg (sd, SP_REGNUM, tmp);
- goto end;
- }
+ goto end;
case O (O_BSR, SW):
case O (O_BSR, SL):
pc = code->next_pc + res;
goto call;
- case O (O_RTS, SN): /* rts, return from subroutine */
- {
- int tmp;
+ case O (O_RTE, SN): /* rte, return from exception */
+ rte:
+ /* Pops exr and ccr before pc -- otherwise identical to rts. */
+ tmp = h8_get_reg (sd, SP_REGNUM);
+
+ if (h8300smode) /* pop exr */
+ {
+ h8_set_exr (sd, GET_MEMORY_L (tmp));
+ tmp += 4;
+ }
+ if (h8300hmode && !h8300_normal_mode)
+ {
+ h8_set_ccr (sd, GET_MEMORY_L (tmp));
+ tmp += 4;
+ pc = GET_MEMORY_L (tmp);
+ tmp += 4;
+ }
+ else
+ {
+ h8_set_ccr (sd, GET_MEMORY_W (tmp));
+ tmp += 2;
+ pc = GET_MEMORY_W (tmp);
+ tmp += 2;
+ }
- tmp = h8_get_reg (sd, SP_REGNUM);
+ GETSR (sd);
+ h8_set_reg (sd, SP_REGNUM, tmp);
+ goto end;
- if (h8300hmode)
- {
- pc = GET_MEMORY_L (tmp);
- tmp += 4;
- }
- else
- {
- pc = GET_MEMORY_W (tmp);
- tmp += 2;
- }
+ case O (O_RTS, SN): /* rts, return from subroutine */
+ rts:
+ tmp = h8_get_reg (sd, SP_REGNUM);
- h8_set_reg (sd, SP_REGNUM, tmp);
- goto end;
- }
+ if (h8300hmode && !h8300_normal_mode)
+ {
+ pc = GET_MEMORY_L (tmp);
+ tmp += 4;
+ }
+ else
+ {
+ pc = GET_MEMORY_W (tmp);
+ tmp += 2;
+ }
+
+ h8_set_reg (sd, SP_REGNUM, tmp);
+ 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
+ when we take a breakpoint trap, R0 has a "random",
+ user-defined value. Don't see any immediate solution. */
+ else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
+ {
+ /* Pass the stop signal up to gdb. */
+ 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;
+ case O (O_TRAPA, SB): /* trapa */
+ if (fetch (sd, &code->src, &res))
+ goto end; /* res is vector number. */
+
+ tmp = h8_get_reg (sd, SP_REGNUM);
+ if(h8300_normal_mode)
+ {
+ tmp -= 2;
+ SET_MEMORY_W (tmp, code->next_pc);
+ tmp -= 2;
+ SET_MEMORY_W (tmp, h8_get_ccr (sd));
+ }
+ else
+ {
+ tmp -= 4;
+ SET_MEMORY_L (tmp, code->next_pc);
+ tmp -= 4;
+ SET_MEMORY_L (tmp, h8_get_ccr (sd));
+ }
+ intMaskBit = 1;
+ BUILDSR (sd);
+
+ if (h8300smode)
+ {
+ tmp -= 4;
+ SET_MEMORY_L (tmp, h8_get_exr (sd));
+ }
+
+ h8_set_reg (sd, SP_REGNUM, tmp);
+
+ if(h8300_normal_mode)
+ pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
+ else
+ pc = GET_MEMORY_L (0x20 + res * 4);
+ 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;
goto next;
- case O (O_TAS, SB): /* tas, (test and set?) */
- if (!h8300smode || code->src.type != X (OP_REG, SL))
- goto illegal;
- switch (code->src.reg)
- {
- case R0_REGNUM:
- case R1_REGNUM:
- case R4_REGNUM:
- case R5_REGNUM:
- break;
- default:
- goto illegal;
- }
+ case O (O_TAS, SB): /* tas (test and set) */
+ if (!h8300sxmode) /* h8sx can use any register. */
+ switch (code->src.reg)
+ {
+ case R0_REGNUM:
+ case R1_REGNUM:
+ case R4_REGNUM:
+ case R5_REGNUM:
+ break;
+ default:
+ goto illegal;
+ }
+
if (fetch (sd, &code->src, &res))
goto end;
if (store (sd, &code->src, res | 0x80))
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;
res = 0;
}
- if (store (sd, &code->dst, (res & 0xffff) | (tmp << 8)))
+ if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
goto end;
goto next;
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)
{
goto next;
case O (O_LDM, SL): /* ldm, load from memory */
+ case O (O_RTEL, SN): /* rte/l, ldm plus rte */
+ case O (O_RTSL, SN): /* rts/l, ldm plus rts */
{
int nregs, firstreg, i;
- nregs = GET_MEMORY_B (pc + 1);
- nregs >>= 4;
- nregs &= 0xf;
- firstreg = code->dst.reg;
- firstreg &= 0xf;
+ nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
+ firstreg = code->dst.reg & 0xf;
for (i = firstreg; i >= firstreg - nregs; i--)
{
h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
}
}
- goto next;
+ switch (code->opcode) {
+ case O (O_RTEL, SN):
+ goto rte;
+ case O (O_RTSL, SN):
+ goto rts;
+ case O (O_LDM, SL):
+ goto next;
+ default:
+ goto illegal;
+ }
case O (O_DAA, SB):
/* Decimal Adjust Addition. This is for BCD arithmetic. */
- res = GET_B_REG (code->src.reg);
+ res = GET_B_REG (code->src.reg); /* FIXME fetch? */
if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
!h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
res = res; /* Value added == 0. */
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:
code->dst.type == X (OP_CCR, SW))
{
h8_set_ccr (sd, res);
- /* Get Status Register (flags). */
- c = (h8_get_ccr (sd) >> 0) & 1;
- v = (h8_get_ccr (sd) >> 1) & 1;
- nz = !((h8_get_ccr (sd) >> 2) & 1);
- n = (h8_get_ccr (sd) >> 3) & 1;
- u = (h8_get_ccr (sd) >> 4) & 1;
- h = (h8_get_ccr (sd) >> 5) & 1;
- ui = ((h8_get_ccr (sd) >> 6) & 1);
- intMaskBit = (h8_get_ccr (sd) >> 7) & 1;
+ GETSR (sd);
}
else if (h8300smode &&
(code->dst.type == X (OP_EXR, SB) ||
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)
+ cpu->pc = shortval; /* PC for Normal mode is 2 bytes */
+ else
+ 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 PC_REGNUM:
- h8_set_pc (sd, 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;
}
- if (h8300hmode || longreg)
+ /* In Normal mode PC is 2 byte, but other registers are 4 byte */
+ if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
{
buf[0] = v >> 24;
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. */
- if (machine == bfd_mach_h8300sx)
+ h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
+
+ if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
h8300sxmode = 1;
if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
h8300hmode = 1;
+
+ if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
+ 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. */
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
switching between H8/300 and H8/300H programs without exiting
gdb. */
- if (h8300smode)
+ if (h8300smode && !h8300_normal_mode)
memory_size = H8300S_MSIZE;
- else if (h8300hmode)
+ else if (h8300hmode && !h8300_normal_mode)
memory_size = H8300H_MSIZE;
else
memory_size = H8300_MSIZE;
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;
-}