diff options
Diffstat (limited to 'sim/ppc')
-rw-r--r-- | sim/ppc/ChangeLog | 26 | ||||
-rw-r--r-- | sim/ppc/configure.in | 24 | ||||
-rw-r--r-- | sim/ppc/cpu.c | 19 | ||||
-rw-r--r-- | sim/ppc/function_unit.c | 611 | ||||
-rw-r--r-- | sim/ppc/function_unit.h | 71 | ||||
-rw-r--r-- | sim/ppc/igen.c | 14 | ||||
-rw-r--r-- | sim/ppc/mon.c | 2 | ||||
-rw-r--r-- | sim/ppc/ppc-instructions | 92 |
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 |