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