Sort instruction names; Add igen -R option; count # of CRs that mtcrf moved
authorMichael Meissner <gnu@the-meissners.org>
Sat, 25 Nov 1995 01:35:14 +0000 (01:35 +0000)
committerMichael Meissner <gnu@the-meissners.org>
Sat, 25 Nov 1995 01:35:14 +0000 (01:35 +0000)
sim/ppc/ChangeLog
sim/ppc/configure
sim/ppc/configure.in
sim/ppc/igen.c
sim/ppc/mon.c
sim/ppc/ppc-instructions

index 15a9bc64004715a0301e8a7669c5373ab70a17b7..89f8acde6dd892b12c1c26fb04300d5d9780002f 100644 (file)
@@ -25,8 +25,9 @@ Fri Nov 24 11:24:34 1995  Michael Meissner  <meissner@tiktok.cygnus.com>
        (model_mon_info): Return structures counting the # of CRs that the
        mtcrf instruction used.
 
-       * mon.c (mon_sort_instruction_names): New function to sort
-       instruction names alphabetically.
+       * mon.c (stdlib.h): Include if the system supplies one.
+       (mon_sort_instruction_names): New function to sort instruction
+       names alphabetically.
        (mon_print_info): Call qsort with mon_sort_instruction_names to
        sort instruction names.
        
index 047100dd56a4a5732f04ea69adde6c9f089c43e6..e9f935813f5a94b0affd4caa124dbc5dd4c3c602 100755 (executable)
@@ -37,6 +37,8 @@ ac_help="$ac_help
   --enable-sim-hostendain=end          Specify host byte endian orientation."
 ac_help="$ac_help
   --enable-sim-smp=n                   Specify number of processors to configure for."
+ac_help="$ac_help
+  --enable-sim-xor-endian=n            Specify number bytes involved in PowerPC XOR bi-endian mode (default 8)."
 ac_help="$ac_help
   --enable-sim-bitsize=n               Specify target bitsize (32 or 64)."
 ac_help="$ac_help
@@ -57,12 +59,12 @@ ac_help="$ac_help
   --enable-sim-float                   Specify whether to use host floating point or simulate."
 ac_help="$ac_help
   --enable-sim-monitor=mon             Specify whether to enable monitoring events."
-ac_help="$ac_help
-  --enable-sim-function-unit           Specify whether detailed functional unit support is built."
 ac_help="$ac_help
   --enable-sim-model=which             Specify PowerPC to model."
 ac_help="$ac_help
   --enable-sim-default-model=which     Specify default PowerPC to model."
+ac_help="$ac_help
+  --enable-sim-model-issue             Specify whether to simulate model specific actions"
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -470,7 +472,7 @@ fi
 enableval="$enable_sim_warnings"
 if test -n "$enableval"; then
   case "${enableval}" in
-  yes) sim_warnings="-Wall -Wpointer-arith -Wbad-function-cast -Wmissing-prototypes -Wmissing-declarations";;
+  yes) sim_warnings="-Werror -Wall -Wpointer-arith -Wmissing-prototypes";;
   no)  sim_warnings="-w";;
   *)   sim_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
 esac
@@ -586,13 +588,21 @@ fi
 # Check whether --enable-sim-icache or --disable-sim-icache was given.
 enableval="$enable_sim_icache"
 if test -n "$enableval"; then
-  case "${enableval}" in
-  yes) sim_icache="-r 1024";;
-  no)  sim_icache="";;
-  *)   sim_icache="-r ${enableval}";;
+  icache=""
+case "${enableval}" in
+  yes)         sim_icache="-r 1024"; icache="1024";;
+  define)      sim_icache="-r 1024 -R"; icache="1024";;
+  no)          sim_icache="";;
+  *)           sim_icache="-r ${enableval}"; icache="${enableval}";;
 esac
+if test x"$silent" != x"yes" && test x"$icache" != x""; then
+  echo "Setting instruction cache size to $icache"
+fi
 else
   sim_icache="-r 1024"
+if test x"$silent" != x"yes"; then
+  echo "Setting instruction cache size to 1024"
+fi
 fi
 
 # Check whether --enable-sim-inline or --disable-sim-inline was given.
@@ -600,7 +610,7 @@ enableval="$enable_sim_inline"
 if test -n "$enableval"; then
   sim_inline=""
 case "$enableval" in
-  no)          sim_inline="";;
+  no)          sim_inline="-DDEFAULT_INLINE=0 -DINLINE=";;
   0)           sim_inline="-DDEFAULT_INLINE=0";;
   yes | 2)     sim_inline="-DDEFAULT_INLINE=2";;
   1)           sim_inline="-DDEFAULT_INLINE=1";;
@@ -609,13 +619,13 @@ case "$enableval" in
        case "$x" in
         *_INLINE=*)    new_flag="-D$x";;
         *_INLINE)      new_flag="-D$x=2";;
-        *=*)           new_flag=`sed -e "s/=/_INLINE=/" -e "s/^/-D/"`;;
+        *=*)           new_flag=`echo "$x" | sed -e "s/=/_INLINE=/" -e "s/^/-D/"`;;
         *)             new_flag="-D$x""_INLINE=2";;
        esac
-       if x"$sim_inline" = x""; then
+       if test x"$sim_inline" = x""; then
         sim_inline="$new_flag"
        else
-        sim_inline="$flags $new_flag"
+        sim_inline="$sim_inline $new_flag"
        fi
      done;;
 esac
@@ -689,7 +699,7 @@ fi
 enableval="$enable_sim_smp"
 if test -n "$enableval"; then
   case "${enableval}" in
-  yes) sim_smp="-DWITH_SMP=2";;
+  yes) sim_smp="-DWITH_SMP=5";;
   no)  sim_smp="-DWITH_SMP=0";;
   *)   sim_smp="-DWITH_SMP=$enableval";;
 esac
@@ -703,6 +713,18 @@ if test x"$silent" != x"yes"; then
 fi
 fi
 
+# Check whether --enable-sim-xor-endian or --disable-sim-xor-endian was given.
+enableval="$enable_sim_xor_endian"
+if test -n "$enableval"; then
+  case "${enableval}" in
+  yes) sim_xor_endian="-DWITH_XOR_ENDIAN=8";;
+  no)  sim_xor_endian="-DWITH_XOR_ENDIAN=0";;
+  *)   sim_xor_endian="-DWITH_XOR_ENDIAN=$enableval";;
+esac
+else
+  sim_xor_endian=""
+fi
+
 # Check whether --enable-sim-bitsize or --disable-sim-bitsize was given.
 enableval="$enable_sim_bitsize"
 if test -n "$enableval"; then
@@ -855,21 +877,6 @@ else
   sim_mon=""
 fi
 
-# Check whether --enable-sim-function-unit or --disable-sim-function-unit was given.
-enableval="$enable_sim_function_unit"
-if test -n "$enableval"; then
-  case "${enableval}" in
-  yes) sim_func="-DWITH_FUNCTION_UNIT=1";;
-  no)  sim_func="-DWITH_FUNCTION_UNIT=0";;
-  *)   { echo "configure: error: "--enable-sim-function-unit does not take a value"" 1>&2; exit 1; }; sim_func="";;
-esac
-if test x"$silent" != x"yes" && test x"$sim_func" != x""; then
-  echo "Setting function-unit flags = $sim_func" 6>&1
-fi
-else
-  sim_func=""
-fi
-
 # Check whether --enable-sim-model or --disable-sim-model was given.
 enableval="$enable_sim_model"
 if test -n "$enableval"; then
@@ -898,6 +905,21 @@ else
   sim_model=""
 fi
 
+# Check whether --enable-sim-model-issue or --disable-sim-model-issue was given.
+enableval="$enable_sim_model_issue"
+if test -n "$enableval"; then
+  case "${enableval}" in
+  yes) sim_model_issue="-DWITH_MODEL_ISSUE=1";;
+  no)  sim_model_issue="-DWITH_MODEL_ISSUE=0";;
+  *)   { echo "configure: error: "--enable-sim-model-issue does not take a value"" 1>&2; exit 1; }; sim_model_issue="";;
+esac
+if test x"$silent" != x"yes"; then
+  echo "Setting model-issue flags = $sim_model_issue" 6>&1
+fi
+else
+  sim_model_issue=""
+fi
+
 ac_aux_dir=
 for ac_dir in `cd $srcdir;pwd`/../.. $srcdir/`cd $srcdir;pwd`/../..; do
   if test -f $ac_dir/install-sh; then
@@ -1155,6 +1177,7 @@ fi
 
 
 
+
 
 
 for ac_func in getrusage
@@ -1164,7 +1187,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1168 "configure"
+#line 1191 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1219,7 +1242,7 @@ else
   ac_cv_c_cross=yes
 else
 cat > conftest.$ac_ext <<EOF
-#line 1223 "configure"
+#line 1246 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
@@ -1257,7 +1280,7 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1261 "configure"
+#line 1284 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1271,7 +1294,7 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1275 "configure"
+#line 1298 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1304,7 +1327,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1308 "configure"
+#line 1331 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
@@ -1465,6 +1488,7 @@ s%@sim_icache@%$sim_icache%g
 s%@sim_inline@%$sim_inline%g
 s%@sim_bswap@%$sim_bswap%g
 s%@sim_endian@%$sim_endian%g
+s%@sim_xor_endian@%$sim_xor_endian%g
 s%@sim_hostendian@%$sim_hostendian%g
 s%@sim_smp@%$sim_smp%g
 s%@sim_bitsize@%$sim_bitsize%g
@@ -1477,9 +1501,9 @@ s%@sim_trace@%$sim_trace%g
 s%@sim_assert@%$sim_assert%g
 s%@sim_reserved@%$sim_reserved%g
 s%@sim_monitor@%$sim_monitor%g
-s%@sim_func@%$sim_func%g
 s%@sim_model@%$sim_model%g
 s%@sim_default_model@%$sim_default_model%g
+s%@sim_model_issue@%$sim_model_issue%g
 s%@CC_FOR_BUILD@%$CC_FOR_BUILD%g
 s%@CPP@%$CPP%g
 
index d59f9c2675ace767741b6014e1a685b468d0b3c3..b884544727ba53bf77c36709a24589127c9c3d32 100644 (file)
@@ -110,9 +110,10 @@ AC_ARG_ENABLE(sim-icache,
 [  --enable-sim-icache=size            Specify instruction cache size.],
 icache=""
 [case "${enableval}" in
-  yes) sim_icache="-r 1024"; icache="1024";;
-  no)  sim_icache="";;
-  *)   sim_icache="-r ${enableval}"; icache="${enableval}";;
+  yes)         sim_icache="-r 1024"; icache="1024";;
+  define)      sim_icache="-r 1024 -R"; icache="1024";;
+  no)          sim_icache="";;
+  *)           sim_icache="-r ${enableval}"; icache="${enableval}";;
 esac
 if test x"$silent" != x"yes" && test x"$icache" != x""; then
   echo "Setting instruction cache size to $icache"
index ddec1665575acd68a07181a223138e37afda0fdf..d3f87bb381854fbae8fb826e1de372a1267b9792 100644 (file)
 #endif
 #endif
 
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
 
 
 /****************************************************************/
@@ -47,6 +51,7 @@ static int hi_bit_nr = 0;
 static int insn_size = max_insn_size;
 static int idecode_expand_semantics = 0;
 static int idecode_cache = 0;
+static int semantics_use_cache_struct = 0;
 static int number_lines = 1;
 
 
@@ -590,6 +595,14 @@ struct _insn {
   insn *next;
 };
 
+typedef struct _insn_undef insn_undef;
+struct _insn_undef {
+  insn_undef *next;
+  char *name;
+};
+
+static insn_undef *first_undef, *last_undef;
+
 typedef struct _model model;
 struct _model {
   model *next;
@@ -1812,6 +1825,24 @@ lf_print_c_extraction(lf *file,
     else
       lf_printf(file, "%d;\n", bits->value);
   }
+  else if (get_value_from_cache && !put_value_in_cache
+          && semantics_use_cache_struct) {
+    insn_undef *undef = ZALLOC(insn_undef);
+    /* Use #define to reference the cache struct directly, rather than putting
+       them into local variables */
+    lf_indent_suppress(file);
+    lf_printf(file, "#define %s (cache_entry->crack.%s.%s)\n",
+             field_name,
+             instruction->file_entry->fields[insn_form],
+             field_name);
+
+    if (first_undef)
+      last_undef->next = undef;
+    else
+      first_undef = undef;
+    last_undef = undef;;
+    undef->name = field_name;
+  }
   else {
     /* put the field in the local variable */
     table_entry_lf_c_line_nr(file, instruction->file_entry);
@@ -2191,6 +2222,7 @@ lf_print_c_semantic_function(lf *file,
                             opcode_field *opcodes,
                             int is_inline_function)
 {
+  insn_undef *undef, *next;
 
   /* build the semantic routine to execute the instruction */
   lf_print_semantic_function_header(file,
@@ -2202,6 +2234,17 @@ lf_print_c_semantic_function(lf *file,
                      instruction,
                      expanded_bits,
                      opcodes);
+
+  /* If we are referencing the cache structure directly instead of putting the values
+     in local variables, undef any defines we created */
+  for(undef = first_undef; undef; undef = next) {
+    next = undef->next;
+    lf_indent_suppress(file);
+    lf_printf(file, "#undef %s\n", undef->name);
+    free((void *)undef);
+  }
+  first_undef = (insn_undef *)0;
+  last_undef = (insn_undef *)0;
 }
 
 
@@ -3329,25 +3372,28 @@ main(int argc,
     printf("  igen <config-opts> ... <input-opts>... <output-opts>...\n");
     printf("Config options:\n");
     printf("  -f <filter-out-flag>  eg -f 64 to skip 64bit instructions\n");
-    printf("  -e    Expand (duplicate) semantic functions\n");
-    printf("  -r <icache-size>  Generate cracking cache version\n");
-    printf("  -l    Supress line numbering in output files\n");
-    printf("  -b <bit-size>  Set the number of bits in an instruction\n");
-    printf("  -h <high-bit>  Set the nr of the high (msb bit)\n");
+    printf("  -e                    Expand (duplicate) semantic functions\n");
+    printf("  -r <icache-size>      Generate cracking cache version\n");
+    printf("  -R                    Use defines to reference cache vars\n");
+    printf("  -l                    Supress line numbering in output files\n");
+    printf("  -b <bit-size>         Set the number of bits in an instruction\n");
+    printf("  -h <high-bit>         Set the nr of the high (msb bit)\n");
+    printf("\n");
     printf("Input options (ucase version also dumps loaded table):\n");
     printf("  -[Oo] <opcode-rules>\n");
     printf("  -[Kk] <cache-rules>\n");
     printf("  -[Ii] <instruction-table>\n");
+    printf("\n");
     printf("Output options:\n");
     printf("  -[Cc] <output-file>  output icache.h(C) invalid(c)\n");
     printf("  -[Dd] <output-file>  output idecode.h(D) idecode.c(d)\n");
     printf("  -[Mm] <output-file>  output model.h(M) model.c(M)\n");
     printf("  -[Ss] <output-file>  output schematic.h(S) schematic.c(s)\n");
-    printf("  -[Tt] <table>      output itable.h(T) itable.c(t)\n");
+    printf("  -[Tt] <table>        output itable.h(T) itable.c(t)\n");
   }
 
   while ((ch = getopt(argc, argv,
-                     "leb:h:r:f:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
+                     "leb:h:r:Rf:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
     fprintf(stderr, "\t-%c %s\n", ch, (optarg ? optarg : ""));
     switch(ch) {
     case 'l':
@@ -3359,6 +3405,9 @@ main(int argc,
     case 'r':
       idecode_cache = a2i(optarg);
       break;
+    case 'R':
+      semantics_use_cache_struct = 1;
+      break;
     case 'b':
       insn_size = a2i(optarg);
       ASSERT(insn_size > 0 && insn_size <= max_insn_size
index 10d0bbcd380504cc5fe458c5f3685cbe8f8a4322..d9f515be3a1ae17db5e73249495fc5332d068bd9 100644 (file)
 #include <unistd.h>
 #endif
 
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
 #ifdef HAVE_TIME_H
 #include <time.h>
 #endif
@@ -57,12 +61,12 @@ int getrusage();
 #endif
 
 struct _cpu_mon {
-  unsigned issue_count[nr_itable_entries];
-  unsigned read_count;
-  unsigned write_count;
-  unsigned unaligned_read_count;
-  unsigned unaligned_write_count;
-  unsigned event_count[nr_mon_events];
+  count_type issue_count[nr_itable_entries];
+  count_type read_count;
+  count_type write_count;
+  count_type unaligned_read_count;
+  count_type unaligned_write_count;
+  count_type event_count[nr_mon_events];
 };
 
 struct _mon {
@@ -146,20 +150,29 @@ mon_event(mon_events event,
   monitor->event_count[event] += 1;
 }
 
-STATIC_INLINE_MON unsigned
+STATIC_INLINE_MON count_type
 mon_get_number_of_insns(cpu_mon *monitor)
 {
   itable_index index;
-  unsigned total_insns = 0;
+  count_type total_insns = 0;
   for (index = 0; index < nr_itable_entries; index++)
     total_insns += monitor->issue_count[index];
   return total_insns;
 }
 
+static int
+mon_sort_instruction_names(const void *ptr_a, const void *ptr_b)
+{
+  itable_index a = *(const itable_index *)ptr_a;
+  itable_index b = *(const itable_index *)ptr_b;
+
+  return strcmp (itable[a].name, itable[b].name);
+}
+
 STATIC_INLINE_MON char *
 mon_add_commas(char *buf,
               int sizeof_buf,
-              long value)
+              count_type value)
 {
   int comma = 3;
   char *endbuf = buf + sizeof_buf - 1;
@@ -195,14 +208,14 @@ mon_print_info(psim *system,
   double cpu_time = 0.0;
 
   for (cpu_nr = 0; cpu_nr < monitor->nr_cpus; cpu_nr++) {
-    unsigned num_insns = mon_get_number_of_insns(&monitor->cpu_monitor[cpu_nr]);
+    count_type num_insns = mon_get_number_of_insns(&monitor->cpu_monitor[cpu_nr]);
 
     total_insns += num_insns;
     len = strlen (mon_add_commas(buffer, sizeof(buffer), num_insns));
     if (len_num < len)
       len_num = len;
   }
-  
+
   sprintf (buffer, "%d", (int)monitor->nr_cpus + 1);
   len_cpu = strlen (buffer);
 
@@ -222,18 +235,29 @@ mon_print_info(psim *system,
   for (cpu_nr = 0; cpu_nr < monitor->nr_cpus; cpu_nr++) {
 
     if (verbose > 1) {
+      itable_index sort_insns[nr_itable_entries];
+      int nr_sort_insns = 0;
       itable_index index;
+      int index2;
 
       if (cpu_nr)
        printf_filtered ("\n");
 
       for (index = 0; index < nr_itable_entries; index++) {
-       if (monitor->cpu_monitor[cpu_nr].issue_count[index])
-         printf_filtered("CPU #%*d executed %*s %s instruction%s.\n",
-                         len_cpu, cpu_nr+1,
-                         len_num, mon_add_commas(buffer,
-                                                 sizeof(buffer),
-                                                 monitor->cpu_monitor[cpu_nr].issue_count[index]),
+       if (monitor->cpu_monitor[cpu_nr].issue_count[index]) {
+         sort_insns[nr_sort_insns++] = index;
+       }
+      }
+
+      qsort((void *)sort_insns, nr_sort_insns, sizeof(sort_insns[0]), mon_sort_instruction_names);
+
+      for (index2 = 0; index2 < nr_sort_insns; index2++) {
+       index = sort_insns[index2];
+       printf_filtered("CPU #%*d executed %*s %s instruction%s.\n",
+                       len_cpu, cpu_nr+1,
+                       len_num, mon_add_commas(buffer,
+                                               sizeof(buffer),
+                                               monitor->cpu_monitor[cpu_nr].issue_count[index]),
                          itable[index].name,
                          (monitor->cpu_monitor[cpu_nr].issue_count[index] == 1) ? "" : "s");
       }
index 555a38cbdb341b1b99867183e5a2c80fed31a635..4631f5fc10633d25bb3818cd65dc83ef7fdf3a53 100644 (file)
 # Flags for model.h
 ::model-macro:::
        #define PPC_INSN_INT(OUT_MASK, IN_MASK, RC) \
-               if (WITH_MODEL_ISSUE) \
-                 ppc_insn_int(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK, (RC) ? (1 << 0) : 0)
+               do { \
+                 if (WITH_MODEL_ISSUE) { \
+                   if (RC) \
+                     ppc_insn_int(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \
+                   else \
+                     ppc_insn_int_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
+                 } \
+               } while (0)
 
        #define PPC_INSN_INT_CR(OUT_MASK, IN_MASK, CR_MASK) \
-               if (WITH_MODEL_ISSUE) \
-                 ppc_insn_int(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK)
+               do { \
+                 if (WITH_MODEL_ISSUE) \
+                   ppc_insn_int_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
+               } while (0)
 
        #define PPC_INSN_CR(OUT_MASK, IN_MASK) \
-               if (WITH_MODEL_ISSUE) \
-                 ppc_insn_cr(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK)
+               do { \
+                 if (WITH_MODEL_ISSUE) \
+                   ppc_insn_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \
+               } while (0)
 
        #define PPC_INSN_FLOAT(OUT_MASK, IN_MASK, RC) \
-               if (WITH_MODEL_ISSUE) \
-                 ppc_insn_float(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK, (RC) ? (1 << 1) : 0)
+               do { \
+                 if (WITH_MODEL_ISSUE) { \
+                   if (RC) \
+                     ppc_insn_float(my_index, cpu_model(processor), OUT_MASK, IN_MASK); \
+                   else \
+                     ppc_insn_float_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, 1 << 0); \
+                 } \
+               } while (0)
 
        #define PPC_INSN_FLOAT_CR(OUT_MASK, IN_MASK, CR_MASK) \
-               if (WITH_MODEL_ISSUE) \
-                 ppc_insn_float(my_index, processor, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK)
+               do { \
+                 if (WITH_MODEL_ISSUE) \
+                   ppc_insn_float_cr(my_index, cpu_model(processor), OUT_MASK, IN_MASK, CR_MASK); \
+               } while (0)
 
        #define PPC_INSN_INT_FLOAT(OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK) \
-               if (WITH_MODEL_ISSUE) \
-                 ppc_insn_int_float(my_index, processor, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK)
+               do { \
+                 if (WITH_MODEL_ISSUE) \
+                   ppc_insn_int_float(my_index, cpu_model(processor), OUT_INT_MASK, OUT_FP_MASK, IN_INT_MASK, IN_FP_MASK); \
+               } while (0)
 
        #define PPC_INSN_FROM_SPR(INT_MASK, SPR) \
-               if (WITH_MODEL_ISSUE) \
-                 ppc_insn_from_spr(my_index, processor, cpu_model(processor), INT_MASK, SPR)
+               do { \
+                 if (WITH_MODEL_ISSUE) \
+                   ppc_insn_from_spr(my_index, cpu_model(processor), INT_MASK, SPR); \
+               } while (0)
 
        #define PPC_INSN_TO_SPR(INT_MASK, SPR) \
-               if (WITH_MODEL_ISSUE) \
-                 ppc_insn_to_spr(my_index, processor, cpu_model(processor), INT_MASK, SPR)
+               do { \
+                 if (WITH_MODEL_ISSUE) \
+                   ppc_insn_to_spr(my_index, cpu_model(processor), INT_MASK, SPR); \
+               } while (0)
 
        #define PPC_INSN_MFCR(INT_MASK) \
-               if (WITH_MODEL_ISSUE) \
-                 ppc_insn_mfcr(my_index, processor, cpu_model(processor), INT_MASK)
+               do { \
+                 if (WITH_MODEL_ISSUE) \
+                   ppc_insn_mfcr(my_index, cpu_model(processor), INT_MASK); \
+               } while (0)
+
+       #define PPC_INSN_MTCR(INT_MASK, FXM) \
+               do { \
+                 if (WITH_MODEL_ISSUE) \
+                   ppc_insn_mtcr(my_index, cpu_model(processor), INT_MASK, FXM); \
+               } while (0)
 
 ::model-data:::
        typedef enum _ppc_function_unit {
          count_type nr_branch_predict_trues;           /* # branches predicted correctly */
          count_type nr_branch_predict_falses;          /* # branches predicted incorrectly */
          count_type nr_branch_conditional[32];         /* # of each type of bc */
+         count_type nr_mtcrf_crs[9];                   /* # of CR's moved in a mtcrf instruction */
          count_type nr_stalls_data;                    /* # of stalls for data */
          count_type nr_stalls_unit;                    /* # of stalls waiting for a function unit */
          count_type nr_stalls_serialize;               /* # of stalls waiting for things to quiet down */
          "branch always (ignored bits 1,4,5 set to 1)",
        };
 
+       STATIC_MODEL const char *const ppc_nr_mtcrf_crs[9] = {
+         "mtcrf moving 0 CRs",
+         "mtcrf moving 1 CR",
+         "mtcrf moving 2 CRs",
+         "mtcrf moving 3 CRs",
+         "mtcrf moving 4 CRs",
+         "mtcrf moving 5 CRs",
+         "mtcrf moving 6 CRs",
+         "mtcrf moving 7 CRs",
+         "mtcrf moving all CRs",
+       };
 \f
 # Trace releasing resources
 void::model-static::model_trace_release:model_data *model_ptr, model_busy *busy
@@ -380,13 +424,6 @@ model_busy *::model-internal::model_make_busy:model_data *model_ptr, ppc_functio
        model_ptr->nr_units[unit]++;
        return busy;
 \f
-# Make a given CR register busy
-void::model-internal::model_make_cr_reg_busy:model_data *model_ptr, model_busy *busy_ptr, int regno
-       TRACE(trace_model,("Marking register cr%d as busy\n", regno));
-       busy_ptr->cr_fpscr_busy |= (1 << regno);
-       model_ptr->cr_fpscr_busy |= (1 << regno);
-
-\f
 # Wait until a function unit is non-busy, and then allocate a busy pointer & return the pointer
 model_busy *::model-internal::model_wait_for_unit:itable_index index, model_data *const model_ptr, const model_time *const time_ptr
        ppc_function_unit first_unit = time_ptr->first_unit;
@@ -437,108 +474,131 @@ void::model-function::model_wait_for_cr:model_data *model_ptr, unsigned CRBIT
          model_new_cycle(model_ptr);
        }
 
-# Schedule an instruction that takes integer input registers and produces output registers & possibly sets some CR registers
-void::model-function::ppc_insn_int:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask
+# Schedule an instruction that takes integer input registers and produces output registers
+void::model-function::ppc_insn_int:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
        const unsigned32 int_mask = out_mask | in_mask;
        model_busy *busy_ptr;
 
-       if (!cr_mask) {
-         if ((model_ptr->int_busy & int_mask) != 0) {
-           model_new_cycle(model_ptr);                 /* don't count first dependency as a stall */
+       if ((model_ptr->int_busy & int_mask) != 0) {
+         model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
 
-           while ((model_ptr->int_busy & int_mask) != 0) {
-             if (WITH_TRACE && ppc_trace[trace_model])
-               model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
+         while ((model_ptr->int_busy & int_mask) != 0) {
+           if (WITH_TRACE && ppc_trace[trace_model])
+             model_trace_busy_p(model_ptr, int_mask, 0, 0, PPC_NO_SPR);
 
-             model_ptr->nr_stalls_data++;
-             model_new_cycle(model_ptr);
-           }
+           model_ptr->nr_stalls_data++;
+           model_new_cycle(model_ptr);
          }
-
-         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
-         model_ptr->int_busy |= out_mask;
-         busy_ptr->int_busy |= out_mask;
-         if (WITH_TRACE && ppc_trace[trace_model])
-           model_trace_make_busy(model_ptr, out_mask, 0, 0);
-         return;
        }
 
-       else {
-         if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
-           model_new_cycle(model_ptr);                 /* don't count first dependency as a stall */
+       busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
+       model_ptr->int_busy |= out_mask;
+       busy_ptr->int_busy |= out_mask;
+       if (WITH_TRACE && ppc_trace[trace_model])
+         model_trace_make_busy(model_ptr, out_mask, 0, 0);
 
-           while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
-             if (WITH_TRACE && ppc_trace[trace_model])
-               model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
+# Schedule an instruction that takes integer input registers and produces output registers & sets some CR registers
+void::model-function::ppc_insn_int_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask
+       const unsigned32 int_mask = out_mask | in_mask;
+       model_busy *busy_ptr;
 
-             model_ptr->nr_stalls_data++;
-             model_new_cycle(model_ptr);
-           }
+       if ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
+         model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
+
+         while ((model_ptr->int_busy & int_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
+           if (WITH_TRACE && ppc_trace[trace_model])
+             model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
+
+           model_ptr->nr_stalls_data++;
+           model_new_cycle(model_ptr);
          }
+       }
 
-         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
-         model_ptr->int_busy |= out_mask;
-         busy_ptr->int_busy |= out_mask;
-         model_ptr->cr_fpscr_busy |= cr_mask;
-         busy_ptr->cr_fpscr_busy |= cr_mask;
-         if (WITH_TRACE && ppc_trace[trace_model])
-           model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
-         return;
+       busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
+       model_ptr->int_busy |= out_mask;
+       busy_ptr->int_busy |= out_mask;
+       model_ptr->cr_fpscr_busy |= cr_mask;
+       busy_ptr->cr_fpscr_busy |= cr_mask;
+       if (WITH_TRACE && ppc_trace[trace_model])
+         model_trace_make_busy(model_ptr, out_mask, 0, cr_mask);
+
+
+# Schedule an instruction that takes CR input registers and produces output CR registers
+void::model-function::ppc_insn_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
+       const unsigned32 cr_mask = out_mask | in_mask;
+       model_busy *busy_ptr;
+
+       if ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
+         model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
+
+         while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
+           if (WITH_TRACE && ppc_trace[trace_model])
+             model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
+
+           model_ptr->nr_stalls_data++;
+           model_new_cycle(model_ptr);
+         }
        }
 
+       busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
+       model_ptr->cr_fpscr_busy |= out_mask;
+       busy_ptr->cr_fpscr_busy |= out_mask;
+       if (WITH_TRACE && ppc_trace[trace_model])
+         model_trace_make_busy(model_ptr, 0, 0, out_mask);
 
-# Schedule an instruction that takes floating point input registers and produces output fp registers & possibly sets some CR regs
-void::model-function::ppc_insn_float:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask
+
+# Schedule an instruction that takes floating point input registers and produces output fp registers
+void::model-function::ppc_insn_float:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask
        const unsigned32 fp_mask = out_mask | in_mask;
        model_busy *busy_ptr;
 
-       if (!cr_mask) {
-         if ((model_ptr->fp_busy & fp_mask) != 0) {
-           model_new_cycle(model_ptr);                 /* don't count first dependency as a stall */
+       if ((model_ptr->fp_busy & fp_mask) != 0) {
+         model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
 
-           while ((model_ptr->fp_busy & fp_mask) != 0) {
-             if (WITH_TRACE && ppc_trace[trace_model])
-               model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
+         while ((model_ptr->fp_busy & fp_mask) != 0) {
+           if (WITH_TRACE && ppc_trace[trace_model])
+             model_trace_busy_p(model_ptr, 0, fp_mask, 0, PPC_NO_SPR);
 
-             model_ptr->nr_stalls_data++;
-             model_new_cycle(model_ptr);
-           }
+           model_ptr->nr_stalls_data++;
+           model_new_cycle(model_ptr);
          }
-
-         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
-         model_ptr->fp_busy |= out_mask;
-         busy_ptr->fp_busy |= out_mask;
-         if (WITH_TRACE && ppc_trace[trace_model])
-           model_trace_make_busy(model_ptr, 0, out_mask, 0);
-         return;
        }
 
-       else {
-         if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
-           model_new_cycle(model_ptr);                 /* don't count first dependency as a stall */
+       busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
+       model_ptr->fp_busy |= out_mask;
+       busy_ptr->fp_busy |= out_mask;
+       if (WITH_TRACE && ppc_trace[trace_model])
+         model_trace_make_busy(model_ptr, 0, out_mask, 0);
 
-           while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
-             if (WITH_TRACE && ppc_trace[trace_model])
-               model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
 
-             model_ptr->nr_stalls_data++;
-             model_new_cycle(model_ptr);
-           }
-         }
+# Schedule an instruction that takes floating point input registers and produces output fp registers & sets some CR regs
+void::model-function::ppc_insn_float_cr:itable_index index, model_data *model_ptr, const unsigned32 out_mask, const unsigned32 in_mask, const unsigned32 cr_mask
+       const unsigned32 fp_mask = out_mask | in_mask;
+       model_busy *busy_ptr;
 
-         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
-         model_ptr->fp_busy |= out_mask;
-         busy_ptr->fp_busy |= out_mask;
-         model_ptr->cr_fpscr_busy |= cr_mask;
-         busy_ptr->cr_fpscr_busy |= cr_mask;
-         if (WITH_TRACE && ppc_trace[trace_model])
-           model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
-         return;
+       if ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
+         model_new_cycle(model_ptr);                   /* don't count first dependency as a stall */
+
+         while ((model_ptr->fp_busy & fp_mask) || (model_ptr->cr_fpscr_busy & cr_mask)) {
+           if (WITH_TRACE && ppc_trace[trace_model])
+             model_trace_busy_p(model_ptr, 0, fp_mask, cr_mask, PPC_NO_SPR);
+
+           model_ptr->nr_stalls_data++;
+           model_new_cycle(model_ptr);
+         }
        }
 
+       busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
+       model_ptr->fp_busy |= out_mask;
+       busy_ptr->fp_busy |= out_mask;
+       model_ptr->cr_fpscr_busy |= cr_mask;
+       busy_ptr->cr_fpscr_busy |= cr_mask;
+       if (WITH_TRACE && ppc_trace[trace_model])
+         model_trace_make_busy(model_ptr, 0, out_mask, cr_mask);
+
 
 # Schedule an instruction that takes both int/float input registers and produces output int/float registers
-void::model-function::ppc_insn_int_float:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 out_int_mask, const unsigned32 out_fp_mask, const unsigned32 in_int_mask, const unsigned32 in_fp_mask
+void::model-function::ppc_insn_int_float:itable_index index, model_data *model_ptr, const unsigned32 out_int_mask, const unsigned32 out_fp_mask, const unsigned32 in_int_mask, const unsigned32 in_fp_mask
        const unsigned32 int_mask = out_int_mask | in_int_mask;
        const unsigned32 fp_mask = out_fp_mask | in_fp_mask;
        model_busy *busy_ptr;
@@ -565,7 +625,7 @@ void::model-function::ppc_insn_int_float:itable_index index, cpu *processor, mod
        }
 
 # Schedule an MFSPR instruction that takes 1 special purpose register and produces an integer output register
-void::model-function::ppc_insn_from_spr:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
+void::model-function::ppc_insn_from_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
        model_busy *busy_ptr;
 
        while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
@@ -583,7 +643,7 @@ void::model-function::ppc_insn_from_spr:itable_index index, cpu *processor, mode
          model_trace_make_busy(model_ptr, int_mask, 0, 0);
 
 # Schedule an MTSPR instruction that takes 1 integer register and produces a special purpose output register
-void::model-function::ppc_insn_to_spr:itable_index index, cpu *processor, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
+void::model-function::ppc_insn_to_spr:itable_index index, model_data *model_ptr, const unsigned32 int_mask, const unsigned nSPR
        model_busy *busy_ptr;
 
        while ((model_ptr->int_busy & int_mask) != 0 || model_ptr->spr_busy[nSPR] != 0) {
@@ -600,7 +660,7 @@ void::model-function::ppc_insn_to_spr:itable_index index, cpu *processor, model_
        TRACE(trace_model,("Making register %s busy.\n", spr_name(nSPR)));
 
 # Schedule a MFCR instruction that moves the CR into an integer regsiter
-void::model-function::ppc_insn_mfcr:itable_index index, cpu *processor, model_data *model_ptr, unsigned32 int_mask
+void::model-function::ppc_insn_mfcr:itable_index index, model_data *model_ptr, unsigned32 int_mask
        const unsigned32 cr_mask = 0xff;
        model_busy *busy_ptr;
 
@@ -619,94 +679,41 @@ void::model-function::ppc_insn_mfcr:itable_index index, cpu *processor, model_da
          model_trace_make_busy(model_ptr, int_mask, 0, 0);
 
 # Schedule a MTCR instruction that moves an integer register into the CR
-void::model-function::ppc_insn_mtcr:itable_index index, cpu *processor, model_data *model_ptr, signed_word *rT, unsigned FXM
-       if (!WITH_MODEL_ISSUE)
-         return;
-
-       else {
-         registers *cpu_regs = cpu_registers(processor);
-         const unsigned ppc_RT = (rT - &cpu_regs->gpr[0]);
-         const unsigned32 int_mask = (1 << ppc_RT);
-         const unsigned32 cr_mask = 0xff;
-         const model_time *normal_time = &model_ptr->timing[index];
-         static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0 };
-         model_busy *busy_ptr;
-
-         while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
-           if (WITH_TRACE && ppc_trace[trace_model])
-             model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
-
-           model_ptr->nr_stalls_data++;
-           model_new_cycle(model_ptr);
-         }
+void::model-function::ppc_insn_mtcr:itable_index index, model_data *model_ptr, unsigned32 int_mask, unsigned FXM
+       int f;
+       int nr_crs = 0;
+       unsigned32 cr_mask = 0;
+       const model_time *normal_time = &model_ptr->timing[index];
+       static const model_time ppc604_1bit_time = { PPC_UNIT_SCIU1, PPC_UNIT_SCIU2, 1,  1,  0 };
+       model_busy *busy_ptr;
 
-         /* If only one bit is being moved, use the SCIU, not the MCIU on the 604 */
-         if (CURRENT_MODEL == MODEL_ppc604 && (FXM & (FXM-1)) == 0) {
-           normal_time = &ppc604_1bit_time;
+       for (f = 0; f < 8; f++) {
+         if (FXM & (0x80 >> f)) {
+           cr_mask |= (1 << f);
+           nr_crs++;
          }
-
-         busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
-         busy_ptr->cr_fpscr_busy |= cr_mask;
-         model_ptr->cr_fpscr_busy |= cr_mask;
-         if (WITH_TRACE && ppc_trace[trace_model])
-           model_trace_make_busy(model_ptr, 0, 0, cr_mask);
-       }
-
-# Convert a BIT32(x) number back into the original number
-int::model-internal::ppc_undo_bit32:unsigned bitmask
-       unsigned u = 0x80000000;
-       int i = 0;
-       while (u && (u & bitmask) == 0) {
-         u >>= 1;
-         i++;
        }
 
-       return i;
-
-# Schedule an instruction that takes 2 CR input registers and produces an output CR register
-void::model-function::ppc_insn_cr2:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned crA_bit, unsigned crB_bit
-       if (!WITH_MODEL_ISSUE)
-         return;
-
-       else {
-         const unsigned ppc_CRA = ppc_undo_bit32(crA_bit);
-         const unsigned ppc_CRB = ppc_undo_bit32(crB_bit);
-         const unsigned32 cr_mask = (1 << ppc_CRA) | (1 << ppc_CRB) | (1 << crD);
-         model_busy *busy_ptr;
-
-         while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
-           if (WITH_TRACE && ppc_trace[trace_model])
-               model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
-
-           model_ptr->nr_stalls_data++;
-           model_new_cycle(model_ptr);
-         }
+       while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
+         if (WITH_TRACE && ppc_trace[trace_model])
+           model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
 
-         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
-         model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
+         model_ptr->nr_stalls_data++;
+         model_new_cycle(model_ptr);
        }
 
-# Schedule an instruction that takes 1 CR input registers and produces an output CR register
-void::model-function::ppc_insn_cr1:itable_index index, cpu *processor, model_data *model_ptr, unsigned crD, unsigned CRA
-       if (!WITH_MODEL_ISSUE)
-         return;
-
-       else {
-         const unsigned32 cr_mask = (1 << CRA) | (1 << crD);
-         model_busy *busy_ptr;
-
-         while ((model_ptr->cr_fpscr_busy & cr_mask) != 0) {
-           if (WITH_TRACE && ppc_trace[trace_model])
-               model_trace_busy_p(model_ptr, 0, 0, cr_mask, PPC_NO_SPR);
-
-           model_ptr->nr_stalls_data++;
-           model_new_cycle(model_ptr);
-         }
-
-         busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
-         model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
+       /* If only one CR is being moved, use the SCIU, not the MCIU on the 604 */
+       if (CURRENT_MODEL == MODEL_ppc604 && nr_crs == 1) {
+         normal_time = &ppc604_1bit_time;
        }
 
+       busy_ptr = model_wait_for_unit(index, model_ptr, normal_time);
+       busy_ptr->cr_fpscr_busy |= cr_mask;
+       model_ptr->cr_fpscr_busy |= cr_mask;
+       model_ptr->nr_mtcrf_crs[nr_crs]++;
+       if (WITH_TRACE && ppc_trace[trace_model])
+         model_trace_make_busy(model_ptr, 0, 0, cr_mask);
+\f
 model_data *::model-function::model_create:cpu *processor
        model_data *model_ptr = ZALLOC(model_data);
        ASSERT(CURRENT_MODEL > 0 && CURRENT_MODEL < nr_models);
@@ -810,6 +817,17 @@ model_print *::model-function::model_mon_info:model_data *model_ptr
          }
        }
 
+       for (j = 0; j < 9; j++) {
+         if (model_ptr->nr_mtcrf_crs[j]) {
+           tail->next = ZALLOC(model_print);
+           tail = tail->next;
+           tail->count = model_ptr->nr_mtcrf_crs[j];
+           tail->name = ppc_nr_mtcrf_crs[j];
+           tail->suffix_plural = " instructions";
+           tail->suffix_singular = " instruction";
+         }
+       }
+
        nr_insns = 0;
        for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
          if (model_ptr->nr_units[i]) {
@@ -1437,7 +1455,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
        BLIT32(CR, BT, CR{BA} && CR{BB});
-       ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
+       PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
 
 0.19,6.BT,11.BA,16.BB,21.449,31./:XL::cror:Condition Register OR
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
@@ -1445,7 +1463,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
        BLIT32(CR, BT, CR{BA} || CR{BB});
-       ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
+       PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
 
 0.19,6.BT,11.BA,16.BB,21.193,31./:XL::crxor:Condition Register XOR
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
@@ -1453,7 +1471,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
        BLIT32(CR, BT, CR{BA} != CR{BB});
-       ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
+       PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
 
 0.19,6.BT,11.BA,16.BB,21.225,31./:XL::crnand:Condition Register NAND
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
@@ -1461,7 +1479,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
        BLIT32(CR, BT, !(CR{BA} && CR{BB}));
-       ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
+       PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
 
 0.19,6.BT,11.BA,16.BB,21.33,31./:XL::crnor:Condition Register NOR
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
@@ -1469,7 +1487,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
        BLIT32(CR, BT, !(CR{BA} || CR{BB}));
-       ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
+       PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
 
 0.19,6.BT,11.BA,16.BB,21.289,31./:XL::creqv:Condition Register Equivalent
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
@@ -1477,7 +1495,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
        BLIT32(CR, BT, CR{BA} == CR{BB});
-       ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
+       PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
 
 0.19,6.BT,11.BA,16.BB,21.129,31./:XL::crandc:Condition Register AND with Complement
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
@@ -1485,7 +1503,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
        BLIT32(CR, BT, CR{BA} && !CR{BB});
-       ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
+       PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
 
 0.19,6.BT,11.BA,16.BB,21.417,31./:XL::crorc:Condition Register OR with Complement
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
@@ -1493,7 +1511,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
        BLIT32(CR, BT, CR{BA} || !CR{BB});
-       ppc_insn_cr2(my_index, processor, cpu_model(processor), BT, BIT32_BA, BIT32_BB);
+       PPC_INSN_CR(BT_BITMASK, BA_BITMASK | BB_BITMASK);
 
 #
 # I.2.4.4 Condition Register Field Instruction
@@ -1504,7 +1522,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_BPU,   PPC_UNIT_BPU,   1,  1,  0
        MBLIT32(CR, 4*BF, 4*BF+3, EXTRACTED32(CR, 4*BFA, 4*BFA+3));
-       ppc_insn_cr1(my_index, processor, cpu_model(processor), BF, BFA);
+       PPC_INSN_CR(BF_BITMASK, 1 << BFA);
 
 
 #
@@ -2962,13 +2980,13 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 # I.3.3.14 Move to/from System Register Instructions
 #
 
-0.31,6.RS,11.spr,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
+0.31,6.RS,11.SPR,21.467,31./:XFX::mtspr %SPR, %RS:Move to Special Purpose Register
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0
 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  1,  1,  0
-       int n = (spr{5:9} << 5) | spr{0:4};
-       if (spr{0} && IS_PROBLEM_STATE(processor))
+       int n = (SPR{5:9} << 5) | SPR{0:4};
+       if (SPR{0} && IS_PROBLEM_STATE(processor))
          program_interrupt(processor, cia,
                            privileged_instruction_program_interrupt);
        else if (!spr_is_valid(n)
@@ -3006,13 +3024,13 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
        }
        PPC_INSN_TO_SPR(RS_BITMASK, n);
 
-0.31,6.RT,11.spr,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
+0.31,6.RT,11.SPR,21.339,31./:XFX::mfspr %RT, %SPR:Move from Special Purpose Register
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *603e:PPC_UNIT_SRU,   PPC_UNIT_SRU,   1,  1,  0
 *604: PPC_UNIT_MCIU,  PPC_UNIT_MCIU,  3,  3,  0
-       int n = (spr{5:9} << 5) | spr{0:4};
-       if (spr{0} && IS_PROBLEM_STATE(processor))
+       int n = (SPR{5:9} << 5) | SPR{0:4};
+       if (SPR{0} && IS_PROBLEM_STATE(processor))
          program_interrupt(processor, cia,
                            privileged_instruction_program_interrupt);
        else if (!spr_is_valid(n))
@@ -3041,7 +3059,7 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
          }
          CR = (MASKED(*rS, 32, 63) & mask) | (CR & ~mask);
        }
-       ppc_insn_mtcr(my_index, processor, cpu_model(processor), rS, FXM);
+       PPC_INSN_MTCR(RS_BITMASK, FXM);
 
 0.31,6.BF,9./,11./,16./,21.512,31./:X:::Move to Condition Register from XER
 
@@ -4370,8 +4388,8 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
 # III.3.4.1 Move to/from System Register Instructions
 #
 
-#0.31,6.RS,11.spr,21.467,31./:XFX:::Move To Special Purpose Register
-#0.31,6.RT,11.spr,21.339,31./:XFX:::Move From Special Purpose Register
+#0.31,6.RS,11.SPR,21.467,31./:XFX:::Move To Special Purpose Register
+#0.31,6.RT,11.SPR,21.339,31./:XFX:::Move From Special Purpose Register
 0.31,6.RS,11./,16./,21.146,31./:X:::Move To Machine State Register
 *601: PPC_UNIT_IU,    PPC_UNIT_IU,    1,  1,  0
 *603: PPC_UNIT_SRU,   PPC_UNIT_SRU,   2,  2,  0