Inline most things except semantics which causes GCC to balloon, and device{s,_tree...
authorMichael Meissner <gnu@the-meissners.org>
Thu, 12 Oct 1995 15:48:22 +0000 (15:48 +0000)
committerMichael Meissner <gnu@the-meissners.org>
Thu, 12 Oct 1995 15:48:22 +0000 (15:48 +0000)
sim/ppc/ChangeLog
sim/ppc/Makefile.in
sim/ppc/devices.c
sim/ppc/devices.h
sim/ppc/std-config.h [new file with mode: 0644]

index f4afa11ed7a01439cdf0ce714a8ab67fe26138d6..5e657ed6ad69d9603961748b98e6c313c4043aff 100644 (file)
@@ -1,3 +1,106 @@
+Thu Oct 12 11:35:53 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+       * Makefile.in (INLINE_CFLAGS): Add -DDEFAULT_INLINE=2 to add
+       default inline support.  Pass INLINE_CFLAGS when compiling.
+
+       * devices.{h,c} (unimp_device_ioctl): Use STATIC_DEVICES, not
+       INLINE_DEVICES since GCC doesn't like inline functions that
+       accept variable arguments.
+       (stack_ioctl_callback): Make function just static because GCC
+       doesn't like inline functions that accept variable arguments.
+
+       * devices.h (STATIC_DEVICES): Define as empty if not defined.
+
+       * inline.c: Correct pathnames of included C files to match current
+       implementation.
+
+       * inline.h (STATIC_DEVICES): If DEVICES_INLINE is defined to be
+       non-zero, define STATIC_DEVICES to be static.
+
+       * std-config.h (INLINE): If GNU C and optimizing, define this as
+       __inline__.
+       (DEFAULT_INLINE): If not defined, define as 0.
+       (ENDIAN_INLINE): If not defined, define as DEFAULT_INLINE.
+       ({CORE,VM,CPU,EVENTS,REGISTERS,INTERRUPTS}_INLINE): Ditto.
+       ({SPREG,IDECODE}_INLINE): Ditto.        
+       
+Wed Oct 11 17:13:15 1995  Andrew Cagney  <cagney@kremvax>
+
+        * ppc-instructions: Initial cut of floating point suport added.
+       Of note include - use of host IEEE floating point instructions,
+       use of PowerPC manual pseudo code to handle the FPSCR.  It is not
+       currently a pretty sight.
+       
+       * memory_map.h, memory_map.c, memory_map_n.h, core.h, core.c:
+       merge into core.h, core.c, core_n.h. The type memory_map replaced
+       with core_map.  This removes a level of pointer indirection when
+       translating an address.
+
+       * memory_map.h, memory_map.c, memory_map_n.h: delete.
+
+       * Makefile.in et.al (sorry): tweek to use new core, core_map and
+       core.h.
+       
+Wed Oct 11 12:10:26 1995  Andrew Cagney  <cagney@kremvax>
+
+       * sim_calls.c, main.c: Add -g (trace_gdb) option, add tracing to
+       most of the other functions in sim_calls.c.
+
+       * basics.h (CONCAT3), memory_map.c, memory_map_n.h, Makefile.in:
+       Add macros to better cover up `generic' code.  Makes it possible
+       to step through the generic code!
+
+       * vm.c, vm_n.h, Makefile.in: ditto
+       
+Tue Oct 10 15:42:59 1995  Andrew Cagney  <cagney@kremvax>
+
+       * devices.h, devices.c, memory_map.h, memory_map.c: Changed
+       callback interface so that there is a read/write buffer but no
+       read/write_word.  VEA default memory read/write handler sometimes
+       couldn't resolve an access and of those some were for a memory
+       fault and some were because gdb was making a bogus request.
+
+       * devices.h, devices.c, memory_map.h, memory_map.c, vm.h, vm.c:
+       eliminate transfer_mode (raw or cooked) parameter from read/write
+       buffer.
+       
+Fri Oct  6 20:23:56 1995  Andrew Cagney  <cagney@kremvax>
+
+       * ppc-instructions (fmul, fmuls): correct instruction format - had
+       FRB instead of FRC.
+
+Wed Oct  4 17:31:12 1995  Andrew Cagney  <cagney@kremvax>
+
+       * psim.c, device_tree.h, device_tree.c, devices.c (printd_*,
+       scand_*): new functions to parse/print fields in device names
+       while hiding any machine dependency.
+
+       * devices.c, psim.c: Change the stack init code so that it is
+       handled by a device.  Arguments passed across using a device ioctl
+       (hack).
+
+       * devices.h, devices.c: device ioctl callback changed to allow a
+       variable number of arguments.  This gives greater flexability and
+       greater chance of bugs.
+
+Tue Oct  3 22:01:56 1995  Andrew Cagney - aka Noid  <cagney@kremvax>
+
+       * main.c (printf_filtered, error): Missing va_end() to close off
+        variable argument use.
+
+       * Makefile.in (tmp-gencode): comment out hack to get around some
+        versions of make not handling files being created as side-effects.
+
+       * gen.c (lf_open): Add -n (real_file_name) option.  Specifies an
+        alternative file name to use in output files for things like #line
+        macros.
+
+        Makefile.in (tmp-gencode): Use gen -n so that debug info is
+        correct.
+
+       * Makefile.in (TARGETLIB): Use this instead of libsim.a in the
+       Makefile.
+
 Sat Oct  7 22:40:59 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
 
        * sim_calls.c (sim_set_callbacks): Define new function.
index 4999db10811824e1096204e209e98224558e0206..c9b02e59369231d15d103d892c0d6a7ca66ba825 100644 (file)
@@ -18,6 +18,8 @@
 #   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #
 
+default: all
+
 VPATH = @srcdir@
 srcdir = @srcdir@
 srcroot = $(srcdir)/../..
@@ -77,15 +79,18 @@ INCLUDES    = -I. -I$(srcdir) $(LIB_INCLUDES) $(BFD_INCLUDES) $(GDB_INCLUDES)
 
 CONFIG_FILE    = std-config.h
 
+# See inline.h for appropriate flags to set
+INLINE_CFLAGS  = -DDEFAULT_INLINE=2
+
 LIBIBERTY_LIB  = ../../libiberty/libiberty.a
 BFD_LIB                = ../../bfd/libbfd.a
 
 TARGETLIB = libsim.a
 
-all:   run libsim.a $(GDB_OBJ)
+all:   run $(TARGETLIB) $(GDB_OBJ)
 
 .c.o:
-       $(CC) -c $(CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $<
+       $(CC) -c $(CFLAGS) $(INLINE_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $<
 
 
 
@@ -104,7 +109,6 @@ PSIM_H = \
 
 IDECODE_H = \
        idecode.h \
-       idecode_insn.h \
        idecode_expression.h \
        idecode_branch.h \
        idecode_fields.h \
@@ -119,7 +123,6 @@ CPU_H = \
        $(BASICS_H) \
        $(REGISTERS_H) \
        device_tree.h \
-       memory_map.h \
        core.h \
        vm.h \
        events.h \
@@ -145,7 +148,6 @@ LIB_SRC = \
        bits.c \
        ppc-endian.c \
        debug.c \
-       memory_map.c \
        vm.c \
        core.c \
        events.c \
@@ -167,7 +169,6 @@ LIB_OBJ = \
        ppc-endian.o \
        system.o \
        registers.o \
-       memory_map.o \
        vm.o \
        core.o \
        spreg.o \
@@ -184,14 +185,14 @@ LIB_OBJ = \
 GDB_OBJ = sim_calls.o 
 
 
-psim: libsim.a main.o $(LIBIBERTY_LIB) $(BFD_LIB) $(LIBS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -o psim main.o libsim.a $(BFD_LIB) $(LIBIBERTY_LIB) $(LIBS)
+psim: $(TARGETLIB) main.o $(LIBIBERTY_LIB) $(BFD_LIB) $(LIBS)
+       $(CC) $(CFLAGS) $(LDFLAGS) -o psim main.o $(TARGETLIB) $(BFD_LIB) $(LIBIBERTY_LIB) $(LIBS)
 
 run: psim
        rm -f run
        ln psim run
 
-libsim.a: $(BUILT_SRC) $(LIB_OBJ) $(GDB_OBJ)
+$(TARGETLIB): tmp-gencode $(LIB_OBJ) $(GDB_OBJ)
        rm -f $(TARGETLIB)
        $(AR) $(AR_FLAGS) $(TARGETLIB) $(LIB_OBJ) $(GDB_OBJ)
        $(RANLIB) $(TARGETLIB)
@@ -215,15 +216,12 @@ interrupts.o: interrupts.c $(CPU_H) $(IDECODE_H) system.h
 
 idecode.o: idecode.c $(CPU_H) $(IDECODE_H) semantics.h
 
-memory_map.o: memory_map.c memory_map.h $(BASICS_H) device_tree.h interrupts.h
-
 # double.o: double.c dp-bit.c
 
-vm.o: vm.c vm.h $(BASICS_H) $(REGISTERS_H) \
-       device_tree.h memory_map.h core.h interrupts.h
+vm.o: vm.c vm.h vm_n.h $(BASICS_H) $(REGISTERS_H) \
+       device_tree.h core.h interrupts.h
 
-core.o: core.c core.h $(BASICS_H) \
-       device_tree.h memory_map.h
+core.o: core.c core.h $(BASICS_H) device_tree.h
 
 events.o: events.c events.h $(BASICS_H) 
 
@@ -251,14 +249,14 @@ ppc-config.h: $(CONFIG_FILE)
 
 tmp-gencode: gen ppc-instructions ppc-spr-table $(srcdir)/../../move-if-change
        ./gen   -r $(srcdir)/ppc-spr-table \
-               -P tmp-spreg.h \
-               -p tmp-spreg.c \
                -i $(srcdir)/ppc-instructions \
-               -C tmp-icache.h \
-               -S tmp-semantics.h \
-               -s tmp-semantics.c \
-               -D tmp-idecode.h \
-               -d tmp-idecode.c
+               -n spreg.h     -P tmp-spreg.h \
+               -n spreg.c     -p tmp-spreg.c \
+               -n icache.h    -C tmp-icache.h \
+               -n semantics.h -S tmp-semantics.h \
+               -n semantics.c -s tmp-semantics.c \
+               -n idecode.h   -D tmp-idecode.h \
+               -n idecode.c   -d tmp-idecode.c
        $(srcdir)/../../move-if-change tmp-icache.h icache.h
        $(srcdir)/../../move-if-change tmp-idecode.h idecode.h
        $(srcdir)/../../move-if-change tmp-idecode.c idecode.c
@@ -268,7 +266,11 @@ tmp-gencode: gen ppc-instructions ppc-spr-table $(srcdir)/../../move-if-change
        $(srcdir)/../../move-if-change tmp-spreg.c spreg.c
        touch tmp-gencode
 
-icache.h idecode.h idecode.c semantics.h semantics.c spreg.h spreg.c: tmp-gencode
+# NOTE: Some versions of make don't handle files created as side-effects
+# uncomment the below if that is the case.
+#
+# $(TARGETLIB): tmp-gencode
+# icache.h idecode.h idecode.c semantics.h semantics.c spreg.h spreg.c: tmp-gencode
 
 gen.o: gen.c config.h ppc-config.h
        $(CC_FOR_BUILD) -c $(CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $(srcdir)/gen.c
@@ -286,7 +288,7 @@ TAGS: tmp-gencode config.h ppc-config.h
 clean mostlyclean:
        rm -f tmp-* *.[oas] core psim run gen config.log
 
-distclean realclean: clean
+distclean maintainer-clean realclean: clean
        rm -f TAGS $(BUILT_SRC) Makefile config.cache config.status config.h stamp-h
 
 Makefile: Makefile.in config.status
index 983b6934d82879a994c58d1533e5fcc186bc3506..6b4d94049613290fb138727b97d6cd2c6ddcf566 100644 (file)
@@ -189,7 +189,7 @@ unimp_device_interrupt_ack(const device *me,
   error("device_interrupt_ack_callback for %s not implemented\n", me->name);
 }
 
-INLINE_DEVICES void
+STATIC_DEVICES void
 unimp_device_ioctl(const device *me,
                   psim *system,
                   cpu *processor,
@@ -834,7 +834,7 @@ vm_io_write_buffer_callback(const device *me,
 }
 
 
-STATIC_INLINE_DEVICES void
+static void
 vm_ioctl_callback(const device *me,
                  psim *system,
                  cpu *processor,
@@ -1485,7 +1485,7 @@ create_aix_stack_frame(psim *system,
 
 
 
-STATIC_INLINE_DEVICES void
+static void
 stack_ioctl_callback(const device *me,
                     psim *system,
                     cpu *processor,
index 681992e1269f94d40f459f3761461356ef78c0ef..df02288d5163d88b0cc758d45507e01008da4c8b 100644 (file)
 #define INLINE_DEVICES
 #endif
 
+#ifndef STATIC_DEVICES
+#define STATIC_DEVICES
+#endif
+
 
 /* forward declaration of types */
 /* typedef struct _device device; -- in devices.h */
@@ -313,7 +317,7 @@ INLINE_DEVICES device_config_interrupt_callback unimp_device_attach_interrupt;
 INLINE_DEVICES device_config_interrupt_callback unimp_device_detach_interrupt;
 INLINE_DEVICES device_interrupt_callback unimp_device_interrupt;
 INLINE_DEVICES device_interrupt_ack_callback unimp_device_interrupt_ack;
-INLINE_DEVICES device_ioctl_callback unimp_device_ioctl;
+STATIC_DEVICES device_ioctl_callback unimp_device_ioctl;
 
 /* Pass through and ignore callback functions.  A call going towards
    the root device are passed on up, local calls are ignored and call
diff --git a/sim/ppc/std-config.h b/sim/ppc/std-config.h
new file mode 100644 (file)
index 0000000..07018bf
--- /dev/null
@@ -0,0 +1,772 @@
+/*  This file is part of the program psim.
+
+    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+
+    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 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, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+    */
+
+
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+
+/* endianness of the host/target:
+
+   If the build process is aware (at compile time) of the endianness
+   of the host/target it is able to eliminate slower generic endian
+   handling code.
+
+   If ENDIAN_OK is true then no byte swapping is required.  If it is
+   false, copy-in / copy-out functions assume that data should be byte
+   reversed as part of the copy. */
+
+#define WITH_HOST_BYTE_ORDER           0 /*unknown*/
+#define WITH_TARGET_BYTE_ORDER         0 /*unknown*/
+
+extern int current_host_byte_order;
+extern int current_target_byte_order;
+#define CURRENT_HOST_BYTE_ORDER (WITH_HOST_BYTE_ORDER \
+                                ? WITH_HOST_BYTE_ORDER \
+                                : current_host_byte_order)
+#define CURRENT_TARGET_BYTE_ORDER (WITH_TARGET_BYTE_ORDER \
+                                  ? WITH_TARGET_BYTE_ORDER \
+                                  : current_target_byte_order)
+
+
+/* SMP support:
+
+   Sets a limit on the number of processors that can be simulated.  If
+   WITH_SMP is set to zero (0), the simulator is restricted to
+   suporting only on processor (and as a consequence leaves the SMP
+   code out of the build process). */
+
+#ifndef WITH_SMP
+#define WITH_SMP                        0
+#endif
+
+
+/* Word size of host/target:
+
+   Set these according to your host and target requirements.  At this
+   point in time, I've only compiled (not run) for a 64bit and never
+   built for a 64bit host.  This will always remain a compile time
+   option */
+
+#ifndef WITH_TARGET_WORD_BITSIZE
+#define WITH_TARGET_WORD_BITSIZE        32 /* compiled only */
+#endif
+#ifndef WITH_HOST_WORD_BITSIZE
+#define WITH_HOST_WORD_BITSIZE         32 /* 64bit ready? */
+#endif
+
+
+/* Program environment:
+
+   Two environments are available. VEA (or virtual environment
+   architecture) and OEA (or operating environment architecture).  The
+   former is the environment that a user program would see while the
+   latter is the environment as seen by an operating system.  By
+   setting these to specific values, the build process is able to
+   eliminate non relevent environment code
+
+   CURRENT_ENVIRONMENT specifies which of vea or oea is required for
+   the current runtime. */
+
+#define WITH_ENVIRONMENT               0
+#define VIRTUAL_ENVIRONMENT            1
+#define OPERATING_ENVIRONMENT          2
+
+extern int current_environment;
+#define CURRENT_ENVIRONMENT (WITH_ENVIRONMENT \
+                            ? WITH_ENVIRONMENT \
+                            : current_environment)
+
+
+/* Optional VEA/OEA code: 
+
+   The below, required for the OEA model may also be included in the
+   VEA model however, as far as I can tell only make things
+   slower... */
+
+
+/* Events.  Devices modeling real H/W need to be able to efficiently
+   schedule things to do at known times in the future.  The event
+   queue implements this.  Unfortunatly this adds the need to check
+   for any events once each full instruction cycle. */
+
+#define WITH_EVENTS                     (WITH_ENVIRONMENT != VIRTUAL_ENVIRONMENT)
+
+
+/* Time base:
+
+   The PowerPC architecture includes the addition of both a time base
+   register and a decrement timer.  Like events adds to the overhead
+   of of some instruction cycles. */
+
+#ifndef WITH_TIME_BASE
+#define WITH_TIME_BASE                 1
+#endif
+
+
+/* Callback/Default Memory.
+
+   Core includes a builtin memory type (raw_memory) that is
+   implemented using an array.  raw_memory does not require any
+   additional functions etc.
+
+   Callback memory is where the core calls a core device for the data
+   it requires.
+
+   Default memory is an extenstion of this where for addresses that do
+   not map into either a callback or core memory range a default map
+   can be used.
+
+   The OEA model uses callback memory for devices and default memory
+   for buses.
+
+   The VEA model uses callback memory to capture `page faults'.
+
+   While it may be possible to eliminate callback/default memory (and
+   hence also eliminate an additional test per memory fetch) it
+   probably is not worth the effort.
+
+   BTW, while raw_memory could have been implemented as a callback,
+   profiling has shown that there is a biger win (at least for the
+   x86) in eliminating a function call for the most common
+   (raw_memory) case. */
+
+#define WITH_CALLBACK_MEMORY           1
+
+
+/* Alignment:
+
+   The PowerPC may or may not handle miss aligned transfers.  An
+   implementation normally handles miss aligned transfers in big
+   endian mode but generates an exception in little endian mode.
+
+   This model.  Instead allows both little and big endian modes to
+   either take exceptions or handle miss aligned transfers.
+
+   If 0 is specified then for big-endian mode miss alligned accesses
+   are permitted (NONSTRICT_ALIGNMENT) while in little-endian mode the
+   processor will fault on them (STRICT_ALIGNMENT). */
+
+#define NONSTRICT_ALIGNMENT                    1
+#define STRICT_ALIGNMENT               2
+
+#ifndef WITH_ALIGNMENT
+#define WITH_ALIGNMENT                 0
+#endif
+extern int current_alignment;
+#define CURRENT_ALIGNMENT (WITH_ALIGNMENT \
+                          ? WITH_ALIGNMENT \
+                          : current_alignment)
+
+
+/* Floating point suport:
+
+   Still under development. */
+
+#define SOFT_FLOATING_POINT            1
+#define HARD_FLOATING_POINT            2
+
+#ifndef WITH_FLOATING_POINT
+#define WITH_FLOATING_POINT            HARD_FLOATING_POINT
+#endif
+extern int current_floating_point;
+#define CURRENT_FLOATING_POINT (WITH_FLOATING_POINT \
+                               ? WITH_FLOATING_POINT \
+                               : current_floating_point)
+
+
+/* Debugging:
+
+   Control the inclusion of debugging code. */
+
+/* Include the tracing code.  Disabling this eliminates all tracing
+   code */
+
+#ifndef WITH_TRACE
+#define WITH_TRACE                      1
+#endif
+
+/* include code that checks assertions scattered through out the
+   program */
+
+#ifndef WITH_ASSERT
+#define WITH_ASSERT                    1
+#endif
+
+/* include profiling code that doesn't yet exist */
+
+#ifndef WITH_PROFILE
+#define WITH_PROFILE                   1
+#endif
+
+
+/* INSTRUCTION TABLE CODE GENERATION:
+
+   The program gen takes the files ppc.instructions and spr.table and
+   creates from them code that provides:
+
+   o   instruction decode and issue
+   o   spr information
+
+   The program gen does this according to the configuration
+   information that follows. */
+
+
+/* Line numbering of generated code:
+
+   When generating the semantic and idecode files, gen can also output
+   line number information (w.r.t. ppc.instructions).  It may be
+   useful to disable this if you suspect that gen.c is incorrectly
+   generating itermediate code files.  */
+
+#ifndef WITH_LINE_NUMBERS
+#define WITH_LINE_NUMBERS               1
+#endif
+
+
+/* Instruction cache:
+
+   Instead of the idecode routine calling the semantic function
+   directly, idecode can instead return a descriptor of the
+   instruction (cache entry).
+
+   With level one caching, idecode just returns the address of the
+   semantic function.  With level two caching, in addition to this,
+   the idecode routine decodes key fields within the instruction and
+   also enters them into the cache.  The table IDECODE_CACHE_RULES
+   controls what goes into the cache.*/
+
+#ifndef        WITH_IDECODE_CACHE
+#define WITH_IDECODE_CACHE              0
+#endif
+#ifndef        IDECODE_CACHE_SIZE
+#define IDECODE_CACHE_SIZE             1024
+#endif
+
+
+/* Semantic code expansion:
+
+   For a given instruction there is the potential to improve
+   performance bo creating copies of the instructions code for one or
+   more of its possible variations.  Eg branch being relative.  This
+   macro determines of semantic functions should be expanded.  How
+   well they are expanded is determined by the table
+   WITH_IDECODE_OPCODE_RULES. */
+
+#ifndef WITH_IDECODE_EXPAND_SEMANTICS
+#define WITH_IDECODE_EXPAND_SEMANTICS   0
+#endif
+
+
+/* SPR database:
+
+   The attributes of the SPR's are kept in a `lookup table'.  This
+   table can be implemented as either a true table or a switch
+   statement.
+
+   A swith statement may be a performance advantage if the SPR's are
+   known at compile time.  The compiler is then able to eliminate the
+   switch. */
+
+#ifndef WITH_SPREG_LOOKUP_TABLE
+#define WITH_SPREG_LOOKUP_TABLE         1
+#endif
+
+
+/* Instruction decode:
+
+   The table that follows is used by gen to construct a decision tree
+   that can identify each possible instruction.  Gen then outputs this
+   decision tree as (according to config) a table or switch statement
+   as the function idecode.
+
+   In parallel to this, as mentioned above, WITH_EXPANDED_SEMANTICS
+   determines of the semantic functions themselves should be expanded
+   in a similar way.
+
+   The table contains the following entries:
+
+   <valid>
+
+   Must be 1 for the entry to be considered.  The last entry must be
+   zero.
+       
+   <first>
+   <last>
+
+   Range of bits (within the instruction) that should be searched for
+   an instruction field.  Within such ranges, gen looks for opcodes
+   (constants), registers (strings) and reserved bits (slash) and
+   according to the rules that follows includes or excludes them from
+   a possible instruction field.
+
+   <force_first>
+   <force_last>
+
+   If an instructioin field was found, enlarge the field size so that
+   it is forced to at least include bits starting from <force_first>
+   (<force_last>).  To stop this occuring, use <force_first> = <last>
+   + 1 and <force_last> = <first> - 1.
+
+   <force_slash>
+
+   Treat `/' fields as a constant instead of variable when looking for
+   an instruction field.
+
+   <force_expansion>
+
+   Treat any contained register (string) fields as constant when
+   determining the instruction field.  For the instruction decode (and
+   controled by IDECODE_EXPAND_SEMANTICS) this forces the expansion of
+   what would otherwize be non constant bits of an instruction.
+
+   <use_switch>
+
+   Should this table be expanded using a switch statement (val 1) and
+   if so, should it be padded with entries so as to force the compiler
+   to generate a jump table (val 2).
+
+   <special_mask>
+   <special_value>
+   <special_rule>
+
+   Special rule to fine tune how specific (or groups) of instructions
+   are expanded.  The applicability of the rule is determined by
+
+     <special_mask> != 0 && (instruction> & <special_mask>) == <special_value>
+
+   Where <instruction> is obtained by looking only at constant fields
+   with in an instructions spec.  When determining an expansion, the
+   rule is only considered when a node contains a single instruction.
+   <special_rule> can be any of:
+
+        0: for this instruction, expand by earlier rules
+       1: expand bits <force_low> .. <force_hi> only
+       2: boolean expansion of only zero/non-zero cases
+
+   Ok? */
+
+
+#define WITH_IDECODE_OPCODE_RULES { \
+  { 1,  0,  5,  0,  5, 0, 0,                1, 0x00000000, 0x00000000, 0 }, \
+  { 1, 21, 31, 32, -1, 0, 0,                1, 0x00000000, 0x00000000, 0 }, \
+  { 0 } \
+}
+
+
+/* Instruction unpacking:
+
+   Once the instruction has been decoded, the register (and other)
+   fields within the instruction need to be extracted.
+
+   The table that follows determines how each field should be treated.
+   Importantly it considers the case where the extracted field is to
+   be used immediatly or stored in an instruction cache.
+
+   <valid>
+
+   Zero marks the end of the table.  More importantly 1. indicates
+   that the entry is valid and can be cached. 2. indicates that that
+   the entry is valid but can not be cached.
+
+   <old_name>
+
+   The field name as given in the instruction spec.
+
+   <new_name>
+
+   A name for <old_name> once it has been extracted from the
+   instructioin (and possibly stored in the instruction cache).
+
+   <type>
+
+   String specifying the storage type for <new_name> (the extracted
+   field>.
+
+   <expression>
+
+   Specifies how to get <new_name> from <old_name>.  If null, old and
+   new name had better be the same. */
+
+#define WITH_IDECODE_CACHE_RULES { \
+  { 1, "RA", "RA", 0, 0 }, \
+  { 1, "RA", "rA", "signed_word *", \
+      "(cpu_registers(processor)->gpr + RA)" }, \
+  { 1, "RT", "RT", 0, 0 }, \
+  { 1, "RT", "rT", "signed_word *", \
+      "(cpu_registers(processor)->gpr + RT)" }, \
+  { 2, "RS", "RS", 0, 0 }, \
+  { 1, "RS", "rS", "signed_word *", \
+      "(cpu_registers(processor)->gpr + RS)" }, \
+  { 2, "RB", "RB", 0, 0 }, \
+  { 1, "RB", "rB", "signed_word *", \
+      "(cpu_registers(processor)->gpr + RB)" }, \
+  { 2, "FRA", "FRA", 0, 0 }, \
+  { 1, "FRA", "frA", "unsigned64 *", \
+      "(cpu_registers(processor)->fpr + FRA)" }, \
+  { 2, "FRB", "FRB", 0, 0 }, \
+  { 1, "FRB", "frB", "unsigned64 *", \
+      "(cpu_registers(processor)->fpr + FRB)" }, \
+  { 2, "FRC", "FRC", 0, 0 }, \
+  { 1, "FRC", "frC", "unsigned64 *", \
+      "(cpu_registers(processor)->fpr + FRC)" }, \
+  { 2, "FRS", "FRS", 0, 0 }, \
+  { 1, "FRS", "frS", "unsigned64 *", \
+      "(cpu_registers(processor)->fpr + FRS)" }, \
+  { 2, "FRT", "FRT", 0, 0 }, \
+  { 1, "FRT", "frT", "unsigned64 *", \
+      "(cpu_registers(processor)->fpr + FRT)" }, \
+  { 1, "SI", "EXTS_SI", "unsigned_word", \
+      "((signed_word)(signed16)instruction)" }, \
+  { 2, "BI", "BI", 0, 0 }, \
+  { 1, "BI", "BIT32_BI", 0, \
+      "BIT32(BI)" }, \
+  { 2, "BA", "BA", 0, 0 }, \
+  { 1, "BA", "BIT32_BA", 0, \
+       "BIT32(BA)" }, \
+  { 2, "BB", "BB", 0, 0 }, \
+  { 1, "BB", "BIT32_BB", 0, \
+      "BIT32(BB)" }, \
+  { 1, "BD", "EXTS_BD_0b00", "unsigned_word", \
+      "(((signed_word)(signed16)instruction) & ~3)" }, \
+/*{ 1, "BD", "CIA_plus_EXTS_BD_0b00", "unsigned_word", */ \
+/*    "CIA + EXTS(BD_0b00)" }, */ \
+  { 1, "LI", "EXTS_LI_0b00", "unsigned_word", \
+      "((((signed_word)(signed32)(instruction << 6)) >> 6) & ~0x3)" }, \
+  { 1, "D", "EXTS_D", "unsigned_word", \
+      "((signed_word)(signed16)(instruction))" }, \
+  { 1, "DS", "EXTS_DS_0b00", "unsigned_word", \
+      "(((signed_word)(signed16)instruction) & ~0x3)" }, \
+  { 0 } \
+};
+
+
+
+/* INLINE CODE SELECTION:
+
+   GCC -O3 attempts to inline any function or procedure in scope.  The
+   options below facilitate fine grained control over what is and what
+   isn't made inline.  For instance it can control things down to a
+   specific modules static routines.  This control is implemented in
+   two parts.  Doing this allows the compiler to both eliminate the
+   overhead of function calls and (as a consequence) also eliminate
+   further dead code.
+
+   Experementing with CISC (x86) I've found that I can achieve an
+   order of magintude speed improvement (x3-x5).  In the case of RISC
+   (sparc) while the performance gain isn't as great it is still
+   significant.
+
+   Part One - Static functions: It is possible to control how static
+   functions within each module are to be compiled.  On a per module
+   or global basis, it is possible to specify that a modules static
+   functions should be compiled inline.  This is controled by the the
+   macro's STATIC_INLINE and INLINE_STATIC_<module>.
+
+   Part Two - External functions: Again it is possible to allow the
+   inlining of calls to external functions.  This is far more
+   complicated and much heaver on the compiler.  In this case, it is
+   controled by the <module>_INLINE macro's.  Where each can have a
+   value:
+
+      0  ppc.c should call external module
+
+      1  ppc.c should have local copy (and hence possibly facilitate
+         the in lineing of that modules external calls)
+
+      2  ppc.c should inline this module
+
+   Finally, this is not for the faint harted.  I've seen GCC get up to
+   200mb trying to compile what this can create */
+
+/* Your compilers inline reserved word */
+
+#ifndef INLINE
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#define INLINE __inline__
+#else
+#define INLINE /*inline*/
+#endif
+#endif
+
+/* Default prefix for static functions */
+
+#ifndef STATIC_INLINE
+#define STATIC_INLINE static INLINE
+#endif
+
+/* Default macro to control several of the inlines */
+
+#ifndef DEFAULT_INLINE
+#define        DEFAULT_INLINE                  0
+#endif
+
+/* Code that does byte swapping used on any memory access */
+
+#ifndef ENDIAN_INLINE
+#define ENDIAN_INLINE                  DEFAULT_INLINE
+#endif
+
+/* Instruction cache if in use */
+
+#if 0 /*DNE*/
+#ifndef ICACHE_INLINE
+#define ICACHE_INLINE                  0
+#endif
+#endif
+
+/* Given a translated address, core maps it onto either simulator data
+   or a function call, this is performed once for each
+   data/instruction access */
+
+
+#ifndef CORE_INLINE
+#define CORE_INLINE                    DEFAULT_INLINE
+#endif
+
+
+/* The cpu object.  May things call upon this module to manipulate
+   each cpu object for instance register updates (from semantics) or
+   instruction execution from psim */
+
+#ifndef VM_INLINE
+#define VM_INLINE                      DEFAULT_INLINE
+#endif
+
+/* Physical memory is implemented using the memory map module */
+
+#ifndef CPU_INLINE
+#define CPU_INLINE                     DEFAULT_INLINE
+#endif
+
+/* handle the queue of events to happen in the future */
+
+#ifndef EVENTS_INLINE
+#define EVENTS_INLINE                  DEFAULT_INLINE
+#endif
+
+/* not so important register manipulation code.  Most important
+   register operations are performed directly on the register file */
+
+#ifndef REGISTERS_INLINE
+#define REGISTERS_INLINE               DEFAULT_INLINE
+#endif
+
+/* interrupt handling code */
+
+#ifndef INTERRUPTS_INLINE
+#define INTERRUPTS_INLINE              DEFAULT_INLINE
+#endif
+
+/* device code. While possibly important, this isn't as critical as
+   the cpu/memory path
+
+   There seems to be some problem with making either device_tree or
+   devices inline.  It reports the message:
+   device_tree_find_node() not a leaf  */
+
+#ifndef DEVICE_TREE_INLINE
+#define DEVICE_TREE_INLINE             0
+#endif
+
+#ifndef DEVICES_INLINE
+#define DEVICES_INLINE                 0
+#endif
+
+/* Special Purpose Register tables.  Provide information on the
+   attributes of given SPR's. */
+
+#ifndef SPREG_INLINE
+#define SPREG_INLINE                   DEFAULT_INLINE
+#endif
+
+/* Functions modeling the semantics of each instruction.  Two cases to
+   consider, firstly of idecode is implemented with a switch then this
+   allows the idecode function to inline each semantic function
+   (avoiding a call).  The second case is when idecode is using a
+   table, even then while the semantic functions can't be inlined,
+   setting it to one still enables each semantic function to inline
+   anything they call (if that code is marked for being inlined).
+
+   WARNING: you need lots (like 200mb of swap) of swap.  Setting this
+   to 1 is useful when using a table as it enables the sematic code to
+   inline all of their called functions */
+
+#ifndef SEMANTICS_INLINE
+#define SEMANTICS_INLINE               0
+#endif
+
+/* Functions that decode an instruction.  Called by the cpu module.
+   Part of the performance critical fetch - decode - issue sequence */
+
+#ifndef IDECODE_INLINE
+#define IDECODE_INLINE                 DEFAULT_INLINE
+#endif
+
+
+
+/* If you're confused by the above, check out some of the generic
+   configurations below. */
+
+
+#if 0
+/* Allow the expansion of the semantic functions.  That is, if the
+   branch instruction is called with AA=0 and AA=1, generate separate
+   functions for each case */
+
+#undef WITH_IDECODE_EXPAND_SEMANTICS
+#define WITH_IDECODE_EXPAND_SEMANTICS 1
+
+#undef WITH_IDECODE_OPCODE_RULES
+#define WITH_IDECODE_OPCODE_RULES { \
+  { 1,  0,  5,  0,  5, 0, 0,                0, 0x00000000, 0x00000000, 0 }, \
+  { 1, 21, 31, 32, -1, 0, "OE,LR,AA,Rc,LK", 0, 0x00000000, 0x00000000, 0 }, \
+  { 1,  6,  9,  6,  9, 0, "BO",             0, 0xfc000000, 0x40000000, 1 }, \
+  { 1, 11, 15, 11, 15, 0, "RA",             0, 0xfc000000, 0x38000000, 2 }, \
+  { 1, 11, 15, 11, 15, 0, "RA",             0, 0xfc000000, 0x3c000000, 2 }, \
+  { 0 } \
+}
+#endif
+
+
+#if 0
+/* eliminate any debugging noise */
+
+#undef WITH_TRACE
+#define WITH_TRACE 0
+
+#undef WITH_ASSERT
+#define WITH_ASSERT 0
+
+#endif
+
+
+#if 0
+/* A reasonable set of inline macro's that give the compiler a
+   fighting chance at eliminating much of the function call overhead.
+
+   Typically, with the below the -O3 option (to get inline of all
+   functioins) isn't of any greate benefit. */
+
+#undef INLINE
+#define INLINE inline
+
+#undef STATIC_INLINE
+#define STATIC_INLINE static INLINE
+
+#undef ENDIAN_INLINE
+#define ENDIAN_INLINE 2
+
+#if 0 /*DNE*/
+#undef ICACHE_INLINE
+#define ICACHE_INLINE 0
+#endif
+
+#undef CORE_INLINE
+#define CORE_INLINE 2
+
+#undef VM_INLINE
+#define VM_INLINE 2
+
+#undef CPU_INLINE
+#define CPU_INLINE 2
+
+#undef EVENTS_INLINE
+#define EVENTS_INLINE 2
+
+#undef REGISTERS_INLINE
+#define REGISTERS_INLINE 2
+
+#undef INTERRUPTS_INLINE
+#define INTERRUPTS_INLINE 2
+
+#undef DEVICE_TREE_INLINE
+#define DEVICE_TREE_INLINE 0
+
+#undef DEVICES_INLINE
+#define DEVICES_INLINE 0
+
+#undef SPREG_INLINE
+#define SPREG_INLINE 2
+
+#undef SEMANTICS_INLINE
+#define SEMANTICS_INLINE 1 /* not 2! as it blows away the compiler */
+
+#undef IDECODE_INLINE
+#define IDECODE_INLINE 2
+
+#endif
+
+
+#if 0
+/* Enable the full cracking cache.  The cracked instruction cache
+   appears to give best performance if most functions have been lined
+   as well */
+
+#undef WITH_IDECODE_CACHE
+#define WITH_IDECODE_CACHE 2
+
+#endif
+
+
+
+#if 0
+/* With the VEA model, can eliminate some things.  Not least of which
+   is support for the OEA model */
+
+#undef WITH_ENVIRONMENT
+#define WITH_ENVIRONMENT VIRTUAL_ENVIRONMENT
+
+#undef WITH_EVENTS
+#define WITH_EVENTS 0
+
+#undef WITH_SMP
+#define WITH_SMP 0
+
+#undef WITH_TARGET_BYTE_ORDER 
+#define WITH_TARGET_BYTE_ORDER WITH_HOST_BYTE_ORDER
+
+#endif
+
+
+
+
+#if 0
+/* Finally, the expansion rules below are extreemly agressive.  Only
+   consider them if your build machine is VERY VERY VERY VERY VERY
+   well configured */
+
+#undef WITH_IDECODE_EXPAND_SEMANTICS
+#define WITH_IDECODE_EXPAND_SEMANTICS 1
+
+#undef WITH_IDECODE_OPCODE_RULES
+#define WITH_IDECODE_OPCODE_RULES { \
+  { 1,  0,  5,  0,  5, 0, 0,                0, 0x00000000, 0x00000000, 0 }, \
+  { 1, 21, 31, 32, -1, 0, "OE,LR,AA,Rc,LK", 0, 0x00000000, 0x00000000, 0 }, \
+  { 1,  6, 15,  6, 15, 0, "BO,BI",          0, 0xfc000000, 0x40000000, 0 }, \
+  { 1, 11, 15, 11, 15, 0, "RA",             0, 0xfc000000, 0x38000000, 0 }, \
+  { 1, 11, 15, 11, 15, 0, "RA",             0, 0xfc000000, 0x3c000000, 0 }, \
+  { 1, 11, 20, 11, 20, 0, "spr",            0, 0xfc000000, 0x7c000000, 0 }, \
+  { 0 } \
+}
+#endif
+
+
+#endif /* _CONFIG_H */