#include "config.h"
#include <signal.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#include <sys/param.h>
#include <setjmp.h>
#include "ansidecl.h"
#include "bfd.h"
#include "gdb/callback.h"
#include "gdb/remote-sim.h"
#define O_RECOMPILE 85
#define DEFINE_TABLE
#define DISASSEMBLER_TABLE
void sim_set_simcache_size PARAMS ((int));
int debug;
host_callback *sim_callback;
static SIM_OPEN_KIND sim_kind;
static char *myname;
#ifdef __GNUC__
#define DISPATCH(X) goto *(X); do
#define LABEL(X) X##_L
#define LABELN(X,N) X##_L##N
#define LABEL_REF(X) &&X##_L
#define LABEL_REFN(X,N) &&X##_L##N
#define ENDDISPATCH while (0);
#define fastref void *
#define DEFAULT ;
#define INLINE __inline__
#else
#define DEFAULT default :
#define DISPATCH(X) switch (X)
#define LABEL(X) case X
#define LABELN(X,N) case X
#define LABEL_REF(X) X
#define LABEL_REFN(X,N) X
#define ENDDISPATCH
#define fastref int
#define INLINE
#define STORE_REG_B 1
#define STORE_REG_W 2
#define STORE_INC_B 3
#define STORE_INC_W 4
#define STORE_DEC_B 5
#define STORE_DEC_W 6
#define STORE_DISP_B 7
#define STORE_DISP_W 8
#define STORE_CRB 9
#define STORE_CRW 10
#define STORE_REG_L 11
#define STORE_NOP 12
#define FETCH_NOP 9
#define FETCH_REG_B 10
#define FETCH_REG_W 11
#define FETCH_INC_B 12
#define FETCH_INC_W 13
#define FETCH_DEC_B 14
#define FETCH_DEC_W 15
#define FETCH_DISP_B 16
#define FETCH_DISP_W 17
#define FETCH_IMM 18
#define FETCH_CRB 19
#define FETCH_CRW 20
#define FETCH_LVAL 21
#define FETCH_LVAL24 22
#define FETCH_REG_L 23
#define FLAG_m 20
#define FLAG_M 21
#define FLAG_A 22
#define FLAG_NONE 23
#define FLAG_NOSTORE 24
#define FLAG_CLEAR 25
#define FLAG_a 26
#define FLAG_BRANCH 27
#define FLAG_special 28
#define FLAG_shiftword 29
#define FLAG_shiftbyte 30
#define FLAG_multword 31
#define FLAG_multbyte 32
#endif
#define h8500_table h8500_compile_table
#include "../opcodes/h8500-opc.h"
#include "inst.h"
#define LOW_BYTE(x) ((x) & 0xff)
#define HIGH_BYTE(x) (((x)>>8) & 0xff)
#define NORMAL_CP ((cpu.regs[R_CP].c - cpu.memory)>>16)
#define NORMAL_DP ((cpu.regs[R_DP].c - cpu.memory)>>16)
#define NORMAL_EP ((cpu.regs[R_EP].c - cpu.memory)>>16)
#define NORMAL_TP ((cpu.regs[R_TP].c - cpu.memory)>>16)
#define SET_NORMREG(x,y) ((cpu.regs[x].l = (y)))
#define GET_NORMREG(x) (cpu.regs[x].l)
#define SET_SEGREG(x,y) { cpu.regs[x].c = ((y) & 0xff0000) + cpu.memory;}
#define GET_SEGREG(x) ( (cpu.regs[x].c - cpu.memory ) >> 16)
#define SET_NORMAL_CPPC(x) { pc = (x) & 0xffff; SET_SEGREG(R_CP, (x));}
#define NORMAL_SR ((N<<3)|(Z<<2)|(V<<1)|(C))
#define P(X,Y) ((X<<8) | Y)
#define BUILDSR() cpu.regs[R_SR].s[LOW] = (N << 3) | (Z << 2) | (V<<1) | C;
#define GETSR() \
C = (cpu.regs[R_SR].s[LOW] >> 0) & 1;\
V = (cpu.regs[R_SR].s[LOW] >> 1) & 1;\
Z = (cpu.regs[R_SR].s[LOW] >> 2) & 1;\
N = (cpu.regs[R_SR].s[LOW] >> 3) & 1;
#ifdef __CHAR_IS_SIGNED__
#define SEXTCHAR(x) ((char)(x))
#endif
#ifndef SEXTCHAR
#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff):x)
#endif
#define SEXTSHORT(x) ((short)(x))
static unsigned char **segmap[R_LAST];
static unsigned char *(regptr[R_LAST][3]);
static unsigned char *(segregptr[R_LAST][3]);
static cpu_state_type cpu;
static int segforreg[] = {R_DP, R_DP, R_DP, R_DP,
R_EP, R_EP, R_TP, R_TP,
R_DP, R_DP, R_DP, R_DP,
R_EP, R_EP, R_TP, R_TP};
int LOW;
int HIGH;
#define elval(struct, lit) \
(((*(struct.reg.wptr) + lit) & 0xffff) + (*(struct.r2.segreg)))
#define displval(s) elval((s),(s).literal)
#define ireglval(struct) elval(struct, 0)
#define wordat(x) (((x)[0] << 8) | (x)[1])
#define longat(x) ((wordat((x))<<16)|(wordat((x)+2)))
#define byteat(x) ((x)[0])
#define setwordat(x,y) {x[0] =( y)>>8; x[1] = y;}
#define setbyteat(x,y) {x[0] = y;}
ea_type rd;
ea_type rs;
ea_type imm;
ea_type cr;
ea_type ea;
ea_type nop;
ea_type lval;
ea_type lval24;
ea_type eavector[2];
int disp;
#define JBYTE 0
#define JWORD 1
#define JLONG 2
typedef union
{
struct
{
fastref srcabyte;
fastref srcaword;
fastref srcalong;
fastref srcbbyte;
fastref srcbword;
fastref srcblong;
fastref dstbyte;
fastref dstword;
fastref dstlong;
} s;
struct
{
fastref byte;
fastref word;
fastref lon;
} a[3];
fastref j[9];
} size_ptr;
union
{
struct ea_struct
{
size_ptr ea_nop;
size_ptr ea_reg;
size_ptr ea_inc;
size_ptr ea_dec;
size_ptr ea_disp;
size_ptr ea_imm;
size_ptr ea_cr;
size_ptr ea_lval;
size_ptr ea_lval24;
} s;
#define N_EATYPES (sizeof(struct ea_struct) / sizeof(size_ptr))
size_ptr a[N_EATYPES];
} eas;
static void
howto_workout (encoded, semiencoded, n)
ea_type *encoded;
ea_type *semiencoded;
int n;
{
int i;
*encoded = *semiencoded;
for (i = 0; i < N_EATYPES; i++)
{
if (encoded->type == eas.a[i].s.srcabyte)
{
encoded->type = eas.a[i].a[n].byte;
return;
}
else if (encoded->type == eas.a[i].s.srcaword)
{
encoded->type = eas.a[i].a[n].word;
return;
}
else if (encoded->type == eas.a[i].s.srcalong)
{
encoded->type = eas.a[i].a[n].lon;
return;
}
}
abort ();
}
fastref flag_shiftword;
fastref flag_shiftbyte;
fastref flag_multword;
fastref flag_multbyte;
fastref flag_mp;
fastref flag_special;
fastref flag_Mp;
fastref flag_ap;
fastref flag_Ap;
fastref flag_nonep;
fastref flag_nostorep;
fastref flag_clearp;
fastref flag_branch;
fastref exec_dispatch[100];
static int
get_now ()
{
return time (0);
}
static int
now_persec ()
{
return 1;
}
static void
gotcr (ptr, n)
ea_type *ptr;
int n;
{
int size;
n &= 0x7;
if (n == 0)
{
abort ();
}
else
{
ptr->type = eas.s.ea_cr.j[JBYTE];
ptr->reg.bptr = segregptr[n][JLONG];
}
}
static void
gotreg (ptr, n, size)
ea_type *ptr;
int n;
int size;
{
n &= 0x7;
ptr->type = eas.s.ea_reg.j[size];
ptr->reg.bptr = regptr[n][size];
}
static void
gotinc (ptr, n, inc, size)
ea_type *ptr;
int n;
int size;
{
n &= 0x7;
if (inc > 0)
{
ptr->type = eas.s.ea_inc.j[size];
}
else
{
ptr->type = eas.s.ea_dec.j[size];
}
ptr->reg.bptr = regptr[n][JWORD];
ptr->r2.segreg = segmap[n];
}
static void
gotabs (ptr, disp, reg, size)
ea_type *ptr;
int disp;
int reg;
int size;
{
ptr->type = eas.s.ea_disp.j[size];
ptr->reg.bptr = regptr[reg][JWORD];
ptr->r2.segreg = segmap[reg];
ptr->literal = disp;
}
static void
gotind (ptr, disp, reg, size)
ea_type *ptr;
int disp;
int reg;
int size;
{
gotabs (ptr, disp, reg & 0x7, size);
}
static void
gotimm (ptr, val)
ea_type *ptr;
int val;
{
ptr->type = eas.s.ea_imm.j[0];
ptr->literal = val;
}
static void
indoff (ptr)
ea_type *ptr;
{
int i;
for (i = 0; i < 6; i++)
{
if (ptr->type == eas.s.ea_disp.j[i])
{
ptr->type = eas.s.ea_lval.j[i];
return;
}
}
}
thinkabout_shifts (d, bytesized)
decoded_inst *d;
int bytesized;
{
if (bytesized)
{
d->srcb.type = eas.s.ea_imm.s.srcbword;
d->srcb.literal = 8;
}
else
{
d->srcb.type = eas.s.ea_imm.s.srcbword;
d->srcb.literal = 16;
}
}
static void
compcycles (dst, opcode)
decoded_inst *dst;
h8500_opcode_info *opcode;
{
int cycles = 0;
switch (opcode->length)
{
case 1:
case 2:
cycles += opcode->length;
break;
default:
cycles += opcode->length * 3;
break;
}
dst->cycles = cycles;
}
static void
translate (ptr, from, to)
ea_type *ptr;
fastref from;
fastref to;
{
if (ptr->reg.wptr == &cpu.regs[7].s[LOW]
&& ptr->type == from)
{
ptr->type = to;
}
}
static
void
fix_incdecs (dst)
decoded_inst *dst;
{
if (dst->dst.type == eas.s.ea_inc.s.dstbyte
&& (dst->srca.type == eas.s.ea_inc.s.srcabyte
|| dst->srcb.type == eas.s.ea_inc.s.srcbbyte))
{
dst->dst.type = eas.s.ea_disp.s.dstbyte;
}
if (dst->dst.type == eas.s.ea_inc.s.dstword
&& (dst->srca.type == eas.s.ea_inc.s.srcaword
|| dst->srcb.type == eas.s.ea_inc.s.srcbword))
{
dst->dst.type = eas.s.ea_disp.s.dstword;
}
if (dst->dst.type == eas.s.ea_dec.s.dstbyte
|| dst->dst.type == eas.s.ea_dec.s.dstword)
{
if (dst->srca.type == eas.s.ea_dec.s.srcabyte)
{
dst->srca.type = eas.s.ea_disp.s.srcabyte;
}
else if (dst->srca.type == eas.s.ea_dec.s.srcaword)
{
dst->srca.type = eas.s.ea_disp.s.srcaword;
}
else if (dst->srcb.type == eas.s.ea_dec.s.srcbbyte)
{
dst->srcb.type = eas.s.ea_disp.s.srcbbyte;
}
else if (dst->srcb.type == eas.s.ea_dec.s.srcbword)
{
dst->srcb.type = eas.s.ea_disp.s.srcbword;
}
}
translate (&dst->dst, eas.s.ea_dec.s.dstbyte, eas.s.ea_dec.s.dstword);
translate (&dst->dst, eas.s.ea_inc.s.dstbyte, eas.s.ea_inc.s.dstword);
translate (&dst->srca, eas.s.ea_dec.s.srcabyte, eas.s.ea_dec.s.srcaword);
translate (&dst->srca, eas.s.ea_inc.s.srcabyte, eas.s.ea_inc.s.srcaword);
translate (&dst->srcb, eas.s.ea_dec.s.srcbbyte, eas.s.ea_dec.s.srcbword);
translate (&dst->srcb, eas.s.ea_inc.s.srcbbyte, eas.s.ea_inc.s.srcbword);
}
static void
find (pc, buffer, dst)
int pc;
unsigned char *buffer;
decoded_inst *dst;
{
h8500_opcode_info *opcode;
int i;
int idx;
int hadimm = 0;
dst->srca.reg.rptr = 0;
for (opcode = h8500_table; opcode->name; opcode++)
{
int byte;
int rn;
int rd;
int rs;
int disp;
int abs;
int imm;
int pcrel;
int qim;
int i;
int cr;
dst->opcode = exec_dispatch[opcode->flavor & 0x7f];
for (byte = 0; byte < opcode->length; byte++)
{
if ((buffer[byte] & opcode->bytes[byte].mask)
!= (opcode->bytes[byte].contents))
{
goto next;
}
else
{
switch (opcode->bytes[byte].insert)
{
case 0:
case FP:
break;
default:
abort ();
break;
case RN:
rn = buffer[byte] & 0x7;
break;
case RS:
rs = buffer[byte] & 0x7;
break;
case CRB:
cr = buffer[byte] & 0x7;
if (cr == 0)
goto next;
break;
case CRW:
cr = buffer[byte] & 0x7;
if (cr != 0)
goto next;
break;
case DISP16:
disp = (buffer[byte] << 8) | (buffer[byte + 1]);
break;
case FPIND_D8:
case DISP8:
disp = ((char) (buffer[byte]));
break;
case RD:
case RDIND:
rd = buffer[byte] & 0x7;
break;
case ABS24:
abs =
(buffer[byte] << 16)
| (buffer[byte + 1] << 8)
| (buffer[byte + 2]);
break;
case ABS16:
abs = (buffer[byte] << 8) | (buffer[byte + 1]);
break;
case ABS8:
abs = (buffer[byte]);
break;
case IMM16:
imm = (buffer[byte] << 8) | (buffer[byte + 1]);
break;
case IMM4:
imm = (buffer[byte]) & 0xf;
break;
case IMM8:
case RLIST:
imm = SEXTCHAR (buffer[byte]);
break;
case PCREL16:
pcrel = SEXTSHORT ((buffer[byte] << 8) | (buffer[byte + 1]));
break;
case PCREL8:
pcrel = SEXTCHAR ((buffer[byte]));
break;
case QIM:
switch (buffer[byte] & 0x7)
{
case 0:
imm = 1;
break;
case 1:
imm = 2;
break;
case 4:
imm = -1;
break;
case 5:
imm = -2;
break;
}
break;
}
}
}
if (opcode->flavor & O_BYTE)
{
idx = 0;
switch (opcode->flags)
{
case 'h':
dst->flags = flag_shiftbyte;
break;
case 'p':
dst->flags = flag_multbyte;
break;
case 'B':
dst->flags = flag_branch;
break;
case 'm':
dst->flags = flag_mp;
break;
case 'a':
dst->flags = flag_ap;
break;
case '-':
dst->flags = flag_nonep;
break;
case 0:
dst->flags = flag_nostorep;
break;
case 'c':
dst->flags = flag_clearp;
break;
case 's':
dst->flags = flag_special;
}
}
else
{
idx = 1;
switch (opcode->flags)
{
case 'h':
dst->flags = flag_shiftword;
break;
case 'p':
dst->flags = flag_multword;
break;
case 'B':
dst->flags = flag_branch;
break;
case 'm':
dst->flags = flag_Mp;
break;
case 'a':
dst->flags = flag_Ap;
break;
case '-':
dst->flags = flag_nonep;
break;
case 0:
dst->flags = flag_nostorep;
break;
case 'c':
dst->flags = flag_clearp;
break;
case 's':
dst->flags = flag_special;
break;
}
}
for (i = 0; i < opcode->nargs; i++)
{
ea_type *p = eavector + i;
switch (opcode->arg_type[i])
{
default:
abort ();
case FP:
gotreg (p, 6, idx);
break;
case RNIND:
disp = 0;
case RNIND_D16:
case RNIND_D8:
gotind (p, disp, rn, idx);
break;
break;
case RDIND:
disp = 0;
case RDIND_D16:
case RDIND_D8:
gotind (p, disp, rd, idx);
break;
case FPIND_D8:
gotind (p, disp, 6, idx);
break;
case CRB:
case CRW:
gotcr (p, cr);
break;
case RN:
gotreg (p, rn, idx);
break;
case RD:
gotreg (p, rd, idx);
break;
case RS:
gotreg (p, rs, idx);
break;
case RNDEC:
gotinc (p, rn, -1, idx);
break;
case RNINC:
gotinc (p, rn, 1, idx);
break;
case SPINC:
gotinc (p, 7, 1, idx);
break;
case SPDEC:
gotinc (p, 7, -1, idx);
break;
case ABS24:
case ABS16:
gotabs (p, abs, R_HARD_0, idx);
break;
case ABS8:
gotabs (p, abs, R_HARD8_0, idx);
break;
case IMM16:
case RLIST:
case QIM:
case IMM4:
case IMM8:
gotimm (p, imm);
break;
case PCREL16:
case PCREL8:
gotimm (p,
((pcrel + pc + opcode->length) & 0xffff) | (pc & 0xff0000),
R_HARD_0, JLONG);
}
}
dst->srca.type = eas.s.ea_nop.s.srcabyte;
dst->srcb.type = eas.s.ea_nop.s.srcbbyte;
dst->dst.type = eas.s.ea_nop.s.dstbyte;
if (opcode->nargs)
{
switch (opcode->nargs)
{
case 1:
howto_workout (&dst->srca, &eavector[0], 0);
if (opcode->dst != '!')
howto_workout (&dst->dst, &eavector[0], 2);
break;
case 2:
if (opcode->src2 == '!')
{
howto_workout (&dst->srca, &eavector[0], 0);
howto_workout (&dst->dst, &eavector[1], 2);
}
else
{
howto_workout (&dst->srca, &eavector[0], 0);
howto_workout (&dst->srcb, &eavector[1], 1);
if (opcode->dst != '!')
{
howto_workout (&dst->dst, &eavector[1], 2);
}
}
break;
}
fix_incdecs (dst);
if (dst->opcode == exec_dispatch[O_PJSR]
|| dst->opcode == exec_dispatch[O_PJMP])
{
if (opcode->length == 4)
{
dst->srca.type = eas.s.ea_lval24.s.srcabyte;
}
else
{
dst->srca.type = eas.s.ea_reg.s.srcalong;
}
dst->srca.r2.rptr = &cpu.regs[R_HARD_0];
dst->srcb.literal = pc + opcode->length;
dst->srcb.type = eas.s.ea_imm.s.srcbword;
}
else if (dst->opcode == exec_dispatch[O_MULXU])
{
if (dst->dst.type == eas.s.ea_reg.s.dstword)
{
dst->dst.type = eas.s.ea_reg.s.dstlong;
}
else
{
dst->dst.type = eas.s.ea_reg.s.dstword;
}
dst->dst.reg.bptr = regptr[rd][JWORD];
}
else if (dst->opcode == exec_dispatch[O_DIVXU])
{
dst->srcb.type
= (dst->srcb.type == eas.s.ea_reg.s.srcbword)
? eas.s.ea_reg.s.srcblong
: eas.s.ea_reg.s.srcbword;
dst->dst.type
= (dst->dst.type == eas.s.ea_reg.s.dstword)
? eas.s.ea_reg.s.dstlong
: eas.s.ea_reg.s.dstword;
}
else if (dst->opcode == exec_dispatch[O_LDM])
{
dst->srca.type = eas.s.ea_nop.s.srcabyte;
}
else if (dst->opcode == exec_dispatch[O_STM])
{
dst->srcb.type = eas.s.ea_nop.s.srcbbyte;
}
else if (dst->opcode == exec_dispatch[O_EXTS]
|| dst->opcode == exec_dispatch[O_EXTU])
{
dst->dst.type = eas.s.ea_reg.s.dstword;
dst->dst.reg.bptr = regptr[rd][JWORD];
dst->flags = flag_Ap;
}
if (opcode->flags == 'h')
thinkabout_shifts (dst, opcode->flavor & O_BYTE);
if (opcode->src1 == 'B')
{
indoff (&dst->srca, 0);
}
}
dst->next_pc = pc + opcode->length;
compcycles (dst, opcode);
return;
next:;
}
dst->opcode = exec_dispatch[O_TRAPA];
dst->next_pc = pc + 1;
}
compile (pc)
{
int idx;
idx = cpu.cache_top + 1;
cpu.compiles++;
if (idx >= cpu.csize)
{
idx = 1;
}
cpu.cache_top = idx;
cpu.cache_idx[cpu.cache[idx].oldpc] = 0;
cpu.cache[idx].oldpc = pc;
find (pc, cpu.memory + pc, cpu.cache + idx);
cpu.cache_idx[pc] = idx;
}
baddefault (x)
{
printf ("bad default %d\n", x);
}
static int fetch_l (arg)
ea_type *arg;
{
int l, r;
int h = *(arg->reg.wptr);
r = (union rtype *) (arg->reg.wptr) - &cpu.regs[0];
r++;
l = cpu.regs[r].s[LOW];
return (h << 16) | l;
}
#define FETCH(dst, arg, n) \
{ \
int r; unsigned char*lval; \
DISPATCH((arg).type) \
{ LABELN(FETCH_NOP,n): \
dst= 0; \
break; \
DEFAULT baddefault((arg).type); break; \
LABELN(FETCH_LVAL,n): \
dst = (*(((arg).reg.wptr)) + (arg.literal)) ; \
break; \
LABELN(FETCH_LVAL24,n): \
dst = (*(((arg).reg.wptr)) + *(((arg).r2.wptr)) + (arg.literal)) &0xffffff; \
break; \
LABELN(FETCH_CRB,n): \
dst = (*((arg).reg.segptr) - cpu.memory)>>16; \
break; \
LABELN(FETCH_CRW,n): \
dst = BUILDSR();\
break; \
LABELN(FETCH_REG_B,n): \
dst = *((arg).reg.bptr); \
break; \
LABELN(FETCH_REG_W,n): \
dst = *((arg).reg.wptr); \
break; \
LABELN(FETCH_REG_L,n): \
dst = fetch_l(&(arg));\
break; \
LABELN(FETCH_INC_B,n): \
lval = elval ((arg), 0); \
dst = byteat (lval); \
(*((arg).reg.wptr))++; \
break; \
LABELN(FETCH_INC_W,n): \
lval = elval ((arg), 0); \
dst = wordat (lval); \
(*(((arg).reg.wptr))) += 2; \
break; \
LABELN(FETCH_DEC_B, n): \
(*(arg).reg.wptr)--; \
lval = elval ((arg), 0); \
r = byteat (lval); \
dst = r; \
break; \
LABELN(FETCH_DEC_W, n): \
(*((arg).reg.wptr)) -= 2; \
lval = elval ((arg), 0); \
r = wordat (lval); \
dst = r; \
break; \
LABELN(FETCH_DISP_B,n): \
lval = displval ((arg)); \
dst = byteat (lval); \
break; \
LABELN(FETCH_DISP_W,n): \
lval = displval ((arg)); \
dst = wordat (lval); \
break; \
LABELN(FETCH_IMM, n): \
dst = (arg).literal; \
break; \
} \
ENDDISPATCH; \
}
static union
{
short int i;
struct
{
char low;
char high;
}
u;
}
littleendian;
static
void
init_pointers ()
{
static int init;
if (!init)
{
int i;
init = 1;
littleendian.i = 1;
for (i = 0; i < (int) R_LAST; i++)
{
if (littleendian.u.high)
{
LOW = 1;
HIGH = 0;
regptr[i][0] = ((unsigned char *) (cpu.regs + i)) + 3;
regptr[i][1] = ((unsigned char *) (cpu.regs + i)) + 2;
}
else
{
LOW = 0;
HIGH = 1;
regptr[i][0] = (unsigned char *) &(cpu.regs[i]);
regptr[i][1] = (unsigned char *) (&(cpu.regs[i]));
}
regptr[i][2] = (unsigned char *) &(cpu.regs[i]);
}
memcpy (segregptr + 0, regptr + R_SR, sizeof (segregptr[0]));
memcpy (segregptr + 1, regptr + R_TP, sizeof (segregptr[1]));
memcpy (segregptr + 3, regptr + R_BR, sizeof (segregptr[3]));
memcpy (segregptr + 4, regptr + R_EP, sizeof (segregptr[4]));
memcpy (segregptr + 5, regptr + R_DP, sizeof (segregptr[5]));
memcpy (segregptr + 6, regptr + R_CP, sizeof (segregptr[6]));
memcpy (segregptr + 7, regptr + R_TP, sizeof (segregptr[7]));
segmap[R0] = &cpu.regs[R_DP].c;
segmap[R1] = &cpu.regs[R_DP].c;
segmap[R2] = &cpu.regs[R_DP].c;
segmap[R3] = &cpu.regs[R_DP].c;
segmap[R4] = &cpu.regs[R_EP].c;
segmap[R5] = &cpu.regs[R_EP].c;
segmap[R6] = &cpu.regs[R_TP].c;
segmap[R7] = &cpu.regs[R_TP].c;
segmap[R_HARD_0] = &cpu.regs[R_DP].c;
segmap[R_HARD8_0] = &cpu.regs[R_BP].c;
cpu.memory = (unsigned char *) calloc (sizeof (char), H8500_MSIZE);
cpu.cache_idx = (unsigned short *) calloc (sizeof (short), H8500_MSIZE);
cpu.regs[R_DP].c = cpu.memory;
cpu.regs[R_TP].c = cpu.memory;
cpu.regs[R_CP].c = cpu.memory;
cpu.regs[R_BP].c = cpu.memory;
cpu.regs[R_EP].c = cpu.memory;
cpu.regs[R7].s[LOW] = 0xfffe;
cpu.regs[R6].s[LOW] = 0xfffe;
if (!cpu.cache)
sim_set_simcache_size (CSIZE);
}
}
#define PUSHWORD(x) \
{ \
int sp = cpu.regs[R7].s[LOW]; \
unsigned char *p; \
\
sp -= 2; \
p = (sp & 0xffff) + (cpu.regs[R_TP].c); \
cpu.regs[R7].s[LOW] = sp; \
setwordat (p, x); \
} \
#define POPWORD(d) \
{ \
int spx= cpu.regs[R7].s[LOW]; \
unsigned char *p; \
\
p = (spx& 0xffff) + (cpu.regs[R_TP].c); \
spx+= 2; \
cpu.regs[R7].s[LOW] = spx; \
d = wordat (p); \
} \
trap ()
{
switch (cpu.regs[R3].s[LOW] & 0xff)
{
case 33:
cpu.exception = SIGQUIT;
break;
case 34:
cpu.exception = SIGABRT;
break;
case 6:
printf ("%c", cpu.regs[R0].s[LOW]);
break;
}
}
void
control_c (sig, code, scp, addr)
int sig;
int code;
char *scp;
char *addr;
{
cpu.exception = SIGINT;
}
static jmp_buf jbuf;
static void
segv ()
{
cpu.exception = SIGSEGV;
longjmp (jbuf, 1);
}
int
sim_stop (sd)
SIM_DESC sd;
{
cpu.exception = SIGINT;
return 1;
}
void
sim_resume (sd, step, siggnal)
SIM_DESC sd;
{
static int init1;
int res;
int tmp;
int arga;
int argb;
int bit;
int pc;
int C, Z, V, N;
int cycles = 0;
int insts = 0;
int tick_start = get_now ();
void (*prev) ();
void (*prev_seg) ();
if (!init1)
{
int i;
init1 = 1;
init_pointers ();
for (i = 0; i < N_EATYPES; i++)
{
eas.a[i].s.srcabyte = LABEL_REFN (FETCH_NOP, 0);
eas.a[i].s.srcaword = LABEL_REFN (FETCH_NOP, 0);
eas.a[i].s.srcalong = LABEL_REFN (FETCH_NOP, 0);
eas.a[i].s.srcbbyte = LABEL_REFN (FETCH_NOP, 1);
eas.a[i].s.srcbword = LABEL_REFN (FETCH_NOP, 1);
eas.a[i].s.srcblong = LABEL_REFN (FETCH_NOP, 1);
eas.a[i].s.dstbyte = LABEL_REF (STORE_NOP);
eas.a[i].s.dstword = LABEL_REF (STORE_NOP);
eas.a[i].s.dstlong = LABEL_REF (STORE_NOP);
}
eas.s.ea_lval.s.srcabyte = LABEL_REFN (FETCH_LVAL, 0);
eas.s.ea_lval.s.srcaword = LABEL_REFN (FETCH_LVAL, 0);
eas.s.ea_lval24.s.srcabyte = LABEL_REFN (FETCH_LVAL24, 0);
eas.s.ea_lval24.s.srcaword = LABEL_REFN (FETCH_LVAL24, 0);
eas.s.ea_nop.s.srcabyte = LABEL_REFN (FETCH_NOP, 0);
eas.s.ea_nop.s.srcaword = LABEL_REFN (FETCH_NOP, 0);
eas.s.ea_nop.s.srcbbyte = LABEL_REFN (FETCH_NOP, 1);
eas.s.ea_nop.s.srcbword = LABEL_REFN (FETCH_NOP, 1);
eas.s.ea_nop.s.dstbyte = LABEL_REF (STORE_NOP);
eas.s.ea_nop.s.dstword = LABEL_REF (STORE_NOP);
eas.s.ea_cr.s.srcabyte = LABEL_REFN (FETCH_CRB, 0);
eas.s.ea_cr.s.srcaword = LABEL_REFN (FETCH_CRW, 0);
eas.s.ea_cr.s.srcbbyte = LABEL_REFN (FETCH_CRB, 1);
eas.s.ea_cr.s.srcbword = LABEL_REFN (FETCH_CRW, 1);
eas.s.ea_cr.s.dstbyte = LABEL_REF (STORE_CRB);
eas.s.ea_cr.s.dstword = LABEL_REF (STORE_CRW);
eas.s.ea_reg.s.srcabyte = LABEL_REFN (FETCH_REG_B, 0);
eas.s.ea_reg.s.srcaword = LABEL_REFN (FETCH_REG_W, 0);
eas.s.ea_reg.s.srcalong = LABEL_REFN (FETCH_REG_L, 0);
eas.s.ea_reg.s.srcbbyte = LABEL_REFN (FETCH_REG_B, 1);
eas.s.ea_reg.s.srcbword = LABEL_REFN (FETCH_REG_W, 1);
eas.s.ea_reg.s.srcblong = LABEL_REFN (FETCH_REG_L, 1);
eas.s.ea_reg.s.dstbyte = LABEL_REF (STORE_REG_B);
eas.s.ea_reg.s.dstword = LABEL_REF (STORE_REG_W);
eas.s.ea_reg.s.dstlong = LABEL_REF (STORE_REG_L);
eas.s.ea_inc.s.srcabyte = LABEL_REFN (FETCH_INC_B, 0);
eas.s.ea_inc.s.srcaword = LABEL_REFN (FETCH_INC_W, 0);
eas.s.ea_inc.s.srcbbyte = LABEL_REFN (FETCH_INC_B, 1);
eas.s.ea_inc.s.srcbword = LABEL_REFN (FETCH_INC_W, 1);
eas.s.ea_inc.s.dstbyte = LABEL_REF (STORE_INC_B);
eas.s.ea_inc.s.dstword = LABEL_REF (STORE_INC_W);
eas.s.ea_dec.s.srcabyte = LABEL_REFN (FETCH_DEC_B, 0);
eas.s.ea_dec.s.srcaword = LABEL_REFN (FETCH_DEC_W, 0);
eas.s.ea_dec.s.srcbbyte = LABEL_REFN (FETCH_DEC_B, 1);
eas.s.ea_dec.s.srcbword = LABEL_REFN (FETCH_DEC_W, 1);
eas.s.ea_dec.s.dstbyte = LABEL_REF (STORE_DEC_B);
eas.s.ea_dec.s.dstword = LABEL_REF (STORE_DEC_W);
eas.s.ea_disp.s.srcabyte = LABEL_REFN (FETCH_DISP_B, 0);
eas.s.ea_disp.s.srcaword = LABEL_REFN (FETCH_DISP_W, 0);
eas.s.ea_disp.s.srcbbyte = LABEL_REFN (FETCH_DISP_B, 1);
eas.s.ea_disp.s.srcbword = LABEL_REFN (FETCH_DISP_W, 1);
eas.s.ea_disp.s.dstbyte = LABEL_REF (STORE_DISP_B);
eas.s.ea_disp.s.dstword = LABEL_REF (STORE_DISP_W);
eas.s.ea_imm.s.srcabyte = LABEL_REFN (FETCH_IMM, 0);
eas.s.ea_imm.s.srcaword = LABEL_REFN (FETCH_IMM, 0);
eas.s.ea_imm.s.srcbbyte = LABEL_REFN (FETCH_IMM, 1);
eas.s.ea_imm.s.srcbword = LABEL_REFN (FETCH_IMM, 1);
flag_special = LABEL_REF (FLAG_special);
flag_mp = LABEL_REF (FLAG_m);
flag_Mp = LABEL_REF (FLAG_M);
flag_ap = LABEL_REF (FLAG_a);
flag_Ap = LABEL_REF (FLAG_A);
flag_nonep = LABEL_REF (FLAG_NONE);
flag_nostorep = LABEL_REF (FLAG_NOSTORE);
flag_clearp = LABEL_REF (FLAG_CLEAR);
flag_shiftbyte = LABEL_REF (FLAG_shiftbyte);
flag_shiftword = LABEL_REF (FLAG_shiftword);
flag_multbyte = LABEL_REF (FLAG_multbyte);
flag_multword = LABEL_REF (FLAG_multword);
exec_dispatch[O_ADDS] = LABEL_REF (O_ADDS);
exec_dispatch[O_ADDX] = LABEL_REF (O_ADDX);
exec_dispatch[O_ADD] = LABEL_REF (O_ADD);
exec_dispatch[O_ANDC] = LABEL_REF (O_ANDC);
exec_dispatch[O_AND] = LABEL_REF (O_AND);
exec_dispatch[O_BCC] = LABEL_REF (O_BCC);
exec_dispatch[O_BCLR] = LABEL_REF (O_BCLR);
exec_dispatch[O_BCS] = LABEL_REF (O_BCS);
exec_dispatch[O_BEQ] = LABEL_REF (O_BEQ);
exec_dispatch[O_BF] = LABEL_REF (O_BF);
exec_dispatch[O_BGE] = LABEL_REF (O_BGE);
exec_dispatch[O_BGT] = LABEL_REF (O_BGT);
exec_dispatch[O_BHI] = LABEL_REF (O_BHI);
exec_dispatch[O_BHS] = LABEL_REF (O_BHS);
exec_dispatch[O_BLE] = LABEL_REF (O_BLE);
exec_dispatch[O_BLO] = LABEL_REF (O_BLO);
exec_dispatch[O_BLS] = LABEL_REF (O_BLS);
exec_dispatch[O_BLT] = LABEL_REF (O_BLT);
exec_dispatch[O_BMI] = LABEL_REF (O_BMI);
exec_dispatch[O_BNE] = LABEL_REF (O_BNE);
exec_dispatch[O_BNOT] = LABEL_REF (O_BNOT);
exec_dispatch[O_BPL] = LABEL_REF (O_BPL);
exec_dispatch[O_BPT] = LABEL_REF (O_BPT);
exec_dispatch[O_BRA] = LABEL_REF (O_BRA);
exec_dispatch[O_BRN] = LABEL_REF (O_BRN);
exec_dispatch[O_BSET] = LABEL_REF (O_BSET);
exec_dispatch[O_BSR] = LABEL_REF (O_BSR);
exec_dispatch[O_BTST] = LABEL_REF (O_BTST);
exec_dispatch[O_BT] = LABEL_REF (O_BT);
exec_dispatch[O_BVC] = LABEL_REF (O_BVC);
exec_dispatch[O_BVS] = LABEL_REF (O_BVS);
exec_dispatch[O_CLR] = LABEL_REF (O_CLR);
exec_dispatch[O_CMP] = LABEL_REF (O_CMP);
exec_dispatch[O_DADD] = LABEL_REF (O_DADD);
exec_dispatch[O_DIVXU] = LABEL_REF (O_DIVXU);
exec_dispatch[O_DSUB] = LABEL_REF (O_DSUB);
exec_dispatch[O_EXTS] = LABEL_REF (O_EXTS);
exec_dispatch[O_EXTU] = LABEL_REF (O_EXTU);
exec_dispatch[O_JMP] = LABEL_REF (O_JMP);
exec_dispatch[O_JSR] = LABEL_REF (O_JSR);
exec_dispatch[O_LDC] = LABEL_REF (O_LDC);
exec_dispatch[O_LDM] = LABEL_REF (O_LDM);
exec_dispatch[O_LINK] = LABEL_REF (O_LINK);
exec_dispatch[O_MOVFPE] = LABEL_REF (O_MOVFPE);
exec_dispatch[O_MOVTPE] = LABEL_REF (O_MOVTPE);
exec_dispatch[O_MOV] = LABEL_REF (O_MOV);
exec_dispatch[O_MULXU] = LABEL_REF (O_MULXU);
exec_dispatch[O_NEG] = LABEL_REF (O_NEG);
exec_dispatch[O_NOP] = LABEL_REF (O_NOP);
exec_dispatch[O_NOT] = LABEL_REF (O_NOT);
exec_dispatch[O_ORC] = LABEL_REF (O_ORC);
exec_dispatch[O_OR] = LABEL_REF (O_OR);
exec_dispatch[O_PJMP] = LABEL_REF (O_PJMP);
exec_dispatch[O_PJSR] = LABEL_REF (O_PJSR);
exec_dispatch[O_PRTD] = LABEL_REF (O_PRTD);
exec_dispatch[O_PRTS] = LABEL_REF (O_PRTS);
exec_dispatch[O_RECOMPILE] = LABEL_REF (O_RECOMPILE);
exec_dispatch[O_ROTL] = LABEL_REF (O_ROTL);
exec_dispatch[O_ROTR] = LABEL_REF (O_ROTR);
exec_dispatch[O_ROTXL] = LABEL_REF (O_ROTXL);
exec_dispatch[O_ROTXR] = LABEL_REF (O_ROTXR);
exec_dispatch[O_RTD] = LABEL_REF (O_RTD);
exec_dispatch[O_RTS] = LABEL_REF (O_RTS);
exec_dispatch[O_SCB_EQ] = LABEL_REF (O_SCB_EQ);
exec_dispatch[O_SCB_F] = LABEL_REF (O_SCB_F);
exec_dispatch[O_SCB_NE] = LABEL_REF (O_SCB_NE);
exec_dispatch[O_SHAL] = LABEL_REF (O_SHAL);
exec_dispatch[O_SHAR] = LABEL_REF (O_SHAR);
exec_dispatch[O_SHLL] = LABEL_REF (O_SHLL);
exec_dispatch[O_SHLR] = LABEL_REF (O_SHLR);
exec_dispatch[O_SLEEP] = LABEL_REF (O_SLEEP);
exec_dispatch[O_STC] = LABEL_REF (O_STC);
exec_dispatch[O_STM] = LABEL_REF (O_STM);
exec_dispatch[O_SUBS] = LABEL_REF (O_SUBS);
exec_dispatch[O_SUBX] = LABEL_REF (O_SUBX);
exec_dispatch[O_SUB] = LABEL_REF (O_SUB);
exec_dispatch[O_SWAP] = LABEL_REF (O_SWAP);
exec_dispatch[O_TAS] = LABEL_REF (O_TAS);
exec_dispatch[O_TRAPA] = LABEL_REF (O_TRAPA);
exec_dispatch[O_TRAP_VS] = LABEL_REF (O_TRAP_VS);
exec_dispatch[O_TST] = LABEL_REF (O_TST);
exec_dispatch[O_UNLK] = LABEL_REF (O_UNLK);
exec_dispatch[O_XCH] = LABEL_REF (O_XCH);
exec_dispatch[O_XORC] = LABEL_REF (O_XORC);
exec_dispatch[O_XOR] = LABEL_REF (O_XOR);
nop.type = eas.s.ea_nop.s.srcabyte;
cpu.cache[0].opcode = exec_dispatch[O_RECOMPILE];
cpu.cache[0].srca.type = eas.s.ea_nop.s.srcabyte;
cpu.cache[0].srcb.type = eas.s.ea_nop.s.srcbbyte;
}
prev = signal (SIGINT, control_c);
prev_seg = signal (SIGSEGV, segv);
if (step)
{
cpu.exception = SIGTRAP;
}
else
{
cpu.exception = 0;
}
pc = cpu.regs[R_PC].s[LOW] + (NORMAL_CP << 16);
GETSR ();
if (setjmp (jbuf) == 0) {
do
{
int cidx;
decoded_inst *code;
top:
cidx = cpu.cache_idx[pc];
code = cpu.cache + cidx;
FETCH (arga, code->srca, 0);
FETCH (argb, code->srcb, 1);
#ifdef DEBUG
if (debug)
{
printf ("%x %d %s\n", pc, code->opcode,
code->op ? code->op->name : "**");
}
#endif
cycles += code->cycles;
insts++;
DISPATCH (code->opcode)
{
LABEL (O_RECOMPILE):
compile (pc);
goto top;
break;
LABEL (O_NEG):
arga = -arga;
argb = 0;
res = arga + argb;
break;
LABEL (O_SUBX):
arga += C;
LABEL (O_SUB):
LABEL (O_SUBS):
arga = -arga;
LABEL (O_ADD):
LABEL (O_ADDS):
res = arga + argb;
break;
LABEL (O_ADDX):
res = arga + argb + C;
break;
LABEL (O_AND):
LABEL (O_ANDC):
res = arga & argb;
break;
break;
LABEL (O_BCLR):
arga &= 0xf;
bit = (argb & (1 << arga));
res = argb & ~(1 << arga);
goto bitop;
LABEL (O_BRA):
LABEL (O_BT):
if (1)
goto condtrue;
LABEL (O_BRN):
LABEL (O_BF):
if (0)
goto condtrue;
break;
LABEL (O_BHI):
if ((C || Z) == 0)
goto condtrue;
break;
LABEL (O_BLS):
if ((C || Z))
goto condtrue;
break;
LABEL (O_BCS):
LABEL (O_BLO):
if ((C == 1))
goto condtrue;
break;
LABEL (O_BCC):
LABEL (O_BHS):
if ((C == 0))
goto condtrue;
break;
LABEL (O_BEQ):
if (Z)
goto condtrue;
break;
LABEL (O_BGT):
if (((Z || (N ^ V)) == 0))
goto condtrue;
break;
LABEL (O_BLE):
if (((Z || (N ^ V)) == 1))
goto condtrue;
break;
LABEL (O_BGE):
if ((N ^ V) == 0)
goto condtrue;
break;
LABEL (O_BLT):
if ((N ^ V))
goto condtrue;
break;
LABEL (O_BMI):
if ((N))
goto condtrue;
break;
LABEL (O_BNE):
if ((Z == 0))
goto condtrue;
break;
LABEL (O_BPL):
if (N == 0)
goto condtrue;
break;
break;
LABEL (O_BVC):
if ((V == 0))
goto condtrue;
break;
LABEL (O_BVS):
if ((V == 1))
goto condtrue;
break;
LABEL (O_BNOT):
bit = argb & (1<<(arga & 0xf));
res = argb ^ (1<<(arga & 0xf));
goto bitop;
break;
LABEL (O_BSET):
arga = 1 << (arga & 0xf);
bit = argb & arga;
res = argb | arga;
goto bitop;
break;
LABEL (O_PJMP):
pc = arga;
goto next;
LABEL (O_UNLK):
{
int t;
SET_NORMREG (R7, GET_NORMREG (R6));
POPWORD (t);
SET_NORMREG (R6, t);
pc = code->next_pc;
goto next;
}
LABEL (O_RTS):
{
int cp = pc & 0xff0000;
POPWORD (pc);
pc |= cp;
goto next;
}
break;
LABEL (O_PRTS):
{
int cp;
int off;
POPWORD (cp);
POPWORD (off);
cp <<= 16;
SET_SEGREG (R_CP, cp);
pc = cp + off;
}
goto next;
LABEL (O_PJSR):
PUSHWORD (argb & 0xffff);
PUSHWORD (argb >> 16);
pc = (arga & 0xffffff);
goto next;
LABEL (O_BSR):
LABEL (O_JSR):
PUSHWORD (code->next_pc);
pc = arga | (pc & 0xff0000);
goto next;
LABEL (O_BTST):
Z = (((argb >> (arga & 0xf)) & 1) == 0);
pc = code->next_pc;
goto next;
LABEL (O_CLR):
res = 0;
break;
LABEL (O_CMP):
arga = -arga;
res = arga + argb;
break;
LABEL (O_DADD):
res = arga + argb + C;
if (res > 99)
{
res -= 100;
C = 1;
}
else
{
C = 0;
}
Z = Z && (res == 0);
break;
LABEL (O_DSUB):
res = argb - arga - C;
if (res < 0)
{
res += 100;
C = 1;
}
else
{
C = 0;
}
Z = Z && (res == 0);
break;
LABEL (O_EXTS):
res = SEXTCHAR (arga);
break;
LABEL (O_EXTU):
res = (unsigned char) arga;
break;
LABEL (O_JMP):
pc = arga | (pc & 0xff0000);
goto next;
break;
LABEL (O_LDM):
for (tmp = 0; tmp < 7; tmp++)
{
if (argb & (1 << tmp))
{
POPWORD (cpu.regs[tmp].s[LOW]);
}
}
if (argb & 0x80)
POPWORD (tmp);
goto nextpc;
break;
LABEL (O_LINK):
PUSHWORD (cpu.regs[R6].s[LOW]);
cpu.regs[R6].s[LOW] = cpu.regs[R7].s[LOW];
cpu.regs[R7].s[LOW] += argb;
goto nextpc;
LABEL (O_STC):
LABEL (O_LDC):
LABEL (O_MOVFPE):
LABEL (O_MOVTPE):
LABEL (O_MOV):
LABEL (O_TST):
res = arga;
break;
LABEL (O_TRAPA):
if (arga == 15)
{
trap ();
}
else
{
PUSHWORD (pc & 0xffff);
if (cpu.maximum)
{
PUSHWORD (NORMAL_CP);
}
PUSHWORD (NORMAL_SR);
if (cpu.maximum)
{
arga = arga * 4 + 0x40;
SET_NORMAL_CPPC (longat (cpu.memory + arga));
}
else
{
arga = arga * 2 + 0x20;
SET_NORMAL_CPPC (wordat (cpu.memory + arga));
}
}
break;
LABEL (O_OR):
LABEL (O_ORC):
res = arga | argb;
break;
LABEL (O_XOR):
LABEL (O_XORC):
res = arga ^ argb;
break;
LABEL (O_SCB_F):
{
scb_f:
res = arga - 1;
code->srca.reg.wptr[0] = res;
if (res != -1)
{
pc = argb;
goto next;
}
}
break;
LABEL (O_SCB_EQ):
if (Z == 1)
break;
else
goto scb_f;
LABEL (O_SCB_NE):
if (Z == 0)
break;
else
goto scb_f;
LABEL (O_NOP):
break;
LABEL (O_ROTL):
res = arga << 1;
C = (res >> argb) & 1;
res |= C;
break;
LABEL (O_ROTR):
C = arga & 1;
res = arga >> 1;
res |= (C << (argb - 1));
break;
LABEL (O_ROTXL):
res = arga << 1;
res |= C;
C = (res >> argb) & 1;
break;
LABEL (O_ROTXR):
res = arga >> 1;
res |= (C << (argb - 1));
C = arga & 1;
break;
LABEL (O_SHAL):
res = arga << 1;
if (argb == 16)
{
C = (res >> (16)) & 1;
Z = ((res & 0xffff) == 0);
N = ((res & 0x8000) != 0);
}
else
{
C = (res >> (8)) & 1;
Z = ((res & 0xff) == 0);
N = ((res & 0x80) != 0);
}
V = C ^ N;
goto none;
LABEL (O_SHAR):
C = arga & 1;
if (argb == 16)
{
res = ((short) arga) >> 1;
}
else
{
res = (SEXTCHAR (arga)) >> 1;
}
break;
LABEL (O_SHLL):
res = arga << 1;
C = (res >> argb) & 1;
break;
LABEL (O_SHLR):
C = arga & 1;
res = arga >> 1;
break;
LABEL (O_DIVXU):
if (arga == 0)
{
N = V = C = 0;
Z = 1;
cpu.exception = SIGILL;
}
else
{
int d = argb / arga;
int m = argb % arga;
if (code->dst.type == eas.s.ea_reg.s.dstlong)
{
res = (m << 16) | (d & 0xffff);
}
else
{
res = (m << 8) | (d & 0xff);
}
}
break;
LABEL (O_MULXU):
res = arga * argb;
break;
LABEL (O_NOT):
res = ~arga;
break;
LABEL (O_SWAP):
res = ((arga >> 8) & 0xff) | ((arga << 8) & 0xff00);
break;
LABEL (O_STM):
for (tmp = 7; tmp >= 0; tmp--)
{
if (arga & (1 << tmp))
{
PUSHWORD (cpu.regs[tmp].s[LOW]);
}
}
goto nextpc;
LABEL (O_TAS):
C = 0;
V = 0;
Z = arga == 0;
N = arga < 0;
res = arga | 0x80;
goto none;
LABEL (O_PRTD):
LABEL (O_XCH):
LABEL (O_RTD):
cpu.exception = SIGILL;
goto next;
LABEL (O_TRAP_VS):
LABEL (O_SLEEP):
LABEL (O_BPT):
cpu.exception = SIGTRAP;
goto next;
break;
}
ENDDISPATCH;
DISPATCH (code->flags)
{
bitop:
Z = (res & bit) == 0;
pc = code->next_pc;
break;
LABEL (FLAG_multword):
Z = (res & 0xffff) == 0;
N = (res & 0x8000) != 0;
V = 0;
C = 0;
pc = code->next_pc;
break;
LABEL (FLAG_multbyte):
Z = (res & 0xff) == 0;
N = (res & 0x80) != 0;
V = 0;
C = 0;
pc = code->next_pc;
break;
LABEL (FLAG_shiftword):
N = (res & 0x8000) != 0;
Z = (res & 0xffff) == 0;
V = 0;
pc = code->next_pc;
break;
LABEL (FLAG_shiftbyte):
N = (res & 0x80) != 0;
Z = (res & 0xff) == 0;
V = 0;
pc = code->next_pc;
break;
LABEL (FLAG_special):
pc = code->next_pc;
break;
LABEL (FLAG_m):
N = (res & 0x80) != 0;
Z = (res & 0xff) == 0;
V = (((~arga & ~argb & res) | (arga & argb & ~res)) & 0x80) != 0;
pc = code->next_pc;
break;
LABEL (FLAG_M):
N = (res & 0x8000) != 0;
Z = (res & 0xffff) == 0;
V = (((~arga & ~argb & res) | (arga & argb & ~res)) & 0x8000) != 0;
pc = code->next_pc;
break;
LABEL (FLAG_a):
C = (res & 0x100) != 0;
N = (res & 0x80) != 0;
Z = (res & 0xff) == 0;
V = (((~arga & ~argb & res) | (arga & argb & ~res)) & 0x80) != 0;
pc = code->next_pc;
break;
LABEL (FLAG_A):
C = (res & 0x10000) != 0;
N = (res & 0x8000) != 0;
Z = (res & 0xffff) == 0;
V = (((~arga & ~argb & res) | (arga & argb & ~res)) & 0x8000) != 0;
pc = code->next_pc;
break;
LABEL (FLAG_NONE):
none:;
pc = code->next_pc;
break;
LABEL (FLAG_NOSTORE):
pc = code->next_pc;
break;
LABEL (FLAG_CLEAR):
N = 0;
Z = 1;
V = 0;
C = 0;
pc = code->next_pc;
break;
condtrue:
pc = arga;
goto next;
}
ENDDISPATCH;
DISPATCH (code->dst.type)
{
unsigned char *lval;
LABEL (STORE_CRB):
(*(code->dst.reg.segptr)) = cpu.memory + (res << 16);
break;
LABEL (STORE_NOP):
break;
LABEL (STORE_REG_B):
(*(code->dst.reg.bptr)) = res;
break;
LABEL (STORE_REG_W):
(*(code->dst.reg.wptr)) = res;
break;
LABEL (STORE_REG_L):
{
int l, r;
r = (union rtype *) (code->dst.reg.wptr) - &cpu.regs[0];
r++;
*(code->dst.reg.wptr) = res >> 16;
cpu.regs[r].s[LOW] = res & 0xffff;
}
break;
LABEL (STORE_DISP_W):
lval = displval (code->dst);
setwordat (lval, res);
break;
LABEL (STORE_DISP_B):
lval = displval (code->dst);
setbyteat (lval, res);
break;
LABEL (STORE_INC_B):
lval = elval (code->dst, 0);
setbyteat (lval, res);
(*(code->dst.reg.wptr))++;
break;
LABEL (STORE_INC_W):
lval = elval (code->dst, 0);
setwordat (lval, res);
(*(code->dst.reg.wptr)) += 2;
break;
LABEL (STORE_DEC_B):
(*(code->dst.reg.wptr))--;
lval = elval (code->dst, 0);
setbyteat (lval, res);
break;
LABEL (STORE_CRW):
cpu.regs[R_SR].s[LOW] = res;
GETSR ();
break;
LABEL (STORE_DEC_W):
(*(code->dst.reg.wptr)) -= 2;
lval = elval (code->dst, 0);
setwordat (lval, res);
break;
nextpc:
pc = code->next_pc;
}
ENDDISPATCH;
next:;
}
while (!cpu.exception);
}
cpu.ticks += get_now () - tick_start;
cpu.cycles += cycles;
cpu.insts += insts;
cpu.regs[R_PC].s[LOW] = pc;
BUILDSR ();
signal (SIGINT, prev);
signal (SIGSEGV, prev_seg);
}
int
sim_write (sd, addr, buffer, size)
SIM_DESC sd;
SIM_ADDR addr;
unsigned char *buffer;
int size;
{
int i;
init_pointers ();
if (addr < 0 || addr + size > H8500_MSIZE)
return 0;
for (i = 0; i < size; i++)
{
cpu.memory[addr + i] = buffer[i];
cpu.cache_idx[addr + i] = 0;
}
return size;
}
int
sim_read (sd, addr, buffer, size)
SIM_DESC sd;
SIM_ADDR addr;
unsigned char *buffer;
int size;
{
init_pointers ();
if (addr < 0 || addr + size > H8500_MSIZE)
return 0;
memcpy (buffer, cpu.memory + addr, size);
return size;
}
#define R0_REGNUM 0
#define R1_REGNUM 1
#define R2_REGNUM 2
#define R3_REGNUM 3
#define R4_REGNUM 4
#define R5_REGNUM 5
#define R6_REGNUM 6
#define R7_REGNUM 7
#define PR0_REGNUM 8
#define PR1_REGNUM 9
#define PR2_REGNUM 10
#define PR3_REGNUM 11
#define PR4_REGNUM 12
#define PR5_REGNUM 13
#define PR6_REGNUM 14
#define PR7_REGNUM 15
#define SP_REGNUM PR7_REGNUM
#define FP_REGNUM PR6_REGNUM
#define SEG_C_REGNUM 16
#define SEG_D_REGNUM 17
#define SEG_E_REGNUM 18
#define SEG_T_REGNUM 19
#define CCR_REGNUM 20
#define PC_REGNUM 21
#define CYCLE_REGNUM 22
#define INST_REGNUM 23
#define TICK_REGNUM 24
int
sim_store_register (sd, rn, value, length)
SIM_DESC sd;
int rn;
unsigned char *value;
int length;
{
int seg = 0;
int reg = -1;
init_pointers ();
switch (rn)
{
case PC_REGNUM:
SET_SEGREG (R_CP, (value[1]<<16));
cpu.regs[R_PC].s[LOW] = (value[2] << 8) | value[3];
break;
case SEG_C_REGNUM:
case SEG_D_REGNUM:
case SEG_E_REGNUM:
case SEG_T_REGNUM:
seg = rn - SEG_C_REGNUM + R_CP;
reg = -1;
break;
default:
abort ();
case R0_REGNUM:
case R1_REGNUM:
case R2_REGNUM:
case R3_REGNUM:
case R4_REGNUM:
case R5_REGNUM:
case R6_REGNUM:
case R7_REGNUM:
seg = 0;
reg = rn - R0_REGNUM;
break;
case CCR_REGNUM:
seg = 0;
reg = R_SR;
break;
case CYCLE_REGNUM:
cpu.cycles = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
return;
case INST_REGNUM:
cpu.insts = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
return;
case TICK_REGNUM:
cpu.ticks = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
return;
case PR0_REGNUM:
case PR1_REGNUM:
case PR2_REGNUM:
case PR3_REGNUM:
case PR4_REGNUM:
case PR5_REGNUM:
case PR6_REGNUM:
case PR7_REGNUM:
SET_SEGREG (segforreg[rn], value[1]);
reg = rn - PR0_REGNUM;
cpu.regs[reg].s[LOW] = (value[2] << 8) | value[3];
return;
}
if (seg)
SET_SEGREG (seg, value[0] << 16);
if (reg > 0)
{
cpu.regs[reg].s[LOW] = (value[0] << 8) | value[1];
}
return -1;
}
int
sim_fetch_register (sd, rn, buf, length)
SIM_DESC sd;
int rn;
unsigned char *buf;
int length;
{
init_pointers ();
switch (rn)
{
default:
abort ();
case SEG_C_REGNUM:
case SEG_D_REGNUM:
case SEG_E_REGNUM:
case SEG_T_REGNUM:
buf[0] = GET_SEGREG(rn - SEG_C_REGNUM + R_CP);
break;
case CCR_REGNUM:
buf[0] = cpu.regs[R_SR].s[HIGH];
buf[1] = cpu.regs[R_SR].s[LOW];
break;
case PC_REGNUM:
buf[0] = 0;
buf[1] = GET_SEGREG(R_CP);
buf[2] = HIGH_BYTE (cpu.regs[R_PC].s[LOW]);
buf[3] = LOW_BYTE (cpu.regs[R_PC].s[LOW]);
break;
case PR0_REGNUM:
case PR1_REGNUM:
case PR2_REGNUM:
case PR3_REGNUM:
case PR4_REGNUM:
case PR5_REGNUM:
case PR6_REGNUM:
case PR7_REGNUM:
rn -= PR0_REGNUM;
buf[0] = 0;
buf[1] = GET_SEGREG(segforreg[rn]);
buf[2] = HIGH_BYTE (cpu.regs[rn].s[LOW]);
buf[3] = LOW_BYTE (cpu.regs[rn].s[LOW]);
break;
case R0_REGNUM:
case R1_REGNUM:
case R2_REGNUM:
case R3_REGNUM:
case R4_REGNUM:
case R5_REGNUM:
case R6_REGNUM:
case R7_REGNUM:
buf[0] = HIGH_BYTE (cpu.regs[rn].s[LOW]);
buf[1] = LOW_BYTE (cpu.regs[rn].s[LOW]);
break;
case CYCLE_REGNUM:
buf[0] = cpu.cycles >> 24;
buf[1] = cpu.cycles >> 16;
buf[2] = cpu.cycles >> 8;
buf[3] = cpu.cycles >> 0;
break;
case TICK_REGNUM:
buf[0] = cpu.ticks >> 24;
buf[1] = cpu.ticks >> 16;
buf[2] = cpu.ticks >> 8;
buf[3] = cpu.ticks >> 0;
break;
case INST_REGNUM:
buf[0] = cpu.insts >> 24;
buf[1] = cpu.insts >> 16;
buf[2] = cpu.insts >> 8;
buf[3] = cpu.insts >> 0;
break;
}
return -1;
}
int
sim_trace (sd)
SIM_DESC sd;
{
int i;
for (i = 0; i < 12; i += 2)
{
unsigned char *p = cpu.regs[R_TP].c + ((cpu.regs[R6].s[LOW] + i) & 0xffff);
unsigned short *j = (unsigned short *) p;
printf ("%04x ", *j);
}
printf ("\n");
printf ("%02x %02x %02x %02x:%04x %04x %04x %04x %04x %04x %04x %04x %04x\n",
NORMAL_DP,
NORMAL_EP,
NORMAL_TP,
NORMAL_CP,
cpu.regs[R_PC].s[LOW],
cpu.regs[0].s[LOW],
cpu.regs[1].s[LOW],
cpu.regs[2].s[LOW],
cpu.regs[3].s[LOW],
cpu.regs[4].s[LOW],
cpu.regs[5].s[LOW],
cpu.regs[6].s[LOW],
cpu.regs[7].s[LOW]);
sim_resume (sd, 1, 0);
return 0;
}
void
sim_stop_reason (sd, reason, sigrc)
SIM_DESC sd;
enum sim_stop *reason;
int *sigrc;
{
*reason = sim_stopped;
*sigrc = cpu.exception;
}
void
sim_set_simcache_size (n)
{
if (cpu.cache)
free (cpu.cache);
if (n < 2)
n = 2;
cpu.cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
cpu.csize = n;
}
void
sim_size (n)
int n;
{
}
void
sim_info (sd, verbose)
SIM_DESC sd;
int verbose;
{
double timetaken = (double) cpu.ticks / (double) now_persec ();
double virttime = cpu.cycles / 10.0e6;
(*sim_callback->printf_filtered) (sim_callback,
"\n\ninstructions executed %10d\n",
cpu.insts);
(*sim_callback->printf_filtered) (sim_callback,
"cycles (v approximate) %10d\n",
cpu.cycles);
(*sim_callback->printf_filtered) (sim_callback,
"real time taken %10.4f\n",
timetaken);
(*sim_callback->printf_filtered) (sim_callback,
"virtual time taked %10.4f\n",
virttime);
if (timetaken)
{
(*sim_callback->printf_filtered) (sim_callback,
"simulation ratio %10.4f\n",
virttime / timetaken);
}
(*sim_callback->printf_filtered) (sim_callback,
"compiles %10d\n",
cpu.compiles);
(*sim_callback->printf_filtered) (sim_callback,
"cache size %10d\n",
cpu.csize);
}
SIM_DESC
sim_open (kind, cb, abfd, argv)
SIM_OPEN_KIND kind;
host_callback *cb;
struct _bfd *abfd;
char **argv;
{
sim_kind = kind;
myname = argv[0];
sim_callback = cb;
return (SIM_DESC) 1;
}
void
sim_close (sd, quitting)
SIM_DESC sd;
int quitting;
{
}
SIM_RC
sim_load (sd, prog, abfd, from_tty)
SIM_DESC sd;
char *prog;
bfd *abfd;
int from_tty;
{
extern bfd *sim_load_file ();
bfd *prog_bfd;
prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
sim_kind == SIM_OPEN_DEBUG,
0, sim_write);
if (prog_bfd == NULL)
return SIM_RC_FAIL;
if (abfd == NULL)
bfd_close (prog_bfd);
return SIM_RC_OK;
}
SIM_RC
sim_create_inferior (sd, abfd, argv, env)
SIM_DESC sd;
struct _bfd *abfd;
char **argv;
char **env;
{
int pc;
bfd_vma start_address;
if (abfd != NULL)
start_address = bfd_get_start_address (abfd);
else
start_address = 0;
pc = start_address;
sim_store_register (sd, PC_REGNUM, (unsigned char *) &pc, 4);
return SIM_RC_OK;
}
void
sim_do_command (sd, cmd)
SIM_DESC sd;
char *cmd;
{
(*sim_callback->printf_filtered) (sim_callback,
"This simulator does not accept any commands.\n");
}
void
sim_set_callbacks (ptr)
struct host_callback_struct *ptr;
{
sim_callback = ptr;
}