* AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include "config.h"
+/* This must come before any other includes. */
+#include "defs.h"
+
#include <signal.h>
-#ifdef HAVE_TIME_H
#include <time.h>
-#endif
-#ifdef HAVE_STDLIB_H
#include <stdlib.h>
-#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include "sys/stat.h"
#include "sys/types.h"
#include "sim-options.h"
+#include "sim-signal.h"
+#include "sim/callback.h"
#ifndef SIGTRAP
# define SIGTRAP 5
int debug;
-/* 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
- by gdb. */
-static void set_simcache_size (SIM_DESC, int);
+static int memory_size;
#define X(op, size) (op * 4 + size)
(STATE_CPU (sd, 0)) -> regs[VBR_REGNUM] = val;
}
-static int
-h8_get_cache_top (SIM_DESC sd)
-{
- return sd -> cache_top;
-}
-
-static void
-h8_set_cache_top (SIM_DESC sd, int val)
-{
- sd -> cache_top = val;
-}
-
static int
h8_get_mask (SIM_DESC sd)
{
static enum h8300_sim_state
h8_get_state (SIM_DESC sd)
{
- return sd -> state;
+ return H8300_SIM_STATE (sd)->state;
}
static void
h8_set_state (SIM_DESC sd, enum h8300_sim_state val)
{
- sd -> state = val;
+ H8300_SIM_STATE (sd)->state = val;
}
#endif
static unsigned int
(STATE_CPU (sd, 0)) -> regs[MACL_REGNUM] = val;
}
-static int
-h8_get_compiles (SIM_DESC sd)
-{
- return sd -> compiles;
-}
-
-static void
-h8_increment_compiles (SIM_DESC sd)
-{
- sd -> compiles ++;
-}
-
static unsigned int *
h8_get_reg_buf (SIM_DESC sd)
{
static int
h8_get_stats (SIM_DESC sd, int idx)
{
- return sd -> stats[idx];
+ return H8300_SIM_STATE (sd)->stats[idx];
}
static void
h8_increment_stats (SIM_DESC sd, int idx)
{
- sd -> stats[idx] ++;
+ H8300_SIM_STATE (sd)->stats[idx] ++;
}
#endif /* ADEBUG */
-static unsigned short *
-h8_get_cache_idx_buf (SIM_DESC sd)
-{
- return sd -> cache_idx;
-}
-
-static void
-h8_set_cache_idx_buf (SIM_DESC sd, unsigned short *ptr)
-{
- sd -> cache_idx = ptr;
-}
-
-static unsigned short
-h8_get_cache_idx (SIM_DESC sd, unsigned int idx)
-{
- if (idx > sd->memory_size)
- return (unsigned short) -1;
- return sd -> cache_idx[idx];
-}
-
-static void
-h8_set_cache_idx (SIM_DESC sd, int idx, unsigned int val)
-{
- sd -> cache_idx[idx] = (unsigned short) val;
-}
-
static unsigned char *
h8_get_memory_buf (SIM_DESC sd)
{
static unsigned char
h8_get_memory (SIM_DESC sd, int idx)
{
+ ASSERT (idx < memory_size);
return (STATE_CPU (sd, 0)) -> memory[idx];
}
static void
h8_set_memory (SIM_DESC sd, int idx, unsigned int val)
{
+ ASSERT (idx < memory_size);
(STATE_CPU (sd, 0)) -> memory[idx] = (unsigned char) val;
}
-static unsigned char *
-h8_get_eightbit_buf (SIM_DESC sd)
-{
- return (STATE_CPU (sd, 0)) -> eightbit;
-}
-
-static void
-h8_set_eightbit_buf (SIM_DESC sd, unsigned char *ptr)
-{
- (STATE_CPU (sd, 0)) -> eightbit = ptr;
-}
-
-static unsigned char
-h8_get_eightbit (SIM_DESC sd, int idx)
-{
- return (STATE_CPU (sd, 0)) -> eightbit[idx];
-}
-
-static void
-h8_set_eightbit (SIM_DESC sd, int idx, unsigned int val)
-{
- (STATE_CPU (sd, 0)) -> eightbit[idx] = (unsigned char) val;
-}
-
static unsigned int
h8_get_delayed_branch (SIM_DESC sd)
{
return (STATE_CPU (sd, 0)) -> macS;
}
+#if 0
static void
h8_set_macS (SIM_DESC sd, int val)
{
(STATE_CPU (sd, 0)) -> macS = (val != 0);
}
+#endif
/* MAC Zero Flag */
static int
int h8300_normal_mode = 0;
int h8300sxmode = 0;
-static int memory_size;
-
static int
get_now (void)
{
}
static int
-cmdline_location()
+cmdline_location(void)
{
if (h8300smode && !h8300_normal_mode)
return 0xffff00L;
dst->dst.type = -1;
dst->src.type = -1;
+ dst->op3.type = -1;
/* Find the exact opcode/arg combo. */
for (q = h8_opcodes; q->name; q++)
/* End of Processing for system calls. */
}
+ /* Use same register is specified for source
+ and destination.
+ The value of source will be the value after
+ address calculation. */
+ if (OP_KIND (dst->opcode) != O_CMP &&
+ OP_KIND (dst->src.type) == OP_REG &&
+ (dst->src.reg & 7) == dst->dst.reg) {
+ switch (OP_KIND (dst->dst.type))
+ {
+ case OP_POSTDEC:
+ dst->src.type = X (OP_REG_DEC,
+ OP_SIZE (dst->dst.type));
+ break;
+ case OP_POSTINC:
+ dst->src.type = X (OP_REG_INC,
+ OP_SIZE (dst->dst.type));
+ break;
+ case OP_PREINC:
+ if (OP_KIND (dst->opcode) == O_MOV)
+ dst->src.type = X (OP_REG_INC,
+ OP_SIZE (dst->dst.type));
+ break;
+ case OP_PREDEC:
+ if (OP_KIND (dst->opcode) == O_MOV)
+ dst->src.type = X (OP_REG_DEC,
+ OP_SIZE (dst->dst.type));
+ break;
+ }
+ }
dst->next_pc = addr + len / 2;
return;
}
dst->opcode = O (O_ILL, SB);
}
-static void
-compile (SIM_DESC sd, int pc)
-{
- int idx;
-
- /* Find the next cache entry to use. */
- idx = h8_get_cache_top (sd) + 1;
- h8_increment_compiles (sd);
- if (idx >= sd->sim_cache_size)
- {
- idx = 1;
- }
- h8_set_cache_top (sd, idx);
-
- /* Throw away its old meaning. */
- h8_set_cache_idx (sd, sd->sim_cache[idx].oldpc, 0);
-
- /* Set to new address. */
- sd->sim_cache[idx].oldpc = pc;
-
- /* Fill in instruction info. */
- decode (sd, pc, h8_get_memory_buf (sd) + pc, sd->sim_cache + idx);
-
- /* Point to new cache entry. */
- h8_set_cache_idx (sd, pc, idx);
-}
-
-
static unsigned char *breg[32];
static unsigned short *wreg[16];
((X) < memory_size \
? ((h8_get_memory (sd, (X)+0) << 24) | (h8_get_memory (sd, (X)+1) << 16) \
| (h8_get_memory (sd, (X)+2) << 8) | (h8_get_memory (sd, (X)+3) << 0)) \
- : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 24) \
- | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 16) \
- | (h8_get_eightbit (sd, ((X)+2) & 0xff) << 8) \
- | (h8_get_eightbit (sd, ((X)+3) & 0xff) << 0)))
+ : 0)
#define GET_MEMORY_W(X) \
((X) < memory_size \
- ? ((h8_get_memory (sd, (X)+0) << 8) \
- | (h8_get_memory (sd, (X)+1) << 0)) \
- : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 8) \
- | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 0)))
-
+ ? ((h8_get_memory (sd, (X)+0) << 8) | (h8_get_memory (sd, (X)+1) << 0)) \
+ : 0)
#define GET_MEMORY_B(X) \
- ((X) < memory_size ? (h8_get_memory (sd, (X))) \
- : (h8_get_eightbit (sd, (X) & 0xff)))
+ ((X) < memory_size ? h8_get_memory (sd, (X)) : 0)
#define SET_MEMORY_L(X, Y) \
{ register unsigned char *_p; register int __y = (Y); \
- _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \
- h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
+ _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : 0); \
_p[0] = __y >> 24; _p[1] = __y >> 16; \
_p[2] = __y >> 8; _p[3] = __y >> 0; \
}
#define SET_MEMORY_W(X, Y) \
{ register unsigned char *_p; register int __y = (Y); \
- _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : \
- h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
+ _p = ((X) < memory_size ? h8_get_memory_buf (sd) + (X) : 0); \
_p[0] = __y >> 8; _p[1] = __y; \
}
#define SET_MEMORY_B(X, Y) \
- ((X) < memory_size ? (h8_set_memory (sd, (X), (Y))) \
- : (h8_set_eightbit (sd, (X) & 0xff, (Y))))
+ ((X) < memory_size ? h8_set_memory (sd, (X), (Y)) : 0)
/* Simulate a memory fetch.
Return 0 for success, -1 for failure.
*val = abs;
break;
+ case X (OP_REG_DEC, SB): /* Register direct, affected decrement byte. */
+ *val = GET_B_REG (rn) - 1;
+ break;
+ case X (OP_REG_DEC, SW): /* Register direct, affected decrement word. */
+ *val = GET_W_REG (rn) - 2;
+ break;
+ case X (OP_REG_DEC, SL): /* Register direct, affected decrement long. */
+ *val = GET_L_REG (rn) - 4;
+ break;
+ case X (OP_REG_INC, SB): /* Register direct, affected increment byte. */
+ *val = GET_B_REG (rn) + 1;
+ break;
+ case X (OP_REG_INC, SW): /* Register direct, affected increment word. */
+ *val = GET_W_REG (rn) + 2;
+ break;
+ case X (OP_REG_INC, SL): /* Register direct, affected increment long. */
+ *val = GET_L_REG (rn) + 4;
+ break;
+
case X (OP_MEM, SB): /* Why isn't this implemented? */
default:
sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
static void
init_pointers (SIM_DESC sd)
{
+ struct h8300_sim_state *state = H8300_SIM_STATE (sd);
+
if (init_pointers_needed)
{
int i;
sim_io_printf
(sd,
"init_pointers: bad memory size %d, defaulting to %d.\n",
- memory_size, memory_size = H8300S_MSIZE);
+ memory_size, H8300S_MSIZE);
+ memory_size = H8300S_MSIZE;
}
if (h8_get_memory_buf (sd))
free (h8_get_memory_buf (sd));
- if (h8_get_cache_idx_buf (sd))
- free (h8_get_cache_idx_buf (sd));
- if (h8_get_eightbit_buf (sd))
- free (h8_get_eightbit_buf (sd));
h8_set_memory_buf (sd, (unsigned char *)
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));
+ state->memory_size = memory_size;
h8_set_mask (sd, memory_size - 1);
}
init_pointers_needed = 0;
-
- /* Initialize the seg registers. */
- if (!sd->sim_cache)
- set_simcache_size (sd, CSIZE);
}
}
int bit;
int pc;
int c, nz, v, n, u, h, ui, intMaskBit;
- int trace, intMask;
+ int trace = 0;
+ int intMask = 0;
int oldmask;
+ const struct h8300_sim_state *state = H8300_SIM_STATE (sd);
host_callback *sim_callback = STATE_CALLBACK (sd);
init_pointers (sd);
h8_set_mask (sd, 0xffff);
do
{
- unsigned short cidx;
- decoded_inst *code;
-
- top:
- cidx = h8_get_cache_idx (sd, pc);
- if (cidx == (unsigned short) -1 ||
- cidx >= sd->sim_cache_size)
- goto illegal;
-
- code = sd->sim_cache + cidx;
+ decoded_inst _code, *code = &_code;
+ memset (code, 0, sizeof (*code));
+ decode (sd, pc, h8_get_memory_buf (sd) + pc, code);
+ code->oldpc = pc;
#if ADEBUG
if (debug)
switch (code->opcode)
{
- case 0:
- /*
- * This opcode is a fake for when we get to an
- * instruction which hasnt been compiled
- */
- compile (sd, pc);
- goto top;
- break;
-
case O (O_MOVAB, SL):
case O (O_MOVAW, SL):
case O (O_MOVAL, SL):
of the same register.
*/
- if (code->op3.type == 0)
+ if (code->op3.type == -1)
{
/* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
We get to compose dst and op3 as follows:
case O (O_AND, SB): /* and.b */
/* Fetch rd and ea. */
- if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
+ if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea))
goto end;
res = rd & ea;
goto log8;
case O (O_OR, SB): /* or.b */
/* Fetch rd and ea. */
- if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
+ if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea))
goto end;
res = rd | ea;
goto log8;
? h8_get_reg (sd, R4_REGNUM) & 0xffff
: h8_get_reg (sd, R4_REGNUM) & 0xff);
- _src = (h8_get_reg (sd, R5_REGNUM) < memory_size
- ? h8_get_memory_buf (sd) + h8_get_reg (sd, R5_REGNUM)
- : h8_get_eightbit_buf (sd) +
- (h8_get_reg (sd, R5_REGNUM) & 0xff));
+ _src = h8_get_memory_buf (sd) + h8_get_reg (sd, R5_REGNUM);
if ((_src + count) >= (h8_get_memory_buf (sd) + memory_size))
- {
- if ((_src + count) >= (h8_get_eightbit_buf (sd) + 0x100))
- goto illegal;
- }
- _dst = (h8_get_reg (sd, R6_REGNUM) < memory_size
- ? h8_get_memory_buf (sd) + h8_get_reg (sd, R6_REGNUM)
- : h8_get_eightbit_buf (sd) +
- (h8_get_reg (sd, R6_REGNUM) & 0xff));
-
+ goto illegal;
+ _dst = h8_get_memory_buf (sd) + h8_get_reg (sd, R6_REGNUM);
if ((_dst + count) >= (h8_get_memory_buf (sd) + memory_size))
- {
- if ((_dst + count) >= (h8_get_eightbit_buf (sd) + 0x100))
- goto illegal;
- }
+ goto illegal;
memcpy (_dst, _src, count);
h8_set_reg (sd, R5_REGNUM, h8_get_reg (sd, R5_REGNUM) + count);
if (addr < memory_size)
{
h8_set_memory (sd, addr + i, buffer[i]);
- h8_set_cache_idx (sd, addr + i, 0);
}
else
- {
- h8_set_eightbit (sd, (addr + i) & 0xff, buffer[i]);
- }
+ break;
}
- return size;
+ return i;
}
int
init_pointers (sd);
if (addr < 0)
return 0;
- if (addr < memory_size)
+ if (addr + size < memory_size)
memcpy (buffer, h8_get_memory_buf (sd) + addr, size);
else
- memcpy (buffer, h8_get_eightbit_buf (sd) + (addr & 0xff), size);
+ return 0;
return size;
}
}
}
-static void
-set_simcache_size (SIM_DESC sd, int n)
-{
- if (sd->sim_cache)
- free (sd->sim_cache);
- if (n < 2)
- n = 2;
- sd->sim_cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
- memset (sd->sim_cache, 0, sizeof (decoded_inst) * n);
- sd->sim_cache_size = n;
-}
-
-
void
sim_info (SIM_DESC sd, int verbose)
{
+ const struct h8300_sim_state *state = H8300_SIM_STATE (sd);
double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
double virttime = h8_get_cycles (sd) / 10.0e6;
sim_io_printf (sd, "#virtual time taken %10.4f\n", virttime);
if (timetaken != 0.0)
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'),
/* Indicate whether the cpu is an H8/300 or H8/300H.
FLAG is non-zero for the H8/300H. */
-void
+static void
set_h8300h (unsigned long machine)
{
/* FIXME: Much of the code in sim_load can be moved to sim_open.
SIM_DESC sd;
sim_cpu *cpu;
- sd = sim_state_alloc (kind, callback);
+ sd = sim_state_alloc_extra (kind, callback, sizeof (struct h8300_sim_state));
+
+ /* Set default options before parsing user options. */
+ current_target_byte_order = BFD_ENDIAN_BIG;
/* 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)
+ if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
{
free_state (sd);
return 0;
}
/* Check for/establish the a reference program image. */
- if (sim_analyze_program (sd,
- (STATE_PROG_ARGV (sd) != NULL
- ? *STATE_PROG_ARGV (sd)
- : NULL), abfd) != SIM_RC_OK)
+ if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
{
free_state (sd);
return 0;
SIM_RC
sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
{
+ struct h8300_sim_state *state = H8300_SIM_STATE (sd);
bfd *prog_bfd;
/* FIXME: The code below that sets a specific variant of the H8/300
if (h8_get_memory_buf (sd))
free (h8_get_memory_buf (sd));
- if (h8_get_cache_idx_buf (sd))
- free (h8_get_cache_idx_buf (sd));
- if (h8_get_eightbit_buf (sd))
- free (h8_get_eightbit_buf (sd));
h8_set_memory_buf (sd, (unsigned char *)
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));
+ state->memory_size = memory_size;
/* `msize' must be a power of two. */
if ((memory_size & (memory_size - 1)) != 0)