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