Switch the license of all files explicitly copyright the FSF
[external/binutils.git] / sim / m68hc11 / interrupts.c
1 /* interrupts.c -- 68HC11 Interrupts Emulation
2    Copyright 1999, 2000, 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
3    Written by Stephane Carrez (stcarrez@nerim.fr)
4
5 This file is part of GDB, GAS, and the GNU binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "sim-main.h"
21 #include "sim-options.h"
22
23 static const char *interrupt_names[] = {
24   "R1",
25   "R2",
26   "R3",
27   "R4",
28   "R5",
29   "R6",
30   "R7",
31   "R8",
32   "R9",
33   "R10",
34   "R11",
35
36   "SCI",
37   "SPI",
38   "AINPUT",
39   "AOVERFLOW",
40   "TOVERFLOW",
41   "OUT5",
42   "OUT4",
43   "OUT3",
44   "OUT2",
45   "OUT1",
46   "INC3",
47   "INC2",
48   "INC1",
49   "RT",
50   "IRQ",
51   "XIRQ",
52   "SWI",
53   "ILL",
54   "COPRESET",
55   "COPFAIL",
56   "RESET"
57 };
58
59 struct interrupt_def idefs[] = {
60   /* Serial interrupts.  */
61   { M6811_INT_SCI,      M6811_SCSR,   M6811_TDRE,  M6811_SCCR2,  M6811_TIE },
62   { M6811_INT_SCI,      M6811_SCSR,   M6811_TC,    M6811_SCCR2,  M6811_TCIE },
63   { M6811_INT_SCI,      M6811_SCSR,   M6811_RDRF,  M6811_SCCR2,  M6811_RIE },
64   { M6811_INT_SCI,      M6811_SCSR,   M6811_IDLE,  M6811_SCCR2,  M6811_ILIE },
65
66   /* SPI interrupts.  */
67   { M6811_INT_SPI,      M6811_SPSR,   M6811_SPIF,  M6811_SPCR,   M6811_SPIE },
68
69   /* Realtime interrupts.  */
70   { M6811_INT_TCTN,     M6811_TFLG2,  M6811_TOF,   M6811_TMSK2,  M6811_TOI },
71   { M6811_INT_RT,       M6811_TFLG2,  M6811_RTIF,  M6811_TMSK2,  M6811_RTII },
72
73   /* Output compare interrupts.  */
74   { M6811_INT_OUTCMP1,  M6811_TFLG1,  M6811_OC1F,  M6811_TMSK1,  M6811_OC1I },
75   { M6811_INT_OUTCMP2,  M6811_TFLG1,  M6811_OC2F,  M6811_TMSK1,  M6811_OC2I },
76   { M6811_INT_OUTCMP3,  M6811_TFLG1,  M6811_OC3F,  M6811_TMSK1,  M6811_OC3I },
77   { M6811_INT_OUTCMP4,  M6811_TFLG1,  M6811_OC4F,  M6811_TMSK1,  M6811_OC4I },
78   { M6811_INT_OUTCMP5,  M6811_TFLG1,  M6811_OC5F,  M6811_TMSK1,  M6811_OC5I },
79
80   /* Input compare interrupts.  */
81   { M6811_INT_INCMP1,   M6811_TFLG1,  M6811_IC1F,  M6811_TMSK1,  M6811_IC1I },
82   { M6811_INT_INCMP2,   M6811_TFLG1,  M6811_IC2F,  M6811_TMSK1,  M6811_IC2I },
83   { M6811_INT_INCMP3,   M6811_TFLG1,  M6811_IC3F,  M6811_TMSK1,  M6811_IC3I },
84
85   /* Pulse accumulator.  */
86   { M6811_INT_AINPUT,   M6811_TFLG2,  M6811_PAIF,  M6811_TMSK2,  M6811_PAII },
87   { M6811_INT_AOVERFLOW,M6811_TFLG2,  M6811_PAOVF, M6811_TMSK2,  M6811_PAOVI},
88 #if 0
89   { M6811_INT_COPRESET, M6811_CONFIG, M6811_NOCOP, 0,            0 },
90   { M6811_INT_COPFAIL,  M6811_CONFIG, M6811_NOCOP, 0,            0 }
91 #endif
92 };
93
94 #define TableSize(X) (sizeof X / sizeof(X[0]))
95 #define CYCLES_MAX ((((signed64) 1) << 62) - 1)
96
97 enum
98 {
99   OPTION_INTERRUPT_INFO = OPTION_START,
100   OPTION_INTERRUPT_CATCH,
101   OPTION_INTERRUPT_CLEAR
102 };
103
104 static DECLARE_OPTION_HANDLER (interrupt_option_handler);
105
106 static const OPTION interrupt_options[] =
107 {
108   { {"interrupt-info", no_argument, NULL, OPTION_INTERRUPT_INFO },
109       '\0', NULL, "Print information about interrupts",
110       interrupt_option_handler },
111   { {"interrupt-catch", required_argument, NULL, OPTION_INTERRUPT_CATCH },
112       '\0', "NAME[,MODE]",
113     "Catch interrupts when they are raised or taken\n"
114     "NAME   Name of the interrupt\n"
115     "MODE   Optional mode (`taken' or `raised')",
116       interrupt_option_handler },
117   { {"interrupt-clear", required_argument, NULL, OPTION_INTERRUPT_CLEAR },
118       '\0', "NAME", "No longer catch the interrupt",
119       interrupt_option_handler },
120   
121   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
122 };
123
124 /* Initialize the interrupts module.  */
125 void
126 interrupts_initialize (SIM_DESC sd, struct _sim_cpu *proc)
127 {
128   struct interrupts *interrupts = &proc->cpu_interrupts;
129   
130   interrupts->cpu          = proc;
131
132   sim_add_option_table (sd, 0, interrupt_options);
133 }
134
135 /* Initialize the interrupts of the processor.  */
136 void
137 interrupts_reset (struct interrupts *interrupts)
138 {
139   int i;
140   
141   interrupts->pending_mask = 0;
142   if (interrupts->cpu->cpu_mode & M6811_SMOD)
143     interrupts->vectors_addr = 0xbfc0;
144   else
145     interrupts->vectors_addr = 0xffc0;
146   interrupts->nb_interrupts_raised = 0;
147   interrupts->min_mask_cycles = CYCLES_MAX;
148   interrupts->max_mask_cycles = 0;
149   interrupts->last_mask_cycles = 0;
150   interrupts->start_mask_cycle = -1;
151   interrupts->xirq_start_mask_cycle = -1;
152   interrupts->xirq_max_mask_cycles = 0;
153   interrupts->xirq_min_mask_cycles = CYCLES_MAX;
154   interrupts->xirq_last_mask_cycles = 0;
155   
156   for (i = 0; i < M6811_INT_NUMBER; i++)
157     {
158       interrupts->interrupt_order[i] = i;
159     }
160
161   /* Clear the interrupt history table.  */
162   interrupts->history_index = 0;
163   memset (interrupts->interrupts_history, 0,
164           sizeof (interrupts->interrupts_history));
165
166   memset (interrupts->interrupts, 0,
167           sizeof (interrupts->interrupts));
168
169   /* In bootstrap mode, initialize the vector table to point
170      to the RAM location.  */
171   if (interrupts->cpu->cpu_mode == M6811_SMOD)
172     {
173       bfd_vma addr = interrupts->vectors_addr;
174       uint16 vector = 0x0100 - 3 * (M6811_INT_NUMBER - 1);
175       for (i = 0; i < M6811_INT_NUMBER; i++)
176         {
177           memory_write16 (interrupts->cpu, addr, vector);
178           addr += 2;
179           vector += 3;
180         }
181     }
182 }
183
184 static int
185 find_interrupt (const char *name)
186 {
187   int i;
188
189   if (name)
190     for (i = 0; i < M6811_INT_NUMBER; i++)
191       if (strcasecmp (name, interrupt_names[i]) == 0)
192         return i;
193
194   return -1;
195 }
196
197 static SIM_RC
198 interrupt_option_handler (SIM_DESC sd, sim_cpu *cpu,
199                           int opt, char *arg, int is_command)
200 {
201   char *p;
202   int mode;
203   int id;
204   struct interrupts *interrupts;
205
206   if (cpu == 0)
207     cpu = STATE_CPU (sd, 0);
208
209   interrupts = &cpu->cpu_interrupts;
210   switch (opt)
211     {
212     case OPTION_INTERRUPT_INFO:
213       for (id = 0; id < M6811_INT_NUMBER; id++)
214         {
215           sim_io_eprintf (sd, "%-10.10s ", interrupt_names[id]);
216           switch (interrupts->interrupts[id].stop_mode)
217             {
218             case SIM_STOP_WHEN_RAISED:
219               sim_io_eprintf (sd, "catch raised ");
220               break;
221
222             case SIM_STOP_WHEN_TAKEN:
223               sim_io_eprintf (sd, "catch taken  ");
224               break;
225
226             case SIM_STOP_WHEN_RAISED | SIM_STOP_WHEN_TAKEN:
227               sim_io_eprintf (sd, "catch all    ");
228               break;
229
230             default:
231               sim_io_eprintf (sd, "             ");
232               break;
233             }
234           sim_io_eprintf (sd, "%ld\n",
235                           interrupts->interrupts[id].raised_count);
236         }
237       break;
238
239     case OPTION_INTERRUPT_CATCH:
240       p = strchr (arg, ',');
241       if (p)
242         *p++ = 0;
243
244       mode = SIM_STOP_WHEN_RAISED;
245       id = find_interrupt (arg);
246       if (id < 0)
247         sim_io_eprintf (sd, "Interrupt name not recognized: %s\n", arg);
248
249       if (p && strcasecmp (p, "raised") == 0)
250         mode = SIM_STOP_WHEN_RAISED;
251       else if (p && strcasecmp (p, "taken") == 0)
252         mode = SIM_STOP_WHEN_TAKEN;
253       else if (p && strcasecmp (p, "all") == 0)
254         mode = SIM_STOP_WHEN_RAISED | SIM_STOP_WHEN_TAKEN;
255       else if (p)
256         {
257           sim_io_eprintf (sd, "Invalid argument: %s\n", p);
258           break;
259         }
260       if (id >= 0)
261         interrupts->interrupts[id].stop_mode = mode;
262       break;
263
264     case OPTION_INTERRUPT_CLEAR:
265       mode = SIM_STOP_WHEN_RAISED;
266       id = find_interrupt (arg);
267       if (id < 0)
268         sim_io_eprintf (sd, "Interrupt name not recognized: %s\n", arg);
269       else
270         interrupts->interrupts[id].stop_mode = 0;      
271       break;      
272     }
273
274   return SIM_RC_OK;
275 }
276
277 /* Update the mask of pending interrupts.  This operation must be called
278    when the state of some 68HC11 IO register changes.  It looks the
279    different registers that indicate a pending interrupt (timer, SCI, SPI,
280    ...) and records the interrupt if it's there and enabled.  */
281 void
282 interrupts_update_pending (struct interrupts *interrupts)
283 {
284   int i;
285   uint8 *ioregs;
286   unsigned long clear_mask;
287   unsigned long set_mask;
288
289   clear_mask = 0;
290   set_mask = 0;
291   ioregs = &interrupts->cpu->ios[0];
292   
293   for (i = 0; i < TableSize(idefs); i++)
294     {
295       struct interrupt_def *idef = &idefs[i];
296       uint8 data;
297       
298       /* Look if the interrupt is enabled.  */
299       if (idef->enable_paddr)
300         {
301           data = ioregs[idef->enable_paddr];
302           if (!(data & idef->enabled_mask))
303             {
304               /* Disable it.  */
305               clear_mask |= (1 << idef->int_number);
306               continue;
307             }
308         }
309
310       /* Interrupt is enabled, see if it's there.  */
311       data = ioregs[idef->int_paddr];
312       if (!(data & idef->int_mask))
313         {
314           /* Disable it.  */
315           clear_mask |= (1 << idef->int_number);
316           continue;
317         }
318
319       /* Ok, raise it.  */
320       set_mask |= (1 << idef->int_number);
321     }
322
323   /* Some interrupts are shared (M6811_INT_SCI) so clear
324      the interrupts before setting the new ones.  */
325   interrupts->pending_mask &= ~clear_mask;
326   interrupts->pending_mask |= set_mask;
327
328   /* Keep track of when the interrupt is raised by the device.
329      Also implements the breakpoint-on-interrupt.  */
330   if (set_mask)
331     {
332       signed64 cycle = cpu_current_cycle (interrupts->cpu);
333       int must_stop = 0;
334       
335       for (i = 0; i < M6811_INT_NUMBER; i++)
336         {
337           if (!(set_mask & (1 << i)))
338             continue;
339
340           interrupts->interrupts[i].cpu_cycle = cycle;
341           if (interrupts->interrupts[i].stop_mode & SIM_STOP_WHEN_RAISED)
342             {
343               must_stop = 1;
344               sim_io_printf (CPU_STATE (interrupts->cpu),
345                              "Interrupt %s raised\n",
346                              interrupt_names[i]);
347             }
348         }
349       if (must_stop)
350         sim_engine_halt (CPU_STATE (interrupts->cpu),
351                          interrupts->cpu,
352                          0, cpu_get_pc (interrupts->cpu),
353                          sim_stopped,
354                          SIM_SIGTRAP);
355     }
356 }
357
358
359 /* Finds the current active and non-masked interrupt.
360    Returns the interrupt number (index in the vector table) or -1
361    if no interrupt can be serviced.  */
362 int
363 interrupts_get_current (struct interrupts *interrupts)
364 {
365   int i;
366   
367   if (interrupts->pending_mask == 0)
368     return -1;
369
370   /* SWI and illegal instructions are simulated by an interrupt.
371      They are not maskable.  */
372   if (interrupts->pending_mask & (1 << M6811_INT_SWI))
373     {
374       interrupts->pending_mask &= ~(1 << M6811_INT_SWI);
375       return M6811_INT_SWI;
376     }
377   if (interrupts->pending_mask & (1 << M6811_INT_ILLEGAL))
378     {
379       interrupts->pending_mask &= ~(1 << M6811_INT_ILLEGAL);
380       return M6811_INT_ILLEGAL;
381     }
382   
383   /* If there is a non maskable interrupt, go for it (unless we are masked
384      by the X-bit.  */
385   if (interrupts->pending_mask & (1 << M6811_INT_XIRQ))
386     {
387       if (cpu_get_ccr_X (interrupts->cpu) == 0)
388         {
389           interrupts->pending_mask &= ~(1 << M6811_INT_XIRQ);
390           return M6811_INT_XIRQ;
391         }
392       return -1;
393     }
394
395   /* Interrupts are masked, do nothing.  */
396   if (cpu_get_ccr_I (interrupts->cpu) == 1)
397     {
398       return -1;
399     }
400
401   /* Returns the first interrupt number which is pending.
402      The interrupt priority is specified by the table `interrupt_order'.
403      For these interrupts, the pending mask is cleared when the program
404      performs some actions on the corresponding device.  If the device
405      is not reset, the interrupt remains and will be re-raised when
406      we return from the interrupt (see 68HC11 pink book).  */
407   for (i = 0; i < M6811_INT_NUMBER; i++)
408     {
409       enum M6811_INT int_number = interrupts->interrupt_order[i];
410
411       if (interrupts->pending_mask & (1 << int_number))
412         {
413           return int_number;
414         }
415     }
416   return -1;
417 }
418
419
420 /* Process the current interrupt if there is one.  This operation must
421    be called after each instruction to handle the interrupts.  If interrupts
422    are masked, it does nothing.  */
423 int
424 interrupts_process (struct interrupts *interrupts)
425 {
426   int id;
427   uint8 ccr;
428
429   /* See if interrupts are enabled/disabled and keep track of the
430      number of cycles the interrupts are masked.  Such information is
431      then reported by the info command.  */
432   ccr = cpu_get_ccr (interrupts->cpu);
433   if (ccr & M6811_I_BIT)
434     {
435       if (interrupts->start_mask_cycle < 0)
436         interrupts->start_mask_cycle = cpu_current_cycle (interrupts->cpu);
437     }
438   else if (interrupts->start_mask_cycle >= 0
439            && (ccr & M6811_I_BIT) == 0)
440     {
441       signed64 t = cpu_current_cycle (interrupts->cpu);
442
443       t -= interrupts->start_mask_cycle;
444       if (t < interrupts->min_mask_cycles)
445         interrupts->min_mask_cycles = t;
446       if (t > interrupts->max_mask_cycles)
447         interrupts->max_mask_cycles = t;
448       interrupts->start_mask_cycle = -1;
449       interrupts->last_mask_cycles = t;
450     }
451   if (ccr & M6811_X_BIT)
452     {
453       if (interrupts->xirq_start_mask_cycle < 0)
454         interrupts->xirq_start_mask_cycle
455           = cpu_current_cycle (interrupts->cpu);
456     }
457   else if (interrupts->xirq_start_mask_cycle >= 0
458            && (ccr & M6811_X_BIT) == 0)
459     {
460       signed64 t = cpu_current_cycle (interrupts->cpu);
461
462       t -= interrupts->xirq_start_mask_cycle;
463       if (t < interrupts->xirq_min_mask_cycles)
464         interrupts->xirq_min_mask_cycles = t;
465       if (t > interrupts->xirq_max_mask_cycles)
466         interrupts->xirq_max_mask_cycles = t;
467       interrupts->xirq_start_mask_cycle = -1;
468       interrupts->xirq_last_mask_cycles = t;
469     }
470
471   id = interrupts_get_current (interrupts);
472   if (id >= 0)
473     {
474       uint16 addr;
475       struct interrupt_history *h;
476
477       /* Implement the breakpoint-on-interrupt.  */
478       if (interrupts->interrupts[id].stop_mode & SIM_STOP_WHEN_TAKEN)
479         {
480           sim_io_printf (CPU_STATE (interrupts->cpu),
481                          "Interrupt %s will be handled\n",
482                          interrupt_names[id]);
483           sim_engine_halt (CPU_STATE (interrupts->cpu),
484                            interrupts->cpu,
485                            0, cpu_get_pc (interrupts->cpu),
486                            sim_stopped,
487                            SIM_SIGTRAP);
488         }
489
490       cpu_push_all (interrupts->cpu);
491       addr = memory_read16 (interrupts->cpu,
492                             interrupts->vectors_addr + id * 2);
493       cpu_call (interrupts->cpu, addr);
494
495       /* Now, protect from nested interrupts.  */
496       if (id == M6811_INT_XIRQ)
497         {
498           cpu_set_ccr_X (interrupts->cpu, 1);
499         }
500       else
501         {
502           cpu_set_ccr_I (interrupts->cpu, 1);
503         }
504
505       /* Update the interrupt history table.  */
506       h = &interrupts->interrupts_history[interrupts->history_index];
507       h->type = id;
508       h->taken_cycle = cpu_current_cycle (interrupts->cpu);
509       h->raised_cycle = interrupts->interrupts[id].cpu_cycle;
510       
511       if (interrupts->history_index >= MAX_INT_HISTORY-1)
512         interrupts->history_index = 0;
513       else
514         interrupts->history_index++;
515
516       interrupts->nb_interrupts_raised++;
517       cpu_add_cycles (interrupts->cpu, 14);
518       return 1;
519     }
520   return 0;
521 }
522
523 void
524 interrupts_raise (struct interrupts *interrupts, enum M6811_INT number)
525 {
526   interrupts->pending_mask |= (1 << number);
527   interrupts->nb_interrupts_raised ++;
528 }
529
530 void
531 interrupts_info (SIM_DESC sd, struct interrupts *interrupts)
532 {
533   signed64 t, prev_interrupt;
534   int i;
535   
536   sim_io_printf (sd, "Interrupts Info:\n");
537   sim_io_printf (sd, "  Interrupts raised: %lu\n",
538                  interrupts->nb_interrupts_raised);
539
540   if (interrupts->start_mask_cycle >= 0)
541     {
542       t = cpu_current_cycle (interrupts->cpu);
543
544       t -= interrupts->start_mask_cycle;
545       if (t > interrupts->max_mask_cycles)
546         interrupts->max_mask_cycles = t;
547
548       sim_io_printf (sd, "  Current interrupts masked sequence:   %s\n",
549                      cycle_to_string (interrupts->cpu, t,
550                                       PRINT_TIME | PRINT_CYCLE));
551     }
552   t = interrupts->min_mask_cycles == CYCLES_MAX ?
553     interrupts->max_mask_cycles :
554     interrupts->min_mask_cycles;
555   sim_io_printf (sd, "  Shortest interrupts masked sequence:  %s\n",
556                  cycle_to_string (interrupts->cpu, t,
557                                   PRINT_TIME | PRINT_CYCLE));
558
559   t = interrupts->max_mask_cycles;
560   sim_io_printf (sd, "  Longest interrupts masked sequence:   %s\n",
561                  cycle_to_string (interrupts->cpu, t,
562                                   PRINT_TIME | PRINT_CYCLE));
563
564   t = interrupts->last_mask_cycles;
565   sim_io_printf (sd, "  Last interrupts masked sequence:      %s\n",
566                  cycle_to_string (interrupts->cpu, t,
567                                   PRINT_TIME | PRINT_CYCLE));
568   
569   if (interrupts->xirq_start_mask_cycle >= 0)
570     {
571       t = cpu_current_cycle (interrupts->cpu);
572
573       t -= interrupts->xirq_start_mask_cycle;
574       if (t > interrupts->xirq_max_mask_cycles)
575         interrupts->xirq_max_mask_cycles = t;
576
577       sim_io_printf (sd, "  XIRQ Current interrupts masked sequence: %s\n",
578                      cycle_to_string (interrupts->cpu, t,
579                                       PRINT_TIME | PRINT_CYCLE));
580     }
581
582   t = interrupts->xirq_min_mask_cycles == CYCLES_MAX ?
583     interrupts->xirq_max_mask_cycles :
584     interrupts->xirq_min_mask_cycles;
585   sim_io_printf (sd, "  XIRQ Min interrupts masked sequence:  %s\n",
586                  cycle_to_string (interrupts->cpu, t,
587                                   PRINT_TIME | PRINT_CYCLE));
588
589   t = interrupts->xirq_max_mask_cycles;
590   sim_io_printf (sd, "  XIRQ Max interrupts masked sequence:  %s\n",
591                  cycle_to_string (interrupts->cpu, t,
592                                   PRINT_TIME | PRINT_CYCLE));
593
594   t = interrupts->xirq_last_mask_cycles;
595   sim_io_printf (sd, "  XIRQ Last interrupts masked sequence: %s\n",
596                  cycle_to_string (interrupts->cpu, t,
597                                   PRINT_TIME | PRINT_CYCLE));
598
599   if (interrupts->pending_mask)
600     {
601       sim_io_printf (sd, "  Pending interrupts : ");
602       for (i = 0; i < M6811_INT_NUMBER; i++)
603         {
604           enum M6811_INT int_number = interrupts->interrupt_order[i];
605           
606           if (interrupts->pending_mask & (1 << int_number))
607             {
608               sim_io_printf (sd, "%s ", interrupt_names[int_number]);
609             }
610         }
611       sim_io_printf (sd, "\n");
612     }
613
614   prev_interrupt = 0;
615   sim_io_printf (sd, "N  Interrupt     Cycle Taken         Latency"
616                  "   Delta between interrupts\n");
617   for (i = 0; i < MAX_INT_HISTORY; i++)
618     {
619       int which;
620       struct interrupt_history *h;
621       signed64 dt;
622
623       which = interrupts->history_index - i - 1;
624       if (which < 0)
625         which += MAX_INT_HISTORY;
626       h = &interrupts->interrupts_history[which];
627       if (h->taken_cycle == 0)
628         break;
629
630       dt = h->taken_cycle - h->raised_cycle;
631       sim_io_printf (sd, "%2d %-9.9s %15.15s ", i,
632                      interrupt_names[h->type],
633                      cycle_to_string (interrupts->cpu, h->taken_cycle, 0));
634       sim_io_printf (sd, "%15.15s",
635                      cycle_to_string (interrupts->cpu, dt, 0));
636       if (prev_interrupt)
637         {
638           dt = prev_interrupt - h->taken_cycle;
639           sim_io_printf (sd, " %s",
640                          cycle_to_string (interrupts->cpu, dt, PRINT_TIME));
641         }
642       sim_io_printf (sd, "\n");
643       prev_interrupt = h->taken_cycle;
644     }
645 }