From: Michael Meissner Date: Thu, 2 Nov 1995 20:21:35 +0000 (+0000) Subject: Use autoconf correctly; provide more stats with -I X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c494cadde621b6d371d03df79486176c10bea303;p=binutils-gdb.git Use autoconf correctly; provide more stats with -I --- diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index 8094bdc6ec3..3fdef42510b 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -1,10 +1,43 @@ Thu Nov 2 08:54:04 1995 Michael Meissner + * configure.in: Rewrite --enable-sim switch handling to use the + autoconf builtins so it works correctly if the configure or + Makefile.in files are modified and make decides to rebuild + Makefile. Also document all of the --enable-sim switches + supported. Check whether getrusage and sys/resource.h are + supported. + * config.in: Regenerate. + * configure: Regenerate. + * Makefile.in: Add support for all of the variables set with + --enable-sim switches. + + * Makefile.in (clean): make clean now removes all built sources as + well. + + * cpu.c: Use HAVE_STRING_H, HAVE_STRINGS_H, HAVE_UNISTD_H, + HAVE_TIME_H, HAVE_SYS_TIMES_H, HAVE_SYS_RESOURCE_H defined in + the generated config.h. + * debug.c: Ditto. + * device_tree.c: Ditto. + * devices.c: Ditto. + * dgen.c: Ditto. + * emul_netbsd.c: Ditto. + * igen.c: Ditto. + * lf.c: Ditto. + * misc.c: Ditto. + * psim.c: Ditto. + * registers.c: Ditto. + * sim_calls.c: Ditt. + * table.c: Ditto. + + * main.c (main): Call psim_print_info with verbose == 2. * mon.c (mon_print_info): Align the cpu number and number of instructions fields. Do not print an instruction category if the - CPU did not execute any of those instructions. + CPU did not execute any of those instructions. Print out number + of reads and writes. If getrusage is supported, print out number + of simulated instructins per second. * configure.in: Add support for --enable-sim-opcode=stupid. * configure: Regenerate. diff --git a/sim/ppc/Makefile.in b/sim/ppc/Makefile.in index 566d89edbbe..58607be2875 100644 --- a/sim/ppc/Makefile.in +++ b/sim/ppc/Makefile.in @@ -66,6 +66,40 @@ BISON = bison MAKEINFO = makeinfo RANLIB = @RANLIB@ +SIM_CFLAGS = @sim_cflags@ +INLINE_CFLAGS = @sim_inline@ +BSWAP_CFLAGS = @sim_bswap@ +ENDIAN_CFLAGS = @sim_endian@ +HOSTENDIAN_CFLAGS = @sim_hostendian@ +SMP_CFLAGS = @sim_smp@ +BITSIZE_CFLAGS = @sim_bitsize@ +HOSTBITSIZE_CFLAGS = @sim_hostbitsize@ +ENV_CFLAGS = @sim_env@ +TIMEBASE_CFLAGS = @sim_timebase@ +ALIGNMENT_CFLAGS = @sim_alignment@ +FLOAT_CFLAGS = @sim_float@ +TRACE_CFLAGS = @sim_trace@ +ASSERT_CFLAGS = @sim_assert@ +MONITOR_CFLAGS = @sim_monitor@ +CONFIG_CFLAGS = $(BSWAP_CFLAGS) \ + $(ENDIAN_CFLAGS) \ + $(HOSTENDIAN_CFLAGS) \ + $(SMP_CFLAGS) \ + $(BITSIZE_CFLAGS) \ + $(HOSTBITSIZE_CFLAGS) \ + $(ENV_CFLAGS) \ + $(FLOAT_CFLAGS) \ + $(TRACE_CFLAGS) \ + $(ASSERT_CFLAGS) \ + $(MONITOR_CFLAGS) + +CONFIG_FILE = @sim_config@ +IGEN_OPCODE_RULES = @sim_opcode@ +IGEN_DUPLICATE = @sim_dup@ +IGEN_FILTER = @sim_filter@ +IGEN_ICACHE = @sim_icache@ +DGEN_FLAGS = @sim_switch@ + HDEFINES = @HDEFINES@ TDEFINES = IGEN_FLAGS = $(IGEN_DUPLICATE) $(IGEN_FILTER) $(IGEN_ICACHE) @@ -86,7 +120,7 @@ TARGETLIB = libsim.a all: run $(TARGETLIB) $(GDB_OBJ) .c.o: - $(CC) -c $(CFLAGS) $(INLINE_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $< + $(CC) -c $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $< @@ -327,10 +361,10 @@ TAGS: tmp-igen tmp-dgen config.h ppc-config.h etags $(srcdir)/*.h $(srcdir)/*.c $(BUILT_SRC) clean mostlyclean: - rm -f tmp-* *.[oas] core psim run igen dgen config.log + rm -f tmp-* *.[oas] core psim run igen dgen config.log $(BUILT_SRC) distclean maintainer-clean realclean: clean - rm -f TAGS $(BUILT_SRC) Makefile config.cache config.status config.h stamp-h + rm -f TAGS Makefile config.cache config.status config.h stamp-h Makefile: Makefile.in config.status CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status @@ -345,5 +379,3 @@ config.status: configure config.make config.hdr install: $(INSTALL_XFORM) run $(bindir)/run - -# Make variables generated automatically by configure follow this diff --git a/sim/ppc/configure b/sim/ppc/configure index 3d6b5638e93..aab7e2a35f1 100755 --- a/sim/ppc/configure +++ b/sim/ppc/configure @@ -11,6 +11,53 @@ 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" +ac_help="$ac_help + --enable-sim-config=file Override default config file" +ac_help="$ac_help + --enable-sim-opcode=which Override default opcode lookup." +ac_help="$ac_help + --enable-sim-switch Use a switch instead of a table for instruction call." +ac_help="$ac_help + --enable-sim-duplicate Expand (duplicate) semantic functions." +ac_help="$ac_help + --enable-sim-filter=rule Specify filter rules." +ac_help="$ac_help + --enable-sim-icache=size Specify instruction cache size." +ac_help="$ac_help + --enable-sim-inline=inlines Specify which functions should be inlined." +ac_help="$ac_help + --enable-sim-bswap Use the BSWAP instruction on Intel 486s and Pentiums." +ac_help="$ac_help + --enable-sim-endian=endian Specify target byte endian orientation." +ac_help="$ac_help + --enable-sim-hostendain=end Specify host byte endian orientation." +ac_help="$ac_help + --enable-sim-smp=n Specify number of processors to configure for." +ac_help="$ac_help + --enable-sim-bitsize=n Specify target bitsize (32 or 64)." +ac_help="$ac_help + --enable-sim-hostbitsize=n Specify host bitsize (32 or 64)." +ac_help="$ac_help + --enable-sim-env=env Specify target environment (operating, virtual, user)." +ac_help="$ac_help + --enable-sim-timebase Specify whether the PPC timebase is supported." +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" +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-float Specify whether to use host floating point or simulate." +ac_help="$ac_help + --enable-sim-monitor=mon Specify whether to enable monitoring events." # Initialize some variables set by options. # The variables have the same names as the options, with @@ -399,6 +446,274 @@ fi +# Check whether --enable-sim-cflags or --disable-sim-cflags was given. +enableval="$enable_sim_cflags" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_cflags="-O2 -fomit-frame-pointer";; + no) sim_cflags="";; + *) sim_cflags=`echo "${enableval}" | sed -e "s/,/ /"`;; +esac +else + sim_cflags="" +fi + +# Check whether --enable-sim-config or --disable-sim-config was given. +enableval="$enable_sim_config" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_config="std-config.h";; + no) sim_config="std-config.h";; + *) sim_config="${enableval}";; +esac +else + sim_config="std-config.h" +fi + +# Check whether --enable-sim-opcode or --disable-sim-opcode was given. +enableval="$enable_sim_opcode" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_opcode="ppc-opcode-simple";; + no) sim_opcode="ppc-opcode-simple";; + *) sim_opcode="ppc-opcode-${enableval}";; +esac +else + sim_opcode="ppc-opcode-simple" +fi + +# Check whether --enable-sim-switch or --disable-sim-switch was given. +enableval="$enable_sim_switch" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_switch="-s";; + *) sim_switch="";; +esac +else + sim_switch="" +fi + +# Check whether --enable-sim-duplicate or --disable-sim-duplicate was given. +enableval="$enable_sim_duplicate" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_dup="-e";; + *) sim_dup="";; +esac +else + sim_dup="" +fi + +# Check whether --enable-sim-filter or --disable-sim-filter was given. +enableval="$enable_sim_filter" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_filter="";; + *) sim_filter="-f $enableval";; +esac +else + sim_filter="-f 64" +fi + +# Check whether --enable-sim-icache or --disable-sim-icache was given. +enableval="$enable_sim_icache" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_icache="-r 1024";; + *) sim_icache="";; +esac +else + sim_icache="" +fi + +# Check whether --enable-sim-inline or --disable-sim-inline was given. +enableval="$enable_sim_inline" +if test -n "$enableval"; then + sim_inline="" +case "$enableval" in + no) flags="";; + 0) flags="-DDEFAULT_INLINE=0";; + yes | 2) flags="-DDEFAULT_INLINE=2";; + 1) flags="-DDEFAULT_INLINE=1";; + *) for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + new_flag="" + case "$x" in + *_INLINE=*) new_flag="-D$x";; + *_INLINE) new_flag="-D$x=2";; + *=*) new_flag=`sed -e "s/=/_INLINE=/" -e "s/^/-D/"`;; + *) new_flag="-D$x""_INLINE=2";; + esac + if x"$sim_inline" = x""; then + sim_inline="$new_flag" + else + sim_inline="$flags $new_flag" + fi + done;; +esac +else + sim_inline="" +fi + +# Check whether --enable-sim-bswap or --disable-sim-bswap was given. +enableval="$enable_sim_bswap" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_bswap="-DWITH_BSWAP=1";; + no) sim_bswap="-DWITH_BSWAP=0";; + *) sim_bswap="";; +esac +else + sim_bswap="" +fi + +# Check whether --enable-sim-endian or --disable-sim-endian was given. +enableval="$enable_sim_endian" +if test -n "$enableval"; then + case "${enableval}" in + yes) case "$target" in + *powerpc-*) sim_endian="-DWITH_TARGET_BYTE_ORDER=BIG_ENDIAN";; + *powerpcle-*) sim_endian="-DWITH_TARGET_BYTE_ORDER=LITTLE_ENDIAN";; + *) echo "Unknown target $target" 1>&6; sim_endian="-DWITH_TARGET_BYTE_ORDER=0";; + esac;; + no) sim_endian="-DWITH_TARGET_BYTE_ORDER=0";; + b*|B*) sim_endian="-DWITH_TARGET_BYTE_ORDER=BIG_ENDIAN";; + l*|L*) sim_endian="-DWITH_TARGET_BYTE_ORDER=LITTLE_ENDIAN";; + *) sim_endian="";; +esac +else + sim_endian="" +fi + +# Check whether --enable-sim-hostendian or --disable-sim-hostendian was given. +enableval="$enable_sim_hostendian" +if test -n "$enableval"; then + case "${enableval}" in + no) sim_hostendian="-DWITH_HOST_BYTE_ORDER=0";; + b*|B*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN";; + l*|L*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN";; + *) sim_hostendian="";; +esac +else + sim_hostendian="" +fi + +# Check whether --enable-sim-smp or --disable-sim-smp was given. +enableval="$enable_sim_smp" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_smp="-DWITH_SMP=2";; + no) sim_smp="-DWITH_SMP=0";; + *) sim_smp="-DWITH_SMP=$enableval";; +esac +else + sim_smp="" +fi + +# Check whether --enable-sim-bitsize or --disable-sim-bitsize was given. +enableval="$enable_sim_bitsize" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_bitsize="";; + no) sim_bitsize="";; + *) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=$enableval";; +esac +else + sim_bitsize="" +fi + +# Check whether --enable-sim-hostbitsize or --disable-sim-hostbitsize was given. +enableval="$enable_sim_hostbitsize" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_hostbitsize="";; + no) sim_hostbitsize="";; + *) sim_hostbitsize="-DWITH_HOST_WORD_BITSIZE=$enableval";; +esac +else + sim_hostbitsize="" +fi + +# Check whether --enable-sim-env or --disable-sim-env was given. +enableval="$enable_sim_env" +if test -n "$enableval"; then + case "${enableval}" in + operating | os | oea) sim_env="-DWITH_ENVIRONMENT=OPERATING_ENVIRONMENT";; + virtual | vea) sim_env="-DWITH_ENVIRONMENT=VIRTUAL_ENVIRONMENT";; + user | uea) sim_env="-DWITH_ENVIRONMENT=USER_ENVIRONMENT";; + *) sim_env="";; +esac +else + sim_env="" +fi + +# Check whether --enable-sim-timebase or --disable-sim-timebase was given. +enableval="$enable_sim_timebase" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_timebase="-DWITH_TIME_BASE=1";; + no) sim_timebase="-DWITH_TIME_BASE=0";; + *) sim_timebase="";; +esac +else + sim_timebase="" +fi + +# Check whether --enable-sim-alignment or --disable-sim-alignment was given. +enableval="$enable_sim_alignment" +if test -n "$enableval"; then + sim_alignment="" +fi + +# Check whether --enable-sim-trace or --disable-sim-trace was given. +enableval="$enable_sim_trace" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_trace="-DWITH_TRACE=1";; + no) sim_trace="-DWITH_TRACE=0";; + *) sim_trace="";; +esac +else + sim_trace="" +fi + +# Check whether --enable-sim-assert or --disable-sim-assert was given. +enableval="$enable_sim_assert" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_assert="-DWITH_ASSERT=1";; + no) sim_assert="-DWITH_ASSERT=0";; + *) sim_assert="";; +esac +else + sim_assert="" +fi + +# Check whether --enable-sim-float or --disable-sim-float was given. +enableval="$enable_sim_float" +if test -n "$enableval"; then + case "${enableval}" in + yes | hard) sim_float="-DWITH_FLOATING_POINT=HARD_FLOATING_POINT";; + no | soft) sim_float="-DWITH_FLOATING_POINT=SOFT_FLOATING_POINT";; + *) sim_float="";; +esac +else + sim_float="" +fi + +# Check whether --enable-sim-monitor or --disable-sim-monitor was given. +enableval="$enable_sim_monitor" +if test -n "$enableval"; then + case "${enableval}" in + yes) sim_mon="-DWITH_MON='MONITOR_INSTRUCTION_ISSUE | MONITOR_LOAD_STORE_UNIT'";; + no) sim_mon="-DWITH_MON=0";; + instruction) sim_mon="-DWITH_MON=MONITOR_INSTRUCTION_ISSUE";; + memory) sim_mon="-DWITH_MON=MONITOR_LOAD_STORE_UNIT";; + *) sim_mon="-DWITH_MON='$enableval'";; +esac +else + sim_float="" +fi + ac_aux_dir= @@ -632,6 +947,79 @@ else fi + + + + + + + + + + + + + + + + + + + + + +for ac_func in getrusage +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +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 < +/* Override any gcc2 internal prototype to avoid an error. */ +char $ac_func(); + +int main() { return 0; } +int t() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'` + cat >> confdefs.h <&6 +fi +done + + # Put a plausible default for CC_FOR_BUILD in Makefile. # If we cannot run a trivial program, we must be cross compiling. echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6 @@ -642,7 +1030,7 @@ else ac_cv_c_cross=yes else cat > conftest.$ac_ext < conftest.$ac_ext < Syntax Error @@ -694,7 +1082,7 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error @@ -719,7 +1107,7 @@ else fi echo "$ac_t""$CPP" 1>&6 -for ac_hdr in string.h strings.h stdlib.h time.h sys/times.h +for ac_hdr in string.h strings.h stdlib.h time.h sys/times.h unistd.h sys/resource.h do ac_safe=`echo "$ac_hdr" | tr './\055' '___'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 @@ -727,7 +1115,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 @@ -877,6 +1265,27 @@ s%@CC@%$CC%g s%@HDEFINES@%$HDEFINES%g s%@AR@%$AR%g s%@RANLIB@%$RANLIB%g +s%@sim_cflags@%$sim_cflags%g +s%@sim_config@%$sim_config%g +s%@sim_opcode@%$sim_opcode%g +s%@sim_switch@%$sim_switch%g +s%@sim_dup@%$sim_dup%g +s%@sim_filter@%$sim_filter%g +s%@sim_icache@%$sim_icache%g +s%@sim_inline@%$sim_inline%g +s%@sim_bswap@%$sim_bswap%g +s%@sim_endian@%$sim_endian%g +s%@sim_hostendian@%$sim_hostendian%g +s%@sim_smp@%$sim_smp%g +s%@sim_bitsize@%$sim_bitsize%g +s%@sim_hostbitsize@%$sim_hostbitsize%g +s%@sim_env@%$sim_env%g +s%@sim_timebase@%$sim_timebase%g +s%@sim_alignment@%$sim_alignment%g +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%@CC_FOR_BUILD@%$CC_FOR_BUILD%g s%@CPP@%$CPP%g @@ -1039,118 +1448,3 @@ chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - -if test x"$enable_sim_cflags" != x"" -a x"$enable_sim_cflags" != x"no"; then - if test "$enable_sim_cflags" = "yes"; then - enable_sim_cflags="-fomit-frame-pointer,-O2" - fi - echo "Setting SIM_CFLAGS=$enable_sim_cflags" | sed -e "s/,/ /g" 1>&6 - (echo; echo "# --enable-sim-cflags=$enable_sim_cflags"; - echo "SIM_CFLAGS = $enable_sim_cflags" | sed -e "s/,/ /g") >> Makefile -else - echo "Setting SIM_CFLAGS=" 1>&6 - (echo; echo "# no --enable-sim-cflags"; echo "SIM_CFLAGS =") >> Makefile -fi - -$srcdir/config.make Makefile CONFIG_FILE --enable-sim-config "$enable_sim_config" \ - "" "std-config.h" "no" "std-config.h" "yes" "std-config.h" "*" "$enable_sim_config" 1>&6 - -$srcdir/config.make Makefile IGEN_OPCODE_RULES --enable-sim-opcode "$enable_sim_opcode" \ - "" "ppc-opcode-simple" "no" "ppc-opcode-simple" "yes" "ppc-opcode-simple" \ - "complex" "ppc-opcode-complex" "simple" "ppc-opcode-simple" "stupid" "ppc-opcode-stupid" 1>&6 - -$srcdir/config.make Makefile DGEN_FLAGS --enable-sim-switch "$enable_sim_switch" \ - "" "" "no" "" "yes" "-s" 1>&6 - -$srcdir/config.make Makefile IGEN_DUPLICATE --enable-sim-duplicate "$enable_sim_duplicate" \ - "" "" "no" "" "yes" "-e" 1>&6 - -$srcdir/config.make Makefile IGEN_FILTER --enable-sim-filter "$enable_sim_filter" \ - "" "-f 64" "no" "" "yes" "-f 64" "*" "$enable_sim_filter" 1>&6 - -$srcdir/config.make Makefile IGEN_ICACHE --enable-sim-icache "$enable_sim_icache" \ - "" "" "no" "" "yes" "-r 1024" "*" "-r $enable_sim_icache" 1>&6 - -flags="" -if test x"$enable_sim_inline" != x""; then - case "$enable_sim_inline" in - no) flags="";; - 0) flags=" -DDEFAULT_INLINE=0";; - yes | 2) flags=" -DDEFAULT_INLINE=2";; - 1) flags=" -DDEFAULT_INLINE=1";; - *) for x in `echo "$enable_sim_inline" | sed -e "s/,/ /g"`; do - case "$x" in - *_INLINE=*) flags="$flags -D$x";; - *_INLINE) flags="$flags -D$x=2";; - *=*) x=`sed -e "s/=/_INLINE=/"`; flags="$flags -D$x";; - *) flags="$flags -D$x""_INLINE=2";; - esac - done;; - esac -fi -if test x"$flags" != x""; then - echo "Setting INLINE_CFLAGS=$flags" 1>&6 - (echo; echo "# --enable-sim-inline=$enable_sim_inline"; echo "INLINE_CFLAGS =$flags") >> Makefile -else - echo "Setting INLINE_CFLAGS=" 1>&6 - (echo; echo "# no --enable-sim-inline"; echo "INLINE_CFLAGS =") >> Makefile -fi - -$srcdir/config.hdr config.h WITH_BSWAP --enable-sim-bswap "$enable_sim_bswap" "yes" 1 - -case "$target" in - *powerpc-*) endian="BIG_ENDIAN";; - *powerpcle-*) endian="LITTLE_ENDIAN";; - *) echo "Unknown $target" 1>&6; endian="0";; -esac - -$srcdir/config.hdr config.h WITH_TARGET_BYTE_ORDER --enable-sim-endian "$enable_sim_endian" \ - "" "0" "no" "0" "yes" "$endian" \ - "b" "BIG_ENDIAN" "big" "BIG_ENDIAN" "big-endian" "BIG_ENDIAN" \ - "B" "BIG_ENDIAN" "BIG" "BIG_ENDIAN" "BIG-ENDIAN" "BIG_ENDIAN" \ - "l" "LITTLE_ENDIAN" "little" "LITTLE_ENDIAN" "little-endian" "LITTLE_ENDIAN" \ - "L" "LITTLE_ENDIAN" "little" "LITTLE_ENDIAN" "little-endian" "LITTLE_ENDIAN" 1>&6 - -$srcdir/config.hdr config.h WITH_HOST_BYTE_ORDER --enable-sim-hostendian "$enable_sim_hostendian" \ - "b" "BIG_ENDIAN" "big" "BIG_ENDIAN" "big-endian" "BIG_ENDIAN" \ - "B" "BIG_ENDIAN" "BIG" "BIG_ENDIAN" "BIG-ENDIAN" "BIG_ENDIAN" \ - "l" "LITTLE_ENDIAN" "little" "LITTLE_ENDIAN" "little-endian" "LITTLE_ENDIAN" \ - "L" "LITTLE_ENDIAN" "little" "LITTLE_ENDIAN" "little-endian" "LITTLE_ENDIAN" 1>&6 - -$srcdir/config.hdr config.h WITH_SMP --enable-sim-smp "$enable_sim_smp" \ - "" "0" "no" "0" "yes" "2" "*" "$enable_sim_smp" 1>&6 - -$srcdir/config.hdr config.h WITH_TARGET_WORD_BITSIZE --enable-sim-bitsize "$enable_sim_bitsize" \ - "yes" "32" "32" "32" "32" "64" "64" 1>&6 - -$srcdir/config.hdr config.h WITH_HOST_WORD_BITSIZE --enable-sim-hostbitsize "$enable_sim_hostbitsize" \ - "yes" "32" "32" "32" "32" "64" "64" 1>&6 - -$srcdir/config.hdr config.h WITH_ENVIRONMENT --enable-sim-env "$enable_sim_env" \ - "yes" "0" \ - "operating" "OPERATING_ENVIRONMENT" "os" "OPERATING_ENVIRONMENT" "oea" "OPERATING_ENVIRONMENT" \ - "virtual" "VIRTUAL_ENVIRONMENT" "vea" "VIRTUAL_ENVIRONMENT" \ - "user" "USER_ENVIRONMENT" "uea" "USER_ENVIRONMENT" \ - 1>&6 - -$srcdir/config.hdr config.h WITH_TIME_BASE --enable-sim-timebase "$enable_sim_timebase" \ - "no" "0" "yes" "1" 1>&6 - -$srcdir/config.hdr config.h WITH_ALIGNMENT --enable-sim-alignment "$enable_sim_alignment" \ - "no" "NONSTRICT_ALIGNMENT" "nonstrict" "NONSTRICT_ALIGNMENT" \ - "yes" "STRICT_ALIGNMENT" "strict" "STRICT_ALIGNMENT" 1>&6 - -$srcdir/config.hdr config.h WITH_FLOATING_POINT --enable-sim-float "$enable_sim_float" \ - "no" "SOFT_FLOATING_POINT" "soft" "SOFT_FLOATING_POINT" \ - "yes" "HARD_FLOATING_POINT" "hard" "HARD_FLOATING_POINT" 1>&6 - -$srcdir/config.hdr config.h WITH_TRACE --enable-sim-trace "$enable_sim_trace" \ - "no" "0" "yes" "1" 1>&6 - -$srcdir/config.hdr config.h WITH_ASSERT --enable-sim-assert "$enable_sim_assert" \ - "no" "0" "yes" "1" 1>&6 - -$srcdir/config.hdr config.h WITH_MON --enable-sim-monitor "$enable_sim_monitor" \ - "no" "0" "yes" "MONITOR_INSTRUCTION_ISSUE|MONITOR_LOAD_STORE_UNIT" \ - "instruction" "MONITOR_INSTRUCTION_ISSUE" \ - "memory" "MONITOR_LOAD_STORE_UNIT" 1>&6 diff --git a/sim/ppc/configure.in b/sim/ppc/configure.in index 2f24d6473c9..a3c1f391627 100644 --- a/sim/ppc/configure.in +++ b/sim/ppc/configure.in @@ -2,6 +2,196 @@ dnl Process this file with autoconf to produce a configure script. 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], +[case "${enableval}" in + yes) sim_cflags="-O2 -fomit-frame-pointer";; + no) sim_cflags="";; + *) sim_cflags=`echo "${enableval}" | sed -e "s/,/ /"`;; +esac],[sim_cflags=""])dnl + +AC_ARG_ENABLE(sim-config, +[ --enable-sim-config=file Override default config file], +[case "${enableval}" in + yes) sim_config="std-config.h";; + no) sim_config="std-config.h";; + *) sim_config="${enableval}";; +esac],[sim_config="std-config.h]")dnl + +AC_ARG_ENABLE(sim-opcode, +[ --enable-sim-opcode=which Override default opcode lookup.], +[case "${enableval}" in + yes) sim_opcode="ppc-opcode-simple";; + no) sim_opcode="ppc-opcode-simple";; + *) sim_opcode="ppc-opcode-${enableval}";; +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.], +[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.], +[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.], +[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.], +[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.], +[sim_inline="" +case "$enableval" in + no) flags="";; + 0) flags="-DDEFAULT_INLINE=0";; + yes | 2) flags="-DDEFAULT_INLINE=2";; + 1) flags="-DDEFAULT_INLINE=1";; + *) for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + new_flag="" + case "$x" in + *_INLINE=*) new_flag="-D$x";; + *_INLINE) new_flag="-D$x=2";; + *=*) new_flag=`sed -e "s/=/_INLINE=/" -e "s/^/-D/"`;; + *) new_flag="-D$x""_INLINE=2";; + esac + if x"$sim_inline" = x""; then + sim_inline="$new_flag" + else + sim_inline="$flags $new_flag" + fi + done;; +esac],[sim_inline=""])dnl + +AC_ARG_ENABLE(sim-bswap, +[ --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";; + *) sim_bswap="";; +esac],[sim_bswap=""])dnl + +AC_ARG_ENABLE(sim-endian, +[ --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";; + *powerpcle-*) sim_endian="-DWITH_TARGET_BYTE_ORDER=LITTLE_ENDIAN";; + *) echo "Unknown target $target" 1>&6; sim_endian="-DWITH_TARGET_BYTE_ORDER=0";; + esac;; + no) sim_endian="-DWITH_TARGET_BYTE_ORDER=0";; + b*|B*) sim_endian="-DWITH_TARGET_BYTE_ORDER=BIG_ENDIAN";; + l*|L*) sim_endian="-DWITH_TARGET_BYTE_ORDER=LITTLE_ENDIAN";; + *) sim_endian="";; +esac],[sim_endian=""])dnl + +AC_ARG_ENABLE(sim-hostendian, +[ --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";; + l*|L*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN";; + *) sim_hostendian="";; +esac],[sim_hostendian=""])dnl + +AC_ARG_ENABLE(sim-smp, +[ --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";; + *) sim_smp="-DWITH_SMP=$enableval";; +esac],[sim_smp=""])dnl + +AC_ARG_ENABLE(sim-bitsize, +[ --enable-sim-bitsize=n Specify target bitsize (32 or 64).], +[case "${enableval}" in + yes) sim_bitsize="";; + no) sim_bitsize="";; + *) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=$enableval";; +esac],[sim_bitsize=""])dnl + +AC_ARG_ENABLE(sim-hostbitsize, +[ --enable-sim-hostbitsize=n Specify host bitsize (32 or 64).], +[case "${enableval}" in + yes) sim_hostbitsize="";; + no) sim_hostbitsize="";; + *) sim_hostbitsize="-DWITH_HOST_WORD_BITSIZE=$enableval";; +esac],[sim_hostbitsize=""])dnl + +AC_ARG_ENABLE(sim-env, +[ --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";; + user | uea) sim_env="-DWITH_ENVIRONMENT=USER_ENVIRONMENT";; + *) sim_env="";; +esac],[sim_env=""])dnl + +AC_ARG_ENABLE(sim-timebase, +[ --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";; + *) sim_timebase="";; +esac],[sim_timebase=""])dnl + +AC_ARG_ENABLE(sim-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";; + *) sim_alignment="-DWITH_ALIGNMENT=$enableval";; +esac],[sim_alignment=""])dnl + +AC_ARG_ENABLE(sim-trace, +[ --enable-sim-trace Specify whether tracing is supported.], +[case "${enableval}" in + yes) sim_trace="-DWITH_TRACE=1";; + no) sim_trace="-DWITH_TRACE=0";; + *) sim_trace="";; +esac],[sim_trace=""])dnl + +AC_ARG_ENABLE(sim-assert, +[ --enable-sim-assert Specify whether to perform random assertions.], +[case "${enableval}" in + yes) sim_assert="-DWITH_ASSERT=1";; + no) sim_assert="-DWITH_ASSERT=0";; + *) sim_assert="";; +esac],[sim_assert=""])dnl + +AC_ARG_ENABLE(sim-float, +[ --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";; + *) sim_float="";; +esac],[sim_float=""])dnl + +AC_ARG_ENABLE(sim-monitor, +[ --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";; + instruction) sim_mon="-DWITH_MON=MONITOR_INSTRUCTION_ISSUE";; + memory) sim_mon="-DWITH_MON=MONITOR_LOAD_STORE_UNIT";; + *) sim_mon="-DWITH_MON='$enableval'";; +esac],[sim_float=""])dnl + AC_CONFIG_HEADER(config.h:config.in) AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../..) @@ -16,6 +206,29 @@ AC_SUBST(HDEFINES) AR=${AR-ar} AC_SUBST(AR) AC_PROG_RANLIB +AC_SUBST(sim_cflags) +AC_SUBST(sim_config) +AC_SUBST(sim_opcode) +AC_SUBST(sim_switch) +AC_SUBST(sim_dup) +AC_SUBST(sim_filter) +AC_SUBST(sim_icache) +AC_SUBST(sim_inline) +AC_SUBST(sim_bswap) +AC_SUBST(sim_endian) +AC_SUBST(sim_hostendian) +AC_SUBST(sim_smp) +AC_SUBST(sim_bitsize) +AC_SUBST(sim_hostbitsize) +AC_SUBST(sim_env) +AC_SUBST(sim_timebase) +AC_SUBST(sim_alignment) +AC_SUBST(sim_float) +AC_SUBST(sim_trace) +AC_SUBST(sim_assert) +AC_SUBST(sim_monitor) + +AC_CHECK_FUNCS(getrusage) # Put a plausible default for CC_FOR_BUILD in Makefile. AC_C_CROSS @@ -26,122 +239,7 @@ else fi AC_SUBST(CC_FOR_BUILD) -AC_CHECK_HEADERS(string.h strings.h stdlib.h time.h sys/times.h) +AC_CHECK_HEADERS(string.h strings.h stdlib.h time.h sys/times.h unistd.h sys/resource.h) AC_OUTPUT(Makefile, [case x$CONFIG_HEADERS in xconfig.h:config.in) echo > stamp-h ;; esac]) - -if test x"$enable_sim_cflags" != x"" -a x"$enable_sim_cflags" != x"no"; then - if test "$enable_sim_cflags" = "yes"; then - enable_sim_cflags="-fomit-frame-pointer,-O2" - fi - echo "Setting SIM_CFLAGS=$enable_sim_cflags" | sed -e "s/,/ /g" 1>&6 - (echo; echo "# --enable-sim-cflags=$enable_sim_cflags"; - echo "SIM_CFLAGS = $enable_sim_cflags" | sed -e "s/,/ /g") >> Makefile -else - echo "Setting SIM_CFLAGS=" 1>&6 - (echo; echo "# no --enable-sim-cflags"; echo "SIM_CFLAGS =") >> Makefile -fi - -$srcdir/config.make Makefile CONFIG_FILE --enable-sim-config "$enable_sim_config" \ - "" "std-config.h" "no" "std-config.h" "yes" "std-config.h" "*" "$enable_sim_config" 1>&6 - -$srcdir/config.make Makefile IGEN_OPCODE_RULES --enable-sim-opcode "$enable_sim_opcode" \ - "" "ppc-opcode-simple" "no" "ppc-opcode-simple" "yes" "ppc-opcode-simple" \ - "complex" "ppc-opcode-complex" "simple" "ppc-opcode-simple" "stupid" "ppc-opcode-stupid" 1>&6 - -$srcdir/config.make Makefile DGEN_FLAGS --enable-sim-switch "$enable_sim_switch" \ - "" "" "no" "" "yes" "-s" 1>&6 - -$srcdir/config.make Makefile IGEN_DUPLICATE --enable-sim-duplicate "$enable_sim_duplicate" \ - "" "" "no" "" "yes" "-e" 1>&6 - -$srcdir/config.make Makefile IGEN_FILTER --enable-sim-filter "$enable_sim_filter" \ - "" "-f 64" "no" "" "yes" "-f 64" "*" "$enable_sim_filter" 1>&6 - -$srcdir/config.make Makefile IGEN_ICACHE --enable-sim-icache "$enable_sim_icache" \ - "" "" "no" "" "yes" "-r 1024" "*" "-r $enable_sim_icache" 1>&6 - -flags="" -if test x"$enable_sim_inline" != x""; then - case "$enable_sim_inline" in - no) flags="";; - 0) flags=" -DDEFAULT_INLINE=0";; - yes | 2) flags=" -DDEFAULT_INLINE=2";; - 1) flags=" -DDEFAULT_INLINE=1";; - *) for x in `echo "$enable_sim_inline" | sed -e "s/,/ /g"`; do - case "$x" in - *_INLINE=*) flags="$flags -D$x";; - *_INLINE) flags="$flags -D$x=2";; - *=*) x=`sed -e "s/=/_INLINE=/"`; flags="$flags -D$x";; - *) flags="$flags -D$x""_INLINE=2";; - esac - done;; - esac -fi -if test x"$flags" != x""; then - echo "Setting INLINE_CFLAGS=$flags" 1>&6 - (echo; echo "# --enable-sim-inline=$enable_sim_inline"; echo "INLINE_CFLAGS =$flags") >> Makefile -else - echo "Setting INLINE_CFLAGS=" 1>&6 - (echo; echo "# no --enable-sim-inline"; echo "INLINE_CFLAGS =") >> Makefile -fi - -$srcdir/config.hdr config.h WITH_BSWAP --enable-sim-bswap "$enable_sim_bswap" "yes" 1 - -case "$target" in - *powerpc-*) endian="BIG_ENDIAN";; - *powerpcle-*) endian="LITTLE_ENDIAN";; - *) echo "Unknown $target" 1>&6; endian="0";; -esac - -$srcdir/config.hdr config.h WITH_TARGET_BYTE_ORDER --enable-sim-endian "$enable_sim_endian" \ - "" "0" "no" "0" "yes" "$endian" \ - "b" "BIG_ENDIAN" "big" "BIG_ENDIAN" "big-endian" "BIG_ENDIAN" \ - "B" "BIG_ENDIAN" "BIG" "BIG_ENDIAN" "BIG-ENDIAN" "BIG_ENDIAN" \ - "l" "LITTLE_ENDIAN" "little" "LITTLE_ENDIAN" "little-endian" "LITTLE_ENDIAN" \ - "L" "LITTLE_ENDIAN" "little" "LITTLE_ENDIAN" "little-endian" "LITTLE_ENDIAN" 1>&6 - -$srcdir/config.hdr config.h WITH_HOST_BYTE_ORDER --enable-sim-hostendian "$enable_sim_hostendian" \ - "b" "BIG_ENDIAN" "big" "BIG_ENDIAN" "big-endian" "BIG_ENDIAN" \ - "B" "BIG_ENDIAN" "BIG" "BIG_ENDIAN" "BIG-ENDIAN" "BIG_ENDIAN" \ - "l" "LITTLE_ENDIAN" "little" "LITTLE_ENDIAN" "little-endian" "LITTLE_ENDIAN" \ - "L" "LITTLE_ENDIAN" "little" "LITTLE_ENDIAN" "little-endian" "LITTLE_ENDIAN" 1>&6 - -$srcdir/config.hdr config.h WITH_SMP --enable-sim-smp "$enable_sim_smp" \ - "" "0" "no" "0" "yes" "2" "*" "$enable_sim_smp" 1>&6 - -$srcdir/config.hdr config.h WITH_TARGET_WORD_BITSIZE --enable-sim-bitsize "$enable_sim_bitsize" \ - "yes" "32" "32" "32" "32" "64" "64" 1>&6 - -$srcdir/config.hdr config.h WITH_HOST_WORD_BITSIZE --enable-sim-hostbitsize "$enable_sim_hostbitsize" \ - "yes" "32" "32" "32" "32" "64" "64" 1>&6 - -$srcdir/config.hdr config.h WITH_ENVIRONMENT --enable-sim-env "$enable_sim_env" \ - "yes" "0" \ - "operating" "OPERATING_ENVIRONMENT" "os" "OPERATING_ENVIRONMENT" "oea" "OPERATING_ENVIRONMENT" \ - "virtual" "VIRTUAL_ENVIRONMENT" "vea" "VIRTUAL_ENVIRONMENT" \ - "user" "USER_ENVIRONMENT" "uea" "USER_ENVIRONMENT" \ - 1>&6 - -$srcdir/config.hdr config.h WITH_TIME_BASE --enable-sim-timebase "$enable_sim_timebase" \ - "no" "0" "yes" "1" 1>&6 - -$srcdir/config.hdr config.h WITH_ALIGNMENT --enable-sim-alignment "$enable_sim_alignment" \ - "no" "NONSTRICT_ALIGNMENT" "nonstrict" "NONSTRICT_ALIGNMENT" \ - "yes" "STRICT_ALIGNMENT" "strict" "STRICT_ALIGNMENT" 1>&6 - -$srcdir/config.hdr config.h WITH_FLOATING_POINT --enable-sim-float "$enable_sim_float" \ - "no" "SOFT_FLOATING_POINT" "soft" "SOFT_FLOATING_POINT" \ - "yes" "HARD_FLOATING_POINT" "hard" "HARD_FLOATING_POINT" 1>&6 - -$srcdir/config.hdr config.h WITH_TRACE --enable-sim-trace "$enable_sim_trace" \ - "no" "0" "yes" "1" 1>&6 - -$srcdir/config.hdr config.h WITH_ASSERT --enable-sim-assert "$enable_sim_assert" \ - "no" "0" "yes" "1" 1>&6 - -$srcdir/config.hdr config.h WITH_MON --enable-sim-monitor "$enable_sim_monitor" \ - "no" "0" "yes" "MONITOR_INSTRUCTION_ISSUE|MONITOR_LOAD_STORE_UNIT" \ - "instruction" "MONITOR_INSTRUCTION_ISSUE" \ - "memory" "MONITOR_LOAD_STORE_UNIT" 1>&6 diff --git a/sim/ppc/cpu.c b/sim/ppc/cpu.c index 599a5d16f96..f145ae48abd 100644 --- a/sim/ppc/cpu.c +++ b/sim/ppc/cpu.c @@ -31,6 +31,14 @@ #include "cpu.h" #include "idecode.h" +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + struct _cpu { /* the registers */ @@ -49,13 +57,14 @@ struct _cpu { int external_exception_pending; /* the system this processor is contained within */ + cpu_mon *monitor; psim *system; event_queue *events; int cpu_nr; - /* if required, a cache to store decoded instructions */ -#if WITH_IDECODE_CACHE - idecode_cache icache[IDECODE_CACHE_SIZE]; +#if WITH_IDECODE_CACHE_SIZE + /* a cache to store cracked instructions */ + idecode_cache icache[WITH_IDECODE_CACHE_SIZE]; #endif /* address reservation: keep the physical address and the contents @@ -67,8 +76,6 @@ struct _cpu { signed64 decrementer_local_time; event_entry_tag decrementer_event; - /* Counts of number of instructions executed. */ - long number_of_insns; }; @@ -76,6 +83,7 @@ INLINE_CPU cpu * cpu_create(psim *system, core *memory, event_queue *events, + cpu_mon *monitor, int cpu_nr) { cpu *processor = ZALLOC(cpu); @@ -90,11 +98,20 @@ cpu_create(psim *system, processor->system = system; processor->events = events; processor->cpu_nr = cpu_nr; + processor->monitor = monitor; return processor; } +INLINE_CPU void +cpu_init(cpu *processor) +{ + bzero(&processor->regs, sizeof(processor->regs)); + /* FIXME - should any of VM be inited also ? */ +} + + /* find ones way home */ INLINE_CPU psim * @@ -115,6 +132,11 @@ cpu_event_queue(cpu *processor) return processor->events; } +INLINE_CPU cpu_mon * +cpu_monitor(cpu *processor) +{ + return processor->monitor; +} /* The processors local concept of time */ @@ -219,12 +241,23 @@ cpu_halt(cpu *processor, } -#if WITH_IDECODE_CACHE +#if WITH_IDECODE_CACHE_SIZE /* allow access to the cpu's instruction cache */ INLINE_CPU idecode_cache * -cpu_icache(cpu *processor) +cpu_icache_entry(cpu *processor, + unsigned_word cia) +{ + return &processor->icache[cia / 4 % WITH_IDECODE_CACHE_SIZE]; +} + + +INLINE_CPU void +cpu_flush_icache(cpu *processor) { - return processor->icache; + int i; + /* force all addresses to 0xff... so that they never hit */ + for (i = 0; i < WITH_IDECODE_CACHE_SIZE; i++) + processor->icache[i].address = MASK(0, 63); } #endif @@ -264,11 +297,9 @@ cpu_registers(cpu *processor) INLINE_CPU void cpu_synchronize_context(cpu *processor) { -#if WITH_IDECODE_CACHE - /* kill off the contents of the cache */ - int i; - for (i = 0; i < IDECODE_CACHE_SIZE; i++) - processor->icache[i].address = MASK(0,63); +#if (WITH_IDECODE_CACHE) + /* kill of the cache */ + cpu_flush_icache(processor); #endif /* don't allow the processor to change endian modes */ @@ -285,47 +316,11 @@ cpu_synchronize_context(cpu *processor) } -/* # of instructions counter access */ - -INLINE_CPU void -cpu_increment_number_of_insns(cpu *processor) -{ - processor->number_of_insns++; -} - -INLINE_CPU long -cpu_get_number_of_insns(cpu *processor) -{ - return processor->number_of_insns; -} - -static INLINE_CPU char * -cpu_add_commas(char *endbuf, long value) -{ - int comma = 3; - - *--endbuf = '\0'; - do { - if (comma-- == 0) - { - *--endbuf = ','; - comma = 2; - } - - *--endbuf = (value % 10) + '0'; - } while ((value /= 10) != 0); - - return endbuf; -} +/* might again be useful one day */ INLINE_CPU void cpu_print_info(cpu *processor, int verbose) { - char buffer[20]; - - printf_filtered("CPU #%d executed %s instructions.\n", - processor->cpu_nr+1, - cpu_add_commas(buffer + sizeof(buffer), processor->number_of_insns)); } #endif /* _CPU_C_ */ diff --git a/sim/ppc/debug.c b/sim/ppc/debug.c index b23644c03e4..e8c054f00ad 100644 --- a/sim/ppc/debug.c +++ b/sim/ppc/debug.c @@ -23,7 +23,10 @@ #define _DEBUG_C_ #include "basics.h" + +#ifdef HAVE_STDLIB #include +#endif int ppc_trace[nr_trace_options]; int print_info; diff --git a/sim/ppc/device_tree.c b/sim/ppc/device_tree.c index 0d9f7687ffe..3442ba8f7ca 100644 --- a/sim/ppc/device_tree.c +++ b/sim/ppc/device_tree.c @@ -26,13 +26,23 @@ #define STATIC_INLINE_DEVICE_TREE STATIC_INLINE #endif -#include #include -#include #include "basics.h" #include "device_tree.h" +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + typedef enum { node_any = 0, node_device, diff --git a/sim/ppc/devices.c b/sim/ppc/devices.c index c0813d63957..46a3eec067f 100644 --- a/sim/ppc/devices.c +++ b/sim/ppc/devices.c @@ -26,10 +26,7 @@ #define STATIC_INLINE_DEVICES STATIC_INLINE #endif -#include #include -#include -#include #include #include #include @@ -38,6 +35,22 @@ #include "devices.h" #include "events.h" +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + #include "cpu.h" #include "bfd.h" diff --git a/sim/ppc/dgen.c b/sim/ppc/dgen.c index 2d6d3a33e07..9498e855c23 100644 --- a/sim/ppc/dgen.c +++ b/sim/ppc/dgen.c @@ -22,18 +22,32 @@ #include #include #include -#include -#include #include #include #include #include -#include +#include "config.h" #include "misc.h" #include "lf.h" #include "table.h" +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + /****************************************************************/ int spreg_lookup_table = 1; diff --git a/sim/ppc/emul_netbsd.c b/sim/ppc/emul_netbsd.c index e7d09c31b08..1a05f0ab07f 100644 --- a/sim/ppc/emul_netbsd.c +++ b/sim/ppc/emul_netbsd.c @@ -22,14 +22,21 @@ #ifndef _EMUL_NETBSD_C_ #define _EMUL_NETBSD_C_ +#include "emul_generic.h" + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + #include #include #include -#include -#include #include #include -#include #include #include #include @@ -38,6 +45,14 @@ #include #include +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + #define WITH_NetBSD_HOST (NetBSD >= 199306) #if WITH_NetBSD_HOST /* here NetBSD as that is what we're emulating */ #include /* FIXME - should not be including this one */ @@ -49,9 +64,6 @@ extern int getdirentries(int fd, char *buf, int nbytes, long *basep); extern int errno; #endif -#include "emul_generic.h" - - #ifndef STATIC_INLINE_EMUL_NETBSD #define STATIC_INLINE_EMUL_NETBSD STATIC_INLINE #endif diff --git a/sim/ppc/igen.c b/sim/ppc/igen.c index cab46a049cf..3db56c06bfb 100644 --- a/sim/ppc/igen.c +++ b/sim/ppc/igen.c @@ -20,12 +20,21 @@ #include #include -#include #include #include "misc.h" #include "lf.h" #include "table.h" +#include "config.h" + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + /****************************************************************/ diff --git a/sim/ppc/lf.c b/sim/ppc/lf.c new file mode 100644 index 00000000000..ba0cc1d8fbc --- /dev/null +++ b/sim/ppc/lf.c @@ -0,0 +1,273 @@ +/* This file is part of the program psim. + + Copyright (C) 1994-1995, Andrew Cagney + + 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. + + */ + + +#include +#include +#include + +#include "misc.h" +#include "lf.h" + +#ifdef HAVE_STDLIB_H +#include +#endif + +struct _lf { + FILE *stream; + int line_nr; /* nr complete lines written, curr line is line_nr+1 */ + int indent; + int line_blank; + char *file_name; + int number_lines; +}; + + +lf * +lf_open(char *name, + char *real_name, + int number_lines) +{ + /* create a file object */ + lf *new_lf = ZALLOC(lf); + ASSERT(new_lf != NULL); + new_lf->number_lines = number_lines; + new_lf->file_name = (real_name == NULL + ? name + : real_name); + + /* attach to stdout if pipe */ + if (!strcmp(name, "-")) { + new_lf->stream = stdout; + } + else { + /* create a new file */ + new_lf->stream = fopen(name, "w"); + ASSERT(new_lf->stream != NULL); + } + return new_lf; +} + + +void +lf_close(lf *file) +{ + if (file->stream != stdout) { + if (fclose(file->stream)) { + perror("lf_close.fclose"); + exit(1); + } + free(file); + } +} + + +void +lf_putchr(lf *file, + const char chr) +{ + if (chr == '\n') { + file->line_nr += 1; + file->line_blank = 1; + } + else if (file->line_blank) { + int pad; + for (pad = file->indent; pad > 0; pad--) + putc(' ', file->stream); + file->line_blank = 0; + } + putc(chr, file->stream); +} + +void +lf_indent_suppress(lf *file) +{ + file->line_blank = 0; +} + + +void +lf_putstr(lf *file, + const char *string) +{ + const char *chp; + if (string != NULL) { + for (chp = string; *chp != '\0'; chp++) { + lf_putchr(file, *chp); + } + } +} + +static void +do_lf_putunsigned(lf *file, + unsigned u) +{ + if (u > 0) { + do_lf_putunsigned(file, u / 10); + lf_putchr(file, (u % 10) + '0'); + } +} + + +void +lf_putint(lf *file, + int decimal) +{ + if (decimal == 0) + lf_putchr(file, '0'); + else if (decimal < 0) { + lf_putchr(file, '-'); + do_lf_putunsigned(file, -decimal); + } + else if (decimal > 0) { + do_lf_putunsigned(file, decimal); + } + else + ASSERT(0); +} + + +void +lf_printf(lf *file, + const char *fmt, + ...) +{ + char buf[1024]; + va_list ap; + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + /* FIXME - this is really stuffed but so is vsprintf() on a sun! */ + ASSERT(strlen(buf) > 0 && strlen(buf) < sizeof(buf)); + lf_putstr(file, buf); + va_end(ap); +} + + +void +lf_print_c_code(lf *file, char *code) +{ + char *chp = code; + int in_bit_field = 0; + while (*chp != '\0') { + if (*chp == '\t') + chp++; + if (*chp == '#') + lf_indent_suppress(file); + while (*chp != '\0' && *chp != '\n') { + if (chp[0] == '{' && !isspace(chp[1])) { + in_bit_field = 1; + lf_putchr(file, '_'); + } + else if (in_bit_field && chp[0] == ':') { + lf_putchr(file, '_'); + } + else if (in_bit_field && *chp == '}') { + lf_putchr(file, '_'); + in_bit_field = 0; + } + else { + lf_putchr(file, *chp); + } + chp++; + } + if (in_bit_field) + error("bit field paren miss match some where\n"); + if (*chp == '\n') { + lf_putchr(file, '\n'); + chp++; + } + } + lf_putchr(file, '\n'); +} + + +void +lf_print_c_line_nr(lf *file, + int line_nr, + char *file_name) +{ + if (file->number_lines) { + lf_indent_suppress(file); + lf_putstr(file, "#line "); + lf_putint(file, line_nr); + lf_putstr(file, " \""); + lf_putstr(file, file_name); + lf_putstr(file, "\"\n"); + } +} + +void +lf_print_lf_c_line_nr(lf *file) +{ + lf_print_c_line_nr(file, file->line_nr+2, file->file_name); + /* line_nr == last_line, want to number from next */ +} + +void +lf_indent(lf *file, int delta) +{ + file->indent += delta; +} + + +void +lf_print_copyleft(lf *file) +{ + lf_putstr(file, "\ +/* This file is part of the program psim. + + Copyright (C) 1994-1995, Andrew Cagney + + 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. + + -- + + This file was generated by the program gen */ +"); +} + + +void +lf_print_binary(lf *file, int decimal, int width) +{ + int bit; + ASSERT(width > 0); + + for (bit = 1 << (width-1); bit != 0; bit >>= 1) { + if (decimal & bit) + lf_putchr(file, '1'); + else + lf_putchr(file, '0'); + } + +} diff --git a/sim/ppc/main.c b/sim/ppc/main.c index 47f506d5dee..07412bed066 100644 --- a/sim/ppc/main.c +++ b/sim/ppc/main.c @@ -20,12 +20,22 @@ #include -#include #include -#include #include "psim.h" +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + extern char **environ; extern char *optarg; extern int optind; diff --git a/sim/ppc/mon.c b/sim/ppc/mon.c index 60b6fdbefc5..f08604923a2 100644 --- a/sim/ppc/mon.c +++ b/sim/ppc/mon.c @@ -26,12 +26,34 @@ #define STATIC_INLINE_MON STATIC_INLINE #endif -#include - #include "basics.h" #include "cpu.h" #include "mon.h" +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_TIME_H +#include +#endif + +#ifdef HAVE_SYS_TIMES_H +#include +#endif + +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + struct _cpu_mon { unsigned issue_count[nr_itable_entries]; unsigned read_count; @@ -149,11 +171,15 @@ mon_print_info(mon *monitor, int len_cpu; int len_num = 0; int len; + long total_insns = 0; + long cpu_insns_second; + double cpu_time = 0.0; for (cpu_nr = 0; cpu_nr < monitor->nr_cpus; cpu_nr++) { - len = strlen (mon_add_commas(buffer, - sizeof(buffer), - mon_get_number_of_insns(&monitor->cpu_monitor[cpu_nr]))); + unsigned num_insns = mon_get_number_of_insns(&monitor->cpu_monitor[cpu_nr]); + + total_insns += num_insns; + len = strlen (mon_add_commas(buffer, sizeof(buffer), num_insns)); if (len_num < len) len_num = len; } @@ -161,10 +187,27 @@ mon_print_info(mon *monitor, sprintf (buffer, "%d", (int)monitor->nr_cpus + 1); len_cpu = strlen (buffer); +#ifdef HAVE_GETRUSAGE + if (total_insns && verbose > 1) + { + struct rusage mytime; + if (getrusage (RUSAGE_SELF, &mytime) == 0 + && (mytime.ru_utime.tv_sec > 0 || mytime.ru_utime.tv_usec > 0)) { + + cpu_time = (double)mytime.ru_utime.tv_sec + (((double)mytime.ru_utime.tv_usec) / 1000000.0); + cpu_insns_second = (long)(((double)total_insns / cpu_time) + 0.5); + } + } +#endif + for (cpu_nr = 0; cpu_nr < monitor->nr_cpus; cpu_nr++) { if (verbose > 1) { itable_index index; + + if (cpu_nr) + printf_filtered ("\n"); + for (index = 0; index < nr_itable_entries; index++) { if (monitor->cpu_monitor[cpu_nr].issue_count[index]) printf_filtered("CPU #%*d executed %*s %s instruction%s.\n", @@ -175,15 +218,36 @@ mon_print_info(mon *monitor, itable[index].name, (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("CPU #%d executed %s instructions in total.\n", - cpu_nr+1, - mon_add_commas(buffer, - sizeof(buffer), - mon_get_number_of_insns(&monitor->cpu_monitor[cpu_nr]))); - + 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) + printf_filtered("\nAll CPUs executed %s instructions in total.\n", + mon_add_commas(buffer, sizeof(buffer), total_insns)); + + if (cpu_insns_second) + printf_filtered ("\nSimulator speed was %s instructions/second\n", + mon_add_commas(buffer, sizeof(buffer), cpu_insns_second)); } #endif /* _MON_C_ */ diff --git a/sim/ppc/psim.c b/sim/ppc/psim.c index 66c54ed7e66..03b57fea439 100644 --- a/sim/ppc/psim.c +++ b/sim/ppc/psim.c @@ -24,22 +24,32 @@ #include #include -#include #include "config.h" #include "ppc-config.h" #include "inline.h" +#ifdef HAVE_STDLIB_H +#include +#endif + #ifndef STATIC_INLINE_PSIM #define STATIC_INLINE_PSIM STATIC_INLINE #endif -#include #include #include "cpu.h" /* includes psim.h */ #include "idecode.h" +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + #include "bfd.h" diff --git a/sim/ppc/registers.c b/sim/ppc/registers.c new file mode 100644 index 00000000000..f3314365987 --- /dev/null +++ b/sim/ppc/registers.c @@ -0,0 +1,150 @@ +/* This file is part of the program psim. + + Copyright (C) 1994-1995, Andrew Cagney + + 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 _REGISTERS_C_ +#define _REGISTERS_C_ + +#ifndef STATIC_INLINE_REGISTERS +#define STATIC_INLINE_REGISTERS STATIC_INLINE +#endif + + +#include + +#include "basics.h" +#include "registers.h" + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + + +INLINE_REGISTERS void +registers_dump(registers *registers) +{ + int i; + int j; + for (i = 0; i < 8; i++) { + printf_filtered("GPR %2d:", i*4); + for (j = 0; j < 4; j++) { + printf_filtered(" 0x%08x", registers->gpr[i*4 + j]); + } + printf_filtered("\n"); + } +} + +STATIC_INLINE_REGISTERS sprs +find_spr(const char name[]) +{ + sprs spr; + for (spr = 0; spr < nr_of_sprs; spr++) + if (spr_is_valid(spr) + && !strcmp(name, spr_name(spr)) + && spr_index(spr) == spr) + return spr; + return nr_of_sprs; +} + +STATIC_INLINE_REGISTERS int +are_digits(const char *digits) +{ + while (isdigit(*digits)) + digits++; + return *digits == '\0'; +} + + +INLINE_REGISTERS register_descriptions +register_description(const char reg[]) +{ + register_descriptions description; + + /* try for a general-purpose integer or floating point register */ + if (reg[0] == 'r' && are_digits(reg + 1)) { + description.type = reg_gpr; + description.index = atoi(reg+1); + description.size = sizeof(gpreg); + } + else if (reg[0] == 'f' && are_digits(reg + 1)) { + description.type = reg_fpr; + description.index = atoi(reg+1); + description.size = sizeof(fpreg); + } + else if (!strcmp(reg, "pc") || !strcmp(reg, "nia")) { + description.type = reg_pc; + description.index = 0; + description.size = sizeof(unsigned_word); + } + else if (!strcmp(reg, "sp")) { + description.type = reg_gpr; + description.index = 1; + description.size = sizeof(gpreg); + } + else if (!strcmp(reg, "toc")) { + description.type = reg_gpr; + description.index = 2; + description.size = sizeof(gpreg); + } + else if (!strcmp(reg, "cr") || !strcmp(reg, "cnd")) { + description.type = reg_cr; + description.index = 0; + description.size = sizeof(creg); /* FIXME */ + } + else if (!strcmp(reg, "msr") || !strcmp(reg, "ps")) { + description.type = reg_msr; + description.index = 0; + description.size = sizeof(msreg); + } + else if (!strncmp(reg, "sr", 2) && are_digits(reg + 2)) { + description.type = reg_sr; + description.index = atoi(reg+2); + description.size = sizeof(sreg); + } + else if (!strcmp(reg, "cnt")) { + description.type = reg_spr; + description.index = spr_ctr; + description.size = sizeof(spreg); + } + else { + sprs spr = find_spr(reg); + if (spr != nr_of_sprs) { + description.type = reg_spr; + description.index = spr; + description.size = sizeof(spreg); + } + else { + description.type = reg_invalid; + description.index = 0; + description.size = 0; + } + } + return description; +} + +#endif /* _REGISTERS_C_ */ diff --git a/sim/ppc/sim_calls.c b/sim/ppc/sim_calls.c index e262e05a153..8121c94c2d6 100644 --- a/sim/ppc/sim_calls.c +++ b/sim/ppc/sim_calls.c @@ -21,13 +21,23 @@ #include /* FIXME - should be machine dependant version */ #include -#include -#include #include #include "basics.h" #include "psim.h" +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + #include "../../gdb/defs.h" #include "devices.h" diff --git a/sim/ppc/spa-reporter.c b/sim/ppc/spa-reporter.c index 9a7dd29bc65..d021b077804 100644 --- a/sim/ppc/spa-reporter.c +++ b/sim/ppc/spa-reporter.c @@ -22,13 +22,27 @@ * Imported declarations. */ -#include +#include "config.h" + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +#ifdef HAVE_STDLIB_H #include +#endif + +#ifdef HAVE_UNISTD_H +#include + #include #include #include #include -#include #include #include #include diff --git a/sim/ppc/table.c b/sim/ppc/table.c new file mode 100644 index 00000000000..cc065fce271 --- /dev/null +++ b/sim/ppc/table.c @@ -0,0 +1,220 @@ +/* This file is part of the program psim. + + Copyright (C) 1994-1995, Andrew Cagney + + 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. + + */ + + +#include +#include +#include +#include +#include + +#include "misc.h" +#include "lf.h" +#include "table.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +struct _table { + size_t size; + char *buffer; + char *pos; + int line_nr; + int nr_fields; + char *file_name; +}; + +extern table * +table_open(char *file_name, + int nr_fields) +{ + int fd; + struct stat stat_buf; + table *file; + + /* create a file descriptor */ + file = ZALLOC(table); + ASSERT(file != NULL); + file->nr_fields = nr_fields; + + /* save the file name */ + file->file_name = (char*)zalloc(strlen(file_name) + 1); + ASSERT(file->file_name != NULL); + strcpy(file->file_name, file_name); + + /* open the file */ + fd = open(file->file_name, O_RDONLY, 0); + ASSERT(fd >= 0); + + /* determine the size */ + if (fstat(fd, &stat_buf) < 0) { + perror("table_open.fstat"); + exit(1); + } + file->size = stat_buf.st_size; + + /* allocate this much memory */ + file->buffer = (char*)zalloc(file->size+1); + if(file->buffer == NULL) { + perror("table_open.calloc.file->size+1"); + exit(1); + } + file->pos = file->buffer; + + /* read it in */ + if (read(fd, file->buffer, file->size) < file->size) { + perror("table_open.read"); + exit(1); + } + file->buffer[file->size] = '\0'; + + /* done */ + close(fd); + return file; +} + + +extern table_entry * +table_entry_read(table *file) +{ + int field; + table_entry *entry; + + /* skip comments/blanks */ + while(1) { + /* leading white space */ + while (*file->pos != '\0' + && *file->pos != '\n' + && isspace(*file->pos)) + file->pos++; + /* comment */ + if (*file->pos == '#') { + do { + file->pos++; + } while (*file->pos != '\0' && *file->pos != '\n'); + } + /* end of line? */ + if (*file->pos == '\n') { + file->pos++; + file->line_nr++; + } + else + break; + } + if (*file->pos == '\0') + return NULL; + + /* create this new entry */ + entry = (table_entry*)zalloc(sizeof(table_entry) + + (file->nr_fields + 1) * sizeof(char*)); + ASSERT(entry != NULL); + entry->file_name = file->file_name; + entry->nr_fields = file->nr_fields; + + /* break the line into its colon delimitered fields */ + for (field = 0; field < file->nr_fields-1; field++) { + entry->fields[field] = file->pos; + while(*file->pos && *file->pos != ':' && *file->pos != '\n') + file->pos++; + if (*file->pos == ':') { + *file->pos = '\0'; + file->pos++; + } + } + + /* any trailing stuff not the last field */ + ASSERT(field == file->nr_fields-1); + entry->fields[field] = file->pos; + while (*file->pos && *file->pos != '\n') { + file->pos++; + } + if (*file->pos == '\n') { + *file->pos = '\0'; + file->pos++; + } + file->line_nr++; + entry->line_nr = file->line_nr; + + /* if following lines tab indented, put in the annex */ + if (*file->pos == '\t') { + entry->annex = file->pos; + do { + do { + file->pos++; + } while (*file->pos != '\0' && *file->pos != '\n'); + if (*file->pos == '\n') { + file->pos++; + file->line_nr++; + } + } while (*file->pos != '\0' && *file->pos == '\t'); + if (file->pos[-1] == '\n') + file->pos[-1] = '\0'; + } + else + entry->annex = NULL; + + /* return it */ + return entry; + +} + + +extern void +dump_table_entry(table_entry *entry, + int indent) +{ + printf("(table_entry*)%p\n", entry); + + if (entry != NULL) { + int field; + char sep; + + sep = ' '; + dumpf(indent, "(fields"); + for (field = 0; field < entry->nr_fields; field++) { + printf("%c%s", sep, entry->fields[field]); + sep = ':'; + } + printf(")\n"); + + dumpf(indent, "(line_nr %d)\n", entry->line_nr); + + dumpf(indent, "(file_name %s)\n", entry->file_name); + + dumpf(indent, "(annex\n%s\n", entry->annex); + dumpf(indent, " )\n"); + + } +} + + +extern void +table_entry_lf_c_line_nr(lf *file, + table_entry *entry) +{ + lf_print_c_line_nr(file, entry->line_nr, entry->file_name); +} + +