Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] Add LM32 simulator
@ 2009-04-15 18:12 Jon Beniston
  0 siblings, 0 replies; only message in thread
From: Jon Beniston @ 2009-04-15 18:12 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1486 bytes --]

Hi,

The attach patch adds simulator support for Lattice Mico32 (lm32)
architecture. The gdb part of the patch is here:

http://sourceware.org/ml/gdb-patches/2009-04/msg00336.html

Cheers,
Jon

ChangeLog

include/gdb/
2009-04-15  Jon Beniston <jon@beniston.com>

        * sim-lm32.h: New file.

sim/
2009-04-15  Jon Beniston <jon@beniston.com>

        * MAINTAINERS: Add Jon Beniston as maintainer of lm32 sim.
        * configure.ac: Add lm32 target. 
        * lm32: New directory.               

sim/common
2009-04-15  Jon Beniston <jon@beniston.com>

        * gennltvals.sh: Add lm32 target.
        * nltvals.def: Add lm32 syscall definitions. 
        
sim/lm32/
2009-04-15  Jon Beniston <jon@beniston.com>

        * Makefile.in: New file.
        * arch.c: New file.
        * arch.h: New file.
        * config.in: New file.
        * configure: New file.
        * configure.ac: New file.
        * cpu.c: New file.
        * cpu.h: New file.
        * cpuall.h: New file.
        * decode.c: New file.
        * decode.h: New file.
        * dv-lm32cpu.c: New file.
        * dv-lm32timer.c: New file.
        * dv-lm32uart.c: New file.
        * lm32.c: New file.
        * lm32-sim.h: New file.
        * mloop.in: New file.
        * model.c: New file.
        * sem.c: New file.
        * sem-switch.c: New file.
        * sim-if.c: New file.
        * sim-main.c: New file.
        * tconfig.in: New file.
        * traps.c: New file.
        * user.c: New file.
 


[-- Attachment #2: lm32.patch.3 --]
[-- Type: application/octet-stream, Size: 254213 bytes --]

Index: include/gdb/sim-lm32.h
===================================================================
RCS file: include/gdb/sim-lm32.h
diff -N include/gdb/sim-lm32.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ include/gdb/sim-lm32.h	15 Apr 2009 17:41:22 -0000
@@ -0,0 +1,76 @@
+/* This file defines the interface between the LM32 simulator and GDB.
+   Contributed by Jon Beniston <jon@beniston.com>
+
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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_LM32_H
+#define SIM_LM32_H
+
+#ifdef __cplusplus
+extern "C" { // }
+#endif
+
+enum sim_lm32_regs
+{
+  SIM_LM32_R0_REGNUM,
+  SIM_LM32_R1_REGNUM,     
+  SIM_LM32_R2_REGNUM,     
+  SIM_LM32_R3_REGNUM,     
+  SIM_LM32_R4_REGNUM,     
+  SIM_LM32_R5_REGNUM,     
+  SIM_LM32_R6_REGNUM,     
+  SIM_LM32_R7_REGNUM,     
+  SIM_LM32_R8_REGNUM,     
+  SIM_LM32_R9_REGNUM,     
+  SIM_LM32_R10_REGNUM,    
+  SIM_LM32_R11_REGNUM,    
+  SIM_LM32_R12_REGNUM,    
+  SIM_LM32_R13_REGNUM,    
+  SIM_LM32_R14_REGNUM,    
+  SIM_LM32_R15_REGNUM,    
+  SIM_LM32_R16_REGNUM,    
+  SIM_LM32_R17_REGNUM,    
+  SIM_LM32_R18_REGNUM,    
+  SIM_LM32_R19_REGNUM,    
+  SIM_LM32_R20_REGNUM,    
+  SIM_LM32_R21_REGNUM,    
+  SIM_LM32_R22_REGNUM,    
+  SIM_LM32_R23_REGNUM,    
+  SIM_LM32_R24_REGNUM,    
+  SIM_LM32_R25_REGNUM,    
+  SIM_LM32_GP_REGNUM,     
+  SIM_LM32_FP_REGNUM,     
+  SIM_LM32_SP_REGNUM,     
+  SIM_LM32_RA_REGNUM,     
+  SIM_LM32_BA_REGNUM,     
+  SIM_LM32_EA_REGNUM,     
+  SIM_LM32_PC_REGNUM,
+  SIM_LM32_EID_REGNUM,
+  SIM_LM32_EBA_REGNUM,  
+  SIM_LM32_DEBA_REGNUM, 
+  SIM_LM32_IE_REGNUM,  
+  SIM_LM32_IM_REGNUM,  
+  SIM_LM32_IP_REGNUM,  
+  SIM_LM32_NUM_REGS      
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: sim/MAINTAINERS
===================================================================
RCS file: /cvs/src/src/sim/MAINTAINERS,v
retrieving revision 1.22
diff -u -p -r1.22 MAINTAINERS
--- sim/MAINTAINERS	8 Apr 2008 07:15:39 -0000	1.22
+++ sim/MAINTAINERS	15 Apr 2009 17:41:22 -0000
@@ -14,6 +14,7 @@ cr16	        M R Swami Reddy <MR.Swami.R
 frv		Dave Brolley <brolley@redhat.com>
 igen		(igen simulators)
 ppc		Andrew Cagney <ac131313@redhat.com>
+lm32            Jon Beniston <jon@beniston.com>
 m68hc11		Stephane Carrez <stcarrez@nerim.fr>
 mips		Thiemo Seufer <ths@networkno.de>
 sh		(global maintainers)
Index: sim/configure
===================================================================
RCS file: /cvs/src/src/sim/configure,v
retrieving revision 1.26
diff -u -p -r1.26 configure
--- sim/configure	8 Apr 2008 09:15:56 -0000	1.26
+++ sim/configure	15 Apr 2009 17:41:24 -0000
@@ -279,6 +279,7 @@ ac_subdirs_all="$ac_subdirs_all d10v"
 ac_subdirs_all="$ac_subdirs_all frv"
 ac_subdirs_all="$ac_subdirs_all h8300"
 ac_subdirs_all="$ac_subdirs_all iq2000"
+ac_subdirs_all="$ac_subdirs_all lm32"
 ac_subdirs_all="$ac_subdirs_all m32c"
 ac_subdirs_all="$ac_subdirs_all m32r"
 ac_subdirs_all="$ac_subdirs_all m68hc11"
@@ -3465,6 +3466,13 @@ subdirs="$subdirs iq2000"
 
 	   testsuite=yes
 	   ;;
+       lm32-*-*)
+
+
+subdirs="$subdirs lm32"
+
+           testsuite=yes
+           ;;
        m32c-*-*)
 
 
Index: sim/configure.ac
===================================================================
RCS file: /cvs/src/src/sim/configure.ac,v
retrieving revision 1.14
diff -u -p -r1.14 configure.ac
--- sim/configure.ac	8 Apr 2008 09:15:56 -0000	1.14
+++ sim/configure.ac	15 Apr 2009 17:41:24 -0000
@@ -74,6 +74,10 @@ if test "${enable_sim}" != no; then
            AC_CONFIG_SUBDIRS(iq2000)
 	   testsuite=yes
 	   ;;
+       lm32-*-*)
+           AC_CONFIG_SUBDIRS(lm32)
+	   testsuite=yes
+           ;;
        m32c-*-*)
            AC_CONFIG_SUBDIRS(m32c)
            ;;
Index: sim/common/gennltvals.sh
===================================================================
RCS file: /cvs/src/src/sim/common/gennltvals.sh,v
retrieving revision 1.4
diff -u -p -r1.4 gennltvals.sh
--- sim/common/gennltvals.sh	8 Apr 2008 08:44:51 -0000	1.4
+++ sim/common/gennltvals.sh	15 Apr 2009 17:41:24 -0000
@@ -73,3 +73,6 @@ dir=libgloss/v850/sys target=v850
 $shell ${srccom}/gentvals.sh $target sys ${srcroot}/$dir \
 	"syscall.h" 'SYS_[_A-Za-z0-9]*' "${cpp}"
 
+dir=libgloss target=lm32
+$shell ${srccom}/gentvals.sh $target sys ${srcroot}/$dir \
+        "syscall.h" 'SYS_[_A-Za-z0-9]*' "${cpp}"
Index: sim/common/nltvals.def
===================================================================
RCS file: /cvs/src/src/sim/common/nltvals.def,v
retrieving revision 1.4
diff -u -p -r1.4 nltvals.def
--- sim/common/nltvals.def	8 Apr 2008 08:44:51 -0000	1.4
+++ sim/common/nltvals.def	15 Apr 2009 17:41:25 -0000
@@ -454,3 +454,30 @@
 /* end cr16 sys target macros */
 #endif
 #endif
+#ifdef NL_TARGET_lm32
+#ifdef sys_defs
+/* from syscall.h */
+/* begin lm32 sys target macros */
+ { "SYS_argv", 13 },
+ { "SYS_argvlen", 12 },
+ { "SYS_chdir", 14 },
+ { "SYS_chmod", 16 },
+ { "SYS_close", 3 },
+ { "SYS_exit", 1 },
+ { "SYS_fstat", 10 },
+ { "SYS_getpid", 8 },
+ { "SYS_gettimeofday", 19 },
+ { "SYS_kill", 9 },
+ { "SYS_link", 21 },
+ { "SYS_lseek", 6 },
+ { "SYS_open", 2 },
+ { "SYS_read", 4 },
+ { "SYS_stat", 15 },
+ { "SYS_time", 18 },
+ { "SYS_times", 20 },
+ { "SYS_unlink", 7 },
+ { "SYS_utime", 17 },
+ { "SYS_write", 5 },
+/* end lm32 sys target macros */
+#endif
+#endif
Index: sim/lm32/Makefile.in
===================================================================
RCS file: sim/lm32/Makefile.in
diff -N sim/lm32/Makefile.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/Makefile.in	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,90 @@
+# Makefile for Lattice Mico32 simulator.
+# Contributed by Jon Beniston <jon@beniston.com>
+
+## COMMON_PRE_CONFIG_FRAG
+
+# List of object files, less common parts.
+SIM_OBJS = \
+	$(SIM_NEW_COMMON_OBJS) \
+	sim-cpu.o \
+	sim-hload.o \
+	sim-hrw.o \
+	sim-model.o \
+	sim-reg.o \
+	sim-signal.o \
+        cgen-utils.o cgen-trace.o cgen-scache.o \
+        cgen-run.o sim-reason.o sim-engine.o sim-stop.o \
+        sim-if.o arch.o \
+        cpu.o decode.o sem.o model.o mloop.o \
+        lm32.o traps.o user.o 
+        
+# List of extra dependencies.
+# Generally this consists of simulator specific files included by sim-main.h.
+SIM_EXTRA_DEPS = $(CGEN_INCLUDE_DEPS) $(srcdir)/../../opcodes/lm32-desc.h
+
+# List of flags to always pass to $(CC).
+#SIM_EXTRA_CFLAGS =
+
+# List of main object files for `run'.
+SIM_RUN_OBJS = nrun.o
+
+SIM_EXTRA_CLEAN = lm32-clean
+
+# This selects the lm32 newlib/libgloss syscall definitions.
+NL_TARGET = -DNL_TARGET_lm32
+
+## COMMON_POST_CONFIG_FRAG
+
+arch = lm32 
+
+arch.o: arch.c $(SIM_MAIN_DEPS)
+
+sim-if.o: sim-if.c $(SIM_MAIN_DEPS) $(srcdir)/../common/sim-core.h
+
+LM32BF_INCLUDE_DEPS = \
+	$(CGEN_MAIN_CPU_DEPS) \
+	cpu.h decode.h eng.h
+
+lm32.o: lm32.c $(LM32BF_INCLUDE_DEPS)
+
+# FIXME: Use of `mono' is wip.
+mloop.c eng.h: stamp-mloop
+stamp-mloop: $(srcdir)/../common/genmloop.sh mloop.in Makefile
+	$(SHELL) $(srccom)/genmloop.sh \
+		-mono -fast -pbb -switch sem-switch.c \
+		-cpu lm32bf -infile $(srcdir)/mloop.in
+	$(SHELL) $(srcroot)/move-if-change eng.hin eng.h
+	$(SHELL) $(srcroot)/move-if-change mloop.cin mloop.c
+	touch stamp-mloop
+mloop.o: mloop.c sem-switch.c 
+
+cpu.o: cpu.c $(LM32BF_INCLUDE_DEPS)
+decode.o: decode.c $(LM32BF_INCLUDE_DEPS)
+sem.o: sem.c $(LM32BF_INCLUDE_DEPS)
+model.o: model.c $(LM32BF_INCLUDE_DEPS)
+
+lm32-clean:
+	rm -f mloop.c eng.h stamp-mloop
+	rm -f stamp-arch stamp-cpu 
+	rm -f tmp-*
+
+# cgen support, enable with --enable-cgen-maint
+CGEN_MAINT = ; @true
+# The following line is commented in or out depending upon --enable-cgen-maint.
+@CGEN_MAINT@CGEN_MAINT =
+
+stamp-arch: $(CGEN_READ_SCM) $(CGEN_ARCH_SCM) $(CGEN_CPU_DIR)/lm32.cpu
+	$(MAKE) cgen-arch $(CGEN_FLAGS_TO_PASS) mach=all \
+	  archfile=$(CGEN_CPU_DIR)/lm32.cpu \
+	  FLAGS="with-scache with-profile=fn"
+	touch stamp-arch
+arch.h arch.c cpuall.h: $(CGEN_MAINT) stamp-arch
+
+stamp-cpu: $(CGEN_READ_SCM) $(CGEN_CPU_SCM) $(CGEN_DECODE_SCM) $(CGEN_CPU_DIR)/lm32.cpu
+	$(MAKE) cgen-cpu-decode $(CGEN_FLAGS_TO_PASS) \
+	  cpu=lm32bf mach=lm32 SUFFIX= \
+	  archfile=$(CGEN_CPU_DIR)/lm32.cpu \
+	  FLAGS="with-scache with-profile=fn" \
+	  EXTRAFILES="$(CGEN_CPU_SEM) $(CGEN_CPU_SEMSW)"
+	touch stamp-cpu
+cpu.h sem.c sem-switch.c model.c decode.c decode.h: $(CGEN_MAINT) stamp-cpu
Index: sim/lm32/arch.c
===================================================================
RCS file: sim/lm32/arch.c
diff -N sim/lm32/arch.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/arch.c	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,35 @@
+/* Simulator support for lm32.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include "sim-main.h"
+#include "bfd.h"
+
+const MACH *sim_machs[] =
+{
+#ifdef HAVE_CPU_LM32BF
+  & lm32_mach,
+#endif
+  0
+};
+
Index: sim/lm32/arch.h
===================================================================
RCS file: sim/lm32/arch.h
diff -N sim/lm32/arch.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/arch.h	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,44 @@
+/* Simulator header for lm32.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef LM32_ARCH_H
+#define LM32_ARCH_H
+
+#define TARGET_BIG_ENDIAN 1
+
+/* Enum declaration for model types.  */
+typedef enum model_type {
+  MODEL_LM32, MODEL_MAX
+} MODEL_TYPE;
+
+#define MAX_MODELS ((int) MODEL_MAX)
+
+/* Enum declaration for unit types.  */
+typedef enum unit_type {
+  UNIT_NONE, UNIT_LM32_U_EXEC, UNIT_MAX
+} UNIT_TYPE;
+
+#define MAX_UNITS (1)
+
+#endif /* LM32_ARCH_H */
Index: sim/lm32/config.in
===================================================================
RCS file: sim/lm32/config.in
diff -N sim/lm32/config.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/config.in	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,116 @@
+/* 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
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the <fpu_control.h> header file. */
+#undef HAVE_FPU_CONTROL_H
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the `time' function. */
+#undef HAVE_TIME
+
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
+/* Define to 1 if you have the `__setfpucw' function. */
+#undef HAVE___SETFPUCW
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Additional package description */
+#undef PKGVERSION
+
+/* Bug reporting address */
+#undef REPORT_BUGS_TO
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* 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
Index: sim/lm32/configure.ac
===================================================================
RCS file: sim/lm32/configure.ac
diff -N sim/lm32/configure.ac
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/configure.ac	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,21 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.59)dnl
+AC_INIT(Makefile.in)
+AC_CONFIG_HEADER(config.h:config.in)
+
+sinclude(../common/aclocal.m4)
+
+# Bugs in autoconf 2.59 break the call to SIM_AC_COMMON, hack around
+# it by inlining the macro's contents.
+sinclude(../common/common.m4)
+
+SIM_AC_OPTION_ENDIAN(BIG_ENDIAN)
+SIM_AC_OPTION_ALIGNMENT(STRICT_ALIGNMENT,STRICT_ALIGNMENT)
+SIM_AC_OPTION_HOSTENDIAN
+SIM_AC_OPTION_SCACHE(16384)
+SIM_AC_OPTION_DEFAULT_MODEL(lm32)
+SIM_AC_OPTION_ENVIRONMENT
+SIM_AC_OPTION_CGEN_MAINT
+SIM_AC_OPTION_HARDWARE(yes,,lm32cpu lm32timer lm32uart)
+
+SIM_AC_OUTPUT
Index: sim/lm32/cpu.c
===================================================================
RCS file: sim/lm32/cpu.c
diff -N sim/lm32/cpu.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/cpu.c	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,85 @@
+/* Misc. support for CPU family lm32bf.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#define WANT_CPU lm32bf
+#define WANT_CPU_LM32BF
+
+#include "sim-main.h"
+#include "cgen-ops.h"
+
+/* Get the value of h-pc.  */
+
+USI
+lm32bf_h_pc_get (SIM_CPU *current_cpu)
+{
+  return CPU (h_pc);
+}
+
+/* Set a value for h-pc.  */
+
+void
+lm32bf_h_pc_set (SIM_CPU *current_cpu, USI newval)
+{
+  CPU (h_pc) = newval;
+}
+
+/* Get the value of h-gr.  */
+
+SI
+lm32bf_h_gr_get (SIM_CPU *current_cpu, UINT regno)
+{
+  return CPU (h_gr[regno]);
+}
+
+/* Set a value for h-gr.  */
+
+void
+lm32bf_h_gr_set (SIM_CPU *current_cpu, UINT regno, SI newval)
+{
+  CPU (h_gr[regno]) = newval;
+}
+
+/* Get the value of h-csr.  */
+
+SI
+lm32bf_h_csr_get (SIM_CPU *current_cpu, UINT regno)
+{
+  return CPU (h_csr[regno]);
+}
+
+/* Set a value for h-csr.  */
+
+void
+lm32bf_h_csr_set (SIM_CPU *current_cpu, UINT regno, SI newval)
+{
+  CPU (h_csr[regno]) = newval;
+}
+
+/* Record trace results for INSN.  */
+
+void
+lm32bf_record_trace_results (SIM_CPU *current_cpu, CGEN_INSN *insn,
+			    int *indices, TRACE_RECORD *tr)
+{
+}
Index: sim/lm32/cpu.h
===================================================================
RCS file: sim/lm32/cpu.h
diff -N sim/lm32/cpu.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/cpu.h	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,349 @@
+/* CPU family header for lm32bf.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef CPU_LM32BF_H
+#define CPU_LM32BF_H
+
+/* Maximum number of instructions that are fetched at a time.
+   This is for LIW type instructions sets (e.g. m32r).  */
+#define MAX_LIW_INSNS 1
+
+/* Maximum number of instructions that can be executed in parallel.  */
+#define MAX_PARALLEL_INSNS 1
+
+/* CPU state information.  */
+typedef struct {
+  /* Hardware elements.  */
+  struct {
+  /* Program counter */
+  USI h_pc;
+#define GET_H_PC() CPU (h_pc)
+#define SET_H_PC(x) (CPU (h_pc) = (x))
+  /* General purpose registers */
+  SI h_gr[32];
+#define GET_H_GR(a1) CPU (h_gr)[a1]
+#define SET_H_GR(a1, x) (CPU (h_gr)[a1] = (x))
+  /* Control and status registers */
+  SI h_csr[32];
+#define GET_H_CSR(a1) CPU (h_csr)[a1]
+#define SET_H_CSR(a1, x) (CPU (h_csr)[a1] = (x))
+  } hardware;
+#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
+} LM32BF_CPU_DATA;
+
+/* Cover fns for register access.  */
+USI lm32bf_h_pc_get (SIM_CPU *);
+void lm32bf_h_pc_set (SIM_CPU *, USI);
+SI lm32bf_h_gr_get (SIM_CPU *, UINT);
+void lm32bf_h_gr_set (SIM_CPU *, UINT, SI);
+SI lm32bf_h_csr_get (SIM_CPU *, UINT);
+void lm32bf_h_csr_set (SIM_CPU *, UINT, SI);
+
+/* These must be hand-written.  */
+extern CPUREG_FETCH_FN lm32bf_fetch_register;
+extern CPUREG_STORE_FN lm32bf_store_register;
+
+typedef struct {
+  int empty;
+} MODEL_LM32_DATA;
+
+/* Instruction argument buffer.  */
+
+union sem_fields {
+  struct { /* no operands */
+    int empty;
+  } fmt_empty;
+  struct { /*  */
+    IADDR i_call;
+  } sfmt_bi;
+  struct { /*  */
+    UINT f_csr;
+    UINT f_r1;
+  } sfmt_wcsr;
+  struct { /*  */
+    UINT f_csr;
+    UINT f_r2;
+  } sfmt_rcsr;
+  struct { /*  */
+    IADDR i_branch;
+    UINT f_r0;
+    UINT f_r1;
+  } sfmt_be;
+  struct { /*  */
+    UINT f_r0;
+    UINT f_r1;
+    UINT f_uimm;
+  } sfmt_andi;
+  struct { /*  */
+    INT f_imm;
+    UINT f_r0;
+    UINT f_r1;
+  } sfmt_addi;
+  struct { /*  */
+    UINT f_r0;
+    UINT f_r1;
+    UINT f_r2;
+    UINT f_user;
+  } sfmt_user;
+#if WITH_SCACHE_PBB
+  /* Writeback handler.  */
+  struct {
+    /* Pointer to argbuf entry for insn whose results need writing back.  */
+    const struct argbuf *abuf;
+  } write;
+  /* x-before handler */
+  struct {
+    /*const SCACHE *insns[MAX_PARALLEL_INSNS];*/
+    int first_p;
+  } before;
+  /* x-after handler */
+  struct {
+    int empty;
+  } after;
+  /* This entry is used to terminate each pbb.  */
+  struct {
+    /* Number of insns in pbb.  */
+    int insn_count;
+    /* Next pbb to execute.  */
+    SCACHE *next;
+    SCACHE *branch_target;
+  } chain;
+#endif
+};
+
+/* The ARGBUF struct.  */
+struct argbuf {
+  /* These are the baseclass definitions.  */
+  IADDR addr;
+  const IDESC *idesc;
+  char trace_p;
+  char profile_p;
+  /* ??? Temporary hack for skip insns.  */
+  char skip_count;
+  char unused;
+  /* cpu specific data follows */
+  union sem semantic;
+  int written;
+  union sem_fields fields;
+};
+
+/* A cached insn.
+
+   ??? SCACHE used to contain more than just argbuf.  We could delete the
+   type entirely and always just use ARGBUF, but for future concerns and as
+   a level of abstraction it is left in.  */
+
+struct scache {
+  struct argbuf argbuf;
+};
+
+/* Macros to simplify extraction, reading and semantic code.
+   These define and assign the local vars that contain the insn's fields.  */
+
+#define EXTRACT_IFMT_EMPTY_VARS \
+  unsigned int length;
+#define EXTRACT_IFMT_EMPTY_CODE \
+  length = 0; \
+
+#define EXTRACT_IFMT_ADD_VARS \
+  UINT f_opcode; \
+  UINT f_r0; \
+  UINT f_r1; \
+  UINT f_r2; \
+  UINT f_resv0; \
+  unsigned int length;
+#define EXTRACT_IFMT_ADD_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
+  f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
+
+#define EXTRACT_IFMT_ADDI_VARS \
+  UINT f_opcode; \
+  UINT f_r0; \
+  UINT f_r1; \
+  INT f_imm; \
+  unsigned int length;
+#define EXTRACT_IFMT_ADDI_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_imm = EXTRACT_LSB0_INT (insn, 32, 15, 16); \
+
+#define EXTRACT_IFMT_ANDI_VARS \
+  UINT f_opcode; \
+  UINT f_r0; \
+  UINT f_r1; \
+  UINT f_uimm; \
+  unsigned int length;
+#define EXTRACT_IFMT_ANDI_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16); \
+
+#define EXTRACT_IFMT_ANDHII_VARS \
+  UINT f_opcode; \
+  UINT f_r0; \
+  UINT f_r1; \
+  UINT f_uimm; \
+  unsigned int length;
+#define EXTRACT_IFMT_ANDHII_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16); \
+
+#define EXTRACT_IFMT_B_VARS \
+  UINT f_opcode; \
+  UINT f_r0; \
+  UINT f_r1; \
+  UINT f_r2; \
+  UINT f_resv0; \
+  unsigned int length;
+#define EXTRACT_IFMT_B_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
+  f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
+
+#define EXTRACT_IFMT_BI_VARS \
+  UINT f_opcode; \
+  SI f_call; \
+  unsigned int length;
+#define EXTRACT_IFMT_BI_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_call = ((pc) + (((int) (((EXTRACT_LSB0_INT (insn, 32, 25, 26)) << (6))) >> (4)))); \
+
+#define EXTRACT_IFMT_BE_VARS \
+  UINT f_opcode; \
+  UINT f_r0; \
+  UINT f_r1; \
+  SI f_branch; \
+  unsigned int length;
+#define EXTRACT_IFMT_BE_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_branch = ((pc) + (((int) (((EXTRACT_LSB0_INT (insn, 32, 15, 16)) << (16))) >> (14)))); \
+
+#define EXTRACT_IFMT_ORI_VARS \
+  UINT f_opcode; \
+  UINT f_r0; \
+  UINT f_r1; \
+  UINT f_uimm; \
+  unsigned int length;
+#define EXTRACT_IFMT_ORI_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16); \
+
+#define EXTRACT_IFMT_RCSR_VARS \
+  UINT f_opcode; \
+  UINT f_csr; \
+  UINT f_r1; \
+  UINT f_r2; \
+  UINT f_resv0; \
+  unsigned int length;
+#define EXTRACT_IFMT_RCSR_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_csr = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
+  f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
+
+#define EXTRACT_IFMT_SEXTB_VARS \
+  UINT f_opcode; \
+  UINT f_r0; \
+  UINT f_r1; \
+  UINT f_r2; \
+  UINT f_resv0; \
+  unsigned int length;
+#define EXTRACT_IFMT_SEXTB_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
+  f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
+
+#define EXTRACT_IFMT_USER_VARS \
+  UINT f_opcode; \
+  UINT f_r0; \
+  UINT f_r1; \
+  UINT f_r2; \
+  UINT f_user; \
+  unsigned int length;
+#define EXTRACT_IFMT_USER_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
+  f_user = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
+
+#define EXTRACT_IFMT_WCSR_VARS \
+  UINT f_opcode; \
+  UINT f_csr; \
+  UINT f_r1; \
+  UINT f_r2; \
+  UINT f_resv0; \
+  unsigned int length;
+#define EXTRACT_IFMT_WCSR_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_csr = EXTRACT_LSB0_UINT (insn, 32, 25, 5); \
+  f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5); \
+  f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5); \
+  f_resv0 = EXTRACT_LSB0_UINT (insn, 32, 10, 11); \
+
+#define EXTRACT_IFMT_BREAK_VARS \
+  UINT f_opcode; \
+  UINT f_exception; \
+  unsigned int length;
+#define EXTRACT_IFMT_BREAK_CODE \
+  length = 4; \
+  f_opcode = EXTRACT_LSB0_UINT (insn, 32, 31, 6); \
+  f_exception = EXTRACT_LSB0_UINT (insn, 32, 25, 26); \
+
+/* Collection of various things for the trace handler to use.  */
+
+typedef struct trace_record {
+  IADDR pc;
+  /* FIXME:wip */
+} TRACE_RECORD;
+
+#endif /* CPU_LM32BF_H */
Index: sim/lm32/cpuall.h
===================================================================
RCS file: sim/lm32/cpuall.h
diff -N sim/lm32/cpuall.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/cpuall.h	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,66 @@
+/* Simulator CPU header for lm32.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef LM32_CPUALL_H
+#define LM32_CPUALL_H
+
+/* Include files for each cpu family.  */
+
+#ifdef WANT_CPU_LM32BF
+#include "eng.h"
+#include "cgen-engine.h"
+#include "cpu.h"
+#include "decode.h"
+#endif
+
+extern const MACH lm32_mach;
+
+#ifndef WANT_CPU
+/* The ARGBUF struct.  */
+struct argbuf {
+  /* These are the baseclass definitions.  */
+  IADDR addr;
+  const IDESC *idesc;
+  char trace_p;
+  char profile_p;
+  /* ??? Temporary hack for skip insns.  */
+  char skip_count;
+  char unused;
+  /* cpu specific data follows */
+};
+#endif
+
+#ifndef WANT_CPU
+/* A cached insn.
+
+   ??? SCACHE used to contain more than just argbuf.  We could delete the
+   type entirely and always just use ARGBUF, but for future concerns and as
+   a level of abstraction it is left in.  */
+
+struct scache {
+  struct argbuf argbuf;
+};
+#endif
+
+#endif /* LM32_CPUALL_H */
Index: sim/lm32/decode.c
===================================================================
RCS file: sim/lm32/decode.c
diff -N sim/lm32/decode.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/decode.c	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,955 @@
+/* Simulator instruction decoder for lm32bf.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#define WANT_CPU lm32bf
+#define WANT_CPU_LM32BF
+
+#include "sim-main.h"
+#include "sim-assert.h"
+
+/* The instruction descriptor array.
+   This is computed at runtime.  Space for it is not malloc'd to save a
+   teensy bit of cpu in the decoder.  Moving it to malloc space is trivial
+   but won't be done until necessary (we don't currently support the runtime
+   addition of instructions nor an SMP machine with different cpus).  */
+static IDESC lm32bf_insn_data[LM32BF_INSN__MAX];
+
+/* Commas between elements are contained in the macros.
+   Some of these are conditionally compiled out.  */
+
+static const struct insn_sem lm32bf_insn_sem[] =
+{
+  { VIRTUAL_INSN_X_INVALID, LM32BF_INSN_X_INVALID, LM32BF_SFMT_EMPTY },
+  { VIRTUAL_INSN_X_AFTER, LM32BF_INSN_X_AFTER, LM32BF_SFMT_EMPTY },
+  { VIRTUAL_INSN_X_BEFORE, LM32BF_INSN_X_BEFORE, LM32BF_SFMT_EMPTY },
+  { VIRTUAL_INSN_X_CTI_CHAIN, LM32BF_INSN_X_CTI_CHAIN, LM32BF_SFMT_EMPTY },
+  { VIRTUAL_INSN_X_CHAIN, LM32BF_INSN_X_CHAIN, LM32BF_SFMT_EMPTY },
+  { VIRTUAL_INSN_X_BEGIN, LM32BF_INSN_X_BEGIN, LM32BF_SFMT_EMPTY },
+  { LM32_INSN_ADD, LM32BF_INSN_ADD, LM32BF_SFMT_ADD },
+  { LM32_INSN_ADDI, LM32BF_INSN_ADDI, LM32BF_SFMT_ADDI },
+  { LM32_INSN_AND, LM32BF_INSN_AND, LM32BF_SFMT_ADD },
+  { LM32_INSN_ANDI, LM32BF_INSN_ANDI, LM32BF_SFMT_ANDI },
+  { LM32_INSN_ANDHII, LM32BF_INSN_ANDHII, LM32BF_SFMT_ANDHII },
+  { LM32_INSN_B, LM32BF_INSN_B, LM32BF_SFMT_B },
+  { LM32_INSN_BI, LM32BF_INSN_BI, LM32BF_SFMT_BI },
+  { LM32_INSN_BE, LM32BF_INSN_BE, LM32BF_SFMT_BE },
+  { LM32_INSN_BG, LM32BF_INSN_BG, LM32BF_SFMT_BE },
+  { LM32_INSN_BGE, LM32BF_INSN_BGE, LM32BF_SFMT_BE },
+  { LM32_INSN_BGEU, LM32BF_INSN_BGEU, LM32BF_SFMT_BE },
+  { LM32_INSN_BGU, LM32BF_INSN_BGU, LM32BF_SFMT_BE },
+  { LM32_INSN_BNE, LM32BF_INSN_BNE, LM32BF_SFMT_BE },
+  { LM32_INSN_CALL, LM32BF_INSN_CALL, LM32BF_SFMT_CALL },
+  { LM32_INSN_CALLI, LM32BF_INSN_CALLI, LM32BF_SFMT_CALLI },
+  { LM32_INSN_CMPE, LM32BF_INSN_CMPE, LM32BF_SFMT_ADD },
+  { LM32_INSN_CMPEI, LM32BF_INSN_CMPEI, LM32BF_SFMT_ADDI },
+  { LM32_INSN_CMPG, LM32BF_INSN_CMPG, LM32BF_SFMT_ADD },
+  { LM32_INSN_CMPGI, LM32BF_INSN_CMPGI, LM32BF_SFMT_ADDI },
+  { LM32_INSN_CMPGE, LM32BF_INSN_CMPGE, LM32BF_SFMT_ADD },
+  { LM32_INSN_CMPGEI, LM32BF_INSN_CMPGEI, LM32BF_SFMT_ADDI },
+  { LM32_INSN_CMPGEU, LM32BF_INSN_CMPGEU, LM32BF_SFMT_ADD },
+  { LM32_INSN_CMPGEUI, LM32BF_INSN_CMPGEUI, LM32BF_SFMT_ANDI },
+  { LM32_INSN_CMPGU, LM32BF_INSN_CMPGU, LM32BF_SFMT_ADD },
+  { LM32_INSN_CMPGUI, LM32BF_INSN_CMPGUI, LM32BF_SFMT_ANDI },
+  { LM32_INSN_CMPNE, LM32BF_INSN_CMPNE, LM32BF_SFMT_ADD },
+  { LM32_INSN_CMPNEI, LM32BF_INSN_CMPNEI, LM32BF_SFMT_ADDI },
+  { LM32_INSN_DIVU, LM32BF_INSN_DIVU, LM32BF_SFMT_DIVU },
+  { LM32_INSN_LB, LM32BF_INSN_LB, LM32BF_SFMT_LB },
+  { LM32_INSN_LBU, LM32BF_INSN_LBU, LM32BF_SFMT_LB },
+  { LM32_INSN_LH, LM32BF_INSN_LH, LM32BF_SFMT_LH },
+  { LM32_INSN_LHU, LM32BF_INSN_LHU, LM32BF_SFMT_LH },
+  { LM32_INSN_LW, LM32BF_INSN_LW, LM32BF_SFMT_LW },
+  { LM32_INSN_MODU, LM32BF_INSN_MODU, LM32BF_SFMT_DIVU },
+  { LM32_INSN_MUL, LM32BF_INSN_MUL, LM32BF_SFMT_ADD },
+  { LM32_INSN_MULI, LM32BF_INSN_MULI, LM32BF_SFMT_ADDI },
+  { LM32_INSN_NOR, LM32BF_INSN_NOR, LM32BF_SFMT_ADD },
+  { LM32_INSN_NORI, LM32BF_INSN_NORI, LM32BF_SFMT_ANDI },
+  { LM32_INSN_OR, LM32BF_INSN_OR, LM32BF_SFMT_ADD },
+  { LM32_INSN_ORI, LM32BF_INSN_ORI, LM32BF_SFMT_ORI },
+  { LM32_INSN_ORHII, LM32BF_INSN_ORHII, LM32BF_SFMT_ANDHII },
+  { LM32_INSN_RCSR, LM32BF_INSN_RCSR, LM32BF_SFMT_RCSR },
+  { LM32_INSN_SB, LM32BF_INSN_SB, LM32BF_SFMT_SB },
+  { LM32_INSN_SEXTB, LM32BF_INSN_SEXTB, LM32BF_SFMT_SEXTB },
+  { LM32_INSN_SEXTH, LM32BF_INSN_SEXTH, LM32BF_SFMT_SEXTB },
+  { LM32_INSN_SH, LM32BF_INSN_SH, LM32BF_SFMT_SH },
+  { LM32_INSN_SL, LM32BF_INSN_SL, LM32BF_SFMT_SL },
+  { LM32_INSN_SLI, LM32BF_INSN_SLI, LM32BF_SFMT_ADDI },
+  { LM32_INSN_SR, LM32BF_INSN_SR, LM32BF_SFMT_SL },
+  { LM32_INSN_SRI, LM32BF_INSN_SRI, LM32BF_SFMT_ADDI },
+  { LM32_INSN_SRU, LM32BF_INSN_SRU, LM32BF_SFMT_SL },
+  { LM32_INSN_SRUI, LM32BF_INSN_SRUI, LM32BF_SFMT_ADDI },
+  { LM32_INSN_SUB, LM32BF_INSN_SUB, LM32BF_SFMT_ADD },
+  { LM32_INSN_SW, LM32BF_INSN_SW, LM32BF_SFMT_SW },
+  { LM32_INSN_USER, LM32BF_INSN_USER, LM32BF_SFMT_USER },
+  { LM32_INSN_WCSR, LM32BF_INSN_WCSR, LM32BF_SFMT_WCSR },
+  { LM32_INSN_XOR, LM32BF_INSN_XOR, LM32BF_SFMT_ADD },
+  { LM32_INSN_XORI, LM32BF_INSN_XORI, LM32BF_SFMT_ANDI },
+  { LM32_INSN_XNOR, LM32BF_INSN_XNOR, LM32BF_SFMT_ADD },
+  { LM32_INSN_XNORI, LM32BF_INSN_XNORI, LM32BF_SFMT_ANDI },
+  { LM32_INSN_BREAK, LM32BF_INSN_BREAK, LM32BF_SFMT_BREAK },
+  { LM32_INSN_SCALL, LM32BF_INSN_SCALL, LM32BF_SFMT_BREAK },
+};
+
+static const struct insn_sem lm32bf_insn_sem_invalid = {
+  VIRTUAL_INSN_X_INVALID, LM32BF_INSN_X_INVALID, LM32BF_SFMT_EMPTY
+};
+
+/* Initialize an IDESC from the compile-time computable parts.  */
+
+static INLINE void
+init_idesc (SIM_CPU *cpu, IDESC *id, const struct insn_sem *t)
+{
+  const CGEN_INSN *insn_table = CGEN_CPU_INSN_TABLE (CPU_CPU_DESC (cpu))->init_entries;
+
+  id->num = t->index;
+  id->sfmt = t->sfmt;
+  if ((int) t->type <= 0)
+    id->idata = & cgen_virtual_insn_table[- (int) t->type];
+  else
+    id->idata = & insn_table[t->type];
+  id->attrs = CGEN_INSN_ATTRS (id->idata);
+  /* Oh my god, a magic number.  */
+  id->length = CGEN_INSN_BITSIZE (id->idata) / 8;
+
+#if WITH_PROFILE_MODEL_P
+  id->timing = & MODEL_TIMING (CPU_MODEL (cpu)) [t->index];
+  {
+    SIM_DESC sd = CPU_STATE (cpu);
+    SIM_ASSERT (t->index == id->timing->num);
+  }
+#endif
+
+  /* Semantic pointers are initialized elsewhere.  */
+}
+
+/* Initialize the instruction descriptor table.  */
+
+void
+lm32bf_init_idesc_table (SIM_CPU *cpu)
+{
+  IDESC *id,*tabend;
+  const struct insn_sem *t,*tend;
+  int tabsize = LM32BF_INSN__MAX;
+  IDESC *table = lm32bf_insn_data;
+
+  memset (table, 0, tabsize * sizeof (IDESC));
+
+  /* First set all entries to the `invalid insn'.  */
+  t = & lm32bf_insn_sem_invalid;
+  for (id = table, tabend = table + tabsize; id < tabend; ++id)
+    init_idesc (cpu, id, t);
+
+  /* Now fill in the values for the chosen cpu.  */
+  for (t = lm32bf_insn_sem, tend = t + sizeof (lm32bf_insn_sem) / sizeof (*t);
+       t != tend; ++t)
+    {
+      init_idesc (cpu, & table[t->index], t);
+    }
+
+  /* Link the IDESC table into the cpu.  */
+  CPU_IDESC (cpu) = table;
+}
+
+/* Given an instruction, return a pointer to its IDESC entry.  */
+
+const IDESC *
+lm32bf_decode (SIM_CPU *current_cpu, IADDR pc,
+              CGEN_INSN_INT base_insn, CGEN_INSN_INT entire_insn,
+              ARGBUF *abuf)
+{
+  /* Result of decoder.  */
+  LM32BF_INSN_TYPE itype;
+
+  {
+    CGEN_INSN_INT insn = base_insn;
+
+    {
+      unsigned int val = (((insn >> 26) & (63 << 0)));
+      switch (val)
+      {
+      case 0 :
+        if ((entire_insn & 0xfc000000) == 0x0)
+          { itype = LM32BF_INSN_SRUI; goto extract_sfmt_addi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 1 :
+        if ((entire_insn & 0xfc000000) == 0x4000000)
+          { itype = LM32BF_INSN_NORI; goto extract_sfmt_andi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 2 :
+        if ((entire_insn & 0xfc000000) == 0x8000000)
+          { itype = LM32BF_INSN_MULI; goto extract_sfmt_addi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 3 :
+        if ((entire_insn & 0xfc000000) == 0xc000000)
+          { itype = LM32BF_INSN_SH; goto extract_sfmt_sh; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 4 :
+        if ((entire_insn & 0xfc000000) == 0x10000000)
+          { itype = LM32BF_INSN_LB; goto extract_sfmt_lb; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 5 :
+        if ((entire_insn & 0xfc000000) == 0x14000000)
+          { itype = LM32BF_INSN_SRI; goto extract_sfmt_addi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 6 :
+        if ((entire_insn & 0xfc000000) == 0x18000000)
+          { itype = LM32BF_INSN_XORI; goto extract_sfmt_andi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 7 :
+        if ((entire_insn & 0xfc000000) == 0x1c000000)
+          { itype = LM32BF_INSN_LH; goto extract_sfmt_lh; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 8 :
+        if ((entire_insn & 0xfc000000) == 0x20000000)
+          { itype = LM32BF_INSN_ANDI; goto extract_sfmt_andi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 9 :
+        if ((entire_insn & 0xfc000000) == 0x24000000)
+          { itype = LM32BF_INSN_XNORI; goto extract_sfmt_andi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 10 :
+        if ((entire_insn & 0xfc000000) == 0x28000000)
+          { itype = LM32BF_INSN_LW; goto extract_sfmt_lw; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 11 :
+        if ((entire_insn & 0xfc000000) == 0x2c000000)
+          { itype = LM32BF_INSN_LHU; goto extract_sfmt_lh; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 12 :
+        if ((entire_insn & 0xfc000000) == 0x30000000)
+          { itype = LM32BF_INSN_SB; goto extract_sfmt_sb; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 13 :
+        if ((entire_insn & 0xfc000000) == 0x34000000)
+          { itype = LM32BF_INSN_ADDI; goto extract_sfmt_addi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 14 :
+        if ((entire_insn & 0xfc000000) == 0x38000000)
+          { itype = LM32BF_INSN_ORI; goto extract_sfmt_ori; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 15 :
+        if ((entire_insn & 0xfc000000) == 0x3c000000)
+          { itype = LM32BF_INSN_SLI; goto extract_sfmt_addi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 16 :
+        if ((entire_insn & 0xfc000000) == 0x40000000)
+          { itype = LM32BF_INSN_LBU; goto extract_sfmt_lb; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 17 :
+        if ((entire_insn & 0xfc000000) == 0x44000000)
+          { itype = LM32BF_INSN_BE; goto extract_sfmt_be; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 18 :
+        if ((entire_insn & 0xfc000000) == 0x48000000)
+          { itype = LM32BF_INSN_BG; goto extract_sfmt_be; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 19 :
+        if ((entire_insn & 0xfc000000) == 0x4c000000)
+          { itype = LM32BF_INSN_BGE; goto extract_sfmt_be; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 20 :
+        if ((entire_insn & 0xfc000000) == 0x50000000)
+          { itype = LM32BF_INSN_BGEU; goto extract_sfmt_be; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 21 :
+        if ((entire_insn & 0xfc000000) == 0x54000000)
+          { itype = LM32BF_INSN_BGU; goto extract_sfmt_be; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 22 :
+        if ((entire_insn & 0xfc000000) == 0x58000000)
+          { itype = LM32BF_INSN_SW; goto extract_sfmt_sw; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 23 :
+        if ((entire_insn & 0xfc000000) == 0x5c000000)
+          { itype = LM32BF_INSN_BNE; goto extract_sfmt_be; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 24 :
+        if ((entire_insn & 0xfc000000) == 0x60000000)
+          { itype = LM32BF_INSN_ANDHII; goto extract_sfmt_andhii; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 25 :
+        if ((entire_insn & 0xfc000000) == 0x64000000)
+          { itype = LM32BF_INSN_CMPEI; goto extract_sfmt_addi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 26 :
+        if ((entire_insn & 0xfc000000) == 0x68000000)
+          { itype = LM32BF_INSN_CMPGI; goto extract_sfmt_addi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 27 :
+        if ((entire_insn & 0xfc000000) == 0x6c000000)
+          { itype = LM32BF_INSN_CMPGEI; goto extract_sfmt_addi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 28 :
+        if ((entire_insn & 0xfc000000) == 0x70000000)
+          { itype = LM32BF_INSN_CMPGEUI; goto extract_sfmt_andi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 29 :
+        if ((entire_insn & 0xfc000000) == 0x74000000)
+          { itype = LM32BF_INSN_CMPGUI; goto extract_sfmt_andi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 30 :
+        if ((entire_insn & 0xfc000000) == 0x78000000)
+          { itype = LM32BF_INSN_ORHII; goto extract_sfmt_andhii; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 31 :
+        if ((entire_insn & 0xfc000000) == 0x7c000000)
+          { itype = LM32BF_INSN_CMPNEI; goto extract_sfmt_addi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 32 :
+        if ((entire_insn & 0xfc0007ff) == 0x80000000)
+          { itype = LM32BF_INSN_SRU; goto extract_sfmt_sl; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 33 :
+        if ((entire_insn & 0xfc0007ff) == 0x84000000)
+          { itype = LM32BF_INSN_NOR; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 34 :
+        if ((entire_insn & 0xfc0007ff) == 0x88000000)
+          { itype = LM32BF_INSN_MUL; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 35 :
+        if ((entire_insn & 0xfc0007ff) == 0x8c000000)
+          { itype = LM32BF_INSN_DIVU; goto extract_sfmt_divu; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 36 :
+        if ((entire_insn & 0xfc1f07ff) == 0x90000000)
+          { itype = LM32BF_INSN_RCSR; goto extract_sfmt_rcsr; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 37 :
+        if ((entire_insn & 0xfc0007ff) == 0x94000000)
+          { itype = LM32BF_INSN_SR; goto extract_sfmt_sl; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 38 :
+        if ((entire_insn & 0xfc0007ff) == 0x98000000)
+          { itype = LM32BF_INSN_XOR; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 40 :
+        if ((entire_insn & 0xfc0007ff) == 0xa0000000)
+          { itype = LM32BF_INSN_AND; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 41 :
+        if ((entire_insn & 0xfc0007ff) == 0xa4000000)
+          { itype = LM32BF_INSN_XNOR; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 43 :
+        {
+          unsigned int val = (((insn >> 1) & (1 << 1)) | ((insn >> 0) & (1 << 0)));
+          switch (val)
+          {
+          case 0 :
+            if ((entire_insn & 0xffffffff) == 0xac000002)
+              { itype = LM32BF_INSN_BREAK; goto extract_sfmt_break; }
+            itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+          case 3 :
+            if ((entire_insn & 0xffffffff) == 0xac000007)
+              { itype = LM32BF_INSN_SCALL; goto extract_sfmt_break; }
+            itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+          default : itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+          }
+        }
+      case 44 :
+        if ((entire_insn & 0xfc1f07ff) == 0xb0000000)
+          { itype = LM32BF_INSN_SEXTB; goto extract_sfmt_sextb; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 45 :
+        if ((entire_insn & 0xfc0007ff) == 0xb4000000)
+          { itype = LM32BF_INSN_ADD; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 46 :
+        if ((entire_insn & 0xfc0007ff) == 0xb8000000)
+          { itype = LM32BF_INSN_OR; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 47 :
+        if ((entire_insn & 0xfc0007ff) == 0xbc000000)
+          { itype = LM32BF_INSN_SL; goto extract_sfmt_sl; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 48 :
+        if ((entire_insn & 0xfc1fffff) == 0xc0000000)
+          { itype = LM32BF_INSN_B; goto extract_sfmt_b; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 49 :
+        if ((entire_insn & 0xfc0007ff) == 0xc4000000)
+          { itype = LM32BF_INSN_MODU; goto extract_sfmt_divu; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 50 :
+        if ((entire_insn & 0xfc0007ff) == 0xc8000000)
+          { itype = LM32BF_INSN_SUB; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 51 :
+        if ((entire_insn & 0xfc000000) == 0xcc000000)
+          { itype = LM32BF_INSN_USER; goto extract_sfmt_user; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 52 :
+        if ((entire_insn & 0xfc00ffff) == 0xd0000000)
+          { itype = LM32BF_INSN_WCSR; goto extract_sfmt_wcsr; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 54 :
+        if ((entire_insn & 0xfc1fffff) == 0xd8000000)
+          { itype = LM32BF_INSN_CALL; goto extract_sfmt_call; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 55 :
+        if ((entire_insn & 0xfc1f07ff) == 0xdc000000)
+          { itype = LM32BF_INSN_SEXTH; goto extract_sfmt_sextb; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 56 :
+        if ((entire_insn & 0xfc000000) == 0xe0000000)
+          { itype = LM32BF_INSN_BI; goto extract_sfmt_bi; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 57 :
+        if ((entire_insn & 0xfc0007ff) == 0xe4000000)
+          { itype = LM32BF_INSN_CMPE; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 58 :
+        if ((entire_insn & 0xfc0007ff) == 0xe8000000)
+          { itype = LM32BF_INSN_CMPG; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 59 :
+        if ((entire_insn & 0xfc0007ff) == 0xec000000)
+          { itype = LM32BF_INSN_CMPGE; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 60 :
+        if ((entire_insn & 0xfc0007ff) == 0xf0000000)
+          { itype = LM32BF_INSN_CMPGEU; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 61 :
+        if ((entire_insn & 0xfc0007ff) == 0xf4000000)
+          { itype = LM32BF_INSN_CMPGU; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 62 :
+        if ((entire_insn & 0xfc000000) == 0xf8000000)
+          { itype = LM32BF_INSN_CALLI; goto extract_sfmt_calli; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      case 63 :
+        if ((entire_insn & 0xfc0007ff) == 0xfc000000)
+          { itype = LM32BF_INSN_CMPNE; goto extract_sfmt_add; }
+        itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      default : itype = LM32BF_INSN_X_INVALID; goto extract_sfmt_empty;
+      }
+    }
+  }
+
+  /* The instruction has been decoded, now extract the fields.  */
+
+ extract_sfmt_empty:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+#define FLD(f) abuf->fields.fmt_empty.f
+
+
+  /* Record the fields for the semantic handler.  */
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_empty", (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_add:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_user.f
+    UINT f_r0;
+    UINT f_r1;
+    UINT f_r2;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  FLD (f_r2) = f_r2;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_add", "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, "f_r2 0x%x", 'x', f_r2, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_addi:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_addi.f
+    UINT f_r0;
+    UINT f_r1;
+    INT f_imm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_imm = EXTRACT_LSB0_INT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_imm) = f_imm;
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_addi", "f_imm 0x%x", 'x', f_imm, "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_andi:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_andi.f
+    UINT f_r0;
+    UINT f_r1;
+    UINT f_uimm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_r0) = f_r0;
+  FLD (f_uimm) = f_uimm;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_andi", "f_r0 0x%x", 'x', f_r0, "f_uimm 0x%x", 'x', f_uimm, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_andhii:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_andi.f
+    UINT f_r0;
+    UINT f_r1;
+    UINT f_uimm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_uimm) = f_uimm;
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_andhii", "f_uimm 0x%x", 'x', f_uimm, "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_b:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_be.f
+    UINT f_r0;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_r0) = f_r0;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_b", "f_r0 0x%x", 'x', f_r0, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_bi:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_bi.f
+    SI f_call;
+
+    f_call = ((pc) + (((int) (((EXTRACT_LSB0_INT (insn, 32, 25, 26)) << (6))) >> (4))));
+
+  /* Record the fields for the semantic handler.  */
+  FLD (i_call) = f_call;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_bi", "call 0x%x", 'x', f_call, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_be:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_be.f
+    UINT f_r0;
+    UINT f_r1;
+    SI f_branch;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_branch = ((pc) + (((int) (((EXTRACT_LSB0_INT (insn, 32, 15, 16)) << (16))) >> (14))));
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  FLD (i_branch) = f_branch;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_be", "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, "branch 0x%x", 'x', f_branch, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_call:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_be.f
+    UINT f_r0;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_r0) = f_r0;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_call", "f_r0 0x%x", 'x', f_r0, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_calli:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_bi.f
+    SI f_call;
+
+    f_call = ((pc) + (((int) (((EXTRACT_LSB0_INT (insn, 32, 25, 26)) << (6))) >> (4))));
+
+  /* Record the fields for the semantic handler.  */
+  FLD (i_call) = f_call;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_calli", "call 0x%x", 'x', f_call, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_divu:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_user.f
+    UINT f_r0;
+    UINT f_r1;
+    UINT f_r2;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  FLD (f_r2) = f_r2;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_divu", "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, "f_r2 0x%x", 'x', f_r2, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_lb:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_addi.f
+    UINT f_r0;
+    UINT f_r1;
+    INT f_imm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_imm = EXTRACT_LSB0_INT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_imm) = f_imm;
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_lb", "f_imm 0x%x", 'x', f_imm, "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_lh:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_addi.f
+    UINT f_r0;
+    UINT f_r1;
+    INT f_imm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_imm = EXTRACT_LSB0_INT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_imm) = f_imm;
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_lh", "f_imm 0x%x", 'x', f_imm, "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_lw:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_addi.f
+    UINT f_r0;
+    UINT f_r1;
+    INT f_imm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_imm = EXTRACT_LSB0_INT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_imm) = f_imm;
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_lw", "f_imm 0x%x", 'x', f_imm, "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_ori:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_andi.f
+    UINT f_r0;
+    UINT f_r1;
+    UINT f_uimm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_uimm = EXTRACT_LSB0_UINT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_uimm) = f_uimm;
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_ori", "f_uimm 0x%x", 'x', f_uimm, "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_rcsr:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_rcsr.f
+    UINT f_csr;
+    UINT f_r2;
+
+    f_csr = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_csr) = f_csr;
+  FLD (f_r2) = f_r2;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_rcsr", "f_csr 0x%x", 'x', f_csr, "f_r2 0x%x", 'x', f_r2, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_sb:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_addi.f
+    UINT f_r0;
+    UINT f_r1;
+    INT f_imm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_imm = EXTRACT_LSB0_INT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_imm) = f_imm;
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_sb", "f_imm 0x%x", 'x', f_imm, "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_sextb:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_user.f
+    UINT f_r0;
+    UINT f_r2;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_r0) = f_r0;
+  FLD (f_r2) = f_r2;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_sextb", "f_r0 0x%x", 'x', f_r0, "f_r2 0x%x", 'x', f_r2, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_sh:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_addi.f
+    UINT f_r0;
+    UINT f_r1;
+    INT f_imm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_imm = EXTRACT_LSB0_INT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_imm) = f_imm;
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_sh", "f_imm 0x%x", 'x', f_imm, "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_sl:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_user.f
+    UINT f_r0;
+    UINT f_r1;
+    UINT f_r2;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  FLD (f_r2) = f_r2;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_sl", "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, "f_r2 0x%x", 'x', f_r2, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_sw:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_addi.f
+    UINT f_r0;
+    UINT f_r1;
+    INT f_imm;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_imm = EXTRACT_LSB0_INT (insn, 32, 15, 16);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_imm) = f_imm;
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_sw", "f_imm 0x%x", 'x', f_imm, "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_user:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_user.f
+    UINT f_r0;
+    UINT f_r1;
+    UINT f_r2;
+    UINT f_user;
+
+    f_r0 = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+    f_r2 = EXTRACT_LSB0_UINT (insn, 32, 15, 5);
+    f_user = EXTRACT_LSB0_UINT (insn, 32, 10, 11);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_r0) = f_r0;
+  FLD (f_r1) = f_r1;
+  FLD (f_user) = f_user;
+  FLD (f_r2) = f_r2;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_user", "f_r0 0x%x", 'x', f_r0, "f_r1 0x%x", 'x', f_r1, "f_user 0x%x", 'x', f_user, "f_r2 0x%x", 'x', f_r2, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_wcsr:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+    CGEN_INSN_INT insn = entire_insn;
+#define FLD(f) abuf->fields.sfmt_wcsr.f
+    UINT f_csr;
+    UINT f_r1;
+
+    f_csr = EXTRACT_LSB0_UINT (insn, 32, 25, 5);
+    f_r1 = EXTRACT_LSB0_UINT (insn, 32, 20, 5);
+
+  /* Record the fields for the semantic handler.  */
+  FLD (f_csr) = f_csr;
+  FLD (f_r1) = f_r1;
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_wcsr", "f_csr 0x%x", 'x', f_csr, "f_r1 0x%x", 'x', f_r1, (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+ extract_sfmt_break:
+  {
+    const IDESC *idesc = &lm32bf_insn_data[itype];
+#define FLD(f) abuf->fields.fmt_empty.f
+
+
+  /* Record the fields for the semantic handler.  */
+  TRACE_EXTRACT (current_cpu, abuf, (current_cpu, pc, "sfmt_break", (char *) 0));
+
+#undef FLD
+    return idesc;
+  }
+
+}
Index: sim/lm32/decode.h
===================================================================
RCS file: sim/lm32/decode.h
diff -N sim/lm32/decode.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/decode.h	15 Apr 2009 17:41:25 -0000
@@ -0,0 +1,76 @@
+/* Decode header for lm32bf.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef LM32BF_DECODE_H
+#define LM32BF_DECODE_H
+
+extern const IDESC *lm32bf_decode (SIM_CPU *, IADDR,
+                                  CGEN_INSN_INT, CGEN_INSN_INT,
+                                  ARGBUF *);
+extern void lm32bf_init_idesc_table (SIM_CPU *);
+extern void lm32bf_sem_init_idesc_table (SIM_CPU *);
+extern void lm32bf_semf_init_idesc_table (SIM_CPU *);
+
+/* Enum declaration for instructions in cpu family lm32bf.  */
+typedef enum lm32bf_insn_type {
+  LM32BF_INSN_X_INVALID, LM32BF_INSN_X_AFTER, LM32BF_INSN_X_BEFORE, LM32BF_INSN_X_CTI_CHAIN
+ , LM32BF_INSN_X_CHAIN, LM32BF_INSN_X_BEGIN, LM32BF_INSN_ADD, LM32BF_INSN_ADDI
+ , LM32BF_INSN_AND, LM32BF_INSN_ANDI, LM32BF_INSN_ANDHII, LM32BF_INSN_B
+ , LM32BF_INSN_BI, LM32BF_INSN_BE, LM32BF_INSN_BG, LM32BF_INSN_BGE
+ , LM32BF_INSN_BGEU, LM32BF_INSN_BGU, LM32BF_INSN_BNE, LM32BF_INSN_CALL
+ , LM32BF_INSN_CALLI, LM32BF_INSN_CMPE, LM32BF_INSN_CMPEI, LM32BF_INSN_CMPG
+ , LM32BF_INSN_CMPGI, LM32BF_INSN_CMPGE, LM32BF_INSN_CMPGEI, LM32BF_INSN_CMPGEU
+ , LM32BF_INSN_CMPGEUI, LM32BF_INSN_CMPGU, LM32BF_INSN_CMPGUI, LM32BF_INSN_CMPNE
+ , LM32BF_INSN_CMPNEI, LM32BF_INSN_DIVU, LM32BF_INSN_LB, LM32BF_INSN_LBU
+ , LM32BF_INSN_LH, LM32BF_INSN_LHU, LM32BF_INSN_LW, LM32BF_INSN_MODU
+ , LM32BF_INSN_MUL, LM32BF_INSN_MULI, LM32BF_INSN_NOR, LM32BF_INSN_NORI
+ , LM32BF_INSN_OR, LM32BF_INSN_ORI, LM32BF_INSN_ORHII, LM32BF_INSN_RCSR
+ , LM32BF_INSN_SB, LM32BF_INSN_SEXTB, LM32BF_INSN_SEXTH, LM32BF_INSN_SH
+ , LM32BF_INSN_SL, LM32BF_INSN_SLI, LM32BF_INSN_SR, LM32BF_INSN_SRI
+ , LM32BF_INSN_SRU, LM32BF_INSN_SRUI, LM32BF_INSN_SUB, LM32BF_INSN_SW
+ , LM32BF_INSN_USER, LM32BF_INSN_WCSR, LM32BF_INSN_XOR, LM32BF_INSN_XORI
+ , LM32BF_INSN_XNOR, LM32BF_INSN_XNORI, LM32BF_INSN_BREAK, LM32BF_INSN_SCALL
+ , LM32BF_INSN__MAX
+} LM32BF_INSN_TYPE;
+
+/* Enum declaration for semantic formats in cpu family lm32bf.  */
+typedef enum lm32bf_sfmt_type {
+  LM32BF_SFMT_EMPTY, LM32BF_SFMT_ADD, LM32BF_SFMT_ADDI, LM32BF_SFMT_ANDI
+ , LM32BF_SFMT_ANDHII, LM32BF_SFMT_B, LM32BF_SFMT_BI, LM32BF_SFMT_BE
+ , LM32BF_SFMT_CALL, LM32BF_SFMT_CALLI, LM32BF_SFMT_DIVU, LM32BF_SFMT_LB
+ , LM32BF_SFMT_LH, LM32BF_SFMT_LW, LM32BF_SFMT_ORI, LM32BF_SFMT_RCSR
+ , LM32BF_SFMT_SB, LM32BF_SFMT_SEXTB, LM32BF_SFMT_SH, LM32BF_SFMT_SL
+ , LM32BF_SFMT_SW, LM32BF_SFMT_USER, LM32BF_SFMT_WCSR, LM32BF_SFMT_BREAK
+} LM32BF_SFMT_TYPE;
+
+/* Function unit handlers (user written).  */
+
+extern int lm32bf_model_lm32_u_exec (SIM_CPU *, const IDESC *, int /*unit_num*/, int /*referenced*/);
+
+/* Profiling before/after handlers (user written) */
+
+extern void lm32bf_model_insn_before (SIM_CPU *, int /*first_p*/);
+extern void lm32bf_model_insn_after (SIM_CPU *, int /*last_p*/, int /*cycles*/);
+
+#endif /* LM32BF_DECODE_H */
Index: sim/lm32/dv-lm32cpu.c
===================================================================
RCS file: sim/lm32/dv-lm32cpu.c
diff -N sim/lm32/dv-lm32cpu.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/dv-lm32cpu.c	15 Apr 2009 17:41:26 -0000
@@ -0,0 +1,247 @@
+/*  Lattice Mico32 CPU model.
+    Contributed by Jon Beniston <jon@beniston.com>
+
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "hw-main.h"
+#include "sim-main.h"
+
+
+struct lm32cpu
+{
+  struct hw_event *event;
+};
+
+/* input port ID's.  */
+
+enum
+{
+  INT0_PORT,
+  INT1_PORT,
+  INT2_PORT,
+  INT3_PORT,
+  INT4_PORT,
+  INT5_PORT,
+  INT6_PORT,
+  INT7_PORT,
+  INT8_PORT,
+  INT9_PORT,
+  INT10_PORT,
+  INT11_PORT,
+  INT12_PORT,
+  INT13_PORT,
+  INT14_PORT,
+  INT15_PORT,
+  INT16_PORT,
+  INT17_PORT,
+  INT18_PORT,
+  INT19_PORT,
+  INT20_PORT,
+  INT21_PORT,
+  INT22_PORT,
+  INT23_PORT,
+  INT24_PORT,
+  INT25_PORT,
+  INT26_PORT,
+  INT27_PORT,
+  INT28_PORT,
+  INT29_PORT,
+  INT30_PORT,
+  INT31_PORT,
+};
+
+static const struct hw_port_descriptor lm32cpu_ports[] = {
+  /* interrupt inputs.  */
+  {"int0", INT0_PORT, 0, input_port,},
+  {"int1", INT1_PORT, 0, input_port,},
+  {"int2", INT2_PORT, 0, input_port,},
+  {"int3", INT3_PORT, 0, input_port,},
+  {"int4", INT4_PORT, 0, input_port,},
+  {"int5", INT5_PORT, 0, input_port,},
+  {"int6", INT6_PORT, 0, input_port,},
+  {"int7", INT7_PORT, 0, input_port,},
+  {"int8", INT8_PORT, 0, input_port,},
+  {"int9", INT9_PORT, 0, input_port,},
+  {"int10", INT10_PORT, 0, input_port,},
+  {"int11", INT11_PORT, 0, input_port,},
+  {"int12", INT12_PORT, 0, input_port,},
+  {"int13", INT13_PORT, 0, input_port,},
+  {"int14", INT14_PORT, 0, input_port,},
+  {"int15", INT15_PORT, 0, input_port,},
+  {"int16", INT16_PORT, 0, input_port,},
+  {"int17", INT17_PORT, 0, input_port,},
+  {"int18", INT18_PORT, 0, input_port,},
+  {"int19", INT19_PORT, 0, input_port,},
+  {"int20", INT20_PORT, 0, input_port,},
+  {"int21", INT21_PORT, 0, input_port,},
+  {"int22", INT22_PORT, 0, input_port,},
+  {"int23", INT23_PORT, 0, input_port,},
+  {"int24", INT24_PORT, 0, input_port,},
+  {"int25", INT25_PORT, 0, input_port,},
+  {"int26", INT26_PORT, 0, input_port,},
+  {"int27", INT27_PORT, 0, input_port,},
+  {"int28", INT28_PORT, 0, input_port,},
+  {"int29", INT29_PORT, 0, input_port,},
+  {"int30", INT30_PORT, 0, input_port,},
+  {"int31", INT31_PORT, 0, input_port,},
+  {NULL,},
+};
+
+
+
+/*
+ * Finish off the partially created hw device.  Attach our local
+ * callbacks.  Wire up our port names etc.  
+ */
+static hw_port_event_method lm32cpu_port_event;
+
+
+static void
+lm32cpu_finish (struct hw *me)
+{
+  struct lm32cpu *controller;
+
+  controller = HW_ZALLOC (me, struct lm32cpu);
+  set_hw_data (me, controller);
+  set_hw_ports (me, lm32cpu_ports);
+  set_hw_port_event (me, lm32cpu_port_event);
+
+  /* Initialize the pending interrupt flags.  */
+  controller->event = NULL;
+}
+
+
+/* An event arrives on an interrupt port.  */
+static unsigned int s_ui_ExtIntrs = 0;
+
+
+static void
+deliver_lm32cpu_interrupt (struct hw *me, void *data)
+{
+  static unsigned int ip, im, im_and_ip_result;
+  struct lm32cpu *controller = hw_data (me);
+  SIM_DESC sd = hw_system (me);
+  sim_cpu *cpu = STATE_CPU (sd, 0);	/* NB: fix CPU 0.  */
+  address_word cia = CIA_GET (cpu);
+  int interrupt = (int) data;
+
+
+  HW_TRACE ((me, "interrupt-check event"));
+
+
+  /*
+   * Determine if an external interrupt is active 
+   * and needs to cause an exception.
+   */
+  im = lm32bf_h_csr_get (cpu, LM32_CSR_IM);
+  ip = lm32bf_h_csr_get (cpu, LM32_CSR_IP);
+  im_and_ip_result = im & ip;
+
+
+  if ((lm32bf_h_csr_get (cpu, LM32_CSR_IE) & 1) && (im_and_ip_result != 0))
+    {
+      /* Save PC in exception address register.  */
+      lm32bf_h_gr_set (cpu, 30, lm32bf_h_pc_get (cpu));
+      /* Restart at interrupt offset in handler exception table.  */
+      lm32bf_h_pc_set (cpu,
+		       lm32bf_h_csr_get (cpu,
+					 LM32_CSR_EBA) +
+		       LM32_EID_INTERRUPT * 32);
+      /* Save interrupt enable and then clear.  */
+      lm32bf_h_csr_set (cpu, LM32_CSR_IE, 0x2);
+    }
+
+  /* reschedule soon.  */
+  if (controller->event != NULL)
+    hw_event_queue_deschedule (me, controller->event);
+  controller->event = NULL;
+
+
+  /* if there are external interrupts, schedule an interrupt-check again.
+   * NOTE: THIS MAKES IT VERY INEFFICIENT. INSTEAD, TRIGGER THIS
+   * CHECk_EVENT WHEN THE USER ENABLES IE OR USER MODIFIES IM REGISTERS.
+   */
+  if (s_ui_ExtIntrs != 0)
+    controller->event =
+      hw_event_queue_schedule (me, 1, deliver_lm32cpu_interrupt, data);
+}
+
+
+
+/* Handle an event on one of the CPU's ports.  */
+static void
+lm32cpu_port_event (struct hw *me,
+		    int my_port,
+		    struct hw *source, int source_port, int level)
+{
+  struct lm32cpu *controller = hw_data (me);
+  SIM_DESC sd = hw_system (me);
+  sim_cpu *cpu = STATE_CPU (sd, 0);	/* NB: fix CPU 0.  */
+  address_word cia = CIA_GET (cpu);
+
+
+  HW_TRACE ((me, "interrupt event on port %d, level %d", my_port, level));
+
+
+
+  /* 
+   * Activate IP if the interrupt's activated; don't do anything if
+   * the interrupt's deactivated.
+   */
+  if (level == 1)
+    {
+      /*
+       * save state of external interrupt.
+       */
+      s_ui_ExtIntrs |= (1 << my_port);
+
+      /* interrupt-activated so set IP.  */
+      lm32bf_h_csr_set (cpu, LM32_CSR_IP,
+			lm32bf_h_csr_get (cpu, LM32_CSR_IP) | (1 << my_port));
+
+      /* 
+       * Since interrupt is activated, queue an immediate event
+       * to check if this interrupt is serviceable.
+       */
+      if (controller->event != NULL)
+	hw_event_queue_deschedule (me, controller->event);
+
+
+      /* 
+       * Queue an immediate event to check if this interrupt must be serviced;
+       * this will happen after the current instruction is complete.
+       */
+      controller->event = hw_event_queue_schedule (me,
+						   0,
+						   deliver_lm32cpu_interrupt,
+						   0);
+    }
+  else
+    {
+      /*
+       * save state of external interrupt.
+       */
+      s_ui_ExtIntrs &= ~(1 << my_port);
+    }
+}
+
+
+const struct hw_descriptor dv_lm32cpu_descriptor[] = {
+  {"lm32cpu", lm32cpu_finish,},
+  {NULL},
+};
Index: sim/lm32/dv-lm32timer.c
===================================================================
RCS file: sim/lm32/dv-lm32timer.c
diff -N sim/lm32/dv-lm32timer.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/dv-lm32timer.c	15 Apr 2009 17:41:26 -0000
@@ -0,0 +1,220 @@
+/*  Lattice Mico32 timer model.
+    Contributed by Jon Beniston <jon@beniston.com>
+    
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "sim-main.h"
+#include "hw-main.h"
+#include "sim-assert.h"
+
+struct lm32timer
+{
+  unsigned base;		/* Base address of this timer.  */
+  unsigned limit;		/* Limit address of this timer.  */
+  unsigned int status;
+  unsigned int control;
+  unsigned int period;
+  unsigned int snapshot;
+  struct hw_event *event;
+};
+
+/* Timer registers.  */
+#define LM32_TIMER_STATUS       0x0
+#define LM32_TIMER_CONTROL      0x4
+#define LM32_TIMER_PERIOD       0x8
+#define LM32_TIMER_SNAPSHOT     0xc
+
+/* Timer ports.  */
+
+enum
+{
+  INT_PORT
+};
+
+static const struct hw_port_descriptor lm32timer_ports[] = {
+  {"int", INT_PORT, 0, output_port},
+  {}
+};
+
+static void
+do_timer_event (struct hw *me, void *data)
+{
+  struct lm32timer *timer = hw_data (me);
+
+  /* Is timer started? */
+  if (timer->control & 0x4)
+    {
+      if (timer->snapshot)
+	{
+	  /* Decrement timer.  */
+	  timer->snapshot--;
+	}
+      else if (timer->control & 1)
+	{
+	  /* Restart timer.  */
+	  timer->snapshot = timer->period;
+	}
+    }
+  /* Generate interrupt when timer is at 0, and interrupt enable is 1.  */
+  if ((timer->snapshot == 0) && (timer->control & 1))
+    {
+      /* Generate interrupt.  */
+      hw_port_event (me, INT_PORT, 1);
+    }
+  /* If timer is started, schedule another event to decrement the timer again.  */
+  if (timer->control & 4)
+    hw_event_queue_schedule (me, 1, do_timer_event, 0);
+}
+
+static unsigned
+lm32timer_io_write_buffer (struct hw *me,
+			   const void *source,
+			   int space, unsigned_word base, unsigned nr_bytes)
+{
+  struct lm32timer *timers = hw_data (me);
+  int timer_reg;
+  const unsigned char *source_bytes = source;
+  int value = 0;
+
+  HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
+	     (int) nr_bytes, value));
+
+  if (nr_bytes == 4)
+    value = (source_bytes[0] << 24)
+      | (source_bytes[1] << 16) | (source_bytes[2] << 8) | (source_bytes[3]);
+  else
+    hw_abort (me, "write with invalid number of bytes: %d", nr_bytes);
+
+  timer_reg = base - timers->base;
+
+  switch (timer_reg)
+    {
+    case LM32_TIMER_STATUS:
+      timers->status = value;
+      break;
+    case LM32_TIMER_CONTROL:
+      timers->control = value;
+      if (timers->control & 0x4)
+	{
+	  /* Timer is started.  */
+	  hw_event_queue_schedule (me, 1, do_timer_event, 0);
+	}
+      break;
+    case LM32_TIMER_PERIOD:
+      timers->period = value;
+      break;
+    default:
+      hw_abort (me, "invalid register address: 0x%x.", timer_reg);
+    }
+
+  return nr_bytes;
+}
+
+static unsigned
+lm32timer_io_read_buffer (struct hw *me,
+			  void *dest,
+			  int space, unsigned_word base, unsigned nr_bytes)
+{
+  struct lm32timer *timers = hw_data (me);
+  int timer_reg;
+  int value;
+  unsigned char *dest_bytes = dest;
+
+  HW_TRACE ((me, "read 0x%08lx length %d", (long) base, (int) nr_bytes));
+
+  timer_reg = base - timers->base;
+
+  switch (timer_reg)
+    {
+    case LM32_TIMER_STATUS:
+      value = timers->status;
+      break;
+    case LM32_TIMER_CONTROL:
+      value = timers->control;
+      break;
+    case LM32_TIMER_PERIOD:
+      value = timers->period;
+      break;
+    case LM32_TIMER_SNAPSHOT:
+      value = timers->snapshot;
+      break;
+    default:
+      hw_abort (me, "invalid register address: 0x%x.", timer_reg);
+    }
+
+  if (nr_bytes == 4)
+    {
+      dest_bytes[0] = value >> 24;
+      dest_bytes[1] = value >> 16;
+      dest_bytes[2] = value >> 8;
+      dest_bytes[3] = value;
+    }
+  else
+    hw_abort (me, "read of unsupported number of bytes: %d", nr_bytes);
+
+  return nr_bytes;
+}
+
+static void
+attach_lm32timer_regs (struct hw *me, struct lm32timer *timers)
+{
+  unsigned_word attach_address;
+  int attach_space;
+  unsigned attach_size;
+  reg_property_spec reg;
+
+  if (hw_find_property (me, "reg") == NULL)
+    hw_abort (me, "Missing \"reg\" property");
+  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+    hw_abort (me, "\"reg\" property must contain three addr/size entries");
+  hw_unit_address_to_attach_address (hw_parent (me),
+				     &reg.address,
+				     &attach_space, &attach_address, me);
+  timers->base = attach_address;
+  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+  timers->limit = attach_address + (attach_size - 1);
+  hw_attach_address (hw_parent (me),
+		     0, attach_space, attach_address, attach_size, me);
+}
+
+static void
+lm32timer_finish (struct hw *me)
+{
+  struct lm32timer *timers;
+  int i;
+
+  timers = HW_ZALLOC (me, struct lm32timer);
+  set_hw_data (me, timers);
+  set_hw_io_read_buffer (me, lm32timer_io_read_buffer);
+  set_hw_io_write_buffer (me, lm32timer_io_write_buffer);
+  set_hw_ports (me, lm32timer_ports);
+
+  /* Attach ourself to our parent bus.  */
+  attach_lm32timer_regs (me, timers);
+
+  /* Initialize the timers.  */
+  timers->status = 0;
+  timers->control = 0;
+  timers->period = 0;
+  timers->snapshot = 0;
+}
+
+const struct hw_descriptor dv_lm32timer_descriptor[] = {
+  {"lm32timer", lm32timer_finish,},
+  {NULL},
+};
Index: sim/lm32/dv-lm32uart.c
===================================================================
RCS file: sim/lm32/dv-lm32uart.c
diff -N sim/lm32/dv-lm32uart.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/dv-lm32uart.c	15 Apr 2009 17:41:26 -0000
@@ -0,0 +1,317 @@
+/*  Lattice Mico32 UART model.
+    Contributed by Jon Beniston <jon@beniston.com>
+    
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "sim-main.h"
+#include "hw-main.h"
+#include "sim-assert.h"
+
+#include <stdio.h>
+#include <sys/time.h>
+
+struct lm32uart
+{
+  unsigned base;		/* Base address of this UART.  */
+  unsigned limit;		/* Limit address of this UART.  */
+  unsigned char rbr;
+  unsigned char thr;
+  unsigned char ier;
+  unsigned char iir;
+  unsigned char lcr;
+  unsigned char mcr;
+  unsigned char lsr;
+  unsigned char msr;
+  unsigned char div;
+  struct hw_event *event;
+};
+
+/* UART registers.  */
+
+#define LM32_UART_RBR           0x0
+#define LM32_UART_THR           0x0
+#define LM32_UART_IER           0x4
+#define LM32_UART_IIR           0x8
+#define LM32_UART_LCR           0xc
+#define LM32_UART_MCR           0x10
+#define LM32_UART_LSR           0x14
+#define LM32_UART_MSR           0x18
+#define LM32_UART_DIV           0x1c
+
+#define LM32_UART_IER_RX_INT    0x1
+#define LM32_UART_IER_TX_INT    0x2
+
+#define MICOUART_IIR_TXRDY      0x2
+#define MICOUART_IIR_RXRDY      0x4
+
+#define LM32_UART_LSR_RX_RDY    0x01
+#define LM32_UART_LSR_TX_RDY    0x20
+
+#define LM32_UART_LCR_WLS_MASK  0x3
+#define LM32_UART_LCR_WLS_5     0x0
+#define LM32_UART_LCR_WLS_6     0x1
+#define LM32_UART_LCR_WLS_7     0x2
+#define LM32_UART_LCR_WLS_8     0x3
+
+/* UART ports.  */
+
+enum
+{
+  INT_PORT
+};
+
+static const struct hw_port_descriptor lm32uart_ports[] = {
+  {"int", INT_PORT, 0, output_port},
+  {}
+};
+
+static void
+do_uart_tx_event (struct hw *me, void *data)
+{
+  struct lm32uart *uart = hw_data (me);
+  char c;
+
+  /* Generate interrupt when transmission is complete.  */
+  if (uart->ier & LM32_UART_IER_TX_INT)
+    {
+      /* Generate interrupt */
+      hw_port_event (me, INT_PORT, 1);
+    }
+
+  /* Indicate which interrupt has occured.  */
+  uart->iir = MICOUART_IIR_TXRDY;
+
+  /* Indicate THR is empty.  */
+  uart->lsr |= LM32_UART_LSR_TX_RDY;
+
+  /* Output the character in the THR.  */
+  c = (char) uart->thr;
+
+  /* WLS field in LCR register specifies the number of bits to output.  */
+  switch (uart->lcr & LM32_UART_LCR_WLS_MASK)
+    {
+    case LM32_UART_LCR_WLS_5:
+      c &= 0x1f;
+      break;
+    case LM32_UART_LCR_WLS_6:
+      c &= 0x3f;
+      break;
+    case LM32_UART_LCR_WLS_7:
+      c &= 0x7f;
+      break;
+    }
+  printf ("%c", c);
+}
+
+static unsigned
+lm32uart_io_write_buffer (struct hw *me,
+			  const void *source,
+			  int space, unsigned_word base, unsigned nr_bytes)
+{
+  struct lm32uart *uart = hw_data (me);
+  int uart_reg;
+  const unsigned char *source_bytes = source;
+  int value = 0;
+
+  HW_TRACE ((me, "write to 0x%08lx length %d with 0x%x", (long) base,
+	     (int) nr_bytes, value));
+
+  if (nr_bytes == 4)
+    value = (source_bytes[0] << 24)
+      | (source_bytes[1] << 16) | (source_bytes[2] << 8) | (source_bytes[3]);
+  else
+    hw_abort (me, "write of unsupported number of bytes: %d.", nr_bytes);
+
+  uart_reg = base - uart->base;
+
+  switch (uart_reg)
+    {
+    case LM32_UART_THR:
+      /* Buffer the character to output.  */
+      uart->thr = value;
+
+      /* Indicate the THR is full.  */
+      uart->lsr &= ~LM32_UART_LSR_TX_RDY;
+
+      /* deassert interrupt when IER is loaded.  */
+      uart->iir &= ~MICOUART_IIR_TXRDY;
+
+      /* schedule an event to output the character.  */
+      hw_event_queue_schedule (me, 1, do_uart_tx_event, 0);
+
+      break;
+    case LM32_UART_IER:
+      uart->ier = value;
+      if ((value & LM32_UART_IER_TX_INT)
+	  && (uart->lsr & LM32_UART_LSR_TX_RDY))
+	{
+	  /* hw_event_queue_schedule (me, 1, do_uart_tx_event, 0); */
+	  uart->lsr |= LM32_UART_LSR_TX_RDY;
+	  uart->iir |= MICOUART_IIR_TXRDY;
+	  hw_port_event (me, INT_PORT, 1);
+	}
+      else if ((value & LM32_UART_IER_TX_INT) == 0)
+	{
+	  hw_port_event (me, INT_PORT, 0);
+	}
+      break;
+    case LM32_UART_IIR:
+      uart->iir = value;
+      break;
+    case LM32_UART_LCR:
+      uart->lcr = value;
+      break;
+    case LM32_UART_MCR:
+      uart->mcr = value;
+      break;
+    case LM32_UART_LSR:
+      uart->lsr = value;
+      break;
+    case LM32_UART_MSR:
+      uart->msr = value;
+      break;
+    case LM32_UART_DIV:
+      uart->div = value;
+      break;
+    default:
+      hw_abort (me, "write to invalid register address: 0x%x.", uart_reg);
+    }
+
+  return nr_bytes;
+}
+
+static unsigned
+lm32uart_io_read_buffer (struct hw *me,
+			 void *dest,
+			 int space, unsigned_word base, unsigned nr_bytes)
+{
+  struct lm32uart *uart = hw_data (me);
+  int uart_reg;
+  int value;
+  unsigned char *dest_bytes = dest;
+  fd_set fd;
+  struct timeval tv;
+
+  HW_TRACE ((me, "read 0x%08lx length %d", (long) base, (int) nr_bytes));
+
+  uart_reg = base - uart->base;
+
+  switch (uart_reg)
+    {
+    case LM32_UART_RBR:
+      value = getchar ();
+      uart->lsr &= ~LM32_UART_LSR_RX_RDY;
+      break;
+    case LM32_UART_IER:
+      value = uart->ier;
+      break;
+    case LM32_UART_IIR:
+      value = uart->iir;
+      break;
+    case LM32_UART_LCR:
+      value = uart->lcr;
+      break;
+    case LM32_UART_MCR:
+      value = uart->mcr;
+      break;
+    case LM32_UART_LSR:
+      /* Check to see if any data waiting in stdin.  */
+      FD_ZERO (&fd);
+      FD_SET (fileno (stdin), &fd);
+      tv.tv_sec = 0;
+      tv.tv_usec = 1;
+      if (select (fileno (stdin) + 1, &fd, NULL, NULL, &tv))
+	uart->lsr |= LM32_UART_LSR_RX_RDY;
+      value = uart->lsr;
+      break;
+    case LM32_UART_MSR:
+      value = uart->msr;
+      break;
+    case LM32_UART_DIV:
+      value = uart->div;
+      break;
+    default:
+      hw_abort (me, "read from invalid register address: 0x%x.", uart_reg);
+    }
+
+  if (nr_bytes == 4)
+    {
+      dest_bytes[0] = value >> 24;
+      dest_bytes[1] = value >> 16;
+      dest_bytes[2] = value >> 8;
+      dest_bytes[3] = value;
+    }
+  else
+    hw_abort (me, "read of unsupported number of bytes: %d", nr_bytes);
+
+  return nr_bytes;
+}
+
+static void
+attach_lm32uart_regs (struct hw *me, struct lm32uart *uart)
+{
+  unsigned_word attach_address;
+  int attach_space;
+  unsigned attach_size;
+  reg_property_spec reg;
+
+  if (hw_find_property (me, "reg") == NULL)
+    hw_abort (me, "Missing \"reg\" property");
+  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+    hw_abort (me, "\"reg\" property must contain three addr/size entries");
+  hw_unit_address_to_attach_address (hw_parent (me),
+				     &reg.address,
+				     &attach_space, &attach_address, me);
+  uart->base = attach_address;
+  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
+  uart->limit = attach_address + (attach_size - 1);
+  hw_attach_address (hw_parent (me),
+		     0, attach_space, attach_address, attach_size, me);
+}
+
+static void
+lm32uart_finish (struct hw *me)
+{
+  struct lm32uart *uart;
+  int i;
+
+  uart = HW_ZALLOC (me, struct lm32uart);
+  set_hw_data (me, uart);
+  set_hw_io_read_buffer (me, lm32uart_io_read_buffer);
+  set_hw_io_write_buffer (me, lm32uart_io_write_buffer);
+  set_hw_ports (me, lm32uart_ports);
+
+  /* Attach ourself to our parent bus.  */
+  attach_lm32uart_regs (me, uart);
+
+  /* Initialize the UART.  */
+  uart->rbr = 0;
+  uart->thr = 0;
+  uart->ier = 0;
+  uart->iir = 0;
+  uart->lcr = 0;
+  uart->mcr = 0;
+  uart->lsr = LM32_UART_LSR_TX_RDY;
+  uart->msr = 0;
+  uart->div = 0;		/* By setting to zero, characters are output immediately.  */
+}
+
+const struct hw_descriptor dv_lm32uart_descriptor[] = {
+  {"lm32uart", lm32uart_finish,},
+  {NULL},
+};
Index: sim/lm32/lm32-sim.h
===================================================================
RCS file: sim/lm32/lm32-sim.h
diff -N sim/lm32/lm32-sim.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/lm32-sim.h	15 Apr 2009 17:41:26 -0000
@@ -0,0 +1,57 @@
+/* Contributed by Jon Beniston <jon@beniston.com>
+
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 LM32_SIM_H
+#define LM32_SIM_H
+
+#include "gdb/sim-lm32.h"
+
+/* CSRs.  */
+#define LM32_CSR_IE             0
+#define LM32_CSR_IM             1
+#define LM32_CSR_IP             2
+#define LM32_CSR_ICC            3
+#define LM32_CSR_DCC            4
+#define LM32_CSR_CC             5
+#define LM32_CSR_CFG            6
+#define LM32_CSR_EBA            7
+#define LM32_CSR_DC             8
+#define LM32_CSR_DEBA           9
+#define LM32_CSR_JTX            0xe
+#define LM32_CSR_JRX            0xf
+#define LM32_CSR_BP0            0x10
+#define LM32_CSR_BP1            0x11
+#define LM32_CSR_BP2            0x12
+#define LM32_CSR_BP3            0x13
+#define LM32_CSR_WP0            0x18
+#define LM32_CSR_WP1            0x19
+#define LM32_CSR_WP2            0x1a
+#define LM32_CSR_WP3            0x1b
+
+/* Exception IDs.  */
+#define LM32_EID_RESET                  0
+#define LM32_EID_BREAKPOINT             1
+#define LM32_EID_INSTRUCTION_BUS_ERROR  2
+#define LM32_EID_WATCHPOINT             3
+#define LM32_EID_DATA_BUS_ERROR         4
+#define LM32_EID_DIVIDE_BY_ZERO         5
+#define LM32_EID_INTERRUPT              6
+#define LM32_EID_SYSTEM_CALL            7
+
+#endif /* LM32_SIM_H */
Index: sim/lm32/lm32.c
===================================================================
RCS file: sim/lm32/lm32.c
diff -N sim/lm32/lm32.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/lm32.c	15 Apr 2009 17:41:26 -0000
@@ -0,0 +1,100 @@
+/* Lattice Mico32 simulator support code.
+   Contributed by Jon Beniston <jon@beniston.com>
+
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#define WANT_CPU lm32bf
+#define WANT_CPU_LM32BF
+
+#include "sim-main.h"
+#include "cgen-mem.h"
+#include "cgen-ops.h"
+
+/* The contents of BUF are in target byte order.  */
+
+int
+lm32bf_fetch_register (SIM_CPU * current_cpu, int rn, unsigned char *buf,
+		       int len)
+{
+  if (rn < 32)
+    SETTSI (buf, lm32bf_h_gr_get (current_cpu, rn));
+  else
+    switch (rn)
+      {
+      case SIM_LM32_PC_REGNUM:
+	SETTSI (buf, lm32bf_h_pc_get (current_cpu));
+	break;
+      default:
+	return 0;
+      }
+
+  return -1;
+}
+
+/* The contents of BUF are in target byte order.  */
+
+int
+lm32bf_store_register (SIM_CPU * current_cpu, int rn, unsigned char *buf,
+		       int len)
+{
+  if (rn < 32)
+    lm32bf_h_gr_set (current_cpu, rn, GETTSI (buf));
+  else
+    switch (rn)
+      {
+      case SIM_LM32_PC_REGNUM:
+	lm32bf_h_pc_set (current_cpu, GETTSI (buf));
+	break;
+      default:
+	return 0;
+      }
+
+  return -1;
+}
+
+
+
+#if WITH_PROFILE_MODEL_P
+
+/* Initialize cycle counting for an insn.
+   FIRST_P is non-zero if this is the first insn in a set of parallel
+   insns.  */
+
+void
+lm32bf_model_insn_before (SIM_CPU * cpu, int first_p)
+{
+}
+
+/* Record the cycles computed for an insn.
+   LAST_P is non-zero if this is the last insn in a set of parallel insns,
+   and we update the total cycle count.
+   CYCLES is the cycle count of the insn.  */
+
+void
+lm32bf_model_insn_after (SIM_CPU * cpu, int last_p, int cycles)
+{
+}
+
+int
+lm32bf_model_lm32_u_exec (SIM_CPU * cpu, const IDESC * idesc,
+			  int unit_num, int referenced)
+{
+  return idesc->timing->units[unit_num].done;
+}
+
+#endif /* WITH_PROFILE_MODEL_P */
Index: sim/lm32/mloop.in
===================================================================
RCS file: sim/lm32/mloop.in
diff -N sim/lm32/mloop.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/mloop.in	15 Apr 2009 17:41:26 -0000
@@ -0,0 +1,203 @@
+# Simulator main loop for lm32. -*- C -*-
+# Contributed by Jon Beniston <jon@beniston.com>
+#
+# This file is part of the GNU Simulators.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Syntax:
+# /bin/sh mainloop.in command
+#
+# Command is one of:
+#
+# init
+# support
+# extract-{simple,scache,pbb}
+# {full,fast}-exec-{simple,scache,pbb}
+#
+
+case "x$1" in
+
+xsupport)
+
+cat <<EOF
+
+static INLINE const IDESC *
+extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
+	   ARGBUF *abuf, int fast_p)
+{
+  const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);
+
+  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
+  if (! fast_p)
+    {
+      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
+      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
+      @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
+    }
+  return id;
+}
+
+static INLINE SEM_PC
+execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
+{
+  SEM_PC vpc;
+
+  if (fast_p)
+    {
+#if ! WITH_SEM_SWITCH_FAST
+#if WITH_SCACHE
+      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
+#else
+      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, &sc->argbuf);
+#endif
+#else
+      abort ();
+#endif /* WITH_SEM_SWITCH_FAST */
+    }
+  else
+    {
+#if ! WITH_SEM_SWITCH_FULL
+      ARGBUF *abuf = &sc->argbuf;
+      const IDESC *idesc = abuf->idesc;
+      const CGEN_INSN *idata = idesc->idata;
+#if WITH_SCACHE_PBB
+      int virtual_p = CGEN_INSN_ATTR_VALUE (idata, CGEN_INSN_VIRTUAL);
+#else
+      int virtual_p = 0;
+#endif
+      if (! virtual_p)
+	{
+	  /* FIXME: call x-before */
+	  if (ARGBUF_PROFILE_P (abuf))
+	    PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
+	  /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */
+	  if (PROFILE_MODEL_P (current_cpu)
+	      && ARGBUF_PROFILE_P (abuf))
+	    @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
+	  TRACE_INSN_INIT (current_cpu, abuf, 1);
+	  TRACE_INSN (current_cpu, idata,
+		      (const struct argbuf *) abuf, abuf->addr);
+	}
+#if WITH_SCACHE
+      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
+#else
+      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);
+#endif
+      if (! virtual_p)
+	{
+	  /* FIXME: call x-after */
+	  if (PROFILE_MODEL_P (current_cpu)
+	      && ARGBUF_PROFILE_P (abuf))
+	    {
+	      int cycles;
+
+	      cycles = (*idesc->timing->model_fn) (current_cpu, sc);
+	      @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
+	    }
+	  TRACE_INSN_FINI (current_cpu, abuf, 1);
+	}
+#else
+      abort ();
+#endif /* WITH_SEM_SWITCH_FULL */
+    }
+
+  return vpc;
+}
+
+EOF
+
+;;
+
+xinit)
+
+# Nothing needed.
+
+;;
+
+xextract-simple | xextract-scache)
+
+cat <<EOF
+{
+  CGEN_INSN_INT insn = GETIMEMUSI (current_cpu, vpc);
+  extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P);
+}
+EOF
+
+;;
+
+xextract-pbb)
+
+# Inputs:  current_cpu, pc, sc, max_insns, FAST_P
+# Outputs: sc, pc
+# sc must be left pointing past the last created entry.
+# pc must be left pointing past the last created entry.
+# If the pbb is terminated by a cti insn, SET_CTI_VPC(sc) must be called
+# to record the vpc of the cti insn.
+# SET_INSN_COUNT(n) must be called to record number of real insns.
+
+cat <<EOF
+{
+  const IDESC *idesc;
+  int icount = 0;
+
+  while (max_insns > 0)
+    {
+      USI insn = GETIMEMUSI (current_cpu, pc);
+      
+      idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
+      ++sc;
+      --max_insns;
+      ++icount;
+      pc += idesc->length;
+
+      if (IDESC_CTI_P (idesc))
+        {
+          SET_CTI_VPC (sc - 1);
+          break;
+        }
+    }
+
+ Finish:
+  SET_INSN_COUNT (icount);
+}
+EOF
+
+;;
+
+xfull-exec-* | xfast-exec-*)
+
+# Inputs: current_cpu, vpc, FAST_P
+# Outputs: vpc
+
+cat <<EOF
+  /* Update cycle counter */
+  SET_H_CSR (LM32_CSR_CC, GET_H_CSR (LM32_CSR_CC) + 1);
+#if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST)
+#define DEFINE_SWITCH
+#include "sem-switch.c"
+#else
+  vpc = execute (current_cpu, vpc, FAST_P);
+#endif
+EOF
+
+;;
+
+*)
+  echo "Invalid argument to mainloop.in: $1" >&2
+  exit 1
+  ;;
+
+esac
Index: sim/lm32/model.c
===================================================================
RCS file: sim/lm32/model.c
diff -N sim/lm32/model.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/model.c	15 Apr 2009 17:41:26 -0000
@@ -0,0 +1,1176 @@
+/* Simulator model support for lm32bf.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#define WANT_CPU lm32bf
+#define WANT_CPU_LM32BF
+
+#include "sim-main.h"
+
+/* The profiling data is recorded here, but is accessed via the profiling
+   mechanism.  After all, this is information for profiling.  */
+
+#if WITH_PROFILE_MODEL_P
+
+/* Model handlers for each insn.  */
+
+static int
+model_lm32_add (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_addi (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_and (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_andi (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_andhii (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_b (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_bi (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_bi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_be (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_bg (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_bge (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_bgeu (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_bgu (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_bne (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_call (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_calli (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_bi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpe (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpei (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpg (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpgi (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpge (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpgei (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpgeu (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpgeui (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpgu (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpgui (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpne (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_cmpnei (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_divu (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_lb (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_lbu (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_lh (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_lhu (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_lw (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_modu (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_mul (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_muli (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_nor (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_nori (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_or (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_ori (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_orhii (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_rcsr (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_rcsr.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sb (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sextb (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sexth (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sh (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sl (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sli (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sr (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sri (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sru (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_srui (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sub (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_sw (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_user (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_wcsr (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_wcsr.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_xor (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_xori (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_xnor (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_xnori (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_break (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+static int
+model_lm32_scall (SIM_CPU *current_cpu, void *sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  const ARGBUF * UNUSED abuf = SEM_ARGBUF ((SEM_ARG) sem_arg);
+  const IDESC * UNUSED idesc = abuf->idesc;
+  int cycles = 0;
+  {
+    int referenced = 0;
+    int UNUSED insn_referenced = abuf->written;
+    cycles += lm32bf_model_lm32_u_exec (current_cpu, idesc, 0, referenced);
+  }
+  return cycles;
+#undef FLD
+}
+
+/* We assume UNIT_NONE == 0 because the tables don't always terminate
+   entries with it.  */
+
+/* Model timing data for `lm32'.  */
+
+static const INSN_TIMING lm32_timing[] = {
+  { LM32BF_INSN_X_INVALID, 0, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_X_AFTER, 0, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_X_BEFORE, 0, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_X_CTI_CHAIN, 0, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_X_CHAIN, 0, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_X_BEGIN, 0, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_ADD, model_lm32_add, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_ADDI, model_lm32_addi, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_AND, model_lm32_and, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_ANDI, model_lm32_andi, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_ANDHII, model_lm32_andhii, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_B, model_lm32_b, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_BI, model_lm32_bi, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_BE, model_lm32_be, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_BG, model_lm32_bg, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_BGE, model_lm32_bge, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_BGEU, model_lm32_bgeu, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_BGU, model_lm32_bgu, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_BNE, model_lm32_bne, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CALL, model_lm32_call, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CALLI, model_lm32_calli, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPE, model_lm32_cmpe, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPEI, model_lm32_cmpei, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPG, model_lm32_cmpg, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPGI, model_lm32_cmpgi, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPGE, model_lm32_cmpge, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPGEI, model_lm32_cmpgei, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPGEU, model_lm32_cmpgeu, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPGEUI, model_lm32_cmpgeui, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPGU, model_lm32_cmpgu, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPGUI, model_lm32_cmpgui, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPNE, model_lm32_cmpne, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_CMPNEI, model_lm32_cmpnei, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_DIVU, model_lm32_divu, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_LB, model_lm32_lb, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_LBU, model_lm32_lbu, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_LH, model_lm32_lh, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_LHU, model_lm32_lhu, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_LW, model_lm32_lw, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_MODU, model_lm32_modu, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_MUL, model_lm32_mul, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_MULI, model_lm32_muli, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_NOR, model_lm32_nor, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_NORI, model_lm32_nori, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_OR, model_lm32_or, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_ORI, model_lm32_ori, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_ORHII, model_lm32_orhii, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_RCSR, model_lm32_rcsr, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SB, model_lm32_sb, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SEXTB, model_lm32_sextb, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SEXTH, model_lm32_sexth, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SH, model_lm32_sh, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SL, model_lm32_sl, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SLI, model_lm32_sli, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SR, model_lm32_sr, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SRI, model_lm32_sri, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SRU, model_lm32_sru, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SRUI, model_lm32_srui, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SUB, model_lm32_sub, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SW, model_lm32_sw, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_USER, model_lm32_user, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_WCSR, model_lm32_wcsr, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_XOR, model_lm32_xor, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_XORI, model_lm32_xori, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_XNOR, model_lm32_xnor, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_XNORI, model_lm32_xnori, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_BREAK, model_lm32_break, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+  { LM32BF_INSN_SCALL, model_lm32_scall, { { (int) UNIT_LM32_U_EXEC, 1, 1 } } },
+};
+
+#endif /* WITH_PROFILE_MODEL_P */
+
+static void
+lm32_model_init (SIM_CPU *cpu)
+{
+  CPU_MODEL_DATA (cpu) = (void *) zalloc (sizeof (MODEL_LM32_DATA));
+}
+
+#if WITH_PROFILE_MODEL_P
+#define TIMING_DATA(td) td
+#else
+#define TIMING_DATA(td) 0
+#endif
+
+static const MODEL lm32_models[] =
+{
+  { "lm32", & lm32_mach, MODEL_LM32, TIMING_DATA (& lm32_timing[0]), lm32_model_init },
+  { 0 }
+};
+
+/* The properties of this cpu's implementation.  */
+
+static const MACH_IMP_PROPERTIES lm32bf_imp_properties =
+{
+  sizeof (SIM_CPU),
+#if WITH_SCACHE
+  sizeof (SCACHE)
+#else
+  0
+#endif
+};
+
+
+static void
+lm32bf_prepare_run (SIM_CPU *cpu)
+{
+  if (CPU_IDESC (cpu) == NULL)
+    lm32bf_init_idesc_table (cpu);
+}
+
+static const CGEN_INSN *
+lm32bf_get_idata (SIM_CPU *cpu, int inum)
+{
+  return CPU_IDESC (cpu) [inum].idata;
+}
+
+static void
+lm32_init_cpu (SIM_CPU *cpu)
+{
+  CPU_REG_FETCH (cpu) = lm32bf_fetch_register;
+  CPU_REG_STORE (cpu) = lm32bf_store_register;
+  CPU_PC_FETCH (cpu) = lm32bf_h_pc_get;
+  CPU_PC_STORE (cpu) = lm32bf_h_pc_set;
+  CPU_GET_IDATA (cpu) = lm32bf_get_idata;
+  CPU_MAX_INSNS (cpu) = LM32BF_INSN__MAX;
+  CPU_INSN_NAME (cpu) = cgen_insn_name;
+  CPU_FULL_ENGINE_FN (cpu) = lm32bf_engine_run_full;
+#if WITH_FAST
+  CPU_FAST_ENGINE_FN (cpu) = lm32bf_engine_run_fast;
+#else
+  CPU_FAST_ENGINE_FN (cpu) = lm32bf_engine_run_full;
+#endif
+}
+
+const MACH lm32_mach =
+{
+  "lm32", "lm32", MACH_LM32,
+  32, 32, & lm32_models[0], & lm32bf_imp_properties,
+  lm32_init_cpu,
+  lm32bf_prepare_run
+};
+
Index: sim/lm32/sem-switch.c
===================================================================
RCS file: sim/lm32/sem-switch.c
diff -N sim/lm32/sem-switch.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/sem-switch.c	15 Apr 2009 17:41:27 -0000
@@ -0,0 +1,1554 @@
+/* Simulator instruction semantics for lm32bf.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifdef DEFINE_LABELS
+
+  /* The labels have the case they have because the enum of insn types
+     is all uppercase and in the non-stdc case the insn symbol is built
+     into the enum name.  */
+
+  static struct {
+    int index;
+    void *label;
+  } labels[] = {
+    { LM32BF_INSN_X_INVALID, && case_sem_INSN_X_INVALID },
+    { LM32BF_INSN_X_AFTER, && case_sem_INSN_X_AFTER },
+    { LM32BF_INSN_X_BEFORE, && case_sem_INSN_X_BEFORE },
+    { LM32BF_INSN_X_CTI_CHAIN, && case_sem_INSN_X_CTI_CHAIN },
+    { LM32BF_INSN_X_CHAIN, && case_sem_INSN_X_CHAIN },
+    { LM32BF_INSN_X_BEGIN, && case_sem_INSN_X_BEGIN },
+    { LM32BF_INSN_ADD, && case_sem_INSN_ADD },
+    { LM32BF_INSN_ADDI, && case_sem_INSN_ADDI },
+    { LM32BF_INSN_AND, && case_sem_INSN_AND },
+    { LM32BF_INSN_ANDI, && case_sem_INSN_ANDI },
+    { LM32BF_INSN_ANDHII, && case_sem_INSN_ANDHII },
+    { LM32BF_INSN_B, && case_sem_INSN_B },
+    { LM32BF_INSN_BI, && case_sem_INSN_BI },
+    { LM32BF_INSN_BE, && case_sem_INSN_BE },
+    { LM32BF_INSN_BG, && case_sem_INSN_BG },
+    { LM32BF_INSN_BGE, && case_sem_INSN_BGE },
+    { LM32BF_INSN_BGEU, && case_sem_INSN_BGEU },
+    { LM32BF_INSN_BGU, && case_sem_INSN_BGU },
+    { LM32BF_INSN_BNE, && case_sem_INSN_BNE },
+    { LM32BF_INSN_CALL, && case_sem_INSN_CALL },
+    { LM32BF_INSN_CALLI, && case_sem_INSN_CALLI },
+    { LM32BF_INSN_CMPE, && case_sem_INSN_CMPE },
+    { LM32BF_INSN_CMPEI, && case_sem_INSN_CMPEI },
+    { LM32BF_INSN_CMPG, && case_sem_INSN_CMPG },
+    { LM32BF_INSN_CMPGI, && case_sem_INSN_CMPGI },
+    { LM32BF_INSN_CMPGE, && case_sem_INSN_CMPGE },
+    { LM32BF_INSN_CMPGEI, && case_sem_INSN_CMPGEI },
+    { LM32BF_INSN_CMPGEU, && case_sem_INSN_CMPGEU },
+    { LM32BF_INSN_CMPGEUI, && case_sem_INSN_CMPGEUI },
+    { LM32BF_INSN_CMPGU, && case_sem_INSN_CMPGU },
+    { LM32BF_INSN_CMPGUI, && case_sem_INSN_CMPGUI },
+    { LM32BF_INSN_CMPNE, && case_sem_INSN_CMPNE },
+    { LM32BF_INSN_CMPNEI, && case_sem_INSN_CMPNEI },
+    { LM32BF_INSN_DIVU, && case_sem_INSN_DIVU },
+    { LM32BF_INSN_LB, && case_sem_INSN_LB },
+    { LM32BF_INSN_LBU, && case_sem_INSN_LBU },
+    { LM32BF_INSN_LH, && case_sem_INSN_LH },
+    { LM32BF_INSN_LHU, && case_sem_INSN_LHU },
+    { LM32BF_INSN_LW, && case_sem_INSN_LW },
+    { LM32BF_INSN_MODU, && case_sem_INSN_MODU },
+    { LM32BF_INSN_MUL, && case_sem_INSN_MUL },
+    { LM32BF_INSN_MULI, && case_sem_INSN_MULI },
+    { LM32BF_INSN_NOR, && case_sem_INSN_NOR },
+    { LM32BF_INSN_NORI, && case_sem_INSN_NORI },
+    { LM32BF_INSN_OR, && case_sem_INSN_OR },
+    { LM32BF_INSN_ORI, && case_sem_INSN_ORI },
+    { LM32BF_INSN_ORHII, && case_sem_INSN_ORHII },
+    { LM32BF_INSN_RCSR, && case_sem_INSN_RCSR },
+    { LM32BF_INSN_SB, && case_sem_INSN_SB },
+    { LM32BF_INSN_SEXTB, && case_sem_INSN_SEXTB },
+    { LM32BF_INSN_SEXTH, && case_sem_INSN_SEXTH },
+    { LM32BF_INSN_SH, && case_sem_INSN_SH },
+    { LM32BF_INSN_SL, && case_sem_INSN_SL },
+    { LM32BF_INSN_SLI, && case_sem_INSN_SLI },
+    { LM32BF_INSN_SR, && case_sem_INSN_SR },
+    { LM32BF_INSN_SRI, && case_sem_INSN_SRI },
+    { LM32BF_INSN_SRU, && case_sem_INSN_SRU },
+    { LM32BF_INSN_SRUI, && case_sem_INSN_SRUI },
+    { LM32BF_INSN_SUB, && case_sem_INSN_SUB },
+    { LM32BF_INSN_SW, && case_sem_INSN_SW },
+    { LM32BF_INSN_USER, && case_sem_INSN_USER },
+    { LM32BF_INSN_WCSR, && case_sem_INSN_WCSR },
+    { LM32BF_INSN_XOR, && case_sem_INSN_XOR },
+    { LM32BF_INSN_XORI, && case_sem_INSN_XORI },
+    { LM32BF_INSN_XNOR, && case_sem_INSN_XNOR },
+    { LM32BF_INSN_XNORI, && case_sem_INSN_XNORI },
+    { LM32BF_INSN_BREAK, && case_sem_INSN_BREAK },
+    { LM32BF_INSN_SCALL, && case_sem_INSN_SCALL },
+    { 0, 0 }
+  };
+  int i;
+
+  for (i = 0; labels[i].label != 0; ++i)
+    {
+#if FAST_P
+      CPU_IDESC (current_cpu) [labels[i].index].sem_fast_lab = labels[i].label;
+#else
+      CPU_IDESC (current_cpu) [labels[i].index].sem_full_lab = labels[i].label;
+#endif
+    }
+
+#undef DEFINE_LABELS
+#endif /* DEFINE_LABELS */
+
+#ifdef DEFINE_SWITCH
+
+/* If hyper-fast [well not unnecessarily slow] execution is selected, turn
+   off frills like tracing and profiling.  */
+/* FIXME: A better way would be to have TRACE_RESULT check for something
+   that can cause it to be optimized out.  Another way would be to emit
+   special handlers into the instruction "stream".  */
+
+#if FAST_P
+#undef TRACE_RESULT
+#define TRACE_RESULT(cpu, abuf, name, type, val)
+#endif
+
+#undef GET_ATTR
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#define GET_ATTR(cpu, num, attr) CGEN_ATTR_VALUE (NULL, abuf->idesc->attrs, CGEN_INSN_##attr)
+#else
+#define GET_ATTR(cpu, num, attr) CGEN_ATTR_VALUE (NULL, abuf->idesc->attrs, CGEN_INSN_/**/attr)
+#endif
+
+{
+
+#if WITH_SCACHE_PBB
+
+/* Branch to next handler without going around main loop.  */
+#define NEXT(vpc) goto * SEM_ARGBUF (vpc) -> semantic.sem_case
+SWITCH (sem, SEM_ARGBUF (vpc) -> semantic.sem_case)
+
+#else /* ! WITH_SCACHE_PBB */
+
+#define NEXT(vpc) BREAK (sem)
+#ifdef __GNUC__
+#if FAST_P
+  SWITCH (sem, SEM_ARGBUF (sc) -> idesc->sem_fast_lab)
+#else
+  SWITCH (sem, SEM_ARGBUF (sc) -> idesc->sem_full_lab)
+#endif
+#else
+  SWITCH (sem, SEM_ARGBUF (sc) -> idesc->num)
+#endif
+
+#endif /* ! WITH_SCACHE_PBB */
+
+    {
+
+  CASE (sem, INSN_X_INVALID) : /* --invalid-- */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.fmt_empty.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+    /* Update the recorded pc in the cpu state struct.
+       Only necessary for WITH_SCACHE case, but to avoid the
+       conditional compilation ....  */
+    SET_H_PC (pc);
+    /* Virtual insns have zero size.  Overwrite vpc with address of next insn
+       using the default-insn-bitsize spec.  When executing insns in parallel
+       we may want to queue the fault and continue execution.  */
+    vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+    vpc = sim_engine_invalid_insn (current_cpu, pc, vpc);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_X_AFTER) : /* --after-- */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.fmt_empty.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+    lm32bf_pbb_after (current_cpu, sem_arg);
+#endif
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_X_BEFORE) : /* --before-- */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.fmt_empty.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+    lm32bf_pbb_before (current_cpu, sem_arg);
+#endif
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_X_CTI_CHAIN) : /* --cti-chain-- */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.fmt_empty.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+#ifdef DEFINE_SWITCH
+    vpc = lm32bf_pbb_cti_chain (current_cpu, sem_arg,
+			       pbb_br_type, pbb_br_npc);
+    BREAK (sem);
+#else
+    /* FIXME: Allow provision of explicit ifmt spec in insn spec.  */
+    vpc = lm32bf_pbb_cti_chain (current_cpu, sem_arg,
+			       CPU_PBB_BR_TYPE (current_cpu),
+			       CPU_PBB_BR_NPC (current_cpu));
+#endif
+#endif
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_X_CHAIN) : /* --chain-- */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.fmt_empty.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+    vpc = lm32bf_pbb_chain (current_cpu, sem_arg);
+#ifdef DEFINE_SWITCH
+    BREAK (sem);
+#endif
+#endif
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_X_BEGIN) : /* --begin-- */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.fmt_empty.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+#if defined DEFINE_SWITCH || defined FAST_P
+    /* In the switch case FAST_P is a constant, allowing several optimizations
+       in any called inline functions.  */
+    vpc = lm32bf_pbb_begin (current_cpu, FAST_P);
+#else
+#if 0 /* cgen engine can't handle dynamic fast/full switching yet.  */
+    vpc = lm32bf_pbb_begin (current_cpu, STATE_RUN_FAST_P (CPU_STATE (current_cpu)));
+#else
+    vpc = lm32bf_pbb_begin (current_cpu, 0);
+#endif
+#endif
+#endif
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_ADD) : /* add $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ADDSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_ADDI) : /* addi $r1,$r0,$imm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_AND) : /* and $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ANDSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_ANDI) : /* andi $r1,$r0,$uimm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_andi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ANDSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_ANDHII) : /* andhi $r1,$r0,$hi16 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_andi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ANDSI (CPU (h_gr[FLD (f_r0)]), SLLSI (FLD (f_uimm), 16));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_B) : /* b $r0 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_be.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_b_insn (current_cpu, CPU (h_gr[FLD (f_r0)]), FLD (f_r0));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_BI) : /* bi $call */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_bi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = EXTSISI (FLD (i_call));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_BE) : /* be $r0,$r1,$branch */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_be.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (EQSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_BG) : /* bg $r0,$r1,$branch */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_be.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (GTSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_BGE) : /* bge $r0,$r1,$branch */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_be.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (GESI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_BGEU) : /* bgeu $r0,$r1,$branch */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_be.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (GEUSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_BGU) : /* bgu $r0,$r1,$branch */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_be.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (GTUSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_BNE) : /* bne $r0,$r1,$branch */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_be.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (NESI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CALL) : /* call $r0 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_be.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+{
+  {
+    SI opval = ADDSI (pc, 4);
+    CPU (h_gr[((UINT) 29)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+  {
+    USI opval = CPU (h_gr[FLD (f_r0)]);
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CALLI) : /* calli $call */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_bi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+{
+  {
+    SI opval = ADDSI (pc, 4);
+    CPU (h_gr[((UINT) 29)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+  {
+    USI opval = EXTSISI (FLD (i_call));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPE) : /* cmpe $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EQSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPEI) : /* cmpei $r1,$r0,$imm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EQSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPG) : /* cmpg $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GTSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPGI) : /* cmpgi $r1,$r0,$imm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GTSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPGE) : /* cmpge $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GESI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPGEI) : /* cmpgei $r1,$r0,$imm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GESI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPGEU) : /* cmpgeu $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GEUSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPGEUI) : /* cmpgeui $r1,$r0,$uimm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_andi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GEUSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPGU) : /* cmpgu $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GTUSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPGUI) : /* cmpgui $r1,$r0,$uimm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_andi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GTUSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPNE) : /* cmpne $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = NESI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_CMPNEI) : /* cmpnei $r1,$r0,$imm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = NESI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_DIVU) : /* divu $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_divu_insn (current_cpu, pc, FLD (f_r0), FLD (f_r1), FLD (f_r2));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_LB) : /* lb $r1,($r0+$imm) */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EXTQISI (GETMEMQI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_LBU) : /* lbu $r1,($r0+$imm) */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ZEXTQISI (GETMEMQI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_LH) : /* lh $r1,($r0+$imm) */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EXTHISI (GETMEMHI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_LHU) : /* lhu $r1,($r0+$imm) */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ZEXTHISI (GETMEMHI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_LW) : /* lw $r1,($r0+$imm) */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GETMEMSI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm)))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_MODU) : /* modu $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_modu_insn (current_cpu, pc, FLD (f_r0), FLD (f_r1), FLD (f_r2));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_MUL) : /* mul $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = MULSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_MULI) : /* muli $r1,$r0,$imm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = MULSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_NOR) : /* nor $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = INVSI (ORSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)])));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_NORI) : /* nori $r1,$r0,$uimm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_andi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = INVSI (ORSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_OR) : /* or $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ORSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_ORI) : /* ori $r1,$r0,$lo16 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_andi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ORSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_ORHII) : /* orhi $r1,$r0,$hi16 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_andi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ORSI (CPU (h_gr[FLD (f_r0)]), SLLSI (FLD (f_uimm), 16));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_RCSR) : /* rcsr $r2,$csr */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_rcsr.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = CPU (h_csr[FLD (f_csr)]);
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SB) : /* sb ($r0+$imm),$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    QI opval = CPU (h_gr[FLD (f_r1)]);
+    SETMEMQI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm)))), opval);
+    TRACE_RESULT (current_cpu, abuf, "memory", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SEXTB) : /* sextb $r2,$r0 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EXTQISI (TRUNCSIQI (CPU (h_gr[FLD (f_r0)])));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SEXTH) : /* sexth $r2,$r0 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EXTHISI (TRUNCSIHI (CPU (h_gr[FLD (f_r0)])));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SH) : /* sh ($r0+$imm),$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    HI opval = CPU (h_gr[FLD (f_r1)]);
+    SETMEMHI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm)))), opval);
+    TRACE_RESULT (current_cpu, abuf, "memory", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SL) : /* sl $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SLLSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SLI) : /* sli $r1,$r0,$imm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SLLSI (CPU (h_gr[FLD (f_r0)]), FLD (f_imm));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SR) : /* sr $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SRASI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SRI) : /* sri $r1,$r0,$imm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SRASI (CPU (h_gr[FLD (f_r0)]), FLD (f_imm));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SRU) : /* sru $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SRLSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SRUI) : /* srui $r1,$r0,$imm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SRLSI (CPU (h_gr[FLD (f_r0)]), FLD (f_imm));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SUB) : /* sub $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SUBSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SW) : /* sw ($r0+$imm),$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_addi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = CPU (h_gr[FLD (f_r1)]);
+    SETMEMSI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm)))), opval);
+    TRACE_RESULT (current_cpu, abuf, "memory", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_USER) : /* user $r2,$r0,$r1,$user */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = lm32bf_user_insn (current_cpu, CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]), FLD (f_user));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_WCSR) : /* wcsr $csr,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_wcsr.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+lm32bf_wcsr_insn (current_cpu, FLD (f_csr), CPU (h_gr[FLD (f_r1)]));
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_XOR) : /* xor $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = XORSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_XORI) : /* xori $r1,$r0,$uimm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_andi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = XORSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_XNOR) : /* xnor $r2,$r0,$r1 */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_user.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = INVSI (XORSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)])));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_XNORI) : /* xnori $r1,$r0,$uimm */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.sfmt_andi.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = INVSI (XORSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_BREAK) : /* break */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.fmt_empty.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_break_insn (current_cpu, pc);
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+  CASE (sem, INSN_SCALL) : /* scall */
+{
+  SEM_ARG sem_arg = SEM_SEM_ARG (vpc, sc);
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+#define FLD(f) abuf->fields.fmt_empty.f
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_scall_insn (current_cpu, pc);
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+#undef FLD
+}
+  NEXT (vpc);
+
+
+    }
+  ENDSWITCH (sem) /* End of semantic switch.  */
+
+  /* At this point `vpc' contains the next insn to execute.  */
+}
+
+#undef DEFINE_SWITCH
+#endif /* DEFINE_SWITCH */
Index: sim/lm32/sem.c
===================================================================
RCS file: sim/lm32/sem.c
diff -N sim/lm32/sem.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/sem.c	15 Apr 2009 17:41:27 -0000
@@ -0,0 +1,1669 @@
+/* Simulator instruction semantics for lm32bf.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright 1996-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU simulators.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#define WANT_CPU lm32bf
+#define WANT_CPU_LM32BF
+
+#include "sim-main.h"
+#include "cgen-mem.h"
+#include "cgen-ops.h"
+
+#undef GET_ATTR
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#define GET_ATTR(cpu, num, attr) CGEN_ATTR_VALUE (NULL, abuf->idesc->attrs, CGEN_INSN_##attr)
+#else
+#define GET_ATTR(cpu, num, attr) CGEN_ATTR_VALUE (NULL, abuf->idesc->attrs, CGEN_INSN_/**/attr)
+#endif
+
+/* This is used so that we can compile two copies of the semantic code,
+   one with full feature support and one without that runs fast(er).
+   FAST_P, when desired, is defined on the command line, -DFAST_P=1.  */
+#if FAST_P
+#define SEM_FN_NAME(cpu,fn) XCONCAT3 (cpu,_semf_,fn)
+#undef TRACE_RESULT
+#define TRACE_RESULT(cpu, abuf, name, type, val)
+#else
+#define SEM_FN_NAME(cpu,fn) XCONCAT3 (cpu,_sem_,fn)
+#endif
+
+/* x-invalid: --invalid-- */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,x_invalid) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+    /* Update the recorded pc in the cpu state struct.
+       Only necessary for WITH_SCACHE case, but to avoid the
+       conditional compilation ....  */
+    SET_H_PC (pc);
+    /* Virtual insns have zero size.  Overwrite vpc with address of next insn
+       using the default-insn-bitsize spec.  When executing insns in parallel
+       we may want to queue the fault and continue execution.  */
+    vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+    vpc = sim_engine_invalid_insn (current_cpu, pc, vpc);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* x-after: --after-- */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,x_after) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+    lm32bf_pbb_after (current_cpu, sem_arg);
+#endif
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* x-before: --before-- */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,x_before) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+    lm32bf_pbb_before (current_cpu, sem_arg);
+#endif
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* x-cti-chain: --cti-chain-- */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,x_cti_chain) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+#ifdef DEFINE_SWITCH
+    vpc = lm32bf_pbb_cti_chain (current_cpu, sem_arg,
+			       pbb_br_type, pbb_br_npc);
+    BREAK (sem);
+#else
+    /* FIXME: Allow provision of explicit ifmt spec in insn spec.  */
+    vpc = lm32bf_pbb_cti_chain (current_cpu, sem_arg,
+			       CPU_PBB_BR_TYPE (current_cpu),
+			       CPU_PBB_BR_NPC (current_cpu));
+#endif
+#endif
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* x-chain: --chain-- */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,x_chain) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+    vpc = lm32bf_pbb_chain (current_cpu, sem_arg);
+#ifdef DEFINE_SWITCH
+    BREAK (sem);
+#endif
+#endif
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* x-begin: --begin-- */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,x_begin) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 0);
+
+  {
+#if WITH_SCACHE_PBB_LM32BF
+#if defined DEFINE_SWITCH || defined FAST_P
+    /* In the switch case FAST_P is a constant, allowing several optimizations
+       in any called inline functions.  */
+    vpc = lm32bf_pbb_begin (current_cpu, FAST_P);
+#else
+#if 0 /* cgen engine can't handle dynamic fast/full switching yet.  */
+    vpc = lm32bf_pbb_begin (current_cpu, STATE_RUN_FAST_P (CPU_STATE (current_cpu)));
+#else
+    vpc = lm32bf_pbb_begin (current_cpu, 0);
+#endif
+#endif
+#endif
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* add: add $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,add) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ADDSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* addi: addi $r1,$r0,$imm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,addi) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* and: and $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,and) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ANDSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* andi: andi $r1,$r0,$uimm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,andi) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ANDSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* andhii: andhi $r1,$r0,$hi16 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,andhii) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ANDSI (CPU (h_gr[FLD (f_r0)]), SLLSI (FLD (f_uimm), 16));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* b: b $r0 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,b) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_b_insn (current_cpu, CPU (h_gr[FLD (f_r0)]), FLD (f_r0));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* bi: bi $call */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,bi) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_bi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = EXTSISI (FLD (i_call));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* be: be $r0,$r1,$branch */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,be) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (EQSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* bg: bg $r0,$r1,$branch */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,bg) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (GTSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* bge: bge $r0,$r1,$branch */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,bge) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (GESI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* bgeu: bgeu $r0,$r1,$branch */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,bgeu) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (GEUSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* bgu: bgu $r0,$r1,$branch */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,bgu) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (GTUSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* bne: bne $r0,$r1,$branch */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,bne) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+if (NESI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]))) {
+  {
+    USI opval = FLD (i_branch);
+    SEM_BRANCH_VIA_CACHE (current_cpu, sem_arg, opval, vpc);
+    written |= (1 << 3);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  abuf->written = written;
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* call: call $r0 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,call) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_be.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+{
+  {
+    SI opval = ADDSI (pc, 4);
+    CPU (h_gr[((UINT) 29)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+  {
+    USI opval = CPU (h_gr[FLD (f_r0)]);
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* calli: calli $call */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,calli) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_bi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+{
+  {
+    SI opval = ADDSI (pc, 4);
+    CPU (h_gr[((UINT) 29)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+  {
+    USI opval = EXTSISI (FLD (i_call));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+}
+
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* cmpe: cmpe $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpe) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EQSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpei: cmpei $r1,$r0,$imm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpei) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EQSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpg: cmpg $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpg) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GTSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpgi: cmpgi $r1,$r0,$imm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpgi) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GTSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpge: cmpge $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpge) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GESI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpgei: cmpgei $r1,$r0,$imm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpgei) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GESI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpgeu: cmpgeu $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpgeu) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GEUSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpgeui: cmpgeui $r1,$r0,$uimm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpgeui) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GEUSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpgu: cmpgu $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpgu) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GTUSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpgui: cmpgui $r1,$r0,$uimm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpgui) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GTUSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpne: cmpne $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpne) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = NESI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* cmpnei: cmpnei $r1,$r0,$imm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,cmpnei) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = NESI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* divu: divu $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,divu) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_divu_insn (current_cpu, pc, FLD (f_r0), FLD (f_r1), FLD (f_r2));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* lb: lb $r1,($r0+$imm) */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,lb) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EXTQISI (GETMEMQI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* lbu: lbu $r1,($r0+$imm) */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,lbu) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ZEXTQISI (GETMEMQI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* lh: lh $r1,($r0+$imm) */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,lh) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EXTHISI (GETMEMHI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* lhu: lhu $r1,($r0+$imm) */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,lhu) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ZEXTHISI (GETMEMHI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* lw: lw $r1,($r0+$imm) */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,lw) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = GETMEMSI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm)))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* modu: modu $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,modu) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_modu_insn (current_cpu, pc, FLD (f_r0), FLD (f_r1), FLD (f_r2));
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* mul: mul $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,mul) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = MULSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* muli: muli $r1,$r0,$imm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,muli) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = MULSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* nor: nor $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,nor) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = INVSI (ORSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)])));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* nori: nori $r1,$r0,$uimm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,nori) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = INVSI (ORSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* or: or $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,or) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ORSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* ori: ori $r1,$r0,$lo16 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,ori) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ORSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* orhii: orhi $r1,$r0,$hi16 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,orhii) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = ORSI (CPU (h_gr[FLD (f_r0)]), SLLSI (FLD (f_uimm), 16));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* rcsr: rcsr $r2,$csr */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,rcsr) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_rcsr.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = CPU (h_csr[FLD (f_csr)]);
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sb: sb ($r0+$imm),$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sb) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    QI opval = CPU (h_gr[FLD (f_r1)]);
+    SETMEMQI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm)))), opval);
+    TRACE_RESULT (current_cpu, abuf, "memory", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sextb: sextb $r2,$r0 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sextb) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EXTQISI (TRUNCSIQI (CPU (h_gr[FLD (f_r0)])));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sexth: sexth $r2,$r0 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sexth) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = EXTHISI (TRUNCSIHI (CPU (h_gr[FLD (f_r0)])));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sh: sh ($r0+$imm),$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sh) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    HI opval = CPU (h_gr[FLD (f_r1)]);
+    SETMEMHI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm)))), opval);
+    TRACE_RESULT (current_cpu, abuf, "memory", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sl: sl $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sl) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SLLSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sli: sli $r1,$r0,$imm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sli) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SLLSI (CPU (h_gr[FLD (f_r0)]), FLD (f_imm));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sr: sr $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sr) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SRASI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sri: sri $r1,$r0,$imm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sri) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SRASI (CPU (h_gr[FLD (f_r0)]), FLD (f_imm));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sru: sru $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sru) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SRLSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* srui: srui $r1,$r0,$imm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,srui) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SRLSI (CPU (h_gr[FLD (f_r0)]), FLD (f_imm));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sub: sub $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sub) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = SUBSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* sw: sw ($r0+$imm),$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,sw) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_addi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = CPU (h_gr[FLD (f_r1)]);
+    SETMEMSI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm)))), opval);
+    TRACE_RESULT (current_cpu, abuf, "memory", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* user: user $r2,$r0,$r1,$user */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,user) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = lm32bf_user_insn (current_cpu, CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]), FLD (f_user));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* wcsr: wcsr $csr,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,wcsr) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_wcsr.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+lm32bf_wcsr_insn (current_cpu, FLD (f_csr), CPU (h_gr[FLD (f_r1)]));
+
+  return vpc;
+#undef FLD
+}
+
+/* xor: xor $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,xor) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = XORSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)]));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* xori: xori $r1,$r0,$uimm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,xori) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = XORSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm)));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* xnor: xnor $r2,$r0,$r1 */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,xnor) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_user.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = INVSI (XORSI (CPU (h_gr[FLD (f_r0)]), CPU (h_gr[FLD (f_r1)])));
+    CPU (h_gr[FLD (f_r2)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* xnori: xnori $r1,$r0,$uimm */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,xnori) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.sfmt_andi.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    SI opval = INVSI (XORSI (CPU (h_gr[FLD (f_r0)]), ZEXTSISI (FLD (f_uimm))));
+    CPU (h_gr[FLD (f_r1)]) = opval;
+    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
+  }
+
+  return vpc;
+#undef FLD
+}
+
+/* break: break */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,break) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_break_insn (current_cpu, pc);
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* scall: scall */
+
+static SEM_PC
+SEM_FN_NAME (lm32bf,scall) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
+{
+#define FLD(f) abuf->fields.fmt_empty.f
+  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
+  int UNUSED written = 0;
+  IADDR UNUSED pc = abuf->addr;
+  SEM_BRANCH_INIT
+  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);
+
+  {
+    USI opval = lm32bf_scall_insn (current_cpu, pc);
+    SEM_BRANCH_VIA_ADDR (current_cpu, sem_arg, opval, vpc);
+    TRACE_RESULT (current_cpu, abuf, "pc", 'x', opval);
+  }
+
+  SEM_BRANCH_FINI (vpc);
+  return vpc;
+#undef FLD
+}
+
+/* Table of all semantic fns.  */
+
+static const struct sem_fn_desc sem_fns[] = {
+  { LM32BF_INSN_X_INVALID, SEM_FN_NAME (lm32bf,x_invalid) },
+  { LM32BF_INSN_X_AFTER, SEM_FN_NAME (lm32bf,x_after) },
+  { LM32BF_INSN_X_BEFORE, SEM_FN_NAME (lm32bf,x_before) },
+  { LM32BF_INSN_X_CTI_CHAIN, SEM_FN_NAME (lm32bf,x_cti_chain) },
+  { LM32BF_INSN_X_CHAIN, SEM_FN_NAME (lm32bf,x_chain) },
+  { LM32BF_INSN_X_BEGIN, SEM_FN_NAME (lm32bf,x_begin) },
+  { LM32BF_INSN_ADD, SEM_FN_NAME (lm32bf,add) },
+  { LM32BF_INSN_ADDI, SEM_FN_NAME (lm32bf,addi) },
+  { LM32BF_INSN_AND, SEM_FN_NAME (lm32bf,and) },
+  { LM32BF_INSN_ANDI, SEM_FN_NAME (lm32bf,andi) },
+  { LM32BF_INSN_ANDHII, SEM_FN_NAME (lm32bf,andhii) },
+  { LM32BF_INSN_B, SEM_FN_NAME (lm32bf,b) },
+  { LM32BF_INSN_BI, SEM_FN_NAME (lm32bf,bi) },
+  { LM32BF_INSN_BE, SEM_FN_NAME (lm32bf,be) },
+  { LM32BF_INSN_BG, SEM_FN_NAME (lm32bf,bg) },
+  { LM32BF_INSN_BGE, SEM_FN_NAME (lm32bf,bge) },
+  { LM32BF_INSN_BGEU, SEM_FN_NAME (lm32bf,bgeu) },
+  { LM32BF_INSN_BGU, SEM_FN_NAME (lm32bf,bgu) },
+  { LM32BF_INSN_BNE, SEM_FN_NAME (lm32bf,bne) },
+  { LM32BF_INSN_CALL, SEM_FN_NAME (lm32bf,call) },
+  { LM32BF_INSN_CALLI, SEM_FN_NAME (lm32bf,calli) },
+  { LM32BF_INSN_CMPE, SEM_FN_NAME (lm32bf,cmpe) },
+  { LM32BF_INSN_CMPEI, SEM_FN_NAME (lm32bf,cmpei) },
+  { LM32BF_INSN_CMPG, SEM_FN_NAME (lm32bf,cmpg) },
+  { LM32BF_INSN_CMPGI, SEM_FN_NAME (lm32bf,cmpgi) },
+  { LM32BF_INSN_CMPGE, SEM_FN_NAME (lm32bf,cmpge) },
+  { LM32BF_INSN_CMPGEI, SEM_FN_NAME (lm32bf,cmpgei) },
+  { LM32BF_INSN_CMPGEU, SEM_FN_NAME (lm32bf,cmpgeu) },
+  { LM32BF_INSN_CMPGEUI, SEM_FN_NAME (lm32bf,cmpgeui) },
+  { LM32BF_INSN_CMPGU, SEM_FN_NAME (lm32bf,cmpgu) },
+  { LM32BF_INSN_CMPGUI, SEM_FN_NAME (lm32bf,cmpgui) },
+  { LM32BF_INSN_CMPNE, SEM_FN_NAME (lm32bf,cmpne) },
+  { LM32BF_INSN_CMPNEI, SEM_FN_NAME (lm32bf,cmpnei) },
+  { LM32BF_INSN_DIVU, SEM_FN_NAME (lm32bf,divu) },
+  { LM32BF_INSN_LB, SEM_FN_NAME (lm32bf,lb) },
+  { LM32BF_INSN_LBU, SEM_FN_NAME (lm32bf,lbu) },
+  { LM32BF_INSN_LH, SEM_FN_NAME (lm32bf,lh) },
+  { LM32BF_INSN_LHU, SEM_FN_NAME (lm32bf,lhu) },
+  { LM32BF_INSN_LW, SEM_FN_NAME (lm32bf,lw) },
+  { LM32BF_INSN_MODU, SEM_FN_NAME (lm32bf,modu) },
+  { LM32BF_INSN_MUL, SEM_FN_NAME (lm32bf,mul) },
+  { LM32BF_INSN_MULI, SEM_FN_NAME (lm32bf,muli) },
+  { LM32BF_INSN_NOR, SEM_FN_NAME (lm32bf,nor) },
+  { LM32BF_INSN_NORI, SEM_FN_NAME (lm32bf,nori) },
+  { LM32BF_INSN_OR, SEM_FN_NAME (lm32bf,or) },
+  { LM32BF_INSN_ORI, SEM_FN_NAME (lm32bf,ori) },
+  { LM32BF_INSN_ORHII, SEM_FN_NAME (lm32bf,orhii) },
+  { LM32BF_INSN_RCSR, SEM_FN_NAME (lm32bf,rcsr) },
+  { LM32BF_INSN_SB, SEM_FN_NAME (lm32bf,sb) },
+  { LM32BF_INSN_SEXTB, SEM_FN_NAME (lm32bf,sextb) },
+  { LM32BF_INSN_SEXTH, SEM_FN_NAME (lm32bf,sexth) },
+  { LM32BF_INSN_SH, SEM_FN_NAME (lm32bf,sh) },
+  { LM32BF_INSN_SL, SEM_FN_NAME (lm32bf,sl) },
+  { LM32BF_INSN_SLI, SEM_FN_NAME (lm32bf,sli) },
+  { LM32BF_INSN_SR, SEM_FN_NAME (lm32bf,sr) },
+  { LM32BF_INSN_SRI, SEM_FN_NAME (lm32bf,sri) },
+  { LM32BF_INSN_SRU, SEM_FN_NAME (lm32bf,sru) },
+  { LM32BF_INSN_SRUI, SEM_FN_NAME (lm32bf,srui) },
+  { LM32BF_INSN_SUB, SEM_FN_NAME (lm32bf,sub) },
+  { LM32BF_INSN_SW, SEM_FN_NAME (lm32bf,sw) },
+  { LM32BF_INSN_USER, SEM_FN_NAME (lm32bf,user) },
+  { LM32BF_INSN_WCSR, SEM_FN_NAME (lm32bf,wcsr) },
+  { LM32BF_INSN_XOR, SEM_FN_NAME (lm32bf,xor) },
+  { LM32BF_INSN_XORI, SEM_FN_NAME (lm32bf,xori) },
+  { LM32BF_INSN_XNOR, SEM_FN_NAME (lm32bf,xnor) },
+  { LM32BF_INSN_XNORI, SEM_FN_NAME (lm32bf,xnori) },
+  { LM32BF_INSN_BREAK, SEM_FN_NAME (lm32bf,break) },
+  { LM32BF_INSN_SCALL, SEM_FN_NAME (lm32bf,scall) },
+  { 0, 0 }
+};
+
+/* Add the semantic fns to IDESC_TABLE.  */
+
+void
+SEM_FN_NAME (lm32bf,init_idesc_table) (SIM_CPU *current_cpu)
+{
+  IDESC *idesc_table = CPU_IDESC (current_cpu);
+  const struct sem_fn_desc *sf;
+  int mach_num = MACH_NUM (CPU_MACH (current_cpu));
+
+  for (sf = &sem_fns[0]; sf->fn != 0; ++sf)
+    {
+      const CGEN_INSN *insn = idesc_table[sf->index].idata;
+      int valid_p = (CGEN_INSN_VIRTUAL_P (insn)
+		     || CGEN_INSN_MACH_HAS_P (insn, mach_num));
+#if FAST_P
+      if (valid_p)
+	idesc_table[sf->index].sem_fast = sf->fn;
+      else
+	idesc_table[sf->index].sem_fast = SEM_FN_NAME (lm32bf,x_invalid);
+#else
+      if (valid_p)
+	idesc_table[sf->index].sem_full = sf->fn;
+      else
+	idesc_table[sf->index].sem_full = SEM_FN_NAME (lm32bf,x_invalid);
+#endif
+    }
+}
+
Index: sim/lm32/sim-if.c
===================================================================
RCS file: sim/lm32/sim-if.c
diff -N sim/lm32/sim-if.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/sim-if.c	15 Apr 2009 17:41:28 -0000
@@ -0,0 +1,290 @@
+/* Main simulator entry points specific to Lattice Mico32.
+   Contributed by Jon Beniston <jon@beniston.com>
+   
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "sim-main.h"
+#include "sim-options.h"
+#include "libiberty.h"
+#include "bfd.h"
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+static void free_state (SIM_DESC);
+static void print_lm32_misc_cpu (SIM_CPU * cpu, int verbose);
+static DECLARE_OPTION_HANDLER (lm32_option_handler);
+
+enum
+{
+  OPTION_ENDIAN = OPTION_START,
+};
+
+/* GDB passes -E, even though it's fixed, so we have to handle it here. common code only handles it if SIM_HAVE_BIENDIAN is defined, which it isn't for lm32.  */
+static const OPTION lm32_options[] = {
+  {{"endian", required_argument, NULL, OPTION_ENDIAN},
+   'E', "big", "Set endianness",
+   lm32_option_handler},
+  {{NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL}
+};
+
+/* Records simulator descriptor so utilities like lm32_dump_regs can be
+   called from gdb.  */
+SIM_DESC current_state;
+\f
+/* Cover function of sim_state_free to free the cpu buffers as well.  */
+
+static void
+free_state (SIM_DESC sd)
+{
+  if (STATE_MODULES (sd) != NULL)
+    sim_module_uninstall (sd);
+  sim_cpu_free_all (sd);
+  sim_state_free (sd);
+}
+
+/* Find memory range used by program.  */
+
+static unsigned long
+find_base (bfd *prog_bfd)
+{
+  int found;
+  unsigned long base = ~(0UL);
+  asection *s;
+
+  found = 0;
+  for (s = prog_bfd->sections; s; s = s->next)
+    {
+      if ((strcmp (bfd_get_section_name (prog_bfd, s), ".boot") == 0)
+	  || (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
+	  || (strcmp (bfd_get_section_name (prog_bfd, s), ".data") == 0)
+	  || (strcmp (bfd_get_section_name (prog_bfd, s), ".bss") == 0))
+	{
+	  if (!found)
+	    {
+	      base = bfd_get_section_vma (prog_bfd, s);
+	      found = 1;
+	    }
+	  else
+	    base =
+	      bfd_get_section_vma (prog_bfd,
+				   s) < base ? bfd_get_section_vma (prog_bfd,
+								    s) : base;
+	}
+    }
+  return base & ~(0xffffUL);
+}
+
+static unsigned long
+find_limit (bfd *prog_bfd)
+{
+  struct bfd_symbol **asymbols;
+  long symsize;
+  long symbol_count;
+  long s;
+
+  symsize = bfd_get_symtab_upper_bound (prog_bfd);
+  if (symsize < 0)
+    return 0;
+  asymbols = (asymbol **) xmalloc (symsize);
+  symbol_count = bfd_canonicalize_symtab (prog_bfd, asymbols);
+  if (symbol_count < 0)
+    return 0;
+
+  for (s = 0; s < symbol_count; s++)
+    {
+      if (!strcmp (asymbols[s]->name, "_fstack"))
+	return (asymbols[s]->value + 65536) & ~(0xffffUL);
+    }
+  return 0;
+}
+
+/* Handle lm32 specific options.  */
+
+static SIM_RC
+lm32_option_handler (sd, cpu, opt, arg, is_command)
+     SIM_DESC sd;
+     sim_cpu *cpu;
+     int opt;
+     char *arg;
+     int is_command;
+{
+  return SIM_RC_OK;
+}
+
+/* Create an instance of the simulator.  */
+
+SIM_DESC
+sim_open (kind, callback, abfd, argv)
+     SIM_OPEN_KIND kind;
+     host_callback *callback;
+     struct bfd *abfd;
+     char **argv;
+{
+  SIM_DESC sd = sim_state_alloc (kind, callback);
+  char c;
+  int i;
+  unsigned long base, limit;
+
+  /* The cpu data is kept in a separately allocated chunk of memory.  */
+  if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
+
+  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
+  sim_add_option_table (sd, NULL, lm32_options);
+
+  /* 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;
+    }
+
+#if 0
+  /* Allocate a handler for I/O devices
+     if no memory for that range has been allocated by the user.
+     All are allocated in one chunk to keep things from being
+     unnecessarily complicated.  */
+  if (sim_core_read_buffer (sd, NULL, read_map, &c, LM32_DEVICE_ADDR, 1) == 0)
+    sim_core_attach (sd, NULL, 0 /*level */ ,
+		     access_read_write, 0 /*space ??? */ ,
+		     LM32_DEVICE_ADDR, LM32_DEVICE_LEN /*nr_bytes */ ,
+		     0 /*modulo */ ,
+		     &lm32_devices, NULL /*buffer */ );
+#endif
+
+  /* check for/establish the 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;
+    }
+
+  /* Check to see if memory exists at programs start address.  */
+  if (sim_core_read_buffer (sd, NULL, read_map, &c, STATE_START_ADDR (sd), 1)
+      == 0)
+    {
+      if (STATE_PROG_BFD (sd) != NULL)
+	{
+	  /* It doesn't, so we should try to allocate enough memory to hold program.  */
+	  base = find_base (STATE_PROG_BFD (sd));
+	  limit = find_limit (STATE_PROG_BFD (sd));
+	  if (limit == 0)
+	    {
+	      sim_io_eprintf (sd,
+			      "Failed to find symbol _fstack in program. You must specify memory regions with --memory-region.\n");
+	      free_state (sd);
+	      return 0;
+	    }
+	  /*sim_io_printf (sd, "Allocating memory at 0x%x size 0x%x\n", base, limit); */
+	  sim_do_commandf (sd, "memory region 0x%x,0x%x", base, limit);
+	}
+    }
+
+  /* Establish any remaining configuration options.  */
+  if (sim_config (sd) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
+
+  if (sim_post_argv_init (sd) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 0;
+    }
+
+  /* Open a copy of the cpu descriptor table.  */
+  {
+    CGEN_CPU_DESC cd =
+      lm32_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
+			    CGEN_ENDIAN_BIG);
+    for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+      {
+	SIM_CPU *cpu = STATE_CPU (sd, i);
+	CPU_CPU_DESC (cpu) = cd;
+	CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
+      }
+    lm32_cgen_init_dis (cd);
+  }
+
+  /* Initialize various cgen things not done by common framework.
+     Must be done after lm32_cgen_cpu_open.  */
+  cgen_init (sd);
+
+  /* Store in a global so things like lm32_dump_regs can be invoked
+     from the gdb command line.  */
+  current_state = sd;
+
+  return sd;
+}
+
+void
+sim_close (sd, quitting)
+     SIM_DESC sd;
+     int quitting;
+{
+  lm32_cgen_cpu_close (CPU_CPU_DESC (STATE_CPU (sd, 0)));
+  sim_module_uninstall (sd);
+}
+\f
+SIM_RC
+sim_create_inferior (sd, abfd, argv, envp)
+     SIM_DESC sd;
+     struct bfd *abfd;
+     char **argv;
+     char **envp;
+{
+  SIM_CPU *current_cpu = STATE_CPU (sd, 0);
+  SIM_ADDR addr;
+
+  if (abfd != NULL)
+    addr = bfd_get_start_address (abfd);
+  else
+    addr = 0;
+  sim_pc_set (current_cpu, addr);
+
+#if 0
+  STATE_ARGV (sd) = sim_copy_argv (argv);
+  STATE_ENVP (sd) = sim_copy_argv (envp);
+#endif
+
+  return SIM_RC_OK;
+}
+
+void
+sim_do_command (sd, cmd)
+     SIM_DESC sd;
+     char *cmd;
+{
+  if (sim_args_command (sd, cmd) != SIM_RC_OK)
+    sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
+}
Index: sim/lm32/sim-main.h
===================================================================
RCS file: sim/lm32/sim-main.h
diff -N sim/lm32/sim-main.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/sim-main.h	15 Apr 2009 17:41:28 -0000
@@ -0,0 +1,102 @@
+/* Lattice Mico32 simulator support code
+   Contributed by Jon Beniston <jon@beniston.com>
+
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+/* Main header for the LM32 simulator.  */
+
+#ifndef SIM_MAIN_H
+#define SIM_MAIN_H
+
+#define USING_SIM_BASE_H	/* FIXME: quick hack */
+
+struct _sim_cpu;		/* FIXME: should be in sim-basics.h */
+typedef struct _sim_cpu SIM_CPU;
+
+#include "symcat.h"
+#include "sim-basics.h"
+#include "cgen-types.h"
+#include "lm32-desc.h"
+#include "lm32-opc.h"
+#include "arch.h"
+
+/* These must be defined before sim-base.h.  */
+typedef USI sim_cia;
+
+#define CIA_GET(cpu)     CPU_PC_GET (cpu)
+#define CIA_SET(cpu,val) CPU_PC_SET ((cpu), (val))
+
+#define SIM_ENGINE_HALT_HOOK(sd, cpu, cia) \
+do { \
+  if (cpu) /* null if ctrl-c */ \
+    sim_pc_set ((cpu), (cia)); \
+} while (0)
+#define SIM_ENGINE_RESTART_HOOK(sd, cpu, cia) \
+do { \
+  sim_pc_set ((cpu), (cia)); \
+} while (0)
+
+#include "sim-base.h"
+#include "cgen-sim.h"
+#include "lm32-sim.h"
+#include "opcode/cgen.h"
+\f
+/* The _sim_cpu struct.  */
+
+struct _sim_cpu
+{
+  /* sim/common cpu base.  */
+  sim_cpu_base base;
+
+  /* Static parts of cgen.  */
+  CGEN_CPU cgen_cpu;
+
+  /* CPU specific parts go here.
+     Note that in files that don't need to access these pieces WANT_CPU_FOO
+     won't be defined and thus these parts won't appear.  This is ok in the
+     sense that things work.  It is a source of bugs though.
+     One has to of course be careful to not take the size of this
+     struct and no structure members accessed in non-cpu specific files can
+     go after here.  Oh for a better language.  */
+#if defined (WANT_CPU_LM32BF)
+  LM32BF_CPU_DATA cpu_data;
+#endif
+
+};
+\f
+/* The sim_state struct.  */
+
+struct sim_state
+{
+  sim_cpu *cpu;
+#define STATE_CPU(sd, n) (/*&*/ (sd)->cpu)
+
+  CGEN_STATE cgen_state;
+
+  sim_state_base base;
+};
+\f
+/* Misc.  */
+
+/* Catch address exceptions.  */
+extern SIM_CORE_SIGNAL_FN lm32_core_signal;
+#define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
+lm32_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), \
+		  (TRANSFER), (ERROR))
+
+#endif /* SIM_MAIN_H */
Index: sim/lm32/tconfig.in
===================================================================
RCS file: sim/lm32/tconfig.in
diff -N sim/lm32/tconfig.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/tconfig.in	15 Apr 2009 17:41:28 -0000
@@ -0,0 +1,27 @@
+/* Lattice Mico32 simulator configuration.
+   Contributed by Jon Beniston <jon@beniston.com>
+
+   This file is part of GDB.
+
+   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 LM32_TCONFIG_H
+#define LM32_TCONFIG_H
+
+/* See sim-hload.c.  We properly handle LMA.  */
+#define SIM_HANDLES_LMA 1
+
+#define WITH_SCACHE_PBB 1
+
+#endif /* LM32_TCONFIG_H */
Index: sim/lm32/traps.c
===================================================================
RCS file: sim/lm32/traps.c
diff -N sim/lm32/traps.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/traps.c	15 Apr 2009 17:41:28 -0000
@@ -0,0 +1,268 @@
+/* Lattice Mico32 exception and system call support.
+   Contributed by Jon Beniston <jon@beniston.com>
+
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#define WANT_CPU lm32bf
+#define WANT_CPU_LM32BF
+
+#include "sim-main.h"
+#include "lm32-sim.h"
+#include "targ-vals.h"
+
+/* Read memory function for system call interface.  */
+
+static int
+syscall_read_mem (host_callback * cb, struct cb_syscall *sc,
+		  unsigned long taddr, char *buf, int bytes)
+{
+  SIM_DESC sd = (SIM_DESC) sc->p1;
+  SIM_CPU *cpu = (SIM_CPU *) sc->p2;
+
+  return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
+}
+
+/* Write memory function for system call interface.  */
+
+static int
+syscall_write_mem (host_callback * cb, struct cb_syscall *sc,
+		   unsigned long taddr, const char *buf, int bytes)
+{
+  SIM_DESC sd = (SIM_DESC) sc->p1;
+  SIM_CPU *cpu = (SIM_CPU *) sc->p2;
+
+  return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
+}
+
+/* Handle invalid instructions.  */
+
+SEM_PC
+sim_engine_invalid_insn (SIM_CPU * current_cpu, IADDR cia, SEM_PC pc)
+{
+  SIM_DESC sd = CPU_STATE (current_cpu);
+
+  sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
+
+  return pc;
+}
+
+/* Handle divide instructions. */
+
+USI
+lm32bf_divu_insn (SIM_CPU * current_cpu, IADDR pc, USI r0, USI r1, USI r2)
+{
+  SIM_DESC sd = CPU_STATE (current_cpu);
+  host_callback *cb = STATE_CALLBACK (sd);
+
+  /* Check for divide by zero */
+  if (GET_H_GR (r1) == 0)
+    {
+      if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
+	sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGFPE);
+      else
+	{
+	  /* Save PC in exception address register.  */
+	  SET_H_GR (30, pc);
+	  /* Save and clear interrupt enable.  */
+	  SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
+	  /* Branch to divide by zero exception handler.  */
+	  return GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DIVIDE_BY_ZERO * 32;
+	}
+    }
+  else
+    {
+      SET_H_GR (r2, (USI) GET_H_GR (r0) / (USI) GET_H_GR (r1));
+      return pc + 4;
+    }
+}
+
+USI
+lm32bf_modu_insn (SIM_CPU * current_cpu, IADDR pc, USI r0, USI r1, USI r2)
+{
+  SIM_DESC sd = CPU_STATE (current_cpu);
+  host_callback *cb = STATE_CALLBACK (sd);
+
+  /* Check for divide by zero.  */
+  if (GET_H_GR (r1) == 0)
+    {
+      if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
+	sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGFPE);
+      else
+	{
+	  /* Save PC in exception address register.  */
+	  SET_H_GR (30, pc);
+	  /* Save and clear interrupt enable.  */
+	  SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
+	  /* Branch to divide by zero exception handler.  */
+	  return GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DIVIDE_BY_ZERO * 32;
+	}
+    }
+  else
+    {
+      SET_H_GR (r2, (USI) GET_H_GR (r0) % (USI) GET_H_GR (r1));
+      return pc + 4;
+    }
+}
+
+/* Handle break instructions.  */
+
+USI
+lm32bf_break_insn (SIM_CPU * current_cpu, IADDR pc)
+{
+  SIM_DESC sd = CPU_STATE (current_cpu);
+  host_callback *cb = STATE_CALLBACK (sd);
+  /* Breakpoint.  */
+  if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
+    {
+      sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
+      return pc;
+    }
+  else
+    {
+      /* Save PC in breakpoint address register.  */
+      SET_H_GR (31, pc);
+      /* Save and clear interrupt enable.  */
+      SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 2);
+      /* Branch to breakpoint exception handler.  */
+      return GET_H_CSR (LM32_CSR_DEBA) + LM32_EID_BREAKPOINT * 32;
+    }
+}
+
+/* Handle scall instructions.  */
+
+USI
+lm32bf_scall_insn (SIM_CPU * current_cpu, IADDR pc)
+{
+  SIM_DESC sd = CPU_STATE (current_cpu);
+  host_callback *cb = STATE_CALLBACK (sd);
+
+  if ((STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
+      || (GET_H_GR (8) == TARGET_SYS_exit))
+    {
+      /* Delegate system call to host O/S.  */
+      CB_SYSCALL s;
+      CB_SYSCALL_INIT (&s);
+      s.p1 = (PTR) sd;
+      s.p2 = (PTR) current_cpu;
+      s.read_mem = syscall_read_mem;
+      s.write_mem = syscall_write_mem;
+      /* Extract parameters.  */
+      s.func = GET_H_GR (8);
+      s.arg1 = GET_H_GR (1);
+      s.arg2 = GET_H_GR (2);
+      s.arg3 = GET_H_GR (3);
+      /* Halt the simulator if the requested system call is _exit.  */
+      if (s.func == TARGET_SYS_exit)
+	sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
+      /* Perform the system call.  */
+      cb_syscall (cb, &s);
+      /* Store the return value in the CPU's registers.  */
+      SET_H_GR (1, s.result);
+      SET_H_GR (2, s.result2);
+      SET_H_GR (3, s.errcode);
+      /* Skip over scall instruction.  */
+      return pc + 4;
+    }
+  else
+    {
+      /* Save PC in exception address register.  */
+      SET_H_GR (30, pc);
+      /* Save and clear interrupt enable */
+      SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
+      /* Branch to system call exception handler.  */
+      return GET_H_CSR (LM32_CSR_EBA) + LM32_EID_SYSTEM_CALL * 32;
+    }
+}
+
+/* Handle b instructions.  */
+
+USI
+lm32bf_b_insn (SIM_CPU * current_cpu, USI r0, USI f_r0)
+{
+  SIM_DESC sd = CPU_STATE (current_cpu);
+  host_callback *cb = STATE_CALLBACK (sd);
+
+  /* Restore interrupt enable.  */
+  if (f_r0 == 30)
+    SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 2) >> 1);
+  else if (f_r0 == 31)
+    SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 4) >> 2);
+  return r0;
+}
+
+/* Handle wcsr instructions.  */
+
+void
+lm32bf_wcsr_insn (SIM_CPU * current_cpu, USI f_csr, USI r1)
+{
+  SIM_DESC sd = CPU_STATE (current_cpu);
+  host_callback *cb = STATE_CALLBACK (sd);
+
+  /* Writing a 1 to IP CSR clears a bit, writing 0 has no effect.  */
+  if (f_csr == LM32_CSR_IP)
+    SET_H_CSR (f_csr, GET_H_CSR (f_csr) & ~r1);
+  else
+    SET_H_CSR (f_csr, r1);
+}
+
+/* Handle signals.  */
+
+void
+lm32_core_signal (SIM_DESC sd,
+		  sim_cpu * cpu,
+		  sim_cia cia,
+		  unsigned map,
+		  int nr_bytes,
+		  address_word addr,
+		  transfer_type transfer, sim_core_signals sig)
+{
+  const char *copy = (transfer == read_transfer ? "read" : "write");
+  address_word ip = CIA_ADDR (cia);
+  SIM_CPU *current_cpu = cpu;
+
+  switch (sig)
+    {
+    case sim_core_unmapped_signal:
+      sim_io_eprintf (sd,
+		      "core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
+		      nr_bytes, copy, (unsigned long) addr,
+		      (unsigned long) ip);
+      SET_H_GR (30, ip);
+      /* Save and clear interrupt enable.  */
+      SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
+      CIA_SET (cpu, GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DATA_BUS_ERROR * 32);
+      sim_engine_halt (sd, cpu, NULL, LM32_EID_DATA_BUS_ERROR * 32,
+		       sim_stopped, SIM_SIGSEGV);
+      break;
+    case sim_core_unaligned_signal:
+      sim_io_eprintf (sd,
+		      "core: %d byte misaligned %s to address 0x%lx at 0x%lx\n",
+		      nr_bytes, copy, (unsigned long) addr,
+		      (unsigned long) ip);
+      SET_H_GR (30, ip);
+      /* Save and clear interrupt enable.  */
+      SET_H_CSR (LM32_CSR_IE, (GET_H_CSR (LM32_CSR_IE) & 1) << 1);
+      CIA_SET (cpu, GET_H_CSR (LM32_CSR_EBA) + LM32_EID_DATA_BUS_ERROR * 32);
+      sim_engine_halt (sd, cpu, NULL, LM32_EID_DATA_BUS_ERROR * 32,
+		       sim_stopped, SIM_SIGBUS);
+      break;
+    default:
+      sim_engine_abort (sd, cpu, cia,
+			"sim_core_signal - internal error - bad switch");
+    }
+}
Index: sim/lm32/user.c
===================================================================
RCS file: sim/lm32/user.c
diff -N sim/lm32/user.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sim/lm32/user.c	15 Apr 2009 17:41:28 -0000
@@ -0,0 +1,30 @@
+/* Semantics for user defined instructions on the Lattice Mico32.
+   Contributed by Jon Beniston <jon@beniston.com>
+
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "sim-main.h"
+
+/* Handle user defined instructions.  */
+
+UINT
+lm32bf_user_insn (SIM_CPU * current_cpu, INT r0, INT r1, UINT imm)
+{
+  /* FIXME: Should probably call code in a user supplied library.  */
+  return 0;
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-04-15 18:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-15 18:12 [PATCH] Add LM32 simulator Jon Beniston

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox