Update the machine code decode algorithm using hash table.
[deliverable/binutils-gdb.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 }
This page took 0.073534 seconds and 5 git commands to generate.