aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorMichael Meissner <gnu@the-meissners.org>1995-11-16 21:42:27 +0000
committerMichael Meissner <gnu@the-meissners.org>1995-11-16 21:42:27 +0000
commit84bbbc3577f6191dca8be835e91c742f4ca865fd (patch)
tree81ce2e2b6c8b737419b0d1d1e899a6e873402f9e /sim
parentcd2b240203746798651ee052ac0ce7bd31a9263d (diff)
downloadfsf-binutils-gdb-84bbbc3577f6191dca8be835e91c742f4ca865fd.zip
fsf-binutils-gdb-84bbbc3577f6191dca8be835e91c742f4ca865fd.tar.gz
fsf-binutils-gdb-84bbbc3577f6191dca8be835e91c742f4ca865fd.tar.bz2
Delete old functional_unit support; Add --enable-sim-model-issue; Monitor branch prediction success
Diffstat (limited to 'sim')
-rw-r--r--sim/ppc/ChangeLog26
-rw-r--r--sim/ppc/configure.in24
-rw-r--r--sim/ppc/cpu.c19
-rw-r--r--sim/ppc/function_unit.c611
-rw-r--r--sim/ppc/function_unit.h71
-rw-r--r--sim/ppc/igen.c14
-rw-r--r--sim/ppc/mon.c2
-rw-r--r--sim/ppc/ppc-instructions92
8 files changed, 131 insertions, 728 deletions
diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog
index 3b12484..878e269 100644
--- a/sim/ppc/ChangeLog
+++ b/sim/ppc/ChangeLog
@@ -22,6 +22,32 @@ Thu Nov 16 09:52:26 1995 Michael Meissner <meissner@tiktok.cygnus.com>
* mon.c (mon_issue): Pass processor argument to model_issue.
+ * Makefile.in: Delete all function unit support, since the newer
+ table driven model support replaces it.
+ * cpu.{c,h}: Ditto.
+ * mon.c: Ditto.
+ * inline.{c,h}: Ditto.
+ * std-config.h: Ditto.
+ * options.c: Ditto.
+ * configure{,.in}: Ditto.
+ * Makefile.in: Ditto.
+ * psim.c: Ditto.
+ * function_unit.{c,h}: Delete these now usused files.
+
+ * std-config.h (WITH_MODEL_ISSUE): Add new macro on whether to
+ trace instructions in a model specific manor.
+ * options.c (print_options): Print it out.
+ * configure{,.in}: Add --enable-sim-model-issue option.
+ * Makefile.in: Add --enable-sim-model-issue flags.
+ * igen.c (lf_print_c_semantic): Add call to mon_issue here. Check
+ for WITH_MODEL_ISSUE.
+ * mon.c (mon_issue): Remove call to mon_issue_here.
+
+ * ppc-instructions: Move branch tracing to the actual branch
+ instructions, rather than testing it in model_issue. Add code to
+ code successful/unsuccessful branch predictions, and the number of
+ conditional branches that fell through.
+
Wed Nov 15 17:32:13 1995 Michael Meissner <meissner@tiktok.cygnus.com>
* cpu.h (cpu_model): Add declaration.
diff --git a/sim/ppc/configure.in b/sim/ppc/configure.in
index acb0442..d59f9c2 100644
--- a/sim/ppc/configure.in
+++ b/sim/ppc/configure.in
@@ -329,17 +329,6 @@ if test x"$silent" != x"yes" && test x"$sim_mon" != x""; then
echo "Setting monitor flags = $sim_mon" 6>&1
fi],[sim_mon=""])dnl
-AC_ARG_ENABLE(sim-function-unit,
-[ --enable-sim-function-unit Specify whether detailed functional unit support is built.],
-[case "${enableval}" in
- yes) sim_func="-DWITH_FUNCTION_UNIT=1";;
- no) sim_func="-DWITH_FUNCTION_UNIT=0";;
- *) AC_MSG_ERROR("--enable-sim-function-unit does not take a value"); 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],[sim_func=""])dnl
-
AC_ARG_ENABLE(sim-model,
[ --enable-sim-model=which Specify PowerPC to model.],
[case "${enableval}" in
@@ -360,6 +349,17 @@ if test x"$silent" != x"yes" && test x"$sim_default_model" != x""; then
echo "Setting default-model flags = $sim_default_model" 6>&1
fi],[sim_model=""])dnl
+AC_ARG_ENABLE(sim-model-issue,
+[ --enable-sim-model-issue Specify whether to simulate model specific actions],
+[case "${enableval}" in
+ yes) sim_model_issue="-DWITH_MODEL_ISSUE=1";;
+ no) sim_model_issue="-DWITH_MODEL_ISSUE=0";;
+ *) AC_MSG_ERROR("--enable-sim-model-issue does not take a value"); sim_model_issue="";;
+esac
+if test x"$silent" != x"yes"; then
+ echo "Setting model-issue flags = $sim_model_issue" 6>&1
+fi],[sim_model_issue=""])dnl
+
AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../..)
AC_CANONICAL_SYSTEM
AC_ARG_PROGRAM
@@ -398,9 +398,9 @@ AC_SUBST(sim_trace)
AC_SUBST(sim_assert)
AC_SUBST(sim_reserved)
AC_SUBST(sim_monitor)
-AC_SUBST(sim_func)
AC_SUBST(sim_model)
AC_SUBST(sim_default_model)
+AC_SUBST(sim_model_issue)
AC_CHECK_FUNCS(getrusage)
diff --git a/sim/ppc/cpu.c b/sim/ppc/cpu.c
index 6defe2f..33094fe 100644
--- a/sim/ppc/cpu.c
+++ b/sim/ppc/cpu.c
@@ -62,9 +62,6 @@ struct _cpu {
event_queue *events;
int cpu_nr;
- /* Current functional unit information */
- function_unit *func_unit;
-
/* Current CPU model information */
model_data *model_ptr;
@@ -107,10 +104,6 @@ cpu_create(psim *system,
processor->cpu_nr = cpu_nr;
processor->monitor = monitor;
- /* Create function unit if desired */
- if (WITH_FUNCTION_UNIT)
- processor->func_unit = function_unit_create ();
-
return processor;
}
@@ -121,9 +114,6 @@ cpu_init(cpu *processor)
memset(&processor->regs, 0, sizeof(processor->regs));
/* FIXME - should any of VM be inited also ? */
- if (WITH_FUNCTION_UNIT)
- function_unit_init (processor->func_unit);
-
model_init (processor, processor->model_ptr);
}
@@ -154,12 +144,6 @@ cpu_monitor(cpu *processor)
return processor->monitor;
}
-INLINE_CPU function_unit *
-cpu_function_unit(cpu *processor)
-{
- return processor->func_unit;
-}
-
INLINE_CPU model_data *
cpu_model(cpu *processor)
{
@@ -263,9 +247,6 @@ cpu_halt(cpu *processor,
signal);
}
else {
- if (WITH_FUNCTION_UNIT)
- function_unit_halt(processor, processor->func_unit);
-
model_halt(processor, processor->model_ptr);
processor->program_counter = cia;
psim_halt(processor->system, processor->cpu_nr, cia, reason, signal);
diff --git a/sim/ppc/function_unit.c b/sim/ppc/function_unit.c
deleted file mode 100644
index a4f2768..0000000
--- a/sim/ppc/function_unit.c
+++ /dev/null
@@ -1,611 +0,0 @@
-/* This file is part of the program psim.
-
- Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- */
-
-
-#ifndef _FUNCTION_UNIT_C_
-#define _FUNCTION_UNIT_C_
-
-#ifndef STATIC_INLINE_FUNCTION_UNIT
-#define STATIC_INLINE_FUNCTION_UNIT STATIC_INLINE
-#endif
-
-
-#include "basics.h"
-#include "cpu.h"
-#include "function_unit.h"
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-typedef enum _unit_index {
- UNIT_UNKNOWN, /* unknown functional unit */
- UNIT_INT, /* integer functional unit */
- UNIT_SINT, /* integer or SRU functional unit */
- UNIT_CINT, /* complex integer functional unit */
- UNIT_FPU, /* floating point functional unit */
- UNIT_MEM, /* memory functional unit */
- UNIT_BRANCH, /* branch functional unit */
- UNIT_SREG, /* system register functional unit */
- NR_UNITS
-} unit_index;
-
-static const char *unit_names[] = {
- "unknown functional unit instruction", /* UNIT_UNKNOWN */
- "int functional unit instruction", /* UNIT_INT */
- "int or SRU functional unit instruction", /* UNIT_SINT */
- "complex int functional unit instruction", /* UNIT_CINT */
- "floating point functional unit instruction", /* UNIT_FPU */
- "memory function unit instruction", /* UNIT_MEM */
- "branch functional unit instruction", /* UNIT_BRANCH */
- "system register functional unit instruction", /* UNIT_SREG */
-};
-
-typedef struct _timing {
- itable_index index; /* instruction # */
- unit_index unit; /* functional unit */
- int cycles; /* # cycles */
- unsigned flags; /* random other flags */
-} timing;
-
-struct _function_unit {
- unsigned_word old_program_counter;
- unsigned nr_branches;
- unsigned nr_stalls;
- unsigned nr_units[ (int)NR_UNITS ];
- struct {
- unit_index unit;
- int cycles;
- unsigned flags;
- } time[ (int)nr_itable_entries ];
-};
-
-/* Flags used in timing info */
-
-#define FUNC_LOAD 0x00000001 /* this is a load */
-#define FUNC_STORE 0x00000002 /* this is a store */
-
-
-/* 603 timings */
-static timing time_603[] = {
- /* Instruction index Function unit Cycles Flags */
- { itable_AND, UNIT_INT, 1, 0 },
- { itable_AND_Immediate, UNIT_INT, 1, 0 },
- { itable_AND_Immediate_Shifted, UNIT_INT, 1, 0 },
- { itable_AND_with_Complement, UNIT_INT, 1, 0 },
- { itable_Add, UNIT_SINT, 1, 0 },
- { itable_Add_Carrying, UNIT_INT, 1, 0 },
- { itable_Add_Extended, UNIT_INT, 1, 0 },
- { itable_Add_Immediate, UNIT_SINT, 1, 0 },
- { itable_Add_Immediate_Carrying, UNIT_INT, 1, 0 },
- { itable_Add_Immediate_Carrying_and_Record, UNIT_INT, 1, 0 },
- { itable_Add_Immediate_Shifted, UNIT_SINT, 1, 0 },
- { itable_Add_to_Minus_One_Extended, UNIT_INT, 1, 0 },
- { itable_Add_to_Zero_Extended, UNIT_INT, 1, 0 },
- { itable_Branch, UNIT_BRANCH, 1, 0 },
- { itable_Branch_Conditional, UNIT_BRANCH, 1, 0 },
- { itable_Branch_Conditional_to_Count_Register, UNIT_BRANCH, 1, 0 },
- { itable_Branch_Conditional_to_Link_Register, UNIT_BRANCH, 1, 0 },
- { itable_Compare, UNIT_SINT, 1, 0 },
- { itable_Compare_Immediate, UNIT_SINT, 1, 0 },
- { itable_Compare_Logical, UNIT_SINT, 1, 0 },
- { itable_Compare_Logical_Immediate, UNIT_SINT, 1, 0 },
- { itable_Condition_Register_AND, UNIT_SREG, 1, 0 },
- { itable_Condition_Register_AND_with_Complement, UNIT_SREG, 1, 0 },
- { itable_Condition_Register_Equivalent, UNIT_SREG, 1, 0 },
- { itable_Condition_Register_NAND, UNIT_SREG, 1, 0 },
- { itable_Condition_Register_NOR, UNIT_SREG, 1, 0 },
- { itable_Condition_Register_OR, UNIT_SREG, 1, 0 },
- { itable_Condition_Register_OR_with_Complement, UNIT_SREG, 1, 0 },
- { itable_Condition_Register_XOR, UNIT_SREG, 1, 0 },
- { itable_Count_Leading_Zeros_Word, UNIT_INT, 1, 0 },
- { itable_Data_Cache_Block_Flush, UNIT_MEM, 5, 0 },
- { itable_Data_Cache_Block_Invalidate, UNIT_MEM, 2, 0 },
- { itable_Data_Cache_Block_Store, UNIT_MEM, 5, 0 },
- { itable_Data_Cache_Block_Touch, UNIT_MEM, 2, 0 },
- { itable_Data_Cache_Block_Touch_for_Store, UNIT_MEM, 2, 0 },
- { itable_Data_Cache_Block_set_to_Zero, UNIT_MEM, 10, 0 },
- { itable_Divide_Word, UNIT_INT, 37, 0 },
- { itable_Divide_Word_Unsigned, UNIT_INT, 37, 0 },
- { itable_Enforce_Inorder_Execution_of_IO, UNIT_SREG, 1, 0 },
- { itable_Equivalent, UNIT_INT, 1, 0 },
- { itable_Extend_Sign_Byte, UNIT_INT, 1, 0 },
- { itable_Extend_Sign_Half_Word, UNIT_INT, 1, 0 },
- { itable_External_Control_In_Word_Indexed, UNIT_MEM, 2, 0 },
- { itable_External_Control_Out_Word_Indexed, UNIT_MEM, 2, 0 },
- { itable_Floating_Absolute_Value, UNIT_FPU, 1, 0 },
- { itable_Floating_Add, UNIT_FPU, 1, 0 },
- { itable_Floating_Add_Single, UNIT_FPU, 1, 0 },
- { itable_Floating_Compare_Ordered, UNIT_FPU, 1, 0 },
- { itable_Floating_Compare_Unordered, UNIT_FPU, 1, 0 },
- { itable_Floating_Convert_To_Integer_Word, UNIT_FPU, 1, 0 },
- { itable_Floating_Convert_To_Integer_Word_with_round_towards_Zero, UNIT_FPU, 1, 0 },
- { itable_Floating_Divide, UNIT_FPU, 33, 0 },
- { itable_Floating_Divide_Single, UNIT_FPU, 18, 0 },
- { itable_Floating_Move_Register, UNIT_FPU, 1, 0 },
- { itable_Floating_Multiply, UNIT_FPU, 2, 0 },
- { itable_Floating_MultiplyAdd, UNIT_FPU, 2, 0 },
- { itable_Floating_MultiplyAdd_Single, UNIT_FPU, 1, 0 },
- { itable_Floating_MultiplySubtract, UNIT_FPU, 2, 0 },
- { itable_Floating_MultiplySubtract_Single, UNIT_FPU, 1, 0 },
- { itable_Floating_Multiply_Single, UNIT_FPU, 1, 0 },
- { itable_Floating_Negate, UNIT_FPU, 1, 0 },
- { itable_Floating_Negative_Absolute_Value, UNIT_FPU, 1, 0 },
- { itable_Floating_Negative_MultiplyAdd, UNIT_FPU, 2, 0 },
- { itable_Floating_Negative_MultiplyAdd_Single, UNIT_FPU, 1, 0 },
- { itable_Floating_Negative_MultiplySubtract, UNIT_FPU, 2, 0 },
- { itable_Floating_Negative_MultiplySubtract_Single, UNIT_FPU, 1, 0 },
- { itable_Floating_Reciprocal_Estimate_Single, UNIT_FPU, 18, 0 },
- { itable_Floating_Reciprocal_Square_Root_Estimate, UNIT_FPU, 1, 0 },
- { itable_Floating_Round_to_SinglePrecision, UNIT_FPU, 1, 0 },
- { itable_Floating_Select, UNIT_FPU, 1, 0 },
- { itable_Floating_Square_Root, UNIT_UNKNOWN, 0, 0 },
- { itable_Floating_Square_Root_Single, UNIT_UNKNOWN, 0, 0 },
- { itable_Floating_Subtract, UNIT_FPU, 1, 0 },
- { itable_Floating_Subtract_Single, UNIT_FPU, 1, 0 },
- { itable_Instruction_Cache_Block_Invalidate, UNIT_MEM, 3, 0 },
- { itable_Instruction_Synchronize, UNIT_SREG, 1, 0 },
- { itable_Load_Byte_and_Zero, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Byte_and_Zero_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Byte_and_Zero_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Byte_and_Zero_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_FloatingPoint_Double, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_FloatingPoint_Double_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_FloatingPoint_Double_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_FloatingPoint_Double_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_FloatingPoint_Single, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_FloatingPoint_Single_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_FloatingPoint_Single_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_FloatingPoint_Single_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_Algebraic, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_Algebraic_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_Algebraic_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_Algebraic_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_ByteReverse_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_and_Zero, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_and_Zero_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_and_Zero_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_and_Zero_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Multiple_Word, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_String_Word_Immediate, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_String_Word_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_And_Reserve_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_ByteReverse_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_and_Zero, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_and_Zero_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_and_Zero_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_and_Zero_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Move_Condition_Register_Field, UNIT_SREG, 1, 0 },
- { itable_Move_From_Condition_Register, UNIT_SREG, 1, 0 },
- { itable_Move_From_FPSCR, UNIT_FPU, 1, 0 },
- { itable_Move_From_Machine_State_Register, UNIT_SREG, 1, 0 },
- { itable_Move_From_Segment_Register, UNIT_SREG, 3, 0 },
- { itable_Move_From_Segment_Register_Indirect, UNIT_SREG, 1, 0 },
- { itable_Move_From_Time_Base, UNIT_SREG, 1, 0 },
- { itable_Move_To_FPSCR_Bit_0, UNIT_FPU, 1, 0 },
- { itable_Move_To_FPSCR_Bit_1, UNIT_FPU, 1, 0 },
- { itable_Move_To_FPSCR_Field_Immediate, UNIT_FPU, 1, 0 },
- { itable_Move_To_FPSCR_Fields, UNIT_FPU, 1, 0 },
- { itable_Move_To_Machine_State_Register, UNIT_SREG, 2, 0 },
- { itable_Move_To_Segment_Register, UNIT_SREG, 2, 0 },
- { itable_Move_To_Segment_Register_Indirect, UNIT_SREG, 2, 0 },
- { itable_Move_from_Special_Purpose_Register, UNIT_SREG, 1, 0 },
- { itable_Move_to_Condition_Register_Fields, UNIT_SREG, 1, 0 },
- { itable_Move_to_Condition_Register_from_FPSCR, UNIT_FPU, 1, 0 },
- { itable_Move_to_Condition_Register_from_XER, UNIT_SREG, 1, 0 },
- { itable_Move_to_Special_Purpose_Register, UNIT_SREG, 1, 0 },
- { itable_Multiply_High_Word, UNIT_INT, 5, 0 },
- { itable_Multiply_High_Word_Unsigned, UNIT_INT, 6, 0 },
- { itable_Multiply_Low_Immediate, UNIT_INT, 3, 0 },
- { itable_Multiply_Low_Word, UNIT_INT, 5, 0 },
- { itable_NAND, UNIT_INT, 1, 0 },
- { itable_NOR, UNIT_INT, 1, 0 },
- { itable_Negate, UNIT_INT, 1, 0 },
- { itable_OR, UNIT_INT, 1, 0 },
- { itable_OR_Immediate, UNIT_INT, 1, 0 },
- { itable_OR_Immediate_Shifted, UNIT_INT, 1, 0 },
- { itable_OR_with_Complement, UNIT_INT, 1, 0 },
- { itable_Return_From_Interrupt, UNIT_SREG, 3, 0 },
- { itable_Rotate_Left_Word_Immediate_then_AND_with_Mask, UNIT_INT, 1, 0 },
- { itable_Rotate_Left_Word_Immediate_then_Mask_Insert, UNIT_INT, 1, 0 },
- { itable_Rotate_Left_Word_then_AND_with_Mask, UNIT_INT, 1, 0 },
- { itable_Shift_Left_Word, UNIT_INT, 1, 0 },
- { itable_Shift_Right_Algebraic_Word, UNIT_INT, 1, 0 },
- { itable_Shift_Right_Algebraic_Word_Immediate, UNIT_INT, 1, 0 },
- { itable_Shift_Right_Word, UNIT_INT, 1, 0 },
- { itable_Store_Byte, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Byte_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Byte_with_Update, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Byte_with_Update_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_FloatingPoint_Double, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_FloatingPoint_Double_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_FloatingPoint_Double_with_Update, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_FloatingPoint_Double_with_Update_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_FloatingPoint_Single, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_FloatingPoint_Single_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_FloatingPoint_Single_with_Update, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_FloatingPoint_Single_with_Update_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_FloatingPoint_as_Integer_Word_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Half_Word, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Half_Word_ByteReversed_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Half_Word_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Half_Word_with_Update, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Half_Word_with_Update_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Multiple_Word, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_String_Word_Immedate, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_String_Word_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Word, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Word_ByteReversed_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Word_Conditional_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Word_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Word_with_Update, UNIT_MEM, 1, FUNC_STORE },
- { itable_Store_Word_with_Update_Indexed, UNIT_MEM, 1, FUNC_STORE },
- { itable_Subtract_From, UNIT_INT, 1, 0 },
- { itable_Subtract_From_Carrying, UNIT_INT, 1, 0 },
- { itable_Subtract_From_Extended, UNIT_INT, 1, 0 },
- { itable_Subtract_From_Immediate_Carrying, UNIT_INT, 1, 0 },
- { itable_Subtract_From_Minus_One_Extended, UNIT_INT, 1, 0 },
- { itable_Subtract_from_Zero_Extended, UNIT_INT, 1, 0 },
- { itable_Synchronize, UNIT_SREG, 3, 0 },
- { itable_System_Call, UNIT_MEM, 3, 0 },
- { itable_TLB_Invalidate_All, UNIT_MEM, 3, 0 },
- { itable_TLB_Invalidate_Entry, UNIT_MEM, 3, 0 },
- { itable_TLB_Sychronize, UNIT_MEM, 3, 0 },
- { itable_Trap_Word, UNIT_INT, 2, 0 },
- { itable_Trap_Word_Immediate, UNIT_INT, 2, 0 },
- { itable_XOR, UNIT_INT, 1, 0 },
- { itable_XOR_Immediate, UNIT_INT, 1, 0 },
- { itable_XOR_Immediate_Shifted, UNIT_INT, 1, 0 },
- { nr_itable_entries, UNIT_UNKNOWN, -1, 0 },
-};
-
-
-/* 604 timings */
-static timing time_604[] = {
- /* Instruction index Function unit Cycles Flags */
- { itable_AND, UNIT_INT, 1, 0 },
- { itable_AND_Immediate, UNIT_INT, 1, 0 },
- { itable_AND_Immediate_Shifted, UNIT_INT, 1, 0 },
- { itable_AND_with_Complement, UNIT_INT, 1, 0 },
- { itable_Add, UNIT_INT, 1, 0 },
- { itable_Add_Carrying, UNIT_INT, 1, 0 },
- { itable_Add_Extended, UNIT_INT, 1, 0 },
- { itable_Add_Immediate, UNIT_INT, 1, 0 },
- { itable_Add_Immediate_Carrying, UNIT_INT, 1, 0 },
- { itable_Add_Immediate_Carrying_and_Record, UNIT_INT, 1, 0 },
- { itable_Add_Immediate_Shifted, UNIT_INT, 1, 0 },
- { itable_Add_to_Minus_One_Extended, UNIT_INT, 1, 0 },
- { itable_Add_to_Zero_Extended, UNIT_INT, 1, 0 },
- { itable_Branch, UNIT_BRANCH, 1, 0 },
- { itable_Branch_Conditional, UNIT_BRANCH, 1, 0 },
- { itable_Branch_Conditional_to_Count_Register, UNIT_BRANCH, 1, 0 },
- { itable_Branch_Conditional_to_Link_Register, UNIT_BRANCH, 1, 0 },
- { itable_Compare, UNIT_INT, 1, 0 },
- { itable_Compare_Immediate, UNIT_INT, 1, 0 },
- { itable_Compare_Logical, UNIT_INT, 1, 0 },
- { itable_Compare_Logical_Immediate, UNIT_INT, 1, 0 },
- { itable_Condition_Register_AND, UNIT_INT, 1, 0 },
- { itable_Condition_Register_AND_with_Complement, UNIT_INT, 1, 0 },
- { itable_Condition_Register_Equivalent, UNIT_INT, 1, 0 },
- { itable_Condition_Register_NAND, UNIT_INT, 1, 0 },
- { itable_Condition_Register_NOR, UNIT_INT, 1, 0 },
- { itable_Condition_Register_OR, UNIT_INT, 1, 0 },
- { itable_Condition_Register_OR_with_Complement, UNIT_INT, 1, 0 },
- { itable_Condition_Register_XOR, UNIT_INT, 1, 0 },
- { itable_Count_Leading_Zeros_Word, UNIT_INT, 1, 0 },
- { itable_Data_Cache_Block_Flush, UNIT_MEM, 1, 0 },
- { itable_Data_Cache_Block_Invalidate, UNIT_MEM, 1, 0 },
- { itable_Data_Cache_Block_Store, UNIT_MEM, 1, 0 },
- { itable_Data_Cache_Block_Touch, UNIT_MEM, 1, 0 },
- { itable_Data_Cache_Block_Touch_for_Store, UNIT_MEM, 1, 0 },
- { itable_Data_Cache_Block_set_to_Zero, UNIT_MEM, 3, 0 },
- { itable_Divide_Word, UNIT_CINT, 20, 0 },
- { itable_Divide_Word_Unsigned, UNIT_CINT, 20, 0 },
- { itable_Enforce_Inorder_Execution_of_IO, UNIT_INT, 1, 0 },
- { itable_Equivalent, UNIT_INT, 1, 0 },
- { itable_Extend_Sign_Byte, UNIT_INT, 1, 0 },
- { itable_Extend_Sign_Half_Word, UNIT_INT, 1, 0 },
- { itable_External_Control_In_Word_Indexed, UNIT_MEM, 2, 0 },
- { itable_External_Control_Out_Word_Indexed, UNIT_MEM, 3, 0 },
- { itable_Floating_Absolute_Value, UNIT_FPU, 3, 0 },
- { itable_Floating_Add, UNIT_FPU, 3, 0 },
- { itable_Floating_Add_Single, UNIT_FPU, 3, 0 },
- { itable_Floating_Compare_Ordered, UNIT_FPU, 3, 0 },
- { itable_Floating_Compare_Unordered, UNIT_FPU, 3, 0 },
- { itable_Floating_Convert_To_Integer_Word, UNIT_FPU, 3, 0 },
- { itable_Floating_Convert_To_Integer_Word_with_round_towards_Zero, UNIT_FPU, 3, 0 },
- { itable_Floating_Divide, UNIT_FPU, 32, 0 },
- { itable_Floating_Divide_Single, UNIT_FPU, 18, 0 },
- { itable_Floating_Move_Register, UNIT_FPU, 3, 0 },
- { itable_Floating_Multiply, UNIT_FPU, 3, 0 },
- { itable_Floating_MultiplyAdd, UNIT_FPU, 3, 0 },
- { itable_Floating_MultiplyAdd_Single, UNIT_FPU, 3, 0 },
- { itable_Floating_MultiplySubtract, UNIT_FPU, 3, 0 },
- { itable_Floating_MultiplySubtract_Single, UNIT_FPU, 3, 0 },
- { itable_Floating_Multiply_Single, UNIT_FPU, 3, 0 },
- { itable_Floating_Negate, UNIT_FPU, 3, 0 },
- { itable_Floating_Negative_Absolute_Value, UNIT_FPU, 3, 0 },
- { itable_Floating_Negative_MultiplyAdd, UNIT_FPU, 3, 0 },
- { itable_Floating_Negative_MultiplyAdd_Single, UNIT_FPU, 3, 0 },
- { itable_Floating_Negative_MultiplySubtract, UNIT_FPU, 3, 0 },
- { itable_Floating_Negative_MultiplySubtract_Single, UNIT_FPU, 3, 0 },
- { itable_Floating_Reciprocal_Estimate_Single, UNIT_FPU, 18, 0 },
- { itable_Floating_Reciprocal_Square_Root_Estimate, UNIT_FPU, 3, 0 },
- { itable_Floating_Round_to_SinglePrecision, UNIT_FPU, 3, 0 },
- { itable_Floating_Select, UNIT_FPU, 3, 0 },
- { itable_Floating_Square_Root, UNIT_UNKNOWN, 0, 0 },
- { itable_Floating_Square_Root_Single, UNIT_UNKNOWN, 0, 0 },
- { itable_Floating_Subtract, UNIT_FPU, 3, 0 },
- { itable_Floating_Subtract_Single, UNIT_FPU, 3, 0 },
- { itable_Instruction_Cache_Block_Invalidate, UNIT_MEM, 1, 0 },
- { itable_Instruction_Synchronize, UNIT_INT, 1, 0 },
- { itable_Load_Byte_and_Zero, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Byte_and_Zero_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Byte_and_Zero_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Byte_and_Zero_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_FloatingPoint_Double, UNIT_MEM, 3, FUNC_LOAD },
- { itable_Load_FloatingPoint_Double_Indexed, UNIT_MEM, 3, FUNC_LOAD },
- { itable_Load_FloatingPoint_Double_with_Update, UNIT_MEM, 3, FUNC_LOAD },
- { itable_Load_FloatingPoint_Double_with_Update_Indexed, UNIT_MEM, 3, FUNC_LOAD },
- { itable_Load_FloatingPoint_Single, UNIT_MEM, 3, FUNC_LOAD },
- { itable_Load_FloatingPoint_Single_Indexed, UNIT_MEM, 3, FUNC_LOAD },
- { itable_Load_FloatingPoint_Single_with_Update, UNIT_MEM, 3, FUNC_LOAD },
- { itable_Load_FloatingPoint_Single_with_Update_Indexed, UNIT_MEM, 3, FUNC_LOAD },
- { itable_Load_Halfword_Algebraic, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_Algebraic_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_Algebraic_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_Algebraic_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_ByteReverse_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_and_Zero, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_and_Zero_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_and_Zero_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Halfword_and_Zero_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Multiple_Word, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_String_Word_Immediate, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_String_Word_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_And_Reserve_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_ByteReverse_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_and_Zero, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_and_Zero_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_and_Zero_with_Update, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Load_Word_and_Zero_with_Update_Indexed, UNIT_MEM, 2, FUNC_LOAD },
- { itable_Move_Condition_Register_Field, UNIT_BRANCH, 1, 0 },
- { itable_Move_From_Condition_Register, UNIT_CINT, 3, 0 },
- { itable_Move_From_FPSCR, UNIT_FPU, 3, 0 },
- { itable_Move_From_Machine_State_Register, UNIT_CINT, 3, 0 },
- { itable_Move_From_Segment_Register, UNIT_CINT, 3, 0 },
- { itable_Move_From_Segment_Register_Indirect, UNIT_CINT, 3, 0 },
- { itable_Move_From_Time_Base, UNIT_CINT, 3, 0 },
- { itable_Move_To_FPSCR_Bit_0, UNIT_FPU, 3, 0 },
- { itable_Move_To_FPSCR_Bit_1, UNIT_FPU, 3, 0 },
- { itable_Move_To_FPSCR_Field_Immediate, UNIT_FPU, 3, 0 },
- { itable_Move_To_FPSCR_Fields, UNIT_FPU, 3, 0 },
- { itable_Move_To_Machine_State_Register, UNIT_CINT, 1, 0 },
- { itable_Move_To_Segment_Register, UNIT_CINT, 1, 0 },
- { itable_Move_To_Segment_Register_Indirect, UNIT_CINT, 1, 0 },
- { itable_Move_from_Special_Purpose_Register, UNIT_CINT, 1, 0 },
- { itable_Move_to_Condition_Register_Fields, UNIT_CINT, 1, 0 },
- { itable_Move_to_Condition_Register_from_FPSCR, UNIT_FPU, 3, 0 },
- { itable_Move_to_Condition_Register_from_XER, UNIT_CINT, 3, 0 },
- { itable_Move_to_Special_Purpose_Register, UNIT_CINT, 1, 0 },
- { itable_Multiply_High_Word, UNIT_CINT, 4, 0 },
- { itable_Multiply_High_Word_Unsigned, UNIT_CINT, 4, 0 },
- { itable_Multiply_Low_Immediate, UNIT_CINT, 3, 0 },
- { itable_Multiply_Low_Word, UNIT_CINT, 4, 0 },
- { itable_NAND, UNIT_INT, 1, 0 },
- { itable_NOR, UNIT_INT, 1, 0 },
- { itable_Negate, UNIT_INT, 1, 0 },
- { itable_OR, UNIT_INT, 1, 0 },
- { itable_OR_Immediate, UNIT_INT, 1, 0 },
- { itable_OR_Immediate_Shifted, UNIT_INT, 1, 0 },
- { itable_OR_with_Complement, UNIT_INT, 1, 0 },
- { itable_Return_From_Interrupt, UNIT_INT, 3, 0 },
- { itable_Rotate_Left_Word_Immediate_then_AND_with_Mask, UNIT_INT, 1, 0 },
- { itable_Rotate_Left_Word_Immediate_then_Mask_Insert, UNIT_INT, 1, 0 },
- { itable_Rotate_Left_Word_then_AND_with_Mask, UNIT_INT, 1, 0 },
- { itable_Shift_Left_Word, UNIT_INT, 1, 0 },
- { itable_Shift_Right_Algebraic_Word, UNIT_INT, 1, 0 },
- { itable_Shift_Right_Algebraic_Word_Immediate, UNIT_INT, 1, 0 },
- { itable_Shift_Right_Word, UNIT_INT, 1, 0 },
- { itable_Store_Byte, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Byte_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Byte_with_Update, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Byte_with_Update_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_FloatingPoint_Double, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_FloatingPoint_Double_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_FloatingPoint_Double_with_Update, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_FloatingPoint_Double_with_Update_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_FloatingPoint_Single, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_FloatingPoint_Single_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_FloatingPoint_Single_with_Update, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_FloatingPoint_Single_with_Update_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_FloatingPoint_as_Integer_Word_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Half_Word, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Half_Word_ByteReversed_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Half_Word_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Half_Word_with_Update, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Half_Word_with_Update_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Multiple_Word, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_String_Word_Immedate, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_String_Word_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Word, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Word_ByteReversed_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Word_Conditional_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Word_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Word_with_Update, UNIT_MEM, 3, FUNC_STORE },
- { itable_Store_Word_with_Update_Indexed, UNIT_MEM, 3, FUNC_STORE },
- { itable_Subtract_From, UNIT_INT, 1, 0 },
- { itable_Subtract_From_Carrying, UNIT_INT, 1, 0 },
- { itable_Subtract_From_Extended, UNIT_INT, 1, 0 },
- { itable_Subtract_From_Immediate_Carrying, UNIT_INT, 1, 0 },
- { itable_Subtract_From_Minus_One_Extended, UNIT_INT, 1, 0 },
- { itable_Subtract_from_Zero_Extended, UNIT_INT, 1, 0 },
- { itable_Synchronize, UNIT_INT, 1, 0 },
- { itable_System_Call, UNIT_MEM, 1, 0 },
- { itable_TLB_Invalidate_All, UNIT_MEM, 1, 0 },
- { itable_TLB_Invalidate_Entry, UNIT_MEM, 1, 0 },
- { itable_TLB_Sychronize, UNIT_MEM, 1, 0 },
- { itable_Trap_Word, UNIT_INT, 1, 0 },
- { itable_Trap_Word_Immediate, UNIT_INT, 1, 0 },
- { itable_XOR, UNIT_INT, 1, 0 },
- { itable_XOR_Immediate, UNIT_INT, 1, 0 },
- { itable_XOR_Immediate_Shifted, UNIT_INT, 1, 0 },
- { nr_itable_entries, UNIT_UNKNOWN, -1, 0 },
-};
-
-
-INLINE_FUNCTION_UNIT function_unit *
-function_unit_create(void)
-{
- function_unit *new_func;
- timing *timing_ptr;
-
- if (!WITH_FUNCTION_UNIT)
- return (function_unit *)0;
-
- new_func = ZALLOC(function_unit);
-
- /* Get the model specific timing information */
- switch (CURRENT_PPC_MODEL) {
- default: timing_ptr = (timing *)0; break;
- case PPC_MODEL_603: timing_ptr = time_603; break;
- case PPC_MODEL_603e: timing_ptr = time_603; break;
- case PPC_MODEL_604: timing_ptr = time_604; break;
- }
-
- /* If we have it, provide model specific timing info */
- if (timing_ptr) {
- for (; timing_ptr->cycles >= 0; timing_ptr++) {
- int i = (int)timing_ptr->index;
- unit_index unit = timing_ptr->unit;
-
- /* The 603 as compared to the 603e doesn't support putting add/cmp instructions
- in the system register unit, so convert these instructions back to normal
- integer instructions. */
- if (CURRENT_PPC_MODEL == PPC_MODEL_603 && unit == UNIT_SINT)
- unit = UNIT_INT;
-
- new_func->time[i].unit = unit;
- new_func->time[i].cycles = timing_ptr->cycles;
- new_func->time[i].flags = timing_ptr->flags;
- }
- }
-
- return new_func;
-}
-
-INLINE_FUNCTION_UNIT void
-function_unit_init(function_unit *func_unit)
-{
- func_unit->old_program_counter = 0;
-}
-
-INLINE_FUNCTION_UNIT void
-function_unit_halt(cpu *processor,
- function_unit *func_unit)
-{
-}
-
-INLINE_FUNCTION_UNIT function_unit_print *
-function_unit_mon_info(function_unit *func_unit)
-{
- function_unit_print *head;
- function_unit_print *tail;
- int i;
-
- head = tail = ZALLOC(function_unit_print);
- tail->count = func_unit->nr_stalls;
- tail->name = "stall";
- tail->suffix_plural = "s";
- tail->suffix_singular = "";
-
- tail->next = ZALLOC(function_unit_print);
- tail = tail->next;
- tail->count = func_unit->nr_branches;
- tail->name = "branch";
- tail->suffix_plural = "es";
- tail->suffix_singular = "";
-
- for (i = 0; i < (int)NR_UNITS; i++) {
- if (func_unit->nr_units[i]) {
- tail->next = ZALLOC(function_unit_print);
- tail = tail->next;
- tail->count = func_unit->nr_units[i];
- tail->name = unit_names[i];
- tail->suffix_plural = "s";
- tail->suffix_singular = "";
- }
- }
-
- tail->next = (function_unit_print *)0;
- return head;
-}
-
-INLINE_FUNCTION_UNIT void
-function_unit_mon_free(function_unit *func_unit,
- function_unit_print *ptr)
-{
- function_unit_print *next;
-
- while (ptr) {
- next = ptr->next;
- free((void *)ptr);
- ptr = next;
- }
-}
-
-INLINE_FUNCTION_UNIT void
-function_unit_issue(itable_index index,
- function_unit *func_unit,
- unsigned_word cia)
-{
- if (func_unit->old_program_counter+4 != cia)
- func_unit->nr_branches++;
-
- func_unit->old_program_counter = cia;
- func_unit->nr_units[ (int)func_unit->time[ (int)index ].unit ]++;
-}
-
-INLINE_FUNCTION_UNIT void
-function_unit_model(const char *model)
-{
- if (!strcmp (model, "601"))
- current_ppc_model = PPC_MODEL_601;
- else if (!strcmp (model, "602"))
- current_ppc_model = PPC_MODEL_602;
- else if (!strcmp (model, "603"))
- current_ppc_model = PPC_MODEL_603;
- else if (!strcmp (model, "603e"))
- current_ppc_model = PPC_MODEL_603e;
- else if (!strcmp (model, "604"))
- current_ppc_model = PPC_MODEL_604;
- else if (!strcmp (model, "403"))
- current_ppc_model = PPC_MODEL_403;
- else if (!strcmp (model, "505"))
- current_ppc_model = PPC_MODEL_505;
- else if (!strcmp (model, "821"))
- current_ppc_model = PPC_MODEL_821;
- else if (!strcmp (model, "860"))
- current_ppc_model = PPC_MODEL_860;
- else
- error ("Unknown PowerPC model %s", model);
-}
-
-#endif /* _FUNCTION_UNIT_C_ */
diff --git a/sim/ppc/function_unit.h b/sim/ppc/function_unit.h
deleted file mode 100644
index 904abce..0000000
--- a/sim/ppc/function_unit.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* This file is part of the program psim.
-
- Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- */
-
-
-#ifndef _FUNCTION_UNIT_H_
-#define _FUNCTION_UNIT_H_
-
-#include "itable.h"
-
-#ifndef INLINE_FUNCTION_UNIT
-#define INLINE_FUNCTION_UNIT
-#endif
-
-/* basic types */
-
-typedef struct _function_unit function_unit;
-
-typedef struct _function_unit_print function_unit_print;
-struct _function_unit_print {
- function_unit_print *next;
- const char *name;
- const char *suffix_singular;
- const char *suffix_plural;
- unsigned count;
-};
-
-/* constructor */
-
-INLINE_FUNCTION_UNIT function_unit *function_unit_create
-(void);
-
-INLINE_FUNCTION_UNIT void function_unit_init
-(function_unit *func_unit);
-
-INLINE_FUNCTION_UNIT void function_unit_halt
-(cpu *processor,
- function_unit *func_unit);
-
-INLINE_FUNCTION_UNIT function_unit_print *function_unit_mon_info
-(function_unit *func_unit);
-
-INLINE_FUNCTION_UNIT void function_unit_mon_free
-(function_unit *func_unit,
- function_unit_print *ptr);
-
-INLINE_FUNCTION_UNIT void function_unit_issue
-(itable_index index,
- function_unit *func_unit,
- unsigned_word cia);
-
-INLINE_FUNCTION_UNIT void function_unit_model
-(const char *model);
-
-#endif /* _FUNCTION_UNIT_H_ */
diff --git a/sim/ppc/igen.c b/sim/ppc/igen.c
index 818c16f..07a825b 100644
--- a/sim/ppc/igen.c
+++ b/sim/ppc/igen.c
@@ -2119,16 +2119,26 @@ lf_print_c_semantic(lf *file,
if (!idecode_cache)
lf_print_c_validate(file, instruction, opcodes);
- /* generate the profileing call - this is delayed until after the
+ /* generate the profiling call - this is delayed until after the
instruction has been verified */
lf_printf(file, "\n");
- lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
+ lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE) {\n");
lf_printf(file, " mon_issue(");
lf_print_function_name(file,
instruction->file_entry->fields[insn_name],
NULL,
function_name_prefix_itable);
lf_printf(file, ", processor, cia);\n");
+ lf_printf(file, "\n");
+ lf_printf(file, " if (WITH_MODEL_ISSUE)\n");
+ lf_printf(file, " model_issue(");
+ lf_print_function_name(file,
+ instruction->file_entry->fields[insn_name],
+ NULL,
+ function_name_prefix_itable);
+ lf_printf(file, ", processor, cpu_model(processor), cia);\n");
+ lf_printf(file, "}\n");
+ lf_printf(file, "\n");
/* generate the code (or at least something */
if (instruction->file_entry->annex != NULL) {
diff --git a/sim/ppc/mon.c b/sim/ppc/mon.c
index 33d6b7e..10d0bbc 100644
--- a/sim/ppc/mon.c
+++ b/sim/ppc/mon.c
@@ -63,7 +63,6 @@ struct _cpu_mon {
unsigned unaligned_read_count;
unsigned unaligned_write_count;
unsigned event_count[nr_mon_events];
- function_unit_print *func_unit_print;
};
struct _mon {
@@ -107,7 +106,6 @@ mon_issue(itable_index index,
cpu_mon *monitor = cpu_monitor(processor);
ASSERT(index <= nr_itable_entries);
monitor->issue_count[index] += 1;
- model_issue(index, processor, cpu_model(processor), cia);
}
diff --git a/sim/ppc/ppc-instructions b/sim/ppc/ppc-instructions
index 05709e0..65b326f 100644
--- a/sim/ppc/ppc-instructions
+++ b/sim/ppc/ppc-instructions
@@ -104,8 +104,10 @@
struct _model_data {
const char *name; /* model name */
const model_time *timing; /* timing information */
- unsigned_word old_program_counter; /* previous PC */
unsigned nr_branches; /* # branches */
+ unsigned nr_branches_fallthrough; /* # conditional branches that fell through */
+ unsigned nr_branch_predict_trues; /* # branches predicted correctly */
+ unsigned nr_branch_predict_falses; /* # branches predicted incorrectly */
unsigned nr_units[nr_ppc_function_units]; /* function unit counts */
unsigned16 busy[nr_ppc_function_units]; /* how long until free */
};
@@ -139,10 +141,6 @@ void::model-function::model_init:cpu *processor, model_data *model_ptr
void::model-function::model_halt:cpu *processor, model_data *model_ptr
void::model-function::model_issue:itable_index index, cpu *processor, model_data *model_ptr, unsigned_word cia
- if (model_ptr->old_program_counter+4 != cia)
- model_ptr->nr_branches++;
-
- model_ptr->old_program_counter = cia;
model_ptr->nr_units[ (int)model_ptr->timing[ (int)index ].first_unit ]++;
/* Assume that any instruction we don't know about is illegal for this
@@ -162,6 +160,33 @@ model_print *::model-function::model_mon_info:model_data *model_ptr
tail->suffix_plural = "es";
tail->suffix_singular = "";
+ if (model_ptr->nr_branches_fallthrough) {
+ tail->next = ZALLOC(model_print);
+ tail = tail->next;
+ tail->count = model_ptr->nr_branches_fallthrough;
+ tail->name = "conditional branch";
+ tail->suffix_plural = "es fell through";
+ tail->suffix_singular = " fell through";
+ }
+
+ if (model_ptr->nr_branch_predict_trues) {
+ tail->next = ZALLOC(model_print);
+ tail = tail->next;
+ tail->count = model_ptr->nr_branch_predict_trues;
+ tail->name = "successful branch prediction";
+ tail->suffix_plural = "s";
+ tail->suffix_singular = "";
+ }
+
+ if (model_ptr->nr_branch_predict_falses) {
+ tail->next = ZALLOC(model_print);
+ tail = tail->next;
+ tail->count = model_ptr->nr_branch_predict_falses;
+ tail->name = "unsuccessful branch prediction";
+ tail->suffix_plural = "s";
+ tail->suffix_singular = "";
+ }
+
for (i = PPC_UNIT_BAD; i < nr_ppc_function_units; i++) {
if (model_ptr->nr_units[i]) {
tail->next = ZALLOC(model_print);
@@ -185,6 +210,17 @@ void::model-function::model_mon_info_free:model_data *model_ptr, model_print *pt
ptr = next;
}
+void::model-function::model_branches:model_data *model_ptr, int failed
+ if (failed)
+ model_ptr->nr_branches_fallthrough++;
+ else
+ model_ptr->nr_branches++;
+
+void::model-function::model_branch_predict:model_data *model_ptr, int success
+ if (success)
+ model_ptr->nr_branch_predict_trues++;
+ else
+ model_ptr->nr_branch_predict_falses++;
# The following (illegal) instruction is `known' by gen and is
# called when ever an illegal instruction is encountered
@@ -668,43 +704,77 @@ void::function::invalid_arithemetic_operation:cpu *processor, unsigned_word cia,
if (AA) NIA = IEA(EXTS(LI_0b00));
else NIA = IEA(CIA + EXTS(LI_0b00));
if (LK) LR = (spreg)CIA+4;
+ model_branches(cpu_model(processor), 1);
+
0.16,6.BO,11.BI,16.BD,30.AA,31.LK:B:t::Branch Conditional
*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
- int M, ctr_ok, cond_ok;
+ int M, ctr_ok, cond_ok, succeed;
if (is_64bit_implementation && is_64bit_mode) M = 0;
else M = 32;
if (!BO{2}) CTR = CTR - 1;
ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != (BO{3}));
cond_ok = BO{0} || ((CR{BI}) == (BO{1}));
- if (ctr_ok && cond_ok)
+ if (ctr_ok && cond_ok) {
if (AA) NIA = IEA(EXTS(BD_0b00));
else NIA = IEA(CIA + EXTS(BD_0b00));
+ succeed = 1;
+ }
+ else
+ succeed = 0;
if (LK) LR = (spreg)IEA(CIA + 4);
+ model_branches(cpu_model(processor), succeed);
+ if (! BO{0}) {
+ int reverse;
+ if (BO{4}) { /* branch prediction bit set, reverse sense of test */
+ reverse = EXTS(BD_0b00) < 0;
+ } else { /* branch prediction bit not set */
+ reverse = EXTS(BD_0b00) >= 0;
+ }
+ model_branch_predict(cpu_model(processor), reverse ? !succeed : succeed);
+ }
+
0.19,6.BO,11.BI,16./,21.16,31.LK:XL:t::Branch Conditional to Link Register
*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
- int M, ctr_ok, cond_ok;
+ int M, ctr_ok, cond_ok, succeed;
if (is_64bit_implementation && is_64bit_mode) M = 0;
else M = 32;
if (!BO{2}) CTR = CTR - 1;
ctr_ok = BO{2} || ((MASKED(CTR, M, 63) != 0) != BO{3});
cond_ok = BO{0} || (CR{BI} == BO{1});
- if (ctr_ok && cond_ok) NIA = IEA(LR_0b00);
+ if (ctr_ok && cond_ok) {
+ NIA = IEA(LR_0b00);
+ succeed = 1;
+ }
+ else
+ succeed = 0;
if (LK) LR = (spreg)IEA(CIA + 4);
+ model_branches(cpu_model(processor), succeed);
+ if (! BO{0})
+ model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
+
0.19,6.BO,11.BI,16./,21.528,31.LK:XL:t::Branch Conditional to Count Register
*601: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
*603: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
*603e:PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
*604: PPC_UNIT_BPU, PPC_UNIT_BPU, 1, 1, 0
- int cond_ok;
+ int cond_ok, succeed;
cond_ok = BO{0} || (CR{BI} == BO{1});
- if (cond_ok) NIA = IEA(CTR_0b00);
+ if (cond_ok) {
+ NIA = IEA(CTR_0b00);
+ succeed = 1;
+ }
+ else
+ succeed = 0;
if (LK) LR = (spreg)IEA(CIA + 4);
+ model_branches(cpu_model(processor), succeed);
+ if (! BO{0})
+ model_branch_predict(cpu_model(processor), BO{4} ? !succeed : succeed);
#
# I.2.4.2 System Call Instruction