Don't deprecate powerpc mftb insn
[platform/upstream/binutils.git] / sim / m68hc11 / interp.c
1 /* interp.c -- Simulator for Motorola 68HC11/68HC12
2    Copyright (C) 1999-2014 Free Software Foundation, Inc.
3    Written by Stephane Carrez (stcarrez@nerim.fr)
4
5 This file is part of GDB, the GNU debugger.
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-assert.h"
22 #include "sim-hw.h"
23 #include "sim-options.h"
24 #include "hw-tree.h"
25 #include "hw-device.h"
26 #include "hw-ports.h"
27 #include "elf32-m68hc1x.h"
28
29 #ifndef MONITOR_BASE
30 # define MONITOR_BASE (0x0C000)
31 # define MONITOR_SIZE (0x04000)
32 #endif
33
34 static void sim_get_info (SIM_DESC sd, char *cmd);
35
36
37 char *interrupt_names[] = {
38   "reset",
39   "nmi",
40   "int",
41   NULL
42 };
43
44 #ifndef INLINE
45 #if defined(__GNUC__) && defined(__OPTIMIZE__)
46 #define INLINE __inline__
47 #else
48 #define INLINE
49 #endif
50 #endif
51
52 struct sim_info_list
53 {
54   const char *name;
55   const char *device;
56 };
57
58 struct sim_info_list dev_list_68hc11[] = {
59   {"cpu", "/m68hc11"},
60   {"timer", "/m68hc11/m68hc11tim"},
61   {"sio", "/m68hc11/m68hc11sio"},
62   {"spi", "/m68hc11/m68hc11spi"},
63   {"eeprom", "/m68hc11/m68hc11eepr"},
64   {0, 0}
65 };
66
67 struct sim_info_list dev_list_68hc12[] = {
68   {"cpu", "/m68hc12"},
69   {"timer", "/m68hc12/m68hc12tim"},
70   {"sio", "/m68hc12/m68hc12sio"},
71   {"spi", "/m68hc12/m68hc12spi"},
72   {"eeprom", "/m68hc12/m68hc12eepr"},
73   {0, 0}
74 };
75
76 /* Cover function of sim_state_free to free the cpu buffers as well.  */
77
78 static void
79 free_state (SIM_DESC sd)
80 {
81   if (STATE_MODULES (sd) != NULL)
82     sim_module_uninstall (sd);
83
84   sim_state_free (sd);
85 }
86
87 /* Give some information about the simulator.  */
88 static void
89 sim_get_info (SIM_DESC sd, char *cmd)
90 {
91   sim_cpu *cpu;
92
93   cpu = STATE_CPU (sd, 0);
94   if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
95     {
96       int i;
97       struct hw *hw_dev;
98       struct sim_info_list *dev_list;
99       const struct bfd_arch_info *arch;
100
101       arch = STATE_ARCHITECTURE (sd);
102       cmd++;
103
104       if (arch->arch == bfd_arch_m68hc11)
105         dev_list = dev_list_68hc11;
106       else
107         dev_list = dev_list_68hc12;
108
109       for (i = 0; dev_list[i].name; i++)
110         if (strcmp (cmd, dev_list[i].name) == 0)
111           break;
112
113       if (dev_list[i].name == 0)
114         {
115           sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
116           sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
117           return;
118         }
119       hw_dev = sim_hw_parse (sd, dev_list[i].device);
120       if (hw_dev == 0)
121         {
122           sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
123           return;
124         }
125       hw_ioctl (hw_dev, 23, 0);
126       return;
127     }
128
129   cpu_info (sd, cpu);
130   interrupts_info (sd, &cpu->cpu_interrupts);
131 }
132
133
134 void
135 sim_board_reset (SIM_DESC sd)
136 {
137   struct hw *hw_cpu;
138   sim_cpu *cpu;
139   const struct bfd_arch_info *arch;
140   const char *cpu_type;
141
142   cpu = STATE_CPU (sd, 0);
143   arch = STATE_ARCHITECTURE (sd);
144
145   /*  hw_cpu = sim_hw_parse (sd, "/"); */
146   if (arch->arch == bfd_arch_m68hc11)
147     {
148       cpu->cpu_type = CPU_M6811;
149       cpu_type = "/m68hc11";
150     }
151   else
152     {
153       cpu->cpu_type = CPU_M6812;
154       cpu_type = "/m68hc12";
155     }
156   
157   hw_cpu = sim_hw_parse (sd, cpu_type);
158   if (hw_cpu == 0)
159     {
160       sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
161       return;
162     }
163
164   cpu_reset (cpu);
165   hw_port_event (hw_cpu, 3, 0);
166   cpu_restart (cpu);
167 }
168
169 static int
170 sim_hw_configure (SIM_DESC sd)
171 {
172   const struct bfd_arch_info *arch;
173   struct hw *device_tree;
174   sim_cpu *cpu;
175   
176   arch = STATE_ARCHITECTURE (sd);
177   if (arch == 0)
178     return 0;
179
180   cpu = STATE_CPU (sd, 0);
181   cpu->cpu_configured_arch = arch;
182   device_tree = sim_hw_parse (sd, "/");
183   if (arch->arch == bfd_arch_m68hc11)
184     {
185       cpu->cpu_interpretor = cpu_interp_m6811;
186       if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
187         {
188           /* Allocate core managed memory */
189
190           /* the monitor  */
191           sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
192                            /* MONITOR_BASE, MONITOR_SIZE */
193                            0x8000, M6811_RAM_LEVEL, 0x8000);
194           sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
195                            M6811_RAM_LEVEL);
196           sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
197           if (cpu->bank_start < cpu->bank_end)
198             {
199               sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
200                                cpu->bank_virtual, M6811_RAM_LEVEL);
201               sim_hw_parse (sd, "/m68hc11/use_bank 1");
202             }
203         }
204       if (cpu->cpu_start_mode)
205         {
206           sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
207         }
208       if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
209         {
210           sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
211           sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
212           sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
213         }
214       if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
215         {
216           /* M68hc11 Timer configuration. */
217           sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
218           sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
219           sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
220         }
221
222       /* Create the SPI device.  */
223       if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
224         {
225           sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
226           sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
227         }
228       if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
229         {
230           /* M68hc11 persistent ram configuration. */
231           sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
232           sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
233           sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
234           /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
235         }
236       if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
237         {
238           sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
239           sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
240         }
241       sim_hw_parse (sd, "/m68hc11 > port-a cpu-write-port /m68hc11");
242       sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
243       sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
244       sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
245       cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
246     }
247   else
248     {
249       cpu->cpu_interpretor = cpu_interp_m6812;
250       if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
251         {
252           /* Allocate core external memory.  */
253           sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
254                            0x8000, M6811_RAM_LEVEL, 0x8000);
255           sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
256                            M6811_RAM_LEVEL);
257           if (cpu->bank_start < cpu->bank_end)
258             {
259               sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
260                                cpu->bank_virtual, M6811_RAM_LEVEL);
261               sim_hw_parse (sd, "/m68hc12/use_bank 1");
262             }
263           sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
264         }
265
266       if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
267         {
268           sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
269           sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
270           sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
271         }
272       if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
273         {
274           /* M68hc11 Timer configuration. */
275           sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
276           sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
277           sim_hw_parse (sd, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
278         }
279
280       /* Create the SPI device.  */
281       if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
282         {
283           sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
284           sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
285         }
286       if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
287         {
288           /* M68hc11 persistent ram configuration. */
289           sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
290           sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
291           sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
292         }
293       if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
294         {
295           sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
296           sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
297         }
298
299       sim_hw_parse (sd, "/m68hc12 > port-a cpu-write-port /m68hc12");
300       sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
301       sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
302       sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
303       cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
304     }
305   return 1;
306 }
307
308 /* Get the memory bank parameters by looking at the global symbols
309    defined by the linker.  */
310 static int
311 sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
312 {
313   sim_cpu *cpu;
314   long symsize;
315   long symbol_count, i;
316   unsigned size;
317   asymbol** asymbols;
318   asymbol** current;
319
320   cpu = STATE_CPU (sd, 0);
321
322   symsize = bfd_get_symtab_upper_bound (abfd);
323   if (symsize < 0)
324     {
325       sim_io_eprintf (sd, "Cannot read symbols of program");
326       return 0;
327     }
328   asymbols = (asymbol **) xmalloc (symsize);
329   symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
330   if (symbol_count < 0)
331     {
332       sim_io_eprintf (sd, "Cannot read symbols of program");
333       return 0;
334     }
335
336   size = 0;
337   for (i = 0, current = asymbols; i < symbol_count; i++, current++)
338     {
339       const char* name = bfd_asymbol_name (*current);
340
341       if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
342         {
343           cpu->bank_start = bfd_asymbol_value (*current);
344         }
345       else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
346         {
347           size = bfd_asymbol_value (*current);
348         }
349       else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
350         {
351           cpu->bank_virtual = bfd_asymbol_value (*current);
352         }
353     }
354   free (asymbols);
355
356   cpu->bank_end = cpu->bank_start + size;
357   cpu->bank_shift = 0;
358   for (; size > 1; size >>= 1)
359     cpu->bank_shift++;
360
361   return 0;
362 }
363
364 static int
365 sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
366 {
367   sim_cpu *cpu;
368   int elf_flags = 0;
369
370   cpu = STATE_CPU (sd, 0);
371
372   if (abfd != NULL)
373     {
374       asection *s;
375
376       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
377         elf_flags = elf_elfheader (abfd)->e_flags;
378
379       cpu->cpu_elf_start = bfd_get_start_address (abfd);
380       /* See if any section sets the reset address */
381       cpu->cpu_use_elf_start = 1;
382       for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next) 
383         {
384           if (s->flags & SEC_LOAD)
385             {
386               bfd_size_type size;
387
388               size = bfd_get_section_size (s);
389               if (size > 0)
390                 {
391                   bfd_vma lma;
392
393                   if (STATE_LOAD_AT_LMA_P (sd))
394                     lma = bfd_section_lma (abfd, s);
395                   else
396                     lma = bfd_section_vma (abfd, s);
397
398                   if (lma <= 0xFFFE && lma+size >= 0x10000)
399                     cpu->cpu_use_elf_start = 0;
400                 }
401             }
402         }
403
404       if (elf_flags & E_M68HC12_BANKS)
405         {
406           if (sim_get_bank_parameters (sd, abfd) != 0)
407             sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
408         }
409     }
410
411   if (!sim_hw_configure (sd))
412     return SIM_RC_FAIL;
413
414   /* reset all state information */
415   sim_board_reset (sd);
416
417   return SIM_RC_OK;
418 }
419
420 SIM_DESC
421 sim_open (SIM_OPEN_KIND kind, host_callback *callback,
422           bfd *abfd, char **argv)
423 {
424   SIM_DESC sd;
425   sim_cpu *cpu;
426
427   sd = sim_state_alloc (kind, callback);
428   cpu = STATE_CPU (sd, 0);
429
430   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
431
432   /* for compatibility */
433   current_alignment = NONSTRICT_ALIGNMENT;
434   current_target_byte_order = BIG_ENDIAN;
435
436   cpu_initialize (sd, cpu);
437
438   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
439     {
440       free_state (sd);
441       return 0;
442     }
443
444   /* getopt will print the error message so we just have to exit if this fails.
445      FIXME: Hmmm...  in the case of gdb we need getopt to call
446      print_filtered.  */
447   if (sim_parse_args (sd, argv) != SIM_RC_OK)
448     {
449       /* Uninstall the modules to avoid memory leaks,
450          file descriptor leaks, etc.  */
451       free_state (sd);
452       return 0;
453     }
454
455   /* Check for/establish the a reference program image.  */
456   if (sim_analyze_program (sd,
457                            (STATE_PROG_ARGV (sd) != NULL
458                             ? *STATE_PROG_ARGV (sd)
459                             : NULL), abfd) != SIM_RC_OK)
460     {
461       free_state (sd);
462       return 0;
463     }
464
465   /* Establish any remaining configuration options.  */
466   if (sim_config (sd) != SIM_RC_OK)
467     {
468       free_state (sd);
469       return 0;
470     }
471
472   if (sim_post_argv_init (sd) != SIM_RC_OK)
473     {
474       /* Uninstall the modules to avoid memory leaks,
475          file descriptor leaks, etc.  */
476       free_state (sd);
477       return 0;
478     }
479   if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
480     {
481       free_state (sd);
482       return 0;
483     }      
484
485   /* Fudge our descriptor.  */
486   return sd;
487 }
488
489
490 void
491 sim_close (SIM_DESC sd, int quitting)
492 {
493   /* shut down modules */
494   sim_module_uninstall (sd);
495
496   /* Ensure that any resources allocated through the callback
497      mechanism are released: */
498   sim_io_shutdown (sd);
499
500   /* FIXME - free SD */
501   sim_state_free (sd);
502   return;
503 }
504
505 void
506 sim_set_profile (int n)
507 {
508 }
509
510 void
511 sim_set_profile_size (int n)
512 {
513 }
514
515 /* Generic implementation of sim_engine_run that works within the
516    sim_engine setjmp/longjmp framework. */
517
518 void
519 sim_engine_run (SIM_DESC sd,
520                 int next_cpu_nr,        /* ignore */
521                 int nr_cpus,    /* ignore */
522                 int siggnal)    /* ignore */
523 {
524   sim_cpu *cpu;
525
526   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
527   cpu = STATE_CPU (sd, 0);
528   while (1)
529     {
530       cpu_single_step (cpu);
531
532       /* process any events */
533       if (sim_events_tickn (sd, cpu->cpu_current_cycle))
534         {
535           sim_events_process (sd);
536         }
537     }
538 }
539
540 int
541 sim_trace (SIM_DESC sd)
542 {
543   sim_resume (sd, 0, 0);
544   return 1;
545 }
546
547 void
548 sim_info (SIM_DESC sd, int verbose)
549 {
550   const char *cpu_type;
551   const struct bfd_arch_info *arch;
552
553   /* Nothing to do if there is no verbose flag set.  */
554   if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
555     return;
556
557   arch = STATE_ARCHITECTURE (sd);
558   if (arch->arch == bfd_arch_m68hc11)
559     cpu_type = "68HC11";
560   else
561     cpu_type = "68HC12";
562
563   sim_io_eprintf (sd, "Simulator info:\n");
564   sim_io_eprintf (sd, "  CPU Motorola %s\n", cpu_type);
565   sim_get_info (sd, 0);
566   sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
567 }
568
569 SIM_RC
570 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
571                      char **argv, char **env)
572 {
573   return sim_prepare_for_program (sd, abfd);
574 }
575
576
577 void
578 sim_set_callbacks (host_callback *p)
579 {
580   /*  m6811_callback = p; */
581 }
582
583
584 int
585 sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
586 {
587   sim_cpu *cpu;
588   uint16 val;
589   int size = 2;
590
591   cpu = STATE_CPU (sd, 0);
592   switch (rn)
593     {
594     case A_REGNUM:
595       val = cpu_get_a (cpu);
596       size = 1;
597       break;
598
599     case B_REGNUM:
600       val = cpu_get_b (cpu);
601       size = 1;
602       break;
603
604     case D_REGNUM:
605       val = cpu_get_d (cpu);
606       break;
607
608     case X_REGNUM:
609       val = cpu_get_x (cpu);
610       break;
611
612     case Y_REGNUM:
613       val = cpu_get_y (cpu);
614       break;
615
616     case SP_REGNUM:
617       val = cpu_get_sp (cpu);
618       break;
619
620     case PC_REGNUM:
621       val = cpu_get_pc (cpu);
622       break;
623
624     case PSW_REGNUM:
625       val = cpu_get_ccr (cpu);
626       size = 1;
627       break;
628
629     case PAGE_REGNUM:
630       val = cpu_get_page (cpu);
631       size = 1;
632       break;
633
634     default:
635       val = 0;
636       break;
637     }
638   if (size == 1)
639     {
640       memory[0] = val;
641     }
642   else
643     {
644       memory[0] = val >> 8;
645       memory[1] = val & 0x0FF;
646     }
647   return size;
648 }
649
650 int
651 sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
652 {
653   uint16 val;
654   sim_cpu *cpu;
655
656   cpu = STATE_CPU (sd, 0);
657
658   val = *memory++;
659   if (length == 2)
660     val = (val << 8) | *memory;
661
662   switch (rn)
663     {
664     case D_REGNUM:
665       cpu_set_d (cpu, val);
666       break;
667
668     case A_REGNUM:
669       cpu_set_a (cpu, val);
670       return 1;
671
672     case B_REGNUM:
673       cpu_set_b (cpu, val);
674       return 1;
675
676     case X_REGNUM:
677       cpu_set_x (cpu, val);
678       break;
679
680     case Y_REGNUM:
681       cpu_set_y (cpu, val);
682       break;
683
684     case SP_REGNUM:
685       cpu_set_sp (cpu, val);
686       break;
687
688     case PC_REGNUM:
689       cpu_set_pc (cpu, val);
690       break;
691
692     case PSW_REGNUM:
693       cpu_set_ccr (cpu, val);
694       return 1;
695
696     case PAGE_REGNUM:
697       cpu_set_page (cpu, val);
698       return 1;
699
700     default:
701       break;
702     }
703
704   return 2;
705 }
706
707 void
708 sim_size (int s)
709 {
710   ;
711 }
712
713 /* Halt the simulator after just one instruction */
714
715 static void
716 has_stepped (SIM_DESC sd,
717              void *data)
718 {
719   ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
720   sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
721 }
722
723
724 /* Generic resume - assumes the existance of sim_engine_run */
725
726 void
727 sim_resume (SIM_DESC sd,
728             int step,
729             int siggnal)
730 {
731   sim_engine *engine = STATE_ENGINE (sd);
732   jmp_buf buf;
733   int jmpval;
734
735   ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
736
737   /* we only want to be single stepping the simulator once */
738   if (engine->stepper != NULL)
739     {
740       sim_events_deschedule (sd, engine->stepper);
741       engine->stepper = NULL;
742     }
743   sim_module_resume (sd);
744
745   /* run/resume the simulator */
746   engine->jmpbuf = &buf;
747   jmpval = setjmp (buf);
748   if (jmpval == sim_engine_start_jmpval
749       || jmpval == sim_engine_restart_jmpval)
750     {
751       int last_cpu_nr = sim_engine_last_cpu_nr (sd);
752       int next_cpu_nr = sim_engine_next_cpu_nr (sd);
753       int nr_cpus = sim_engine_nr_cpus (sd);
754
755       sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
756       if (next_cpu_nr >= nr_cpus)
757         next_cpu_nr = 0;
758
759       /* Only deliver the siggnal ]sic] the first time through - don't
760          re-deliver any siggnal during a restart. */
761       if (jmpval == sim_engine_restart_jmpval)
762         siggnal = 0;
763
764       /* Install the stepping event after having processed some
765          pending events.  This is necessary for HC11/HC12 simulator
766          because the tick counter is incremented by the number of cycles
767          the instruction took.  Some pending ticks to process can still
768          be recorded internally by the simulator and sim_events_preprocess
769          will handle them.  If the stepping event is inserted before,
770          these pending ticks will raise the event and the simulator will
771          stop without having executed any instruction.  */
772       if (step)
773         engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);
774
775 #ifdef SIM_CPU_EXCEPTION_RESUME
776       {
777         sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
778         SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
779       }
780 #endif
781
782       sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
783     }
784   engine->jmpbuf = NULL;
785
786   sim_module_suspend (sd);
787 }