AArch64: Add negative tests for Armv8.3-a complex number instructions instructions.
[deliverable/binutils-gdb.git] / sim / frv / profile.c
index 2eadef4ce80a6cdbcb26c58889e412619e740734..d417fc3301a0ef0e709d55727d5601ff23f2e97c 100644 (file)
@@ -1,23 +1,22 @@
 /* frv simulator machine independent profiling code.
 
-   Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1998-2019 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 <http://www.gnu.org/licenses/>.
 
 */
 #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;
     }
@@ -1242,7 +1265,6 @@ decrease_ACC_busy (SIM_CPU *cpu, INT out_ACC, int cycles)
     }
 }
 
-/* start-sanitize-frv */
 void
 increase_ACC_busy (SIM_CPU *cpu, INT out_ACC, int cycles)
 {
@@ -1261,7 +1283,6 @@ enforce_full_acc_latency (SIM_CPU *cpu, INT in_ACC)
   ps->acc_busy_adjust [in_ACC] = -1;
 }
 
-/* end-sanitize-frv */
 void
 decrease_FR_busy (SIM_CPU *cpu, INT out_FR, int cycles)
 {
@@ -1360,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)
@@ -1572,6 +1614,46 @@ vliw_wait_for_fsqrt_resource (SIM_CPU *cpu, INT 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];
+    }
+}
+
 /* Run the caches until all requests for the given register(s) are satisfied. */
 void
 load_wait_for_GR (SIM_CPU *cpu, INT in_GR)
@@ -1824,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))
 
@@ -1863,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"
 };
@@ -1923,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");
This page took 0.02613 seconds and 4 git commands to generate.