first stage in function unit support; add new switches & latest code from andrew
authorMichael Meissner <gnu@the-meissners.org>
Wed, 8 Nov 1995 18:57:06 +0000 (18:57 +0000)
committerMichael Meissner <gnu@the-meissners.org>
Wed, 8 Nov 1995 18:57:06 +0000 (18:57 +0000)
30 files changed:
sim/ppc/.Sanitize
sim/ppc/ChangeLog
sim/ppc/Makefile.in
sim/ppc/configure
sim/ppc/configure.in
sim/ppc/corefile.c
sim/ppc/cpu.h
sim/ppc/debug.c
sim/ppc/devices.c
sim/ppc/emul_generic.c [new file with mode: 0644]
sim/ppc/emul_netbsd.c
sim/ppc/filter_filename.c
sim/ppc/function_unit.c [new file with mode: 0644]
sim/ppc/function_unit.h [new file with mode: 0644]
sim/ppc/inline.c
sim/ppc/inline.h [new file with mode: 0644]
sim/ppc/main.c
sim/ppc/mon.c
sim/ppc/mon.h [new file with mode: 0644]
sim/ppc/ppc-endian.c [deleted file]
sim/ppc/ppc-endian.h [deleted file]
sim/ppc/ppc-instructions
sim/ppc/psim.c
sim/ppc/sim-endian-n.h [new file with mode: 0644]
sim/ppc/sim-endian.c [new file with mode: 0644]
sim/ppc/sim_calls.c
sim/ppc/std-config.h
sim/ppc/table.c
sim/ppc/vm.c
sim/ppc/vm_n.h

index b5b07fa..f72289b 100644 (file)
@@ -59,6 +59,8 @@ events.c
 events.h
 filter_filename.c
 filter_filename.h
+function_unit.c
+function_unit.h
 idecode_branch.h
 idecode_expression.h
 idecode_fields.h
@@ -77,8 +79,6 @@ mon.h
 os_emul.c
 os_emul.h
 ppc-cache-rules
-ppc-endian.c
-ppc-endian.h
 ppc-instructions
 ppc-opcode-complex
 ppc-opcode-simple
@@ -91,6 +91,9 @@ registers.c
 registers.h
 sim_callbacks.h
 sim_calls.c
+sim-endian.c
+sim-endian.h
+sim-endian-n.h
 spa-reporter.c
 spa-system-calls.c
 spa-system-calls.h
index 3a0f385..60decfd 100644 (file)
@@ -1,3 +1,132 @@
+Wed Nov  8 13:19:47 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+       * Makefile.in ({FUNC,MODEL,WARNING}_CFLAGS): New flags set by
+       configure --enable switches.
+       (CONFIG_CFLAGS): Include FUNC_CFLAGS and MODE_CFLAGS.
+       (.c.o): Include WARNING_CFLAGS.
+       (CPU_H): Include function_unit.h.
+       (LIB_OBJ): Include function_unit.o.
+       (BUILT_SRC_WO_CONFIG): Split from BUILT_SRC and do not include
+       config.h or ppc-config.h.
+       (BUILT_SRC): Include BUILT_SRC_WO_CONFIG, config.h and
+       ppc-config.h.
+       (filter_filename.o): Include config.h/ppc-config.h dependencies.
+       (idecode.o, semantics.o): Specify CC line without WARNING_CFLAGS
+       so that we don't get all of the unused variable warnings that are
+       generated.
+       (function_unit.o): Add rule to build.
+       (main.o, sim_calls.o): Add function_unit.h, itable.h dependencies.
+       (mon.o): Include mon.c dependency.
+       (TAGS): Depend on BUILT_SRC.
+       (clean): Don't delete config.h or ppc-config.h
+
+       * basics.h (sim_callbacks.h): Move include after the include of
+       config.h and ppc-config.h.
+
+       * bits.{h,c} (ROTL32,ROTL64): Move these functions to bits.c.  Add
+       support for BITS_INLINE to inline these.  Add declarations to
+       bits.h.
+
+       * configure.in (--enable-sim-warnings): Add new option to specify
+       compiler warnings for all modules except idecode.o and semantics.o
+       which have lots of unused variables because they are machine
+       generated.
+       (--enable-sim-function-unit): New switch to configure whether
+       function unit support is compiled in or not.
+       (--enable-sim-{,default-}mode): New switches to control which cpu
+       model is used.
+       * configure: Regenerate.
+
+       * corefile.c (core_attach_address_callback): Delete unused
+       variable device_address.
+
+       * cpu.c (struct _cpu): Add function unit pointer field func_unit.
+       (cpu_create): If WITH_FUNCTION_UNIT, call function_unit_create.
+       (cpu_init): If WITH_FUNCTION_UNIT, call function_unit_init.
+       (cpu_halt): If WITH_FUNCTION_UNIT, call function_unit_halt.
+       (cpu_function_unit): New function to return func_unit field.
+
+       * cpu.h (function_unit.h): Include new include file.
+       (cpu_function_unit): Declare.
+
+       * debug.c (stdlib.h): Test HAVE_STDLIB_H, not HAVE_STDLIB.
+       (config.h): Include config.h.
+
+       * devices.c (icu_io_write_buffer_callback): Delete unused variable
+       system.
+
+       * emul_generic.c (emul_exit_call): Print out status value.
+
+       * emul_netbsd.c (do_read): Delete unused variable nr_moved.
+
+       * filter_filename.h (includes): Include config.h, ppc-config.h,
+       not basics.h.
+
+       * inline.c: Include bits.c if BITS_INLINE.  Include
+       function_unit.c if FUNCTION_UNIT_INLINE.
+
+       * inline.h (INLINE_BITS): Define if BITS_INLINE.
+       (INLINE_FUNCTION_UNIT): Define if FUNCTION_UNIT_INLINE.
+
+       * interrupts.c (instruction_storage_interrupt): Delete unused
+       variable nia.
+
+       * lf.h (config.h): Include config.h.
+
+       * main.c (includes): Include function_unit.c.  If HAVE_UNISTD_H,
+       include unistd.h.
+       (usage): Update for -m model, -i, and -I options.
+       (main): Delete unused variables stack_pointer and i.  Add support
+       for -i, -m model arguments.  Call psim_print_info with verbose ==
+       1 if -i, and verbose == 2 if -I.
+
+       * mon.c (stdio.h): Include stdio.h to pick up sprintf prototype.
+       (mon_issue): Call function_unit_issue if function units are
+       supported.
+       (mon_print_info): Take psim * argument.  Print out information
+       from function_unit if available.  Move read/write stats to always
+       print, instead of printing if verbose > 1.  Fix up plural
+       vs. singular usage.
+
+       * mon.h (mon_print_info): Update prototype.
+
+       * psim.c (current_ppc_model): Add global variable.
+       (psim_print_info): Pass system argument to mon_print_info.
+
+       * sim_calls.c (function_unit.h): Include.
+       (sim_open): Add support for -i and -m model options.  If -i call
+       psim_print_info with verbose == 1, if -I, with verbose == 2.
+       (sim_resume): Delete unused variable program_counter.
+
+       * std-config.h (WITH_FUNCTION_UNIT): Define.
+       (ppc_model): Add enumeration giving all PowerPC models currently
+       known about.
+       ({WITH,CURRENT}_PPC_MODEL): Define.
+       (FUNCTION_UNIT_INLINE): Define.
+
+       * table.c (config.h): Include config.h.
+
+       * vm.c (om_virtual_to_real): Print pte_word_{0,1} so the compiler
+       doesn't complain that they're unused.
+
+       * vm_n.h (vm_data_map_read_N): Delete unused variable rval.
+       
+Mon Nov  6 23:15:54 1995  Andrew Cagney  <cagney@highland.com.au>
+
+       * sim-endian.c (ppc-endian.c), sim-endian.h (ppc-endian.h):
+        renameed.  These files are target independant.
+       * Makefile.in, basics.h: update for new name.
+
+       * sim-endian.h (SWAP_N), sim-endian.c (_SWAP_1): Rename existing
+        SWAP_<N> to _SWAP_<N> so that sim-endian.h can contain SWAP_N
+        macro's as required.
+
+       * sim-endian.c, sim-endian-n.h (new file): Move endian code into a
+        debugable header file.
+
+       * ppc-instructions (Byte-Reverse): Enable byte reverse
+        instructions using SWAP_N macros.
+
 Mon Nov  6 10:39:28 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
 
        * Makefile.in (config.status): Remove references to config.make
index e233156..0a12ee7 100644 (file)
@@ -81,6 +81,9 @@ FLOAT_CFLAGS = @sim_float@
 TRACE_CFLAGS = @sim_trace@
 ASSERT_CFLAGS = @sim_assert@
 MONITOR_CFLAGS = @sim_monitor@
+FUNC_CFLAGS = @sim_func@
+MODEL_CFLAGS = @sim_model@ @sim_default_model@
+WARNING_CFLAGS = @sim_warnings@
 CONFIG_CFLAGS = $(BSWAP_CFLAGS) \
   $(ENDIAN_CFLAGS) \
   $(HOSTENDIAN_CFLAGS) \
@@ -93,7 +96,9 @@ CONFIG_CFLAGS = $(BSWAP_CFLAGS) \
   $(FLOAT_CFLAGS) \
   $(TRACE_CFLAGS) \
   $(ASSERT_CFLAGS) \
-  $(MONITOR_CFLAGS)
+  $(MONITOR_CFLAGS) \
+  $(FUNC_CFLAGS) \
+  $(MODEL_CFLAGS)
 
 CONFIG_FILE = @sim_config@
 IGEN_OPCODE_RULES = @sim_opcode@
@@ -122,7 +127,7 @@ TARGETLIB   = libsim.a
 all:   run $(TARGETLIB) $(GDB_OBJ)
 
 .c.o:
-       $(CC) -c $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $<
+       $(CC) -c $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(WARNING_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $<
 
 
 
@@ -130,7 +135,7 @@ BASICS_H = \
        config.h \
        ppc-config.h \
        words.h \
-       ppc-endian.h \
+       sim-endian.h \
        debug.h \
        filter_filename.h \
        bits.h \
@@ -163,7 +168,8 @@ CPU_H = \
        psim.h \
        icache.h \
        itable.h \
-       mon.h
+       mon.h \
+       function_unit.h
 
 EMUL_GENERIC_H = \
        $(CPU_H) \
@@ -176,12 +182,15 @@ INLINE = \
        inline.h \
        inline.c
 
-BUILT_SRC = \
+BUILT_SRC_WO_CONFIG = \
        icache.h \
        idecode.h idecode.c \
        semantics.h semantics.c \
        itable.h itable.c \
-       spreg.h spreg.c \
+       spreg.h spreg.c
+
+BUILT_SRC = \
+       $(BUILT_SRC_WO_CONFIG) \
        config.h \
        ppc-config.h 
 
@@ -189,9 +198,13 @@ LIB_SRC = \
        psim.c \
        bits.c \
        debug.c \
-       ppc-endian.c \
+       sim-endian.c \
+       sim-endian.h \
+       sim-endian-n.h \
        vm.c \
+       vm_n.h \
        corefile.c \
+       function_unit.c \
        events.c \
        os_emul.c \
        emul_generic.c \
@@ -214,13 +227,14 @@ LIB_OBJ = \
        debug.o \
        filter_filename.o \
        bits.o \
-       ppc-endian.o \
+       sim-endian.o \
        os_emul.o \
        emul_generic.o \
        emul_netbsd.o \
        registers.o \
        vm.o \
        corefile.o \
+       function_unit.o \
        spreg.o \
        cpu.o \
        interrupts.o \
@@ -256,10 +270,9 @@ psim.o: psim.c psim.h $(CPU_H) $(IDECODE_H) $(INLINE) $(LIB_SRC) $(BUILT_SRC)
 bits.o: bits.c $(BASICS_H)
 
 debug.o: debug.c $(BASICS_H)
-filter_filename.o: filter_filename.c $(BASICS_H)
+filter_filename.o: filter_filename.c config.h ppc-config.h
 
-ppc-endian.o: ppc-endian.c ppc-endian.h \
-       config.h ppc-config.h words.h sim_callbacks.h
+sim-endian.o: sim-endian.c sim-endian-n.h $(BASICS_H)
 
 os_emul.o: os_emul.c $(EMUL_GENERIC_H)
 emul_generic.o: emul_generic.c $(EMUL_GENERIC_H)
@@ -272,6 +285,7 @@ cpu.o: cpu.c $(CPU_H) $(IDECODE_H)
 interrupts.o: interrupts.c $(CPU_H) $(IDECODE_H) os_emul.h
 
 idecode.o: idecode.c $(CPU_H) $(IDECODE_H) semantics.h
+       $(CC) -c $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $<
 
 # double.o: double.c dp-bit.c
 
@@ -280,13 +294,15 @@ vm.o: vm.c vm.h vm_n.h $(BASICS_H) $(REGISTERS_H) \
 
 corefile.o: corefile.c corefile.h $(BASICS_H) device_tree.h
 
+function_unit.o: function_unit.c $(CPU_H)
+
 events.o: events.c events.h $(BASICS_H) 
 
-sim_calls.o: sim_calls.c $(PSIM_H) ../../gdb/tm.h devices.h
+sim_calls.o: sim_calls.c $(PSIM_H) function_unit.h itable.h ../../gdb/tm.h devices.h
 
 spreg.o: spreg.h spreg.c words.h
 
-main.o: main.c $(PSIM_H)
+main.o: main.c $(PSIM_H) function_unit.h itable.h
 
 devices.o: devices.c devices.h $(BASICS_H) \
        device_tree.h events.h
@@ -294,10 +310,11 @@ devices.o: devices.c devices.h $(BASICS_H) \
 device_tree.o: device_tree.c device_tree.h devices.h $(BASICS_H)
 
 semantics.o: semantics.c semantics.h $(CPU_H) $(IDECODE_H)
+       $(CC) -c $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $<
 
 itable.o: itable.c itable.h
 
-mon.o: $(CPU_H)
+mon.o: mon.c $(CPU_H)
 
 #
 # Rules to create the built c source code files
@@ -359,11 +376,11 @@ misc.o: misc.h filter_filename.h
 
 tags etags: TAGS
 
-TAGS: tmp-igen tmp-dgen config.h ppc-config.h
+TAGS: $(BUILT_SRC)
        etags $(srcdir)/*.h $(srcdir)/*.c $(BUILT_SRC)
 
 clean mostlyclean:
-       rm -f tmp-* *.[oas] core psim run igen dgen config.log $(BUILT_SRC)
+       rm -f tmp-* *.[oasi] core psim run igen dgen config.log $(BUILT_SRC_WO_CONFIG)
 
 distclean maintainer-clean realclean: clean
        rm -f TAGS Makefile config.cache config.status config.h stamp-h
index 7eefa07..9c3b40d 100755 (executable)
@@ -12,52 +12,55 @@ ac_help=
 ac_default_prefix=/usr/local
 # Any additions from configure.in:
 ac_help="$ac_help
-  --enable-sim-cflags=opts     Extra CFLAGS for use in building simulator"
+  --enable-sim-cflags=opts             Extra CFLAGS for use in building simulator"
 ac_help="$ac_help
-  --enable-sim-config=file     Override default config file"
+  --enable-sim-warnings=opts           Extra CFLAGS for turning on compiler warnings"
 ac_help="$ac_help
-  --enable-sim-opcode=which    Override default opcode lookup."
+  --enable-sim-config=file             Override default config file"
 ac_help="$ac_help
-  --enable-sim-switch          Use a switch instead of a table for instruction call."
+  --enable-sim-opcode=which            Override default opcode lookup."
 ac_help="$ac_help
-  --enable-sim-duplicate       Expand (duplicate) semantic functions."
+  --enable-sim-switch                  Use a switch instead of a table for instruction call."
 ac_help="$ac_help
-  --enable-sim-filter=rule     Specify filter rules."
+  --enable-sim-duplicate               Expand (duplicate) semantic functions."
 ac_help="$ac_help
-  --enable-sim-icache=size     Specify instruction cache size."
+  --enable-sim-filter=rule             Specify filter rules."
 ac_help="$ac_help
-  --enable-sim-inline=inlines  Specify which functions should be inlined."
+  --enable-sim-icache=size             Specify instruction cache size."
 ac_help="$ac_help
-  --enable-sim-bswap           Use the BSWAP instruction on Intel 486s and Pentiums."
+  --enable-sim-inline=inlines          Specify which functions should be inlined."
 ac_help="$ac_help
-  --enable-sim-endian=endian   Specify target byte endian orientation."
+  --enable-sim-bswap                   Use the BSWAP instruction on Intel 486s and Pentiums."
 ac_help="$ac_help
-  --enable-sim-hostendain=end  Specify host byte endian orientation."
+  --enable-sim-endian=endian           Specify target byte endian orientation."
 ac_help="$ac_help
-  --enable-sim-smp=n           Specify number of processors to configure for."
+  --enable-sim-hostendain=end          Specify host byte endian orientation."
 ac_help="$ac_help
-  --enable-sim-bitsize=n       Specify target bitsize (32 or 64)."
+  --enable-sim-smp=n                   Specify number of processors to configure for."
 ac_help="$ac_help
-  --enable-sim-hostbitsize=n   Specify host bitsize (32 or 64)."
+  --enable-sim-bitsize=n               Specify target bitsize (32 or 64)."
 ac_help="$ac_help
-  --enable-sim-env=env         Specify target environment (operating, virtual, user)."
+  --enable-sim-hostbitsize=n           Specify host bitsize (32 or 64)."
 ac_help="$ac_help
-  --enable-sim-timebase        Specify whether the PPC timebase is supported."
+  --enable-sim-env=env                 Specify target environment (operating, virtual, user)."
 ac_help="$ac_help
-  --enable-sim-alignment=align Specify strict or nonstrict alignment.
-case "${enableval}" in
-  yes | strict | STRICT)       sim_alignment="-DWITH_ALIGNMENT=STRICT_ALIGNMENT";;
-  no | nonstrict | NONSTRICT)  sim_alignment="-DWITH_ALIGNMENT=NOSTRICT_ALIGNMENT";;
-  *)                           sim_alignment="-DWITH_ALIGNMENT=$enableval";;
-esac"
+  --enable-sim-timebase                        Specify whether the PPC timebase is supported."
+ac_help="$ac_help
+  --enable-sim-alignment=align         Specify strict or nonstrict alignment."
+ac_help="$ac_help
+  --enable-sim-trace                   Specify whether tracing is supported."
+ac_help="$ac_help
+  --enable-sim-assert                  Specify whether to perform random assertions."
 ac_help="$ac_help
-  --enable-sim-trace           Specify whether tracing is supported."
+  --enable-sim-float                   Specify whether to use host floating point or simulate."
 ac_help="$ac_help
-  --enable-sim-assert          Specify whether to perform random assertions."
+  --enable-sim-monitor=mon             Specify whether to enable monitoring events."
 ac_help="$ac_help
-  --enable-sim-float           Specify whether to use host floating point or simulate."
+  --enable-sim-function-unit           Specify whether detailed functional unit support is built."
 ac_help="$ac_help
-  --enable-sim-monitor=mon     Specify whether to enable monitoring events."
+  --enable-sim-model=which             Specify PowerPC to model."
+ac_help="$ac_help
+  --enable-sim-default-model=which     Specify default PowerPC to model."
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -458,6 +461,18 @@ else
   sim_cflags=""
 fi
 
+# Check whether --enable-sim-warnings or --disable-sim-warnings was given.
+enableval="$enable_sim_warnings"
+if test -n "$enableval"; then
+  case "${enableval}" in
+  yes) sim_warnings="-Wall";;
+  no)  sim_warnings="-w";;
+  *)   sim_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+else
+  sim_warnings=""
+fi
+
 # Check whether --enable-sim-config or --disable-sim-config was given.
 enableval="$enable_sim_config"
 if test -n "$enableval"; then
@@ -661,6 +676,12 @@ fi
 # Check whether --enable-sim-alignment or --disable-sim-alignment was given.
 enableval="$enable_sim_alignment"
 if test -n "$enableval"; then
+  case "${enableval}" in
+  yes | strict | STRICT)       sim_alignment="-DWITH_ALIGNMENT=STRICT_ALIGNMENT";;
+  no | nonstrict | NONSTRICT)  sim_alignment="-DWITH_ALIGNMENT=NOSTRICT_ALIGNMENT";;
+  *)                           sim_alignment="-DWITH_ALIGNMENT=$enableval";;
+esac
+else
   sim_alignment=""
 fi
 
@@ -714,6 +735,42 @@ else
   sim_float=""
 fi
 
+# Check whether --enable-sim-function-unit or --disable-sim-function-unit was given.
+enableval="$enable_sim_function_unit"
+if test -n "$enableval"; then
+  case "${enableval}" in
+  yes) sim_func="-DWITH_FUNCTION_UNIT=1";;
+  no)  sim_func="-DWITH_FUNCTION_UNIT=0";;
+  *)   sim_func="";;
+esac
+else
+  sim_func=""
+fi
+
+# Check whether --enable-sim-model or --disable-sim-model was given.
+enableval="$enable_sim_model"
+if test -n "$enableval"; then
+  case "${enableval}" in
+  yes) sim_model="";;
+  no)  sim_model="";;
+  *)   sim_model="-DWITH_PPC_MODEL=${enableval}";;
+esac
+else
+  sim_model=""
+fi
+
+# Check whether --enable-sim-default-model or --disable-sim-default-model was given.
+enableval="$enable_sim_default_model"
+if test -n "$enableval"; then
+  case "${enableval}" in
+  yes) sim_default_model="";;
+  no)  sim_default_model="";;
+  *)   sim_default_model="-DWITH_DEFAULT_PPC_MODEL=${enableval}";;
+esac
+else
+  sim_model=""
+fi
+
 
 
 ac_aux_dir=
@@ -968,6 +1025,10 @@ fi
 
 
 
+
+
+
+
 for ac_func in getrusage
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
@@ -975,7 +1036,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 979 "configure"
+#line 1040 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1030,7 +1091,7 @@ else
   ac_cv_c_cross=yes
 else
 cat > conftest.$ac_ext <<EOF
-#line 1034 "configure"
+#line 1095 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
@@ -1068,7 +1129,7 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1072 "configure"
+#line 1133 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1082,7 +1143,7 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1086 "configure"
+#line 1147 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1115,7 +1176,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1119 "configure"
+#line 1180 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
@@ -1266,6 +1327,7 @@ s%@HDEFINES@%$HDEFINES%g
 s%@AR@%$AR%g
 s%@RANLIB@%$RANLIB%g
 s%@sim_cflags@%$sim_cflags%g
+s%@sim_warnings@%$sim_warnings%g
 s%@sim_config@%$sim_config%g
 s%@sim_opcode@%$sim_opcode%g
 s%@sim_switch@%$sim_switch%g
@@ -1286,6 +1348,9 @@ s%@sim_float@%$sim_float%g
 s%@sim_trace@%$sim_trace%g
 s%@sim_assert@%$sim_assert%g
 s%@sim_monitor@%$sim_monitor%g
+s%@sim_func@%$sim_func%g
+s%@sim_model@%$sim_model%g
+s%@sim_default_model@%$sim_default_model%g
 s%@CC_FOR_BUILD@%$CC_FOR_BUILD%g
 s%@CPP@%$CPP%g
 
index 43761d8..4ebcefb 100644 (file)
@@ -3,15 +3,23 @@ AC_PREREQ(2.3)dnl
 AC_INIT(Makefile.in)
 
 AC_ARG_ENABLE(sim-cflags,
-[  --enable-sim-cflags=opts    Extra CFLAGS for use in building simulator],
+[  --enable-sim-cflags=opts            Extra CFLAGS for use in building simulator],
 [case "${enableval}" in
   yes) sim_cflags="-O2 -fomit-frame-pointer";;
   no)  sim_cflags="";;
   *)   sim_cflags=`echo "${enableval}" | sed -e "s/,/ /g"`;;
 esac],[sim_cflags=""])dnl
 
+AC_ARG_ENABLE(sim-warnings,
+[  --enable-sim-warnings=opts          Extra CFLAGS for turning on compiler warnings except for idecode.o and semantics.o],
+[case "${enableval}" in
+  yes) sim_warnings="-Wall";;
+  no)  sim_warnings="-w";;
+  *)   sim_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac],[sim_warnings=""])dnl
+
 AC_ARG_ENABLE(sim-config,
-[  --enable-sim-config=file    Override default config file],
+[  --enable-sim-config=file            Override default config file],
 [case "${enableval}" in
   yes) sim_config="std-config.h";;
   no)  sim_config="std-config.h";;
@@ -19,7 +27,7 @@ AC_ARG_ENABLE(sim-config,
 esac],[sim_config="std-config.h]")dnl
 
 AC_ARG_ENABLE(sim-opcode,
-[  --enable-sim-opcode=which   Override default opcode lookup.],
+[  --enable-sim-opcode=which           Override default opcode lookup.],
 [case "${enableval}" in
   yes) sim_opcode="ppc-opcode-simple";;
   no)  sim_opcode="ppc-opcode-simple";;
@@ -27,35 +35,35 @@ AC_ARG_ENABLE(sim-opcode,
 esac],[sim_opcode="ppc-opcode-simple"])dnl
 
 AC_ARG_ENABLE(sim-switch,
-[  --enable-sim-switch         Use a switch instead of a table for instruction call.],
+[  --enable-sim-switch                 Use a switch instead of a table for instruction call.],
 [case "${enableval}" in
   yes) sim_switch="-s";;
   *)   sim_switch="";;
 esac],[sim_switch=""])dnl
 
 AC_ARG_ENABLE(sim-duplicate,
-[  --enable-sim-duplicate      Expand (duplicate) semantic functions.],
+[  --enable-sim-duplicate              Expand (duplicate) semantic functions.],
 [case "${enableval}" in
    yes)        sim_dup="-e";;
    *)  sim_dup="";;
 esac],[sim_dup=""])dnl
 
 AC_ARG_ENABLE(sim-filter,
-[  --enable-sim-filter=rule    Specify filter rules.],
+[  --enable-sim-filter=rule            Specify filter rules.],
 [case "${enableval}" in
    yes)        sim_filter="";;
    *)  sim_filter="-f $enableval";;
 esac],[sim_filter="-f 64"])dnl
 
 AC_ARG_ENABLE(sim-icache,
-[  --enable-sim-icache=size    Specify instruction cache size.],
+[  --enable-sim-icache=size            Specify instruction cache size.],
 [case "${enableval}" in
    yes)        sim_icache="-r 1024";;
    *)  sim_icache="";;
 esac],[sim_icache=""])dnl
 
 AC_ARG_ENABLE(sim-inline,
-[  --enable-sim-inline=inlines Specify which functions should be inlined.],
+[  --enable-sim-inline=inlines         Specify which functions should be inlined.],
 [sim_inline=""
 case "$enableval" in
   no)          sim_inline="";;
@@ -79,7 +87,7 @@ case "$enableval" in
 esac],[sim_inline=""])dnl
 
 AC_ARG_ENABLE(sim-bswap,
-[  --enable-sim-bswap          Use the BSWAP instruction on Intel 486s and Pentiums.],
+[  --enable-sim-bswap                  Use the BSWAP instruction on Intel 486s and Pentiums.],
 [case "${enableval}" in
   yes) sim_bswap="-DWITH_BSWAP=1";;
   no)  sim_bswap="-DWITH_BSWAP=0";;
@@ -87,7 +95,7 @@ AC_ARG_ENABLE(sim-bswap,
 esac],[sim_bswap=""])dnl
 
 AC_ARG_ENABLE(sim-endian,
-[  --enable-sim-endian=endian  Specify target byte endian orientation.],
+[  --enable-sim-endian=endian          Specify target byte endian orientation.],
 [case "${enableval}" in
   yes) case "$target" in
          *powerpc-*) sim_endian="-DWITH_TARGET_BYTE_ORDER=BIG_ENDIAN";;
@@ -101,7 +109,7 @@ AC_ARG_ENABLE(sim-endian,
 esac],[sim_endian=""])dnl
 
 AC_ARG_ENABLE(sim-hostendian,
-[  --enable-sim-hostendain=end Specify host byte endian orientation.],
+[  --enable-sim-hostendain=end         Specify host byte endian orientation.],
 [case "${enableval}" in
   no)   sim_hostendian="-DWITH_HOST_BYTE_ORDER=0";;
   b*|B*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN";;
@@ -110,7 +118,7 @@ AC_ARG_ENABLE(sim-hostendian,
 esac],[sim_hostendian=""])dnl
 
 AC_ARG_ENABLE(sim-smp,
-[  --enable-sim-smp=n          Specify number of processors to configure for.],
+[  --enable-sim-smp=n                  Specify number of processors to configure for.],
 [case "${enableval}" in
   yes) sim_smp="-DWITH_SMP=2";;
   no)  sim_smp="-DWITH_SMP=0";;
@@ -118,7 +126,7 @@ AC_ARG_ENABLE(sim-smp,
 esac],[sim_smp=""])dnl
 
 AC_ARG_ENABLE(sim-bitsize,
-[  --enable-sim-bitsize=n      Specify target bitsize (32 or 64).],
+[  --enable-sim-bitsize=n              Specify target bitsize (32 or 64).],
 [case "${enableval}" in
   yes) sim_bitsize="";;
   no)  sim_bitsize="";;
@@ -126,7 +134,7 @@ AC_ARG_ENABLE(sim-bitsize,
 esac],[sim_bitsize=""])dnl
 
 AC_ARG_ENABLE(sim-hostbitsize,
-[  --enable-sim-hostbitsize=n  Specify host bitsize (32 or 64).],
+[  --enable-sim-hostbitsize=n          Specify host bitsize (32 or 64).],
 [case "${enableval}" in
   yes) sim_hostbitsize="";;
   no)  sim_hostbitsize="";;
@@ -134,7 +142,7 @@ AC_ARG_ENABLE(sim-hostbitsize,
 esac],[sim_hostbitsize=""])dnl
 
 AC_ARG_ENABLE(sim-env,
-[  --enable-sim-env=env                Specify target environment (operating, virtual, user).],
+[  --enable-sim-env=env                        Specify target environment (operating, virtual, user).],
 [case "${enableval}" in
   operating | os | oea)        sim_env="-DWITH_ENVIRONMENT=OPERATING_ENVIRONMENT";;
   virtual | vea)       sim_env="-DWITH_ENVIRONMENT=VIRTUAL_ENVIRONMENT";;
@@ -143,7 +151,7 @@ AC_ARG_ENABLE(sim-env,
 esac],[sim_env=""])dnl
 
 AC_ARG_ENABLE(sim-timebase,
-[  --enable-sim-timebase       Specify whether the PPC timebase is supported.],
+[  --enable-sim-timebase                       Specify whether the PPC timebase is supported.],
 [case "${enableval}" in
   yes) sim_timebase="-DWITH_TIME_BASE=1";;
   no)  sim_timebase="-DWITH_TIME_BASE=0";;
@@ -151,7 +159,7 @@ AC_ARG_ENABLE(sim-timebase,
 esac],[sim_timebase=""])dnl
 
 AC_ARG_ENABLE(sim-alignment,
-[  --enable-sim-alignment=align        Specify strict or nonstrict alignment.]
+[  --enable-sim-alignment=align                Specify strict or nonstrict alignment.],
 [case "${enableval}" in
   yes | strict | STRICT)       sim_alignment="-DWITH_ALIGNMENT=STRICT_ALIGNMENT";;
   no | nonstrict | NONSTRICT)  sim_alignment="-DWITH_ALIGNMENT=NOSTRICT_ALIGNMENT";;
@@ -159,7 +167,7 @@ AC_ARG_ENABLE(sim-alignment,
 esac],[sim_alignment=""])dnl
 
 AC_ARG_ENABLE(sim-trace,
-[  --enable-sim-trace          Specify whether tracing is supported.],
+[  --enable-sim-trace                  Specify whether tracing is supported.],
 [case "${enableval}" in
   yes) sim_trace="-DWITH_TRACE=1";;
   no)  sim_trace="-DWITH_TRACE=0";;
@@ -167,7 +175,7 @@ AC_ARG_ENABLE(sim-trace,
 esac],[sim_trace=""])dnl
 
 AC_ARG_ENABLE(sim-assert,
-[  --enable-sim-assert         Specify whether to perform random assertions.],
+[  --enable-sim-assert                 Specify whether to perform random assertions.],
 [case "${enableval}" in
   yes) sim_assert="-DWITH_ASSERT=1";;
   no)  sim_assert="-DWITH_ASSERT=0";;
@@ -175,7 +183,7 @@ AC_ARG_ENABLE(sim-assert,
 esac],[sim_assert=""])dnl
 
 AC_ARG_ENABLE(sim-float,
-[  --enable-sim-float          Specify whether to use host floating point or simulate.],
+[  --enable-sim-float                  Specify whether to use host floating point or simulate.],
 [case "${enableval}" in
   yes | hard)  sim_float="-DWITH_FLOATING_POINT=HARD_FLOATING_POINT";;
   no | soft)   sim_float="-DWITH_FLOATING_POINT=SOFT_FLOATING_POINT";;
@@ -183,7 +191,7 @@ AC_ARG_ENABLE(sim-float,
 esac],[sim_float=""])dnl
 
 AC_ARG_ENABLE(sim-monitor,
-[  --enable-sim-monitor=mon    Specify whether to enable monitoring events.],
+[  --enable-sim-monitor=mon            Specify whether to enable monitoring events.],
 [case "${enableval}" in
   yes)         sim_mon="-DWITH_MON='MONITOR_INSTRUCTION_ISSUE | MONITOR_LOAD_STORE_UNIT'";;
   no)          sim_mon="-DWITH_MON=0";;
@@ -192,6 +200,30 @@ AC_ARG_ENABLE(sim-monitor,
   *)           sim_mon="-DWITH_MON='$enableval'";;
 esac],[sim_float=""])dnl
 
+AC_ARG_ENABLE(sim-function-unit,
+[  --enable-sim-function-unit          Specify whether detailed functional unit support is built.],
+[case "${enableval}" in
+  yes) sim_func="-DWITH_FUNCTION_UNIT=1";;
+  no)  sim_func="-DWITH_FUNCTION_UNIT=0";;
+  *)   sim_func="";;
+esac],[sim_func=""])dnl
+
+AC_ARG_ENABLE(sim-model,
+[  --enable-sim-model=which            Specify PowerPC to model.],
+[case "${enableval}" in
+  yes) sim_model="";;
+  no)  sim_model="";;
+  *)   sim_model="-DWITH_PPC_MODEL=${enableval}";;
+esac],[sim_model=""])dnl
+
+AC_ARG_ENABLE(sim-default-model,
+[  --enable-sim-default-model=which    Specify default PowerPC to model.],
+[case "${enableval}" in
+  yes) sim_default_model="";;
+  no)  sim_default_model="";;
+  *)   sim_default_model="-DWITH_DEFAULT_PPC_MODEL=${enableval}";;
+esac],[sim_model=""])dnl
+
 AC_CONFIG_HEADER(config.h:config.in)
 
 AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../..)
@@ -207,6 +239,7 @@ AR=${AR-ar}
 AC_SUBST(AR)
 AC_PROG_RANLIB
 AC_SUBST(sim_cflags)
+AC_SUBST(sim_warnings)
 AC_SUBST(sim_config)
 AC_SUBST(sim_opcode)
 AC_SUBST(sim_switch)
@@ -227,6 +260,9 @@ AC_SUBST(sim_float)
 AC_SUBST(sim_trace)
 AC_SUBST(sim_assert)
 AC_SUBST(sim_monitor)
+AC_SUBST(sim_func)
+AC_SUBST(sim_model)
+AC_SUBST(sim_default_model)
 
 AC_CHECK_FUNCS(getrusage)
 
index 1c67357..c112a63 100644 (file)
@@ -398,7 +398,6 @@ core_attach_address_callback(const device *me,
                             const device *who) /*callback/default*/
 {
   core *memory = (core*)me->data;
-  unsigned_word device_address;
   DTRACE_ATTACH_ADDRESS(core);
   if (space != 0)
     error("core_attach_address_callback() invalid address space\n");
index 82290f6..a89f7b9 100644 (file)
@@ -37,6 +37,7 @@
 #include "icache.h"
 #include "itable.h"
 #include "mon.h"
+#include "function_unit.h"
 
 
 /* typedef struct _cpu cpu;
@@ -176,6 +177,9 @@ INLINE_CPU registers *cpu_registers
 INLINE_CPU void cpu_synchronize_context
 (cpu *processor);
 
+INLINE_CPU function_unit *cpu_function_unit
+(cpu *processor);
+
 #define IS_PROBLEM_STATE(PROCESSOR) \
 (CURRENT_ENVIRONMENT == OPERATING_ENVIRONMENT \
  ? (cpu_registers(PROCESSOR)->msr & msr_problem_state) \
index e8c054f..c77b51f 100644 (file)
 #ifndef _DEBUG_C_
 #define _DEBUG_C_
 
+#include "config.h"
 #include "basics.h"
 
-#ifdef HAVE_STDLIB
+#ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
 
index 46a3eec..b0368d5 100644 (file)
@@ -544,7 +544,6 @@ icu_io_write_buffer_callback(const device *me,
                             cpu *processor,
                             unsigned_word cia)
 {
-  psim *system = cpu_system(processor);
   unsigned_1 val = H2T_1(*(unsigned_1*)source);
   DTRACE_IO_WRITE_BUFFER(icu);
   /* tell the parent device that the interrupt lines have changed.
diff --git a/sim/ppc/emul_generic.c b/sim/ppc/emul_generic.c
new file mode 100644 (file)
index 0000000..f764205
--- /dev/null
@@ -0,0 +1,230 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+
+    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.
+    ----
+
+    Code to output system call traces Copyright (C) 1991 Gordon Irlam.
+    All rights reserved.
+
+    This tool is part of the Spa(7) package.  The Spa(7) package
+    may  be redistributed and/or modified under the terms of the
+    GNU General Public License Version 2 (GPL(7))  as  published
+    by the Free Software Foundation.
+
+    */
+
+
+#ifndef _EMUL_GENERIC_C_
+#define _EMUL_GENERIC_C_
+
+#include "emul_generic.h"
+
+#ifndef STATIC_INLINE_EMUL_GENERIC
+#define STATIC_INLINE_EMUL_GENERIC STATIC_INLINE
+#endif
+
+
+INLINE_EMUL_GENERIC void
+emul_enter_call(emulation *emul,
+               int call,
+               int arg0,
+               cpu *processor,
+               unsigned_word cia)
+{
+  printf_filtered("%d:0x%x:%s(",
+                 cpu_nr(processor) + 1,
+                 cia, 
+                 emul->call_descriptor[call].name);
+}
+
+
+INLINE_EMUL_GENERIC void
+emul_exit_call(emulation *emul,
+              int call,
+              int arg0,
+              cpu *processor,
+              unsigned_word cia)
+{
+  int status = cpu_registers(processor)->gpr[3];
+  int error = cpu_registers(processor)->gpr[0];
+  printf_filtered(")=%d", status);
+  if (error > 0 && error < emul->nr_error_names)
+    printf_filtered("[%s]",
+                   emul->error_names[cpu_registers(processor)->gpr[0]]);
+  printf_filtered("\n");
+}
+
+
+INLINE_EMUL_GENERIC unsigned64
+emul_read_gpr64(cpu *processor,
+               int g)
+{
+  unsigned32 hi;
+  unsigned32 lo;
+  if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) {
+    hi = cpu_registers(processor)->gpr[g];
+    lo = cpu_registers(processor)->gpr[g+1];
+  }
+  else {
+    lo = cpu_registers(processor)->gpr[g];
+    hi = cpu_registers(processor)->gpr[g+1];
+  }
+  return (INSERTED64(hi, 0, 31) | INSERTED64(lo, 32, 63));
+}
+
+
+INLINE_EMUL_GENERIC void
+emul_write_gpr64(cpu *processor,
+                int g,
+                unsigned64 val)
+{
+  unsigned32 hi = EXTRACTED64(val, 0, 31);
+  unsigned32 lo = EXTRACTED64(val, 32, 63);
+  if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) {
+    cpu_registers(processor)->gpr[g] = hi;
+    cpu_registers(processor)->gpr[g+1] = lo;
+  }
+  else {
+    cpu_registers(processor)->gpr[g] = lo;
+    cpu_registers(processor)->gpr[g+1] = hi;
+  }
+}
+
+
+INLINE_EMUL_GENERIC char *
+emul_read_string(char *dest,
+                unsigned_word addr,
+                unsigned nr_bytes,
+                cpu *processor,
+                unsigned_word cia)
+{
+  unsigned nr_moved = 0;
+  if (addr == 0)
+    return NULL;
+  while (1) {
+    if (vm_data_map_read_buffer(cpu_data_map(processor),
+                               &dest[nr_moved],
+                               addr + nr_moved,
+                               sizeof(dest[nr_moved]))
+       != sizeof(dest[nr_moved]))
+      return NULL;
+    if (dest[nr_moved] == '\0' || nr_moved >= nr_bytes)
+      break;
+    nr_moved++;
+  }
+  dest[nr_moved] = '\0';
+  return dest;
+}
+
+
+INLINE_EMUL_GENERIC void
+emul_write_status(cpu *processor,
+                 int status,
+                 int errno)
+{
+  cpu_registers(processor)->gpr[3] = status;
+  if (status < 0)
+    cpu_registers(processor)->gpr[0] = errno;
+  else
+    cpu_registers(processor)->gpr[0] = 0;
+}
+
+
+INLINE_EMUL_GENERIC void
+emul_write_word(unsigned_word addr,
+               unsigned_word buf,
+               cpu *processor,
+               unsigned_word cia)
+{
+  int nr_moved;
+  H2T(buf);
+  nr_moved = vm_data_map_write_buffer(cpu_data_map(processor),
+                                     &buf,
+                                     addr,
+                                     sizeof(buf),
+                                     0/*violate_ro*/);
+  if (nr_moved != sizeof(buf)) {
+    printf_filtered("emul_write_word() write failed, %d out of %d written\n",
+                   nr_moved, sizeof(buf));
+    cpu_halt(processor, cia, was_exited, 14/*EFAULT*/);
+  }
+}
+
+
+INLINE_EMUL_GENERIC void
+emul_write_buffer(const void *source,
+                 unsigned_word addr,
+                 unsigned nr_bytes,
+                 cpu *processor,
+                 unsigned_word cia)
+{
+  int nr_moved = vm_data_map_write_buffer(cpu_data_map(processor),
+                                         source,
+                                         addr,
+                                         nr_bytes,
+                                         0/*violate_ro*/);
+  if (nr_moved != nr_bytes) {
+    printf_filtered("emul_write_buffer() write failed %d out of %d written\n",
+                   nr_moved, nr_bytes);
+    cpu_halt(processor, cia, was_exited, 14/*EFAULT*/);
+  }
+}
+
+
+INLINE_EMUL_GENERIC void
+emul_read_buffer(void *dest,
+                unsigned_word addr,
+                unsigned nr_bytes,
+                cpu *processor,
+                unsigned_word cia)
+{
+  int nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
+                                        dest,
+                                        addr,
+                                        nr_bytes);
+  if (nr_moved != nr_bytes) {
+    printf_filtered("emul_read_buffer() read failed %d out of %d read\n",
+                   nr_moved, nr_bytes);
+    cpu_halt(processor, cia, was_exited, 14/*EFAULT*/);
+  }
+}
+
+
+INLINE_EMUL_GENERIC void
+emul_do_call(emulation *emul,
+            unsigned call,
+            const int arg0,
+            cpu *processor,
+            unsigned_word cia)
+{
+  emul_call_handler *handler = NULL;
+  if (call >= emul->nr_system_calls)
+    error("do_call() os_emul call %d out-of-range\n", call);
+
+  handler = emul->call_descriptor[call].handler;
+  if (handler == NULL)
+    error("do_call() unimplemented call %d\n", call);
+
+  ENTER_CALL;
+  cpu_registers(processor)->gpr[0] = 0; /* default success */
+  handler(emul, call, arg0, processor, cia);
+  EXIT_CALL;
+}
+
+
+#endif /* _SYSTEM_C_ */
index 1a05f0a..ac2cd80 100644 (file)
@@ -248,7 +248,6 @@ do_read(emulation *emul,
   unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
   int nbytes = cpu_registers(processor)->gpr[arg0+2];
   int status;
-  int nr_moved;
   SYS(read);
   
   if (WITH_TRACE && ppc_trace[trace_os_emul])
index 72923b9..ecbde5c 100644 (file)
@@ -18,7 +18,8 @@
  
     */
 
-#include "basics.h"
+#include "config.h"
+#include "ppc-config.h"
 
 /* Shorten traces by eliminating the directory component to filenames.  */
 extern char *
diff --git a/sim/ppc/function_unit.c b/sim/ppc/function_unit.c
new file mode 100644 (file)
index 0000000..7793c7b
--- /dev/null
@@ -0,0 +1,611 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+
+    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 _FUNCTION_UNIT_C_
+#define _FUNCTION_UNIT_C_
+
+#ifndef STATIC_INLINE_FUNCTION_UNIT
+#define STATIC_INLINE_FUNCTION_UNIT STATIC_INLINE
+#endif
+
+
+#include "basics.h"
+#include "cpu.h"
+#include "function_unit.h"
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+typedef enum _unit_index {
+  UNIT_UNKNOWN,                                /* unknown functional unit */
+  UNIT_INT,                            /* integer functional unit */
+  UNIT_SINT,                           /* integer or SRU functional unit */
+  UNIT_CINT,                           /* complex integer functional unit */
+  UNIT_FPU,                            /* floating point functional unit */
+  UNIT_MEM,                            /* memory functional unit */
+  UNIT_BRANCH,                         /* branch functional unit */
+  UNIT_SREG,                           /* system register functional unit */
+  NR_UNITS
+} unit_index;
+
+static const char *unit_names[] = {
+  "unknown functional unit instruction",               /* UNIT_UNKNOWN */
+  "int functional unit instruction",                   /* UNIT_INT */
+  "int or SRU functional unit instruction",            /* UNIT_SINT */
+  "complex int functional unit instruction",           /* UNIT_CINT */
+  "floating point functional unit instruction",                /* UNIT_FPU */
+  "memory function unit instruction",                  /* UNIT_MEM */
+  "branch functional unit instruction",                        /* UNIT_BRANCH */
+  "system register functional unit instruction",       /* UNIT_SREG */
+};
+
+typedef struct _timing {
+  itable_index index;                                  /* instruction # */
+  unit_index unit;                                     /* functional unit */
+  int cycles;                                          /* # cycles */
+  unsigned flags;                                      /* random other flags */
+} timing;
+
+struct _function_unit {
+  unsigned_word old_program_counter;
+  unsigned nr_branches;
+  unsigned nr_stalls;
+  unsigned nr_units[ (int)NR_UNITS ];
+  struct {
+    unit_index unit;
+    int cycles;
+    unsigned flags;
+  } time[ (int)nr_itable_entries ];
+};
+
+/* Flags used in timing info */
+
+#define LOAD   0x00000001                              /* this is a load */
+#define        STORE   0x00000002                              /* this is a store */
+
+\f
+/* 603 timings */
+static timing time_603[] = {
+  /* Instruction index                                                 Function unit   Cycles  Flags */
+  { itable_AND,                                                                UNIT_INT,       1,      0 },
+  { itable_AND_Immediate,                                              UNIT_INT,       1,      0 },
+  { itable_AND_Immediate_Shifted,                                      UNIT_INT,       1,      0 },
+  { itable_AND_with_Complement,                                                UNIT_INT,       1,      0 },
+  { itable_Add,                                                                UNIT_SINT,      1,      0 },
+  { itable_Add_Carrying,                                               UNIT_INT,       1,      0 },
+  { itable_Add_Extended,                                               UNIT_INT,       1,      0 },
+  { itable_Add_Immediate,                                              UNIT_SINT,      1,      0 },
+  { itable_Add_Immediate_Carrying,                                     UNIT_INT,       1,      0 },
+  { itable_Add_Immediate_Carrying_and_Record,                          UNIT_INT,       1,      0 },
+  { itable_Add_Immediate_Shifted,                                      UNIT_SINT,      1,      0 },
+  { itable_Add_to_Minus_One_Extended,                                  UNIT_INT,       1,      0 },
+  { itable_Add_to_Zero_Extended,                                       UNIT_INT,       1,      0 },
+  { itable_Branch,                                                     UNIT_BRANCH,    1,      0 },
+  { itable_Branch_Conditional,                                         UNIT_BRANCH,    1,      0 },
+  { itable_Branch_Conditional_to_Count_Register,                       UNIT_BRANCH,    1,      0 },
+  { itable_Branch_Conditional_to_Link_Register,                                UNIT_BRANCH,    1,      0 },
+  { itable_Compare,                                                    UNIT_SINT,      1,      0 },
+  { itable_Compare_Immediate,                                          UNIT_SINT,      1,      0 },
+  { itable_Compare_Logical,                                            UNIT_SINT,      1,      0 },
+  { itable_Compare_Logical_Immediate,                                  UNIT_SINT,      1,      0 },
+  { itable_Condition_Register_AND,                                     UNIT_SREG,      1,      0 },
+  { itable_Condition_Register_AND_with_Complement,                     UNIT_SREG,      1,      0 },
+  { itable_Condition_Register_Equivalent,                              UNIT_SREG,      1,      0 },
+  { itable_Condition_Register_NAND,                                    UNIT_SREG,      1,      0 },
+  { itable_Condition_Register_NOR,                                     UNIT_SREG,      1,      0 },
+  { itable_Condition_Register_OR,                                      UNIT_SREG,      1,      0 },
+  { itable_Condition_Register_OR_with_Complement,                      UNIT_SREG,      1,      0 },
+  { itable_Condition_Register_XOR,                                     UNIT_SREG,      1,      0 },
+  { itable_Count_Leading_Zeros_Word,                                   UNIT_INT,       1,      0 },
+  { itable_Data_Cache_Block_Flush,                                     UNIT_MEM,       5,      0 },
+  { itable_Data_Cache_Block_Invalidate,                                        UNIT_MEM,       2,      0 },
+  { itable_Data_Cache_Block_Store,                                     UNIT_MEM,       5,      0 },
+  { itable_Data_Cache_Block_Touch,                                     UNIT_MEM,       2,      0 },
+  { itable_Data_Cache_Block_Touch_for_Store,                           UNIT_MEM,       2,      0 },
+  { itable_Data_Cache_Block_set_to_Zero,                               UNIT_MEM,       10,     0 },
+  { itable_Divide_Word,                                                        UNIT_INT,       37,     0 },
+  { itable_Divide_Word_Unsigned,                                       UNIT_INT,       37,     0 },
+  { itable_Enforce_Inorder_Execution_of_IO,                            UNIT_SREG,      1,      0 },
+  { itable_Equivalent,                                                 UNIT_INT,       1,      0 },
+  { itable_Extend_Sign_Byte,                                           UNIT_INT,       1,      0 },
+  { itable_Extend_Sign_Half_Word,                                      UNIT_INT,       1,      0 },
+  { itable_External_Control_In_Word_Indexed,                           UNIT_MEM,       2,      0 },
+  { itable_External_Control_Out_Word_Indexed,                          UNIT_MEM,       2,      0 },
+  { itable_Floating_Absolute_Value,                                    UNIT_FPU,       1,      0 },
+  { itable_Floating_Add,                                               UNIT_FPU,       1,      0 },
+  { itable_Floating_Add_Single,                                                UNIT_FPU,       1,      0 },
+  { itable_Floating_Compare_Ordered,                                   UNIT_FPU,       1,      0 },
+  { itable_Floating_Compare_Unordered,                                 UNIT_FPU,       1,      0 },
+  { itable_Floating_Convert_To_Integer_Word,                           UNIT_FPU,       1,      0 },
+  { itable_Floating_Convert_To_Integer_Word_with_round_towards_Zero,   UNIT_FPU,       1,      0 },
+  { itable_Floating_Divide,                                            UNIT_FPU,       33,     0 },
+  { itable_Floating_Divide_Single,                                     UNIT_FPU,       18,     0 },
+  { itable_Floating_Move_Register,                                     UNIT_FPU,       1,      0 },
+  { itable_Floating_Multiply,                                          UNIT_FPU,       2,      0 },
+  { itable_Floating_MultiplyAdd,                                       UNIT_FPU,       2,      0 },
+  { itable_Floating_MultiplyAdd_Single,                                        UNIT_FPU,       1,      0 },
+  { itable_Floating_MultiplySubtract,                                  UNIT_FPU,       2,      0 },
+  { itable_Floating_MultiplySubtract_Single,                           UNIT_FPU,       1,      0 },
+  { itable_Floating_Multiply_Single,                                   UNIT_FPU,       1,      0 },
+  { itable_Floating_Negate,                                            UNIT_FPU,       1,      0 },
+  { itable_Floating_Negative_Absolute_Value,                           UNIT_FPU,       1,      0 },
+  { itable_Floating_Negative_MultiplyAdd,                              UNIT_FPU,       2,      0 },
+  { itable_Floating_Negative_MultiplyAdd_Single,                       UNIT_FPU,       1,      0 },
+  { itable_Floating_Negative_MultiplySubtract,                         UNIT_FPU,       2,      0 },
+  { itable_Floating_Negative_MultiplySubtract_Single,                  UNIT_FPU,       1,      0 },
+  { itable_Floating_Reciprocal_Estimate_Single,                                UNIT_FPU,       18,     0 },
+  { itable_Floating_Reciprocal_Square_Root_Estimate,                   UNIT_FPU,       1,      0 },
+  { itable_Floating_Round_to_SinglePrecision,                          UNIT_FPU,       1,      0 },
+  { itable_Floating_Select,                                            UNIT_FPU,       1,      0 },
+  { itable_Floating_Square_Root,                                       UNIT_UNKNOWN,   0,      0 },
+  { itable_Floating_Square_Root_Single,                                        UNIT_UNKNOWN,   0,      0 },
+  { itable_Floating_Subtract,                                          UNIT_FPU,       1,      0 },
+  { itable_Floating_Subtract_Single,                                   UNIT_FPU,       1,      0 },
+  { itable_Instruction_Cache_Block_Invalidate,                         UNIT_MEM,       3,      0 },
+  { itable_Instruction_Synchronize,                                    UNIT_SREG,      1,      0 },
+  { itable_Load_Byte_and_Zero,                                         UNIT_MEM,       2,      LOAD },
+  { itable_Load_Byte_and_Zero_Indexed,                                 UNIT_MEM,       2,      LOAD },
+  { itable_Load_Byte_and_Zero_with_Update,                             UNIT_MEM,       2,      LOAD },
+  { itable_Load_Byte_and_Zero_with_Update_Indexed,                     UNIT_MEM,       2,      LOAD },
+  { itable_Load_FloatingPoint_Double,                                  UNIT_MEM,       2,      LOAD },
+  { itable_Load_FloatingPoint_Double_Indexed,                          UNIT_MEM,       2,      LOAD },
+  { itable_Load_FloatingPoint_Double_with_Update,                      UNIT_MEM,       2,      LOAD },
+  { itable_Load_FloatingPoint_Double_with_Update_Indexed,              UNIT_MEM,       2,      LOAD },
+  { itable_Load_FloatingPoint_Single,                                  UNIT_MEM,       2,      LOAD },
+  { itable_Load_FloatingPoint_Single_Indexed,                          UNIT_MEM,       2,      LOAD },
+  { itable_Load_FloatingPoint_Single_with_Update,                      UNIT_MEM,       2,      LOAD },
+  { itable_Load_FloatingPoint_Single_with_Update_Indexed,              UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_Algebraic,                                    UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_Algebraic_Indexed,                            UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_Algebraic_with_Update,                                UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_Algebraic_with_Update_Indexed,                        UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_ByteReverse_Indexed,                          UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_and_Zero,                                     UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_and_Zero_Indexed,                             UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_and_Zero_with_Update,                         UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_and_Zero_with_Update_Indexed,                 UNIT_MEM,       2,      LOAD },
+  { itable_Load_Multiple_Word,                                         UNIT_MEM,       2,      LOAD },
+  { itable_Load_String_Word_Immediate,                                 UNIT_MEM,       2,      LOAD },
+  { itable_Load_String_Word_Indexed,                                   UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_And_Reserve_Indexed,                              UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_ByteReverse_Indexed,                              UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_and_Zero,                                         UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_and_Zero_Indexed,                                 UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_and_Zero_with_Update,                             UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_and_Zero_with_Update_Indexed,                     UNIT_MEM,       2,      LOAD },
+  { itable_Move_Condition_Register_Field,                              UNIT_SREG,      1,      0 },
+  { itable_Move_From_Condition_Register,                               UNIT_SREG,      1,      0 },
+  { itable_Move_From_FPSCR,                                            UNIT_FPU,       1,      0 },
+  { itable_Move_From_Machine_State_Register,                           UNIT_SREG,      1,      0 },
+  { itable_Move_From_Segment_Register,                                 UNIT_SREG,      3,      0 },
+  { itable_Move_From_Segment_Register_Indirect,                                UNIT_SREG,      1,      0 },
+  { itable_Move_From_Time_Base,                                                UNIT_SREG,      1,      0 },
+  { itable_Move_To_FPSCR_Bit_0,                                                UNIT_FPU,       1,      0 },
+  { itable_Move_To_FPSCR_Bit_1,                                                UNIT_FPU,       1,      0 },
+  { itable_Move_To_FPSCR_Field_Immediate,                              UNIT_FPU,       1,      0 },
+  { itable_Move_To_FPSCR_Fields,                                       UNIT_FPU,       1,      0 },
+  { itable_Move_To_Machine_State_Register,                             UNIT_SREG,      2,      0 },
+  { itable_Move_To_Segment_Register,                                   UNIT_SREG,      2,      0 },
+  { itable_Move_To_Segment_Register_Indirect,                          UNIT_SREG,      2,      0 },
+  { itable_Move_from_Special_Purpose_Register,                         UNIT_SREG,      1,      0 },
+  { itable_Move_to_Condition_Register_Fields,                          UNIT_SREG,      1,      0 },
+  { itable_Move_to_Condition_Register_from_FPSCR,                      UNIT_FPU,       1,      0 },
+  { itable_Move_to_Condition_Register_from_XER,                                UNIT_SREG,      1,      0 },
+  { itable_Move_to_Special_Purpose_Register,                           UNIT_SREG,      1,      0 },
+  { itable_Multiply_High_Word,                                         UNIT_INT,       5,      0 },
+  { itable_Multiply_High_Word_Unsigned,                                        UNIT_INT,       6,      0 },
+  { itable_Multiply_Low_Immediate,                                     UNIT_INT,       3,      0 },
+  { itable_Multiply_Low_Word,                                          UNIT_INT,       5,      0 },
+  { itable_NAND,                                                       UNIT_INT,       1,      0 },
+  { itable_NOR,                                                                UNIT_INT,       1,      0 },
+  { itable_Negate,                                                     UNIT_INT,       1,      0 },
+  { itable_OR,                                                         UNIT_INT,       1,      0 },
+  { itable_OR_Immediate,                                               UNIT_INT,       1,      0 },
+  { itable_OR_Immediate_Shifted,                                       UNIT_INT,       1,      0 },
+  { itable_OR_with_Complement,                                         UNIT_INT,       1,      0 },
+  { itable_Return_From_Interrupt,                                      UNIT_SREG,      3,      0 },
+  { itable_Rotate_Left_Word_Immediate_then_AND_with_Mask,              UNIT_INT,       1,      0 },
+  { itable_Rotate_Left_Word_Immediate_then_Mask_Insert,                        UNIT_INT,       1,      0 },
+  { itable_Rotate_Left_Word_then_AND_with_Mask,                                UNIT_INT,       1,      0 },
+  { itable_Shift_Left_Word,                                            UNIT_INT,       1,      0 },
+  { itable_Shift_Right_Algebraic_Word,                                 UNIT_INT,       1,      0 },
+  { itable_Shift_Right_Algebraic_Word_Immediate,                       UNIT_INT,       1,      0 },
+  { itable_Shift_Right_Word,                                           UNIT_INT,       1,      0 },
+  { itable_Store_Byte,                                                 UNIT_MEM,       1,      STORE },
+  { itable_Store_Byte_Indexed,                                         UNIT_MEM,       1,      STORE },
+  { itable_Store_Byte_with_Update,                                     UNIT_MEM,       1,      STORE },
+  { itable_Store_Byte_with_Update_Indexed,                             UNIT_MEM,       1,      STORE },
+  { itable_Store_FloatingPoint_Double,                                 UNIT_MEM,       1,      STORE },
+  { itable_Store_FloatingPoint_Double_Indexed,                         UNIT_MEM,       1,      STORE },
+  { itable_Store_FloatingPoint_Double_with_Update,                     UNIT_MEM,       1,      STORE },
+  { itable_Store_FloatingPoint_Double_with_Update_Indexed,             UNIT_MEM,       1,      STORE },
+  { itable_Store_FloatingPoint_Single,                                 UNIT_MEM,       1,      STORE },
+  { itable_Store_FloatingPoint_Single_Indexed,                         UNIT_MEM,       1,      STORE },
+  { itable_Store_FloatingPoint_Single_with_Update,                     UNIT_MEM,       1,      STORE },
+  { itable_Store_FloatingPoint_Single_with_Update_Indexed,             UNIT_MEM,       1,      STORE },
+  { itable_Store_FloatingPoint_as_Integer_Word_Indexed,                        UNIT_MEM,       1,      STORE },
+  { itable_Store_Half_Word,                                            UNIT_MEM,       1,      STORE },
+  { itable_Store_Half_Word_ByteReversed_Indexed,                       UNIT_MEM,       1,      STORE },
+  { itable_Store_Half_Word_Indexed,                                    UNIT_MEM,       1,      STORE },
+  { itable_Store_Half_Word_with_Update,                                        UNIT_MEM,       1,      STORE },
+  { itable_Store_Half_Word_with_Update_Indexed,                                UNIT_MEM,       1,      STORE },
+  { itable_Store_Multiple_Word,                                                UNIT_MEM,       1,      STORE },
+  { itable_Store_String_Word_Immedate,                                 UNIT_MEM,       1,      STORE },
+  { itable_Store_String_Word_Indexed,                                  UNIT_MEM,       1,      STORE },
+  { itable_Store_Word,                                                 UNIT_MEM,       1,      STORE },
+  { itable_Store_Word_ByteReversed_Indexed,                            UNIT_MEM,       1,      STORE },
+  { itable_Store_Word_Conditional_Indexed,                             UNIT_MEM,       1,      STORE },
+  { itable_Store_Word_Indexed,                                         UNIT_MEM,       1,      STORE },
+  { itable_Store_Word_with_Update,                                     UNIT_MEM,       1,      STORE },
+  { itable_Store_Word_with_Update_Indexed,                             UNIT_MEM,       1,      STORE },
+  { itable_Subtract_From,                                              UNIT_INT,       1,      0 },
+  { itable_Subtract_From_Carrying,                                     UNIT_INT,       1,      0 },
+  { itable_Subtract_From_Extended,                                     UNIT_INT,       1,      0 },
+  { itable_Subtract_From_Immediate_Carrying,                           UNIT_INT,       1,      0 },
+  { itable_Subtract_From_Minus_One_Extended,                           UNIT_INT,       1,      0 },
+  { itable_Subtract_from_Zero_Extended,                                        UNIT_INT,       1,      0 },
+  { itable_Synchronize,                                                        UNIT_SREG,      3,      0 },
+  { itable_System_Call,                                                        UNIT_MEM,       3,      0 },
+  { itable_TLB_Invalidate_All,                                         UNIT_MEM,       3,      0 },
+  { itable_TLB_Invalidate_Entry,                                       UNIT_MEM,       3,      0 },
+  { itable_TLB_Sychronize,                                             UNIT_MEM,       3,      0 },
+  { itable_Trap_Word,                                                  UNIT_INT,       2,      0 },
+  { itable_Trap_Word_Immediate,                                                UNIT_INT,       2,      0 },
+  { itable_XOR,                                                                UNIT_INT,       1,      0 },
+  { itable_XOR_Immediate,                                              UNIT_INT,       1,      0 },
+  { itable_XOR_Immediate_Shifted,                                      UNIT_INT,       1,      0 },
+  { nr_itable_entries,                                                 UNIT_UNKNOWN,   -1,     0 },
+};
+
+\f
+/* 604 timings */
+static timing time_604[] = {
+  /* Instruction index                                                 Function unit   Cycles  Flags */
+  { itable_AND,                                                                UNIT_INT,       1,      0 },
+  { itable_AND_Immediate,                                              UNIT_INT,       1,      0 },
+  { itable_AND_Immediate_Shifted,                                      UNIT_INT,       1,      0 },
+  { itable_AND_with_Complement,                                                UNIT_INT,       1,      0 },
+  { itable_Add,                                                                UNIT_INT,       1,      0 },
+  { itable_Add_Carrying,                                               UNIT_INT,       1,      0 },
+  { itable_Add_Extended,                                               UNIT_INT,       1,      0 },
+  { itable_Add_Immediate,                                              UNIT_INT,       1,      0 },
+  { itable_Add_Immediate_Carrying,                                     UNIT_INT,       1,      0 },
+  { itable_Add_Immediate_Carrying_and_Record,                          UNIT_INT,       1,      0 },
+  { itable_Add_Immediate_Shifted,                                      UNIT_INT,       1,      0 },
+  { itable_Add_to_Minus_One_Extended,                                  UNIT_INT,       1,      0 },
+  { itable_Add_to_Zero_Extended,                                       UNIT_INT,       1,      0 },
+  { itable_Branch,                                                     UNIT_BRANCH,    1,      0 },
+  { itable_Branch_Conditional,                                         UNIT_BRANCH,    1,      0 },
+  { itable_Branch_Conditional_to_Count_Register,                       UNIT_BRANCH,    1,      0 },
+  { itable_Branch_Conditional_to_Link_Register,                                UNIT_BRANCH,    1,      0 },
+  { itable_Compare,                                                    UNIT_INT,       1,      0 },
+  { itable_Compare_Immediate,                                          UNIT_INT,       1,      0 },
+  { itable_Compare_Logical,                                            UNIT_INT,       1,      0 },
+  { itable_Compare_Logical_Immediate,                                  UNIT_INT,       1,      0 },
+  { itable_Condition_Register_AND,                                     UNIT_INT,       1,      0 },
+  { itable_Condition_Register_AND_with_Complement,                     UNIT_INT,       1,      0 },
+  { itable_Condition_Register_Equivalent,                              UNIT_INT,       1,      0 },
+  { itable_Condition_Register_NAND,                                    UNIT_INT,       1,      0 },
+  { itable_Condition_Register_NOR,                                     UNIT_INT,       1,      0 },
+  { itable_Condition_Register_OR,                                      UNIT_INT,       1,      0 },
+  { itable_Condition_Register_OR_with_Complement,                      UNIT_INT,       1,      0 },
+  { itable_Condition_Register_XOR,                                     UNIT_INT,       1,      0 },
+  { itable_Count_Leading_Zeros_Word,                                   UNIT_INT,       1,      0 },
+  { itable_Data_Cache_Block_Flush,                                     UNIT_MEM,       1,      0 },
+  { itable_Data_Cache_Block_Invalidate,                                        UNIT_MEM,       1,      0 },
+  { itable_Data_Cache_Block_Store,                                     UNIT_MEM,       1,      0 },
+  { itable_Data_Cache_Block_Touch,                                     UNIT_MEM,       1,      0 },
+  { itable_Data_Cache_Block_Touch_for_Store,                           UNIT_MEM,       1,      0 },
+  { itable_Data_Cache_Block_set_to_Zero,                               UNIT_MEM,       3,      0 },
+  { itable_Divide_Word,                                                        UNIT_CINT,      20,     0 },
+  { itable_Divide_Word_Unsigned,                                       UNIT_CINT,      20,     0 },
+  { itable_Enforce_Inorder_Execution_of_IO,                            UNIT_INT,       1,      0 },
+  { itable_Equivalent,                                                 UNIT_INT,       1,      0 },
+  { itable_Extend_Sign_Byte,                                           UNIT_INT,       1,      0 },
+  { itable_Extend_Sign_Half_Word,                                      UNIT_INT,       1,      0 },
+  { itable_External_Control_In_Word_Indexed,                           UNIT_MEM,       2,      0 },
+  { itable_External_Control_Out_Word_Indexed,                          UNIT_MEM,       3,      0 },
+  { itable_Floating_Absolute_Value,                                    UNIT_FPU,       3,      0 },
+  { itable_Floating_Add,                                               UNIT_FPU,       3,      0 },
+  { itable_Floating_Add_Single,                                                UNIT_FPU,       3,      0 },
+  { itable_Floating_Compare_Ordered,                                   UNIT_FPU,       3,      0 },
+  { itable_Floating_Compare_Unordered,                                 UNIT_FPU,       3,      0 },
+  { itable_Floating_Convert_To_Integer_Word,                           UNIT_FPU,       3,      0 },
+  { itable_Floating_Convert_To_Integer_Word_with_round_towards_Zero,   UNIT_FPU,       3,      0 },
+  { itable_Floating_Divide,                                            UNIT_FPU,       32,     0 },
+  { itable_Floating_Divide_Single,                                     UNIT_FPU,       18,     0 },
+  { itable_Floating_Move_Register,                                     UNIT_FPU,       3,      0 },
+  { itable_Floating_Multiply,                                          UNIT_FPU,       3,      0 },
+  { itable_Floating_MultiplyAdd,                                       UNIT_FPU,       3,      0 },
+  { itable_Floating_MultiplyAdd_Single,                                        UNIT_FPU,       3,      0 },
+  { itable_Floating_MultiplySubtract,                                  UNIT_FPU,       3,      0 },
+  { itable_Floating_MultiplySubtract_Single,                           UNIT_FPU,       3,      0 },
+  { itable_Floating_Multiply_Single,                                   UNIT_FPU,       3,      0 },
+  { itable_Floating_Negate,                                            UNIT_FPU,       3,      0 },
+  { itable_Floating_Negative_Absolute_Value,                           UNIT_FPU,       3,      0 },
+  { itable_Floating_Negative_MultiplyAdd,                              UNIT_FPU,       3,      0 },
+  { itable_Floating_Negative_MultiplyAdd_Single,                       UNIT_FPU,       3,      0 },
+  { itable_Floating_Negative_MultiplySubtract,                         UNIT_FPU,       3,      0 },
+  { itable_Floating_Negative_MultiplySubtract_Single,                  UNIT_FPU,       3,      0 },
+  { itable_Floating_Reciprocal_Estimate_Single,                                UNIT_FPU,       18,     0 },
+  { itable_Floating_Reciprocal_Square_Root_Estimate,                   UNIT_FPU,       3,      0 },
+  { itable_Floating_Round_to_SinglePrecision,                          UNIT_FPU,       3,      0 },
+  { itable_Floating_Select,                                            UNIT_FPU,       3,      0 },
+  { itable_Floating_Square_Root,                                       UNIT_UNKNOWN,   0,      0 },
+  { itable_Floating_Square_Root_Single,                                        UNIT_UNKNOWN,   0,      0 },
+  { itable_Floating_Subtract,                                          UNIT_FPU,       3,      0 },
+  { itable_Floating_Subtract_Single,                                   UNIT_FPU,       3,      0 },
+  { itable_Instruction_Cache_Block_Invalidate,                         UNIT_MEM,       1,      0 },
+  { itable_Instruction_Synchronize,                                    UNIT_INT,       1,      0 },
+  { itable_Load_Byte_and_Zero,                                         UNIT_MEM,       2,      LOAD },
+  { itable_Load_Byte_and_Zero_Indexed,                                 UNIT_MEM,       2,      LOAD },
+  { itable_Load_Byte_and_Zero_with_Update,                             UNIT_MEM,       2,      LOAD },
+  { itable_Load_Byte_and_Zero_with_Update_Indexed,                     UNIT_MEM,       2,      LOAD },
+  { itable_Load_FloatingPoint_Double,                                  UNIT_MEM,       3,      LOAD },
+  { itable_Load_FloatingPoint_Double_Indexed,                          UNIT_MEM,       3,      LOAD },
+  { itable_Load_FloatingPoint_Double_with_Update,                      UNIT_MEM,       3,      LOAD },
+  { itable_Load_FloatingPoint_Double_with_Update_Indexed,              UNIT_MEM,       3,      LOAD },
+  { itable_Load_FloatingPoint_Single,                                  UNIT_MEM,       3,      LOAD },
+  { itable_Load_FloatingPoint_Single_Indexed,                          UNIT_MEM,       3,      LOAD },
+  { itable_Load_FloatingPoint_Single_with_Update,                      UNIT_MEM,       3,      LOAD },
+  { itable_Load_FloatingPoint_Single_with_Update_Indexed,              UNIT_MEM,       3,      LOAD },
+  { itable_Load_Halfword_Algebraic,                                    UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_Algebraic_Indexed,                            UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_Algebraic_with_Update,                                UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_Algebraic_with_Update_Indexed,                        UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_ByteReverse_Indexed,                          UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_and_Zero,                                     UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_and_Zero_Indexed,                             UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_and_Zero_with_Update,                         UNIT_MEM,       2,      LOAD },
+  { itable_Load_Halfword_and_Zero_with_Update_Indexed,                 UNIT_MEM,       2,      LOAD },
+  { itable_Load_Multiple_Word,                                         UNIT_MEM,       2,      LOAD },
+  { itable_Load_String_Word_Immediate,                                 UNIT_MEM,       2,      LOAD },
+  { itable_Load_String_Word_Indexed,                                   UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_And_Reserve_Indexed,                              UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_ByteReverse_Indexed,                              UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_and_Zero,                                         UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_and_Zero_Indexed,                                 UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_and_Zero_with_Update,                             UNIT_MEM,       2,      LOAD },
+  { itable_Load_Word_and_Zero_with_Update_Indexed,                     UNIT_MEM,       2,      LOAD },
+  { itable_Move_Condition_Register_Field,                              UNIT_BRANCH,    1,      0 },
+  { itable_Move_From_Condition_Register,                               UNIT_CINT,      3,      0 },
+  { itable_Move_From_FPSCR,                                            UNIT_FPU,       3,      0 },
+  { itable_Move_From_Machine_State_Register,                           UNIT_CINT,      3,      0 },
+  { itable_Move_From_Segment_Register,                                 UNIT_CINT,      3,      0 },
+  { itable_Move_From_Segment_Register_Indirect,                                UNIT_CINT,      3,      0 },
+  { itable_Move_From_Time_Base,                                                UNIT_CINT,      3,      0 },
+  { itable_Move_To_FPSCR_Bit_0,                                                UNIT_FPU,       3,      0 },
+  { itable_Move_To_FPSCR_Bit_1,                                                UNIT_FPU,       3,      0 },
+  { itable_Move_To_FPSCR_Field_Immediate,                              UNIT_FPU,       3,      0 },
+  { itable_Move_To_FPSCR_Fields,                                       UNIT_FPU,       3,      0 },
+  { itable_Move_To_Machine_State_Register,                             UNIT_CINT,      1,      0 },
+  { itable_Move_To_Segment_Register,                                   UNIT_CINT,      1,      0 },
+  { itable_Move_To_Segment_Register_Indirect,                          UNIT_CINT,      1,      0 },
+  { itable_Move_from_Special_Purpose_Register,                         UNIT_CINT,      1,      0 },
+  { itable_Move_to_Condition_Register_Fields,                          UNIT_CINT,      1,      0 },
+  { itable_Move_to_Condition_Register_from_FPSCR,                      UNIT_FPU,       3,      0 },
+  { itable_Move_to_Condition_Register_from_XER,                                UNIT_CINT,      3,      0 },
+  { itable_Move_to_Special_Purpose_Register,                           UNIT_CINT,      1,      0 },
+  { itable_Multiply_High_Word,                                         UNIT_CINT,      4,      0 },
+  { itable_Multiply_High_Word_Unsigned,                                        UNIT_CINT,      4,      0 },
+  { itable_Multiply_Low_Immediate,                                     UNIT_CINT,      3,      0 },
+  { itable_Multiply_Low_Word,                                          UNIT_CINT,      4,      0 },
+  { itable_NAND,                                                       UNIT_INT,       1,      0 },
+  { itable_NOR,                                                                UNIT_INT,       1,      0 },
+  { itable_Negate,                                                     UNIT_INT,       1,      0 },
+  { itable_OR,                                                         UNIT_INT,       1,      0 },
+  { itable_OR_Immediate,                                               UNIT_INT,       1,      0 },
+  { itable_OR_Immediate_Shifted,                                       UNIT_INT,       1,      0 },
+  { itable_OR_with_Complement,                                         UNIT_INT,       1,      0 },
+  { itable_Return_From_Interrupt,                                      UNIT_INT,       3,      0 },
+  { itable_Rotate_Left_Word_Immediate_then_AND_with_Mask,              UNIT_INT,       1,      0 },
+  { itable_Rotate_Left_Word_Immediate_then_Mask_Insert,                        UNIT_INT,       1,      0 },
+  { itable_Rotate_Left_Word_then_AND_with_Mask,                                UNIT_INT,       1,      0 },
+  { itable_Shift_Left_Word,                                            UNIT_INT,       1,      0 },
+  { itable_Shift_Right_Algebraic_Word,                                 UNIT_INT,       1,      0 },
+  { itable_Shift_Right_Algebraic_Word_Immediate,                       UNIT_INT,       1,      0 },
+  { itable_Shift_Right_Word,                                           UNIT_INT,       1,      0 },
+  { itable_Store_Byte,                                                 UNIT_MEM,       3,      STORE },
+  { itable_Store_Byte_Indexed,                                         UNIT_MEM,       3,      STORE },
+  { itable_Store_Byte_with_Update,                                     UNIT_MEM,       3,      STORE },
+  { itable_Store_Byte_with_Update_Indexed,                             UNIT_MEM,       3,      STORE },
+  { itable_Store_FloatingPoint_Double,                                 UNIT_MEM,       3,      STORE },
+  { itable_Store_FloatingPoint_Double_Indexed,                         UNIT_MEM,       3,      STORE },
+  { itable_Store_FloatingPoint_Double_with_Update,                     UNIT_MEM,       3,      STORE },
+  { itable_Store_FloatingPoint_Double_with_Update_Indexed,             UNIT_MEM,       3,      STORE },
+  { itable_Store_FloatingPoint_Single,                                 UNIT_MEM,       3,      STORE },
+  { itable_Store_FloatingPoint_Single_Indexed,                         UNIT_MEM,       3,      STORE },
+  { itable_Store_FloatingPoint_Single_with_Update,                     UNIT_MEM,       3,      STORE },
+  { itable_Store_FloatingPoint_Single_with_Update_Indexed,             UNIT_MEM,       3,      STORE },
+  { itable_Store_FloatingPoint_as_Integer_Word_Indexed,                        UNIT_MEM,       3,      STORE },
+  { itable_Store_Half_Word,                                            UNIT_MEM,       3,      STORE },
+  { itable_Store_Half_Word_ByteReversed_Indexed,                       UNIT_MEM,       3,      STORE },
+  { itable_Store_Half_Word_Indexed,                                    UNIT_MEM,       3,      STORE },
+  { itable_Store_Half_Word_with_Update,                                        UNIT_MEM,       3,      STORE },
+  { itable_Store_Half_Word_with_Update_Indexed,                                UNIT_MEM,       3,      STORE },
+  { itable_Store_Multiple_Word,                                                UNIT_MEM,       3,      STORE },
+  { itable_Store_String_Word_Immedate,                                 UNIT_MEM,       3,      STORE },
+  { itable_Store_String_Word_Indexed,                                  UNIT_MEM,       3,      STORE },
+  { itable_Store_Word,                                                 UNIT_MEM,       3,      STORE },
+  { itable_Store_Word_ByteReversed_Indexed,                            UNIT_MEM,       3,      STORE },
+  { itable_Store_Word_Conditional_Indexed,                             UNIT_MEM,       3,      STORE },
+  { itable_Store_Word_Indexed,                                         UNIT_MEM,       3,      STORE },
+  { itable_Store_Word_with_Update,                                     UNIT_MEM,       3,      STORE },
+  { itable_Store_Word_with_Update_Indexed,                             UNIT_MEM,       3,      STORE },
+  { itable_Subtract_From,                                              UNIT_INT,       1,      0 },
+  { itable_Subtract_From_Carrying,                                     UNIT_INT,       1,      0 },
+  { itable_Subtract_From_Extended,                                     UNIT_INT,       1,      0 },
+  { itable_Subtract_From_Immediate_Carrying,                           UNIT_INT,       1,      0 },
+  { itable_Subtract_From_Minus_One_Extended,                           UNIT_INT,       1,      0 },
+  { itable_Subtract_from_Zero_Extended,                                        UNIT_INT,       1,      0 },
+  { itable_Synchronize,                                                        UNIT_INT,       1,      0 },
+  { itable_System_Call,                                                        UNIT_MEM,       1,      0 },
+  { itable_TLB_Invalidate_All,                                         UNIT_MEM,       1,      0 },
+  { itable_TLB_Invalidate_Entry,                                       UNIT_MEM,       1,      0 },
+  { itable_TLB_Sychronize,                                             UNIT_MEM,       1,      0 },
+  { itable_Trap_Word,                                                  UNIT_INT,       1,      0 },
+  { itable_Trap_Word_Immediate,                                                UNIT_INT,       1,      0 },
+  { itable_XOR,                                                                UNIT_INT,       1,      0 },
+  { itable_XOR_Immediate,                                              UNIT_INT,       1,      0 },
+  { itable_XOR_Immediate_Shifted,                                      UNIT_INT,       1,      0 },
+  { nr_itable_entries,                                                 UNIT_UNKNOWN,   -1,     0 },
+};
+
+\f
+INLINE_FUNCTION_UNIT function_unit *
+function_unit_create(void)
+{
+  function_unit *new_func;
+  timing *timing_ptr;
+
+  if (!WITH_FUNCTION_UNIT)
+    return (function_unit *)0;
+
+  new_func = ZALLOC(function_unit);
+
+  /* Get the model specific timing information */
+  switch (CURRENT_PPC_MODEL) {
+  default:             timing_ptr = (timing *)0;       break;
+  case PPC_MODEL_603:  timing_ptr = time_603;          break;
+  case PPC_MODEL_603e: timing_ptr = time_603;          break;
+  case PPC_MODEL_604:  timing_ptr = time_604;          break;
+  }
+
+  /* If we have it, provide model specific timing info */
+  if (timing_ptr) {
+    for (; timing_ptr->cycles >= 0; timing_ptr++) {
+      int i = (int)timing_ptr->index;
+      unit_index unit = timing_ptr->unit;
+
+      /* The 603 as compared to the 603e doesn't support putting add/cmp instructions
+        in the system register unit, so convert these instructions back to normal
+        integer instructions.  */
+      if (CURRENT_PPC_MODEL == PPC_MODEL_603 && unit == UNIT_SINT)
+       unit = UNIT_INT;
+
+      new_func->time[i].unit = unit;
+      new_func->time[i].cycles = timing_ptr->cycles;
+      new_func->time[i].flags = timing_ptr->flags;
+    }
+  }
+
+  return new_func;
+}
+
+INLINE_FUNCTION_UNIT void
+function_unit_init(function_unit *func_unit)
+{
+  func_unit->old_program_counter = 0;
+}
+
+INLINE_FUNCTION_UNIT void
+function_unit_halt(cpu *processor,
+                  function_unit *func_unit)
+{
+}
+
+INLINE_FUNCTION_UNIT function_unit_print *
+function_unit_mon_info(function_unit *func_unit)
+{
+  function_unit_print *head;
+  function_unit_print *tail;
+  int i;
+
+  head = tail = ZALLOC(function_unit_print);
+  tail->count = func_unit->nr_stalls;
+  tail->name = "stall";
+  tail->suffix_plural = "s";
+  tail->suffix_singular = "";
+
+  tail->next = ZALLOC(function_unit_print);
+  tail = tail->next;
+  tail->count = func_unit->nr_branches;
+  tail->name = "branch";
+  tail->suffix_plural = "es";
+  tail->suffix_singular = "";
+
+  for (i = 0; i < (int)NR_UNITS; i++) {
+    if (func_unit->nr_units[i]) {
+      tail->next = ZALLOC(function_unit_print);
+      tail = tail->next;
+      tail->count = func_unit->nr_units[i];
+      tail->name = unit_names[i];
+      tail->suffix_plural = "s";
+      tail->suffix_singular = "";
+    }
+  }
+
+  tail->next = (function_unit_print *)0;
+  return head;
+}
+
+INLINE_FUNCTION_UNIT void
+function_unit_mon_free(function_unit *func_unit,
+                      function_unit_print *ptr)
+{
+  function_unit_print *next;
+
+  while (ptr) {
+    next = ptr->next;
+    free((void *)ptr);
+    ptr = next;
+  }
+}
+
+INLINE_FUNCTION_UNIT void
+function_unit_issue(itable_index index,
+                   function_unit *func_unit,
+                   unsigned_word cia)
+{
+  if (func_unit->old_program_counter+4 != cia)
+    func_unit->nr_branches++;
+
+  func_unit->old_program_counter = cia;
+  func_unit->nr_units[ (int)func_unit->time[ (int)index ].unit ]++;
+}
+
+INLINE_FUNCTION_UNIT void
+function_unit_model(const char *model)
+{
+  if (!strcmp (model, "601"))
+    current_ppc_model = PPC_MODEL_601;
+  else if (!strcmp (model, "602"))
+    current_ppc_model = PPC_MODEL_602;
+  else if (!strcmp (model, "603"))
+    current_ppc_model = PPC_MODEL_603;
+  else if (!strcmp (model, "603e"))
+    current_ppc_model = PPC_MODEL_603e;
+  else if (!strcmp (model, "604"))
+    current_ppc_model = PPC_MODEL_604;
+  else if (!strcmp (model, "403"))
+    current_ppc_model = PPC_MODEL_403;
+  else if (!strcmp (model, "505"))
+    current_ppc_model = PPC_MODEL_505;
+  else if (!strcmp (model, "821"))
+    current_ppc_model = PPC_MODEL_821;
+  else if (!strcmp (model, "860"))
+    current_ppc_model = PPC_MODEL_860;
+  else
+    error ("Unknown PowerPC model %s", model);
+}
+
+#endif /* _FUNCTION_UNIT_C_ */
diff --git a/sim/ppc/function_unit.h b/sim/ppc/function_unit.h
new file mode 100644 (file)
index 0000000..904abce
--- /dev/null
@@ -0,0 +1,71 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+
+    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 _FUNCTION_UNIT_H_
+#define _FUNCTION_UNIT_H_
+
+#include "itable.h"
+
+#ifndef INLINE_FUNCTION_UNIT
+#define INLINE_FUNCTION_UNIT
+#endif
+
+/* basic types */
+
+typedef struct _function_unit function_unit;
+
+typedef struct _function_unit_print function_unit_print;
+struct _function_unit_print {
+  function_unit_print *next;
+  const char *name;
+  const char *suffix_singular;
+  const char *suffix_plural;
+  unsigned count;
+};
+
+/* constructor */
+
+INLINE_FUNCTION_UNIT function_unit *function_unit_create
+(void);
+
+INLINE_FUNCTION_UNIT void function_unit_init
+(function_unit *func_unit);
+
+INLINE_FUNCTION_UNIT void function_unit_halt
+(cpu *processor,
+ function_unit *func_unit);
+
+INLINE_FUNCTION_UNIT function_unit_print *function_unit_mon_info
+(function_unit *func_unit);
+
+INLINE_FUNCTION_UNIT void function_unit_mon_free
+(function_unit *func_unit,
+ function_unit_print *ptr);
+
+INLINE_FUNCTION_UNIT void function_unit_issue
+(itable_index index,
+ function_unit *func_unit,
+ unsigned_word cia);
+
+INLINE_FUNCTION_UNIT void function_unit_model
+(const char *model);
+
+#endif /* _FUNCTION_UNIT_H_ */
index 4ac048b..715373a 100644 (file)
     */
 
 
-#ifndef _PPC_INLINE_C_
-#define _PPC_INLINE_C_
+#ifndef _INLINE_C_
+#define _INLINE_C_
 
-#if ENDIAN_INLINE
-#include "ppc-endian.c"
+#if BITS_INLINE
+#include "bits.c"
+#endif
+
+#if SIM_ENDIAN_INLINE
+#include "sim-endian.c"
 #endif
 
 #if ICACHE_INLINE
 #include "mon.c"
 #endif
 
+#if FUNCTION_UNIT_INLINE
+#include "function_unit.c"
+#endif
+
 #if REGISTERS_INLINE
 #include "registers.c"
 #endif
diff --git a/sim/ppc/inline.h b/sim/ppc/inline.h
new file mode 100644 (file)
index 0000000..646e696
--- /dev/null
@@ -0,0 +1,155 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+
+    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 _INLINE_H_
+#define _INLINE_H_
+
+#if SIM_ENDIAN_INLINE
+#if SIM_ENDIAN_INLINE == 2
+#define INLINE_SIM_ENDIAN static INLINE
+#else
+#define INLINE_SIM_ENDIAN static
+#endif
+#endif
+
+#if ICACHE_INLINE
+#if ICACHE_INLINE == 2
+#define INLINE_ICACHE static INLINE
+#else
+#define INLINE_ICACHE static
+#endif
+#endif
+
+#if CORE_INLINE
+#if CORE_INLINE == 2
+#define INLINE_CORE static INLINE
+#else
+#define INLINE_CORE static
+#endif
+#endif
+
+#if VM_INLINE
+#if VM_INLINE == 2
+#define INLINE_VM static INLINE
+#else
+#define INLINE_VM static
+#endif
+#endif
+
+#if CPU_INLINE
+#if CPU_INLINE == 2
+#define INLINE_CPU static INLINE
+#else
+#define INLINE_CPU static
+#endif
+#endif
+
+#if BITS_INLINE
+#if BITS_INLINE == 2
+#define INLINE_BITS static INLINE
+#else
+#define INLINE_BITS static
+#endif
+#endif
+
+#if EVENTS_INLINE
+#if EVENTS_INLINE == 2
+#define INLINE_EVENTS static INLINE
+#else
+#define INLINE_EVENTS static
+#endif
+#endif
+
+#if MON_INLINE
+#if MON_INLINE == 2
+#define INLINE_MON static INLINE
+#else
+#define INLINE_MON static
+#endif
+#endif
+
+#if REGISTERS_INLINE
+#if REGISTERS_INLINE == 2
+#define INLINE_REGISTERS static INLINE
+#else
+#define INLINE_REGISTERS static
+#endif
+#endif
+
+#if INTERRUPTS_INLINE
+#if INTERRUPTS_INLINE == 2
+#define INLINE_INTERRUPTS static INLINE
+#else
+#define INLINE_INTERRUPTS static
+#endif
+#endif
+
+#if DEVICE_TREE_INLINE
+#if DEVICE_TREE_INLINE == 2
+#define INLINE_DEVICE_TREE static INLINE
+#else
+#define INLINE_DEVICE_TREE static
+#endif
+#endif
+
+#if DEVICES_INLINE
+#if DEVICES_INLINE == 2
+#define INLINE_DEVICES static INLINE
+#else
+#define INLINE_DEVICES static
+#endif
+#define STATIC_DEVICES static
+#endif
+
+#if SPREG_INLINE
+#if SPREG_INLINE == 2
+#define INLINE_SPREG static INLINE
+#else
+#define INLINE_SPREG static
+#endif
+#endif
+
+#if SEMANTICS_INLINE && !defined(_SEMANTICS_C_)
+#if SEMANTICS_INLINE == 2
+#define INLINE_SEMANTICS static INLINE
+#else
+#define INLINE_SEMANTICS static
+#endif
+#endif
+
+#if IDECODE_INLINE
+#if IDECODE_INLINE == 2
+#define INLINE_IDECODE static INLINE
+#else
+#define INLINE_IDECODE static
+#endif
+#endif
+
+#if FUNCTION_UNIT_INLINE
+#if FUNCTION_UNIT_INLINE == 2
+#define INLINE_FUNCTION_UNIT static INLINE
+#else
+#define INLINE_FUNCTION_UNIT static
+#endif
+#endif
+
+
+#endif
index 07412be..80b993f 100644 (file)
 #include <stdio.h>
 
 #include "psim.h"
+#include "function_unit.h"
 
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
 #ifdef HAVE_STRING_H
 #include <string.h>
 #else
@@ -80,7 +85,7 @@ zfree(void *chunk)
 static void
 usage(void)
 {
-  printf_filtered("Usage:\n\tpsim [ -t <trace-option> ] <image> [ <image-args> ... ]\n");
+  printf_filtered("Usage:\n\tpsim [ -t <trace-option> ] [-m model] [-i] [-I] <image> [ <image-args> ... ]\n");
   trace_usage();
   error("");
 }
@@ -91,23 +96,27 @@ main(int argc, char **argv)
   psim *system;
   const char *name_of_file;
   char *arg_;
-  unsigned_word stack_pointer;
   psim_status status;
   int letter;
-  int i;
   int print_info = 0;
 
   /* check for arguments -- note sim_calls.c also contains argument processing
      code for the simulator linked within gdb.  */
-  while ((letter = getopt (argc, argv, "It:")) != EOF)
+  while ((letter = getopt (argc, argv, "Iim:t:")) != EOF)
     {
       switch (letter) {
       case 't':
        trace_option(optarg);
        break;
-      case 'I':
+      case 'm':
+       function_unit_model(optarg);
+       break;
+      case 'i':
        print_info = 1;
        break;
+      case 'I':
+       print_info = 2;
+       break;
       default:
        usage();
       }
@@ -133,7 +142,7 @@ main(int argc, char **argv)
 
   /* any final clean up */
   if (print_info)
-    psim_print_info (system, 2);
+    psim_print_info (system, print_info);
 
   /* why did we stop */
   status = psim_get_status(system);
index f086049..0efb1bf 100644 (file)
@@ -29,6 +29,7 @@
 #include "basics.h"
 #include "cpu.h"
 #include "mon.h"
+#include <stdio.h>
 
 #ifdef HAVE_STRING_H
 #include <string.h>
@@ -58,6 +59,7 @@ struct _cpu_mon {
   unsigned issue_count[nr_itable_entries];
   unsigned read_count;
   unsigned write_count;
+  function_unit_print *func_unit_print;
 };
 
 struct _mon {
@@ -101,6 +103,9 @@ mon_issue(itable_index index,
   cpu_mon *monitor = cpu_monitor(processor);
   ASSERT(index <= nr_itable_entries);
   monitor->issue_count[index] += 1;
+
+  if (WITH_FUNCTION_UNIT)
+    function_unit_issue(index, cpu_function_unit(processor), cia);
 }
 
 
@@ -127,7 +132,6 @@ mon_write(unsigned_word ea,
   monitor->write_count += 1;
 }
 
-
 STATIC_INLINE_MON unsigned
 mon_get_number_of_insns(cpu_mon *monitor)
 {
@@ -163,7 +167,8 @@ mon_add_commas(char *buf,
 
 
 INLINE_MON void
-mon_print_info(mon *monitor,
+mon_print_info(psim *system,
+              mon *monitor,
               int verbose)
 {
   char buffer[20];
@@ -172,7 +177,7 @@ mon_print_info(mon *monitor,
   int len_num = 0;
   int len;
   long total_insns = 0;
-  long cpu_insns_second;
+  long cpu_insns_second = 0;
   double cpu_time = 0.0;
 
   for (cpu_nr = 0; cpu_nr < monitor->nr_cpus; cpu_nr++) {
@@ -219,26 +224,55 @@ mon_print_info(mon *monitor,
                          (monitor->cpu_monitor[cpu_nr].issue_count[index] == 1) ? "" : "s");
       }
 
-      if (monitor->cpu_monitor[cpu_nr].read_count)
-       printf_filtered ("CPU #%*d executed %*s data reads.\n",
-                        len_cpu, cpu_nr+1,
-                        len_num, mon_add_commas(buffer,
-                                                sizeof(buffer),
-                                                monitor->cpu_monitor[cpu_nr].read_count));
-
-      if (monitor->cpu_monitor[cpu_nr].write_count)
-       printf_filtered ("CPU #%*d executed %*s data writes.\n",
-                        len_cpu, cpu_nr+1,
-                        len_num, mon_add_commas(buffer,
-                                                sizeof(buffer),
-                                                monitor->cpu_monitor[cpu_nr].write_count));
+      printf_filtered ("\n");
     }
+
+    if (WITH_FUNCTION_UNIT)
+      {
+       function_unit *func_unit = cpu_function_unit(psim_cpu(system, cpu_nr));
+       function_unit_print *ptr = function_unit_mon_info(func_unit);
+       function_unit_print *orig_ptr = ptr;
+
+       while (ptr) {
+         if (ptr->count)
+           printf_filtered("CPU #%*d executed %*s %s%s.\n",
+                           len_cpu, cpu_nr+1,
+                           len_num, mon_add_commas(buffer,
+                                                   sizeof(buffer),
+                                                   ptr->count),
+                           ptr->name,
+                           ((ptr->count == 1)
+                            ? ptr->suffix_singular
+                            : ptr->suffix_plural));
+
+         ptr = ptr->next;
+       }
+
+       function_unit_mon_free(func_unit, orig_ptr);
+      }
+
+    if (monitor->cpu_monitor[cpu_nr].read_count)
+      printf_filtered ("CPU #%*d executed %*s data read%s.\n",
+                      len_cpu, cpu_nr+1,
+                      len_num, mon_add_commas(buffer,
+                                              sizeof(buffer),
+                                              monitor->cpu_monitor[cpu_nr].read_count),
+                      (monitor->cpu_monitor[cpu_nr].read_count == 1) ? "" : "s");
+
+    if (monitor->cpu_monitor[cpu_nr].write_count)
+      printf_filtered ("CPU #%*d executed %*s data write%s.\n",
+                      len_cpu, cpu_nr+1,
+                      len_num, mon_add_commas(buffer,
+                                              sizeof(buffer),
+                                              monitor->cpu_monitor[cpu_nr].write_count),
+                      (monitor->cpu_monitor[cpu_nr].write_count == 1) ? "" : "s");
     
     printf_filtered("CPU #%*d executed %*s instructions in total.\n",
                    len_cpu, cpu_nr+1,
                    len_num, mon_add_commas(buffer,
                                            sizeof(buffer),
                                            mon_get_number_of_insns(&monitor->cpu_monitor[cpu_nr])));
+
   }
 
   if (monitor->nr_cpus > 1)
@@ -246,7 +280,8 @@ mon_print_info(mon *monitor,
                    mon_add_commas(buffer, sizeof(buffer), total_insns));
 
   if (cpu_insns_second)
-    printf_filtered ("\nSimulator speed was %s instructions/second\n",
+    printf_filtered ("%sSimulator speed was %s instructions/second\n",
+                    (monitor->nr_cpus <= 1 && verbose <= 1) ? "" : "\n",
                     mon_add_commas(buffer, sizeof(buffer), cpu_insns_second));
 }
 
diff --git a/sim/ppc/mon.h b/sim/ppc/mon.h
new file mode 100644 (file)
index 0000000..e8ac2e3
--- /dev/null
@@ -0,0 +1,76 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+
+    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 _MON_H_
+#define _MON_H_
+
+#ifndef INLINE_MON
+#define INLINE_MON
+#endif
+
+#include "basics.h"
+#include "itable.h"
+
+/* monitor/logger: counts what the simulation is up to */
+
+typedef struct _mon mon;
+typedef struct _cpu_mon cpu_mon;
+
+INLINE_MON mon *mon_create
+(void);
+
+INLINE_MON cpu_mon *mon_cpu
+(mon *monitor,
+ int cpu_nr);
+
+INLINE_MON void mon_init
+(mon *monitor,
+ int nr_cpus);
+
+INLINE_MON void mon_issue
+(itable_index index,
+ cpu *processor, 
+ unsigned_word cia);
+
+/* NOTE - there is no mon_iload - it is made reduntant by mon_issue()
+   and besides when the cpu's have their own cache, the information is
+   wrong */
+
+INLINE_MON void mon_read
+(unsigned_word ea,
+ unsigned_word ra,
+ unsigned nr_bytes,
+ cpu *processor,
+ unsigned_word cia);
+
+INLINE_MON void mon_write
+(unsigned_word ea,
+ unsigned_word ra,
+ unsigned nr_bytes,
+ cpu *processor,
+ unsigned_word cia);
+
+INLINE_MON void mon_print_info
+(psim *system,
+ mon *monitor,
+ int verbose);
+
+#endif
diff --git a/sim/ppc/ppc-endian.c b/sim/ppc/ppc-endian.c
deleted file mode 100644 (file)
index ec90bb7..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*  This file is part of the program psim.
-
-    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
-
-    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 _ENDIAN_C_
-#define _ENDIAN_C_
-
-#ifndef STATIC_INLINE_ENDIAN
-#define STATIC_INLINE_ENDIAN STATIC_INLINE
-#endif
-
-
-#include "config.h"
-#include "ppc-config.h"
-#include "words.h"
-#include "ppc-endian.h"
-#include "sim_callbacks.h"
-
-#if !defined(SWAP_2) && (WITH_HOST_BYTE_ORDER == LITTLE_ENDIAN) && WITH_NTOH
-#define SWAP_2(SET,RAW) SET htons (RAW)
-#endif
-
-#ifndef        SWAP_2
-#define SWAP_2(SET,RAW) SET (((RAW) >> 8) | ((RAW) << 8))
-#endif
-
-#if !defined(SWAP_4) && (WITH_HOST_BYTE_ORDER == LITTLE_ENDIAN) && WITH_NTOH
-#define SWAP_4(SET,RAW) SET htonl (RAW)
-#endif
-
-#ifndef SWAP_4
-#define        SWAP_4(SET,RAW) SET (((RAW) << 24) | (((RAW) & 0xff00) << 8) | (((RAW) & 0xff0000) >> 8) | ((RAW) >> 24))
-#endif
-
-#ifndef SWAP_8
-#define SWAP_8(SET,RAW)                                                        \
-  union { unsigned_8 dword; unsigned_4 words[2]; } in, out;            \
-  in.dword = RAW;                                                      \
-  SWAP_4 (out.words[0] =, in.words[1]);                                        \
-  SWAP_4 (out.words[1] =, in.words[0]);                                        \
-  SET out.dword;
-#endif
-
-#ifndef ENDIAN_N
-#define ENDIAN_N(NAME,BYTE_SIZE) \
-INLINE unsigned_##BYTE_SIZE \
-endian_##NAME##_##BYTE_SIZE(unsigned_##BYTE_SIZE raw_in) \
-{ \
-  if (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER) { \
-    return raw_in; \
-  } \
-  else { \
-    SWAP_##BYTE_SIZE(return,raw_in); \
-  } \
-}
-#endif
-
-ENDIAN_N(h2t, 2)
-ENDIAN_N(h2t, 4)
-ENDIAN_N(h2t, 8)
-ENDIAN_N(t2h, 2)
-ENDIAN_N(t2h, 4)
-ENDIAN_N(t2h, 8)
-
-#endif /* _ENDIAN_C_ */
diff --git a/sim/ppc/ppc-endian.h b/sim/ppc/ppc-endian.h
deleted file mode 100644 (file)
index 748d2ef..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/*  This file is part of the program psim.
-
-    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
-
-    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 _ENDIAN_H_
-#define _ENDIAN_H_
-
-/* C byte conversion functions */
-
-extern unsigned_1 endian_h2t_1(unsigned_1 x);
-extern unsigned_2 endian_h2t_2(unsigned_2 x);
-extern unsigned_4 endian_h2t_4(unsigned_4 x);
-extern unsigned_8 endian_h2t_8(unsigned_8 x);
-
-extern unsigned_1 endian_t2h_1(unsigned_1 x);
-extern unsigned_2 endian_t2h_2(unsigned_2 x);
-extern unsigned_4 endian_t2h_4(unsigned_4 x);
-extern unsigned_8 endian_t2h_8(unsigned_8 x);
-
-/* Host dependant:
-
-   The CPP below defines information about the compilation host.  In
-   particular it defines the macro's:
-
-       WITH_HOST_BYTE_ORDER    The byte order of the host. Could
-                               be any of LITTLE_ENDIAN, BIG_ENDIAN
-                               or 0 (unknown).  Those macro's also
-                               need to be defined.
-
-       WITH_NTOH               Network byte order macros defined.
-                               Possible value is 32 or (maybe one
-                               day 64 because some 64bit network
-                               byte order macro is defined.
- */
-
-
-/* NetBSD:
-
-   NetBSD is easy, everything you could ever want is in a header file
-   (well almost :-) */
-
-#if defined(__NetBSD__)
-# include <machine/endian.h>
-# define WITH_NTOH 32 /* what about alpha? */
-# if (WITH_HOST_BYTE_ORDER == 0)
-#  undef WITH_HOST_BYTE_ORDER
-#  define WITH_HOST_BYTE_ORDER BYTE_ORDER
-# endif
-# if (BYTE_ORDER != WITH_HOST_BYTE_ORDER)
-#  error "host endian incorrectly configured, check config.h"
-# endif
-#endif
-
-/* Linux is similarly easy.  */
-
-#if defined(__linux__)
-# include <endian.h>
-# include <asm/byteorder.h>
-# if defined(__LITTLE_ENDIAN) && !defined(LITTLE_ENDIAN)
-#  define LITTLE_ENDIAN __LITTLE_ENDIAN
-# endif
-# if defined(__BIG_ENDIAN) && !defined(BIG_ENDIAN)
-#  define BIG_ENDIAN __BIG_ENDIAN
-# endif
-# if defined(__BYTE_ORDER) && !defined(BYTE_ORDER)
-#  define BYTE_ORDER __BYTE_ORDER
-# endif
-# if !defined(__alpha__)
-#  define WITH_NTOH 32 /* what about alpha? */
-# endif
-# if (WITH_HOST_BYTE_ORDER == 0)
-#  undef WITH_HOST_BYTE_ORDER
-#  define WITH_HOST_BYTE_ORDER BYTE_ORDER
-# endif
-# if (BYTE_ORDER != WITH_HOST_BYTE_ORDER)
-#  error "host endian incorrectly configured, check config.h"
-# endif
-#endif
-
-/* INSERT HERE - hosts that have available LITTLE_ENDIAN and
-   BIG_ENDIAN macro's */
-
-
-/* Some hosts don't define LITTLE_ENDIAN or BIG_ENDIAN, help them out */
-
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#endif
-
-
-/* SunOS on SPARC:
-
-   Big endian last time I looked */
-
-#if defined(sparc) || defined(__sparc__)
-# if (WITH_HOST_BYTE_ORDER == 0)
-#  undef WITH_HOST_BYTE_ORDER
-#  define WITH_HOST_BYTE_ORDER BIG_ENDIAN
-# endif
-# if (WITH_HOST_BYTE_ORDER != BIG_ENDIAN)
-#  error "sun was big endian last time I looked ..."
-# endif
-#endif
-
-
-/* Random x86
-
-   Little endian last time I looked */
-
-#if defined(i386) || defined(i486) || defined(i586) || defined(__i386__) || defined(__i486__) || defined(__i586__)
-# if (WITH_HOST_BYTE_ORDER == 0)
-#  undef WITH_HOST_BYTE_ORDER
-#  define WITH_HOST_BYTE_ORDER LITTLE_ENDIAN
-# endif
-# if (WITH_HOST_BYTE_ORDER != LITTLE_ENDIAN)
-#  error "x86 was little endian last time I looked ..."
-# endif
-#endif
-
-
-/* INSERT HERE - additional hosts that do not have LITTLE_ENDIAN and
-   BIG_ENDIAN definitions available.  */
-
-
-/* SWAPPING:
-
-   According to the following table:
-
-                TARG BE   TARG LE   TARG ??
-       HOST BE    ok        s/w      s/w
-       HOST LE   htohl      ok      ok|ntohl
-       HOST ??   ntohl      s/w      s/w
-
-    define host <-> target byte order conversion macro's */
-
-
-/* IN PLACE:
-
-   These macro's given a variable argument swap its value in place if
-   so required */
-
-#define H2T(VARIABLE) \
-do { \
-  switch (sizeof(VARIABLE)) { \
-  case 1: VARIABLE = H2T_1(VARIABLE); break; \
-  case 2: VARIABLE = H2T_2(VARIABLE); break; \
-  case 4: VARIABLE = H2T_4(VARIABLE); break; \
-  case 8: VARIABLE = H2T_8(VARIABLE); break; \
-  } \
-} while (0)
-
-#define T2H(VARIABLE) \
-do { \
-  switch (sizeof(VARIABLE)) { \
-  case 1: VARIABLE = T2H_1(VARIABLE); break; \
-  case 2: VARIABLE = T2H_2(VARIABLE); break; \
-  case 4: VARIABLE = T2H_4(VARIABLE); break; \
-  case 8: VARIABLE = T2H_8(VARIABLE); break; \
-  } \
-} while (0)
-
-
-/* TARGET WORD:
-
-   Byte swap a quantity the size of the targets word */
-
-#if (WITH_TARGET_WORD_BITSIZE == 64)
-#define H2T_word(X) H2T_8(X)
-#define T2H_word(X) T2H_8(X)
-#endif
-#if (WITH_TARGET_WORD_BITSIZE == 32)
-#define H2T_word(X) H2T_4(X)
-#define T2H_word(X) T2H_4(X)
-#endif
-
-
-/* FUNCTIONS:
-
-   Returns the value swapped according to the host/target byte order */
-
-/* no need to swap */
-#if (WITH_HOST_BYTE_ORDER \
-     && WITH_TARGET_BYTE_ORDER \
-     && WITH_HOST_BYTE_ORDER == WITH_TARGET_BYTE_ORDER )
-#define H2T_1(X) (X)
-#define H2T_2(X) (X)
-#define H2T_4(X) (X)
-#define H2T_8(X) (X)
-#define T2H_1(X) (X)
-#define T2H_2(X) (X)
-#define T2H_4(X) (X)
-#define T2H_8(X) (X)
-#endif
-
-/* have ntoh and big endian target */
-#if (WITH_TARGET_BYTE_ORDER == BIG_ENDIAN \
-     && WITH_HOST_BYTE_ORDER != BIG_ENDIAN \
-     && WITH_NTOH)
-#define H2T_8(X) endian_h2t_8(X)
-#define H2T_4(X) htonl(X)
-#define H2T_2(X) htons(X)
-#define H2T_1(X) (X)
-#define T2H_8(X) endian_t2h_8(X)
-#define T2H_4(X) htonl(X)
-#define T2H_2(X) htons(X)
-#define T2H_1(X) (X)
-#endif
-
-#if (defined (__i486__) || defined (__i586__)) && defined(__GNUC__) && WITH_BSWAP && WITH_NTOH
-#undef  htonl
-#undef  ntohl
-#define htonl(IN) __extension__ ({ int _out; __asm__ ("bswap %0" : "=r" (_out) : "0" (IN)); _out; })
-#define ntohl(IN) __extension__ ({ int _out; __asm__ ("bswap %0" : "=r" (_out) : "0" (IN)); _out; })
-#endif
-
-/* have ntoh, little host and unknown target */
-#if (WITH_HOST_BYTE_ORDER == LITTLE_ENDIAN \
-     && WITH_TARGET_BYTE_ORDER == 0 \
-     && WITH_NTOH)
-#define H2T_8(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : endian_h2t_8(X))
-#define H2T_4(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : htonl(X))
-#define H2T_2(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : htons(X))
-#define H2T_1(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : (X))
-#define T2H_8(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : endian_t2h_8(X))
-#define T2H_4(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : htonl(X))
-#define T2H_2(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : htons(X))
-#define T2H_1(X) (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER ? (X) : (X))
-#endif
-
-/* if all else fails use software */
-#ifndef H2T_1
-#define H2T_1(X) (X)
-#define H2T_2(X) endian_h2t_2(X)
-#define H2T_4(X) endian_h2t_4(X)
-#define H2T_8(X) endian_h2t_8(X)
-#define T2H_1(X) (X)
-#define T2H_2(X) endian_t2h_2(X)
-#define T2H_4(X) endian_t2h_4(X)
-#define T2H_8(X) endian_t2h_8(X)
-#endif
-
-#endif
index 8d2ca05..67ec1dd 100644 (file)
@@ -905,34 +905,34 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 #
 
 0.31,6.RT,11.RA,16.RB,21.790,31./:X:::Load Halfword Byte-Reverse Indexed
-#      unsigned_word b;
-#      unsigned_word EA;
-#      if (RA == 0) b = 0;
-#      else         b = *rA;
-#      EA = b + *rB;
-#      *rT = SWAP2(MEM(unsigned, EA, 2));
+       unsigned_word b;
+       unsigned_word EA;
+       if (RA == 0) b = 0;
+       else         b = *rA;
+       EA = b + *rB;
+       *rT = SWAP_2(MEM(unsigned, EA, 2));
 0.31,6.RT,11.RA,16.RB,21.534,31./:X:::Load Word Byte-Reverse Indexed
-#      unsigned_word b;
-#      unsigned_word EA;
-#      if (RA == 0) b = 0;
-#      else         b = *rA;
-#      EA = b + *rB;
-#      *rT = SWAP4(MEM(unsigned, EA, 4));
+       unsigned_word b;
+       unsigned_word EA;
+       if (RA == 0) b = 0;
+       else         b = *rA;
+       EA = b + *rB;
+       *rT = SWAP_4(MEM(unsigned, EA, 4));
 
 0.31,6.RS,11.RA,16.RB,21.918,31./:X:::Store Half Word Byte-Reversed Indexed
-#      unsigned_word b;
-#      unsigned_word EA;
-#      if (RA == 0) b = 0;
-#      else         b = *rA;
-#      EA = b + *rB;
-#      STORE(EA, 2, SWAP2(*rS));
+       unsigned_word b;
+       unsigned_word EA;
+       if (RA == 0) b = 0;
+       else         b = *rA;
+       EA = b + *rB;
+       STORE(EA, 2, SWAP_2(*rS));
 0.31,6.RS,11.RA,16.RB,21.662,31./:X:::Store Word Byte-Reversed Indexed
-#      unsigned_word b;
-#      unsigned_word EA;
-#      if (RA == 0) b = 0;
-#      else         b = *rA;
-#      EA = b + *rB;
-#      STORE(EA, 4, SWAP4(*rS));
+       unsigned_word b;
+       unsigned_word EA;
+       if (RA == 0) b = 0;
+       else         b = *rA;
+       EA = b + *rB;
+       STORE(EA, 4, SWAP_4(*rS));
 
 
 #
index 60acc9b..b696ab0 100644 (file)
@@ -97,6 +97,7 @@ int current_host_byte_order;
 int current_environment;
 int current_alignment;
 int current_floating_point;
+ppc_model current_ppc_model = WITH_DEFAULT_PPC_MODEL;
 
 
 /* create a device tree from the image */
@@ -1015,7 +1016,7 @@ INLINE_PSIM void
 psim_print_info(psim *system,
                int verbose)
 {
-  mon_print_info(system->monitor, verbose);
+  mon_print_info(system, system->monitor, verbose);
 }
 
 
diff --git a/sim/ppc/sim-endian-n.h b/sim/ppc/sim-endian-n.h
new file mode 100644 (file)
index 0000000..302b088
--- /dev/null
@@ -0,0 +1,65 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+
+    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 N
+#error "N must be #defined"
+#endif
+
+#undef unsigned_N
+#define unsigned_N XCONCAT2(unsigned_,N)
+#undef _SWAP_N
+#define _SWAP_N XCONCAT2(_SWAP_,N)
+#undef endian_t2h_N
+#define endian_t2h_N XCONCAT2(endian_t2h_,N)
+#undef endian_h2t_N
+#define endian_h2t_N XCONCAT2(endian_h2t_,N)
+#undef swap_N
+#define swap_N XCONCAT2(swap_,N)
+
+INLINE_SIM_ENDIAN unsigned_N
+endian_t2h_N(unsigned_N raw_in)
+{
+  if (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER) {
+    return raw_in;
+  }
+  else {
+    _SWAP_N(return,raw_in);
+  }
+}
+
+
+INLINE_SIM_ENDIAN unsigned_N
+endian_h2t_N(unsigned_N raw_in)
+{
+  if (CURRENT_TARGET_BYTE_ORDER == CURRENT_HOST_BYTE_ORDER) {
+    return raw_in;
+  }
+  else {
+    _SWAP_N(return,raw_in);
+  }
+}
+
+
+INLINE_SIM_ENDIAN unsigned_N
+swap_N(unsigned_N raw_in)
+{
+  _SWAP_N(return,raw_in);
+}
diff --git a/sim/ppc/sim-endian.c b/sim/ppc/sim-endian.c
new file mode 100644 (file)
index 0000000..8edf7a3
--- /dev/null
@@ -0,0 +1,79 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+
+    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_ENDIAN_C_
+#define _SIM_ENDIAN_C_
+
+#ifndef STATIC_INLINE_ENDIAN
+#define STATIC_INLINE_ENDIAN STATIC_INLINE
+#endif
+
+
+#include "config.h"
+#include "basics.h"
+
+
+#if !defined(_SWAP_1)
+#define _SWAP_1(SET,RAW) SET (RAW)
+#endif
+
+#if !defined(_SWAP_2) && (WITH_HOST_BYTE_ORDER == LITTLE_ENDIAN) && WITH_NTOH
+#define _SWAP_2(SET,RAW) SET htons (RAW)
+#endif
+
+#ifndef        _SWAP_2
+#define _SWAP_2(SET,RAW) SET (((RAW) >> 8) | ((RAW) << 8))
+#endif
+
+#if !defined(_SWAP_4) && (WITH_HOST_BYTE_ORDER == LITTLE_ENDIAN) && WITH_NTOH
+#define _SWAP_4(SET,RAW) SET htonl (RAW)
+#endif
+
+#ifndef _SWAP_4
+#define        _SWAP_4(SET,RAW) SET (((RAW) << 24) | (((RAW) & 0xff00) << 8) | (((RAW) & 0xff0000) >> 8) | ((RAW) >> 24))
+#endif
+
+#ifndef _SWAP_8
+#define _SWAP_8(SET,RAW) \
+  union { unsigned_8 dword; unsigned_4 words[2]; } in, out; \
+  in.dword = RAW; \
+  _SWAP_4 (out.words[0] =, in.words[1]); \
+  _SWAP_4 (out.words[1] =, in.words[0]); \
+  SET out.dword;
+#endif
+
+#undef N
+#define N 1
+#include "sim-endian-n.h"
+
+#undef N
+#define N 2
+#include "sim-endian-n.h"
+
+#undef N
+#define N 4
+#include "sim-endian-n.h"
+
+#undef N
+#define N 8
+#include "sim-endian-n.h"
+
+#endif /* _SIM_ENDIAN_C_ */
index 32bd4f5..5a61e53 100644 (file)
@@ -24,6 +24,7 @@
 #include <ctype.h>
 
 #include "basics.h"
+#include "function_unit.h"
 #include "psim.h"
 
 #ifdef HAVE_STDLIB_H
@@ -55,8 +56,6 @@ static int print_info = 0;
 void
 sim_open (char *args)
 {
-  int i;
-
   /* trace the call */
   TRACE(trace_gdb, ("sim_open(args=%s) called\n", args ? args : "(null)"));
 
@@ -77,19 +76,38 @@ sim_open (char *args)
        while (*p != '\0') {
          switch (*p) {
          default:
-           printf_filtered("Usage:\n\ttarget sim [ -t <trace-option> ]\n");
+           printf_filtered("Usage:\n\ttarget sim [ -t <trace-option> ] [-m model] [-i] [-I]\n");
            trace_usage();
            error ("");
            break;
          case 't':
-           argp += 1;
-           if (argv[argp] == NULL)
-             error("Missing <trace> option for -t\n");
-           trace_option(argv[argp]); /* better fail if NULL */
+           if (p[1])
+             trace_option(p+1);
+           else {
+             argp += 1;
+             if (argv[argp] == NULL)
+               error("Missing <trace> option for -t\n");
+             else
+               trace_option(argv[argp]);
+           }
            break;
-         case 'I':
+         case 'm':
+           if (p[1])
+             function_unit_model(p+1);
+           else {
+             argp += 1;
+             if (argv[argp] == NULL)
+               error("Missing <trace> option for -t\n");
+             else
+               function_unit_model(argv[argp]);
+           }
+           break;
+         case 'i':
            print_info = 1;
            break;
+         case 'I':
+           print_info = 2;
+           break;
          }
          p += 1;
        }
@@ -109,7 +127,7 @@ sim_close (int quitting)
 {
   TRACE(trace_gdb, ("sim_close(quitting=%d) called\n", quitting));
   if (print_info)
-    psim_print_info (simulator, 1);
+    psim_print_info (simulator, print_info);
 
   /* nothing to do */
 }
@@ -285,7 +303,6 @@ void
 sim_resume (int step, int siggnal)
 {
   void (*prev) ();
-  unsigned_word program_counter;
 
   TRACE(trace_gdb, ("sim_resume(step=%d, siggnal=%d)\n",
                    step, siggnal));
index 69359f4..ace2888 100644 (file)
@@ -246,6 +246,41 @@ extern int current_floating_point;
 #endif
 
 
+/* Include code that simulates function units to model particular
+   machines more closely and provide more detailed information about
+   optimization potential.  */
+
+#ifndef WITH_FUNCTION_UNIT
+#define        WITH_FUNCTION_UNIT              1
+#endif
+
+/* Which specific processor to model */
+typedef enum _ppc_model {
+  PPC_MODEL_UNKNOWN,
+  PPC_MODEL_601,
+  PPC_MODEL_602,
+  PPC_MODEL_603,
+  PPC_MODEL_603e,
+  PPC_MODEL_604,
+  PPC_MODEL_403,
+  PPC_MODEL_505,
+  PPC_MODEL_821,
+  PPC_MODEL_860
+} ppc_model;
+
+#ifndef WITH_DEFAULT_PPC_MODEL
+#define        WITH_DEFAULT_PPC_MODEL PPC_MODEL_603e
+#endif
+
+extern ppc_model current_ppc_model;
+
+#ifndef WITH_PPC_MODEL
+#define        WITH_PPC_MODEL                  0
+#endif
+
+#define CURRENT_PPC_MODEL (WITH_PPC_MODEL      \
+                          ? WITH_PPC_MODEL     \
+                          : current_ppc_model)
 
 /* INLINE CODE SELECTION:
 
@@ -309,11 +344,18 @@ extern int current_floating_point;
 #endif
 
 /* Code that converts between hosts and target byte order.  Used on
-   every memory access (instruction and data).  (See ppc-endian.h for
+   every memory access (instruction and data).  (See sim-endian.h for
    additional byte swapping configuration information) */
 
-#ifndef ENDIAN_INLINE
-#define ENDIAN_INLINE                  DEFAULT_INLINE
+#ifndef SIM_ENDIAN_INLINE
+#define SIM_ENDIAN_INLINE              DEFAULT_INLINE
+#endif
+
+/* Low level bit manipulation routines used to work around a compiler
+   bug in 2.6.3.  */
+
+#ifndef BITS_INLINE
+#define BITS_INLINE                    DEFAULT_INLINE
 #endif
 
 /* Code that gives access to various CPU internals such as registers.
@@ -412,4 +454,10 @@ extern int current_floating_point;
 #define IDECODE_INLINE                 DEFAULT_INLINE
 #endif
 
+/* Code to simule functional units of real machines */
+
+#ifndef FUNCTION_UNIT_INLINE
+#define FUNCTION_UNIT_INLINE           DEFAULT_INLINE
+#endif
+
 #endif /* _CONFIG_H */
index cc065fc..6bc01d8 100644 (file)
@@ -25,6 +25,7 @@
 #include <fcntl.h>
 #include <ctype.h>
 
+#include "config.h"
 #include "misc.h"
 #include "lf.h"
 #include "table.h"
index 269f660..2feddd5 100644 (file)
@@ -485,7 +485,9 @@ om_virtual_to_real(om_map *map,
          core_map_read_word(map->physical,
                             real_address_of_pte + sizeof_pte / 2,
                             processor, cia);
-       error("fixme - check pte hit\n");
+       error("fixme - check pte hit %ld %ld\n",
+             (long)pte_word_0,
+             (long)pte_word_1);
        if (1) {
          error("fixme - update the page_tlb\n");
          page_tlb_entry->valid = 1;
index 63bd54c..0a9d0a1 100644 (file)
@@ -53,7 +53,6 @@ XCONCAT2(vm_data_map_read_,N)(vm_data_map *map,
       return 0;
     case NONSTRICT_ALIGNMENT:
       {
-       unsigned_N rval;
        unsigned_N val;
        if (vm_data_map_read_buffer(map, &val, ea, sizeof(unsigned_N))
            != sizeof(unsigned_N))