sim: avr: convert to nrun.o
authorMike Frysinger <vapier@gentoo.org>
Sat, 28 Mar 2015 09:34:55 +0000 (05:34 -0400)
committerMike Frysinger <vapier@gentoo.org>
Sat, 28 Mar 2015 09:35:29 +0000 (05:35 -0400)
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
sim/avr/Makefile.in
sim/avr/config.in
sim/avr/configure
sim/avr/configure.ac
sim/avr/interp.c
sim/avr/sim-main.h [new file with mode: 0644]

index 6f1e042f5cc3ed3fefd06fcdaf28146155290889..b8fa775668dde7aaac4320c8ef59224c72d50e42 100644 (file)
@@ -1,3 +1,35 @@
+2015-03-28  Mike Frysinger  <vapier@gentoo.org>
+
+       * 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  <vapier@gentoo.org>
 
        * aclocal.m4, config.in, configure: Regenerate.
index b852211b07e99369cb925c2483a538ef246b1e3d..880b11828833081b4eb788122d152bed3eec17e1 100644 (file)
@@ -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
 
 ## 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
index 5ded70312e7f60ef73bdea691aa113fcac75584a..6003e581c68d0becc09fb940056d385b10a0056e 100644 (file)
@@ -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
 #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
 
index fa262774f0beb35966f19c11e5294e1c27f638a3..c5f7a712e59c8a9b28fcaabbf821e6ced7ca44ae 100755 (executable)
@@ -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 <sys/types.h>
+            #include <sys/param.h>
+
+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 <sys/types.h>
+               #include <sys/param.h>
+
+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 <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+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 <limits.h>
+
+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
index 799a5dfa61238c4fc99460bd46fdb356a3878064..a487225058c0eeee921fde14df01d339b5d09e78 100644 (file)
@@ -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
index 0df51557f3c37cad3cc78067b5a3950b284d9322..d16993598bc60d85f8247a684c0f18c06e757a83 100644 (file)
 #include <string.h>
 #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 (file)
index 0000000..02c76d3
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.  */
+
+#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