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