diff options
-rw-r--r-- | sim/ppc/ChangeLog | 5 | ||||
-rwxr-xr-x | sim/ppc/configure | 90 | ||||
-rw-r--r-- | sim/ppc/configure.in | 7 | ||||
-rw-r--r-- | sim/ppc/igen.c | 63 | ||||
-rw-r--r-- | sim/ppc/mon.c | 58 | ||||
-rw-r--r-- | sim/ppc/ppc-instructions | 412 |
6 files changed, 376 insertions, 259 deletions
diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index 15a9bc6..89f8acd 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -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. diff --git a/sim/ppc/configure b/sim/ppc/configure index 047100d..e9f9358 100755 --- a/sim/ppc/configure +++ b/sim/ppc/configure @@ -38,6 +38,8 @@ ac_help="$ac_help 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 --enable-sim-hostbitsize=32|64 Specify host bitsize (32 or 64)." @@ -58,11 +60,11 @@ ac_help="$ac_help 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 @@ -1157,6 +1179,7 @@ fi + for ac_func in getrusage do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 @@ -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 diff --git a/sim/ppc/configure.in b/sim/ppc/configure.in index d59f9c2..b884544 100644 --- a/sim/ppc/configure.in +++ b/sim/ppc/configure.in @@ -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" diff --git a/sim/ppc/igen.c b/sim/ppc/igen.c index ddec166..d3f87bb 100644 --- a/sim/ppc/igen.c +++ b/sim/ppc/igen.c @@ -35,6 +35,10 @@ #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 diff --git a/sim/ppc/mon.c b/sim/ppc/mon.c index 10d0bbc..d9f515b 100644 --- a/sim/ppc/mon.c +++ b/sim/ppc/mon.c @@ -43,6 +43,10 @@ #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"); } diff --git a/sim/ppc/ppc-instructions b/sim/ppc/ppc-instructions index 555a38c..4631f5f 100644 --- a/sim/ppc/ppc-instructions +++ b/sim/ppc/ppc-instructions @@ -75,40 +75,72 @@ # 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 { @@ -165,6 +197,7 @@ 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 */ @@ -223,6 +256,17 @@ "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", + }; # 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; -# 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); - - # 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); + 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 |