xref: /netbsd-src/external/gpl3/gdb/dist/sim/cr16/interp.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /* Simulation code for the CR16 processor.
2    Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
3    Contributed by M Ranga Swami Reddy <MR.Swami.Reddy@nsc.com>
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, or (at your option)
10    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 <signal.h>
21 #include "sysdep.h"
22 #include "bfd.h"
23 #include "gdb/callback.h"
24 #include "gdb/remote-sim.h"
25 
26 #include "cr16_sim.h"
27 #include "gdb/sim-cr16.h"
28 #include "gdb/signals.h"
29 #include "opcode/cr16.h"
30 
31 static char *myname;
32 static SIM_OPEN_KIND sim_kind;
33 int cr16_debug;
34 
35 /* Set this to true to get the previous segment layout. */
36 
37 int old_segment_mapping;
38 
39 host_callback *cr16_callback;
40 unsigned long ins_type_counters[ (int)INS_MAX ];
41 
42 uint32 OP[4];
43 uint32 sign_flag;
44 
45 static int init_text_p = 0;
46 /* non-zero if we opened prog_bfd */
47 static int prog_bfd_was_opened_p;
48 bfd *prog_bfd;
49 asection *text;
50 bfd_vma text_start;
51 bfd_vma text_end;
52 
53 static struct hash_entry *lookup_hash PARAMS ((uint64 ins, int size));
54 static void get_operands PARAMS ((operand_desc *s, uint64 mcode, int isize, int nops));
55 static int do_run PARAMS ((uint64 mc));
56 static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));
57 extern void sim_set_profile PARAMS ((int n));
58 extern void sim_set_profile_size PARAMS ((int n));
59 static INLINE uint8 *map_memory (unsigned phys_addr);
60 
61 #ifdef NEED_UI_LOOP_HOOK
62 /* How often to run the ui_loop update, when in use */
63 #define UI_LOOP_POLL_INTERVAL 0x14000
64 
65 /* Counter for the ui_loop_hook update */
66 static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
67 
68 /* Actual hook to call to run through gdb's gui event loop */
69 extern int (*deprecated_ui_loop_hook) PARAMS ((int signo));
70 #endif /* NEED_UI_LOOP_HOOK */
71 
72 #ifndef INLINE
73 #if defined(__GNUC__) && defined(__OPTIMIZE__)
74 #define INLINE __inline__
75 #else
76 #define INLINE
77 #endif
78 #endif
79 #define MAX_HASH  16
80 
81 struct hash_entry
82 {
83   struct hash_entry *next;
84   uint32 opcode;
85   uint32 mask;
86   int format;
87   int size;
88   struct simops *ops;
89 };
90 
91 struct hash_entry hash_table[MAX_HASH+1];
92 
93 INLINE static long
94 hash(unsigned long long insn, int format)
95 {
96   unsigned int i = 4, tmp;
97   if (format)
98     {
99       while ((insn >> i) != 0) i +=4;
100 
101       return ((insn >> (i-4)) & 0xf); /* Use last 4 bits as hask key.  */
102     }
103   return ((insn & 0xF)); /* Use last 4 bits as hask key.  */
104 }
105 
106 
107 INLINE static struct hash_entry *
108 lookup_hash (uint64 ins, int size)
109 {
110   uint32 mask;
111   struct hash_entry *h;
112 
113   h = &hash_table[hash(ins,1)];
114 
115 
116   mask = (((1 << (32 - h->mask)) -1) << h->mask);
117 
118  /* Adjuest mask for branch with 2 word instructions.  */
119   if ((h->ops->mnimonic != NULL) &&
120       ((streq(h->ops->mnimonic,"b") && h->size == 2)))
121     mask = 0xff0f0000;
122 
123 
124   while ((ins & mask) != (BIN(h->opcode, h->mask)))
125     {
126       if (h->next == NULL)
127         {
128           State.exception = SIGILL;
129           State.pc_changed = 1; /* Don't increment the PC. */
130           return NULL;
131         }
132       h = h->next;
133 
134       mask = (((1 << (32 - h->mask)) -1) << h->mask);
135      /* Adjuest mask for branch with 2 word instructions.  */
136      if ((streq(h->ops->mnimonic,"b")) && h->size == 2)
137        mask = 0xff0f0000;
138 
139      }
140    return (h);
141 }
142 
143 INLINE static void
144 get_operands (operand_desc *s, uint64 ins, int isize, int nops)
145 {
146   uint32 i, opn = 0, start_bit = 0, op_type = 0;
147   int32 op_size = 0, mask = 0;
148 
149   if (isize == 1) /* Trunkcate the extra 16 bits of INS.  */
150     ins = ins >> 16;
151 
152   for (i=0; i < 4; ++i,++opn)
153     {
154       if (s[opn].op_type == dummy) break;
155 
156       op_type = s[opn].op_type;
157       start_bit = s[opn].shift;
158       op_size = cr16_optab[op_type].bit_size;
159 
160       switch (op_type)
161         {
162           case imm3: case imm4: case imm5: case imm6:
163             {
164              if (isize == 1)
165                OP[i] = ((ins >> 4) & ((1 << op_size) -1));
166              else
167                OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));
168 
169              if (OP[i] & ((long)1 << (op_size -1)))
170                {
171                  sign_flag = 1;
172                  OP[i] = ~(OP[i]) + 1;
173                }
174              OP[i] = (unsigned long int)(OP[i] & (((long)1 << op_size) -1));
175             }
176             break;
177 
178           case uimm3: case uimm3_1: case uimm4_1:
179              switch (isize)
180                {
181               case 1:
182                OP[i] = ((ins >> 4) & ((1 << op_size) -1)); break;
183               case 2:
184                OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));break;
185               default: /* for case 3.  */
186                OP[i] = ((ins >> (16 + start_bit)) & ((1 << op_size) -1)); break;
187                break;
188                }
189             break;
190 
191           case uimm4:
192             switch (isize)
193               {
194               case 1:
195                  if (start_bit == 20)
196                    OP[i] = ((ins >> 4) & ((1 << op_size) -1));
197                  else
198                    OP[i] = (ins & ((1 << op_size) -1));
199                  break;
200               case 2:
201                  OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
202                  break;
203               case 3:
204                  OP[i] = ((ins >> (start_bit + 16)) & ((1 << op_size) -1));
205                  break;
206               default:
207                  OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
208                  break;
209               }
210             break;
211 
212           case imm16: case uimm16:
213             OP[i] = ins & 0xFFFF;
214             break;
215 
216           case uimm20: case imm20:
217             OP[i] = ins & (((long)1 << op_size) - 1);
218             break;
219 
220           case imm32: case uimm32:
221             OP[i] = ins & 0xFFFFFFFF;
222             break;
223 
224           case uimm5: break; /*NOT USED.  */
225             OP[i] = ins & ((1 << op_size) - 1); break;
226 
227           case disps5:
228             OP[i] = (ins >> 4) & ((1 << 4) - 1);
229             OP[i] = (OP[i] * 2) + 2;
230             if (OP[i] & ((long)1 << 5))
231               {
232                 sign_flag = 1;
233                 OP[i] = ~(OP[i]) + 1;
234                 OP[i] = (unsigned long int)(OP[i] & 0x1F);
235               }
236             break;
237 
238           case dispe9:
239             OP[i] = ((((ins >> 8) & 0xf) << 4) | (ins & 0xf));
240             OP[i] <<= 1;
241             if (OP[i] & ((long)1 << 8))
242               {
243                 sign_flag = 1;
244                 OP[i] = ~(OP[i]) + 1;
245                 OP[i] = (unsigned long int)(OP[i] & 0xFF);
246               }
247             break;
248 
249           case disps17:
250             OP[i] = (ins & 0xFFFF);
251             if (OP[i] & 1)
252               {
253                 OP[i] = (OP[i] & 0xFFFE);
254                 sign_flag = 1;
255                 OP[i] = ~(OP[i]) + 1;
256                 OP[i] = (unsigned long int)(OP[i] & 0xFFFF);
257               }
258             break;
259 
260           case disps25:
261             if (isize == 2)
262               OP[i] = (ins & 0xFFFFFF);
263             else
264               OP[i] = (ins & 0xFFFF) | (((ins >> 24) & 0xf) << 16) |
265                       (((ins >> 16) & 0xf) << 20);
266 
267             if (OP[i] & 1)
268               {
269                 OP[i] = (OP[i] & 0xFFFFFE);
270                 sign_flag = 1;
271                 OP[i] = ~(OP[i]) + 1;
272                 OP[i] = (unsigned long int)(OP[i] & 0xFFFFFF);
273               }
274             break;
275 
276           case abs20:
277             if (isize == 3)
278               OP[i] = (ins) & 0xFFFFF;
279             else
280               OP[i] = (ins >> start_bit) & 0xFFFFF;
281             break;
282           case abs24:
283             if (isize == 3)
284               OP[i] = ((ins & 0xFFFF) | (((ins >> 16) & 0xf) << 20)
285                        | (((ins >> 24) & 0xf) << 16));
286             else
287               OP[i] = (ins >> 16) & 0xFFFFFF;
288             break;
289 
290           case rra:
291           case rbase: break; /* NOT USED.  */
292           case rbase_disps20:  case rbase_dispe20:
293           case rpbase_disps20: case rpindex_disps20:
294             OP[i] = ((((ins >> 24)&0xf) << 16)|((ins) & 0xFFFF));
295             OP[++i] = (ins >> 16) & 0xF;     /* get 4 bit for reg.  */
296             break;
297           case rpbase_disps0:
298             OP[i] = 0;                       /* 4 bit disp const.  */
299             OP[++i] = (ins) & 0xF;           /* get 4 bit for reg.  */
300             break;
301           case rpbase_dispe4:
302             OP[i] = ((ins >> 8) & 0xF) * 2;  /* 4 bit disp const.   */
303             OP[++i] = (ins) & 0xF;           /* get 4 bit for reg.  */
304             break;
305           case rpbase_disps4:
306             OP[i] = ((ins >> 8) & 0xF);      /* 4 bit disp const.  */
307             OP[++i] = (ins) & 0xF;           /* get 4 bit for reg.  */
308             break;
309           case rpbase_disps16:
310             OP[i] = (ins) & 0xFFFF;
311             OP[++i] = (ins >> 16) & 0xF;     /* get 4 bit for reg.  */
312             break;
313           case rpindex_disps0:
314             OP[i] = 0;
315             OP[++i] = (ins >> 4) & 0xF;      /* get 4 bit for reg.  */
316             OP[++i] = (ins >> 8) & 0x1;      /* get 1 bit for index-reg.  */
317             break;
318           case rpindex_disps14:
319             OP[i] = (ins) & 0x3FFF;
320             OP[++i] = (ins >> 14) & 0x1;     /* get 1 bit for index-reg.  */
321             OP[++i] = (ins >> 16) & 0xF;     /* get 4 bit for reg.  */
322           case rindex7_abs20:
323           case rindex8_abs20:
324             OP[i] = (ins) & 0xFFFFF;
325             OP[++i] = (ins >> 24) & 0x1;     /* get 1 bit for index-reg.  */
326             OP[++i] = (ins >> 20) & 0xF;     /* get 4 bit for reg.  */
327             break;
328           case regr: case regp: case pregr: case pregrp:
329               switch(isize)
330                 {
331                   case 1:
332                     if (start_bit == 20) OP[i] = (ins >> 4) & 0xF;
333                     else if (start_bit == 16) OP[i] = ins & 0xF;
334                     break;
335                   case 2: OP[i] = (ins >>  start_bit) & 0xF; break;
336                   case 3: OP[i] = (ins >> (start_bit + 16)) & 0xF; break;
337                 }
338                break;
339           case cc:
340             {
341               if (isize == 1) OP[i] = (ins >> 4) & 0xF;
342               else if (isize == 2)  OP[i] = (ins >> start_bit)  & 0xF;
343               else  OP[i] = (ins >> (start_bit + 16)) & 0xF;
344               break;
345             }
346           default: break;
347         }
348 
349       /* For ESC on uimm4_1 operand.  */
350       if (op_type == uimm4_1)
351         if (OP[i] == 9)
352            OP[i] = -1;
353 
354       /* For increment by 1.  */
355       if ((op_type == pregr) || (op_type == pregrp))
356           OP[i] += 1;
357    }
358   /* FIXME: for tracing, update values that need to be updated each
359             instruction decode cycle */
360   State.trace.psw = PSR;
361 }
362 
363 bfd_vma
364 decode_pc ()
365 {
366   asection *s;
367   if (!init_text_p && prog_bfd != NULL)
368     {
369       init_text_p = 1;
370       for (s = prog_bfd->sections; s; s = s->next)
371         if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
372           {
373             text = s;
374             text_start = bfd_get_section_vma (prog_bfd, s);
375             text_end = text_start + bfd_section_size (prog_bfd, s);
376             break;
377            }
378      }
379 
380   return (PC) + text_start;
381 }
382 
383 
384 
385 static int
386 do_run(uint64 mcode)
387 {
388   struct simops *s= Simops;
389   struct hash_entry *h;
390   char func[12]="\0";
391   uint8 *iaddr;
392 #ifdef DEBUG
393   if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
394     (*cr16_callback->printf_filtered) (cr16_callback, "do_long 0x%x\n", mcode);
395 #endif
396 
397    h =  lookup_hash(mcode, 1);
398 
399    if ((h == NULL) || (h->opcode == NULL)) return 0;
400 
401    if (h->size == 3)
402     {
403       iaddr = imem_addr ((uint32)PC + 2);
404        mcode = (mcode << 16) | get_longword( iaddr );
405     }
406 
407   /* Re-set OP list.  */
408   OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0;
409 
410   /* for push/pop/pushrtn with RA instructions. */
411   if ((h->format & REG_LIST) && (mcode & 0x800000))
412     OP[2] = 1; /* Set 1 for RA operand.  */
413 
414   /* numops == 0 means, no operands.  */
415   if (((h->ops) != NULL) && (((h->ops)->numops) != 0))
416     get_operands ((h->ops)->operands, mcode, h->size, (h->ops)->numops);
417 
418   //State.ins_type = h->flags;
419 
420   (h->ops->func)();
421 
422   return h->size;
423 }
424 
425 static char *
426 add_commas(char *buf, int sizeof_buf, unsigned long value)
427 {
428   int comma = 3;
429   char *endbuf = buf + sizeof_buf - 1;
430 
431   *--endbuf = '\0';
432   do {
433     if (comma-- == 0)
434       {
435         *--endbuf = ',';
436         comma = 2;
437       }
438 
439     *--endbuf = (value % 10) + '0';
440   } while ((value /= 10) != 0);
441 
442   return endbuf;
443 }
444 
445 void
446 sim_size (int power)
447 {
448   int i;
449   for (i = 0; i < IMEM_SEGMENTS; i++)
450     {
451       if (State.mem.insn[i])
452         free (State.mem.insn[i]);
453     }
454   for (i = 0; i < DMEM_SEGMENTS; i++)
455     {
456       if (State.mem.data[i])
457         free (State.mem.data[i]);
458     }
459   for (i = 0; i < UMEM_SEGMENTS; i++)
460     {
461       if (State.mem.unif[i])
462         free (State.mem.unif[i]);
463     }
464   /* Always allocate dmem segment 0.  This contains the IMAP and DMAP
465      registers. */
466   State.mem.data[0] = calloc (1, SEGMENT_SIZE);
467 }
468 
469 /* For tracing - leave info on last access around. */
470 static char *last_segname = "invalid";
471 static char *last_from = "invalid";
472 static char *last_to = "invalid";
473 
474 enum
475   {
476     IMAP0_OFFSET = 0xff00,
477     DMAP0_OFFSET = 0xff08,
478     DMAP2_SHADDOW = 0xff04,
479     DMAP2_OFFSET = 0xff0c
480   };
481 
482 static void
483 set_dmap_register (int reg_nr, unsigned long value)
484 {
485   uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
486                            + DMAP0_OFFSET + 2 * reg_nr);
487   WRITE_16 (raw, value);
488 #ifdef DEBUG
489   if ((cr16_debug & DEBUG_MEMORY))
490     {
491       (*cr16_callback->printf_filtered)
492         (cr16_callback, "mem: dmap%d=0x%04lx\n", reg_nr, value);
493     }
494 #endif
495 }
496 
497 static unsigned long
498 dmap_register (void *regcache, int reg_nr)
499 {
500   uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
501                            + DMAP0_OFFSET + 2 * reg_nr);
502   return READ_16 (raw);
503 }
504 
505 static void
506 set_imap_register (int reg_nr, unsigned long value)
507 {
508   uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
509                            + IMAP0_OFFSET + 2 * reg_nr);
510   WRITE_16 (raw, value);
511 #ifdef DEBUG
512   if ((cr16_debug & DEBUG_MEMORY))
513     {
514       (*cr16_callback->printf_filtered)
515         (cr16_callback, "mem: imap%d=0x%04lx\n", reg_nr, value);
516     }
517 #endif
518 }
519 
520 static unsigned long
521 imap_register (void *regcache, int reg_nr)
522 {
523   uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
524                            + IMAP0_OFFSET + 2 * reg_nr);
525   return READ_16 (raw);
526 }
527 
528 enum
529   {
530     HELD_SPI_IDX = 0,
531     HELD_SPU_IDX = 1
532   };
533 
534 static unsigned long
535 spu_register (void)
536 {
537     return GPR (SP_IDX);
538 }
539 
540 static unsigned long
541 spi_register (void)
542 {
543     return GPR (SP_IDX);
544 }
545 
546 static void
547 set_spi_register (unsigned long value)
548 {
549     SET_GPR (SP_IDX, value);
550 }
551 
552 static void
553 set_spu_register  (unsigned long value)
554 {
555     SET_GPR (SP_IDX, value);
556 }
557 
558 /* Given a virtual address in the DMAP address space, translate it
559    into a physical address. */
560 
561 unsigned long
562 sim_cr16_translate_dmap_addr (unsigned long offset,
563                               int nr_bytes,
564                               unsigned long *phys,
565                               void *regcache,
566                               unsigned long (*dmap_register) (void *regcache,
567                                                               int reg_nr))
568 {
569   short map;
570   int regno;
571   last_from = "logical-data";
572   if (offset >= DMAP_BLOCK_SIZE * SIM_CR16_NR_DMAP_REGS)
573     {
574       /* Logical address out side of data segments, not supported */
575       return 0;
576     }
577   regno = (offset / DMAP_BLOCK_SIZE);
578   offset = (offset % DMAP_BLOCK_SIZE);
579 
580 #if 1
581   if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
582     {
583       /* Don't cross a BLOCK boundary */
584       nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
585     }
586   map = dmap_register (regcache, regno);
587   if (regno == 3)
588     {
589       /* Always maps to data memory */
590       int iospi = (offset / 0x1000) % 4;
591       int iosp = (map >> (4 * (3 - iospi))) % 0x10;
592       last_to = "io-space";
593       *phys = (SIM_CR16_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);
594     }
595   else
596     {
597       int sp = ((map & 0x3000) >> 12);
598       int segno = (map & 0x3ff);
599       switch (sp)
600         {
601         case 0: /* 00: Unified memory */
602           *phys = SIM_CR16_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
603           last_to = "unified";
604           break;
605         case 1: /* 01: Instruction Memory */
606           *phys = SIM_CR16_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
607           last_to = "chip-insn";
608           break;
609         case 2: /* 10: Internal data memory */
610           *phys = SIM_CR16_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;
611           last_to = "chip-data";
612           break;
613         case 3: /* 11: Reserved */
614           return 0;
615         }
616     }
617 #endif
618   return nr_bytes;
619 }
620 
621 /* Given a virtual address in the IMAP address space, translate it
622    into a physical address. */
623 
624 unsigned long
625 sim_cr16_translate_imap_addr (unsigned long offset,
626                               int nr_bytes,
627                               unsigned long *phys,
628                               void *regcache,
629                               unsigned long (*imap_register) (void *regcache,
630                                                               int reg_nr))
631 {
632   short map;
633   int regno;
634   int sp;
635   int segno;
636   last_from = "logical-insn";
637   if (offset >= (IMAP_BLOCK_SIZE * SIM_CR16_NR_IMAP_REGS))
638     {
639       /* Logical address outside of IMAP segments, not supported */
640       return 0;
641     }
642   regno = (offset / IMAP_BLOCK_SIZE);
643   offset = (offset % IMAP_BLOCK_SIZE);
644   if (offset + nr_bytes > IMAP_BLOCK_SIZE)
645     {
646       /* Don't cross a BLOCK boundary */
647       nr_bytes = IMAP_BLOCK_SIZE - offset;
648     }
649   map = imap_register (regcache, regno);
650   sp = (map & 0x3000) >> 12;
651   segno = (map & 0x007f);
652   switch (sp)
653     {
654     case 0: /* 00: unified memory */
655       *phys = SIM_CR16_MEMORY_UNIFIED + (segno << 17) + offset;
656       last_to = "unified";
657       break;
658     case 1: /* 01: instruction memory */
659       *phys = SIM_CR16_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
660       last_to = "chip-insn";
661       break;
662     case 2: /*10*/
663       /* Reserved. */
664       return 0;
665     case 3: /* 11: for testing  - instruction memory */
666       offset = (offset % 0x800);
667       *phys = SIM_CR16_MEMORY_INSN + offset;
668       if (offset + nr_bytes > 0x800)
669         /* don't cross VM boundary */
670         nr_bytes = 0x800 - offset;
671       last_to = "test-insn";
672       break;
673     }
674   return nr_bytes;
675 }
676 
677 unsigned long
678 sim_cr16_translate_addr (unsigned long memaddr, int nr_bytes,
679                          unsigned long *targ_addr, void *regcache,
680                          unsigned long (*dmap_register) (void *regcache,
681                                                          int reg_nr),
682                          unsigned long (*imap_register) (void *regcache,
683                                                          int reg_nr))
684 {
685   unsigned long phys;
686   unsigned long seg;
687   unsigned long off;
688 
689   last_from = "unknown";
690   last_to = "unknown";
691 
692   seg = (memaddr >> 24);
693   off = (memaddr & 0xffffffL);
694 
695   /* However, if we've asked to use the previous generation of segment
696      mapping, rearrange the segments as follows. */
697 
698   if (old_segment_mapping)
699     {
700       switch (seg)
701         {
702         case 0x00: /* DMAP translated memory */
703           seg = 0x10;
704           break;
705         case 0x01: /* IMAP translated memory */
706           seg = 0x11;
707           break;
708         case 0x10: /* On-chip data memory */
709           seg = 0x02;
710           break;
711         case 0x11: /* On-chip insn memory */
712           seg = 0x01;
713           break;
714         case 0x12: /* Unified memory */
715           seg = 0x00;
716           break;
717         }
718     }
719 
720   switch (seg)
721     {
722     case 0x00:                        /* Physical unified memory */
723       last_from = "phys-unified";
724       last_to = "unified";
725       phys = SIM_CR16_MEMORY_UNIFIED + off;
726       if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
727         nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
728       break;
729 
730     case 0x01:                        /* Physical instruction memory */
731       last_from = "phys-insn";
732       last_to = "chip-insn";
733       phys = SIM_CR16_MEMORY_INSN + off;
734       if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
735         nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
736       break;
737 
738     case 0x02:                        /* Physical data memory segment */
739       last_from = "phys-data";
740       last_to = "chip-data";
741       phys = SIM_CR16_MEMORY_DATA + off;
742       if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
743         nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
744       break;
745 
746     case 0x10:                        /* in logical data address segment */
747       nr_bytes = sim_cr16_translate_dmap_addr (off, nr_bytes, &phys, regcache,
748                                                dmap_register);
749       break;
750 
751     case 0x11:                        /* in logical instruction address segment */
752       nr_bytes = sim_cr16_translate_imap_addr (off, nr_bytes, &phys, regcache,
753                                                imap_register);
754       break;
755 
756     default:
757       return 0;
758     }
759 
760   *targ_addr = phys;
761   return nr_bytes;
762 }
763 
764 /* Return a pointer into the raw buffer designated by phys_addr.  It
765    is assumed that the client has already ensured that the access
766    isn't going to cross a segment boundary. */
767 
768 uint8 *
769 map_memory (unsigned phys_addr)
770 {
771   uint8 **memory;
772   uint8 *raw;
773   unsigned offset;
774   int segment = ((phys_addr >> 24) & 0xff);
775 
776   switch (segment)
777     {
778 
779     case 0x00: /* Unified memory */
780       {
781         memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
782         last_segname = "umem";
783         break;
784       }
785 
786     case 0x01: /* On-chip insn memory */
787       {
788         memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
789         last_segname = "imem";
790         break;
791       }
792 
793     case 0x02: /* On-chip data memory */
794       {
795         if ((phys_addr & 0xff00) == 0xff00)
796           {
797             phys_addr = (phys_addr & 0xffff);
798             if (phys_addr == DMAP2_SHADDOW)
799               {
800                 phys_addr = DMAP2_OFFSET;
801                 last_segname = "dmap";
802               }
803             else
804               last_segname = "reg";
805           }
806         else
807           last_segname = "dmem";
808         memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
809         break;
810       }
811 
812     default:
813       /* OOPS! */
814       last_segname = "scrap";
815       return State.mem.fault;
816     }
817 
818   if (*memory == NULL)
819     {
820       *memory = calloc (1, SEGMENT_SIZE);
821       if (*memory == NULL)
822         {
823           (*cr16_callback->printf_filtered) (cr16_callback, "Malloc failed.\n");
824           return State.mem.fault;
825         }
826     }
827 
828   offset = (phys_addr % SEGMENT_SIZE);
829   raw = *memory + offset;
830   return raw;
831 }
832 
833 /* Transfer data to/from simulated memory.  Since a bug in either the
834    simulated program or in gdb or the simulator itself may cause a
835    bogus address to be passed in, we need to do some sanity checking
836    on addresses to make sure they are within bounds.  When an address
837    fails the bounds check, treat it as a zero length read/write rather
838    than aborting the entire run. */
839 
840 static int
841 xfer_mem (SIM_ADDR virt,
842           unsigned char *buffer,
843           int size,
844           int write_p)
845 {
846   uint8 *memory;
847   unsigned long phys;
848   int phys_size;
849   phys_size = sim_cr16_translate_addr (virt, size, &phys, NULL,
850                                        dmap_register, imap_register);
851   if (phys_size == 0)
852     return 0;
853 
854   memory = map_memory (phys);
855 
856 #ifdef DEBUG
857   if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
858     {
859       (*cr16_callback->printf_filtered)
860         (cr16_callback,
861          "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
862              (write_p ? "write" : "read"),
863          phys_size, virt, last_from,
864          phys, last_to,
865          (long) memory, last_segname);
866     }
867 #endif
868 
869   if (write_p)
870     {
871       memcpy (memory, buffer, phys_size);
872     }
873   else
874     {
875       memcpy (buffer, memory, phys_size);
876     }
877 
878   return phys_size;
879 }
880 
881 
882 int
883 sim_write (sd, addr, buffer, size)
884      SIM_DESC sd;
885      SIM_ADDR addr;
886      const unsigned char *buffer;
887      int size;
888 {
889   /* FIXME: this should be performing a virtual transfer */
890   return xfer_mem( addr, buffer, size, 1);
891 }
892 
893 int
894 sim_read (sd, addr, buffer, size)
895      SIM_DESC sd;
896      SIM_ADDR addr;
897      unsigned char *buffer;
898      int size;
899 {
900   /* FIXME: this should be performing a virtual transfer */
901   return xfer_mem( addr, buffer, size, 0);
902 }
903 
904 SIM_DESC
905 sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *callback, struct bfd *abfd, char **argv)
906 {
907   struct simops *s;
908   struct hash_entry *h;
909   static int init_p = 0;
910   char **p;
911 
912   sim_kind = kind;
913   cr16_callback = callback;
914   myname = argv[0];
915   old_segment_mapping = 0;
916 
917   /* NOTE: This argument parsing is only effective when this function
918      is called by GDB. Standalone argument parsing is handled by
919      sim/common/run.c. */
920 #if 0
921   for (p = argv + 1; *p; ++p)
922     {
923       if (strcmp (*p, "-oldseg") == 0)
924         old_segment_mapping = 1;
925 #ifdef DEBUG
926       else if (strcmp (*p, "-t") == 0)
927         cr16_debug = DEBUG;
928       else if (strncmp (*p, "-t", 2) == 0)
929         cr16_debug = atoi (*p + 2);
930 #endif
931       else
932         (*cr16_callback->printf_filtered) (cr16_callback, "ERROR: unsupported option(s): %s\n",*p);
933     }
934 #endif
935 
936   /* put all the opcodes in the hash table.  */
937   if (!init_p++)
938     {
939       for (s = Simops; s->func; s++)
940         {
941           switch(32 - s->mask)
942             {
943             case 0x4:
944                h = &hash_table[hash(s->opcode, 0)];
945                break;
946 
947             case 0x7:
948                if (((s->opcode << 1) >> 4) != 0)
949                   h = &hash_table[hash((s->opcode << 1) >> 4, 0)];
950                else
951                   h = &hash_table[hash((s->opcode << 1), 0)];
952                break;
953 
954             case 0x8:
955                if ((s->opcode >> 4) != 0)
956                   h = &hash_table[hash(s->opcode >> 4, 0)];
957                else
958                   h = &hash_table[hash(s->opcode, 0)];
959                break;
960 
961             case 0x9:
962                if (((s->opcode  >> 1) >> 4) != 0)
963                  h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
964                else
965                  h = &hash_table[hash((s->opcode >> 1), 0)];
966                break;
967 
968             case 0xa:
969                if ((s->opcode >> 8) != 0)
970                  h = &hash_table[hash(s->opcode >> 8, 0)];
971                else if ((s->opcode >> 4) != 0)
972                  h = &hash_table[hash(s->opcode >> 4, 0)];
973                else
974                  h = &hash_table[hash(s->opcode, 0)];
975                break;
976 
977             case 0xc:
978                if ((s->opcode >> 8) != 0)
979                  h = &hash_table[hash(s->opcode >> 8, 0)];
980                else if ((s->opcode >> 4) != 0)
981                  h = &hash_table[hash(s->opcode >> 4, 0)];
982                else
983                  h = &hash_table[hash(s->opcode, 0)];
984                break;
985 
986             case 0xd:
987                if (((s->opcode >> 1) >> 8) != 0)
988                  h = &hash_table[hash((s->opcode >>1) >> 8, 0)];
989                else if (((s->opcode >> 1) >> 4) != 0)
990                  h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
991                else
992                  h = &hash_table[hash((s->opcode >>1), 0)];
993                break;
994 
995             case 0x10:
996                if ((s->opcode >> 0xc) != 0)
997                  h = &hash_table[hash(s->opcode >> 12, 0)];
998                else if ((s->opcode >> 8) != 0)
999                  h = &hash_table[hash(s->opcode >> 8, 0)];
1000                else if ((s->opcode >> 4) != 0)
1001                  h = &hash_table[hash(s->opcode >> 4, 0)];
1002                else
1003                  h = &hash_table[hash(s->opcode, 0)];
1004                break;
1005 
1006             case 0x14:
1007                if ((s->opcode >> 16) != 0)
1008                  h = &hash_table[hash(s->opcode >> 16, 0)];
1009                else if ((s->opcode >> 12) != 0)
1010                  h = &hash_table[hash(s->opcode >> 12, 0)];
1011                else if ((s->opcode >> 8) != 0)
1012                  h = &hash_table[hash(s->opcode >> 8, 0)];
1013                else if ((s->opcode >> 4) != 0)
1014                  h = &hash_table[hash(s->opcode >> 4, 0)];
1015                else
1016                  h = &hash_table[hash(s->opcode, 0)];
1017                break;
1018             default:
1019               break;
1020             }
1021 
1022           /* go to the last entry in the chain.  */
1023           while (h->next)
1024             h = h->next;
1025 
1026           if (h->ops)
1027             {
1028               h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
1029               if (!h->next)
1030                 perror ("malloc failure");
1031 
1032               h = h->next;
1033             }
1034           h->ops = s;
1035           h->mask = s->mask;
1036           h->opcode = s->opcode;
1037           h->format = s->format;
1038           h->size = s->size;
1039         }
1040     }
1041 
1042   /* reset the processor state */
1043   if (!State.mem.data[0])
1044     sim_size (1);
1045   sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL);
1046 
1047   /* Fudge our descriptor.  */
1048   return (SIM_DESC) 1;
1049 }
1050 
1051 
1052 void
1053 sim_close (sd, quitting)
1054      SIM_DESC sd;
1055      int quitting;
1056 {
1057   if (prog_bfd != NULL && prog_bfd_was_opened_p)
1058     {
1059       bfd_close (prog_bfd);
1060       prog_bfd = NULL;
1061       prog_bfd_was_opened_p = 0;
1062     }
1063 }
1064 
1065 void
1066 sim_set_profile (int n)
1067 {
1068   (*cr16_callback->printf_filtered) (cr16_callback, "sim_set_profile %d\n",n);
1069 }
1070 
1071 void
1072 sim_set_profile_size (int n)
1073 {
1074   (*cr16_callback->printf_filtered) (cr16_callback, "sim_set_profile_size %d\n",n);
1075 }
1076 
1077 uint8 *
1078 dmem_addr (uint32 offset)
1079 {
1080   unsigned long phys;
1081   uint8 *mem;
1082   int phys_size;
1083 
1084   /* Note: DMEM address range is 0..0x10000. Calling code can compute
1085      things like ``0xfffe + 0x0e60 == 0x10e5d''.  Since offset's type
1086      is uint16 this is modulo'ed onto 0x0e5d. */
1087 
1088   phys_size = sim_cr16_translate_dmap_addr (offset, 1, &phys, NULL,
1089                                             dmap_register);
1090   if (phys_size == 0)
1091     {
1092       mem = State.mem.fault;
1093     }
1094   else
1095     mem = map_memory (phys);
1096 #ifdef DEBUG
1097   if ((cr16_debug & DEBUG_MEMORY))
1098     {
1099       (*cr16_callback->printf_filtered)
1100         (cr16_callback,
1101          "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1102          offset, last_from,
1103          phys, phys_size, last_to,
1104          (long) mem, last_segname);
1105     }
1106 #endif
1107   return mem;
1108 }
1109 
1110 uint8 *
1111 imem_addr (uint32 offset)
1112 {
1113   unsigned long phys;
1114   uint8 *mem;
1115   int phys_size = sim_cr16_translate_imap_addr (offset, 1, &phys, NULL,
1116                                                 imap_register);
1117   if (phys_size == 0)
1118     {
1119       return State.mem.fault;
1120     }
1121   mem = map_memory (phys);
1122 #ifdef DEBUG
1123   if ((cr16_debug & DEBUG_MEMORY))
1124     {
1125       (*cr16_callback->printf_filtered)
1126         (cr16_callback,
1127          "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1128          offset, last_from,
1129          phys, phys_size, last_to,
1130          (long) mem, last_segname);
1131     }
1132 #endif
1133   return mem;
1134 }
1135 
1136 static int stop_simulator = 0;
1137 
1138 int
1139 sim_stop (sd)
1140      SIM_DESC sd;
1141 {
1142   stop_simulator = 1;
1143   return 1;
1144 }
1145 
1146 
1147 /* Run (or resume) the program.  */
1148 void
1149 sim_resume (SIM_DESC sd, int step, int siggnal)
1150 {
1151   uint32 curr_ins_size = 0;
1152   uint64 mcode = 0;
1153   uint8 *iaddr;
1154 
1155 #ifdef DEBUG
1156 //  (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d)  PC=0x%x\n",step,siggnal,PC);
1157 #endif
1158 
1159   State.exception = 0;
1160   if (step)
1161     sim_stop (sd);
1162 
1163   switch (siggnal)
1164     {
1165     case 0:
1166       break;
1167 #ifdef SIGBUS
1168     case SIGBUS:
1169 #endif
1170     case SIGSEGV:
1171       SET_PC (PC);
1172       SET_PSR (PSR);
1173       JMP (AE_VECTOR_START);
1174       SLOT_FLUSH ();
1175       break;
1176     case SIGILL:
1177       SET_PC (PC);
1178       SET_PSR (PSR);
1179       SET_HW_PSR ((PSR & (PSR_C_BIT)));
1180       JMP (RIE_VECTOR_START);
1181       SLOT_FLUSH ();
1182       break;
1183     default:
1184       /* just ignore it */
1185       break;
1186     }
1187 
1188   do
1189     {
1190       iaddr = imem_addr ((uint32)PC);
1191       if (iaddr == State.mem.fault)
1192         {
1193           State.exception = SIGBUS;
1194           break;
1195         }
1196 
1197       mcode = get_longword( iaddr );
1198 
1199       State.pc_changed = 0;
1200 
1201       curr_ins_size = do_run(mcode);
1202 
1203 #if CR16_DEBUG
1204  (*cr16_callback->printf_filtered) (cr16_callback, "INS: PC=0x%X, mcode=0x%X\n",PC,mcode);
1205 #endif
1206 
1207       if (!State.pc_changed)
1208         {
1209           if (curr_ins_size == 0)
1210            {
1211              State.exception = SIG_CR16_EXIT; /* exit trap */
1212              break;
1213            }
1214           else
1215            SET_PC (PC + (curr_ins_size * 2)); /* For word instructions.  */
1216         }
1217 
1218 #if 0
1219       /* Check for a breakpoint trap on this instruction.  This
1220          overrides any pending branches or loops */
1221       if (PSR_DB && PC == DBS)
1222         {
1223           SET_BPC (PC);
1224           SET_BPSR (PSR);
1225           SET_PC (SDBT_VECTOR_START);
1226         }
1227 #endif
1228 
1229       /* Writeback all the DATA / PC changes */
1230       SLOT_FLUSH ();
1231 
1232 #ifdef NEED_UI_LOOP_HOOK
1233       if (deprecated_ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
1234         {
1235           ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
1236           deprecated_ui_loop_hook (0);
1237         }
1238 #endif /* NEED_UI_LOOP_HOOK */
1239     }
1240   while ( !State.exception && !stop_simulator);
1241 
1242   if (step && !State.exception)
1243     State.exception = SIGTRAP;
1244 }
1245 
1246 void
1247 sim_set_trace (void)
1248 {
1249 #ifdef DEBUG
1250   cr16_debug = DEBUG;
1251 #endif
1252 }
1253 
1254 void
1255 sim_info (SIM_DESC sd, int verbose)
1256 {
1257   char buf1[40];
1258   char buf2[40];
1259   char buf3[40];
1260   char buf4[40];
1261   char buf5[40];
1262 #if 0
1263   unsigned long left                = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1264   unsigned long left_nops        = ins_type_counters[ (int)INS_LEFT_NOPS ];
1265   unsigned long left_parallel        = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1266   unsigned long left_cond        = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1267   unsigned long left_total        = left + left_parallel + left_cond + left_nops;
1268 
1269   unsigned long right                = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1270   unsigned long right_nops        = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1271   unsigned long right_parallel        = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1272   unsigned long right_cond        = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1273   unsigned long right_total        = right + right_parallel + right_cond + right_nops;
1274 
1275   unsigned long unknown                = ins_type_counters[ (int)INS_UNKNOWN ];
1276   unsigned long ins_long        = ins_type_counters[ (int)INS_LONG ];
1277   unsigned long parallel        = ins_type_counters[ (int)INS_PARALLEL ];
1278   unsigned long leftright        = ins_type_counters[ (int)INS_LEFTRIGHT ];
1279   unsigned long rightleft        = ins_type_counters[ (int)INS_RIGHTLEFT ];
1280   unsigned long cond_true        = ins_type_counters[ (int)INS_COND_TRUE ];
1281   unsigned long cond_false        = ins_type_counters[ (int)INS_COND_FALSE ];
1282   unsigned long cond_jump        = ins_type_counters[ (int)INS_COND_JUMP ];
1283   unsigned long cycles                = ins_type_counters[ (int)INS_CYCLES ];
1284   unsigned long total                = (unknown + left_total + right_total + ins_long);
1285 
1286   int size                        = strlen (add_commas (buf1, sizeof (buf1), total));
1287   int parallel_size                = strlen (add_commas (buf1, sizeof (buf1),
1288                                                       (left_parallel > right_parallel) ? left_parallel : right_parallel));
1289   int cond_size                        = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1290   int nop_size                        = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1291   int normal_size                = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
1292 
1293   (*cr16_callback->printf_filtered) (cr16_callback,
1294                                      "executed %*s left  instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1295                                      size, add_commas (buf1, sizeof (buf1), left_total),
1296                                      normal_size, add_commas (buf2, sizeof (buf2), left),
1297                                      parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1298                                      cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1299                                      nop_size, add_commas (buf5, sizeof (buf5), left_nops));
1300 
1301   (*cr16_callback->printf_filtered) (cr16_callback,
1302                                      "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1303                                      size, add_commas (buf1, sizeof (buf1), right_total),
1304                                      normal_size, add_commas (buf2, sizeof (buf2), right),
1305                                      parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1306                                      cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1307                                      nop_size, add_commas (buf5, sizeof (buf5), right_nops));
1308 
1309   if (ins_long)
1310     (*cr16_callback->printf_filtered) (cr16_callback,
1311                                        "executed %*s long instruction(s)\n",
1312                                        size, add_commas (buf1, sizeof (buf1), ins_long));
1313 
1314   if (parallel)
1315     (*cr16_callback->printf_filtered) (cr16_callback,
1316                                        "executed %*s parallel instruction(s)\n",
1317                                        size, add_commas (buf1, sizeof (buf1), parallel));
1318 
1319   if (leftright)
1320     (*cr16_callback->printf_filtered) (cr16_callback,
1321                                        "executed %*s instruction(s) encoded L->R\n",
1322                                        size, add_commas (buf1, sizeof (buf1), leftright));
1323 
1324   if (rightleft)
1325     (*cr16_callback->printf_filtered) (cr16_callback,
1326                                        "executed %*s instruction(s) encoded R->L\n",
1327                                        size, add_commas (buf1, sizeof (buf1), rightleft));
1328 
1329   if (unknown)
1330     (*cr16_callback->printf_filtered) (cr16_callback,
1331                                        "executed %*s unknown instruction(s)\n",
1332                                        size, add_commas (buf1, sizeof (buf1), unknown));
1333 
1334   if (cond_true)
1335     (*cr16_callback->printf_filtered) (cr16_callback,
1336                                        "executed %*s instruction(s) due to EXExxx condition being true\n",
1337                                        size, add_commas (buf1, sizeof (buf1), cond_true));
1338 
1339   if (cond_false)
1340     (*cr16_callback->printf_filtered) (cr16_callback,
1341                                        "skipped  %*s instruction(s) due to EXExxx condition being false\n",
1342                                        size, add_commas (buf1, sizeof (buf1), cond_false));
1343 
1344   if (cond_jump)
1345     (*cr16_callback->printf_filtered) (cr16_callback,
1346                                        "skipped  %*s instruction(s) due to conditional branch succeeding\n",
1347                                        size, add_commas (buf1, sizeof (buf1), cond_jump));
1348 
1349   (*cr16_callback->printf_filtered) (cr16_callback,
1350                                      "executed %*s cycle(s)\n",
1351                                      size, add_commas (buf1, sizeof (buf1), cycles));
1352 
1353   (*cr16_callback->printf_filtered) (cr16_callback,
1354                                      "executed %*s total instructions\n",
1355                                      size, add_commas (buf1, sizeof (buf1), total));
1356 #endif
1357 }
1358 
1359 SIM_RC
1360 sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
1361 {
1362   bfd_vma start_address;
1363 
1364   /* reset all state information */
1365   memset (&State.regs, 0, (int)&State.mem - (int)&State.regs);
1366 
1367   /* There was a hack here to copy the values of argc and argv into r0
1368      and r1.  The values were also saved into some high memory that
1369      won't be overwritten by the stack (0x7C00).  The reason for doing
1370      this was to allow the 'run' program to accept arguments.  Without
1371      the hack, this is not possible anymore.  If the simulator is run
1372      from the debugger, arguments cannot be passed in, so this makes
1373      no difference.  */
1374 
1375   /* set PC */
1376   if (abfd != NULL)
1377     start_address = bfd_get_start_address (abfd);
1378   else
1379     start_address = 0x0;
1380 #ifdef DEBUG
1381   if (cr16_debug)
1382     (*cr16_callback->printf_filtered) (cr16_callback, "sim_create_inferior:  PC=0x%lx\n", (long) start_address);
1383 #endif
1384   SET_CREG (PC_CR, start_address);
1385 
1386   SLOT_FLUSH ();
1387   return SIM_RC_OK;
1388 }
1389 
1390 
1391 void
1392 sim_set_callbacks (p)
1393      host_callback *p;
1394 {
1395   cr16_callback = p;
1396 }
1397 
1398 void
1399 sim_stop_reason (sd, reason, sigrc)
1400      SIM_DESC sd;
1401      enum sim_stop *reason;
1402      int *sigrc;
1403 {
1404 /*   (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason:  PC=0x%x\n",PC<<2); */
1405 
1406   switch (State.exception)
1407     {
1408     case SIG_CR16_STOP:                        /* stop instruction */
1409       *reason = sim_stopped;
1410       *sigrc = 0;
1411       break;
1412 
1413     case SIG_CR16_EXIT:                        /* exit trap */
1414       *reason = sim_exited;
1415       *sigrc = GPR (2);
1416       break;
1417 
1418     case SIG_CR16_BUS:
1419       *reason = sim_stopped;
1420       *sigrc = TARGET_SIGNAL_BUS;
1421       break;
1422 //
1423 //    case SIG_CR16_IAD:
1424 //      *reason = sim_stopped;
1425 //      *sigrc = TARGET_SIGNAL_IAD;
1426 //      break;
1427 
1428     default:                                /* some signal */
1429       *reason = sim_stopped;
1430       if (stop_simulator && !State.exception)
1431         *sigrc = TARGET_SIGNAL_INT;
1432       else
1433         *sigrc = State.exception;
1434       break;
1435     }
1436 
1437   stop_simulator = 0;
1438 }
1439 
1440 int
1441 sim_fetch_register (sd, rn, memory, length)
1442      SIM_DESC sd;
1443      int rn;
1444      unsigned char *memory;
1445      int length;
1446 {
1447   int size;
1448   switch ((enum sim_cr16_regs) rn)
1449     {
1450     case SIM_CR16_R0_REGNUM:
1451     case SIM_CR16_R1_REGNUM:
1452     case SIM_CR16_R2_REGNUM:
1453     case SIM_CR16_R3_REGNUM:
1454     case SIM_CR16_R4_REGNUM:
1455     case SIM_CR16_R5_REGNUM:
1456     case SIM_CR16_R6_REGNUM:
1457     case SIM_CR16_R7_REGNUM:
1458     case SIM_CR16_R8_REGNUM:
1459     case SIM_CR16_R9_REGNUM:
1460     case SIM_CR16_R10_REGNUM:
1461     case SIM_CR16_R11_REGNUM:
1462       WRITE_16 (memory, GPR (rn - SIM_CR16_R0_REGNUM));
1463       size = 2;
1464       break;
1465     case SIM_CR16_R12_REGNUM:
1466     case SIM_CR16_R13_REGNUM:
1467     case SIM_CR16_R14_REGNUM:
1468     case SIM_CR16_R15_REGNUM:
1469       //WRITE_32 (memory, GPR (rn - SIM_CR16_R0_REGNUM));
1470       write_longword (memory, GPR (rn - SIM_CR16_R0_REGNUM));
1471       size = 4;
1472       break;
1473     case SIM_CR16_PC_REGNUM:
1474     case SIM_CR16_ISP_REGNUM:
1475     case SIM_CR16_USP_REGNUM:
1476     case SIM_CR16_INTBASE_REGNUM:
1477     case SIM_CR16_PSR_REGNUM:
1478     case SIM_CR16_CFG_REGNUM:
1479     case SIM_CR16_DBS_REGNUM:
1480     case SIM_CR16_DCR_REGNUM:
1481     case SIM_CR16_DSR_REGNUM:
1482     case SIM_CR16_CAR0_REGNUM:
1483     case SIM_CR16_CAR1_REGNUM:
1484       //WRITE_32 (memory, CREG (rn - SIM_CR16_PC_REGNUM));
1485       write_longword (memory, CREG (rn - SIM_CR16_PC_REGNUM));
1486       size = 4;
1487       break;
1488     default:
1489       size = 0;
1490       break;
1491     }
1492   return size;
1493 }
1494 
1495 int
1496 sim_store_register (sd, rn, memory, length)
1497      SIM_DESC sd;
1498      int rn;
1499      unsigned char *memory;
1500      int length;
1501 {
1502   int size;
1503   switch ((enum sim_cr16_regs) rn)
1504     {
1505     case SIM_CR16_R0_REGNUM:
1506     case SIM_CR16_R1_REGNUM:
1507     case SIM_CR16_R2_REGNUM:
1508     case SIM_CR16_R3_REGNUM:
1509     case SIM_CR16_R4_REGNUM:
1510     case SIM_CR16_R5_REGNUM:
1511     case SIM_CR16_R6_REGNUM:
1512     case SIM_CR16_R7_REGNUM:
1513     case SIM_CR16_R8_REGNUM:
1514     case SIM_CR16_R9_REGNUM:
1515     case SIM_CR16_R10_REGNUM:
1516     case SIM_CR16_R11_REGNUM:
1517       SET_GPR (rn - SIM_CR16_R0_REGNUM, READ_16 (memory));
1518       size = 2;
1519       break;
1520     case SIM_CR16_R12_REGNUM:
1521     case SIM_CR16_R13_REGNUM:
1522     case SIM_CR16_R14_REGNUM:
1523     case SIM_CR16_R15_REGNUM:
1524       SET_GPR32 (rn - SIM_CR16_R0_REGNUM, get_longword (memory));
1525       size = 4;
1526       break;
1527     case SIM_CR16_PC_REGNUM:
1528     case SIM_CR16_ISP_REGNUM:
1529     case SIM_CR16_USP_REGNUM:
1530     case SIM_CR16_INTBASE_REGNUM:
1531     case SIM_CR16_PSR_REGNUM:
1532     case SIM_CR16_CFG_REGNUM:
1533     case SIM_CR16_DBS_REGNUM:
1534     case SIM_CR16_DCR_REGNUM:
1535     case SIM_CR16_DSR_REGNUM:
1536     case SIM_CR16_CAR0_REGNUM:
1537     case SIM_CR16_CAR1_REGNUM:
1538       SET_CREG (rn - SIM_CR16_PC_REGNUM, get_longword (memory));
1539       size = 4;
1540       break;
1541     default:
1542       size = 0;
1543       break;
1544     }
1545   SLOT_FLUSH ();
1546   return size;
1547 }
1548 
1549 
1550 void
1551 sim_do_command (sd, cmd)
1552      SIM_DESC sd;
1553      char *cmd;
1554 {
1555   (*cr16_callback->printf_filtered) (cr16_callback, "sim_do_command: %s\n",cmd);
1556 }
1557 
1558 SIM_RC
1559 sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
1560 {
1561   extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
1562 
1563   if (prog_bfd != NULL && prog_bfd_was_opened_p)
1564     {
1565       bfd_close (prog_bfd);
1566       prog_bfd_was_opened_p = 0;
1567     }
1568   prog_bfd = sim_load_file (sd, myname, cr16_callback, prog, abfd,
1569                             sim_kind == SIM_OPEN_DEBUG,
1570                             1/*LMA*/, sim_write);
1571   if (prog_bfd == NULL)
1572     return SIM_RC_FAIL;
1573   prog_bfd_was_opened_p = abfd == NULL;
1574   return SIM_RC_OK;
1575 }
1576