From: "Jon Beniston" <jon@beniston.com>
To: <gdb-patches@sourceware.org>
Subject: [PATCH] Add LM32 simulator
Date: Wed, 15 Apr 2009 18:12:00 -0000 [thread overview]
Message-ID: <3762C4436985466E996FB66FD085FF56@bibi> (raw)
[-- 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, ®))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+ hw_unit_address_to_attach_address (hw_parent (me),
+ ®.address,
+ &attach_space, &attach_address, me);
+ timers->base = attach_address;
+ hw_unit_size_to_attach_size (hw_parent (me), ®.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, ®))
+ hw_abort (me, "\"reg\" property must contain three addr/size entries");
+ hw_unit_address_to_attach_address (hw_parent (me),
+ ®.address,
+ &attach_space, &attach_address, me);
+ uart->base = attach_address;
+ hw_unit_size_to_attach_size (hw_parent (me), ®.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;
+}
reply other threads:[~2009-04-15 18:12 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3762C4436985466E996FB66FD085FF56@bibi \
--to=jon@beniston.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox