Sort instruction names; Add igen -R option; count # of CRs that mtcrf moved

This commit is contained in:
Michael Meissner 1995-11-25 01:35:14 +00:00
parent 63caaafa5b
commit f2181eff5f
6 changed files with 378 additions and 261 deletions

View 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.

90
sim/ppc/configure vendored
View File

@ -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

View 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"

View File

@ -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

View File

@ -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");
}

View File

@ -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 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 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
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;
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);
return;
}
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;
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;
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);
for (f = 0; f < 8; f++) {
if (FXM & (0x80 >> f)) {
cr_mask |= (1 << f);
nr_crs++;
}
}
/* 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;
}
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;
while (((model_ptr->int_busy & int_mask) | (model_ptr->cr_fpscr_busy & cr_mask)) != 0) {
if (WITH_TRACE && ppc_trace[trace_model])
model_trace_make_busy(model_ptr, 0, 0, cr_mask);
model_trace_busy_p(model_ptr, int_mask, 0, cr_mask, PPC_NO_SPR);
model_ptr->nr_stalls_data++;
model_new_cycle(model_ptr);
}
# 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);
}
busy_ptr = model_wait_for_unit(index, model_ptr, &model_ptr->timing[index]);
model_make_cr_reg_busy(model_ptr, busy_ptr, crD);
}
# 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