sim: unify gettext/intl probing logic
[deliverable/binutils-gdb.git] / sim / common / sim-events.c
index ffda5b3e9c58a047c3eb170efff3f67d7d8d6e04..5a5798d102a8c1f03a97ecf8267cad674b8be338 100644 (file)
@@ -1,40 +1,39 @@
-/*  This file is part of the program psim.
+/* The common simulator framework for GDB, the GNU Debugger.
 
-    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
+   Copyright 2002-2021 Free Software Foundation, Inc.
 
-    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.
+   Contributed by Andrew Cagney and Red Hat.
 
-    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.
-    */
+   This file is part of GDB.
+
+   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 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, see <http://www.gnu.org/licenses/>.  */
 
 
 #ifndef _SIM_EVENTS_C_
 #define _SIM_EVENTS_C_
 
+/* This must come before any other includes.  */
+#include "defs.h"
+
 #include "sim-main.h"
 #include "sim-assert.h"
+#include "sim-cpu.h"
+#include "libiberty.h"
 
-#ifdef HAVE_STRING_H
 #include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
-#include <signal.h>
-
+#include <stdlib.h>
+#include <signal.h> /* For SIGPROCMASK et al. */
 
 typedef enum {
   watch_invalid,
@@ -70,7 +69,10 @@ typedef enum {
   watch_sim_le_2,
   watch_sim_le_4,
   watch_sim_le_8,
-  
+
+  /* pc */
+  watch_pc,
+
   /* wallclock */
   watch_clock,
 
@@ -89,7 +91,7 @@ struct _sim_event {
   unsigned wallclock;
   /* watch core address */
   address_word core_addr;
-  sim_core_maps core_map;
+  unsigned core_map;
   /* watch sim addr */
   void *host_addr;
   /* watch core/sim range */
@@ -98,6 +100,8 @@ struct _sim_event {
   unsigned lb;
   unsigned64 ub64;
   unsigned64 lb64;
+  /* trace info (if any) */
+  char *trace;
   /* list */
   sim_event *next;
 };
@@ -105,19 +109,18 @@ struct _sim_event {
 
 /* The event queue maintains a single absolute time using two
    variables.
-   
+
    TIME_OF_EVENT: this holds the time at which the next event is ment
-   to occure.  If no next event it will hold the time of the last
+   to occur.  If no next event it will hold the time of the last
    event.
 
-   TIME_FROM_EVENT: The current distance from TIME_OF_EVENT.  If an
-   event is pending, this will be positive.  If no future event is
-   pending (eg when poll-event is being processed) this will be
-   negative.  This variable is decremented once for each iteration of
-   a clock cycle.
+   TIME_FROM_EVENT: The current distance from TIME_OF_EVENT.  A value
+   <= 0 (except when poll-event is being processed) indicates that
+   event processing is due.  This variable is decremented once for
+   each iteration of a clock cycle.
 
    Initially, the clock is started at time one (0) with TIME_OF_EVENT
-   == 0 and TIME_FROM_EVENT == 0.
+   == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
 
    Clearly there is a bug in that this code assumes that the absolute
    time counter will never become greater than 2^62.
@@ -139,15 +142,11 @@ struct _sim_event {
 #define ETRACE(ARGS) \
 do \
   { \
-    if (WITH_TRACE) \
+    if (STRACE_EVENTS_P (sd)) \
       { \
-        if (STATE_EVENTS (sd)->trace) \
-          { \
-            const char *file; \
-            SIM_FILTER_PATH (file, __FILE__); \
-            trace_printf (sd, NULL, "%s:%d: ", file, __LINE__); \
-            trace_printf  ARGS; \
-          } \
+        if (STRACE_DEBUG_P (sd)) \
+         trace_printf (sd, NULL, "%s:%d: ", lbasename (__FILE__), __LINE__); \
+        trace_printf  ARGS; \
       } \
   } \
 while (0)
@@ -155,8 +154,8 @@ while (0)
 
 /* event queue iterator - don't iterate over the held queue. */
 
-STATIC_INLINE_SIM_EVENTS\
-(sim_event **)
+#if EXTERN_SIM_EVENTS_P
+static sim_event **
 next_event_queue (SIM_DESC sd,
                  sim_event **queue)
 {
@@ -172,6 +171,7 @@ next_event_queue (SIM_DESC sd,
     sim_io_error (sd, "next_event_queue - bad queue");
   return NULL;
 }
+#endif
 
 
 STATIC_INLINE_SIM_EVENTS\
@@ -189,13 +189,15 @@ sim_events_poll (SIM_DESC sd,
    This is called via sim_module_install to install the "events" subsystem
    into the simulator.  */
 
+#if EXTERN_SIM_EVENTS_P
 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN) sim_events_uninstall;
 STATIC_SIM_EVENTS (MODULE_INIT_FN) sim_events_init;
 STATIC_SIM_EVENTS (MODULE_RESUME_FN) sim_events_resume;
 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN) sim_events_suspend;
+#endif
 
-EXTERN_SIM_EVENTS\
-(SIM_RC)
+#if EXTERN_SIM_EVENTS_P
+SIM_RC
 sim_events_install (SIM_DESC sd)
 {
   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
@@ -205,13 +207,14 @@ sim_events_install (SIM_DESC sd)
   sim_module_add_suspend_fn (sd, sim_events_suspend);
   return SIM_RC_OK;
 }
+#endif
 
 
 /* Suspend/resume the event queue manager when the simulator is not
    running */
 
-STATIC_SIM_EVENTS\
-(SIM_RC)
+#if EXTERN_SIM_EVENTS_P
+static SIM_RC
 sim_events_resume (SIM_DESC sd)
 {
   sim_events *events = STATE_EVENTS (sd);
@@ -220,9 +223,10 @@ sim_events_resume (SIM_DESC sd)
   events->resume_wallclock = sim_elapsed_time_get ();
   return SIM_RC_OK;
 }
+#endif
 
-STATIC_SIM_EVENTS\
-(SIM_RC)
+#if EXTERN_SIM_EVENTS_P
+static SIM_RC
 sim_events_suspend (SIM_DESC sd)
 {
   sim_events *events = STATE_EVENTS (sd);
@@ -232,23 +236,25 @@ sim_events_suspend (SIM_DESC sd)
   events->resume_wallclock = 0;
   return SIM_RC_OK;
 }
+#endif
 
 
 /* Uninstall the "events" subsystem from the simulator.  */
 
-STATIC_SIM_EVENTS\
-(void)
+#if EXTERN_SIM_EVENTS_P
+static void
 sim_events_uninstall (SIM_DESC sd)
 {
   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
   /* FIXME: free buffers, etc. */
 }
+#endif
 
 
 /* malloc/free */
 
-STATIC_INLINE_SIM_EVENTS\
-(sim_event *)
+#if EXTERN_SIM_EVENTS_P
+static sim_event *
 sim_events_zalloc (SIM_DESC sd)
 {
   sim_events *events = STATE_EVENTS (sd);
@@ -264,7 +270,7 @@ sim_events_zalloc (SIM_DESC sd)
       /*-LOCK-*/
       sigset_t old_mask;
       sigset_t new_mask;
-      sigfillset(&new_mask);
+      sigfillset (&new_mask);
       sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
 #endif
       new = ZALLOC (sim_event);
@@ -275,6 +281,7 @@ sim_events_zalloc (SIM_DESC sd)
     }
   return new;
 }
+#endif
 
 STATIC_INLINE_SIM_EVENTS\
 (void)
@@ -284,13 +291,18 @@ sim_events_free (SIM_DESC sd,
   sim_events *events = STATE_EVENTS (sd);
   dead->next = events->free_list;
   events->free_list = dead;
+  if (dead->trace != NULL)
+    {
+      free (dead->trace); /* NB: asprintf returns a `free' buf */
+      dead->trace = NULL;
+    }
 }
 
 
 /* Initialize the simulator event manager */
 
-EXTERN_SIM_EVENTS\
-(SIM_RC)
+#if EXTERN_SIM_EVENTS_P
+SIM_RC
 sim_events_init (SIM_DESC sd)
 {
   sim_events *events = STATE_EVENTS (sd);
@@ -298,7 +310,7 @@ sim_events_init (SIM_DESC sd)
   /* drain the interrupt queue */
   events->nr_held = 0;
   if (events->held == NULL)
-    events->held = zalloc (sizeof (sim_event) * MAX_NR_SIGNAL_SIM_EVENTS);
+    events->held = NZALLOC (sim_event, MAX_NR_SIGNAL_SIM_EVENTS);
 
   /* drain the normal queues */
   {
@@ -332,6 +344,7 @@ sim_events_init (SIM_DESC sd)
 
   return SIM_RC_OK;
 }
+#endif
 
 
 INLINE_SIM_EVENTS\
@@ -339,7 +352,7 @@ INLINE_SIM_EVENTS\
 sim_events_time (SIM_DESC sd)
 {
   sim_events *events = STATE_EVENTS (sd);
-  return events->time_of_event - events->time_from_event;
+  return (events->time_of_event - events->time_from_event);
 }
 
 
@@ -347,11 +360,30 @@ INLINE_SIM_EVENTS\
 (unsigned long)
 sim_events_elapsed_time (SIM_DESC sd)
 {
-  return (sim_elapsed_time_since (STATE_EVENTS (sd)->resume_wallclock)
-         + STATE_EVENTS (sd)->elapsed_wallclock);
+  unsigned long elapsed = STATE_EVENTS (sd)->elapsed_wallclock;
+
+  /* Are we being called inside sim_resume?
+     (Is there a simulation in progress?)  */
+  if (STATE_EVENTS (sd)->resume_wallclock != 0)
+     elapsed += sim_elapsed_time_since (STATE_EVENTS (sd)->resume_wallclock);
+
+  return elapsed;
 }
 
 
+/* Returns the time that remains before the event is raised. */
+INLINE_SIM_EVENTS\
+(signed64)
+sim_events_remain_time (SIM_DESC sd, sim_event *event)
+{
+  if (event == 0)
+    return 0;
+
+  return (event->time_of_event - sim_events_time (sd));
+}
+
+
+
 STATIC_INLINE_SIM_EVENTS\
 (void)
 update_time_from_event (SIM_DESC sd)
@@ -360,21 +392,41 @@ update_time_from_event (SIM_DESC sd)
   signed64 current_time = sim_events_time (sd);
   if (events->queue != NULL)
     {
-      events->time_from_event = (events->queue->time_of_event - current_time);
       events->time_of_event = events->queue->time_of_event;
+      events->time_from_event = (events->queue->time_of_event - current_time);
     }
   else
     {
       events->time_of_event = current_time - 1;
       events->time_from_event = -1;
     }
+  if (STRACE_EVENTS_P (sd))
+    {
+      sim_event *event;
+      int i;
+      for (event = events->queue, i = 0;
+          event != NULL;
+          event = event->next, i++)
+       {
+         ETRACE ((_ETRACE,
+                  "event time-from-event - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
+                  (long)current_time,
+                  (long)events->time_from_event,
+                  i,
+                  (long)event,
+                  (long)event->time_of_event,
+                  (long)event->handler,
+                  (long)event->data,
+                  (event->trace != NULL) ? ", " : "",
+                  (event->trace != NULL) ? event->trace : ""));
+       }
+    }
   SIM_ASSERT (current_time == sim_events_time (sd));
-  SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL));
 }
 
 
-STATIC_INLINE_SIM_EVENTS\
-(void)
+#if EXTERN_SIM_EVENTS_P
+static void
 insert_sim_event (SIM_DESC sd,
                  sim_event *new_event,
                  signed64 delta)
@@ -386,10 +438,10 @@ insert_sim_event (SIM_DESC sd,
 
   if (delta < 0)
     sim_io_error (sd, "what is past is past!\n");
-  
-  /* compute when the event should occure */
+
+  /* compute when the event should occur */
   time_of_event = sim_events_time (sd) + delta;
-  
+
   /* find the queue insertion point - things are time ordered */
   prev = &events->queue;
   curr = events->queue;
@@ -401,42 +453,81 @@ insert_sim_event (SIM_DESC sd,
       curr = curr->next;
     }
   SIM_ASSERT (curr == NULL || time_of_event < curr->time_of_event);
-  
+
   /* insert it */
   new_event->next = curr;
   *prev = new_event;
   new_event->time_of_event = time_of_event;
-  
+
   /* adjust the time until the first event */
   update_time_from_event (sd);
 }
+#endif
 
 
-EXTERN_SIM_EVENTS\
-(sim_event *)
+#if EXTERN_SIM_EVENTS_P
+sim_event *
 sim_events_schedule (SIM_DESC sd,
                     signed64 delta_time,
                     sim_event_handler *handler,
                     void *data)
+{
+  return sim_events_schedule_tracef (sd, delta_time, handler, data, NULL);
+}
+#endif
+
+
+#if EXTERN_SIM_EVENTS_P
+sim_event *
+sim_events_schedule_tracef (SIM_DESC sd,
+                           signed64 delta_time,
+                           sim_event_handler *handler,
+                           void *data,
+                           const char *fmt,
+                           ...)
+{
+  sim_event *new_event;
+  va_list ap;
+  va_start (ap, fmt);
+  new_event = sim_events_schedule_vtracef (sd, delta_time, handler, data, fmt, ap);
+  va_end (ap);
+  return new_event;
+}
+#endif
+
+
+#if EXTERN_SIM_EVENTS_P
+sim_event *
+sim_events_schedule_vtracef (SIM_DESC sd,
+                            signed64 delta_time,
+                            sim_event_handler *handler,
+                            void *data,
+                            const char *fmt,
+                            va_list ap)
 {
   sim_event *new_event = sim_events_zalloc (sd);
   new_event->data = data;
   new_event->handler = handler;
   new_event->watching = watch_timer;
-  insert_sim_event(sd, new_event, delta_time);
-  ETRACE((_ETRACE,
-         "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
-         (long)sim_events_time(sd),
-         (long)new_event,
-         (long)new_event->time_of_event,
-         (long)new_event->handler,
-         (long)new_event->data));
+  if (fmt == NULL || !STRACE_EVENTS_P (sd) || vasprintf (&new_event->trace, fmt, ap) < 0)
+    new_event->trace = NULL;
+  insert_sim_event (sd, new_event, delta_time);
+  ETRACE ((_ETRACE,
+          "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
+          (long)sim_events_time (sd),
+          (long)new_event,
+          (long)new_event->time_of_event,
+          (long)new_event->handler,
+          (long)new_event->data,
+          (new_event->trace != NULL) ? ", " : "",
+          (new_event->trace != NULL) ? new_event->trace : ""));
   return new_event;
 }
+#endif
 
 
-EXTERN_SIM_EVENTS\
-(void)
+#if EXTERN_SIM_EVENTS_P
+void
 sim_events_schedule_after_signal (SIM_DESC sd,
                                  signed64 delta_time,
                                  sim_event_handler *handler,
@@ -448,19 +539,19 @@ sim_events_schedule_after_signal (SIM_DESC sd,
   /*-LOCK-*/
   sigset_t old_mask;
   sigset_t new_mask;
-  sigfillset(&new_mask);
+  sigfillset (&new_mask);
   sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
 #endif
-  
+
   /* allocate an event entry from the signal buffer */
   new_event = &events->held [events->nr_held];
   events->nr_held ++;
   if (events->nr_held > MAX_NR_SIGNAL_SIM_EVENTS)
     {
       sim_engine_abort (NULL, NULL, NULL_CIA,
-                       "sim_events_schedule_after_signal - buffer oveflow");
+                       "sim_events_schedule_after_signal - buffer overflow");
     }
-  
+
   new_event->data = data;
   new_event->handler = handler;
   new_event->time_of_event = delta_time; /* work it out later */
@@ -472,19 +563,20 @@ sim_events_schedule_after_signal (SIM_DESC sd,
   /*-UNLOCK-*/
   sigprocmask (SIG_SETMASK, &old_mask, NULL);
 #endif
-  
+
   ETRACE ((_ETRACE,
           "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
-          (long)sim_events_time(sd),
+          (long)sim_events_time (sd),
           (long)new_event,
           (long)new_event->time_of_event,
           (long)new_event->handler,
           (long)new_event->data));
 }
+#endif
 
 
-EXTERN_SIM_EVENTS\
-(sim_event *)
+#if EXTERN_SIM_EVENTS_P
+sim_event *
 sim_events_watch_clock (SIM_DESC sd,
                        unsigned delta_ms_time,
                        sim_event_handler *handler,
@@ -517,14 +609,54 @@ sim_events_watch_clock (SIM_DESC sd,
           (long)new_event->data));
   return new_event;
 }
+#endif
 
 
-EXTERN_SIM_EVENTS\
-(sim_event *)
+#if EXTERN_SIM_EVENTS_P
+sim_event *
+sim_events_watch_pc (SIM_DESC sd,
+                      int is_within,
+                      unsigned64 lb,
+                      unsigned64 ub,
+                      sim_event_handler *handler,
+                      void *data)
+{
+  sim_events *events = STATE_EVENTS (sd);
+  sim_event *new_event = sim_events_zalloc (sd);
+  /* type */
+  new_event->watching = watch_pc;
+  /* handler */
+  new_event->data = data;
+  new_event->handler = handler;
+  /* data */
+  new_event->lb = lb;
+  new_event->lb64 = lb;
+  new_event->ub = ub;
+  new_event->ub64 = ub;
+  new_event->is_within = (is_within != 0);
+  /* insert */
+  new_event->next = events->watchpoints;
+  events->watchpoints = new_event;
+  events->work_pending = 1;
+  ETRACE ((_ETRACE,
+          "event watching pc at %ld - tag 0x%lx - pc 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
+          (long)sim_events_time (sd),
+          (long)new_event,
+          (long)new_event->lb,
+          (long)new_event->ub,
+          (long)new_event->handler,
+          (long)new_event->data));
+  return new_event;
+}
+#endif
+
+
+#if EXTERN_SIM_EVENTS_P
+sim_event *
 sim_events_watch_sim (SIM_DESC sd,
                      void *host_addr,
                      int nr_bytes,
-                     int byte_order,
+                     enum bfd_endian byte_order,
                      int is_within,
                      unsigned64 lb,
                      unsigned64 ub,
@@ -536,7 +668,7 @@ sim_events_watch_sim (SIM_DESC sd,
   /* type */
   switch (byte_order)
     {
-    case 0:
+    case BFD_ENDIAN_UNKNOWN:
       switch (nr_bytes)
        {
        case 1: new_event->watching = watch_sim_host_1; break;
@@ -546,7 +678,7 @@ sim_events_watch_sim (SIM_DESC sd,
        default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
        }
       break;
-    case BIG_ENDIAN:
+    case BFD_ENDIAN_BIG:
       switch (nr_bytes)
        {
        case 1: new_event->watching = watch_sim_be_1; break;
@@ -556,7 +688,7 @@ sim_events_watch_sim (SIM_DESC sd,
        default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
        }
       break;
-    case LITTLE_ENDIAN:
+    case BFD_ENDIAN_LITTLE:
       switch (nr_bytes)
        {
        case 1: new_event->watching = watch_sim_le_1; break;
@@ -594,15 +726,16 @@ sim_events_watch_sim (SIM_DESC sd,
           (long)new_event->data));
   return new_event;
 }
+#endif
 
 
-EXTERN_SIM_EVENTS\
-(sim_event *)
+#if EXTERN_SIM_EVENTS_P
+sim_event *
 sim_events_watch_core (SIM_DESC sd,
                       address_word core_addr,
-                      sim_core_maps core_map,
+                      unsigned core_map,
                       int nr_bytes,
-                      int byte_order,
+                      enum bfd_endian byte_order,
                       int is_within,
                       unsigned64 lb,
                       unsigned64 ub,
@@ -614,7 +747,7 @@ sim_events_watch_core (SIM_DESC sd,
   /* type */
   switch (byte_order)
     {
-    case 0:
+    case BFD_ENDIAN_UNKNOWN:
       switch (nr_bytes)
        {
        case 1: new_event->watching = watch_core_targ_1; break;
@@ -624,7 +757,7 @@ sim_events_watch_core (SIM_DESC sd,
        default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
        }
       break;
-    case BIG_ENDIAN:
+    case BFD_ENDIAN_BIG:
       switch (nr_bytes)
        {
        case 1: new_event->watching = watch_core_be_1; break;
@@ -634,7 +767,7 @@ sim_events_watch_core (SIM_DESC sd,
        default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
        }
       break;
-    case LITTLE_ENDIAN:
+    case BFD_ENDIAN_LITTLE:
       switch (nr_bytes)
        {
        case 1: new_event->watching = watch_core_le_1; break;
@@ -673,16 +806,16 @@ sim_events_watch_core (SIM_DESC sd,
           (long)new_event->data));
   return new_event;
 }
+#endif
 
 
-EXTERN_SIM_EVENTS\
-(void)
+#if EXTERN_SIM_EVENTS_P
+void
 sim_events_deschedule (SIM_DESC sd,
                       sim_event *event_to_remove)
 {
   sim_events *events = STATE_EVENTS (sd);
   sim_event *to_remove = (sim_event*)event_to_remove;
-  SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL));
   if (event_to_remove != NULL)
     {
       sim_event **queue = NULL;
@@ -697,12 +830,14 @@ sim_events_deschedule (SIM_DESC sd,
              sim_event *dead = *ptr_to_current;
              *ptr_to_current = dead->next;
              ETRACE ((_ETRACE,
-                      "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
+                      "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
                       (long) sim_events_time (sd),
                       (long) event_to_remove,
                       (long) dead->time_of_event,
                       (long) dead->handler,
-                      (long) dead->data));
+                      (long) dead->data,
+                      (dead->trace != NULL) ? ", " : "",
+                      (dead->trace != NULL) ? dead->trace : ""));
              sim_events_free (sd, dead);
              update_time_from_event (sd);
              SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL));
@@ -715,6 +850,7 @@ sim_events_deschedule (SIM_DESC sd,
           (long) sim_events_time (sd),
           (long) event_to_remove));
 }
+#endif
 
 
 STATIC_INLINE_SIM_EVENTS\
@@ -872,6 +1008,21 @@ sim_watch_valid (SIM_DESC sd,
       }
 #undef WATCH_SIM
 
+    case watch_pc:
+      {
+       int c;
+
+       for (c = 0; c < MAX_NR_PROCESSORS; ++c)
+         {
+           sim_cpu *cpu = STATE_CPU (sd, c);
+           sim_cia cia = sim_pc_get (cpu);
+
+           if (to_do->is_within == (cia >= to_do->lb64 && cia <= to_do->ub64))
+             return 1;
+         }
+       return 0;
+      }
+
     case watch_clock: /* wallclock */
       {
        unsigned long elapsed_time = sim_events_elapsed_time (sd);
@@ -892,7 +1043,6 @@ INLINE_SIM_EVENTS\
 sim_events_tick (SIM_DESC sd)
 {
   sim_events *events = STATE_EVENTS (sd);
-  SIM_ASSERT (events->nr_ticks_to_process == 0);
 
   /* this should only be called after the previous ticks have been
      fully processed */
@@ -904,10 +1054,11 @@ sim_events_tick (SIM_DESC sd)
       events->nr_ticks_to_process += 1;
       return 1;
     }
-  else {
-    events->time_from_event -= 1;
-    return 0;
-  }
+  else
+    {
+      events->time_from_event -= 1;
+      return 0;
+    }
 }
 
 
@@ -923,16 +1074,16 @@ sim_events_tickn (SIM_DESC sd,
      fully processed */
 
   /* Advance the time but *only* if there is nothing to process */
-  if (events->work_pending
-      || events->time_from_event < n)
+  if (events->work_pending || events->time_from_event < n)
     {
       events->nr_ticks_to_process += n;
       return 1;
     }
-  else {
-    events->time_from_event -= n;
-    return 0;
-  }
+  else
+    {
+      events->time_from_event -= n;
+      return 0;
+    }
 }
 
 
@@ -944,19 +1095,13 @@ sim_events_slip (SIM_DESC sd,
   sim_events *events = STATE_EVENTS (sd);
   SIM_ASSERT (slip > 0);
 
-  /* Advance either TIME_FROM_EVENT or NR_TICKS_TO_PROCESS dependant
-     on which is closer for this SLIP.  While previous slips may have
-     advanced a different counter is sitll valid as the accumulative
-     effect is still the same. */
+  /* Flag a ready event with work_pending instead of number of ticks
+     to process so that the time continues to be correct */
   if (events->time_from_event < slip)
     {
-      events->nr_ticks_to_process += slip;
       events->work_pending = 1;
     }
-  else 
-    {
-      events->time_from_event -= slip;
-    }
+  events->time_from_event -= slip;
 }
 
 
@@ -966,7 +1111,7 @@ sim_events_preprocess (SIM_DESC sd,
                       int events_were_last,
                       int events_were_next)
 {
-  sim_events *events = STATE_EVENTS(sd);
+  sim_events *events = STATE_EVENTS (sd);
   if (events_were_last)
     {
       /* Halted part way through event processing */
@@ -989,10 +1134,8 @@ INLINE_SIM_EVENTS\
 (void)
 sim_events_process (SIM_DESC sd)
 {
-  sim_events *events = STATE_EVENTS(sd);
-  signed64 event_time = sim_events_time(sd);
-
-  ASSERT (events->nr_ticks_to_process != 0);
+  sim_events *events = STATE_EVENTS (sd);
+  signed64 event_time = sim_events_time (sd);
 
   /* Clear work_pending before checking nr_held.  Clearing
      work_pending after nr_held (with out a lock could loose an
@@ -1004,13 +1147,13 @@ sim_events_process (SIM_DESC sd)
   if (events->nr_held > 0)
     {
       int i;
-      
+
 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
       /*-LOCK-*/
       sigset_t old_mask;
       sigset_t new_mask;
-      sigfillset(&new_mask);
-      sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
+      sigfillset (&new_mask);
+      sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
 #endif
 
       for (i = 0; i < events->nr_held; i++)
@@ -1022,14 +1165,14 @@ sim_events_process (SIM_DESC sd)
                               entry->data);
        }
       events->nr_held = 0;
-      
+
 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
       /*-UNLOCK-*/
-      sigprocmask(SIG_SETMASK, &old_mask, NULL);
+      sigprocmask (SIG_SETMASK, &old_mask, NULL);
 #endif
-      
+
     }
-  
+
   /* Process any watchpoints. Be careful to allow a watchpoint to
      appear/disappear under our feet.
      To ensure that watchpoints are processed only once per cycle,
@@ -1044,12 +1187,14 @@ sim_events_process (SIM_DESC sd)
        {
          sim_event_handler *handler = to_do->handler;
          void *data = to_do->data;
-         ETRACE((_ETRACE,
-                 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx\n",
-                 (long) event_time,
-                 (long) to_do,
-                 (long) handler,
-                 (long) data));
+         ETRACE ((_ETRACE,
+                  "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
+                  (long) event_time,
+                  (long) to_do,
+                  (long) handler,
+                  (long) data,
+                  (to_do->trace != NULL) ? ", " : "",
+                  (to_do->trace != NULL) ? to_do->trace : ""));
          sim_events_free (sd, to_do);
          handler (sd, data);
        }
@@ -1059,7 +1204,7 @@ sim_events_process (SIM_DESC sd)
          events->watchedpoints = to_do;
        }
     }
-  
+
   /* consume all events for this or earlier times.  Be careful to
      allow an event to appear/disappear under our feet */
   while (events->queue->time_of_event <
@@ -1069,24 +1214,26 @@ sim_events_process (SIM_DESC sd)
       sim_event_handler *handler = to_do->handler;
       void *data = to_do->data;
       events->queue = to_do->next;
-      ETRACE((_ETRACE,
-             "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx\n",
-             (long) event_time,
-             (long) to_do,
-             (long) handler,
-             (long) data));
+      update_time_from_event (sd);
+      ETRACE ((_ETRACE,
+              "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
+              (long) event_time,
+              (long) to_do,
+              (long) handler,
+              (long) data,
+              (to_do->trace != NULL) ? ", " : "",
+              (to_do->trace != NULL) ? to_do->trace : ""));
       sim_events_free (sd, to_do);
       handler (sd, data);
     }
-  
+
   /* put things back where they belong ready for the next iteration */
   events->watchpoints = events->watchedpoints;
   events->watchedpoints = NULL;
   if (events->watchpoints != NULL)
     events->work_pending = 1;
-  
-  /* re-caculate time for new events then advance the time */
-  update_time_from_event(sd);
+
+  /* advance the time */
   SIM_ASSERT (events->time_from_event >= events->nr_ticks_to_process);
   SIM_ASSERT (events->queue != NULL); /* always poll event */
   events->time_from_event -= events->nr_ticks_to_process;
This page took 0.035276 seconds and 4 git commands to generate.