old-cross-binutils/sim/h8300/writecode.c
Steve Chamberlain a154eea78c H8/300 simulator
1992-12-22 21:59:06 +00:00

1396 lines
25 KiB
C

/* BFD library support routines for the Hitachi H8/300 architecture.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Hacked by Steve Chamberlain of Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include"bfd.h"
#include"sysdep.h"
#define DEFINE_TABLE
#define INSIM
#include"opcode/h8300.h"
#define MAXSAME 14
#define PTWO 256
static struct h8_opcode *h8_opcodes_sorted[PTWO][MAXSAME];
/* Run through the opcodes and sort them into order to make them easy
to disassemble
*/
char *cs = "/*";
char *ce = "*/";
char *nibs[] =
{
"foo",
"(b0&0xf)",
"((b1>>4)&0xf)",
"((b1)&0xf)",
"((pc[2]>>4)&0xf)",
"((pc[2])&0xf)",
"((pc[3]>>4)&0xf)",
"((pc[3])&0xf)",
0, 0};
char *abs8[] =
{
"foo",
"foo",
"b1",
"foo",
};
#define sorted_key noperands
char *abs16[] =
{
"foo",
"foo",
"foo",
"foo",
"(pc[2]<<8)|pc[3]",
"foo",
"foo",
"foo",
};
char *empty="fake";
init ()
{
unsigned int i;
struct h8_opcode *p;
for (p = h8_opcodes; p->name; p++)
{
int n1 = 0;
int n2 = 0;
int j;
for (j = 0; p->data.nib[j] != E; j++)
{
if ((int)p->data.nib[j] == ABS16ORREL8SRC)
p->data.nib[j] = ABS16SRC;
if ((int)p->data.nib[j ] == ABS16OR8SRC)
p->data.nib[j] = ABS16SRC;
if ((int)p->data.nib[j] == ABS16OR8DST)
p->data.nib[j] = ABS16DST;
}
/* Kill push and pop, they're duplicates */
if (strcmp(p->name,"push")==0) {
p->name = empty;
}
if (strcmp(p->name,"pop")==0) {
p->name = empty;
}
if ((int) p->data.nib[0] < 16)
{
n1 = (int) p->data.nib[0];
}
else
n1 = 0;
if ((int) p->data.nib[1] < 16)
{
n2 = (int) p->data.nib[1];
}
else
n2 = 0;
#if 0
if ((int) p->data.nib[2] < 16)
{
n3 = (int) p->data.nib[2];
}
else if ((int) p->data.nib[2] & B30)
{
n3 = 0;
}
else if ((int) p->data.nib[2] & B31)
{
n3 = 0x8;
}
if ((int) p->data.nib[3] < 16)
{
n4 = (int) p->data.nib[3];
}
else if ((int) p->data.nib[3] & B30)
{
n4 = 0;
}
else if ((int) p->data.nib[3] & B31)
{
n4 = 0x8;
}
#endif
for (i = 0; i < MAXSAME; i++)
{
int j = /* ((n3 >> 3) * 512) + ((n4 >> 3) * 256) + */ n1 * 16 + n2;
if (h8_opcodes_sorted[j][i] == (struct h8_opcode *) NULL)
{
h8_opcodes_sorted[j][i] = p;
p->sorted_key = j;
break;
}
}
if (i == MAXSAME)
abort ();
/* Just make sure there are an even number of nibbles in it, and
that the count is the same s the length */
for (i = 0; p->data.nib[i] != E; i++)
/*EMPTY*/ ;
if (i & 1)
abort ();
p->length = i / 2;
}
for (i = 0; i < PTWO; i++)
{
if (h8_opcodes_sorted[i][0])
p = h8_opcodes_sorted[i][0];
else
h8_opcodes_sorted[i][0] = p;
}
}
unsigned int
DEFUN (bfd_h8_disassemble, (addr, data, stream),
bfd_vma addr AND
CONST bfd_byte * data AND
FILE * stream)
{
/* Find the first entry in the table for this opcode */
CONST static char *regnames[] =
{
"r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
"r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"};
int rs = 0;
int rd = 0;
int rdisp = 0;
int abs = 0;
struct h8_opcode **p = h8_opcodes_sorted[(unsigned) (data[0])];
struct h8_opcode *q;
/* Find the exact opcode/arg combo */
while (*p)
{
op_type *nib;
unsigned int len = 0;
q = *p++;
nib = q->data.nib;
while (*nib != E)
{
op_type looking_for = *nib;
int thisnib = data[len >> 1];
thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
if ((int) looking_for & (int) B31)
{
if (((int) thisnib & 0x8) == 0)
goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B31);
}
if ((int) looking_for & (int) B30)
{
if (((int) thisnib & 0x8) != 0)
goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B30);
}
switch (looking_for)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
if ((int) looking_for != thisnib)
goto fail;
break;
case ABS16SRC:
case ABS16OR8SRC:
case ABS16ORREL8SRC:
case ABS16DST:
case ABS16OR8DST:
case DISPSRC:
case DISPDST:
case IMM16:
abs = (data[len >> 1]) * 256 + data[(len + 2) >> 1];
len += 3;
nib += 3;
break;
case DISPREG:
rdisp = thisnib;
break;
case KBIT:
abs = thisnib == 0x8 ? 2 : 1;
break;
case IMM8:
case ABS8SRC:
case ABS8DST:
case MEMIND:
case DISP8:
abs = data[len >> 1];
len++;
nib++;
break;
case IMM3:
abs = thisnib;
break;
case RS8:
case RS16:
case RSINC:
case RSIND:
rs = thisnib;
break;
case RD16:
case RDDEC:
case RD8:
case RDIND:
rd = thisnib;
break;
default:
fprintf (stream, "Dont understand \n");
goto found;
}
len++;
nib++;
}
goto found;
fail:
;
}
fprintf (stream, "%02x %02x .word\tH'%x,H'%x",
data[0], data[1],
data[0], data[1]);
return 2;
found:;
{
int i;
for (i = 0; i < q->length; i++)
{
fprintf (stream, "%02x", data[i]);
}
for (; i < 6; i++)
{
fprintf (stream, " ");
}
}
fprintf (stream, "%s\t", q->name);
/* Now print out the args */
{
op_type *args = q->args.nib;
int hadone = 0;
while (*args != E)
{
if (hadone)
fprintf (stream, ",");
switch ((int) (*args) & ~((int) B30 | (int) B31))
{
case IMM16:
case IMM8:
case IMM3:
fprintf (stream, "#0x%x", (unsigned) abs);
break;
case RD8:
fprintf (stream, "%s", regnames[rd]);
break;
case RS8:
fprintf (stream, "%s", regnames[rs]);
break;
case RD16:
fprintf (stream, "r%d", rd & 0x7);
break;
case RS16:
fprintf (stream, "r%d", rs & 0x7);
break;
case RSINC:
fprintf (stream, "@r%d+", rs & 0x7);
break;
case RDDEC:
fprintf (stream, "@-r%d", rd & 0x7);
break;
case RDIND:
fprintf (stream, "@r%d", rd & 0x7);
break;
case RSIND:
fprintf (stream, "@r%d", rs & 0x7);
break;
case ABS8SRC:
case ABS16SRC:
case ABS16OR8SRC:
case ABS16ORREL8SRC:
case ABS16OR8DST:
case ABS16DST:
case ABS8DST:
fprintf (stream, "@0x%x", (unsigned) abs);
break;
case MEMIND:
fprintf (stream, "@@%d (%x)", abs, abs);
break;
case DISP8:
fprintf (stream, ".%s%d (%x)", (char) abs > 0 ? "+" : "", (char) abs,
addr + (char) abs + 2);
break;
case DISPSRC:
case DISPDST:
fprintf (stream, "@(0x%x,r%d)", abs, rdisp & 0x7);
break;
case CCR:
fprintf (stream, "ccr");
break;
case KBIT:
fprintf (stream, "#%d", abs);
break;
default:
abort ();
}
hadone = 1;
args++;
}
}
return q->length;
}
void
decode (p, fetch, size)
struct h8_opcode *p;
int fetch;
int size;
{
int i;
char *ss = size == 8 ? "BYTE" : "WORD";
for (i = 0; p->data.nib[i] != E; i++)
{
switch (p->data.nib[i])
{
case RS8:
if (fetch)
printf ("srca = BYTE_REG(%s);\n", nibs[i]);
break;
case RS16 | B30:
case RS16 | B31:
case RS16:
if (fetch)
printf ("srca = WORD_REG(%s);\n", nibs[i]);
break;
case RD8:
if (fetch)
printf ("srcb = BYTE_REG(%s);\n", nibs[i]);
else
printf ("SET_BYTE_REG(%s,dst);\n", nibs[i]);
break;
case RD16 | B30:
case RD16 | B31:
case RD16:
if (fetch)
printf ("srcb = WORD_REG(%s);\n", nibs[i]);
else
printf ("SET_WORD_REG(%s,dst);\n", nibs[i]);
break;
case IMM8:
if (fetch)
printf ("srca = b1;\n", i);
break;
case RSINC:
case RSINC | B30:
case RSINC | B31:
if (fetch)
{
printf("rn = %s &0x7;\n", nibs[i]);
printf ("srca = %s_MEM(reg[rn]);\n", size == 8 ? "BYTE"
: "WORD") ;
printf("reg[rn]+=%d;\n", size/8);
}
break;
case RSIND:
case RSIND | B30:
case RSIND | B31:
if (fetch) {
printf("lval = WORD_REG(%s);\n", nibs[i]);
printf("srca = %s_MEM(lval);\n", ss);
}
break;
case RDIND:
case RDIND | B30:
case RDIND | B31:
if (fetch) {
printf("rn = %s & 0x7;\n", nibs[i] );
printf("lval = reg[rn];\n");
printf("srcb = %s_MEM(lval);\n", size==8 ? "BYTE" : "WORD");
}
else
{
printf("SET_%s_MEM(lval,dst);\n",ss);
}
break;
case MEMIND:
if (fetch)
{
printf("lval = WORD_MEM(b1);\n");
}
break;
case RDDEC:
case RDDEC | B30:
case RDDEC | B31:
if (!fetch)
{
printf("rn = %s & 0x7;\n", nibs[i]);
printf("reg[rn]-=%d;\n", size/8);
printf ("SET_%s_MEM(reg[rn], dst);\n",
size == 8 ? "BYTE" : "WORD");
}
break;
case IMM16:
if (fetch)
printf ("srca =WORD_IMM;\n", i);
break;
case ABS8SRC:
if (fetch) {
printf("lval = (0xff00) + b1;\n");
printf ("srca = BYTE_MEM(lval);\n");
}
break;
case ABS8DST:
if (fetch)
{
printf("lval = (0xff00) + b1;\n");
printf ("srcb = BYTE_MEM(lval);\n");
}
else
{
printf ("SET_BYTE_MEM(lval,dst);\n");
}
break;
case KBIT:
if (fetch)
printf ("srca = KBIT(%d);\n", i);
break;
case ABS16ORREL8SRC:
case ABS16SRC:
if (fetch)
{
printf("lval = ((pc[2] << 8) + pc[3]);\n");
printf("srca = %s_MEM(lval);\n", size==8 ? "BYTE" : "WORD");
}
break;
case DISPREG|B30:
case DISPREG|B31:
case DISPREG:
printf("rn = %s & 0x7;\n", nibs[i]);
break;
case DISPSRC:
if (fetch)
{
printf("lval = 0xffff&((pc[2] << 8) + pc[3] +reg[rn]);\n");
printf("srca = %s_MEM(lval);\n", size == 8 ? "BYTE" : "WORD");
}
break;
case DISPDST:
if (fetch)
{
printf("lval = 0xffff&((pc[2] << 8) + pc[3] +reg[rn]);\n");
printf("srcb = %s_MEM(lval);\n", size == 8 ? "BYTE" : "WORD");
}
else {
printf("SET_%s_MEM(lval,dst);\n",ss);
}
break;
case ABS16DST:
if (fetch)
{
printf("lval = ((pc[2] << 8) + pc[3]);\n");
printf("srcb = WORD_MEM(lval);\n");
}
else
{
printf ("SET_WORD_MEM(lval,dst);\n", i);
}
break;
case IGNORE:
break;
case DISP8:
printf(" /* DISP8 handled in opcode */\n");
break;
default:
if (p->data.nib[i] > HexF)
{
printf("exception = SIGILL;\n");
}
}
}
}
#define NNIBS 8
typedef int keytype[NNIBS];
struct key
{
keytype k;
int nmatch;
/* struct h8_opcode *match[200];*/
};
struct key keys[50];
int nkeys;
calckey (p, key)
struct h8_opcode *p;
keytype key;
{
int j;
for (j = 0; (p->data.nib[j] != E); j++)
{
if (p->data.nib[j] == RS8 || p->data.nib[j] == RD8)
p->size = 8;
if (p->size != 8)
p->size=16;
if (p->data.nib[j] > HexF)
key[j] = p->data.nib[j];
else
key[j] = 0;
}
for (; j < NNIBS; j++)
key[j] = 0;
}
lookup (key)
keytype key;
{
int n;
/* See if this key matches one already found */
for (n = 0; n < nkeys; n++)
{
int i;
for (i = 0; i < NNIBS; i++)
{
if ((keys[n].k[i]&0x3f) != (key[i]&0x3f))
break;
}
if (i == NNIBS)
break;
}
return n;
}
BADNEWS(x) {
if (x == 0x7c) return 0;
if (x == 0x7d) return 0;
if (x == 0x7e) return 0;
if (x == 0x7f) return 0;
return 1;
}
sortmodes ()
{
/* look through all the addressing modes, work out which ones are unique*/
struct h8_opcode **p;
keytype key;
int n;
int i;
memset (keys, 0, sizeof (keys));
for (i = 0; i < PTWO; i++)
{
p = h8_opcodes_sorted[i];
while (*p)
{
int j;
int a = 0;
if (BADNEWS((*p)->sorted_key)) {
calckey (*p, key);
n = lookup (key);
if (n == nkeys)
{
/* No hit, insert */
memcpy (keys[n].k, key, sizeof (keys[n].k));
nkeys++;
}
/* Link in the p */
#if 0
/*e*/ keys[n].match[keys[n].nmatch++] = *p;
#endif
}
(*p)->idx = n;
p++;
}
}
#if 0
for (n = 0; n < nkeys; n++)
{
printf ("%d %d %d %d %d %d %d %d\n", keys[n][0], keys[n][1], keys[n][2], keys[n][3],
keys[n][4], keys[n][5], keys[n][6], keys[n][7]);
}
#endif
}
void
enop ()
{
printf ("%s Nop does nothing %s", cs, ce);
}
void
esleep ()
{
printf ("exception = SIGSTOP;\n");
}
rv (x)
{
printf ("v= 0;\n");
}
void
mov (p, s, sz)
struct h8_opcode *p;
char *s;
int sz;
{
printf("dst = srca;\n");
}
tn (s)
{
/* printf ("n = dst & 0x%x;\n", s == 8 ? 0x80 : 0x8000);*/
}
tz (s)
{
/* printf ("z = ~(dst & 0x%x);\n", s == 8 ? 0xff : 0xffff);*/
}
tv (s)
{
/* printf ("v = (( (~(srca ^ srcb) & (srca ^ dst))) & (1<<%d));\n", s);*/
}
tc (s)
{
printf ("c = dst & 0x%x;\n", 1 << s);
}
log_flags (s)
{
tn (s);
tz (s);
rv (s);
}
alu_flags (s)
{
tn (s);
tz (s);
tv (s);
tc (s);
}
void
bclr (p)
struct h8_opcode *p;
{
printf ("dst = srca & ~(1<<srcb);\n");
}
void
biand (p)
struct h8_opcode *p;
{
printf ("c =(C && ! ((srca >> srcb)&1));\n");
}
void
bild (p)
struct h8_opcode *p;
{
printf ("c = ( ! ((srca >> srcb)&1));\n");
}
void
andc (p)
struct h8_opcode *p;
{
printf ("SET_CCR(GET_CCR() & srca);\n");
}
void
addx (p)
struct h8_opcode *p;
{
printf ("dst = srca + srcb+ (c != 0);\n");
}
void
subx (p)
struct h8_opcode *p;
{
printf ("dst = srcb - srca - (c != 0);\n");
}
void
add (p, s, sz)
struct h8_opcode *p;
char *s;
int sz;
{
printf ("%s;\n", s);
alu_flags (sz);
}
void
adds (p, s)
struct h8_opcode *p;
char *s;
{
printf ("%s;\n", s);
}
void
bra (p, a)
struct h8_opcode *p;
char *a;
{
printf ("if (%s) npc += (((char *)pc)[1]);\n", a);
}
void
bsr (p, a)
struct h8_opcode *p;
char *a;
{
printf("reg[7]-=2;\n");
printf("tmp = reg[7];\n");
printf ("SET_WORD_MEM(tmp, npc-mem);\n");
printf ("npc += (((char *)pc)[1]);\n");
}
void
cmp (p, a, s)
struct h8_opcode *p;
char *a;
int s;
{
decode(p, 1, s);
printf("srca = -srca;\n");
printf ("dst = srca + srcb;\n");
}
void
jsr (p, a, s)
struct h8_opcode *p;
char *a;
int s;
{
printf("if (b1 == 0xc4) {\n");
printf("printf(\"%%c\", reg[2]);\n");
printf("}\n");
printf("else {\n");
printf("reg[7]-=2;\n");
printf("tmp = reg[7];\n");
printf ("SET_WORD_MEM(tmp, npc-mem);\n");
printf ("npc = lval + mem;\n");
printf("}");
}
void
jmp (p, a, s)
struct h8_opcode *p;
char *a;
int s;
{
printf ("npc = lval + mem;\n");
}
void
rts (p, a, s)
struct h8_opcode *p;
char *a;
int s;
{
printf ("tmp = reg[7];\n");
printf ("reg[7]+=2;\n");
printf ("npc = mem + WORD_MEM(tmp);\n");
}
void
setf (p, a, s)
struct h8_opcode *p;
char *a;
int s;
{
printf ("tmp = GET_CCR();\n");
printf ("tmp %s= srca;\n",a);
}
void
bpt (p, a, s)
struct h8_opcode *p;
char *a;
int s;
{
printf ("exception = SIGTRAP;\n");
printf( "npc = pc;\n");
}
void
log (p, a, s)
struct h8_opcode *p;
char *a;
int s;
{
printf ("dst = srcb %s srca;\n", a);
}
void
ulog (p, a, s)
struct h8_opcode *p;
char *a;
int s;
{
printf ("dst = %s srcb ;\n", a);
}
void
nop()
{
}
void
rotl()
{
printf("c = srcb & 0x80;\n");
printf("dst = srcb << 1;\n");
printf("if (c) dst|=1;\n");
}
void
rotr()
{
printf("c = srcb & 1;\n");
printf("dst = srcb >> 1;\n");
printf("if (c) dst|=0x80;\n");
}
void
rotxl()
{
printf("tmp = srcb & 0x80;\n");
printf("dst = srcb << 1;\n");
printf("if (c) dst|=1;\n");
printf("c = tmp;\n");
}
void
rotxr()
{
printf("tmp = srcb & 1;\n");
printf("dst = srcb >> 1;\n");
printf("if (c) dst|=0x80;\n");
printf("c = tmp;\n");
}
void
shal()
{
printf("c = srcb&0x80;\n");
printf("dst = srcb << 1;\n");
}
void
shar()
{
printf("c = srcb&0x1;\n");
printf("if (srcb&0x80) dst = (srcb>>1) | 0x80;\n");
printf("else dst = (srcb>>1) &~ 0x80;\n");
}
void
shll()
{
printf("c = srcb&0x80;\n");
printf("dst = srcb << 1;\n");
}
void
shlr()
{
printf("c = srcb&0x1;\n");
printf("dst = (srcb>>1) &~ 0x80;\n");
}
void
divxu()
{
printf("srca = BYTE_REG(pc[1]>>4);\n");
printf("srcb = WORD_REG(pc[1]&0x7);\n");
printf("n = srca & 0x80\;\n");
printf("z = !srca;\n");
printf("if (srca) dst = srcb / srca;tmp = srcb %% srca;\n");
printf("reg[pc[1]&0x7] = (dst & 0xff) | (tmp << 8);\n");
}
void
mulxu()
{
printf("srca = BYTE_REG(pc[1]>>4);\n");
printf("srcb = WORD_REG(pc[1]&0x7);\n");
printf("dst = (srcb&0xff) * srca;\n");
printf("reg[pc[1]&0x7] = dst;\n");
}
char saf[]="goto setflags;";
char sf[] = "goto shiftflags;";
char af8[] = "goto aluflags8;";
char af16[] = "goto aluflags16;";
char lf[] = "goto logflags;";
char mf8[]= "goto movflags8;";
char mf16[]= "goto movflags16;";
char nx[] = "goto next;";
struct
{
char *ftype;
int decode;
char *name;
void (*func) ();
char *arg;
int size;
}
table [] =
{
saf,1,"orc",setf,"|",0,
saf,1,"xorc",setf,"^",0,
saf,1,"andc",setf,"&",0,
0,1, "bild", bild, 0, 0,
0,1, "nop", nop, 0, 0,
0,1, "bclr", bclr, 0, 0,
0,1, "biand", biand, 0, 0,
0,1, "bra", bra, "1", 0,
0,1, "brn", bra, "0", 0,
0,1, "bf", bra, "0", 0,
0,1, "bhi", bra, "(C||Z)==0", 0,
0,1, "bls", bra, "(C||Z)==1", 0,
0,1, "bcs", bra, "C==1", 0,
0,1, "bcc", bra, "C==0", 0,
0,1, "bpl", bra, "N==0", 0,
0,1, "bmi", bra, "N==1", 0,
0,1, "bvs", bra, "V==1", 0,
0,1, "bvc", bra, "V==0", 0,
0,1, "bge", bra, "(N^V)==0", 0,
0,1, "bgt", bra, "(Z|(N^V))==0", 0,
0,1, "blt", bra, "(N^V)==1", 0,
0,1, "ble", bra, "(Z|(N^V))==1", 0,
0,1, "beq", bra, "Z==1", 0,
0,1, "bne", bra, "Z==0", 0,
0,1, "bsr", bsr, "", 0,
0,1, "jsr", jsr, 0, 0,
0,1, "jmp", jmp, 0, 0,
0,0, "rts", rts, 0, 0,
0,1, "andc", andc, 0, 0,
0,1, "nop", enop, 0, 0,
sf,1, "shal",shal,0,0,
sf,1, "shar",shar,0,0,
sf,1, "shll",shll,0,0,
sf,1, "shlr",shlr,0,0,
sf,1, "rotxl",rotxl,0,0,
sf,1, "rotxr",rotxr,0,0,
sf,1, "rotl",rotl,0,0,
sf,1, "rotr",rotr,0,0,
lf,1, "xor", log, "^",0,
lf,1, "and", log, "&",0,
lf,1, "or", log, "|",0,
lf,1,"not", ulog," ~",0,
lf,1,"neg", ulog," - ",0,
0,1, "adds", adds, "dst = srca + srcb", 0,
0,1, "subs", adds, "srca = -srca; dst = srcb + srca", 0,
af8,1, "add.b", add, "dst = srca + srcb", 8,
af16,1, "add.w", add, "dst = srca + srcb", 16,
af16,1, "sub.w", add, "srca = -srca; dst = srcb + srca", 16,
af8,1, "sub.b", add, "srca = -srca; dst = srcb + srca", 8,
af8,1, "addx", addx, 0, 8,
af8,1, "subx", subx, 0, 8,
af8,0, "cmp.b", cmp, 0, 8,
af16,0, "cmp.w", cmp, 0, 16,
0,1, "sleep", esleep, 0, 0,
0,0, "bpt", bpt, 0, 8,
nx,0, "divxu", divxu,0,0,
nx,0, "mulxu", mulxu,0,0,
mf8,1, "mov.b", mov, 0, 8,
mf16,1, "mov.w", mov, 0, 16,
0, 0
};
edo (p)
struct h8_opcode *p;
{
int i;
printf ("%s %s %s\n", cs, p->name, ce);
for (i = 0; table[i].name; i++)
{
if (strcmp (table[i].name, p->name) == 0)
{
printf ("{\n");
if (table[i].decode) decode(p, 1,p->size);
printf ("cycles += %d;\n", p->time);
printf ("npc = pc + %d;\n", p->length);
table[i].func (p, table[i].arg, table[i].size);
if (table[i].decode) decode(p, 0,p->size);
if (table[i].ftype) printf(table[i].ftype);
else printf ("goto next;\n");
printf ("}\n");
return;
}
}
printf ("%s not found %s\n", cs, ce);
printf("exception = SIGILL;\n");
printf ("break;\n");
}
int
owrite (i)
{
/* write if statements to select the right opcode */
struct h8_opcode **p;
int needand = 1;
p = h8_opcodes_sorted[i];
printf ("case 0x%03x:\n", i);
if (p[1] == 0)
{
/* See if the next few also match */
while (h8_opcodes_sorted[i + 1][0] == *p)
{
i++;
printf ("case 0x%03x:\n", i);
}
/* Dont need any if's this is the only one */
edo (*p);
}
else
{
while (*p)
{
/* start two nibbles in since we know we match in the first byte */
int c;
int nib = 2;
int byte = 1;
int mask1[5];
int mask0[5];
int nibshift = 4;
int any = 0;
for (c = 0; c < 5; c++)
{
mask1[c] = 0;
mask0[c] = 0;
}
printf ("%s %x%x", cs, (*p)->data.nib[0], (*p)->data.nib[1]);
while ((c = (*p)->data.nib[nib]) != E)
{
if (c & B30)
{
/* bit 3 must be zero */
mask0[byte] |= 0x8 << nibshift;
printf ("0");
any = 1;
}
else if (c & B31)
{
/* bit 3 must be one */
mask1[byte] |= 0x8 << nibshift;
printf ("8");
any = 1;
}
else if (c <= HexF)
{
mask0[byte] |= ((~c) & 0xf) << nibshift;
mask1[byte] |= (c & 0xf) << nibshift;
printf ("%x", c);
any = 1;
}
else
{
printf ("x");
}
nib++;
if (nibshift == 4)
{
nibshift = 0;
}
else
{
byte++;
nibshift = 4;
}
}
printf ("*/\n");
if (any)
{
printf ("if (");
needand = 0;
for (c = 1; c < byte; c++)
{
if (mask0[c] | mask1[c])
{
if (needand)
printf ("\n&&");
printf ("((pc[%d]&0x%02x)==0x%x)",
c, mask0[c] | mask1[c], mask1[c]);
needand = 1;
}
}
printf (")\n");
}
edo (*p);
p++;
}
}
return i;
}
print_key (i)
{
int j;
printf ("%s", cs);
for (j = 0; j < 8; j++)
{
/* printf ("(0x%02x ", keys[i].k[j]);*/
if (keys[i].k[j] & B30)
printf ("B30");
else if (keys[i].k[j] & B31)
printf ("B31");
switch (keys[i].k[j])
{
case KBIT:
printf ("KBIT");
break;
case IMM3:
printf ("IMM3");
break;
case RD8:
printf ("RD8");
break;
case RD16:
printf ("RD16");
break;
case RS8:
printf ("RS8");
break;
case RS16:
printf ("RS16");
break;
case IMM8:
printf ("IMM8");
break;
case IMM16:
printf ("IMM16");
break;
case CCR:
printf ("CCR");
break;
case ABS8SRC:
printf ("ABS8SRC");
break;
case ABS8DST:
printf ("ABS8SDST");
break;
case DISP8:
printf ("DISP8");
break;
case ABS16SRC:
printf ("ABS16SRC");
break;
case ABS16OR8SRC:
printf ("ABS16OR8SRC");
break;
case ABS16DST:
printf ("ABS16SDST");
break;
case ABS16OR8DST:
printf ("ABS16OR8SDST");
break;
case DISPSRC:
printf ("DISPSRC");
break;
case DISPDST:
printf ("DISPSDST");
break;
case DISPREG:
printf ("DISPREG");
break;
case RDDEC:
printf ("RDDEC");
break;
case RSINC:
printf ("RSINC");
break;
case RDIND:
printf ("RDIND");
break;
case RSIND:
printf ("RSIND");
break;
case MEMIND:
printf ("MEMIND");
break;
case ABS16ORREL8SRC:
printf ("ABS16ORREL8SRC");
break;
case IGNORE:
printf ("IGNORE");
break;
default:
printf ("**");
break;
}
printf (" ");
}
printf ("%s\n", ce);
}
dofetch (fetch)
int fetch;
{
int i;
int done_for[PTWO];
memset (done_for, 0, sizeof (done_for));
printf ("switch (b0) {\n");
for (i = 0; i < nkeys; i++)
{
struct h8_opcode *p;
struct h8_opcode *l = 0;
int k;
printf ("%s KEY %d %s\n", cs,i,ce);
print_key (i);
{
int j;
l = 0;
for (p = h8_opcodes; p->name; p++)
{
int key[8];
if (p->idx == i && p->name != empty)
{
l = p;
if (done_for[p->sorted_key] != i + 1000)
{
done_for[p->sorted_key] = i + 1000;
printf ("case 0x%03x:\n", p->sorted_key);
printf("%s %s %s\n", cs, p->name, ce);
}
}
}
if (l)
{
decode (l, fetch, l->size);
printf ("break;\n");
}
else
printf (" /* NO */\n");
}
}
printf ("}\n");
}
remove_dups()
{
struct h8_opcode *s;
struct h8_opcode *d;
for (d = s = h8_opcodes; s->name; s++)
{
int doit = 1;
if (strcmp(s->name,"push") ==0) doit = 0;
if (strcmp(s->name,"pop") ==0) doit = 0;
if (doit)
{
*d++ = *s;
}
}
*d++ = *s++;
}
main ()
{
int i;
remove_dups();
init ();
sortmodes ();
#if 0
printf("%s fetch the args %s\n", cs,ce);
dofetch (1);
#endif
printf("%s do the operation %s\n", cs,ce);
printf ("switch (b0) \n{\n");
for (i = 0; i < PTWO; i++)
{
i = owrite (i);
}
printf ("}\n");
#if 0
printf("%s store the result %s\n", cs,ce);
dofetch (0);
#endif
return 0;
}