aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorMichael Meissner <gnu@the-meissners.org>1995-11-08 18:57:06 +0000
committerMichael Meissner <gnu@the-meissners.org>1995-11-08 18:57:06 +0000
commit73c4941b23b9c660bb9bc4bb7acf3ea253356c41 (patch)
treeda13e65308de8337364ccbc1dde964aa60b93609 /sim
parent0634a431423265b525681625d2796346428c53b0 (diff)
downloadgdb-73c4941b23b9c660bb9bc4bb7acf3ea253356c41.zip
gdb-73c4941b23b9c660bb9bc4bb7acf3ea253356c41.tar.gz
gdb-73c4941b23b9c660bb9bc4bb7acf3ea253356c41.tar.bz2
first stage in function unit support; add new switches & latest code from andrew
Diffstat (limited to 'sim')
-rw-r--r--sim/ppc/.Sanitize7
-rw-r--r--sim/ppc/ChangeLog129
-rw-r--r--sim/ppc/Makefile.in49
-rwxr-xr-xsim/ppc/configure127
-rw-r--r--sim/ppc/configure.in78
-rw-r--r--sim/ppc/corefile.c1
-rw-r--r--sim/ppc/cpu.h4
-rw-r--r--sim/ppc/debug.c3
-rw-r--r--sim/ppc/devices.c1
-rw-r--r--sim/ppc/emul_generic.c230
-rw-r--r--sim/ppc/emul_netbsd.c1
-rw-r--r--sim/ppc/filter_filename.c3
-rw-r--r--sim/ppc/function_unit.c611
-rw-r--r--sim/ppc/function_unit.h71
-rw-r--r--sim/ppc/inline.c16
-rw-r--r--sim/ppc/inline.h155
-rw-r--r--sim/ppc/main.c21
-rw-r--r--sim/ppc/mon.c69
-rw-r--r--sim/ppc/mon.h76
-rw-r--r--sim/ppc/ppc-endian.c82
-rw-r--r--sim/ppc/ppc-endian.h262
-rw-r--r--sim/ppc/ppc-instructions48
-rw-r--r--sim/ppc/psim.c3
-rw-r--r--sim/ppc/sim-endian-n.h65
-rw-r--r--sim/ppc/sim-endian.c79
-rw-r--r--sim/ppc/sim_calls.c37
-rw-r--r--sim/ppc/std-config.h54
-rw-r--r--sim/ppc/table.c1
-rw-r--r--sim/ppc/vm.c4
-rw-r--r--sim/ppc/vm_n.h1
30 files changed, 1802 insertions, 486 deletions
diff --git a/sim/ppc/.Sanitize b/sim/ppc/.Sanitize
index b5b07fa..f72289b 100644
--- a/sim/ppc/.Sanitize
+++ b/sim/ppc/.Sanitize
@@ -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
diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog
index 3a0f385..60decfd 100644
--- a/sim/ppc/ChangeLog
+++ b/sim/ppc/ChangeLog
@@ -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
diff --git a/sim/ppc/Makefile.in b/sim/ppc/Makefile.in
index e233156..0a12ee7 100644
--- a/sim/ppc/Makefile.in
+++ b/sim/ppc/Makefile.in
@@ -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
diff --git a/sim/ppc/configure b/sim/ppc/configure
index 7eefa07..9c3b40d 100755
--- a/sim/ppc/configure
+++ b/sim/ppc/configure
@@ -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
diff --git a/sim/ppc/configure.in b/sim/ppc/configure.in
index 43761d8..4ebcefb 100644
--- a/sim/ppc/configure.in
+++ b/sim/ppc/configure.in
@@ -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)
diff --git a/sim/ppc/corefile.c b/sim/ppc/corefile.c
index 1c67357..c112a63 100644
--- a/sim/ppc/corefile.c
+++ b/sim/ppc/corefile.c
@@ -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");
diff --git a/sim/ppc/cpu.h b/sim/ppc/cpu.h
index 82290f6..a89f7b9 100644
--- a/sim/ppc/cpu.h
+++ b/sim/ppc/cpu.h
@@ -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) \
diff --git a/sim/ppc/debug.c b/sim/ppc/debug.c
index e8c054f..c77b51f 100644
--- a/sim/ppc/debug.c
+++ b/sim/ppc/debug.c
@@ -22,9 +22,10 @@
#ifndef _DEBUG_C_
#define _DEBUG_C_
+#include "config.h"
#include "basics.h"
-#ifdef HAVE_STDLIB
+#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
diff --git a/sim/ppc/devices.c b/sim/ppc/devices.c
index 46a3eec..b0368d5 100644
--- a/sim/ppc/devices.c
+++ b/sim/ppc/devices.c
@@ -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
index 0000000..f764205
--- /dev/null
+++ b/sim/ppc/emul_generic.c
@@ -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_ */
diff --git a/sim/ppc/emul_netbsd.c b/sim/ppc/emul_netbsd.c
index 1a05f0a..ac2cd80 100644
--- a/sim/ppc/emul_netbsd.c
+++ b/sim/ppc/emul_netbsd.c
@@ -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])
diff --git a/sim/ppc/filter_filename.c b/sim/ppc/filter_filename.c
index 72923b9..ecbde5c 100644
--- a/sim/ppc/filter_filename.c
+++ b/sim/ppc/filter_filename.c
@@ -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
index 0000000..7793c7b
--- /dev/null
+++ b/sim/ppc/function_unit.c
@@ -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 */
+
+
+/* 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 },
+};
+
+
+/* 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 },
+};
+
+
+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
index 0000000..904abce
--- /dev/null
+++ b/sim/ppc/function_unit.h
@@ -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_ */
diff --git a/sim/ppc/inline.c b/sim/ppc/inline.c
index 4ac048b..715373a 100644
--- a/sim/ppc/inline.c
+++ b/sim/ppc/inline.c
@@ -19,11 +19,15 @@
*/
-#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
@@ -50,6 +54,10 @@
#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
index 0000000..646e696
--- /dev/null
+++ b/sim/ppc/inline.h
@@ -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
diff --git a/sim/ppc/main.c b/sim/ppc/main.c
index 07412be..80b993f 100644
--- a/sim/ppc/main.c
+++ b/sim/ppc/main.c
@@ -23,11 +23,16 @@
#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);
diff --git a/sim/ppc/mon.c b/sim/ppc/mon.c
index f086049..0efb1bf 100644
--- a/sim/ppc/mon.c
+++ b/sim/ppc/mon.c
@@ -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
index 0000000..e8ac2e3
--- /dev/null
+++ b/sim/ppc/mon.h
@@ -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
index ec90bb7..0000000
--- a/sim/ppc/ppc-endian.c
+++ /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
index 748d2ef..0000000
--- a/sim/ppc/ppc-endian.h
+++ /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
diff --git a/sim/ppc/ppc-instructions b/sim/ppc/ppc-instructions
index 8d2ca05..67ec1dd 100644
--- a/sim/ppc/ppc-instructions
+++ b/sim/ppc/ppc-instructions
@@ -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));
#
diff --git a/sim/ppc/psim.c b/sim/ppc/psim.c
index 60acc9b..b696ab0 100644
--- a/sim/ppc/psim.c
+++ b/sim/ppc/psim.c
@@ -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
index 0000000..302b088
--- /dev/null
+++ b/sim/ppc/sim-endian-n.h
@@ -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
index 0000000..8edf7a3
--- /dev/null
+++ b/sim/ppc/sim-endian.c
@@ -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_ */
diff --git a/sim/ppc/sim_calls.c b/sim/ppc/sim_calls.c
index 32bd4f5..5a61e53 100644
--- a/sim/ppc/sim_calls.c
+++ b/sim/ppc/sim_calls.c
@@ -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));
diff --git a/sim/ppc/std-config.h b/sim/ppc/std-config.h
index 69359f4..ace2888 100644
--- a/sim/ppc/std-config.h
+++ b/sim/ppc/std-config.h
@@ -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 */
diff --git a/sim/ppc/table.c b/sim/ppc/table.c
index cc065fc..6bc01d8 100644
--- a/sim/ppc/table.c
+++ b/sim/ppc/table.c
@@ -25,6 +25,7 @@
#include <fcntl.h>
#include <ctype.h>
+#include "config.h"
#include "misc.h"
#include "lf.h"
#include "table.h"
diff --git a/sim/ppc/vm.c b/sim/ppc/vm.c
index 269f6608d..2feddd5 100644
--- a/sim/ppc/vm.c
+++ b/sim/ppc/vm.c
@@ -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;
diff --git a/sim/ppc/vm_n.h b/sim/ppc/vm_n.h
index 63bd54c..0a9d0a1 100644
--- a/sim/ppc/vm_n.h
+++ b/sim/ppc/vm_n.h
@@ -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))