sim: mips: hoist "single" igen rules up to common builds
[binutils-gdb.git] / sim / mips / dv-tx3904cpu.c
index a040d4c8163ce8c115f4e505135ebe83ce13791b..56c23d8dad43f785c3bd36e28862fb2bdcccb37f 100644 (file)
@@ -1,44 +1,45 @@
 /*  This file is part of the program GDB, the GNU debugger.
 /*  This file is part of the program GDB, the GNU debugger.
-    
-    Copyright (C) 1998 Free Software Foundation, Inc.
+
+    Copyright (C) 1998-2022 Free Software Foundation, Inc.
     Contributed by Cygnus Solutions.
     Contributed by Cygnus Solutions.
-    
+
     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
     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
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
     (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.
     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
     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.
-    
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
     */
 
     */
 
+/* This must come before any other includes.  */
+#include "defs.h"
 
 #include "sim-main.h"
 #include "hw-main.h"
 
 /* DEVICE
 
 
 #include "sim-main.h"
 #include "hw-main.h"
 
 /* DEVICE
 
-   
+
    tx3904cpu - tx3904 cpu virtual device
 
    tx3904cpu - tx3904 cpu virtual device
 
-   
+
    DESCRIPTION
 
    DESCRIPTION
 
-   
+
    Implements the external tx3904 functionality.  This includes the
    delivery of of interrupts generated from other devices and the
    handling of device specific registers.
 
 
    PROPERTIES
    Implements the external tx3904 functionality.  This includes the
    delivery of of interrupts generated from other devices and the
    handling of device specific registers.
 
 
    PROPERTIES
-   
+
    none
 
 
    none
 
 
 struct tx3904cpu {
   /* Pending interrupts for delivery by event handler */
   int pending_reset, pending_nmi, pending_level;
 struct tx3904cpu {
   /* Pending interrupts for delivery by event handler */
   int pending_reset, pending_nmi, pending_level;
+  struct hw_event* event;
 };
 
 
 
 };
 
 
 
-/* input port ID's */ 
+/* input port ID's */
 
 enum {
   RESET_PORT,
 
 enum {
   RESET_PORT,
@@ -127,6 +129,7 @@ tx3904cpu_finish (struct hw *me)
   controller->pending_level = 0;
   controller->pending_reset = 0;
   controller->pending_nmi = 0;
   controller->pending_level = 0;
   controller->pending_reset = 0;
   controller->pending_nmi = 0;
+  controller->event = NULL;
 }
 
 
 }
 
 
@@ -140,54 +143,57 @@ deliver_tx3904cpu_interrupt (struct hw *me,
   struct tx3904cpu *controller = hw_data (me);
   SIM_DESC sd = hw_system (me);
   sim_cpu *cpu = STATE_CPU (sd, 0); /* NB: fix CPU 0. */
   struct tx3904cpu *controller = hw_data (me);
   SIM_DESC sd = hw_system (me);
   sim_cpu *cpu = STATE_CPU (sd, 0); /* NB: fix CPU 0. */
-  address_word cia = CIA_GET (cpu);
+  address_word cia = CPU_PC_GET (cpu);
 
 #define CPU cpu
 
 #define CPU cpu
-#define SD current_state
+#define SD sd
 
   if (controller->pending_reset)
     {
       controller->pending_reset = 0;
 
   if (controller->pending_reset)
     {
       controller->pending_reset = 0;
-      HW_TRACE ((me, "reset pc=0x%08lx", (long) CIA_GET (cpu)));
+      HW_TRACE ((me, "reset pc=0x%08lx", (long) CPU_PC_GET (cpu)));
       SignalExceptionNMIReset();
     }
   else if (controller->pending_nmi)
     {
       controller->pending_nmi = 0;
       SignalExceptionNMIReset();
     }
   else if (controller->pending_nmi)
     {
       controller->pending_nmi = 0;
-      HW_TRACE ((me, "nmi pc=0x%08lx", (long) CIA_GET (cpu)));
+      HW_TRACE ((me, "nmi pc=0x%08lx", (long) CPU_PC_GET (cpu)));
       SignalExceptionNMIReset();
     }
   else if (controller->pending_level)
     {
       HW_TRACE ((me, "interrupt level=%d pc=0x%08lx sr=0x%08lx",
                 controller->pending_level,
       SignalExceptionNMIReset();
     }
   else if (controller->pending_level)
     {
       HW_TRACE ((me, "interrupt level=%d pc=0x%08lx sr=0x%08lx",
                 controller->pending_level,
-                (long) CIA_GET (cpu), (long) SR));
+                (long) CPU_PC_GET (cpu), (long) SR));
 
       /* Clear CAUSE register.  It may stay this way if the interrupt
         was cleared with a negative pending_level. */
       CAUSE &= ~ (cause_IP_mask << cause_IP_shift);
 
 
       /* Clear CAUSE register.  It may stay this way if the interrupt
         was cleared with a negative pending_level. */
       CAUSE &= ~ (cause_IP_mask << cause_IP_shift);
 
-      if(controller->pending_level > 0) /* interrupt set */
+      if (controller->pending_level > 0) /* interrupt set */
        {
          /* set hardware-interrupt subfields of CAUSE register */
          CAUSE |= (controller->pending_level & cause_IP_mask) << cause_IP_shift;
 
          /* check for enabled / unmasked interrupts */
        {
          /* set hardware-interrupt subfields of CAUSE register */
          CAUSE |= (controller->pending_level & cause_IP_mask) << cause_IP_shift;
 
          /* check for enabled / unmasked interrupts */
-         if((SR & status_IEc) &&
+         if ((SR & status_IEc) &&
             (controller->pending_level & ((SR >> status_IM_shift) & status_IM_mask)))
            {
              controller->pending_level = 0;
             (controller->pending_level & ((SR >> status_IM_shift) & status_IM_mask)))
            {
              controller->pending_level = 0;
-             SignalExceptionInterrupt();
+             SignalExceptionInterrupt(0 /* dummy value */);
            }
          else
            {
              /* reschedule soon */
            }
          else
            {
              /* reschedule soon */
-             hw_event_queue_schedule (me, 1, deliver_tx3904cpu_interrupt, NULL);
+             if (controller->event != NULL)
+               hw_event_queue_deschedule(me, controller->event);
+             controller->event =
+               hw_event_queue_schedule (me, 1, deliver_tx3904cpu_interrupt, NULL);
            }
        } /* interrupt set */
     }
            }
        } /* interrupt set */
     }
-#undef CPU cpu
-#undef SD current_state
+#undef CPU
+#undef SD
 }
 
 
 }
 
 
@@ -201,26 +207,26 @@ tx3904cpu_port_event (struct hw *me,
   struct tx3904cpu *controller = hw_data (me);
 
   switch (my_port)
   struct tx3904cpu *controller = hw_data (me);
 
   switch (my_port)
-    {      
+    {
     case RESET_PORT:
       controller->pending_reset = 1;
       HW_TRACE ((me, "port-in reset"));
       break;
     case RESET_PORT:
       controller->pending_reset = 1;
       HW_TRACE ((me, "port-in reset"));
       break;
-      
+
     case NMI_PORT:
       controller->pending_nmi = 1;
       HW_TRACE ((me, "port-in nmi"));
       break;
     case NMI_PORT:
       controller->pending_nmi = 1;
       HW_TRACE ((me, "port-in nmi"));
       break;
-      
+
     case LEVEL_PORT:
       /* level == 0 means that the interrupt was cleared */
     case LEVEL_PORT:
       /* level == 0 means that the interrupt was cleared */
-      if(level == 0)
+      if (level == 0)
        controller->pending_level = -1; /* signal end of interrupt */
       else
        controller->pending_level = level;
       HW_TRACE ((me, "port-in level=%d", level));
       break;
        controller->pending_level = -1; /* signal end of interrupt */
       else
        controller->pending_level = level;
       HW_TRACE ((me, "port-in level=%d", level));
       break;
-      
+
     default:
       hw_abort (me, "bad switch");
       break;
     default:
       hw_abort (me, "bad switch");
       break;
@@ -228,7 +234,10 @@ tx3904cpu_port_event (struct hw *me,
 
   /* Schedule an event to be delivered immediately after current
      instruction. */
 
   /* Schedule an event to be delivered immediately after current
      instruction. */
-  hw_event_queue_schedule (me, 0, deliver_tx3904cpu_interrupt, NULL);
+  if (controller->event != NULL)
+    hw_event_queue_deschedule(me, controller->event);
+  controller->event =
+    hw_event_queue_schedule (me, 0, deliver_tx3904cpu_interrupt, NULL);
 }
 
 
 }