X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Ffrv%2Fprofile.c;h=14c4cfec362e2cf561d82fa741870a9a918e6090;hb=41792d688a5a1f158d6e9ecda2b603ae122d69a1;hp=6ef1e3581b2b7a56ad8d6a29d07598173d0bbabf;hpb=153431d6b1197e76ef2a6908034260aa56bc411f;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/frv/profile.c b/sim/frv/profile.c index 6ef1e3581b..14c4cfec36 100644 --- a/sim/frv/profile.c +++ b/sim/frv/profile.c @@ -1,23 +1,22 @@ /* frv simulator machine independent profiling code. - Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + Copyright (C) 1998-2020 Free Software Foundation, Inc. Contributed by Red Hat This file is part of the GNU simulators. 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, or (at your option) -any later version. +the Free Software Foundation; either version 3 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. +You should have received a copy of the GNU General Public License +along with this program. If not, see . */ #define WANT_CPU @@ -31,12 +30,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "profile.h" #include "profile-fr400.h" #include "profile-fr500.h" +#include "profile-fr550.h" static void reset_gr_flags (SIM_CPU *cpu, INT gr) { SIM_DESC sd = CPU_STATE (cpu); - if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400) + if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400 + || STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr450) fr400_reset_gr_flags (cpu, gr); /* Other machines have no gr flags right now. */ } @@ -45,7 +46,8 @@ static void reset_fr_flags (SIM_CPU *cpu, INT fr) { SIM_DESC sd = CPU_STATE (cpu); - if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400) + if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400 + || STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr450) fr400_reset_fr_flags (cpu, fr); else if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr500) fr500_reset_fr_flags (cpu, fr); @@ -55,7 +57,8 @@ static void reset_acc_flags (SIM_CPU *cpu, INT acc) { SIM_DESC sd = CPU_STATE (cpu); - if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400) + if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400 + || STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr450) fr400_reset_acc_flags (cpu, acc); /* Other machines have no acc flags right now. */ } @@ -677,6 +680,8 @@ update_latencies (SIM_CPU *cpu, int cycles) int *fdiv; int *fsqrt; int *idiv; + int *flt; + int *media; int *ccr; int *gr = ps->gr_busy; int *fr = ps->fr_busy; @@ -758,6 +763,16 @@ update_latencies (SIM_CPU *cpu, int cycles) ++fdiv; ++fsqrt; } + /* Float and media units can occur in 4 slots on some machines. */ + flt = ps->float_busy; + media = ps->media_busy; + for (i = 0; i < 4; ++i) + { + *flt = (*flt <= cycles) ? 0 : (*flt - cycles); + *media = (*media <= cycles) ? 0 : (*media - cycles); + ++flt; + ++media; + } } /* Print information about the wait for the given number of cycles. */ @@ -913,11 +928,15 @@ frvbf_model_insn_before (SIM_CPU *cpu, int first_p) switch (STATE_ARCHITECTURE (sd)->mach) { case bfd_mach_fr400: + case bfd_mach_fr450: fr400_model_insn_before (cpu, first_p); break; case bfd_mach_fr500: fr500_model_insn_before (cpu, first_p); break; + case bfd_mach_fr550: + fr550_model_insn_before (cpu, first_p); + break; default: break; } @@ -976,11 +995,15 @@ frvbf_model_insn_after (SIM_CPU *cpu, int last_p, int cycles) switch (STATE_ARCHITECTURE (sd)->mach) { case bfd_mach_fr400: + case bfd_mach_fr450: fr400_model_insn_after (cpu, last_p, cycles); break; case bfd_mach_fr500: fr500_model_insn_after (cpu, last_p, cycles); break; + case bfd_mach_fr550: + fr550_model_insn_after (cpu, last_p, cycles); + break; default: break; } @@ -1155,6 +1178,52 @@ update_FRdouble_latency_for_load (SIM_CPU *cpu, INT out_FR, int cycles) /* Top up the post-processing time of the given FR by the given number of cycles. */ void +update_FR_ptime (SIM_CPU *cpu, INT out_FR, int cycles) +{ + if (out_FR >= 0) + { + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + /* If a load is pending on this register, then add the cycles to + the post processing time for this register. Otherwise apply it + directly to the latency of the register. */ + if (! load_pending_for_register (cpu, out_FR, 1, REGTYPE_FR)) + { + int *fr = ps->fr_latency; + fr[out_FR] += cycles; + } + else + ps->fr_ptime[out_FR] += cycles; + } +} + +void +update_FRdouble_ptime (SIM_CPU *cpu, INT out_FR, int cycles) +{ + if (out_FR >= 0) + { + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + /* If a load is pending on this register, then add the cycles to + the post processing time for this register. Otherwise apply it + directly to the latency of the register. */ + if (! load_pending_for_register (cpu, out_FR, 2, REGTYPE_FR)) + { + int *fr = ps->fr_latency; + fr[out_FR] += cycles; + if (out_FR < 63) + fr[out_FR + 1] += cycles; + } + else + { + ps->fr_ptime[out_FR] += cycles; + if (out_FR < 63) + ps->fr_ptime[out_FR + 1] += cycles; + } + } +} + +/* Top up the post-processing time of the given ACC by the given number of + cycles. */ +void update_ACC_ptime (SIM_CPU *cpu, INT out_ACC, int cycles) { if (out_ACC >= 0) @@ -1167,6 +1236,21 @@ update_ACC_ptime (SIM_CPU *cpu, INT out_ACC, int cycles) } } +/* Top up the post-processing time of the given SPR by the given number of + cycles. */ +void +update_SPR_ptime (SIM_CPU *cpu, INT out_SPR, int cycles) +{ + if (out_SPR >= 0) + { + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + /* No load can be pending on this register. Apply the cycles + directly to the latency of the register. */ + int *spr = ps->spr_latency; + spr[out_SPR] += cycles; + } +} + void decrease_ACC_busy (SIM_CPU *cpu, INT out_ACC, int cycles) { @@ -1181,6 +1265,24 @@ decrease_ACC_busy (SIM_CPU *cpu, INT out_ACC, int cycles) } } +void +increase_ACC_busy (SIM_CPU *cpu, INT out_ACC, int cycles) +{ + if (out_ACC >= 0) + { + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + int *acc = ps->acc_busy; + acc[out_ACC] += cycles; + } +} + +void +enforce_full_acc_latency (SIM_CPU *cpu, INT in_ACC) +{ + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + ps->acc_busy_adjust [in_ACC] = -1; +} + void decrease_FR_busy (SIM_CPU *cpu, INT out_FR, int cycles) { @@ -1279,6 +1381,27 @@ update_fsqrt_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles) r[in_resource] = cycles; } +/* Set the latency of the given resource to the given number of cycles. */ +void +update_float_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles) +{ + /* operate directly on the busy cycles since each resource can only + be used once in a VLIW insn. */ + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + int *r = ps->float_busy; + r[in_resource] = cycles; +} + +void +update_media_resource_latency (SIM_CPU *cpu, INT in_resource, int cycles) +{ + /* operate directly on the busy cycles since each resource can only + be used once in a VLIW insn. */ + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + int *r = ps->media_busy; + r[in_resource] = cycles; +} + /* Set the branch penalty to the given number of cycles. */ void update_branch_penalty (SIM_CPU *cpu, int cycles) @@ -1465,7 +1588,7 @@ vliw_wait_for_fdiv_resource (SIM_CPU *cpu, INT in_resource) { if (TRACE_INSN_P (cpu)) { - sprintf (hazard_name, "Resource hazard for integer division in slot I%d:", in_resource); + sprintf (hazard_name, "Resource hazard for floating point division in slot F%d:", in_resource); } ps->vliw_wait = r[in_resource]; } @@ -1485,7 +1608,47 @@ vliw_wait_for_fsqrt_resource (SIM_CPU *cpu, INT in_resource) { if (TRACE_INSN_P (cpu)) { - sprintf (hazard_name, "Resource hazard for integer division in slot I%d:", in_resource); + sprintf (hazard_name, "Resource hazard for square root in slot F%d:", in_resource); + } + ps->vliw_wait = r[in_resource]; + } +} + +/* Check the availability of the given float unit resource and update + the number of cycles the current VLIW insn must wait until it is available. +*/ +void +vliw_wait_for_float_resource (SIM_CPU *cpu, INT in_resource) +{ + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + int *r = ps->float_busy; + /* If the latency of the resource is greater than the current wait + then update the current wait. */ + if (r[in_resource] > ps->vliw_wait) + { + if (TRACE_INSN_P (cpu)) + { + sprintf (hazard_name, "Resource hazard for floating point unit in slot F%d:", in_resource); + } + ps->vliw_wait = r[in_resource]; + } +} + +/* Check the availability of the given media unit resource and update + the number of cycles the current VLIW insn must wait until it is available. +*/ +void +vliw_wait_for_media_resource (SIM_CPU *cpu, INT in_resource) +{ + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + int *r = ps->media_busy; + /* If the latency of the resource is greater than the current wait + then update the current wait. */ + if (r[in_resource] > ps->vliw_wait) + { + if (TRACE_INSN_P (cpu)) + { + sprintf (hazard_name, "Resource hazard for media unit in slot M%d:", in_resource); } ps->vliw_wait = r[in_resource]; } @@ -1693,6 +1856,20 @@ post_wait_for_CCR (SIM_CPU *cpu, INT in_CCR) } } +int +post_wait_for_SPR (SIM_CPU *cpu, INT in_SPR) +{ + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + int *spr = ps->spr_busy; + + if (in_SPR >= 0 && spr[in_SPR] > ps->post_wait) + { + ps->post_wait = spr[in_SPR]; + if (TRACE_INSN_P (cpu)) + sprintf (hazard_name, "Data hazard for spr[%d]:", in_SPR); + } +} + int post_wait_for_fdiv (SIM_CPU *cpu, INT slot) { @@ -1729,6 +1906,42 @@ post_wait_for_fsqrt (SIM_CPU *cpu, INT slot) } } +int +post_wait_for_float (SIM_CPU *cpu, INT slot) +{ + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + int *flt = ps->float_busy; + + /* Multiple floating point square roots in the same slot need only wait 1 + extra cycle. */ + if (flt[slot] > ps->post_wait) + { + ps->post_wait = flt[slot]; + if (TRACE_INSN_P (cpu)) + { + sprintf (hazard_name, "Resource hazard for floating point unit in slot F%d:", slot); + } + } +} + +int +post_wait_for_media (SIM_CPU *cpu, INT slot) +{ + FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (cpu); + int *media = ps->media_busy; + + /* Multiple floating point square roots in the same slot need only wait 1 + extra cycle. */ + if (media[slot] > ps->post_wait) + { + ps->post_wait = media[slot]; + if (TRACE_INSN_P (cpu)) + { + sprintf (hazard_name, "Resource hazard for media unit in slot M%d:", slot); + } + } +} + /* Print cpu-specific profile information. */ #define COMMAS(n) sim_add_commas (comma_buf, sizeof (comma_buf), (n)) @@ -1768,8 +1981,8 @@ static char * slot_names[] = { "none", - "I0", "I1", "I01", "IALL", - "FM0", "FM1", "FM01", "FMALL", "FMLOW", + "I0", "I1", "I01", "I2", "I3", "IALL", + "FM0", "FM1", "FM01", "FM2", "FM3", "FMALL", "FMLOW", "B0", "B1", "B01", "C" }; @@ -1828,7 +2041,7 @@ print_parallel (SIM_CPU *cpu, int verbose) max_name_len, slot_names[i], max_val < 10000 ? 5 : 10, COMMAS (INSNS_IN_SLOT (i))); - sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH, + sim_profile_print_bar (sd, cpu, PROFILE_HISTOGRAM_WIDTH, INSNS_IN_SLOT (i), max_val); sim_io_printf (sd, "\n");