aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorMartin Hunt <hunt@redhat.com>1996-08-02 00:23:31 +0000
committerMartin Hunt <hunt@redhat.com>1996-08-02 00:23:31 +0000
commit2934d1c9258c32d0eae590e686f13304429a759e (patch)
treeab05bbca72db861e53391937d22fdd0279d290b2 /sim
parent745a0437db96f667ba50ad4aaaaff8907a2ba67c (diff)
downloadgdb-2934d1c9258c32d0eae590e686f13304429a759e.zip
gdb-2934d1c9258c32d0eae590e686f13304429a759e.tar.gz
gdb-2934d1c9258c32d0eae590e686f13304429a759e.tar.bz2
Thu Aug 1 17:05:24 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* ChangeLog, Makefile.in, configure, configure.in, d10v_sim.h, gencode.c, interp.c, simops.c: Created.
Diffstat (limited to 'sim')
-rw-r--r--sim/d10v/ChangeLog5
-rw-r--r--sim/d10v/Makefile.in149
-rw-r--r--sim/d10v/configure.in29
-rw-r--r--sim/d10v/d10v_sim.h104
-rw-r--r--sim/d10v/interp.c345
-rw-r--r--sim/d10v/simops.c1728
6 files changed, 2360 insertions, 0 deletions
diff --git a/sim/d10v/ChangeLog b/sim/d10v/ChangeLog
new file mode 100644
index 0000000..e0a84f0
--- /dev/null
+++ b/sim/d10v/ChangeLog
@@ -0,0 +1,5 @@
+Thu Aug 1 17:05:24 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * ChangeLog, Makefile.in, configure, configure.in, d10v_sim.h,
+ gencode.c, interp.c, simops.c: Created.
+
diff --git a/sim/d10v/Makefile.in b/sim/d10v/Makefile.in
new file mode 100644
index 0000000..393cc61
--- /dev/null
+++ b/sim/d10v/Makefile.in
@@ -0,0 +1,149 @@
+# Makefile template for Configure for the SH sim library.
+# Copyright (C) 1990, 1991, 1992, 1995 Free Software Foundation, Inc.
+# Written by Cygnus Support.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+VPATH = @srcdir@:@srcdir@/../common:@srcdir@/../../gdb/
+srcdir = @srcdir@
+srcroot = $(srcdir)/../..
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+host_alias = @host_alias@
+target_alias = @target_alias@
+program_transform_name = @program_transform_name@
+bindir = @bindir@
+
+libdir = @libdir@
+tooldir = $(libdir)/$(target_alias)
+
+datadir = @datadir@
+mandir = @mandir@
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+man3dir = $(mandir)/man3
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+man6dir = $(mandir)/man6
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+infodir = @infodir@
+includedir = @includedir@
+
+SHELL = /bin/sh
+
+INSTALL = $(srcroot)/install.sh -c
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_XFORM = $(INSTALL) -t='$(program_transform_name)'
+INSTALL_XFORM1= $(INSTALL_XFORM) -b=.1
+
+AR = @AR@
+AR_FLAGS = rc
+CC = @CC@
+CFLAGS = @CFLAGS@
+MAKEINFO = makeinfo
+RANLIB = @RANLIB@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+
+HDEFINES = @HDEFINES@
+TDEFINES =
+
+.NOEXPORT:
+MAKEOVERRIDES=
+
+X=xstuff.o
+XL=-lX11
+X=
+XL=
+
+INCDIR = $(srcdir)/../../include
+CSEARCH = -I. -I$(srcdir) -I../../include \
+ -I../../bfd -I$(INCDIR) -I$(srcdir)/../../bfd -I$(srcdir)/../../gdb -I$(srcdir)/../../newlib/libc/sys/sh
+DEP = mkdep
+
+all: run
+
+run: interp.o $(X) run.o table.o callback.o simops.o
+ $(CC) $(CFLAGS) -o run $(X) interp.o table.o callback.o simops.o run.o ../../bfd/libbfd.a ../../libiberty/libiberty.a $(XL) -lm
+
+interp.o:interp.c table.c
+run.o:run.c
+
+libsim.a:interp.o table.o simops.o
+ $(AR) $(ARFLAGS) libsim.a interp.o table.o
+ $(RANLIB) libsim.a
+
+simops.h: gencode
+ ./gencode -h >$@
+
+table.c: gencode simops.h
+ ./gencode >$@
+
+gencode: gencode.c
+ $(CC) $(CFLAGS) $(HDEFINES) $(TDEFINES) $(CSEARCH) $(CSWITCHE) -o gencode $(srcdir)/gencode.c ../../opcodes/libopcodes.a -lc
+
+.c.o:
+ $(CC) -c -DINSIDE_SIMULATOR $(CFLAGS) $(HDEFINES) $(TDEFINES) $(CSEARCH) $(CSWITCHES) $<
+
+check:
+
+info:
+clean-info:
+install-info:
+
+tags etags: TAGS
+
+TAGS: force
+ etags $(INCDIR)/*.h $(srcdir)/*.h $(srcdir)/*.c
+
+clean:
+ rm -f *.[oa] *~ core *.E *.p *.ip aout-params.h gen-aout
+ rm -f run libsim.a
+
+distclean mostlyclean maintainer-clean realclean: clean
+ rm -f TAGS
+ rm -f Makefile config.cache config.log config.status
+
+# Dummy target to force execution of dependent targets.
+#
+force:
+
+# Copy the files into directories where they will be run.
+install:
+ $(INSTALL_XFORM) run $(bindir)/run
+
+install-man: run.1
+ $(INSTALL_XFORM1) $(srcdir)/run.1 $(man1dir)/run.1
+
+Makefile: Makefile.in config.status
+ $(SHELL) ./config.status
+
+config.status: configure
+ $(SHELL) ./config.status --recheck
+
+dep: $(CFILES)
+ mkdep $(CFLAGS) $?
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/sim/d10v/configure.in b/sim/d10v/configure.in
new file mode 100644
index 0000000..6bc9b3c
--- /dev/null
+++ b/sim/d10v/configure.in
@@ -0,0 +1,29 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.5)dnl
+AC_INIT(Makefile.in)
+
+AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../..)
+AC_CANONICAL_SYSTEM
+AC_ARG_PROGRAM
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_C_BIGENDIAN
+
+. ${srcdir}/../../bfd/configure.host
+
+AC_SUBST(CFLAGS)
+AC_SUBST(HDEFINES)
+AR=${AR-ar}
+AC_SUBST(AR)
+AC_PROG_RANLIB
+
+# Put a plausible default for CC_FOR_BUILD in Makefile.
+AC_C_CROSS
+if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+else
+ CC_FOR_BUILD=gcc
+fi
+AC_SUBST(CC_FOR_BUILD)
+
+AC_OUTPUT(Makefile)
diff --git a/sim/d10v/d10v_sim.h b/sim/d10v/d10v_sim.h
new file mode 100644
index 0000000..6938ba1
--- /dev/null
+++ b/sim/d10v/d10v_sim.h
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include <ctype.h>
+#include "ansidecl.h"
+#include "opcode/d10v.h"
+
+/* FIXME: host defines */
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef signed char int8;
+typedef signed short int16;
+typedef signed int int32;
+typedef signed long long int64;
+
+/* FIXME: D10V defines */
+typedef uint16 reg_t;
+
+struct simops
+{
+ long opcode;
+ long mask;
+ int format;
+ int cycles;
+ int unit;
+ int exec_type;
+ void (*func)();
+ int numops;
+ int operands[9];
+};
+
+struct _state
+{
+ reg_t regs[16]; /* general-purpose registers */
+ reg_t cregs[15]; /* control registers */
+ int64 a[2]; /* accumulators */
+ uint8 SM;
+ uint8 EA;
+ uint8 DB;
+ uint8 IE;
+ uint8 RP;
+ uint8 MD;
+ uint8 FX;
+ uint8 ST;
+ uint8 F0;
+ uint8 F1;
+ uint8 C;
+ uint8 exe;
+ uint8 *imem;
+ uint8 *dmem;
+} State;
+
+extern uint16 OP[4];
+extern struct simops Simops[];
+
+#define PC (State.cregs[2])
+#define PSW (State.cregs[0])
+#define BPSW (State.cregs[1])
+#define BPC (State.cregs[3])
+#define RPT_C (State.cregs[7])
+#define RPT_S (State.cregs[8])
+#define RPT_E (State.cregs[9])
+#define MOD_S (State.cregs[10])
+#define MOD_E (State.cregs[11])
+#define IBA (State.cregs[14])
+
+#define SEXT3(x) ((((x)&0x7)^(~3))+4)
+
+/* sign-extend a 4-bit number */
+#define SEXT4(x) ((((x)&0xf)^(~7))+8)
+
+/* sign-extend an 8-bit number */
+#define SEXT8(x) ((((x)&0xff)^(~0x7f))+0x80)
+
+/* sign-extend a 16-bit number */
+#define SEXT16(x) ((((x)&0xffff)^(~0x7fff))+0x8000)
+
+#define BIT40 0x8000000000LL
+#define BIT44 0x80000000000LL
+#define MAX32 0x7fffffffLL
+#define MIN32 0xff80000000LL
+#define MASK32 0xffffffffLL
+#define MASK40 0xffffffffffLL
+#define MASK44 0xfffffffffffLL
+
+
+#define RB(x) (*((uint8 *)((x)+State.imem)))
+
+#ifdef WORDS_BIGENDIAN
+
+#define RW(x) (*((uint16 *)((x)+State.imem)))
+#define RLW(x) (*((uint32 *)((x)+State.imem)))
+#define SW(addr,data) RW(addr)=data
+
+#else
+
+uint32 get_longword_swap PARAMS ((uint16 x));
+uint16 get_word_swap PARAMS ((uint16 x));
+void write_word_swap PARAMS ((uint16 addr, uint16 data));
+
+#define SW(addr,data) write_word_swap(addr,data)
+#define RW(x) get_word_swap(x)
+#define RLW(x) get_longword_swap(x)
+
+#endif /* not WORDS_BIGENDIAN */
diff --git a/sim/d10v/interp.c b/sim/d10v/interp.c
new file mode 100644
index 0000000..279a6cb
--- /dev/null
+++ b/sim/d10v/interp.c
@@ -0,0 +1,345 @@
+#include "sysdep.h"
+#include "bfd.h"
+#include "remote-sim.h"
+#include "callback.h"
+
+#include "d10v_sim.h"
+
+#define IMEM_SIZE 18 /* D10V instruction memory size is 18 bits */
+#define DMEM_SIZE 16 /* Data memory */
+
+uint16 OP[4];
+
+static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
+
+#define MAX_HASH 63
+struct hash_entry
+{
+ struct hash_entry *next;
+ long opcode;
+ long mask;
+ struct simops *ops;
+};
+
+struct hash_entry hash_table[MAX_HASH+1];
+
+static long
+hash(insn, format)
+ long insn;
+ int format;
+{
+ if (format & LONG_OPCODE)
+ return ((insn & 0x3F000000) >> 24);
+ else
+ return((insn & 0x7E00) >> 9);
+}
+
+static struct hash_entry *
+lookup_hash (ins, size)
+ uint32 ins;
+ int size;
+{
+ struct hash_entry *h;
+
+ if (size)
+ h = &hash_table[(ins & 0x3F000000) >> 24];
+ else
+ h = &hash_table[(ins & 0x7E00) >> 9];
+
+ while ( (ins & h->mask) != h->opcode)
+ {
+ if (h->next == NULL)
+ {
+ printf ("ERROR looking up hash for %x\n",ins);
+ exit(1);
+ }
+ h = h->next;
+ }
+ return (h);
+}
+
+uint32
+get_longword_swap (x)
+ uint16 x;
+{
+ uint8 *a = (uint8 *)(x + State.imem);
+ return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + (a[3]);
+}
+
+uint16
+get_word_swap (x)
+ uint16 x;
+{
+ uint8 *a = (uint8 *)(x + State.imem);
+ return (a[0]<<8) + a[1];
+}
+
+void
+write_word_swap (addr, data)
+ uint16 addr, data;
+{
+ uint8 *a = (uint8 *)(addr + State.imem);
+ a[0] = data >> 8;
+ a[1] = data & 0xff;
+}
+
+
+static void
+get_operands (struct simops *s, uint32 ins)
+{
+ int i, shift, bits, flags;
+ uint32 mask;
+ for (i=0; i < s->numops; i++)
+ {
+ shift = s->operands[3*i];
+ bits = s->operands[3*i+1];
+ flags = s->operands[3*i+2];
+ mask = 0x7FFFFFFF >> (31 - bits);
+ OP[i] = (ins >> shift) & mask;
+ }
+}
+
+static void
+do_long (ins)
+ uint32 ins;
+{
+ struct hash_entry *h;
+ /* printf ("do_long %x\n",ins); */
+ h = lookup_hash (ins, 1);
+ get_operands (h->ops, ins);
+ (h->ops->func)();
+}
+static void
+do_2_short (ins1, ins2)
+ uint16 ins1, ins2;
+{
+ struct hash_entry *h;
+ /* printf ("do_2_short %x -> %x\n",ins1,ins2); */
+ h = lookup_hash (ins1, 0);
+ get_operands (h->ops, ins1);
+ (h->ops->func)();
+ h = lookup_hash (ins2, 0);
+ get_operands (h->ops, ins2);
+ (h->ops->func)();
+}
+static void
+do_parallel (ins1, ins2)
+ uint16 ins1, ins2;
+{
+ struct hash_entry *h1, *h2;
+ /* printf ("do_parallel %x || %x\n",ins1,ins2); */
+ h1 = lookup_hash (ins1, 0);
+ get_operands (h1->ops, ins1);
+ h2 = lookup_hash (ins2, 0);
+ get_operands (h2->ops, ins2);
+ if (h1->ops->exec_type == PARONLY)
+ {
+ (h1->ops->func)();
+ if (State.exe)
+ (h2->ops->func)();
+ }
+ else if (h2->ops->exec_type == PARONLY)
+ {
+ (h2->ops->func)();
+ if (State.exe)
+ (h1->ops->func)();
+ }
+ else
+ {
+ (h1->ops->func)();
+ (h2->ops->func)();
+ }
+}
+
+
+void
+sim_size (power)
+ int power;
+
+{
+ if (State.imem)
+ {
+ free (State.imem);
+ free (State.dmem);
+ }
+
+ State.imem = (uint8 *)calloc(1,1<<IMEM_SIZE);
+ State.dmem = (uint8 *)calloc(1,1<<DMEM_SIZE);
+ if (!State.imem || !State.dmem )
+ {
+ fprintf (stderr,"Memory allocation failed.\n");
+ exit(1);
+ }
+ printf ("Allocated %d bytes instruction memory and\n",1<<IMEM_SIZE);
+ printf (" %d bytes data memory.\n",1<<DMEM_SIZE);
+}
+
+static void
+init_system ()
+{
+ if (!State.imem)
+ sim_size(1);
+}
+
+int
+sim_write (addr, buffer, size)
+ SIM_ADDR addr;
+ unsigned char *buffer;
+ int size;
+{
+ int i;
+ init_system ();
+
+ printf ("sim_write %d bytes to 0x%x\n",size,addr);
+ for (i = 0; i < size; i++)
+ {
+ State.imem[i+addr] = buffer[i];
+ }
+ return size;
+}
+
+void
+sim_open (args)
+ char *args;
+{
+ struct simops *s;
+ struct hash_entry *h, *prev;
+ if (args != NULL)
+ printf ("sim_open %s\n",args);
+
+ /* put all the opcodes in the hash table */
+ for (s = Simops; s->func; s++)
+ {
+ h = &hash_table[hash(s->opcode,s->format)];
+
+ /* go to the last entry in the chain */
+ while (h->next)
+ h = h->next;
+
+ if (h->ops)
+ {
+ h->next = calloc(1,sizeof(struct hash_entry));
+ h = h->next;
+ }
+ h->ops = s;
+ h->mask = s->mask;
+ h->opcode = s->opcode;
+ }
+}
+
+
+void
+sim_close (quitting)
+ int quitting;
+{
+ /* nothing to do */
+}
+
+void
+sim_set_profile (n)
+ int n;
+{
+ printf ("sim_set_profile %d\n",n);
+}
+
+void
+sim_set_profile_size (n)
+ int n;
+{
+ printf ("sim_set_profile_size %d\n",n);
+}
+
+void
+sim_resume (step, siggnal)
+ int step, siggnal;
+{
+ uint32 inst;
+ int i;
+ reg_t oldpc;
+
+ printf ("sim_resume %d %d\n",step,siggnal);
+
+ while (1)
+ {
+ inst = RLW (PC << 2);
+ oldpc = PC;
+ switch (inst & 0xC0000000)
+ {
+ case 0xC0000000:
+ /* long instruction */
+ do_long (inst & 0x3FFFFFFF);
+ break;
+ case 0x80000000:
+ /* R -> L */
+ do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15);
+ break;
+ case 0x40000000:
+ /* L -> R */
+ do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
+ break;
+ case 0:
+ do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
+ break;
+ }
+
+ if (State.RP && PC == RPT_E)
+ {
+ RPT_C -= 1;
+ if (RPT_C == 0)
+ State.RP = 0;
+ else
+ PC = RPT_S;
+ }
+
+ /* FIXME */
+ if (PC == oldpc)
+ PC++;
+ }
+}
+
+int
+sim_trace ()
+{
+ printf ("sim_trace\n");
+ return 0;
+}
+
+void
+sim_info (verbose)
+ int verbose;
+{
+ printf ("sim_verbose\n");
+}
+
+void
+sim_create_inferior (start_address, argv, env)
+ SIM_ADDR start_address;
+ char **argv;
+ char **env;
+{
+ printf ("sim_create_inferior: PC=0x%x\n",start_address);
+ PC = start_address >> 2;
+}
+
+
+void
+sim_kill ()
+{
+ /* nothing to do */
+}
+
+void
+sim_set_callbacks(p)
+ host_callback *p;
+{
+ printf ("sim_set_callbacks\n");
+ /* callback = p; */
+}
+
+void
+sim_stop_reason (reason, sigrc)
+ enum sim_stop *reason;
+ int *sigrc;
+{
+ printf ("sim_stop_reason\n");
+}
diff --git a/sim/d10v/simops.c b/sim/d10v/simops.c
new file mode 100644
index 0000000..573f5d4
--- /dev/null
+++ b/sim/d10v/simops.c
@@ -0,0 +1,1728 @@
+#include "d10v_sim.h"
+#include "simops.h"
+
+/* #define DEBUG 1 */
+
+/* abs */
+void
+OP_4607 ()
+{
+#ifdef DEBUG
+ printf(" abs\tr%d\n",OP[0]);
+#endif
+ State.F1 = State.F0;
+ if ((int16)(State.regs[OP[0]]) < 0)
+ {
+ State.regs[OP[0]] = -(int16)(State.regs[OP[0]]);
+ State.F0 = 1;
+ }
+ else
+ State.F0 = 0;
+}
+
+/* abs */
+void
+OP_5607 ()
+{
+ int64 tmp;
+
+#ifdef DEBUG
+ printf(" abs\ta%d\n",OP[0]);
+#endif
+ State.F1 = State.F0;
+ if (State.a[OP[0]] & BIT40 )
+ {
+ tmp = -State.a[OP[0]] & MASK40;
+ if (State.ST)
+ {
+ if ( !(tmp & BIT40) && (tmp > MAX32))
+ State.a[OP[0]] = MAX32;
+ else if ( (tmp & BIT40) && (tmp < MIN32))
+ State.a[OP[0]] = MIN32;
+ else
+ State.a[OP[0]] = tmp;
+ }
+ else
+ State.a[OP[0]] = tmp;
+ State.F0 = 1;
+ }
+ else
+ State.F0 = 0;
+}
+
+/* add */
+void
+OP_200 ()
+{
+ uint16 tmp = State.regs[OP[0]];
+#ifdef DEBUG
+ printf(" add\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] += State.regs[OP[1]];
+ if ( tmp > State.regs[OP[0]])
+ State.C = 1;
+ else
+ State.C = 0;
+}
+
+/* add */
+void
+OP_1201 ()
+{
+#ifdef DEBUG
+ printf(" add\ta%d,r%d\n",OP[0],OP[1]);
+#endif
+}
+
+/* add */
+void
+OP_1203 ()
+{
+#ifdef DEBUG
+printf(" add\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* add2w */
+void
+OP_1200 ()
+{
+ uint32 tmp;
+ uint32 tmp1 = (State.regs[OP[0]]) << 16 | State.regs[OP[0]+1];
+ uint32 tmp2 = (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1];
+#ifdef DEBUG
+ printf(" add2w\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ tmp = tmp1 + tmp2;
+ if ( (tmp < tmp1) || (tmp < tmp2) )
+ State.C = 1;
+ else
+ State.C = 0;
+ State.regs[OP[0]] = tmp >> 16;
+ State.regs[OP[0]+1] = tmp & 0xFFFF;
+}
+
+/* add3 */
+void
+OP_1000000 ()
+{
+ uint16 tmp = State.regs[OP[0]];
+#ifdef DEBUG
+ printf(" add3\tr%d,r%d,0x%x\n",OP[0],OP[1],OP[2]);
+#endif
+ State.regs[OP[0]] = State.regs[OP[1]] + OP[2];
+ if ( tmp > State.regs[OP[0]])
+ State.C = 1;
+ else
+ State.C = 0;
+}
+
+/* addac3 */
+void
+OP_17000200 ()
+{
+#ifdef DEBUG
+printf(" addac3\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* addac3 */
+void
+OP_17000202 ()
+{
+#ifdef DEBUG
+printf(" addac3\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* addac3s */
+void
+OP_17001200 ()
+{
+#ifdef DEBUG
+printf(" addac3s\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* addac3s */
+void
+OP_17001202 ()
+{
+#ifdef DEBUG
+printf(" addac3s\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* addi */
+void
+OP_201 ()
+{
+#ifdef DEBUG
+ printf(" addi\tr%d,0x%x\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] += OP[1];
+}
+
+/* and */
+void
+OP_C00 ()
+{
+#ifdef DEBUG
+ printf(" and\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] &= State.regs[OP[1]];
+}
+
+/* and3 */
+void
+OP_6000000 ()
+{
+#ifdef DEBUG
+ printf(" and3\tr%d,r%d,0x%x\n",OP[0],OP[1],OP[2]);
+#endif
+ State.regs[OP[0]] = State.regs[OP[1]] & OP[2];
+}
+
+/* bclri */
+void
+OP_C01 ()
+{
+#ifdef DEBUG
+ printf(" bclri\tr%d,%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] &= ~(0x8000 >> OP[1]);
+}
+
+/* bl.s */
+void
+OP_4900 ()
+{
+#ifdef DEBUG
+ printf(" bl.s\t0x%x\n",OP[0]);
+#endif
+ State.regs[13] = PC+1;
+ PC += SEXT8 (OP[0]);
+}
+
+/* bl.l */
+void
+OP_24800000 ()
+{
+#ifdef DEBUG
+ printf(" bl.l\t0x%x\n",OP[0]);
+#endif
+ State.regs[13] = PC+1;
+ PC += OP[0];
+}
+
+/* bnoti */
+void
+OP_A01 ()
+{
+#ifdef DEBUG
+ printf(" bnoti\tr%d,%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] ^= 0x8000 >> OP[1];
+}
+
+/* bra.s */
+void
+OP_4800 ()
+{
+#ifdef DEBUG
+ printf(" bra.s\t0x%x\n",OP[0]);
+#endif
+ PC += SEXT8 (OP[0]);
+}
+
+/* bra.l */
+void
+OP_24000000 ()
+{
+#ifdef DEBUG
+ printf(" bra.l\t0x%x\n",OP[0]);
+#endif
+ PC += OP[0];
+}
+
+/* brf0f.s */
+void
+OP_4A00 ()
+{
+#ifdef DEBUG
+ printf(" brf0f.s\t0x%x\n",OP[0]);
+#endif
+ if (State.F0 == 0)
+ PC += SEXT8 (OP[0]);
+}
+
+/* brf0f.l */
+void
+OP_25000000 ()
+{
+#ifdef DEBUG
+ printf(" brf0f.l\t0x%x\n",OP[0]);
+#endif
+ if (State.F0 == 0)
+ PC += OP[0];
+}
+
+/* brf0t.s */
+void
+OP_4B00 ()
+{
+#ifdef DEBUG
+ printf(" brf0t.s\t0x%x\n",OP[0]);
+#endif
+ if (State.F0)
+ PC += SEXT8 (OP[0]);
+}
+
+/* brf0t.l */
+void
+OP_25800000 ()
+{
+#ifdef DEBUG
+ printf(" brf0t.l\t0x%x\n",OP[0]);
+#endif
+ if (State.F0)
+ PC += OP[0];
+}
+
+/* bseti */
+void
+OP_801 ()
+{
+#ifdef DEBUG
+ printf(" bseti\tr%d,%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] |= 0x8000 >> OP[1];
+}
+
+/* btsti */
+void
+OP_E01 ()
+{
+#ifdef DEBUG
+ printf(" btsti\tr%d,%d\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ State.F0 = (State.regs[OP[0]] & (0x8000 >> OP[1])) ? 1 : 0;
+}
+
+/* clrac */
+void
+OP_5601 ()
+{
+#ifdef DEBUG
+ printf(" clrac\ta%d\n",OP[0]);
+#endif
+ State.a[OP[0]] = 0;
+}
+
+/* cmp */
+void
+OP_600 ()
+{
+#ifdef DEBUG
+ printf(" cmp\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ State.F0 = ((int16)(State.regs[OP[0]]) < (int16)(State.regs[OP[1]])) ? 1 : 0;
+}
+
+/* cmp */
+void
+OP_1603 ()
+{
+#ifdef DEBUG
+printf(" cmp\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* cmpeq */
+void
+OP_400 ()
+{
+#ifdef DEBUG
+ printf(" cmpeq\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ State.F0 = (State.regs[OP[0]] == State.regs[OP[1]]) ? 1 : 0;
+}
+
+/* cmpeq */
+void
+OP_1403 ()
+{
+#ifdef DEBUG
+printf(" cmpeq\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* cmpeqi.s */
+void
+OP_401 ()
+{
+#ifdef DEBUG
+ printf(" cmpeqi.s\tr%d,0x%x\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ State.F0 = (State.regs[OP[0]] == SEXT4(OP[1])) ? 1 : 0;
+}
+
+/* cmpeqi.l */
+void
+OP_2000000 ()
+{
+#ifdef DEBUG
+ printf(" cmpeqi.l\tr%d,0x%x\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ State.F0 = (State.regs[OP[0]] == OP[1]) ? 1 : 0;
+}
+
+/* cmpi.s */
+void
+OP_601 ()
+{
+#ifdef DEBUG
+ printf(" cmpi.s\tr%d,0x%x\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ State.F0 = ((int16)(State.regs[OP[0]]) < SEXT4(OP[1])) ? 1 : 0;
+}
+
+/* cmpi.l */
+void
+OP_3000000 ()
+{
+#ifdef DEBUG
+ printf(" cmpi.l\tr%d,0x%x\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ State.F0 = ((int16)(State.regs[OP[0]]) < (int16)(OP[1])) ? 1 : 0;
+}
+
+/* cmpu */
+void
+OP_4600 ()
+{
+#ifdef DEBUG
+ printf(" cmpu\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ State.F0 = (State.regs[OP[0]] < State.regs[OP[1]]) ? 1 : 0;
+}
+
+/* cmpui */
+void
+OP_23000000 ()
+{
+#ifdef DEBUG
+ printf(" cmpui\tr%d,0x%x\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ State.F0 = (State.regs[OP[0]] < OP[1]) ? 1 : 0;
+}
+
+/* cpfg */
+void
+OP_4E09 ()
+{
+ uint8 *src, *dst;
+#ifdef DEBUG
+ printf(" cpfg\t%x,%x\n",OP[0],OP[1]);
+#endif
+
+ if (OP[0] == 0)
+ dst = &State.F0;
+ else
+ dst = &State.F1;
+
+ if (OP[1] == 0)
+ src = &State.F0;
+ else if (OP[1] == 1)
+ src = &State.F1;
+ else
+ src = &State.C;
+
+ *dst = *src;
+}
+
+/* dbt */
+void
+OP_5F20 ()
+{
+#ifdef DEBUG
+ printf(" dbt\n");
+#endif
+}
+
+/* divs */
+void
+OP_14002800 ()
+{
+ uint16 foo, tmp, tmpf;
+#ifdef DEBUG
+ printf(" divs\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ foo = (State.regs[OP[0]] << 1) | (State.regs[OP[0]+1] >> 15);
+ tmp = (int16)foo - (int16)(State.regs[OP[1]]);
+ tmpf = (foo >= State.regs[OP[1]]) ? 1 : 0;
+ State.regs[OP[0]] = (tmpf == 1) ? tmp : foo;
+ State.regs[OP[0]+1] = (State.regs[OP[0]+1] << 1) | tmpf;
+}
+
+/* exef0f */
+void
+OP_4E04 ()
+{
+#ifdef DEBUG
+ printf(" exef0f\n");
+#endif
+ State.exe = (State.F0) ? 0 : 1;
+}
+
+/* exef0t */
+void
+OP_4E24 ()
+{
+#ifdef DEBUG
+ printf(" exef0t\n");
+#endif
+ State.exe = State.F0;
+}
+
+/* exef1f */
+void
+OP_4E40 ()
+{
+#ifdef DEBUG
+ printf(" exef1f\n");
+#endif
+ State.exe = (State.F1) ? 0 : 1;
+}
+
+/* exef1t */
+void
+OP_4E42 ()
+{
+#ifdef DEBUG
+ printf(" exef1t\n");
+#endif
+ State.exe = State.F1;
+}
+
+/* exefaf */
+void
+OP_4E00 ()
+{
+#ifdef DEBUG
+ printf(" exefaf\n");
+#endif
+ State.exe = (State.F0 | State.F1) ? 0 : 1;
+}
+
+/* exefat */
+void
+OP_4E02 ()
+{
+#ifdef DEBUG
+ printf(" exefat\n");
+#endif
+ State.exe = (State.F0) ? 0 : (State.F1);
+}
+
+/* exetaf */
+void
+OP_4E20 ()
+{
+#ifdef DEBUG
+ printf(" exetaf\n");
+#endif
+ State.exe = (State.F1) ? 0 : (State.F0);
+}
+
+/* exetat */
+void
+OP_4E22 ()
+{
+#ifdef DEBUG
+ printf(" exetat\n");
+#endif
+ State.exe = (State.F0) ? (State.F1) : 0;
+}
+
+/* exp */
+void
+OP_15002A00 ()
+{
+ uint32 tmp, foo;
+ int i;
+
+#ifdef DEBUG
+ printf(" exp\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ if (((int16)State.regs[OP[0]]) >= 0)
+ tmp = (State.regs[OP[0]] << 16) | State.regs[OP[0]+1];
+ else
+ tmp = ~((State.regs[OP[0]] << 16) | State.regs[OP[0]+1]);
+
+ foo = 0x40000000;
+ for (i=1;i<16;i++)
+ {
+ if (tmp & foo)
+ {
+ State.regs[OP[0]] = i-1;
+ return;
+ }
+ }
+ State.regs[OP[0]] = 16;
+}
+
+/* exp */
+void
+OP_15002A02 ()
+{
+#ifdef DEBUG
+printf(" exp\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* jl */
+void
+OP_4D00 ()
+{
+#ifdef DEBUG
+ printf(" jl\t%x\n",OP[0]);
+#endif
+ State.regs[13] = PC+1;
+ PC = State.regs[OP[0]];
+}
+
+/* jmp */
+void
+OP_4C00 ()
+{
+#ifdef DEBUG
+ printf(" jmp\tr%d\n",OP[0]);
+#endif
+ PC = State.regs[OP[0]];
+}
+
+/* ld */
+void
+OP_30000000 ()
+{
+#ifdef DEBUG
+ printf(" ld\tr%d,@(0x%x,r%d)\n",OP[0],OP[1],OP[2]);
+#endif
+ State.regs[OP[0]] = RW (OP[1] + State.regs[OP[2]]);
+}
+
+/* ld */
+void
+OP_6401 ()
+{
+#ifdef DEBUG
+ printf(" ld\tr%d,@r%d-\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = RW (State.regs[OP[2]]);
+ State.regs[OP[1]] -= 2;
+}
+
+/* ld */
+void
+OP_6001 ()
+{
+#ifdef DEBUG
+ printf(" ld\tr%d,@r%d+\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = RW (State.regs[OP[2]]);
+ State.regs[OP[1]] += 2;
+}
+
+/* ld */
+void
+OP_6000 ()
+{
+#ifdef DEBUG
+ printf(" ld\tr%d,@r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = RW (State.regs[OP[1]]);
+}
+
+/* ld2w */
+void
+OP_31000000 ()
+{
+#ifdef DEBUG
+ printf(" ld2w\tr%d,@(0x%x,r%d)\n",OP[0],OP[1],OP[2]);
+#endif
+ State.regs[OP[0]] = RW (OP[1] + State.regs[OP[2]]);
+ State.regs[OP[0]+1] = RW (OP[1] + State.regs[OP[2]] + 2);
+}
+
+/* ld2w */
+void
+OP_6601 ()
+{
+#ifdef DEBUG
+ printf(" ld2w\tr%d,@r%d-\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = RW (State.regs[OP[2]]);
+ State.regs[OP[0]+1] = RW (State.regs[OP[2]]+2);
+ State.regs[OP[1]] -= 4;
+}
+
+/* ld2w */
+void
+OP_6201 ()
+{
+#ifdef DEBUG
+ printf(" ld2w\tr%d,@r%d+\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = RW (State.regs[OP[2]]);
+ State.regs[OP[0]+1] = RW (State.regs[OP[2]]+2);
+ State.regs[OP[1]] += 4;
+}
+
+/* ld2w */
+void
+OP_6200 ()
+{
+#ifdef DEBUG
+ printf(" ld2w\tr%d,@r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = RW (State.regs[OP[2]]);
+ State.regs[OP[0]+1] = RW (State.regs[OP[2]]+2);
+}
+
+/* ldb */
+void
+OP_38000000 ()
+{
+#ifdef DEBUG
+ printf(" ldb\tr%d,@(0x%x,r%d)\n",OP[0],OP[1],OP[2]);
+#endif
+ State.regs[OP[0]] = RB (OP[1] + State.regs[OP[2]]);
+ SEXT8 (State.regs[OP[0]]);
+}
+
+/* ldb */
+void
+OP_7000 ()
+{
+#ifdef DEBUG
+ printf(" ldb\tr%d,@r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = RB (State.regs[OP[1]]);
+ SEXT8 (State.regs[OP[0]]);
+}
+
+/* ldi.s */
+void
+OP_4001 ()
+{
+#ifdef DEBUG
+ printf(" ldi.s\tr%d,%x\n",OP[0],SEXT4(OP[1]));
+#endif
+ State.regs[OP[0]] = SEXT4(OP[1]);
+}
+
+/* ldi.l */
+void
+OP_20000000 ()
+{
+#ifdef DEBUG
+ printf(" ldi.l\tr%d,%d\t;0x%x\n",OP[0],OP[1],OP[1]);
+#endif
+ State.regs[OP[0]] = OP[1];
+}
+
+/* ldub */
+void
+OP_39000000 ()
+{
+#ifdef DEBUG
+ printf(" ldub\tr%d,@(0x%x,r%d)\n",OP[0],OP[1],OP[2]);
+#endif
+ State.regs[OP[0]] = RB (OP[1] + State.regs[OP[2]]);
+}
+
+/* ldub */
+void
+OP_7200 ()
+{
+#ifdef DEBUG
+ printf(" ldub\tr%d,@r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = RB (State.regs[OP[1]]);
+}
+
+/* mac */
+void
+OP_2A00 ()
+{
+#ifdef DEBUG
+printf(" mac\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* macsu */
+void
+OP_1A00 ()
+{
+#ifdef DEBUG
+printf(" macsu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* macu */
+void
+OP_3A00 ()
+{
+#ifdef DEBUG
+printf(" macu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* max */
+void
+OP_2600 ()
+{
+#ifdef DEBUG
+ printf(" max\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ if (State.regs[OP[1]] > State.regs[OP[0]])
+ {
+ State.regs[OP[0]] = State.regs[OP[1]];
+ State.F0 = 1;
+ }
+ else
+ State.F0 = 0;
+}
+
+/* max */
+void
+OP_3600 ()
+{
+#ifdef DEBUG
+printf(" max\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* max */
+void
+OP_3602 ()
+{
+#ifdef DEBUG
+printf(" max\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* min */
+void
+OP_2601 ()
+{
+#ifdef DEBUG
+ printf(" min\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.F1 = State.F0;
+ if (State.regs[OP[1]] < State.regs[OP[0]])
+ {
+ State.regs[OP[0]] = State.regs[OP[1]];
+ State.F0 = 1;
+ }
+ else
+ State.F0 = 0;
+}
+
+/* min */
+void
+OP_3601 ()
+{
+#ifdef DEBUG
+printf(" min\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* min */
+void
+OP_3603 ()
+{
+#ifdef DEBUG
+printf(" min\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* msb */
+void
+OP_2800 ()
+{
+#ifdef DEBUG
+printf(" msb\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* msbsu */
+void
+OP_1800 ()
+{
+#ifdef DEBUG
+printf(" msbsu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* msbu */
+void
+OP_3800 ()
+{
+#ifdef DEBUG
+printf(" msbu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* mul */
+void
+OP_2E00 ()
+{
+#ifdef DEBUG
+ printf(" mul\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] *= State.regs[OP[1]];
+}
+
+/* mulx */
+void
+OP_2C00 ()
+{
+#ifdef DEBUG
+printf(" mulx\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* mulxsu */
+void
+OP_1C00 ()
+{
+#ifdef DEBUG
+printf(" mulxsu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* mulxu */
+void
+OP_3C00 ()
+{
+#ifdef DEBUG
+printf(" mulxu\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* mv */
+void
+OP_4000 ()
+{
+#ifdef DEBUG
+ printf(" mv\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = State.regs[OP[1]];
+}
+
+/* mv2w */
+void
+OP_5000 ()
+{
+#ifdef DEBUG
+ printf(" mv2w\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = State.regs[OP[1]];
+ State.regs[OP[0]+1] = State.regs[OP[1]+1];
+}
+
+/* mv2wfac */
+void
+OP_3E00 ()
+{
+#ifdef DEBUG
+ printf(" mv2wfac\tr%d,a%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = (State.a[OP[1]] >> 16) & 0xffff;
+ State.regs[OP[0]+1] = State.a[OP[1]] & 0xffff;
+}
+
+/* mv2wtac */
+void
+OP_3E01 ()
+{
+#ifdef DEBUG
+ printf(" mv2wtac\tr%d,a%d\n",OP[0],OP[1]);
+#endif
+ State.a[OP[1]] = SEXT16 (State.regs[OP[0]]) << 16 | State.regs[OP[0]+1];
+}
+
+/* mvac */
+void
+OP_3E03 ()
+{
+#ifdef DEBUG
+ printf(" mvac\ta%d,a%d\n",OP[0],OP[1]);
+#endif
+ State.a[OP[0]] = State.a[OP[1]];
+}
+
+/* mvb */
+void
+OP_5400 ()
+{
+#ifdef DEBUG
+ printf(" mvb\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = SEXT8 (State.regs[OP[1]] & 0xff);
+}
+
+/* mvf0f */
+void
+OP_4400 ()
+{
+#ifdef DEBUG
+ printf(" mvf0f\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ if (State.F0 == 0)
+ State.regs[OP[0]] = State.regs[OP[1]];
+}
+
+/* mvf0t */
+void
+OP_4401 ()
+{
+#ifdef DEBUG
+ printf(" mvf0t\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ if (State.F0)
+ State.regs[OP[0]] = State.regs[OP[1]];
+}
+
+/* mvfacg */
+void
+OP_1E04 ()
+{
+#ifdef DEBUG
+ printf(" mvfacg\tr%d,a%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = (State.a[OP[1]] >> 32) & 0xff;
+}
+
+/* mvfachi */
+void
+OP_1E00 ()
+{
+#ifdef DEBUG
+ printf(" mvfachi\tr%d,a%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = (State.a[OP[1]] >> 16) & 0xffff;
+}
+
+/* mvfaclo */
+void
+OP_1E02 ()
+{
+#ifdef DEBUG
+ printf(" mvfaclo\tr%d,a%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = State.a[OP[1]] & 0xffff;
+}
+
+/* mvfc */
+void
+OP_5200 ()
+{
+#ifdef DEBUG
+ printf(" mvfc\tr%d,cr%d\n",OP[0],OP[1]);
+#endif
+ if (OP[1] == 0)
+ {
+ /* PSW is treated specially */
+ PSW = 0;
+ if (State.SM) PSW |= 0x8000;
+ if (State.EA) PSW |= 0x2000;
+ if (State.DB) PSW |= 0x1000;
+ if (State.IE) PSW |= 0x400;
+ if (State.RP) PSW |= 0x200;
+ if (State.MD) PSW |= 0x100;
+ if (State.FX) PSW |= 0x80;
+ if (State.ST) PSW |= 0x40;
+ if (State.F0) PSW |= 8;
+ if (State.F1) PSW |= 4;
+ if (State.C) PSW |= 1;
+ }
+ State.regs[OP[0]] = State.cregs[OP[1]];
+}
+
+/* mvtacg */
+void
+OP_1E41 ()
+{
+#ifdef DEBUG
+ printf(" mvtacg\tr%d,a%d\n",OP[0],OP[1]);
+#endif
+ State.a[OP[1]] &= MASK32;
+ State.a[OP[1]] |= (int64)(State.regs[OP[0]] & 0xff) << 32;
+}
+
+/* mvtachi */
+void
+OP_1E01 ()
+{
+ uint16 tmp;
+#ifdef DEBUG
+ printf(" mvtachi\tr%d,a%d\n",OP[0],OP[1]);
+#endif
+ tmp = State.a[OP[1]] & 0xffff;
+ State.a[OP[1]] = SEXT16 (State.regs[OP[0]]) << 16 | tmp;
+ printf("put 0x%llx\n",State.a[OP[1]]);
+}
+
+/* mvtaclo */
+void
+OP_1E21 ()
+{
+#ifdef DEBUG
+ printf(" mvtaclo\tr%d,a%d\n",OP[0],OP[1]);
+#endif
+ State.a[OP[1]] = SEXT16 (State.regs[OP[0]]);
+}
+
+/* mvtc */
+void
+OP_5600 ()
+{
+#ifdef DEBUG
+ printf(" mvtc\tr%d,cr%d\n",OP[0],OP[1]);
+#endif
+ State.cregs[OP[1]] = State.regs[OP[0]];
+ if (OP[1] == 0)
+ {
+ /* PSW is treated specially */
+ State.SM = (PSW & 0x8000) ? 1 : 0;
+ State.EA = (PSW & 0x2000) ? 1 : 0;
+ State.DB = (PSW & 0x1000) ? 1 : 0;
+ State.IE = (PSW & 0x400) ? 1 : 0;
+ State.RP = (PSW & 0x200) ? 1 : 0;
+ State.MD = (PSW & 0x100) ? 1 : 0;
+ State.FX = (PSW & 0x80) ? 1 : 0;
+ State.ST = (PSW & 0x40) ? 1 : 0;
+ State.F0 = (PSW & 8) ? 1 : 0;
+ State.F1 = (PSW & 4) ? 1 : 0;
+ State.C = PSW & 1;
+ if (State.ST && !State.FX)
+ {
+ fprintf (stderr,"ERROR at PC 0x%x: ST can only be set when FX is set.\n",PC<<2);
+ exit (1);
+ }
+ }
+}
+
+/* mvub */
+void
+OP_5401 ()
+{
+#ifdef DEBUG
+ printf(" mvub\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = State.regs[OP[1]] & 0xff;
+}
+
+/* neg */
+void
+OP_4605 ()
+{
+#ifdef DEBUG
+ printf(" neg\tr%d\n",OP[0]);
+#endif
+ State.regs[OP[0]] = 0 - State.regs[OP[0]];
+}
+
+/* neg */
+void
+OP_5605 ()
+{
+ int64 tmp;
+#ifdef DEBUG
+ printf(" neg\ta%d\n",OP[0]);
+#endif
+ tmp = -State.a[OP[0]] & MASK40;
+ if (State.ST)
+ {
+ if ( !(tmp & BIT40) && (tmp > MAX32))
+ State.a[OP[0]] = MAX32;
+ else if ( (tmp & BIT40) && (tmp < MIN32))
+ State.a[OP[0]] = MIN32;
+ else
+ State.a[OP[0]] = tmp;
+ }
+ else
+ State.a[OP[0]] = tmp;
+}
+
+
+/* nop */
+void
+OP_5E00 ()
+{
+}
+
+/* not */
+void
+OP_4603 ()
+{
+#ifdef DEBUG
+ printf(" not\tr%d\n",OP[0]);
+#endif
+ State.regs[OP[0]] = ~(State.regs[OP[0]]);
+}
+
+/* or */
+void
+OP_800 ()
+{
+#ifdef DEBUG
+ printf(" or\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] |= State.regs[OP[1]];
+}
+
+/* or3 */
+void
+OP_4000000 ()
+{
+#ifdef DEBUG
+ printf(" or3\tr%d,r%d,0x%x\n",OP[0],OP[1],OP[2]);
+#endif
+ State.regs[OP[0]] = State.regs[OP[1]] | OP[2];
+}
+
+/* rac */
+void
+OP_5201 ()
+{
+ int64 tmp;
+ int shift = SEXT3 (OP[2]);
+#ifdef DEBUG
+ printf(" rac\tr%d,a%d,%d\n",OP[0],OP[1],shift);
+#endif
+ State.F1 = State.F0;
+ if (shift >=0)
+ tmp = ((State.a[0] << 16) | (State.a[1] & 0xffff)) << shift;
+ else
+ tmp = ((State.a[0] << 16) | (State.a[1] & 0xffff)) >> -shift;
+ tmp = (tmp + 0x8000) & MASK44;
+ if ( !(tmp & BIT44) && (tmp > MAX32))
+ {
+ State.regs[OP[0]] = 0x7fff;
+ State.regs[OP[0]+1] = 0xffff;
+ State.F0 = 1;
+ }
+ else if ((tmp & BIT44) && (tmp < 0xfff80000000LL))
+ {
+ State.regs[OP[0]] = 0x8000;
+ State.regs[OP[0]+1] = 0;
+ State.F0 = 1;
+ }
+ else
+ {
+ State.regs[OP[0]] = (tmp >> 16) & 0xffff;
+ State.regs[OP[0]+1] = tmp & 0xffff;
+ State.F0 = 0;
+ }
+}
+
+/* rachi */
+void
+OP_4201 ()
+{
+#ifdef DEBUG
+printf(" rachi\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* rep */
+void
+OP_27000000 ()
+{
+#ifdef DEBUG
+ printf(" rep\tr%d,0x%x\n",OP[0],OP[1]);
+#endif
+ RPT_S = PC + 1;
+ RPT_E = PC + OP[1];
+ RPT_C = State.regs[OP[0]];
+ State.RP = 1;
+ if (RPT_C == 0)
+ {
+ fprintf (stderr, "ERROR: rep with count=0 is illegal.\n");
+ exit(1);
+ }
+}
+
+/* repi */
+void
+OP_2F000000 ()
+{
+#ifdef DEBUG
+ printf(" repi\t%d,0x%x\n",OP[0],OP[1]);
+#endif
+ RPT_S = PC + 1;
+ RPT_E = PC + OP[1];
+ RPT_C = OP[0];
+ State.RP = 1;
+ if (RPT_C == 0)
+ {
+ fprintf (stderr, "ERROR: rep with count=0 is illegal.\n");
+ exit(1);
+ }
+}
+
+/* rtd */
+void
+OP_5F60 ()
+{
+#ifdef DEBUG
+printf(" rtd\n");
+#endif
+}
+
+/* rte */
+void
+OP_5F40 ()
+{
+#ifdef DEBUG
+printf(" rte\n");
+#endif
+}
+
+/* sadd */
+void
+OP_1223 ()
+{
+#ifdef DEBUG
+printf(" sadd\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* setf0f */
+void
+OP_4611 ()
+{
+#ifdef DEBUG
+printf(" setf0f\t%x\n",OP[0]);
+#endif
+}
+
+/* setf0t */
+void
+OP_4613 ()
+{
+#ifdef DEBUG
+printf(" setf0t\t%x\n",OP[0]);
+#endif
+}
+
+/* sleep */
+void
+OP_5FC0 ()
+{
+#ifdef DEBUG
+printf(" sleep\n");
+#endif
+}
+
+/* sll */
+void
+OP_2200 ()
+{
+#ifdef DEBUG
+ printf(" sll\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] <<= (State.regs[OP[1]] & 0xf);
+}
+
+/* sll */
+void
+OP_3200 ()
+{
+#ifdef DEBUG
+printf(" sll\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* slli */
+void
+OP_2201 ()
+{
+#ifdef DEBUG
+ printf(" slli\tr%d,%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] <<= OP[1];
+}
+
+/* slli */
+void
+OP_3201 ()
+{
+#ifdef DEBUG
+printf(" slli\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* slx */
+void
+OP_460B ()
+{
+ uint16 tmp;
+#ifdef DEBUG
+ printf(" slx\tr%d\n",OP[0]);
+#endif
+ State.regs[OP[0]] = (State.regs[OP[0]] << 1) | State.F0;
+}
+
+/* sra */
+void
+OP_2400 ()
+{
+#ifdef DEBUG
+ printf(" sra\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = ((int16)(State.regs[OP[0]])) >> (State.regs[OP[1]] & 0xf);
+}
+
+/* sra */
+void
+OP_3400 ()
+{
+#ifdef DEBUG
+printf(" sra\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* srai */
+void
+OP_2401 ()
+{
+#ifdef DEBUG
+ printf(" srai\tr%d,%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] = ((int16)(State.regs[OP[0]])) >> OP[1];
+}
+
+/* srai */
+void
+OP_3401 ()
+{
+#ifdef DEBUG
+printf(" srai\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* srl */
+void
+OP_2000 ()
+{
+#ifdef DEBUG
+ printf(" srl\tr%d,r%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] >>= (State.regs[OP[1]] & 0xf);
+}
+
+/* srl */
+void
+OP_3000 ()
+{
+#ifdef DEBUG
+printf(" srl\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* srli */
+void
+OP_2001 ()
+{
+#ifdef DEBUG
+printf(" srli\tr%d,%d\n",OP[0],OP[1]);
+#endif
+ State.regs[OP[0]] >>= OP[1];
+}
+
+/* srli */
+void
+OP_3001 ()
+{
+#ifdef DEBUG
+printf(" srli\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* srx */
+void
+OP_4609 ()
+{
+ uint16 tmp;
+#ifdef DEBUG
+ printf(" srx\tr%d\n",OP[0]);
+#endif
+ tmp = State.F0 << 15;
+ State.regs[OP[0]] = (State.regs[OP[0]] >> 1) | tmp;
+}
+
+/* st */
+void
+OP_34000000 ()
+{
+#ifdef DEBUG
+ printf(" st\tr%d,@(0x%x,r%d)\n",OP[0],OP[1],OP[2]);
+#endif
+ SW (OP[1] + State.regs[OP[2]], State.regs[OP[0]]);
+}
+
+/* st */
+void
+OP_6800 ()
+{
+#ifdef DEBUG
+ printf(" st\tr%d,@r%d\n",OP[0],OP[1]);
+#endif
+ SW (State.regs[OP[1]], State.regs[OP[0]]);
+}
+
+/* st */
+void
+OP_6C1F ()
+{
+#ifdef DEBUG
+printf(" st\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* st */
+void
+OP_6801 ()
+{
+#ifdef DEBUG
+printf(" st\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* st */
+void
+OP_6C01 ()
+{
+#ifdef DEBUG
+printf(" st\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* st2w */
+void
+OP_35000000 ()
+{
+#ifdef DEBUG
+printf(" st2w\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* st2w */
+void
+OP_6A00 ()
+{
+#ifdef DEBUG
+printf(" st2w\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* st2w */
+void
+OP_6E1F ()
+{
+#ifdef DEBUG
+printf(" st2w\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* st2w */
+void
+OP_6A01 ()
+{
+#ifdef DEBUG
+printf(" st2w\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* st2w */
+void
+OP_6E01 ()
+{
+#ifdef DEBUG
+printf(" st2w\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* stb */
+void
+OP_3C000000 ()
+{
+#ifdef DEBUG
+printf(" stb\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* stb */
+void
+OP_7800 ()
+{
+#ifdef DEBUG
+printf(" stb\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* stop */
+void
+OP_5FE0 ()
+{
+#ifdef DEBUG
+ printf(" stop\n");
+#endif
+ exit(1);
+}
+
+/* sub */
+void
+OP_0 ()
+{
+#ifdef DEBUG
+printf(" sub\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* sub2w */
+void
+OP_1000 ()
+{
+#ifdef DEBUG
+printf(" sub2w\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* subac3 */
+void
+OP_17000000 ()
+{
+#ifdef DEBUG
+printf(" subac3\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* subac3 */
+void
+OP_17000002 ()
+{
+#ifdef DEBUG
+printf(" subac3\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* subac3s */
+void
+OP_17001000 ()
+{
+#ifdef DEBUG
+printf(" subac3s\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* subac3s */
+void
+OP_17001002 ()
+{
+#ifdef DEBUG
+printf(" subac3s\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+
+/* subi */
+void
+OP_1 ()
+{
+#ifdef DEBUG
+printf(" subi\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* trap */
+void
+OP_5F00 ()
+{
+#ifdef DEBUG
+ printf(" trap\t%d\n",OP[0]);
+#endif
+
+ /* for now, trap 0 is used for simulating IO */
+
+ if (OP[0] == 0)
+ {
+ char *fstr = State.regs[2] + State.imem;
+ printf (fstr,State.regs[3],State.regs[4],State.regs[5]);
+ }
+ else if (OP[0] == 1 )
+ {
+ char *fstr = State.regs[2] + State.imem;
+ puts (fstr);
+ }
+}
+
+/* tst0i */
+void
+OP_7000000 ()
+{
+#ifdef DEBUG
+printf(" tst0i\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* tst1i */
+void
+OP_F000000 ()
+{
+#ifdef DEBUG
+printf(" tst1i\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* wait */
+void
+OP_5F80 ()
+{
+#ifdef DEBUG
+printf(" wait\n");
+#endif
+}
+
+/* xor */
+void
+OP_A00 ()
+{
+#ifdef DEBUG
+printf(" xor\t%x,%x\n",OP[0],OP[1]);
+#endif
+}
+
+/* xor3 */
+void
+OP_5000000 ()
+{
+#ifdef DEBUG
+printf(" xor3\t%x,%x,%x\n",OP[0],OP[1],OP[2]);
+#endif
+}
+