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