mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
Sort instruction names; Add igen -R option; count # of CRs that mtcrf moved
This commit is contained in:
parent
63caaafa5b
commit
f2181eff5f
@ -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
90
sim/ppc/configure
vendored
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user