From 73c4941b23b9c660bb9bc4bb7acf3ea253356c41 Mon Sep 17 00:00:00 2001 From: Michael Meissner <gnu@the-meissners.org> Date: Wed, 8 Nov 1995 18:57:06 +0000 Subject: first stage in function unit support; add new switches & latest code from andrew --- sim/ppc/.Sanitize | 7 +- sim/ppc/ChangeLog | 129 ++++++++++ sim/ppc/Makefile.in | 49 ++-- sim/ppc/configure | 127 +++++++--- sim/ppc/configure.in | 78 ++++-- sim/ppc/corefile.c | 1 - sim/ppc/cpu.h | 4 + sim/ppc/debug.c | 3 +- sim/ppc/devices.c | 1 - sim/ppc/emul_generic.c | 230 +++++++++++++++++ sim/ppc/emul_netbsd.c | 1 - sim/ppc/filter_filename.c | 3 +- sim/ppc/function_unit.c | 611 ++++++++++++++++++++++++++++++++++++++++++++++ sim/ppc/function_unit.h | 71 ++++++ sim/ppc/inline.c | 16 +- sim/ppc/inline.h | 155 ++++++++++++ sim/ppc/main.c | 21 +- sim/ppc/mon.c | 69 ++++-- sim/ppc/mon.h | 76 ++++++ sim/ppc/ppc-endian.c | 82 ------- sim/ppc/ppc-endian.h | 262 -------------------- sim/ppc/ppc-instructions | 48 ++-- sim/ppc/psim.c | 3 +- sim/ppc/sim-endian-n.h | 65 +++++ sim/ppc/sim-endian.c | 79 ++++++ sim/ppc/sim_calls.c | 37 ++- sim/ppc/std-config.h | 54 +++- sim/ppc/table.c | 1 + sim/ppc/vm.c | 4 +- sim/ppc/vm_n.h | 1 - 30 files changed, 1802 insertions(+), 486 deletions(-) create mode 100644 sim/ppc/emul_generic.c create mode 100644 sim/ppc/function_unit.c create mode 100644 sim/ppc/function_unit.h create mode 100644 sim/ppc/inline.h create mode 100644 sim/ppc/mon.h delete mode 100644 sim/ppc/ppc-endian.c delete mode 100644 sim/ppc/ppc-endian.h create mode 100644 sim/ppc/sim-endian-n.h create mode 100644 sim/ppc/sim-endian.c (limited to 'sim/ppc') 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)) -- cgit v1.1