Add flakey floating-point support to the TI c80 simulator.
authorAndrew Cagney <cagney@redhat.com>
Mon, 5 May 1997 12:46:25 +0000 (12:46 +0000)
committerAndrew Cagney <cagney@redhat.com>
Mon, 5 May 1997 12:46:25 +0000 (12:46 +0000)
14 files changed:
sim/common/ChangeLog
sim/common/Make-common.in
sim/common/sim-fpu.c [new file with mode: 0644]
sim/common/sim-fpu.h [new file with mode: 0644]
sim/common/sim-inline.c [new file with mode: 0644]
sim/common/sim-inline.h [new file with mode: 0644]
sim/common/sim-trace.c
sim/common/sim-trace.h
sim/testsuite/.Sanitize
sim/tic80/ChangeLog
sim/tic80/Makefile.in
sim/tic80/alu.h
sim/tic80/cpu.h
sim/tic80/insns

index 6ffc2b2..482c498 100644 (file)
@@ -1,3 +1,13 @@
+Mon May  5 13:19:16 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * sim-trace.h (TRACE_FPU_IDX): Add Floating-point specific
+       tracing.
+
+       * sim-fpu.h, sim-fpu.c: New files - prototype for generic target
+       fpu support.
+
+       * sim-inline.h, sim-inline.c: Add support for SIM_FPU.
+
 Fri May  2 17:59:42 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * sim-core.c (sim_core_map_to_str): New function ascii equivalent
index 1654b8e..c2b2fff 100644 (file)
@@ -191,6 +191,7 @@ sim-n-bits_h = $(srcdir)/../common/sim-n-bits.h
 sim-core_h = $(srcdir)/../common/sim-core.h
 sim-n-core_h = $(srcdir)/../common/sim-n-core.h
 sim-events_h = $(srcdir)/../common/sim-events.h
+sim-fpu_h = $(srcdir)/../common/sim-fpu.h
 sim-io_h = $(srcdir)/../common/sim-io.h
 sim-options_h = $(srcdir)/../common/sim-options.h
 
@@ -246,6 +247,14 @@ sim-events.c: $(srcdir)/../common/sim-events.c
        cat $(srcdir)/../common/$@ >> tmp-$@
        $(srcdir)/../../move-if-change tmp-$@ $@
 
+sim-fpu.o: sim-fpu.c $(sim-fpu_h) $(sim-assert_h) \
+       $(SIM_EXTRA_DEPS)
+sim-fpu.c: $(srcdir)/../common/sim-fpu.c
+       rm -f $@ tmp-$@
+       echo "# 1 \"$(srcdir)/../common/$@\"" > tmp-$@
+       cat $(srcdir)/../common/$@ >> tmp-$@
+       $(srcdir)/../../move-if-change tmp-$@ $@
+
 sim-inline.c: $(srcdir)/../common/sim-inline.c
        rm -f $@ tmp-$@
        echo "# 1 \"$(srcdir)/../common/$@\"" > tmp-$@
@@ -302,7 +311,7 @@ cgen-trace.o: $(srcdir)/../common/cgen-trace.c $(sim_main_headers) \
        $(CC) -c $(srcdir)/../common/cgen-trace.c $(ALL_CFLAGS)
 
 cgen-utils.o: $(srcdir)/../common/cgen-utils.c $(sim_main_headers) \
-         $(SIM_EXTRA_DEPS) cgen-mem.h cgen-sem.h
+         $(SIM_EXTRA_DEPS) mem-ops.h sem-ops.h
        $(CC) -c $(srcdir)/../common/cgen-utils.c $(ALL_CFLAGS)
 
 # Support targets.
diff --git a/sim/common/sim-fpu.c b/sim/common/sim-fpu.c
new file mode 100644 (file)
index 0000000..b02530c
--- /dev/null
@@ -0,0 +1,169 @@
+/* Simulator Floating-point support.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+This file is part of GDB, the GNU debugger.
+
+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, 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.  */
+
+
+
+#ifndef _SIM_FPU_C_
+#define _SIM_FPU_C_
+
+#include "sim-main.h"
+#include "sim-fpu.h"
+
+#include <math.h>
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_add (sim_fpu l,
+            sim_fpu r)
+{
+  sim_fpu ans;
+  ans.val = l.val + r.val;
+  return ans;
+}
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_sub (sim_fpu l,
+            sim_fpu r)
+{
+  sim_fpu ans;
+  ans.val = l.val - r.val;
+  return ans;
+}
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_mul (sim_fpu l,
+            sim_fpu r)
+{
+  sim_fpu ans;
+  ans.val = l.val * r.val;
+  return ans;
+}
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_div (sim_fpu l,
+            sim_fpu r)
+{
+  sim_fpu ans;
+  ans.val = l.val / r.val;
+  return ans;
+}
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_inv (sim_fpu r)
+{
+  sim_fpu ans;
+  ans.val = 1 / r.val;
+  return ans;
+}
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_sqrt (sim_fpu r)
+{
+  sim_fpu ans;
+  ans.val = sqrt (r.val);
+  return ans;
+}
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_32to (unsigned32 s)
+{
+  sim_fpu ans;
+  ans.val = *(float*) &s;
+  return ans;
+}
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_64to (unsigned64 s)
+{
+  sim_fpu ans;
+  ans.val = *(double*) &s;
+  return ans;
+}
+
+
+INLINE_SIM_FPU (unsigned32)
+sim_fpu_to32 (sim_fpu l)
+{
+  float s = l.val;
+  return *(unsigned32*) &s;
+}
+
+
+INLINE_SIM_FPU (unsigned64)
+sim_fpu_to64 (sim_fpu s)
+{
+  return *(unsigned64*) &s.val;
+}
+
+
+INLINE_SIM_FPU (float)
+sim_fpu_2f (sim_fpu f)
+{
+  return f.val;
+}
+
+
+INLINE_SIM_FPU (double)
+sim_fpu_2d (sim_fpu s)
+{
+  return s.val;
+}
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_f2 (float f)
+{
+  sim_fpu ans;
+  ans.val = f;
+  return ans;
+}
+
+
+INLINE_SIM_FPU (sim_fpu)
+sim_fpu_d2 (double d)
+{
+  sim_fpu ans;
+  ans.val = d;
+  return ans;
+}
+
+
+INLINE_SIM_FPU (int)
+sim_fpu_is_nan (sim_fpu d)
+{
+  return 0; /* FIXME - detect NaN */
+}
+
+
+INLINE_SIM_FPU (int)
+sim_fpu_cmp (sim_fpu l,
+            sim_fpu r)
+{
+  return l.val - r.val;
+}
+
+#endif
diff --git a/sim/common/sim-fpu.h b/sim/common/sim-fpu.h
new file mode 100644 (file)
index 0000000..a40b4c9
--- /dev/null
@@ -0,0 +1,68 @@
+/* Simulator Floating-point support.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+This file is part of GDB, the GNU debugger.
+
+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, 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.  */
+
+
+
+#ifndef _SIM_FPU_H_
+#define _SIM_FPU_H_
+
+/* the FPU intermediate type */
+
+typedef struct _sim_fpu {
+  double val;
+} sim_fpu;
+
+
+/* Arrithmetic operators */
+
+INLINE_SIM_FPU (sim_fpu) sim_fpu_add (sim_fpu l, sim_fpu r);
+INLINE_SIM_FPU (sim_fpu) sim_fpu_sub (sim_fpu l, sim_fpu r);
+INLINE_SIM_FPU (sim_fpu) sim_fpu_mul (sim_fpu l, sim_fpu r);
+INLINE_SIM_FPU (sim_fpu) sim_fpu_div (sim_fpu l, sim_fpu r);
+INLINE_SIM_FPU (sim_fpu) sim_fpu_inv (sim_fpu l);
+INLINE_SIM_FPU (sim_fpu) sim_fpu_sqrt (sim_fpu sqr);
+
+
+/* Conversions single/double to/from fpu type */
+
+INLINE_SIM_FPU (sim_fpu) sim_fpu_32to (unsigned32 s);
+INLINE_SIM_FPU (sim_fpu) sim_fpu_64to (unsigned64 s);
+
+INLINE_SIM_FPU (unsigned32) sim_fpu_to32 (sim_fpu s);
+INLINE_SIM_FPU (unsigned64) sim_fpu_to64 (sim_fpu s);
+
+INLINE_SIM_FPU (float) sim_fpu_2f (sim_fpu f);
+INLINE_SIM_FPU (double) sim_fpu_2d (sim_fpu d);
+
+INLINE_SIM_FPU (sim_fpu) sim_fpu_f2 (float f);
+INLINE_SIM_FPU (sim_fpu) sim_fpu_d2 (double d);
+
+
+/* Signalling or NonSignalling NaN */
+
+INLINE_SIM_FPU (int) sim_fpu_is_nan (sim_fpu s);
+
+
+/* compare l with r; return <0, ==0, >0 accordingly */
+
+INLINE_SIM_FPU (int) sim_fpu_cmp (sim_fpu l, sim_fpu r);
+
+
+#endif
diff --git a/sim/common/sim-inline.c b/sim/common/sim-inline.c
new file mode 100644 (file)
index 0000000..dffa103
--- /dev/null
@@ -0,0 +1,78 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
+    Copyright (C) 1997, Free Software Foundation, Inc.
+
+    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.
+    */
+
+
+#ifndef _SIM_INLINE_C_
+#define _SIM_INLINE_C_
+
+#include "sim-inline.h"
+
+
+#if defined(SIM_BITS_INLINE)
+#if ((SIM_BITS_INLINE & INCLUDE_MODULE) \
+     && !(SIM_BITS_INLINE & INCLUDED_BY_MODULE))
+#include "sim-bits.c"
+#endif
+#endif
+
+
+#if defined(SIM_CORE_INLINE)
+#if ((SIM_CORE_INLINE & INCLUDE_MODULE) \
+     && !(SIM_CORE_INLINE & INCLUDED_BY_MODULE))
+#include "sim-core.c"
+#endif
+#endif
+
+
+#if defined(SIM_ENDIAN_INLINE)
+#if ((SIM_ENDIAN_INLINE & INCLUDE_MODULE) \
+     && !(SIM_ENDIAN_INLINE & INCLUDED_BY_MODULE))
+#include "sim-endian.c"
+#endif
+#endif
+
+
+#if defined(SIM_EVENTS_INLINE)
+#if ((SIM_EVENTS_INLINE & INCLUDE_MODULE) \
+     && !(SIM_EVENTS_INLINE & INCLUDED_BY_MODULE))
+#include "sim-events.c"
+#endif
+#endif
+
+
+#if defined(SIM_FPU_INLINE)
+#if ((SIM_FPU_INLINE & INCLUDE_MODULE) \
+     && !(SIM_FPU_INLINE & INCLUDED_BY_MODULE))
+#include "sim-fpu.c"
+#endif
+#endif
+
+
+#if defined(SIM_IO_INLINE)
+#if ((SIM_IO_INLINE & INCLUDE_MODULE) \
+     && !(SIM_IO_INLINE & INCLUDED_BY_MODULE))
+#include "sim-io.c"
+#endif
+#endif
+
+
+
+#endif
diff --git a/sim/common/sim-inline.h b/sim/common/sim-inline.h
new file mode 100644 (file)
index 0000000..7e4ec7a
--- /dev/null
@@ -0,0 +1,562 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
+    Copyright (C) 1997, Free Software Foundation, Inc.
+
+    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.
+    */
+
+
+#ifndef _SIM_INLINE_H_
+#define _SIM_INLINE_H_
+
+
+/* INLINE CODE SELECTION:
+
+   GCC -O3 attempts to inline any function or procedure in scope.  The
+   options below facilitate fine grained control over what is and what
+   isn't made inline.  For instance it can control things down to a
+   specific modules static routines.  Doing this allows the compiler
+   to both eliminate the overhead of function calls and (as a
+   consequence) also eliminate further dead code.
+
+   On a CISC (x86) I've found that I can achieve an order of magintude
+   speed improvement (x3-x5).  In the case of RISC (sparc) while the
+   performance gain isn't as great it is still significant.
+
+   Each module is controled by the macro <module>_INLINE which can
+   have the values described below
+
+       0  Do not inline any thing for the given module
+
+   The following additional values are `bit fields' and can be
+   combined.
+
+      REVEAL_MODULE:
+
+         Include the C file for the module into the file being compiled
+         but do not make the functions within the module inline.
+
+        While of no apparent benefit, this makes it possible for the
+        included module, when compiled to inline its calls to what
+        would otherwize be external functions.
+
+      INLINE_MODULE:
+
+         Make external functions within the module `inline'.  Thus if
+         the module is included into a file being compiled, calls to
+        its funtions can be eliminated. 2 implies 1.
+
+      INLINE_LOCALS:
+
+         Make internal (static) functions within the module `inline'.
+
+   In addition to this, modules have been put into two categories.
+
+      INCLUDED_BY_MODULE
+
+         eg sim-endian.h sim-bits.h
+
+        Because these modules are small and simple and do not have
+        any complex interdendencies they are configured, if
+        <module>_INLINE is so enabled, to inline themselves in all
+        modules that include those files.
+
+        For the default build, this is a real win as all byte
+        conversion and bit manipulation functions are inlined.
+
+      !INCLUDED_BY_MODULE
+
+        Complex modules - the rest
+
+        These are all handled using the files sim-inline.h and
+        sim-inline.c.  The main simulator engine includes both of
+        these and hence includes all remaining code.
+
+   The following abreviations are available:
+
+      INCLUDE_MODULE == (REVEAL_MODULE | INLINE_MODULE)
+
+      ALL_INLINE == (REVEAL_MODULE | INLINE_MODULE | INLINE_LOCALS)
+
+      ALL_BY_MODULE = (INCLUDED_BY_MODULE | ALL_INLINE)
+
+   IMPLEMENTATION:
+
+   The inline ability is enabled by prefixing every data / function
+   declaration and definition with one of the following:
+
+
+       INLINE_<module>
+
+       Prefix to any global function that is a candidate for being
+       inline.
+
+       values - `', `static', `static INLINE'
+
+
+       EXTERN_<module>
+      
+       Prefix to any global data structures for the module.  Global
+       functions that are not to be inlined shall also be prefixed
+       with this.
+
+       values - `', `static', `static'
+
+
+       STATIC_INLINE_<module>
+
+       Prefix to any local (static) function that is a candidate for
+       being made inline.
+
+       values - `static', `static INLINE'
+
+
+       static
+
+       Prefix all local data structures.  Local functions that are not
+       to be inlined shall also be prefixed with this.
+
+       values - `static', `static'
+
+       nb: will not work for modules that are being inlined for every
+       use (white lie).
+
+
+       extern
+       #ifndef _SIM_INLINE_C_
+       #endif
+       
+       Prefix to any declaration of a global object (function or
+       variable) that should not be inlined and should have only one
+       definition.  The #ifndef wrapper goes around the definition
+       propper to ensure that only one copy is generated.
+
+       nb: this will not work when a module is being inlined for every
+       use.
+
+
+       STATIC_<module>
+
+       Replaced by either `static' or `EXTERN_MODULE'.
+
+
+   REALITY CHECK:
+
+   This is not for the faint hearted.  I've seen GCC get up to 500mb
+   trying to compile what this can create.
+
+   Some of the modules do not yet implement the WITH_INLINE_STATIC
+   option.  Instead they use the macro STATIC_INLINE to control their
+   local function.
+
+   Because of the way that GCC parses __attribute__(), the macro's
+   need to be adjacent to the functioin name rather then at the start
+   of the line vis:
+
+       int STATIC_INLINE_MODULE f(void);
+       void INLINE_MODULE *g(void);
+
+   */
+
+
+#define REVEAL_MODULE                  1
+#define INLINE_MODULE                  2
+#define INCLUDE_MODULE                 (INLINE_MODULE | REVEAL_MODULE)
+#define INLINE_LOCALS                  4
+#define ALL_INLINE                     7
+#define ALL_BY_MODULE                  (INCLUDED_BY_MODULE | ALL_INLINE)
+
+#define INCLUDED_BY_MODULE             16
+#define REGPARM_MODULE                 32
+
+
+/* Default macro to simplify control several of key the inlines */
+
+#ifndef DEFAULT_INLINE
+#define        DEFAULT_INLINE                  INLINE_LOCALS
+#endif
+
+
+
+/* Your compilers inline prefix */
+
+#ifndef INLINE
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#define INLINE __inline__
+#else
+#define INLINE /*inline*/
+#endif
+#endif
+
+
+
+/* Your compiler's static prefix */
+
+#ifndef STATIC_INLINE
+#define STATIC_INLINE static INLINE
+#endif
+
+
+
+/* Your compiler's no-return reserved word */
+
+#ifndef NORETURN
+#define NORETURN
+#endif
+
+
+
+/* Your compilers's unused reserved word */
+
+#if !defined (UNUSED)
+#if (!defined(__GNUC__) \
+     || (__GNUC__ < 2) \
+     || (__GNUC__ == 2 && __GNUC_MINOR__ < 7))
+#define UNUSED
+#else
+#define UNUSED __attribute__((__unused__))
+#endif
+#endif
+
+
+
+
+/* Your compilers nonstandard function call mechanism prefix */
+
+#if !defined REGPARM
+#if defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__))
+#if (WITH_REGPARM && WITH_STDCALL)
+#define REGPARM __attribute__((__regparm__(WITH_REGPARM),__stdcall__))
+#else
+#if (WITH_REGPARM && !WITH_STDCALL)
+#define REGPARM __attribute__((__regparm__(WITH_REGPARM)))
+#else
+#if (!WITH_REGPARM && WITH_STDCALL)
+#define REGPARM __attribute__((__stdcall__))
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if !defined REGPARM
+#define REGPARM
+#endif
+
+
+
+/* sim-bits */
+
+#if (SIM_BITS_INLINE & REGPARM_MODULE)
+# define REGPARM_SIM_BITS REGPARM
+#else
+# define REGPARM_SIM_BITS
+#endif
+
+#if (((SIM_BITS_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_SIM_BITS_C_) && (SIM_BITS_INLINE & INCLUDE_MODULE))
+# if (SIM_BITS_INLINE & INLINE_MODULE)
+#  define INLINE_SIM_BITS(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_SIM_BITS(TYPE) static TYPE UNUSED REGPARM_SIM_BITS
+# else
+#  define INLINE_SIM_BITS(TYPE) static TYPE UNUSED REGPARM_SIM_BITS
+#  define EXTERN_SIM_BITS(TYPE) static TYPE UNUSED REGPARM_SIM_BITS
+# endif
+#else
+# define INLINE_SIM_BITS(TYPE) TYPE REGPARM_SIM_BITS
+# define EXTERN_SIM_BITS(TYPE) TYPE REGPARM_SIM_BITS
+#endif
+
+#if (SIM_BITS_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_SIM_BITS(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_SIM_BITS(TYPE) static TYPE REGPARM_SIM_BITS
+#endif
+
+
+
+/* sim-core */
+
+#if (SIM_CORE_INLINE & REGPARM_MODULE)
+# define REGPARM_SIM_CORE REGPARM
+#else
+# define REGPARM_SIM_CORE
+#endif
+
+#if (((SIM_CORE_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_SIM_CORE_C_) && (SIM_CORE_INLINE & INCLUDE_MODULE))
+# if (SIM_CORE_INLINE & INLINE_MODULE)
+#  define INLINE_SIM_CORE(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_SIM_CORE(TYPE) static TYPE UNUSED REGPARM_SIM_CORE
+#else
+#  define INLINE_SIM_CORE(TYPE) static TYPE UNUSED REGPARM_SIM_CORE
+#  define EXTERN_SIM_CORE(TYPE) static TYPE UNUSED REGPARM_SIM_CORE
+#endif
+#else
+# define INLINE_SIM_CORE(TYPE) TYPE REGPARM_SIM_CORE
+# define EXTERN_SIM_CORE(TYPE) TYPE REGPARM_SIM_CORE
+#endif
+
+#if (SIM_CORE_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_SIM_CORE(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_SIM_CORE(TYPE) static TYPE REGPARM_SIM_CORE
+#endif
+
+
+
+/* sim-endian */
+
+#if (SIM_ENDIAN_INLINE & REGPARM_MODULE)
+# define REGPARM_SIM_ENDIAN REGPARM
+#else
+# define REGPARM_SIM_ENDIAN
+#endif
+
+#if (((SIM_ENDIAN_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_SIM_ENDIAN_C_) && (SIM_ENDIAN_INLINE & INCLUDE_MODULE))
+# if (SIM_ENDIAN_INLINE & INLINE_MODULE)
+#  define INLINE_SIM_ENDIAN(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_SIM_ENDIAN(TYPE) static TYPE UNUSED REGPARM_SIM_ENDIAN
+# else
+#  define INLINE_SIM_ENDIAN(TYPE) static TYPE UNUSED REGPARM_SIM_ENDIAN
+#  define EXTERN_SIM_ENDIAN(TYPE) static TYPE UNUSED REGPARM_SIM_ENDIAN
+# endif
+#else
+# define INLINE_SIM_ENDIAN(TYPE) TYPE REGPARM_SIM_ENDIAN
+# define EXTERN_SIM_ENDIAN(TYPE) TYPE REGPARM_SIM_ENDIAN
+#endif
+
+#if (SIM_ENDIAN_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_SIM_ENDIAN(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_SIM_ENDIAN(TYPE) static TYPE REGPARM_SIM_ENDIAN
+#endif
+
+
+
+/* sim-events */
+
+#if (SIM_EVENTS_INLINE & REGPARM_MODULE)
+# define REGPARM_SIM_EVENTS REGPARM
+#else
+# define REGPARM_SIM_EVENTS
+#endif
+
+#if (((SIM_EVENTS_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_SIM_EVENTS_C_) && (SIM_EVENTS_INLINE & INCLUDE_MODULE))
+# if (SIM_EVENTS_INLINE & INLINE_MODULE)
+#  define INLINE_SIM_EVENTS(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_SIM_EVENTS(TYPE) static TYPE UNUSED REGPARM_SIM_EVENTS
+# else
+#  define INLINE_SIM_EVENTS(TYPE) static TYPE UNUSED REGPARM_SIM_EVENTS
+#  define EXTERN_SIM_EVENTS(TYPE) static TYPE UNUSED REGPARM_SIM_EVENTS
+# endif
+#else
+# define INLINE_SIM_EVENTS(TYPE) TYPE REGPARM_SIM_EVENTS
+# define EXTERN_SIM_EVENTS(TYPE) TYPE REGPARM_SIM_EVENTS
+#endif
+
+#if (SIM_EVENTS_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_SIM_EVENTS(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_SIM_EVENTS(TYPE) static TYPE REGPARM_SIM_EVENTS
+#endif
+
+
+
+/* sim-fpu */
+
+#if (SIM_FPU_INLINE & REGPARM_MODULE)
+# define REGPARM_SIM_FPU REGPARM
+#else
+# define REGPARM_SIM_FPU
+#endif
+
+#if (((SIM_FPU_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_SIM_FPU_C_) && (SIM_FPU_INLINE & INCLUDE_MODULE))
+# if (SIM_FPU_INLINE & INLINE_MODULE)
+#  define INLINE_SIM_FPU(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_SIM_FPU(TYPE) static TYPE UNUSED REGPARM_SIM_FPU
+# else
+#  define INLINE_SIM_FPU(TYPE) static TYPE UNUSED REGPARM_SIM_FPU
+#  define EXTERN_SIM_FPU(TYPE) static TYPE UNUSED REGPARM_SIM_FPU
+# endif
+#else
+# define INLINE_SIM_FPU(TYPE) TYPE REGPARM_SIM_FPU
+# define EXTERN_SIM_FPU(TYPE) TYPE REGPARM_SIM_FPU
+#endif
+
+#if (SIM_FPU_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_SIM_FPU(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_SIM_FPU(TYPE) static TYPE REGPARM_SIM_FPU
+#endif
+
+
+
+/* sim-types */
+
+#if (SIM_TYPES_INLINE & REGPARM_MODULE)
+# define REGPARM_SIM_TYPES REGPARM
+#else
+# define REGPARM_SIM_TYPES
+#endif
+
+#if (((SIM_TYPES_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_SIM_TYPES_C_) && (SIM_TYPES_INLINE & INCLUDE_MODULE))
+# if (SIM_TYPES_INLINE & INLINE_MODULE)
+#  define INLINE_SIM_TYPES(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_SIM_TYPES(TYPE) static TYPE UNUSED REGPARM_SIM_TYPES
+# else
+#  define INLINE_SIM_TYPES(TYPE) static TYPE UNUSED REGPARM_SIM_TYPES
+#  define EXTERN_SIM_TYPES(TYPE) static TYPE UNUSED REGPARM_SIM_TYPES
+# endif
+#else
+# define INLINE_SIM_TYPES(TYPE) TYPE REGPARM_SIM_TYPES
+# define EXTERN_SIM_TYPES(TYPE) TYPE REGPARM_SIM_TYPES
+#endif
+
+#if (SIM_TYPES_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_SIM_TYPES(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_SIM_TYPES(TYPE) static TYPE REGPARM_SIM_TYPES
+#endif
+
+
+
+/* icache */
+
+#if (ICACHE_INLINE & REGPARM_MODULE)
+# define REGPARM_ICACHE REGPARM
+#else
+# define REGPARM_ICACHE
+#endif
+
+#if (((ICACHE_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_ICACHE_C_) && (ICACHE_INLINE & INCLUDE_MODULE))
+# if (ICACHE_INLINE & INLINE_MODULE)
+#  define INLINE_ICACHE(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_ICACHE(TYPE) static TYPE UNUSED REGPARM_ICACHE
+#else
+#  define INLINE_ICACHE(TYPE) static TYPE UNUSED REGPARM_ICACHE
+#  define EXTERN_ICACHE(TYPE) static TYPE UNUSED REGPARM_ICACHE
+#endif
+#else
+# define INLINE_ICACHE(TYPE) TYPE REGPARM_ICACHE
+# define EXTERN_ICACHE(TYPE) TYPE REGPARM_ICACHE
+#endif
+
+#if (ICACHE_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_ICACHE(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_ICACHE(TYPE) static TYPE REGPARM_ICACHE
+#endif
+
+
+
+/* idecode */
+
+#if (IDECODE_INLINE & REGPARM_MODULE)
+# define REGPARM_IDECODE REGPARM
+#else
+# define REGPARM_IDECODE
+#endif
+
+#if (((IDECODE_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_IDECODE_C_) && (IDECODE_INLINE & INCLUDE_MODULE))
+# if (IDECODE_INLINE & INLINE_MODULE)
+#  define INLINE_IDECODE(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_IDECODE(TYPE) static TYPE UNUSED REGPARM_IDECODE
+#else
+#  define INLINE_IDECODE(TYPE) static TYPE UNUSED REGPARM_IDECODE
+#  define EXTERN_IDECODE(TYPE) static TYPE UNUSED REGPARM_IDECODE
+#endif
+#else
+# define INLINE_IDECODE(TYPE) TYPE REGPARM_IDECODE
+# define EXTERN_IDECODE(TYPE) TYPE REGPARM_IDECODE
+#endif
+
+#if (IDECODE_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_IDECODE(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_IDECODE(TYPE) static TYPE REGPARM_IDECODE
+#endif
+
+
+
+/* semantics */
+
+#if (SEMANTICS_INLINE & REGPARM_MODULE)
+# define REGPARM_SEMANTICS REGPARM
+#else
+# define REGPARM_SEMANTICS
+#endif
+
+#if (((SEMANTICS_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_SEMANTICS_C_) && (SEMANTICS_INLINE & INCLUDE_MODULE))
+# if (SEMANTICS_INLINE & INLINE_MODULE)
+#  define INLINE_SEMANTICS(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_SEMANTICS(TYPE) static TYPE UNUSED REGPARM_SEMANTICS
+#else
+#  define INLINE_SEMANTICS(TYPE) static TYPE UNUSED REGPARM_SEMANTICS
+#  define EXTERN_SEMANTICS(TYPE) static TYPE UNUSED REGPARM_SEMANTICS
+#endif
+#else
+# define INLINE_SEMANTICS(TYPE) TYPE REGPARM_SEMANTICS
+# define EXTERN_SEMANTICS(TYPE) TYPE REGPARM_SEMANTICS
+#endif
+
+#if (SEMANTICS_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_SEMANTICS(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_SEMANTICS(TYPE) static TYPE REGPARM_SEMANTICS
+#endif
+
+
+
+/* support */
+
+#if (SUPPORT_INLINE & REGPARM_MODULE)
+# define REGPARM_SUPPORT REGPARM
+#else
+# define REGPARM_SUPPORT
+#endif
+
+#if (((SUPPORT_INLINE & INCLUDED_BY_MODULE) || defined(_SIM_INLINE_C_)) \
+     && !defined(_SUPPORT_C_) && (SUPPORT_INLINE & INCLUDE_MODULE))
+# if (SUPPORT_INLINE & INLINE_MODULE)
+#  define INLINE_SUPPORT(TYPE) static INLINE TYPE UNUSED
+#  define EXTERN_SUPPORT(TYPE) static TYPE UNUSED REGPARM_SUPPORT
+#else
+#  define INLINE_SUPPORT(TYPE) static TYPE UNUSED REGPARM_SUPPORT
+#  define EXTERN_SUPPORT(TYPE) static TYPE UNUSED REGPARM_SUPPORT
+#endif
+#else
+# define INLINE_SUPPORT(TYPE) TYPE REGPARM_SUPPORT
+# define EXTERN_SUPPORT(TYPE) TYPE REGPARM_SUPPORT
+#endif
+
+#if (SUPPORT_INLINE & INLINE_LOCALS)
+# define STATIC_INLINE_SUPPORT(TYPE) static INLINE TYPE
+#else
+# define STATIC_INLINE_SUPPORT(TYPE) static TYPE REGPARM_SUPPORT
+#endif
+
+
+
+#endif
index ffdaf32..b4f7704 100644 (file)
@@ -20,11 +20,236 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "sim-main.h"
 #include "sim-io.h"
+#include "sim-options.h"
 
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
+static MODULE_UNINSTALL_FN trace_uninstall;
+
+static DECLARE_OPTION_HANDLER (trace_option_handler);
+
+#define OPTION_TRACE_INSN      (OPTION_START + 0)
+#define OPTION_TRACE_DECODE    (OPTION_START + 1)
+#define OPTION_TRACE_EXTRACT   (OPTION_START + 2)
+#define OPTION_TRACE_LINENUM   (OPTION_START + 3)
+#define OPTION_TRACE_MEMORY    (OPTION_START + 4)
+#define OPTION_TRACE_MODEL     (OPTION_START + 5)
+#define OPTION_TRACE_ALU       (OPTION_START + 6)
+#define OPTION_TRACE_CORE      (OPTION_START + 7)
+#define OPTION_TRACE_EVENTS    (OPTION_START + 8)
+#define OPTION_TRACE_FPU       (OPTION_START + 9)
+#define OPTION_TRACE_FILE      (OPTION_START + 10)
+
+static const OPTION trace_options[] =
+{
+  { {"trace", no_argument, NULL, 't'},
+      't', NULL, "Perform tracing",
+      trace_option_handler },
+  { {"trace-insn", no_argument, NULL, OPTION_TRACE_INSN},
+      '\0', NULL, "Perform instruction tracing",
+      trace_option_handler },
+  { {"trace-decode", no_argument, NULL, OPTION_TRACE_DECODE},
+      '\0', NULL, "Perform instruction decoding tracing",
+      trace_option_handler },
+  { {"trace-extract", no_argument, NULL, OPTION_TRACE_EXTRACT},
+      '\0', NULL, "Perform instruction extraction tracing",
+      trace_option_handler },
+  { {"trace-linenum", no_argument, NULL, OPTION_TRACE_LINENUM},
+      '\0', NULL, "Perform line number tracing",
+      trace_option_handler },
+  { {"trace-memory", no_argument, NULL, OPTION_TRACE_MEMORY},
+      '\0', NULL, "Perform memory tracing",
+      trace_option_handler },
+  { {"trace-model", no_argument, NULL, OPTION_TRACE_MODEL},
+      '\0', NULL, "Perform model tracing",
+      trace_option_handler },
+  { {"trace-alu", no_argument, NULL, OPTION_TRACE_ALU},
+      '\0', NULL, "Perform ALU tracing",
+      trace_option_handler },
+  { {"trace-core", no_argument, NULL, OPTION_TRACE_CORE},
+      '\0', NULL, "Perform CORE tracing",
+      trace_option_handler },
+  { {"trace-events", no_argument, NULL, OPTION_TRACE_EVENTS},
+      '\0', NULL, "Perform EVENTS tracing",
+      trace_option_handler },
+  { {"trace-fpu", no_argument, NULL, OPTION_TRACE_FPU},
+      '\0', NULL, "Perform FPU tracing",
+      trace_option_handler },
+  { {"trace-file", required_argument, NULL, OPTION_TRACE_FILE},
+      '\0', "FILE NAME", "Specify tracing output file",
+      trace_option_handler },
+  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
+};
+
+static SIM_RC
+trace_option_handler (sd, opt, arg)
+     SIM_DESC sd;
+     int opt;
+     char *arg;
+{
+  int i,n;
+
+  switch (opt)
+    {
+    case 't' :
+      if (! WITH_TRACE)
+       sim_io_eprintf (sd, "Tracing not compiled in, `-t' ignored\n");
+      else
+       {
+         for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+           for (i = 0; i < MAX_TRACE_VALUES; ++i)
+             CPU_TRACE_FLAGS (STATE_CPU (sd, n))[i] = 1;
+         STATE_CORE(sd)->trace = 1;
+         STATE_EVENTS(sd)->trace = 1;
+       }
+      break;
+
+    case OPTION_TRACE_INSN :
+      if (WITH_TRACE_INSN_P)
+       for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+         CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_INSN_IDX] = 1;
+      else
+       sim_io_eprintf (sd, "Instruction tracing not compiled in, `--trace-insn' ignored\n");
+      break;
+
+    case OPTION_TRACE_DECODE :
+      if (WITH_TRACE_DECODE_P)
+       for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+         CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_DECODE_IDX] = 1;
+      else
+       sim_io_eprintf (sd, "Decode tracing not compiled in, `--trace-decode' ignored\n");
+      break;
+
+    case OPTION_TRACE_EXTRACT :
+      if (WITH_TRACE_EXTRACT_P)
+       for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+         CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_EXTRACT_IDX] = 1;
+      else
+       sim_io_eprintf (sd, "Extract tracing not compiled in, `--trace-extract' ignored\n");
+      break;
+
+    case OPTION_TRACE_LINENUM :
+      if (WITH_TRACE_LINENUM_P)
+       for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+         CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_LINENUM_IDX] = 1;
+      else
+       sim_io_eprintf (sd, "Line number tracing not compiled in, `--trace-linenum' ignored\n");
+      break;
+
+    case OPTION_TRACE_MEMORY :
+      if (WITH_TRACE_MEMORY_P)
+       for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+         CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_MEMORY_IDX] = 1;
+      else
+       sim_io_eprintf (sd, "Memory tracing not compiled in, `--trace-memory' ignored\n");
+      break;
+
+    case OPTION_TRACE_MODEL :
+      if (WITH_TRACE_MODEL_P)
+       for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+         CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_MODEL_IDX] = 1;
+      else
+       sim_io_eprintf (sd, "Model tracing not compiled in, `--trace-model' ignored\n");
+      break;
+
+    case OPTION_TRACE_ALU :
+      if (WITH_TRACE_ALU_P)
+       for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+         CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_ALU_IDX] = 1;
+      else
+       sim_io_eprintf (sd, "ALU tracing not compiled in, `--trace-alu' ignored\n");
+      break;
+
+    case OPTION_TRACE_CORE :
+      if (WITH_TRACE_CORE_P)
+       {
+         for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+           CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_CORE_IDX] = 1;
+         STATE_CORE(sd)->trace = 1;
+       }
+      else
+       sim_io_eprintf (sd, "CORE tracing not compiled in, `--trace-core' ignored\n");
+      break;
+
+    case OPTION_TRACE_EVENTS :
+      if (WITH_TRACE_EVENTS_P)
+       {
+         for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+           CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_EVENTS_IDX] = 1;
+         STATE_EVENTS(sd)->trace = 1;
+       }
+      else
+       sim_io_eprintf (sd, "EVENTS tracing not compiled in, `--trace-events' ignored\n");
+      break;
+
+    case OPTION_TRACE_FPU :
+      if (WITH_TRACE_FPU_P)
+       for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+         CPU_TRACE_FLAGS (STATE_CPU (sd, n))[TRACE_FPU_IDX] = 1;
+      else
+       sim_io_eprintf (sd, "FPU tracing not compiled in, `--trace-fpu' ignored\n");
+      break;
+
+    case OPTION_TRACE_FILE :
+      if (! WITH_TRACE)
+       sim_io_eprintf (sd, "Tracing not compiled in, `--trace-file' ignored\n");
+      else
+       {
+         FILE *f = fopen (arg, "w");
+
+         if (f == NULL)
+           {
+             sim_io_eprintf (sd, "Unable to open trace output file `%s'\n", arg);
+             return SIM_RC_FAIL;
+           }
+         for (n = 0; n < MAX_NR_PROCESSORS; ++n)
+           TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd, n))) = f;
+       }
+      break;
+    }
+
+  return SIM_RC_OK;
+}
+\f
+/* Install tracing support.  */
+
+SIM_RC
+trace_install (SIM_DESC sd)
+{
+  int i;
+
+  sim_add_option_table (sd, trace_options);
+  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+    memset (CPU_TRACE_DATA (STATE_CPU (sd, i)), 0,
+           sizeof (* CPU_TRACE_DATA (STATE_CPU (sd, i))));
+  sim_module_add_uninstall_fn (sd, trace_uninstall);
+  return SIM_RC_OK;
+}
+
+static void
+trace_uninstall (SIM_DESC sd)
+{
+  int i;
+
+  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+    {
+      TRACE_DATA *data = CPU_TRACE_DATA (STATE_CPU (sd, i));
+      if (TRACE_FILE (data) != NULL)
+       fclose (TRACE_FILE (data));
+    }
+}
+\f
 void
-trace_printf VPARAMS ((sim_cpu *cpu, const char *fmt, ...))
+trace_printf VPARAMS ((SIM_DESC sd, sim_cpu *cpu, const char *fmt, ...))
 {
 #ifndef __STDC__
+  SIM_DESC sd;
   sim_cpu *cpu;
   const char *fmt;
 #endif
@@ -32,15 +257,15 @@ trace_printf VPARAMS ((sim_cpu *cpu, const char *fmt, ...))
 
   VA_START (ap, fmt);
 #ifndef __STDC__
+  sd = va_arg (ap, SIM_DESC);
   cpu = va_arg (ap, sim_cpu *);
   fmt = va_arg (ap, const char *);
 #endif
 
-  if (CPU_TRACE_FILE (cpu) == NULL)
-    (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
-      (STATE_CALLBACK (CPU_STATE (cpu)), fmt, ap);
+  if (cpu != NULL && TRACE_FILE (CPU_TRACE_DATA (cpu)) != NULL)
+    vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, ap);
   else
-    vfprintf (CPU_TRACE_FILE (cpu), fmt, ap);
+    sim_io_evprintf (sd, fmt, ap);
 
   va_end (ap);
 }
index ff28a6b..2a98808 100644 (file)
@@ -23,6 +23,71 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef SIM_TRACE_H
 #define SIM_TRACE_H
 
+/* Maximum number of traceable entities.  */
+#ifndef MAX_TRACE_VALUES
+#define MAX_TRACE_VALUES 12
+#endif
+
+/* Standard traceable entities.  */
+#define TRACE_INSN_IDX 0
+#define TRACE_DECODE_IDX 1
+#define TRACE_EXTRACT_IDX 2
+#define TRACE_LINENUM_IDX 3
+#define TRACE_MEMORY_IDX 4
+#define TRACE_MODEL_IDX 5
+#define TRACE_ALU_IDX 6
+#define TRACE_CORE_IDX 7
+#define TRACE_EVENTS_IDX 8
+#define TRACE_FPU_IDX 9
+#define TRACE_NEXT_IDX 16 /* simulator specific trace bits begin here */
+
+/* Masks so WITH_TRACE can have symbolic values.  */
+#define TRACE_insn 1
+#define TRACE_decode 2
+#define TRACE_extract 4
+#define TRACE_linenum 8
+#define TRACE_memory 16
+#define TRACE_model 32
+#define TRACE_alu 64
+#define TRACE_core 128
+#define TRACE_events 256
+#define TRACE_fpu 512
+
+/* Preprocessor macros to simplify tests of WITH_TRACE.  */
+#define WITH_TRACE_INSN_P (WITH_TRACE & TRACE_insn)
+#define WITH_TRACE_DECODE_P (WITH_TRACE & TRACE_decode)
+#define WITH_TRACE_EXTRACT_P (WITH_TRACE & TRACE_extract)
+#define WITH_TRACE_LINENUM_P (WITH_TRACE & TRACE_linenum)
+#define WITH_TRACE_MEMORY_P (WITH_TRACE & TRACE_memory)
+#define WITH_TRACE_MODEL_P (WITH_TRACE & TRACE_model)
+#define WITH_TRACE_ALU_P (WITH_TRACE & TRACE_alu)
+#define WITH_TRACE_CORE_P (WITH_TRACE & TRACE_core)
+#define WITH_TRACE_EVENTS_P (WITH_TRACE & TRACE_events)
+#define WITH_TRACE_FPU_P (WITH_TRACE & TRACE_fpu)
+
+/* Tracing install handler.  */
+MODULE_INSTALL_FN trace_install;
+\f
+/* Struct containing all trace data.  */
+
+typedef struct {
+  /* Boolean array of specified tracing flags.  */
+  /* ??? It's not clear that using an array vs a bit mask is faster.
+     Consider the case where one wants to test whether any of several bits
+     are set.  */
+  char trace_flags[MAX_TRACE_VALUES];
+#define TRACE_FLAGS(t) ((t)->trace_flags)
+
+  /* Tracing output goes to this or stderr if NULL.
+     We can't store `stderr' here as stderr goes through a callback.  */
+  FILE *trace_file;
+#define TRACE_FILE(t) ((t)->trace_file)
+} TRACE_DATA;
+\f
+/* Usage macros.  */
+
+#define CPU_TRACE_FLAGS(cpu) TRACE_FLAGS (CPU_TRACE_DATA (cpu))
+
 /* forward reference */
 struct _sim_cpu;
 
@@ -37,10 +102,14 @@ struct _sim_cpu;
 #define TRACE_INSN_P(cpu) TRACE_P (cpu, TRACE_INSN_IDX)
 /* Non-zero if "--trace-decode" specified for CPU.  */
 #define TRACE_DECODE_P(cpu) TRACE_P (cpu, TRACE_DECODE_IDX)
+/* Non-zero if "--trace-fpu" specified for CPU. */
+#define TRACE_FPU_P(cpu) TRACE_P (cpu, TRACE_FPU_IDX)
 
-extern void trace_printf PARAMS ((struct _sim_cpu *, const char *, ...));
+extern void trace_printf PARAMS ((SIM_DESC, sim_cpu *, const char *, ...));
 
-/* Debug support.  */
+/* Debug support.
+   This is included here because there isn't enough of it to justify
+   a sim-debug.h.  */
 
 /* Return non-zero if debugging of IDX for CPU is enabled.  */
 #define DEBUG_P(cpu, idx) \
index 558b4e5..3fbbadd 100644 (file)
@@ -38,6 +38,7 @@ configure.in
 Things-to-lose:
 
 common
+tic80-coff
 
 Do-last:
 
index 99ea871..5aebb29 100644 (file)
@@ -1,3 +1,16 @@
+Mon May  5 14:10:17 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * insn (cmnd): No-op cache flushes.
+       
+       * insns (do_trap): Allow writes to STDERR.
+
+       * Makefile.in (SIM_OBJS): Link in sim-fpu.o.
+       (SIM_EXTRA_LIBS): Link in the math library.
+
+       * alu.h: Add support for floating point unit using sim-alu.
+       
+       * insns (fadd, fsub, fmpy, fdiv, fcmp, frnd*): Implement.
+
 Fri May  2 14:57:14 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * sim-calls.c: Include sim-utils.h and sim-options.h.
index 3391a79..21be037 100644 (file)
@@ -21,12 +21,16 @@ SIM_OBJS = sim-endian.o sim-bits.o sim-config.o interp.o \
        sim-module.o \
        sim-options.o \
        sim-trace.o \
-       sim-profile.o
+       sim-profile.o \
+       sim-fpu.o
 
 # List of extra dependencies.
 # Generally this consists of simulator specific files included by sim-main.h.
 SIM_EXTRA_DEPS = itable.h idecode.h cpu.h alu.h
 
+# List of extra libraries to link with
+SIM_EXTRA_LIBS = -lm
+
 # List of generators
 SIM_GEN=tmp-igen
 
@@ -36,6 +40,7 @@ SIM_ENDIAN=@sim_endian@
 SIM_HOSTENDIAN=@sim_hostendian@
 SIM_INLINE=@sim_inline@
 SIM_RESERVED_BITS=@sim_reserved_bits@
+SIM_ALIGNMENT=@sim_alignment@
 
 SIM_EXTRA_CFLAGS = \
        $(SIM_WARNINGS) \
index 7312f60..3a325e1 100644 (file)
@@ -1,10 +1,30 @@
+/* Texas Instruments TMS320C80 (MVP) Simulator.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+This file is part of GDB, the GNU debugger.
+
+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, 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.  */
+
+
+
 #ifndef _TIC80_ALU_H_
 #define _TIC80_ALU_H_
 
 #define ALU_CARRY 0 /* FIXME */
 
-#include "sim-alu.h"
-
 #define ALU32_END(TARG) \
 { \
   (TARG) = (unsigned32)alu_carry_val; /* FIXME */ \
@@ -12,6 +32,9 @@
 
 #define ALU_END(TARG) ALU32_END(TARG)
 
+#include "sim-alu.h"
+
+
 
 /* Bring data in from the cold */
 
@@ -37,4 +60,11 @@ do { \
      nia.ip += sizeof (instruction_word); \
      nia.dp += sizeof (instruction_word);
 
+
+
+/* Floating point support */
+
+#include "sim-fpu.h"
+
+
 #endif
index 9e81980..9133632 100644 (file)
@@ -29,3 +29,8 @@ struct _sim_cpu {
 
 #define GPR(N) ((CPU)->reg[N])
 #define ACC(N) ((CPU)->acc[N])
+
+#define SP_FPR(N) (GPR(N))
+#define DP_FPR(N) (*(unsigned64*)&GPR(N))
+#define vSP_FPR(N) (N == 0 ? (unsigned32)0 : GPR(N))
+#define vDP_FPR(N) (*(unsigned64*)&GPR(N))
index 71a0e8f..35cfbf3 100644 (file)
@@ -1,3 +1,24 @@
+// Texas Instruments TMS320C80 (MVP) Simulator.
+// Copyright (C) 1997 Free Software Foundation, Inc.
+// Contributed by Cygnus Support.
+// 
+// This file is part of GDB, the GNU debugger.
+// 
+// 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, 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.  */
+
+
 // The following is called when ever an illegal instruction is
 // encountered
 ::internal::illegal
@@ -185,10 +206,50 @@ instruction_address::function::do_bsr:instruction_address nia, signed32 *rLink,
 
 
 // cmnd
+void::function::do_cmnd:signed32 source
+       int Reset = EXTRACTED32 (source, 31, 31);
+       int Halt = EXTRACTED32 (source, 30, 30);
+       int Unhalt = EXTRACTED32 (source, 29, 29);
+       /* int ICR = EXTRACTED32 (source, 28, 28); */
+       /* int DCR = EXTRACTED32 (source, 27, 27); */
+       int Task = EXTRACTED32 (source, 14, 14);
+       int Msg = EXTRACTED32 (source, 13, 13);
+       int VC = EXTRACTED32 (source, 10, 10);
+       int TC = EXTRACTED32 (source, 9, 9);
+       int MP = EXTRACTED32 (source, 8, 8);
+       int PP = EXTRACTED32 (source, 3, 0);
+       /* what is implemented? */
+       if (PP != 0)
+         engine_error (SD, CPU, cia, "0x%lx: cmnd - PPs not supported",
+                       (unsigned long) cia.ip);
+       if (VC != 0)
+         engine_error (SD, CPU, cia, "0x%lx: cmnd - VC not supported",
+                       (unsigned long) cia.ip);
+       if (TC != 0)
+         engine_error (SD, CPU, cia, "0x%lx: cmnd - TC not supported",
+                       (unsigned long) cia.ip);
+       if (MP)
+         {
+           if (Reset || Halt)
+             engine_halt (SD, CPU, cia, sim_exited, 0);
+           if (Unhalt)
+             engine_error (SD, CPU, cia, "0x%lx: cmnd - Can not unhalt the MP",
+                           (unsigned long) cia.ip);
+           /* if (ICR || DCR); */
+           if (Task)
+             engine_error (SD, CPU, cia, "0x%lx: cmnd - Can not Task the MP",
+                           (unsigned long) cia.ip);
+           if (Msg)
+             engine_error (SD, CPU, cia, "0x%lx: cmnd - Msg to MP not suported",
+                           (unsigned long) cia.ip);
+         }
 31./,21.0b0000010,14.UI::::cmnd i
-31./,21.0b110000010,12.0,11./,4.Source1::::cmnd r
+       do_cmnd (_SD, UI);
+31./,21.0b110000010,12.0,11./,4.Source::::cmnd r
+       do_cmnd (_SD, rSource);
 31./,21.0b110000010,12.1,11./::::cmnd l
-
+       long_immediate (LongUnsignedImmediate);
+       do_cmnd (_SD, LongUnsignedImmediate);
 
 // cmp
 unsigned32::function::cmp_vals:signed32 s1, unsigned32 u1, signed32 s2, unsigned32 u2
@@ -281,76 +342,208 @@ void::function::do_dst:int Source, unsigned32 Base, unsigned32 *rBase, int m , i
 // extu - see shift.dz
 
 
+sim_fpu::function::get_fp_reg:int reg, unsigned32 val, int precision
+       switch (precision)
+         {
+         case 0: /* single */
+           if (reg == 0)
+             return sim_fpu_32to (0);
+           else
+             return sim_fpu_32to (val);
+         case 1: /* double */
+           if (reg < 0)
+             return sim_fpu_32to (val);
+           if (reg & 1)
+             engine_error (SD, CPU, cia, "DP FP register must be even");
+           if (reg <= 1)
+             engine_error (SD, CPU, cia, "DP FP register must be >= 2");
+           return sim_fpu_64to (INSERTED64 (GPR(reg + 1), 63, 32)
+                                | INSERTED64 (GPR(reg), 31, 0));
+         case 2: /* 32 bit signed integer */
+           if (reg == 0)
+             return sim_fpu_32to (0);
+           else            
+             return sim_fpu_d2 ((signed32) val);
+         case 3: /* 32 bit unsigned integer */
+           if (reg == 0)
+             return sim_fpu_32to (0);
+           else            
+             return sim_fpu_d2 ((unsigned32) val);
+         default:
+           engine_error (SD, CPU, cia, "Unsupported FP precision");
+         }
+       return sim_fpu_32to (0);
+void::function::set_fp_reg:int Dest, sim_fpu val, int PD
+       switch (PD)
+         {
+         case 0: /* single */
+           {
+             GPR (Dest) = sim_fpu_to32 (val);
+             break;
+           }
+         case 1: /* double */
+           {
+             unsigned64 v = *(unsigned64*) &val;
+             if (Dest & 1)
+               engine_error (SD, CPU, cia, "DP FP Dest register must be even");
+             if (Dest <= 1)
+               engine_error (SD, CPU, cia, "DP FP Dest register must be >= 2");
+             GPR (Dest) = EXTRACTED64 (v, 21, 0);
+             GPR (Dest + 1) = EXTRACTED64 (v, 63, 32);
+             break;
+           }
+         case 2: /* signed */
+           /* FIXME - rounding */
+           GPR (Dest) = sim_fpu_2d (val);
+           break;
+         case 3: /* unsigned */
+           /* FIXME - rounding */
+           GPR (Dest) = sim_fpu_2d (val);
+           break;
+         default:
+           engine_error (SD, CPU, cia, "Unsupported FP precision");
+         }
+
 // fadd.{s|d}{s|d}{s|d}
-#void::function::do_fadd:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2
-#      sim_io_error ("fadd");
+void::function::do_fadd:int Dest, int PD, sim_fpu s1, sim_fpu s2
+       sim_fpu ans = sim_fpu_add (s1, s2);
+       if (TRACE_FPU_P(CPU))
+         trace_printf (SD, CPU, "0x%lx: fadd - %f + %f = %f\n",
+                       (unsigned long) cia.ip,
+                       sim_fpu_2d (s1), sim_fpu_2d (s2),
+                       sim_fpu_2d (ans));
+       set_fp_reg (_SD, Dest, ans, PD);
 31.Dest,26.Source2,21.0b111110000,12.0,11.r,10.PD,8.P2,6.P1,4.Source1::::fadd r
-#      do_fadd (_SD, rDest, rSource1, rSource2);
+       do_fadd (_SD, Dest, PD,
+                get_fp_reg (_SD, Source1, rSource1, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
 31.Dest,26.Source2,21.0b111110000,12.1,11.r,10.PD,8.P2,6.P1,4./::::fadd l
-#      do_fadd (_SD, rDest, LongSignedImmediate, rSource2);
+       long_immediate (SinglePrecisionFloatingPoint);
+       do_fadd (_SD, Dest, PD,
+                get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
 
 
 // fcmp.{s|d}{s|d}{s|d}
-#void::function::do_fcmp:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2
-#      sim_io_error ("fcmp");
+void::function::do_fcmp:unsigned32 *rDest, sim_fpu s1, sim_fpu s2
+       *rDest = 0;
+       if (sim_fpu_is_nan (s1) || sim_fpu_is_nan (s2))
+         *rDest |= BIT32 (30);
+       else
+         {
+           *rDest |= BIT32 (31);
+           if (sim_fpu_cmp (s1, s2) == 0) *rDest |= BIT32(20);
+           if (sim_fpu_cmp (s1, s2) != 0) *rDest |= BIT32(21);
+           if (sim_fpu_cmp (s1, s2) >  0) *rDest |= BIT32(22);
+           if (sim_fpu_cmp (s1, s2) <= 0) *rDest |= BIT32(23);
+           if (sim_fpu_cmp (s1, s2) <  0) *rDest |= BIT32(24);
+           if (sim_fpu_cmp (s1, s2) >= 0) *rDest |= BIT32(25);
+           if (sim_fpu_cmp (s1, sim_fpu_32to (0)) < 0
+               || sim_fpu_cmp (s1, s2) > 0) *rDest |= BIT32(26);
+           if (sim_fpu_cmp (sim_fpu_32to (0), s1) < 0
+               && sim_fpu_cmp (s1, s2) < 0) *rDest |= BIT32(27);
+           if (sim_fpu_cmp (sim_fpu_32to (0), s1) <= 0
+               && sim_fpu_cmp (s1, s2) <= 0) *rDest |= BIT32(28);
+           if (sim_fpu_cmp (s1, sim_fpu_32to (0)) <= 0
+               || sim_fpu_cmp (s1, s2) >= 0) *rDest |= BIT32(29);
+         }
+       if (TRACE_FPU_P (CPU))
+         trace_printf (SD, CPU, "0x%lx: fcmp - %f >=< %f - 0x%08x\n",
+                       (unsigned long) cia.ip,
+                       sim_fpu_2d (s1), sim_fpu_2d (s2),
+                       (unsigned long) *rDest);
 31.Dest,26.Source2,21.0b111110101,12.0,11./,10.0,8.P2,6.P1,4.Source1::::fcmp r
-#      do_fcmp (_SD, rDest, rSource1, rSource2);
+       do_fcmp (_SD, rDest,
+                get_fp_reg (_SD, Source1, rSource1, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
 31.Dest,26.Source2,21.0b111110101,12.1,11./,10.0,8.P2,6.P1,4./::::fcmp l
-#      do_fcmp (_SD, rDest, LongSignedImmediate, rSource2);
+       long_immediate (SinglePrecisionFloatingPoint);
+       do_fcmp (_SD, rDest,
+                get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
+
 
 
 // fdiv.{s|d}{s|d}{s|d}
-#void::function::do_fdiv:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2
-#      sim_io_error ("fdiv");
+void::function::do_fdiv:int Dest, int PD, sim_fpu s1, sim_fpu s2
+       sim_fpu ans = sim_fpu_div (s1, s2);
+       if (TRACE_FPU_P(CPU))
+         trace_printf (SD, CPU, "0x%lx: fdiv - %f / %f = %f\n",
+                       (unsigned long) cia.ip,
+                       sim_fpu_2d (s1), sim_fpu_2d (s2),
+                       sim_fpu_2d (ans));
+       set_fp_reg (_SD, Dest, ans, PD);
 31.Dest,26.Source2,21.0b111110011,12.0,11./,10.PD,8.P2,6.P1,4.Source1::::fdiv r
-#      do_fdiv (_SD, rDest, rSource1, rSource2);
+       do_fdiv (_SD, Dest, PD,
+                get_fp_reg (_SD, Source1, rSource1, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
 31.Dest,26.Source2,21.0b111110011,12.1,11./,10.PD,8.P2,6.P1,4./::::fdiv l
-#      do_fdiv (_SD, rDest, LongSignedImmediate, rSource2);
+       long_immediate (SinglePrecisionFloatingPoint);
+       do_fdiv (_SD, Dest, PD,
+                get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
 
 
 // fmpy.{s|d|i|u}{s|d|i|u}{s|d|i|u}
-#void::function::do_fmpy:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2
-#      sim_io_error ("fmpy");
+void::function::do_fmpy:int Dest, int PD, sim_fpu s1, sim_fpu s2
+       sim_fpu ans = sim_fpu_mul (s1, s2);
+       if (TRACE_FPU_P(CPU))
+         trace_printf (SD, CPU, "0x%lx: fmpy - %f * %f = %f\n",
+                       (unsigned long) cia.ip,
+                       sim_fpu_2d (s1), sim_fpu_2d (s2),
+                       sim_fpu_2d (ans));
+       set_fp_reg (_SD, Dest, ans, PD);
 31.Dest,26.Source2,21.0b111110010,12.0,11./,10.PD,8.P2,6.P1,4.Source1::::fmpy r
-#      do_fmpy (_SD, rDest, rSource1, rSource2);
+       do_fmpy (_SD, Dest, PD,
+                get_fp_reg (_SD, Source1, rSource1, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
 31.Dest,26.Source2,21.0b111110010,12.1,11./,10.PD,8.P2,6.P1,4./::::fmpy l
-#      do_fmpy (_SD, rDest, LongSignedImmediate, rSource2);
+       long_immediate (SinglePrecisionFloatingPoint);
+       do_fmpy (_SD, Dest, PD,
+                get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
 
 
 // frndm.{s|d|i|u}{s|d|i|u}{s|d|i|u}
-#void::function::do_frndm:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2
-#      sim_io_error ("frndm");
-31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b11,6.P1,4.Source1::::frndm r
-#      do_frndm (_SD, rDest, rSource1, rSource2);
+void::function::do_frnd:int Dest, int PD, sim_fpu s1
+       set_fp_reg (_SD, Dest, s1, PD);
+31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b11,6.P1,4.Source::::frndm r
+       do_frnd (_SD, Dest, PD,
+                get_fp_reg (_SD, Source, rSource, P1));
 31.Dest,26.Source2,21.0b111110100,12.1,11.r,10.PD,8.0b11,6.P1,4./::::frndm l
-#      do_frndm (_SD, rDest, LongSignedImmediate, rSource2);
+       long_immediate (SinglePrecisionFloatingPoint);
+       do_frnd (_SD, Dest, PD,
+                get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1));
 
 
 // frndn.{s|d|i|u}{s|d|i|u}{s|d|i|u}
-#void::function::do_frndn:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2
-#      sim_io_error ("frndn");
-31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b00,6.P1,4.Source1::::frndn r
-#      do_frndn (_SD, rDest, rSource1, rSource2);
+31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b00,6.P1,4.Source::::frndn r
+       do_frnd (_SD, Dest, PD,
+                get_fp_reg (_SD, Source, rSource, P1));
 31.Dest,26.Source2,21.0b111110100,12.1,11.r,10.PD,8.0b00,6.P1,4./::::frndn l
-#      do_frndn (_SD, rDest, LongSignedImmediate, rSource2);
+       long_immediate (SinglePrecisionFloatingPoint);
+       do_frnd (_SD, Dest, PD,
+                get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1));
 
 
 // frndp.{s|d|i|u}{s|d|i|u}{s|d|i|u}
-#void::function::do_frndp:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2
-#      sim_io_error ("frndp");
-#31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b10,6.P1,4.Source1::::frndp r
-#      do_frndp (_SD, rDest, rSource1, rSource2);
-#31.Dest,26.Source2,21.0b111110100,12.1,11.r,10.PD,8.0b10,6.P1,4./::::frndp l
-#      do_frndp (_SD, rDest, LongSignedImmediate, rSource2);
+31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b10,6.P1,4.Source::::frndp r
+       do_frnd (_SD, Dest, PD,
+                get_fp_reg (_SD, Source, rSource, P1));
+31.Dest,26.Source2,21.0b111110100,12.1,11.r,10.PD,8.0b10,6.P1,4./::::frndp l
+       long_immediate (SinglePrecisionFloatingPoint);
+       do_frnd (_SD, Dest, PD,
+                get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1));
 
 
 // frndz.{s|d|i|u}{s|d|i|u}{s|d|i|u}
-#void::function::do_frndz:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2
-#      sim_io_error ("frndz");
-31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b01,6.P1,4.Source1::::frndz r
-#      do_frndz (_SD, rDest, rSource1, rSource2);
+31.Dest,26.Source2,21.0b111110100,12.0,11.r,10.PD,8.0b01,6.P1,4.Source::::frndz r
+       do_frnd (_SD, Dest, PD,
+                get_fp_reg (_SD, Source, rSource, P1));
 31.Dest,26.Source2,21.0b111110100,12.1,11.r,10.PD,8.0b01,6.P1,4./::::frndz l
-#      do_frndz (_SD, rDest, LongSignedImmediate, rSource2);
+       long_immediate (SinglePrecisionFloatingPoint);
+       do_frnd (_SD, Dest, PD,
+                get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1));
 
 
 // fsqrt.{s|d}{s|d}{s|d}
@@ -363,12 +556,23 @@ void::function::do_dst:int Source, unsigned32 Base, unsigned32 *rBase, int m , i
 
 
 // fsub.{s|d}{s|d}{s|d}
-#void::function::do_fsub:unsigned32 *rDest, unsigned32 Source1, unsigned32 Source2
-#      sim_io_error ("fsub");
+void::function::do_fsub:int Dest, int PD, sim_fpu s1, sim_fpu s2
+       sim_fpu ans = sim_fpu_sub (s1, s2);
+       if (TRACE_FPU_P(CPU))
+         trace_printf (SD, CPU, "0x%lx: fsub - %f + %f = %f\n",
+                       (unsigned long) cia.ip,
+                       sim_fpu_2d (s1), sim_fpu_2d (s2),
+                       sim_fpu_2d (ans));
+       set_fp_reg (_SD, Dest, ans, PD);
 31.Dest,26.Source2,21.0b111110001,12.0,11.r,10.PD,8.P2,6.P1,4.Source1::::fsub r
-#      do_fsub (_SD, rDest, rSource1, rSource2);
+       do_fsub (_SD, Dest, PD,
+                get_fp_reg (_SD, Source1, rSource1, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
 31.Dest,26.Source2,21.0b111110001,12.1,11.r,10.PD,8.P2,6.P1,4./::::fsub l
-#      do_fsub (_SD, rDest, LongSignedImmediate, rSource2);
+       long_immediate (SinglePrecisionFloatingPoint);
+       do_fsub (_SD, Dest, PD,
+                get_fp_reg (_SD, -1, SinglePrecisionFloatingPoint, P1),
+                get_fp_reg (_SD, Source2, rSource2, P2));
 
 
 // illop
@@ -390,7 +594,9 @@ instruction_address::function::do_jsr:instruction_address nia, signed32 *rLink,
          *rLink = cia.dp + sizeof (instruction_word);
        nia.dp = offset + base;
        if (nia.dp & 0x3)
-         engine_error (SD, CPU, cia, "destination address 0x%lx misaligned",
+         engine_error (SD, CPU, cia,
+                       "0x%lx: destination address 0x%lx misaligned",
+                       (unsigned long) cia.ip,
                        (unsigned long) nia.dp);
        return nia;
 31.Link,26.Base,21.0b100010,15.A,14.SignedOffset::::jsr i
@@ -752,16 +958,24 @@ void::function::do_trap:unsigned32 trap_number
              case 4: /* WRITE */
                {
                  int i;
-                 if (GPR(2) != 1)
+                 if (GPR(2) == 1)
+                   for (i = 0; i < GPR(6); i++)
+                     {
+                       char c;
+                       c = MEM (unsigned, GPR(4) + i, 1);
+                       sim_io_write_stdout (SD, &c, 1);
+                     }
+                 else if (GPR(2) == 2)
+                   for (i = 0; i < GPR(6); i++)
+                     {
+                       char c;
+                       c = MEM (unsigned, GPR(4) + i, 1);
+                       sim_io_write_stderr (SD, &c, 1);
+                     }
+                 else
                    engine_error (SD, CPU, cia,
                                  "0x%lx: write to invalid fid %d",
                                  (unsigned long) cia.ip, GPR(2));
-                 for (i = 0; i < GPR(6); i++)
-                   {
-                     char c;
-                     c = MEM (unsigned, GPR(4) + i, 1);
-                     sim_io_write_stdout (SD, &c, 1);
-                   }
                  GPR(2) = GPR(6);
                  break;
                }