This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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.

Committed.
---
 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  <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.
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 <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
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 <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
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 <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
-- 
2.3.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]