From 9943d3185abb9aa3e7269ece80d00e9020187ec6 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 28 Mar 2015 05:34:55 -0400 Subject: [PATCH] sim: avr: convert to nrun.o Looks like a lot more work than actually was -- the main decode loop was de-indented by dropping the loop as a step-once function. --- sim/avr/ChangeLog | 32 ++ sim/avr/Makefile.in | 21 +- sim/avr/config.in | 15 + sim/avr/configure | 528 ++++++++++++++++- sim/avr/configure.ac | 7 + sim/avr/interp.c | 1565 +++++++++++++++++++++++--------------------------- sim/avr/sim-main.h | 53 ++ 7 files changed, 1378 insertions(+), 843 deletions(-) create mode 100644 sim/avr/sim-main.h diff --git a/sim/avr/ChangeLog b/sim/avr/ChangeLog index 6f1e042..b8fa775 100644 --- a/sim/avr/ChangeLog +++ b/sim/avr/ChangeLog @@ -1,3 +1,35 @@ +2015-03-28 Mike Frysinger + + * Makefile.in (SIM_EXTRA_CFLAGS, SIM_RUN_OBJS, SIM_EXTRA_LIBS): Delete. + (interp.o): Delete rule. + (SIM_OBJS): Change to $(SIM_NEW_COMMON_OBJS). + * configure.ac: Call SIM_AC_OPTION_ENDIAN, SIM_AC_OPTION_ALIGNMENT, + SIM_AC_OPTION_HOSTENDIAN, SIM_AC_OPTION_ENVIRONMENT, + SIM_AC_OPTION_INLINE, and SIM_AC_OPTION_WARNINGS. + * interp.c: Delete gdb/callback.h, gdb/signals.h, dis-asm.h, and + sim-utils.h includes. Include sim-main.h, sim-base.h, and + sim-options.h. + (tracing, lock_step, verbose): Delete. + (pc): Drop static. + (cur_bfd, cpu_exception, cpu_signal, sim_kind, myname, callback): + Delete. + (flash, sram): Add TODO. + (sim_size, disasm_read_memory, disasm_perror_memory, + disassemble_insn): Delete. + (sim_resume): Rename to ... + (step_once): ... this. Mark static. Delete step variable and while + loop, and unindent body. Add #if 0 around tracing/verbose code. + Change cpu_exception to sim_engine_halt. + (sim_trace): Delete. + (sim_engine_run): New function. + (sim_stop_reason, sim_stop, sim_info): Delete. + (free_state): New function. + (sim_open, sim_close, sim_create_inferior): Rewrite from scratch. + (sim_load, sim_do_command, sim_set_callbacks, + sim_complete_command): delete. + * sim-main.h: New file. + * config.in, configure: Regenerate. + 2015-03-16 Mike Frysinger * aclocal.m4, config.in, configure: Regenerate. diff --git a/sim/avr/Makefile.in b/sim/avr/Makefile.in index b852211..880b118 100644 --- a/sim/avr/Makefile.in +++ b/sim/avr/Makefile.in @@ -1,6 +1,6 @@ # Makefile template for Configure for the AVR sim library. # Copyright (C) 2009-2015 Free Software Foundation, Inc. -# +# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or @@ -16,14 +16,15 @@ ## COMMON_PRE_CONFIG_FRAG -SIM_EXTRA_CFLAGS = -DSIM_USE_DEPRECATED_RUN_FRONTEND - -# Use the deprecated run frontend until we migrate to nrun.o -SIM_RUN_OBJS = run.o - -SIM_OBJS = interp.o sim-load.o -SIM_EXTRA_LIBS = -lm +SIM_OBJS = \ + $(SIM_NEW_COMMON_OBJS) \ + interp.o \ + sim-cpu.o \ + sim-engine.o \ + sim-hload.o \ + sim-hrw.o \ + sim-reason.o \ + sim-resume.o \ + sim-stop.o ## COMMON_POST_CONFIG_FRAG - -interp.o: interp.c diff --git a/sim/avr/config.in b/sim/avr/config.in index 5ded703..6003e58 100644 --- a/sim/avr/config.in +++ b/sim/avr/config.in @@ -1,5 +1,8 @@ /* config.in. Generated from configure.ac by autoheader. */ +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS @@ -135,6 +138,18 @@ #endif +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + /* Define to 1 if on MINIX. */ #undef _MINIX diff --git a/sim/avr/configure b/sim/avr/configure index fa26277..c5f7a71 100755 --- a/sim/avr/configure +++ b/sim/avr/configure @@ -759,6 +759,14 @@ enable_sim_trace enable_sim_profile with_pkgversion with_bugurl +enable_sim_endian +enable_sim_alignment +enable_sim_hostendian +enable_sim_environment +enable_sim_inline +enable_werror +enable_build_warnings +enable_sim_build_warnings ' ac_precious_vars='build_alias host_alias @@ -1401,6 +1409,16 @@ Optional Features: --enable-sim-stdio Specify whether to use stdio for console input/output. --enable-sim-trace=opts Enable tracing flags --enable-sim-profile=opts Enable profiling flags + --enable-sim-endian=endian Specify target byte endian orientation. + --enable-sim-alignment=align Specify strict, nonstrict or forced alignment of memory accesses. + --enable-sim-hostendian=end Specify host byte endian orientation. + --enable-sim-environment=environment Specify mixed, user, virtual or operating environment. + --enable-sim-inline=inlines Specify which functions should be inlined. + --enable-werror treat compile warnings as errors + --enable-build-warnings enable build-time compiler warnings if gcc is used + --enable-sim-build-warnings + enable SIM specific build-time compiler warnings if + gcc is used Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -12354,7 +12372,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12357 "configure" +#line 12375 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12460,7 +12478,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12463 "configure" +#line 12481 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12951,6 +12969,511 @@ sim_link_links="${sim_link_links} targ-vals.def" +wire_endian="LITTLE_ENDIAN" +default_endian="" +# Check whether --enable-sim-endian was given. +if test "${enable_sim_endian+set}" = set; then : + enableval=$enable_sim_endian; case "${enableval}" in + b*|B*) sim_endian="-DWITH_TARGET_BYTE_ORDER=BIG_ENDIAN";; + l*|L*) sim_endian="-DWITH_TARGET_BYTE_ORDER=LITTLE_ENDIAN";; + yes) if test x"$wire_endian" != x; then + sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}" + else + if test x"$default_endian" != x; then + sim_endian="-DWITH_TARGET_BYTE_ORDER=${default_endian}" + else + echo "No hard-wired endian for target $target" 1>&6 + sim_endian="-DWITH_TARGET_BYTE_ORDER=0" + fi + fi;; + no) if test x"$default_endian" != x; then + sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}" + else + if test x"$wire_endian" != x; then + sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${wire_endian}" + else + echo "No default endian for target $target" 1>&6 + sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=0" + fi + fi;; + *) as_fn_error "\"Unknown value $enableval for --enable-sim-endian\"" "$LINENO" 5; sim_endian="";; +esac +if test x"$silent" != x"yes" && test x"$sim_endian" != x""; then + echo "Setting endian flags = $sim_endian" 6>&1 +fi +else + if test x"$default_endian" != x; then + sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}" +else + if test x"$wire_endian" != x; then + sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}" + else + sim_endian= + fi +fi +fi + +wire_alignment="STRICT_ALIGNMENT" +default_alignment="STRICT_ALIGNMENT" + +# Check whether --enable-sim-alignment was given. +if test "${enable_sim_alignment+set}" = set; then : + enableval=$enable_sim_alignment; case "${enableval}" in + strict | STRICT) sim_alignment="-DWITH_ALIGNMENT=STRICT_ALIGNMENT";; + nonstrict | NONSTRICT) sim_alignment="-DWITH_ALIGNMENT=NONSTRICT_ALIGNMENT";; + forced | FORCED) sim_alignment="-DWITH_ALIGNMENT=FORCED_ALIGNMENT";; + yes) if test x"$wire_alignment" != x; then + sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}" + else + if test x"$default_alignment" != x; then + sim_alignment="-DWITH_ALIGNMENT=${default_alignment}" + else + echo "No hard-wired alignment for target $target" 1>&6 + sim_alignment="-DWITH_ALIGNMENT=0" + fi + fi;; + no) if test x"$default_alignment" != x; then + sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}" + else + if test x"$wire_alignment" != x; then + sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${wire_alignment}" + else + echo "No default alignment for target $target" 1>&6 + sim_alignment="-DWITH_DEFAULT_ALIGNMENT=0" + fi + fi;; + *) as_fn_error "\"Unknown value $enableval passed to --enable-sim-alignment\"" "$LINENO" 5; sim_alignment="";; +esac +if test x"$silent" != x"yes" && test x"$sim_alignment" != x""; then + echo "Setting alignment flags = $sim_alignment" 6>&1 +fi +else + if test x"$default_alignment" != x; then + sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}" +else + if test x"$wire_alignment" != x; then + sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}" + else + sim_alignment= + fi +fi +fi + + +# Check whether --enable-sim-hostendian was given. +if test "${enable_sim_hostendian+set}" = set; then : + enableval=$enable_sim_hostendian; 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";; + *) as_fn_error "\"Unknown value $enableval for --enable-sim-hostendian\"" "$LINENO" 5; sim_hostendian="";; +esac +if test x"$silent" != x"yes" && test x"$sim_hostendian" != x""; then + echo "Setting hostendian flags = $sim_hostendian" 6>&1 +fi +else + +if test "x$cross_compiling" = "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + if test $ac_cv_c_bigendian = yes; then + sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN" + else + sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN" + fi +else + sim_hostendian="-DWITH_HOST_BYTE_ORDER=0" +fi +fi + + +# Check whether --enable-sim-environment was given. +if test "${enable_sim_environment+set}" = set; then : + enableval=$enable_sim_environment; case "${enableval}" in + all | ALL) sim_environment="-DWITH_ENVIRONMENT=ALL_ENVIRONMENT";; + user | USER) sim_environment="-DWITH_ENVIRONMENT=USER_ENVIRONMENT";; + virtual | VIRTUAL) sim_environment="-DWITH_ENVIRONMENT=VIRTUAL_ENVIRONMENT";; + operating | OPERATING) sim_environment="-DWITH_ENVIRONMENT=OPERATING_ENVIRONMENT";; + *) as_fn_error "\"Unknown value $enableval passed to --enable-sim-environment\"" "$LINENO" 5; + sim_environment="";; +esac +if test x"$silent" != x"yes" && test x"$sim_environment" != x""; then + echo "Setting sim environment = $sim_environment" 6>&1 +fi +else + sim_environment="-DWITH_ENVIRONMENT=ALL_ENVIRONMENT" +fi + + +default_sim_inline="" +# Check whether --enable-sim-inline was given. +if test "${enable_sim_inline+set}" = set; then : + enableval=$enable_sim_inline; sim_inline="" +case "$enableval" in + no) sim_inline="-DDEFAULT_INLINE=0";; + 0) sim_inline="-DDEFAULT_INLINE=0";; + yes | 2) sim_inline="-DDEFAULT_INLINE=ALL_C_INLINE";; + 1) sim_inline="-DDEFAULT_INLINE=INLINE_LOCALS";; + *) for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + new_flag="" + case "$x" in + *_INLINE=*) new_flag="-D$x";; + *=*) new_flag=`echo "$x" | sed -e "s/=/_INLINE=/" -e "s/^/-D/"`;; + *_INLINE) new_flag="-D$x=ALL_C_INLINE";; + *) new_flag="-D$x""_INLINE=ALL_C_INLINE";; + esac + if test x"$sim_inline" = x""; then + sim_inline="$new_flag" + else + sim_inline="$sim_inline $new_flag" + fi + done;; +esac +if test x"$silent" != x"yes" && test x"$sim_inline" != x""; then + echo "Setting inline flags = $sim_inline" 6>&1 +fi +else + +if test "x$cross_compiling" = "xno"; then + if test x"$GCC" != "x" -a x"${default_sim_inline}" != "x" ; then + sim_inline="${default_sim_inline}" + if test x"$silent" != x"yes"; then + echo "Setting inline flags = $sim_inline" 6>&1 + fi + else + sim_inline="" + fi +else + sim_inline="-DDEFAULT_INLINE=0" +fi +fi + + +# Check whether --enable-werror was given. +if test "${enable_werror+set}" = set; then : + enableval=$enable_werror; case "${enableval}" in + yes | y) ERROR_ON_WARNING="yes" ;; + no | n) ERROR_ON_WARNING="no" ;; + *) as_fn_error "bad value ${enableval} for --enable-werror" "$LINENO" 5 ;; + esac +fi + + +# Enable -Werror by default when using gcc +if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then + ERROR_ON_WARNING=yes +fi + +WERROR_CFLAGS="" +if test "${ERROR_ON_WARNING}" = yes ; then +# NOTE: Disabled in the sim dir due to most sims generating warnings. +# WERROR_CFLAGS="-Werror" + true +fi + +build_warnings="-Wall -Wdeclaration-after-statement -Wpointer-arith \ +-Wpointer-sign \ +-Wno-unused -Wunused-value -Wunused-function \ +-Wno-switch -Wno-char-subscripts -Wmissing-prototypes +-Wdeclaration-after-statement -Wempty-body -Wmissing-parameter-type \ +-Wold-style-declaration -Wold-style-definition" + +# Enable -Wno-format by default when using gcc on mingw since many +# GCC versions complain about %I64. +case "${host}" in + *-*-mingw32*) build_warnings="$build_warnings -Wno-format" ;; + *) build_warnings="$build_warnings -Wformat-nonliteral" ;; +esac + +# Check whether --enable-build-warnings was given. +if test "${enable_build_warnings+set}" = set; then : + enableval=$enable_build_warnings; case "${enableval}" in + yes) ;; + no) build_warnings="-w";; + ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${build_warnings} ${t}";; + *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${t} ${build_warnings}";; + *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then + echo "Setting compiler warning flags = $build_warnings" 6>&1 +fi +fi +# Check whether --enable-sim-build-warnings was given. +if test "${enable_sim_build_warnings+set}" = set; then : + enableval=$enable_sim_build_warnings; case "${enableval}" in + yes) ;; + no) build_warnings="-w";; + ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${build_warnings} ${t}";; + *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${t} ${build_warnings}";; + *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then + echo "Setting GDB specific compiler warning flags = $build_warnings" 6>&1 +fi +fi +WARN_CFLAGS="" +if test "x${build_warnings}" != x -a "x$GCC" = xyes +then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler warning flags" >&5 +$as_echo_n "checking compiler warning flags... " >&6; } + # Separate out the -Werror flag as some files just cannot be + # compiled with it enabled. + for w in ${build_warnings}; do + case $w in + -Werr*) WERROR_CFLAGS=-Werror ;; + *) # Check that GCC accepts it + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $w" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + WARN_CFLAGS="${WARN_CFLAGS} $w" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$saved_CFLAGS" + esac + done + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${WARN_CFLAGS} ${WERROR_CFLAGS}" >&5 +$as_echo "${WARN_CFLAGS} ${WERROR_CFLAGS}" >&6; } +fi + + + ac_sources="$sim_link_files" ac_dests="$sim_link_links" while test -n "$ac_sources"; do @@ -13085,6 +13608,7 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi + : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files diff --git a/sim/avr/configure.ac b/sim/avr/configure.ac index 799a5df..a487225 100644 --- a/sim/avr/configure.ac +++ b/sim/avr/configure.ac @@ -5,4 +5,11 @@ sinclude(../common/acinclude.m4) SIM_AC_COMMON +SIM_AC_OPTION_ENDIAN(LITTLE_ENDIAN) +SIM_AC_OPTION_ALIGNMENT(STRICT_ALIGNMENT,STRICT_ALIGNMENT) +SIM_AC_OPTION_HOSTENDIAN +SIM_AC_OPTION_ENVIRONMENT +SIM_AC_OPTION_INLINE +SIM_AC_OPTION_WARNINGS + SIM_AC_OUTPUT diff --git a/sim/avr/interp.c b/sim/avr/interp.c index 0df5155..d169935 100644 --- a/sim/avr/interp.c +++ b/sim/avr/interp.c @@ -23,12 +23,12 @@ #include #endif #include "bfd.h" -#include "gdb/callback.h" -#include "gdb/signals.h" #include "libiberty.h" #include "gdb/remote-sim.h" -#include "dis-asm.h" -#include "sim-utils.h" + +#include "sim-main.h" +#include "sim-base.h" +#include "sim-options.h" /* As AVR is a 8/16 bits processor, define handy types. */ typedef unsigned short int word; @@ -36,13 +36,8 @@ typedef signed short int sword; typedef unsigned char byte; typedef signed char sbyte; -/* Debug flag to display instructions and registers. */ -static int tracing = 0; -static int lock_step = 0; -static int verbose; - /* The only real register. */ -static unsigned int pc; +unsigned int pc; /* We update a cycle counter. */ static unsigned int cycles = 0; @@ -50,15 +45,6 @@ static unsigned int cycles = 0; /* If true, the pc needs more than 2 bytes. */ static int avr_pc22; -static struct bfd *cur_bfd; - -static enum sim_stop cpu_exception; -static int cpu_signal; - -static SIM_OPEN_KIND sim_kind; -static char *myname; -static host_callback *callback; - /* Max size of I space (which is always flash on avr). */ #define MAX_AVR_FLASH (128 * 1024) #define PC_MASK (MAX_AVR_FLASH - 1) @@ -237,14 +223,10 @@ struct avr_insn_cell }; /* I&D memories. */ +/* TODO: Should be moved to SIM_CPU. */ static struct avr_insn_cell flash[MAX_AVR_FLASH]; static byte sram[MAX_AVR_SRAM]; -void -sim_size (int s) -{ -} - /* Sign extend a value. */ static int sign_ext (word val, int nb_bits) { @@ -747,61 +729,8 @@ decode (unsigned int pc) break; } } - sim_cb_eprintf (callback, - "Unhandled instruction at pc=0x%x, op=%04x\n", pc * 2, op1); - return OP_bad; -} - -/* Disassemble an instruction. */ - -static int -disasm_read_memory (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, - struct disassemble_info *info) -{ - int res; - - res = sim_read (NULL, memaddr, myaddr, length); - if (res != length) - return -1; - return 0; -} - -/* Memory error support for an opcodes disassembler. */ - -static void -disasm_perror_memory (int status, bfd_vma memaddr, - struct disassemble_info *info) -{ - if (status != -1) - /* Can't happen. */ - info->fprintf_func (info->stream, "Unknown error %d.", status); - else - /* Actually, address between memaddr and memaddr + len was - out of bounds. */ - info->fprintf_func (info->stream, - "Address 0x%x is out of bounds.", - (int) memaddr); -} -static void -disassemble_insn (SIM_DESC sd, SIM_ADDR pc) -{ - struct disassemble_info disasm_info; - int len; - int i; - - INIT_DISASSEMBLE_INFO (disasm_info, callback, sim_cb_eprintf); - - disasm_info.arch = bfd_get_arch (cur_bfd); - disasm_info.mach = bfd_get_mach (cur_bfd); - disasm_info.endian = BFD_ENDIAN_LITTLE; - disasm_info.read_memory_func = disasm_read_memory; - disasm_info.memory_error_func = disasm_perror_memory; - - len = print_insn_avr (pc << 1, &disasm_info); - len = len / 2; - for (i = 0; i < len; i++) - sim_cb_eprintf (callback, " %04x", flash[pc + i].op); + return OP_bad; } static void @@ -862,37 +791,27 @@ gen_mul (unsigned int res) cycles++; } -void -sim_resume (SIM_DESC sd, int step, int signal) +static void +step_once (SIM_CPU *cpu) { unsigned int ipc; - if (step) - { - cpu_exception = sim_stopped; - cpu_signal = GDB_SIGNAL_TRAP; - } - else - cpu_exception = sim_running; - - do - { - int code; - word op; - byte res; - byte r, d, vd; - - again: - code = flash[pc].code; - op = flash[pc].op; + int code; + word op; + byte res; + byte r, d, vd; + again: + code = flash[pc].code; + op = flash[pc].op; - if ((tracing || lock_step) && code != OP_unknown) +#if 0 + if (tracing && code != OP_unknown) { if (verbose > 0) { int flags; int i; - + sim_cb_eprintf (callback, "R00-07:"); for (i = 0; i < 8; i++) sim_cb_eprintf (callback, " %02x", sram[i]); @@ -916,709 +835,701 @@ sim_resume (SIM_DESC sd, int step, int signal) sim_cb_eprintf (callback, "\n"); } - if (lock_step && !tracing) + if (!tracing) sim_cb_eprintf (callback, "%06x: %04x\n", 2 * pc, flash[pc].op); else { sim_cb_eprintf (callback, "pc=0x%06x insn=0x%04x code=%d r=%d\n", 2 * pc, flash[pc].op, code, flash[pc].r); - disassemble_insn (sd, pc); + disassemble_insn (CPU_STATE (cpu), pc); sim_cb_eprintf (callback, "\n"); } } +#endif - ipc = pc; - pc = (pc + 1) & PC_MASK; - cycles++; + ipc = pc; + pc = (pc + 1) & PC_MASK; + cycles++; - switch (code) + switch (code) + { + case OP_unknown: + flash[ipc].code = decode(ipc); + pc = ipc; + cycles--; + goto again; + + case OP_nop: + break; + + case OP_jmp: + /* 2 words instruction, but we don't care about the pc. */ + pc = ((flash[ipc].r << 16) | flash[ipc + 1].op) & PC_MASK; + cycles += 2; + break; + + case OP_eijmp: + pc = ((sram[EIND] << 16) | read_word (REGZ)) & PC_MASK; + cycles += 2; + break; + + case OP_ijmp: + pc = read_word (REGZ) & PC_MASK; + cycles += 1; + break; + + case OP_call: + /* 2 words instruction. */ + pc++; + do_call ((flash[ipc].r << 16) | flash[ipc + 1].op); + break; + + case OP_eicall: + do_call ((sram[EIND] << 16) | read_word (REGZ)); + break; + + case OP_icall: + do_call (read_word (REGZ)); + break; + + case OP_rcall: + do_call (pc + sign_ext (op & 0xfff, 12)); + break; + + case OP_reti: + sram[SREG] |= SREG_I; + /* Fall through */ + case OP_ret: { - case OP_unknown: - flash[ipc].code = decode(ipc); - pc = ipc; - cycles--; - goto again; - break; - - case OP_nop: - break; - - case OP_jmp: - /* 2 words instruction, but we don't care about the pc. */ - pc = ((flash[ipc].r << 16) | flash[ipc + 1].op) & PC_MASK; - cycles += 2; - break; - - case OP_eijmp: - pc = ((sram[EIND] << 16) | read_word (REGZ)) & PC_MASK; - cycles += 2; - break; - - case OP_ijmp: - pc = read_word (REGZ) & PC_MASK; - cycles += 1; - break; - - case OP_call: - /* 2 words instruction. */ - pc++; - do_call ((flash[ipc].r << 16) | flash[ipc + 1].op); - break; - - case OP_eicall: - do_call ((sram[EIND] << 16) | read_word (REGZ)); - break; - - case OP_icall: - do_call (read_word (REGZ)); - break; - - case OP_rcall: - do_call (pc + sign_ext (op & 0xfff, 12)); - break; - - case OP_reti: - sram[SREG] |= SREG_I; - /* Fall through */ - case OP_ret: - { - unsigned int sp = read_word (REG_SP); - if (avr_pc22) - { - pc = sram[++sp] << 16; - cycles++; - } - else - pc = 0; - pc |= sram[++sp] << 8; - pc |= sram[++sp]; - write_word (REG_SP, sp); - } - cycles += 3; - break; - - case OP_break: - /* Stop on this address. */ - cpu_exception = sim_stopped; - cpu_signal = GDB_SIGNAL_TRAP; - pc = ipc; - break; - - case OP_bld: - d = get_d (op); - r = flash[ipc].r; - if (sram[SREG] & SREG_T) - sram[d] |= r; - else - sram[d] &= ~r; - break; - - case OP_bst: - if (sram[get_d (op)] & flash[ipc].r) - sram[SREG] |= SREG_T; + unsigned int sp = read_word (REG_SP); + if (avr_pc22) + { + pc = sram[++sp] << 16; + cycles++; + } else - sram[SREG] &= ~SREG_T; - break; - - case OP_sbrc: - case OP_sbrs: - if (((sram[get_d (op)] & flash[ipc].r) == 0) ^ ((op & 0x0200) != 0)) - { - int l = get_insn_length(pc); - pc += l; - cycles += l; - } - break; - - case OP_push: - { - unsigned int sp = read_word (REG_SP); - sram[sp--] = sram[get_d (op)]; - write_word (REG_SP, sp); - } - cycles++; - break; - - case OP_pop: + pc = 0; + pc |= sram[++sp] << 8; + pc |= sram[++sp]; + write_word (REG_SP, sp); + } + cycles += 3; + break; + + case OP_break: + /* Stop on this address. */ + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); + pc = ipc; + break; + + case OP_bld: + d = get_d (op); + r = flash[ipc].r; + if (sram[SREG] & SREG_T) + sram[d] |= r; + else + sram[d] &= ~r; + break; + + case OP_bst: + if (sram[get_d (op)] & flash[ipc].r) + sram[SREG] |= SREG_T; + else + sram[SREG] &= ~SREG_T; + break; + + case OP_sbrc: + case OP_sbrs: + if (((sram[get_d (op)] & flash[ipc].r) == 0) ^ ((op & 0x0200) != 0)) { - unsigned int sp = read_word (REG_SP); - sram[get_d (op)] = sram[++sp]; - write_word (REG_SP, sp); + int l = get_insn_length(pc); + pc += l; + cycles += l; } - cycles++; - break; - - case OP_bclr: - sram[SREG] &= ~(1 << ((op >> 4) & 0x7)); - break; - - case OP_bset: - sram[SREG] |= 1 << ((op >> 4) & 0x7); - break; - - case OP_rjmp: - pc = (pc + sign_ext (op & 0xfff, 12)) & PC_MASK; - cycles++; - break; - - case OP_eor: - d = get_d (op); - res = sram[d] ^ sram[get_r (op)]; - sram[d] = res; - update_flags_logic (res); - break; - - case OP_and: - d = get_d (op); - res = sram[d] & sram[get_r (op)]; - sram[d] = res; - update_flags_logic (res); - break; - - case OP_andi: - d = get_d16 (op); - res = sram[d] & get_K (op); - sram[d] = res; - update_flags_logic (res); - break; + break; - case OP_or: - d = get_d (op); - res = sram[d] | sram[get_r (op)]; - sram[d] = res; - update_flags_logic (res); - break; - - case OP_ori: - d = get_d16 (op); - res = sram[d] | get_K (op); - sram[d] = res; - update_flags_logic (res); - break; + case OP_push: + { + unsigned int sp = read_word (REG_SP); + sram[sp--] = sram[get_d (op)]; + write_word (REG_SP, sp); + } + cycles++; + break; - case OP_com: - d = get_d (op); - res = ~sram[d]; - sram[d] = res; - update_flags_logic (res); + case OP_pop: + { + unsigned int sp = read_word (REG_SP); + sram[get_d (op)] = sram[++sp]; + write_word (REG_SP, sp); + } + cycles++; + break; + + case OP_bclr: + sram[SREG] &= ~(1 << ((op >> 4) & 0x7)); + break; + + case OP_bset: + sram[SREG] |= 1 << ((op >> 4) & 0x7); + break; + + case OP_rjmp: + pc = (pc + sign_ext (op & 0xfff, 12)) & PC_MASK; + cycles++; + break; + + case OP_eor: + d = get_d (op); + res = sram[d] ^ sram[get_r (op)]; + sram[d] = res; + update_flags_logic (res); + break; + + case OP_and: + d = get_d (op); + res = sram[d] & sram[get_r (op)]; + sram[d] = res; + update_flags_logic (res); + break; + + case OP_andi: + d = get_d16 (op); + res = sram[d] & get_K (op); + sram[d] = res; + update_flags_logic (res); + break; + + case OP_or: + d = get_d (op); + res = sram[d] | sram[get_r (op)]; + sram[d] = res; + update_flags_logic (res); + break; + + case OP_ori: + d = get_d16 (op); + res = sram[d] | get_K (op); + sram[d] = res; + update_flags_logic (res); + break; + + case OP_com: + d = get_d (op); + res = ~sram[d]; + sram[d] = res; + update_flags_logic (res); + sram[SREG] |= SREG_C; + break; + + case OP_swap: + d = get_d (op); + vd = sram[d]; + sram[d] = (vd >> 4) | (vd << 4); + break; + + case OP_neg: + d = get_d (op); + vd = sram[d]; + res = -vd; + sram[d] = res; + sram[SREG] &= ~(SREG_H | SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); + if (res == 0) + sram[SREG] |= SREG_Z; + else sram[SREG] |= SREG_C; - break; - - case OP_swap: - d = get_d (op); - vd = sram[d]; - sram[d] = (vd >> 4) | (vd << 4); - break; - - case OP_neg: - d = get_d (op); - vd = sram[d]; - res = -vd; - sram[d] = res; - sram[SREG] &= ~(SREG_H | SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); - if (res == 0) - sram[SREG] |= SREG_Z; - else - sram[SREG] |= SREG_C; - if (res == 0x80) - sram[SREG] |= SREG_V | SREG_N; - else if (res & 0x80) - sram[SREG] |= SREG_N | SREG_S; - if ((res | vd) & 0x08) - sram[SREG] |= SREG_H; - break; - - case OP_inc: - d = get_d (op); - res = sram[d] + 1; - sram[d] = res; - sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z); - if (res == 0x80) - sram[SREG] |= SREG_V | SREG_N; - else if (res & 0x80) - sram[SREG] |= SREG_N | SREG_S; - else if (res == 0) - sram[SREG] |= SREG_Z; - break; - - case OP_dec: - d = get_d (op); - res = sram[d] - 1; - sram[d] = res; - sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z); - if (res == 0x7f) - sram[SREG] |= SREG_V | SREG_S; - else if (res & 0x80) - sram[SREG] |= SREG_N | SREG_S; - else if (res == 0) - sram[SREG] |= SREG_Z; - break; - - case OP_lsr: - case OP_asr: - d = get_d (op); - vd = sram[d]; - res = (vd >> 1) | (vd & flash[ipc].r); - sram[d] = res; - sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); - if (vd & 1) - sram[SREG] |= SREG_C | SREG_S; - if (res & 0x80) - sram[SREG] |= SREG_N; - if (!(sram[SREG] & SREG_N) ^ !(sram[SREG] & SREG_C)) - sram[SREG] |= SREG_V; - if (res == 0) - sram[SREG] |= SREG_Z; - break; - - case OP_ror: - d = get_d (op); - vd = sram[d]; - res = vd >> 1 | (sram[SREG] << 7); - sram[d] = res; - sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); - if (vd & 1) - sram[SREG] |= SREG_C | SREG_S; - if (res & 0x80) - sram[SREG] |= SREG_N; - if (!(sram[SREG] & SREG_N) ^ !(sram[SREG] & SREG_C)) - sram[SREG] |= SREG_V; - if (res == 0) - sram[SREG] |= SREG_Z; - break; - - case OP_mul: - gen_mul ((word)sram[get_r (op)] * (word)sram[get_d (op)]); - break; - - case OP_muls: - gen_mul((sword)(sbyte)sram[get_r16 (op)] - * (sword)(sbyte)sram[get_d16 (op)]); - break; - - case OP_mulsu: - gen_mul ((sword)(word)sram[get_r16_23 (op)] - * (sword)(sbyte)sram[get_d16_23 (op)]); - break; - - case OP_fmul: - gen_mul(((word)sram[get_r16_23 (op)] - * (word)sram[get_d16_23 (op)]) << 1); - break; - - case OP_fmuls: - gen_mul(((sword)(sbyte)sram[get_r16_23 (op)] - * (sword)(sbyte)sram[get_d16_23 (op)]) << 1); - break; - - case OP_fmulsu: - gen_mul(((sword)(word)sram[get_r16_23 (op)] - * (sword)(sbyte)sram[get_d16_23 (op)]) << 1); - break; - - case OP_adc: - case OP_add: - r = sram[get_r (op)]; - d = get_d (op); - vd = sram[d]; - res = r + vd + (sram[SREG] & flash[ipc].r); - sram[d] = res; - update_flags_add (res, vd, r); - break; - - case OP_sub: + if (res == 0x80) + sram[SREG] |= SREG_V | SREG_N; + else if (res & 0x80) + sram[SREG] |= SREG_N | SREG_S; + if ((res | vd) & 0x08) + sram[SREG] |= SREG_H; + break; + + case OP_inc: + d = get_d (op); + res = sram[d] + 1; + sram[d] = res; + sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z); + if (res == 0x80) + sram[SREG] |= SREG_V | SREG_N; + else if (res & 0x80) + sram[SREG] |= SREG_N | SREG_S; + else if (res == 0) + sram[SREG] |= SREG_Z; + break; + + case OP_dec: + d = get_d (op); + res = sram[d] - 1; + sram[d] = res; + sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z); + if (res == 0x7f) + sram[SREG] |= SREG_V | SREG_S; + else if (res & 0x80) + sram[SREG] |= SREG_N | SREG_S; + else if (res == 0) + sram[SREG] |= SREG_Z; + break; + + case OP_lsr: + case OP_asr: + d = get_d (op); + vd = sram[d]; + res = (vd >> 1) | (vd & flash[ipc].r); + sram[d] = res; + sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); + if (vd & 1) + sram[SREG] |= SREG_C | SREG_S; + if (res & 0x80) + sram[SREG] |= SREG_N; + if (!(sram[SREG] & SREG_N) ^ !(sram[SREG] & SREG_C)) + sram[SREG] |= SREG_V; + if (res == 0) + sram[SREG] |= SREG_Z; + break; + + case OP_ror: + d = get_d (op); + vd = sram[d]; + res = vd >> 1 | (sram[SREG] << 7); + sram[d] = res; + sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); + if (vd & 1) + sram[SREG] |= SREG_C | SREG_S; + if (res & 0x80) + sram[SREG] |= SREG_N; + if (!(sram[SREG] & SREG_N) ^ !(sram[SREG] & SREG_C)) + sram[SREG] |= SREG_V; + if (res == 0) + sram[SREG] |= SREG_Z; + break; + + case OP_mul: + gen_mul ((word)sram[get_r (op)] * (word)sram[get_d (op)]); + break; + + case OP_muls: + gen_mul ((sword)(sbyte)sram[get_r16 (op)] + * (sword)(sbyte)sram[get_d16 (op)]); + break; + + case OP_mulsu: + gen_mul ((sword)(word)sram[get_r16_23 (op)] + * (sword)(sbyte)sram[get_d16_23 (op)]); + break; + + case OP_fmul: + gen_mul (((word)sram[get_r16_23 (op)] + * (word)sram[get_d16_23 (op)]) << 1); + break; + + case OP_fmuls: + gen_mul (((sword)(sbyte)sram[get_r16_23 (op)] + * (sword)(sbyte)sram[get_d16_23 (op)]) << 1); + break; + + case OP_fmulsu: + gen_mul (((sword)(word)sram[get_r16_23 (op)] + * (sword)(sbyte)sram[get_d16_23 (op)]) << 1); + break; + + case OP_adc: + case OP_add: + r = sram[get_r (op)]; + d = get_d (op); + vd = sram[d]; + res = r + vd + (sram[SREG] & flash[ipc].r); + sram[d] = res; + update_flags_add (res, vd, r); + break; + + case OP_sub: + d = get_d (op); + vd = sram[d]; + r = sram[get_r (op)]; + res = vd - r; + sram[d] = res; + update_flags_sub (res, vd, r); + if (res == 0) + sram[SREG] |= SREG_Z; + break; + + case OP_sbc: + { + byte old = sram[SREG]; d = get_d (op); vd = sram[d]; r = sram[get_r (op)]; - res = vd - r; + res = vd - r - (old & SREG_C); sram[d] = res; update_flags_sub (res, vd, r); - if (res == 0) + if (res == 0 && (old & SREG_Z)) sram[SREG] |= SREG_Z; - break; - - case OP_sbc: - { - byte old = sram[SREG]; - d = get_d (op); - vd = sram[d]; - r = sram[get_r (op)]; - res = vd - r - (old & SREG_C); - sram[d] = res; - update_flags_sub (res, vd, r); - if (res == 0 && (old & SREG_Z)) - sram[SREG] |= SREG_Z; - } - break; + } + break; + + case OP_subi: + d = get_d16 (op); + vd = sram[d]; + r = get_K (op); + res = vd - r; + sram[d] = res; + update_flags_sub (res, vd, r); + if (res == 0) + sram[SREG] |= SREG_Z; + break; + + case OP_sbci: + { + byte old = sram[SREG]; - case OP_subi: d = get_d16 (op); vd = sram[d]; r = get_K (op); - res = vd - r; + res = vd - r - (old & SREG_C); sram[d] = res; update_flags_sub (res, vd, r); - if (res == 0) + if (res == 0 && (old & SREG_Z)) sram[SREG] |= SREG_Z; - break; - - case OP_sbci: + } + break; + + case OP_mov: + sram[get_d (op)] = sram[get_r (op)]; + break; + + case OP_movw: + d = (op & 0xf0) >> 3; + r = (op & 0x0f) << 1; + sram[d] = sram[r]; + sram[d + 1] = sram[r + 1]; + break; + + case OP_out: + d = get_A (op) + 0x20; + res = sram[get_d (op)]; + sram[d] = res; + if (d == STDIO_PORT) + putchar (res); + else if (d == EXIT_PORT) + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, pc, sim_exited, 0); + else if (d == ABORT_PORT) + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, pc, sim_exited, 1); + break; + + case OP_in: + d = get_A (op) + 0x20; + sram[get_d (op)] = sram[d]; + break; + + case OP_cbi: + d = get_biA (op) + 0x20; + sram[d] &= ~(1 << get_b(op)); + break; + + case OP_sbi: + d = get_biA (op) + 0x20; + sram[d] |= 1 << get_b(op); + break; + + case OP_sbic: + if (!(sram[get_biA (op) + 0x20] & 1 << get_b(op))) { - byte old = sram[SREG]; - - d = get_d16 (op); - vd = sram[d]; - r = get_K (op); - res = vd - r - (old & SREG_C); - sram[d] = res; - update_flags_sub (res, vd, r); - if (res == 0 && (old & SREG_Z)) - sram[SREG] |= SREG_Z; + int l = get_insn_length(pc); + pc += l; + cycles += l; } - break; - - case OP_mov: - sram[get_d (op)] = sram[get_r (op)]; - break; - - case OP_movw: - d = (op & 0xf0) >> 3; - r = (op & 0x0f) << 1; - sram[d] = sram[r]; - sram[d + 1] = sram[r + 1]; - break; - - case OP_out: - d = get_A (op) + 0x20; - res = sram[get_d (op)]; - sram[d] = res; - if (d == STDIO_PORT) - putchar (res); - else if (d == EXIT_PORT) - { - cpu_exception = sim_exited; - cpu_signal = 0; - return; - } - else if (d == ABORT_PORT) - { - cpu_exception = sim_exited; - cpu_signal = 1; - return; - } - break; - - case OP_in: - d = get_A (op) + 0x20; - sram[get_d (op)] = sram[d]; - break; - - case OP_cbi: - d = get_biA (op) + 0x20; - sram[d] &= ~(1 << get_b(op)); - break; - - case OP_sbi: - d = get_biA (op) + 0x20; - sram[d] |= 1 << get_b(op); - break; - - case OP_sbic: - if (!(sram[get_biA (op) + 0x20] & 1 << get_b(op))) - { - int l = get_insn_length(pc); - pc += l; - cycles += l; - } - break; - - case OP_sbis: - if (sram[get_biA (op) + 0x20] & 1 << get_b(op)) - { - int l = get_insn_length(pc); - pc += l; - cycles += l; - } - break; - - case OP_ldi: - res = get_K (op); - d = get_d16 (op); - sram[d] = res; - break; - - case OP_lds: - sram[get_d (op)] = sram[flash[pc].op]; - pc++; - cycles++; - break; - - case OP_sts: - sram[flash[pc].op] = sram[get_d (op)]; - pc++; - cycles++; - break; - - case OP_cpse: - if (sram[get_r (op)] == sram[get_d (op)]) - { - int l = get_insn_length(pc); - pc += l; - cycles += l; - } - break; + break; - case OP_cp: - r = sram[get_r (op)]; + case OP_sbis: + if (sram[get_biA (op) + 0x20] & 1 << get_b(op)) + { + int l = get_insn_length(pc); + pc += l; + cycles += l; + } + break; + + case OP_ldi: + res = get_K (op); + d = get_d16 (op); + sram[d] = res; + break; + + case OP_lds: + sram[get_d (op)] = sram[flash[pc].op]; + pc++; + cycles++; + break; + + case OP_sts: + sram[flash[pc].op] = sram[get_d (op)]; + pc++; + cycles++; + break; + + case OP_cpse: + if (sram[get_r (op)] == sram[get_d (op)]) + { + int l = get_insn_length(pc); + pc += l; + cycles += l; + } + break; + + case OP_cp: + r = sram[get_r (op)]; + d = sram[get_d (op)]; + res = d - r; + update_flags_sub (res, d, r); + if (res == 0) + sram[SREG] |= SREG_Z; + break; + + case OP_cpi: + r = get_K (op); + d = sram[get_d16 (op)]; + res = d - r; + update_flags_sub (res, d, r); + if (res == 0) + sram[SREG] |= SREG_Z; + break; + + case OP_cpc: + { + byte old = sram[SREG]; d = sram[get_d (op)]; - res = d - r; + r = sram[get_r (op)]; + res = d - r - (old & SREG_C); update_flags_sub (res, d, r); - if (res == 0) + if (res == 0 && (old & SREG_Z)) sram[SREG] |= SREG_Z; - break; + } + break; - case OP_cpi: - r = get_K (op); - d = sram[get_d16 (op)]; - res = d - r; - update_flags_sub (res, d, r); - if (res == 0) - sram[SREG] |= SREG_Z; - break; + case OP_brbc: + if (!(sram[SREG] & flash[ipc].r)) + { + pc = (pc + get_k (op)) & PC_MASK; + cycles++; + } + break; - case OP_cpc: + case OP_brbs: + if (sram[SREG] & flash[ipc].r) { - byte old = sram[SREG]; - d = sram[get_d (op)]; - r = sram[get_r (op)]; - res = d - r - (old & SREG_C); - update_flags_sub (res, d, r); - if (res == 0 && (old & SREG_Z)) - sram[SREG] |= SREG_Z; + pc = (pc + get_k (op)) & PC_MASK; + cycles++; } - break; + break; + + case OP_lpm: + sram[0] = get_lpm (read_word (REGZ)); + cycles += 2; + break; + + case OP_lpm_Z: + sram[get_d (op)] = get_lpm (read_word (REGZ)); + cycles += 2; + break; + + case OP_lpm_inc_Z: + sram[get_d (op)] = get_lpm (read_word_post_inc (REGZ)); + cycles += 2; + break; + + case OP_elpm: + sram[0] = get_lpm (get_z ()); + cycles += 2; + break; + + case OP_elpm_Z: + sram[get_d (op)] = get_lpm (get_z ()); + cycles += 2; + break; + + case OP_elpm_inc_Z: + { + unsigned int z = get_z (); - case OP_brbc: - if (!(sram[SREG] & flash[ipc].r)) - { - pc = (pc + get_k (op)) & PC_MASK; - cycles++; - } - break; + sram[get_d (op)] = get_lpm (z); + z++; + sram[REGZ_LO] = z; + sram[REGZ_HI] = z >> 8; + sram[RAMPZ] = z >> 16; + } + cycles += 2; + break; + + case OP_ld_Z_inc: + sram[get_d (op)] = sram[read_word_post_inc (REGZ) & SRAM_MASK]; + cycles++; + break; + + case OP_ld_dec_Z: + sram[get_d (op)] = sram[read_word_pre_dec (REGZ) & SRAM_MASK]; + cycles++; + break; + + case OP_ld_X_inc: + sram[get_d (op)] = sram[read_word_post_inc (REGX) & SRAM_MASK]; + cycles++; + break; + + case OP_ld_dec_X: + sram[get_d (op)] = sram[read_word_pre_dec (REGX) & SRAM_MASK]; + cycles++; + break; + + case OP_ld_Y_inc: + sram[get_d (op)] = sram[read_word_post_inc (REGY) & SRAM_MASK]; + cycles++; + break; + + case OP_ld_dec_Y: + sram[get_d (op)] = sram[read_word_pre_dec (REGY) & SRAM_MASK]; + cycles++; + break; + + case OP_st_X: + sram[read_word (REGX) & SRAM_MASK] = sram[get_d (op)]; + cycles++; + break; + + case OP_st_X_inc: + sram[read_word_post_inc (REGX) & SRAM_MASK] = sram[get_d (op)]; + cycles++; + break; + + case OP_st_dec_X: + sram[read_word_pre_dec (REGX) & SRAM_MASK] = sram[get_d (op)]; + cycles++; + break; + + case OP_st_Z_inc: + sram[read_word_post_inc (REGZ) & SRAM_MASK] = sram[get_d (op)]; + cycles++; + break; + + case OP_st_dec_Z: + sram[read_word_pre_dec (REGZ) & SRAM_MASK] = sram[get_d (op)]; + cycles++; + break; + + case OP_st_Y_inc: + sram[read_word_post_inc (REGY) & SRAM_MASK] = sram[get_d (op)]; + cycles++; + break; + + case OP_st_dec_Y: + sram[read_word_pre_dec (REGY) & SRAM_MASK] = sram[get_d (op)]; + cycles++; + break; + + case OP_std_Y: + sram[read_word (REGY) + flash[ipc].r] = sram[get_d (op)]; + cycles++; + break; + + case OP_std_Z: + sram[read_word (REGZ) + flash[ipc].r] = sram[get_d (op)]; + cycles++; + break; + + case OP_ldd_Z: + sram[get_d (op)] = sram[read_word (REGZ) + flash[ipc].r]; + cycles++; + break; + + case OP_ldd_Y: + sram[get_d (op)] = sram[read_word (REGY) + flash[ipc].r]; + cycles++; + break; + + case OP_ld_X: + sram[get_d (op)] = sram[read_word (REGX) & SRAM_MASK]; + cycles++; + break; + + case OP_sbiw: + { + word wk = get_k6 (op); + word wres; + word wr; - case OP_brbs: - if (sram[SREG] & flash[ipc].r) - { - pc = (pc + get_k (op)) & PC_MASK; - cycles++; - } - break; - - case OP_lpm: - sram[0] = get_lpm (read_word (REGZ)); - cycles += 2; - break; - - case OP_lpm_Z: - sram[get_d (op)] = get_lpm (read_word (REGZ)); - cycles += 2; - break; - - case OP_lpm_inc_Z: - sram[get_d (op)] = get_lpm (read_word_post_inc (REGZ)); - cycles += 2; - break; - - case OP_elpm: - sram[0] = get_lpm (get_z ()); - cycles += 2; - break; - - case OP_elpm_Z: - sram[get_d (op)] = get_lpm (get_z ()); - cycles += 2; - break; - - case OP_elpm_inc_Z: - { - unsigned int z = get_z (); + d = get_d24 (op); + wr = read_word (d); + wres = wr - wk; - sram[get_d (op)] = get_lpm (z); - z++; - sram[REGZ_LO] = z; - sram[REGZ_HI] = z >> 8; - sram[RAMPZ] = z >> 16; - } - cycles += 2; - break; - - case OP_ld_Z_inc: - sram[get_d (op)] = sram[read_word_post_inc (REGZ) & SRAM_MASK]; - cycles++; - break; - - case OP_ld_dec_Z: - sram[get_d (op)] = sram[read_word_pre_dec (REGZ) & SRAM_MASK]; - cycles++; - break; - - case OP_ld_X_inc: - sram[get_d (op)] = sram[read_word_post_inc (REGX) & SRAM_MASK]; - cycles++; - break; - - case OP_ld_dec_X: - sram[get_d (op)] = sram[read_word_pre_dec (REGX) & SRAM_MASK]; - cycles++; - break; - - case OP_ld_Y_inc: - sram[get_d (op)] = sram[read_word_post_inc (REGY) & SRAM_MASK]; - cycles++; - break; - - case OP_ld_dec_Y: - sram[get_d (op)] = sram[read_word_pre_dec (REGY) & SRAM_MASK]; - cycles++; - break; - - case OP_st_X: - sram[read_word (REGX) & SRAM_MASK] = sram[get_d (op)]; - cycles++; - break; - - case OP_st_X_inc: - sram[read_word_post_inc (REGX) & SRAM_MASK] = sram[get_d (op)]; - cycles++; - break; - - case OP_st_dec_X: - sram[read_word_pre_dec (REGX) & SRAM_MASK] = sram[get_d (op)]; - cycles++; - break; - - case OP_st_Z_inc: - sram[read_word_post_inc (REGZ) & SRAM_MASK] = sram[get_d (op)]; - cycles++; - break; - - case OP_st_dec_Z: - sram[read_word_pre_dec (REGZ) & SRAM_MASK] = sram[get_d (op)]; - cycles++; - break; - - case OP_st_Y_inc: - sram[read_word_post_inc (REGY) & SRAM_MASK] = sram[get_d (op)]; - cycles++; - break; - - case OP_st_dec_Y: - sram[read_word_pre_dec (REGY) & SRAM_MASK] = sram[get_d (op)]; - cycles++; - break; - - case OP_std_Y: - sram[read_word (REGY) + flash[ipc].r] = sram[get_d (op)]; - cycles++; - break; - - case OP_std_Z: - sram[read_word (REGZ) + flash[ipc].r] = sram[get_d (op)]; - cycles++; - break; - - case OP_ldd_Z: - sram[get_d (op)] = sram[read_word (REGZ) + flash[ipc].r]; - cycles++; - break; - - case OP_ldd_Y: - sram[get_d (op)] = sram[read_word (REGY) + flash[ipc].r]; - cycles++; - break; - - case OP_ld_X: - sram[get_d (op)] = sram[read_word (REGX) & SRAM_MASK]; - cycles++; - break; - - case OP_sbiw: - { - word wk = get_k6 (op); - word wres; - word wr; - - d = get_d24 (op); - wr = read_word (d); - wres = wr - wk; - - sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); - if (wres == 0) - sram[SREG] |= SREG_Z; - if (wres & 0x8000) - sram[SREG] |= SREG_N; - if (wres & ~wr & 0x8000) - sram[SREG] |= SREG_C; - if (~wres & wr & 0x8000) - sram[SREG] |= SREG_V; - if (((~wres & wr) ^ wres) & 0x8000) - sram[SREG] |= SREG_S; - write_word (d, wres); - } - cycles++; - break; + sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); + if (wres == 0) + sram[SREG] |= SREG_Z; + if (wres & 0x8000) + sram[SREG] |= SREG_N; + if (wres & ~wr & 0x8000) + sram[SREG] |= SREG_C; + if (~wres & wr & 0x8000) + sram[SREG] |= SREG_V; + if (((~wres & wr) ^ wres) & 0x8000) + sram[SREG] |= SREG_S; + write_word (d, wres); + } + cycles++; + break; - case OP_adiw: - { - word wk = get_k6 (op); - word wres; - word wr; - - d = get_d24 (op); - wr = read_word (d); - wres = wr + wk; - - sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); - if (wres == 0) - sram[SREG] |= SREG_Z; - if (wres & 0x8000) - sram[SREG] |= SREG_N; - if (~wres & wr & 0x8000) - sram[SREG] |= SREG_C; - if (wres & ~wr & 0x8000) - sram[SREG] |= SREG_V; - if (((wres & ~wr) ^ wres) & 0x8000) - sram[SREG] |= SREG_S; - write_word (d, wres); - } - cycles++; - break; - - case OP_bad: - sim_cb_eprintf (callback, "Bad instruction at pc=0x%x\n", ipc * 2); - return; - - default: - sim_cb_eprintf (callback, - "Unhandled instruction at pc=0x%x, code=%d\n", - 2 * ipc, code); - return; + case OP_adiw: + { + word wk = get_k6 (op); + word wres; + word wr; + + d = get_d24 (op); + wr = read_word (d); + wres = wr + wk; + + sram[SREG] &= ~(SREG_S | SREG_V | SREG_N | SREG_Z | SREG_C); + if (wres == 0) + sram[SREG] |= SREG_Z; + if (wres & 0x8000) + sram[SREG] |= SREG_N; + if (~wres & wr & 0x8000) + sram[SREG] |= SREG_C; + if (wres & ~wr & 0x8000) + sram[SREG] |= SREG_V; + if (((wres & ~wr) ^ wres) & 0x8000) + sram[SREG] |= SREG_S; + write_word (d, wres); } - } - while (cpu_exception == sim_running); -} + cycles++; + break; + case OP_bad: + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, pc, sim_signalled, SIM_SIGILL); -int -sim_trace (SIM_DESC sd) + default: + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, pc, sim_signalled, SIM_SIGILL); + } +} + +void +sim_engine_run (SIM_DESC sd, + int next_cpu_nr, /* ignore */ + int nr_cpus, /* ignore */ + int siggnal) /* ignore */ { - tracing = 1; - - sim_resume (sd, 0, 0); + SIM_CPU *cpu; + + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + + cpu = STATE_CPU (sd, 0); - tracing = 0; - - return 1; + while (1) + { + step_once (cpu); + if (sim_events_tick (sd)) + sim_events_process (sd); + } } int @@ -1752,104 +1663,96 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length) return 0; } -void -sim_stop_reason (SIM_DESC sd, enum sim_stop * reason, int *sigrc) -{ - *reason = cpu_exception; - *sigrc = cpu_signal; -} - -int -sim_stop (SIM_DESC sd) -{ - cpu_exception = sim_stopped; - cpu_signal = GDB_SIGNAL_INT; - return 1; -} - -void -sim_info (SIM_DESC sd, int verbose) +static void +free_state (SIM_DESC sd) { - callback->printf_filtered - (callback, "\n\n# cycles %10u\n", cycles); + if (STATE_MODULES (sd) != NULL) + sim_module_uninstall (sd); + sim_cpu_free_all (sd); + sim_state_free (sd); } SIM_DESC sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv) { - myname = argv[0]; - callback = cb; - - cur_bfd = abfd; + SIM_DESC sd = sim_state_alloc (kind, cb); + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); - /* Fudge our descriptor for now. */ - return (SIM_DESC) 1; -} + /* The cpu data is kept in a separately allocated chunk of memory. */ + if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK) + { + free_state (sd); + return 0; + } -void -sim_close (SIM_DESC sd, int quitting) -{ - /* nothing to do */ -} + STATE_WATCHPOINTS (sd)->pc = &pc; + STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (pc); -SIM_RC -sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty) -{ - bfd *prog_bfd; + if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) + { + free_state (sd); + return 0; + } - /* Clear all the memory. */ - memset (sram, 0, sizeof (sram)); - memset (flash, 0, sizeof (flash)); + /* getopt will print the error message so we just have to exit if this fails. + FIXME: Hmmm... in the case of gdb we need getopt to call + print_filtered. */ + if (sim_parse_args (sd, argv) != SIM_RC_OK) + { + free_state (sd); + return 0; + } - prog_bfd = sim_load_file (sd, myname, callback, prog, abfd, - sim_kind == SIM_OPEN_DEBUG, - 0, sim_write); - if (prog_bfd == NULL) - return SIM_RC_FAIL; + /* Check for/establish the a reference program image. */ + if (sim_analyze_program (sd, + (STATE_PROG_ARGV (sd) != NULL + ? *STATE_PROG_ARGV (sd) + : NULL), abfd) != SIM_RC_OK) + { + free_state (sd); + return 0; + } - avr_pc22 = (bfd_get_mach (prog_bfd) >= bfd_mach_avr6); + /* Configure/verify the target byte order and other runtime + configuration options. */ + if (sim_config (sd) != SIM_RC_OK) + { + sim_module_uninstall (sd); + return 0; + } - if (abfd != NULL) - cur_bfd = abfd; + if (sim_post_argv_init (sd) != SIM_RC_OK) + { + /* Uninstall the modules to avoid memory leaks, + file descriptor leaks, etc. */ + sim_module_uninstall (sd); + return 0; + } - return SIM_RC_OK; -} + /* Clear all the memory. */ + memset (sram, 0, sizeof (sram)); + memset (flash, 0, sizeof (flash)); -SIM_RC -sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd, char **argv, char **env) -{ - /* Set the initial register set. */ - pc = 0; - - return SIM_RC_OK; + return sd; } void -sim_do_command (SIM_DESC sd, const char *cmd) +sim_close (SIM_DESC sd, int quitting) { - /* Nothing there yet; it's all an error. */ - - if (cmd == NULL) - return; - - if (strcmp (cmd, "verbose") == 0) - verbose = 2; - else if (strcmp (cmd, "trace") == 0) - tracing = 1; - else - sim_cb_eprintf (callback, - "Error: \"%s\" is not a valid avr simulator command.\n", - cmd); + sim_module_uninstall (sd); } -void -sim_set_callbacks (host_callback *ptr) +SIM_RC +sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env) { - callback = ptr; -} + /* Set the PC. */ + if (abfd != NULL) + pc = bfd_get_start_address (abfd); + else + pc = 0; -char ** -sim_complete_command (SIM_DESC sd, const char *text, const char *word) -{ - return NULL; + if (abfd != NULL) + avr_pc22 = (bfd_get_mach (abfd) >= bfd_mach_avr6); + + return SIM_RC_OK; } diff --git a/sim/avr/sim-main.h b/sim/avr/sim-main.h new file mode 100644 index 0000000..02c76d3 --- /dev/null +++ b/sim/avr/sim-main.h @@ -0,0 +1,53 @@ +/* Moxie Simulator definition. + Copyright (C) 2009-2015 Free Software Foundation, Inc. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 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, see . */ + +#ifndef SIM_MAIN_H +#define SIM_MAIN_H + +#define SIM_HAVE_BIENDIAN + +#include "sim-basics.h" + +typedef address_word sim_cia; +extern unsigned int pc; + +#define CIA_GET(cpu) pc +#define CIA_SET(cpu,val) (pc) = (val) + +typedef struct _sim_cpu SIM_CPU; + +#include "sim-base.h" + +struct _sim_cpu { + + sim_cpu_base base; +}; + +struct sim_state { + + sim_cpu *cpu[MAX_NR_PROCESSORS]; +#if (WITH_SMP) +#define STATE_CPU(sd,n) ((sd)->cpu[n]) +#else +#define STATE_CPU(sd,n) ((sd)->cpu[0]) +#endif + + sim_state_base base; +}; + +#endif -- 2.7.4