From: Martin Hunt Date: Fri, 2 Aug 1996 00:23:31 +0000 (+0000) Subject: Thu Aug 1 17:05:24 1996 Martin M. Hunt X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2934d1c9258c32d0eae590e686f13304429a759e;p=binutils-gdb.git Thu Aug 1 17:05:24 1996 Martin M. Hunt * ChangeLog, Makefile.in, configure, configure.in, d10v_sim.h, gencode.c, interp.c, simops.c: Created. --- diff --git a/sim/d10v/ChangeLog b/sim/d10v/ChangeLog new file mode 100644 index 00000000000..e0a84f0715e --- /dev/null +++ b/sim/d10v/ChangeLog @@ -0,0 +1,5 @@ +Thu Aug 1 17:05:24 1996 Martin M. Hunt + + * 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 00000000000..393cc61940e --- /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 00000000000..6bc9b3ccf5e --- /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 00000000000..6938ba19f15 --- /dev/null +++ b/sim/d10v/d10v_sim.h @@ -0,0 +1,104 @@ +#include +#include +#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 00000000000..279a6cb13ab --- /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<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 00000000000..573f5d4f24d --- /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 +} +