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>
5 This file is part of GDB, the GNU debugger.
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)
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.
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/>. */
23 #include "gdb/callback.h"
24 #include "gdb/remote-sim.h"
27 #include "gdb/sim-cr16.h"
28 #include "gdb/signals.h"
29 #include "opcode/cr16.h"
32 static SIM_OPEN_KIND sim_kind;
35 /* Set this to true to get the previous segment layout. */
37 int old_segment_mapping;
39 host_callback *cr16_callback;
40 unsigned long ins_type_counters[ (int)INS_MAX ];
45 static int init_text_p = 0;
46 /* non-zero if we opened prog_bfd */
47 static int prog_bfd_was_opened_p;
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);
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
66 /* Counter for the ui_loop_hook update */
67 static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
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 */
74 #if defined(__GNUC__) && defined(__OPTIMIZE__)
75 #define INLINE __inline__
84 struct hash_entry *next;
92 struct hash_entry hash_table[MAX_HASH+1];
95 hash(unsigned long long insn, int format)
97 unsigned int i = 4, tmp;
100 while ((insn >> i) != 0) i +=4;
102 return ((insn >> (i-4)) & 0xf); /* Use last 4 bits as hask key. */
104 return ((insn & 0xF)); /* Use last 4 bits as hask key. */
108 INLINE static struct hash_entry *
109 lookup_hash (uint64 ins, int size)
112 struct hash_entry *h;
114 h = &hash_table[hash(ins,1)];
117 mask = (((1 << (32 - h->mask)) -1) << h->mask);
119 /* Adjuest mask for branch with 2 word instructions. */
120 if ((h->ops->mnimonic != NULL) &&
121 ((streq(h->ops->mnimonic,"b") && h->size == 2)))
125 while ((ins & mask) != (BIN(h->opcode, h->mask)))
129 State.exception = SIGILL;
130 State.pc_changed = 1; /* Don't increment the PC. */
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)
145 get_operands (operand_desc *s, uint64 ins, int isize, int nops)
147 uint32 i, opn = 0, start_bit = 0, op_type = 0;
148 int32 op_size = 0, mask = 0;
150 if (isize == 1) /* Trunkcate the extra 16 bits of INS. */
153 for (i=0; i < 4; ++i,++opn)
155 if (s[opn].op_type == dummy) break;
157 op_type = s[opn].op_type;
158 start_bit = s[opn].shift;
159 op_size = cr16_optab[op_type].bit_size;
163 case imm3: case imm4: case imm5: case imm6:
166 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
168 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));
170 if (OP[i] & ((long)1 << (op_size -1)))
173 OP[i] = ~(OP[i]) + 1;
175 OP[i] = (unsigned long int)(OP[i] & (((long)1 << op_size) -1));
179 case uimm3: case uimm3_1: case uimm4_1:
183 OP[i] = ((ins >> 4) & ((1 << op_size) -1)); break;
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;
197 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
199 OP[i] = (ins & ((1 << op_size) -1));
202 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
205 OP[i] = ((ins >> (start_bit + 16)) & ((1 << op_size) -1));
208 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
213 case imm16: case uimm16:
214 OP[i] = ins & 0xFFFF;
217 case uimm20: case imm20:
218 OP[i] = ins & (((long)1 << op_size) - 1);
221 case imm32: case uimm32:
222 OP[i] = ins & 0xFFFFFFFF;
225 case uimm5: break; /*NOT USED. */
226 OP[i] = ins & ((1 << op_size) - 1); break;
229 OP[i] = (ins >> 4) & ((1 << 4) - 1);
230 OP[i] = (OP[i] * 2) + 2;
231 if (OP[i] & ((long)1 << 5))
234 OP[i] = ~(OP[i]) + 1;
235 OP[i] = (unsigned long int)(OP[i] & 0x1F);
240 OP[i] = ((((ins >> 8) & 0xf) << 4) | (ins & 0xf));
242 if (OP[i] & ((long)1 << 8))
245 OP[i] = ~(OP[i]) + 1;
246 OP[i] = (unsigned long int)(OP[i] & 0xFF);
251 OP[i] = (ins & 0xFFFF);
254 OP[i] = (OP[i] & 0xFFFE);
256 OP[i] = ~(OP[i]) + 1;
257 OP[i] = (unsigned long int)(OP[i] & 0xFFFF);
263 OP[i] = (ins & 0xFFFFFF);
265 OP[i] = (ins & 0xFFFF) | (((ins >> 24) & 0xf) << 16) |
266 (((ins >> 16) & 0xf) << 20);
270 OP[i] = (OP[i] & 0xFFFFFE);
272 OP[i] = ~(OP[i]) + 1;
273 OP[i] = (unsigned long int)(OP[i] & 0xFFFFFF);
279 OP[i] = (ins) & 0xFFFFF;
281 OP[i] = (ins >> start_bit) & 0xFFFFF;
285 OP[i] = ((ins & 0xFFFF) | (((ins >> 16) & 0xf) << 20)
286 | (((ins >> 24) & 0xf) << 16));
288 OP[i] = (ins >> 16) & 0xFFFFFF;
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. */
299 OP[i] = 0; /* 4 bit disp const. */
300 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
303 OP[i] = ((ins >> 8) & 0xF) * 2; /* 4 bit disp const. */
304 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
307 OP[i] = ((ins >> 8) & 0xF); /* 4 bit disp const. */
308 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
311 OP[i] = (ins) & 0xFFFF;
312 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
316 OP[++i] = (ins >> 4) & 0xF; /* get 4 bit for reg. */
317 OP[++i] = (ins >> 8) & 0x1; /* get 1 bit for index-reg. */
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. */
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. */
329 case regr: case regp: case pregr: case pregrp:
333 if (start_bit == 20) OP[i] = (ins >> 4) & 0xF;
334 else if (start_bit == 16) OP[i] = ins & 0xF;
336 case 2: OP[i] = (ins >> start_bit) & 0xF; break;
337 case 3: OP[i] = (ins >> (start_bit + 16)) & 0xF; break;
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;
350 /* For ESC on uimm4_1 operand. */
351 if (op_type == uimm4_1)
355 /* For increment by 1. */
356 if ((op_type == pregr) || (op_type == pregrp))
359 /* FIXME: for tracing, update values that need to be updated each
360 instruction decode cycle */
361 State.trace.psw = PSR;
368 if (!init_text_p && prog_bfd != NULL)
371 for (s = prog_bfd->sections; s; s = s->next)
372 if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
375 text_start = bfd_get_section_vma (prog_bfd, s);
376 text_end = text_start + bfd_section_size (prog_bfd, s);
381 return (PC) + text_start;
389 struct simops *s= Simops;
390 struct hash_entry *h;
394 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
395 (*cr16_callback->printf_filtered) (cr16_callback, "do_long 0x%x\n", mcode);
398 h = lookup_hash(mcode, 1);
400 if ((h == NULL) || (h->opcode == NULL)) return 0;
404 iaddr = imem_addr ((uint32)PC + 2);
405 mcode = (mcode << 16) | get_longword( iaddr );
408 /* Re-set OP list. */
409 OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0;
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. */
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);
419 //State.ins_type = h->flags;
427 add_commas(char *buf, int sizeof_buf, unsigned long value)
430 char *endbuf = buf + sizeof_buf - 1;
440 *--endbuf = (value % 10) + '0';
441 } while ((value /= 10) != 0);
450 for (i = 0; i < IMEM_SEGMENTS; i++)
452 if (State.mem.insn[i])
453 free (State.mem.insn[i]);
455 for (i = 0; i < DMEM_SEGMENTS; i++)
457 if (State.mem.data[i])
458 free (State.mem.data[i]);
460 for (i = 0; i < UMEM_SEGMENTS; i++)
462 if (State.mem.unif[i])
463 free (State.mem.unif[i]);
465 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
467 State.mem.data[0] = calloc (1, SEGMENT_SIZE);
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";
477 IMAP0_OFFSET = 0xff00,
478 DMAP0_OFFSET = 0xff08,
479 DMAP2_SHADDOW = 0xff04,
480 DMAP2_OFFSET = 0xff0c
484 set_dmap_register (int reg_nr, unsigned long value)
486 uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
487 + DMAP0_OFFSET + 2 * reg_nr);
488 WRITE_16 (raw, value);
490 if ((cr16_debug & DEBUG_MEMORY))
492 (*cr16_callback->printf_filtered)
493 (cr16_callback, "mem: dmap%d=0x%04lx\n", reg_nr, value);
499 dmap_register (void *regcache, int reg_nr)
501 uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
502 + DMAP0_OFFSET + 2 * reg_nr);
503 return READ_16 (raw);
507 set_imap_register (int reg_nr, unsigned long value)
509 uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
510 + IMAP0_OFFSET + 2 * reg_nr);
511 WRITE_16 (raw, value);
513 if ((cr16_debug & DEBUG_MEMORY))
515 (*cr16_callback->printf_filtered)
516 (cr16_callback, "mem: imap%d=0x%04lx\n", reg_nr, value);
522 imap_register (void *regcache, int reg_nr)
524 uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
525 + IMAP0_OFFSET + 2 * reg_nr);
526 return READ_16 (raw);
548 set_spi_register (unsigned long value)
550 SET_GPR (SP_IDX, value);
554 set_spu_register (unsigned long value)
556 SET_GPR (SP_IDX, value);
559 /* Given a virtual address in the DMAP address space, translate it
560 into a physical address. */
563 sim_cr16_translate_dmap_addr (unsigned long offset,
567 unsigned long (*dmap_register) (void *regcache,
572 last_from = "logical-data";
573 if (offset >= DMAP_BLOCK_SIZE * SIM_CR16_NR_DMAP_REGS)
575 /* Logical address out side of data segments, not supported */
578 regno = (offset / DMAP_BLOCK_SIZE);
579 offset = (offset % DMAP_BLOCK_SIZE);
582 if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
584 /* Don't cross a BLOCK boundary */
585 nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
587 map = dmap_register (regcache, regno);
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);
598 int sp = ((map & 0x3000) >> 12);
599 int segno = (map & 0x3ff);
602 case 0: /* 00: Unified memory */
603 *phys = SIM_CR16_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
606 case 1: /* 01: Instruction Memory */
607 *phys = SIM_CR16_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
608 last_to = "chip-insn";
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";
614 case 3: /* 11: Reserved */
622 /* Given a virtual address in the IMAP address space, translate it
623 into a physical address. */
626 sim_cr16_translate_imap_addr (unsigned long offset,
630 unsigned long (*imap_register) (void *regcache,
637 last_from = "logical-insn";
638 if (offset >= (IMAP_BLOCK_SIZE * SIM_CR16_NR_IMAP_REGS))
640 /* Logical address outside of IMAP segments, not supported */
643 regno = (offset / IMAP_BLOCK_SIZE);
644 offset = (offset % IMAP_BLOCK_SIZE);
645 if (offset + nr_bytes > IMAP_BLOCK_SIZE)
647 /* Don't cross a BLOCK boundary */
648 nr_bytes = IMAP_BLOCK_SIZE - offset;
650 map = imap_register (regcache, regno);
651 sp = (map & 0x3000) >> 12;
652 segno = (map & 0x007f);
655 case 0: /* 00: unified memory */
656 *phys = SIM_CR16_MEMORY_UNIFIED + (segno << 17) + offset;
659 case 1: /* 01: instruction memory */
660 *phys = SIM_CR16_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
661 last_to = "chip-insn";
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";
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,
683 unsigned long (*imap_register) (void *regcache,
690 last_from = "unknown";
693 seg = (memaddr >> 24);
694 off = (memaddr & 0xffffffL);
696 /* However, if we've asked to use the previous generation of segment
697 mapping, rearrange the segments as follows. */
699 if (old_segment_mapping)
703 case 0x00: /* DMAP translated memory */
706 case 0x01: /* IMAP translated memory */
709 case 0x10: /* On-chip data memory */
712 case 0x11: /* On-chip insn memory */
715 case 0x12: /* Unified memory */
723 case 0x00: /* Physical unified memory */
724 last_from = "phys-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);
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);
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);
747 case 0x10: /* in logical data address segment */
748 nr_bytes = sim_cr16_translate_dmap_addr (off, nr_bytes, &phys, regcache,
752 case 0x11: /* in logical instruction address segment */
753 nr_bytes = sim_cr16_translate_imap_addr (off, nr_bytes, &phys, regcache,
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. */
770 map_memory (unsigned phys_addr)
775 int segment = ((phys_addr >> 24) & 0xff);
780 case 0x00: /* Unified memory */
782 memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
783 last_segname = "umem";
787 case 0x01: /* On-chip insn memory */
789 memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
790 last_segname = "imem";
794 case 0x02: /* On-chip data memory */
796 if ((phys_addr & 0xff00) == 0xff00)
798 phys_addr = (phys_addr & 0xffff);
799 if (phys_addr == DMAP2_SHADDOW)
801 phys_addr = DMAP2_OFFSET;
802 last_segname = "dmap";
805 last_segname = "reg";
808 last_segname = "dmem";
809 memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
815 last_segname = "scrap";
816 return State.mem.fault;
821 *memory = calloc (1, SEGMENT_SIZE);
824 (*cr16_callback->printf_filtered) (cr16_callback, "Malloc failed.\n");
825 return State.mem.fault;
829 offset = (phys_addr % SEGMENT_SIZE);
830 raw = *memory + offset;
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. */
842 xfer_mem (SIM_ADDR virt,
843 unsigned char *buffer,
850 phys_size = sim_cr16_translate_addr (virt, size, &phys, NULL,
851 dmap_register, imap_register);
855 memory = map_memory (phys);
858 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
860 (*cr16_callback->printf_filtered)
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,
866 (long) memory, last_segname);
872 memcpy (memory, buffer, phys_size);
876 memcpy (buffer, memory, phys_size);
884 sim_write (sd, addr, buffer, size)
887 unsigned char *buffer;
890 /* FIXME: this should be performing a virtual transfer */
891 return xfer_mem( addr, buffer, size, 1);
895 sim_read (sd, addr, buffer, size)
898 unsigned char *buffer;
901 /* FIXME: this should be performing a virtual transfer */
902 return xfer_mem( addr, buffer, size, 0);
906 sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *callback, struct bfd *abfd, char **argv)
909 struct hash_entry *h;
910 static int init_p = 0;
914 cr16_callback = callback;
916 old_segment_mapping = 0;
918 /* NOTE: This argument parsing is only effective when this function
919 is called by GDB. Standalone argument parsing is handled by
922 for (p = argv + 1; *p; ++p)
924 if (strcmp (*p, "-oldseg") == 0)
925 old_segment_mapping = 1;
927 else if (strcmp (*p, "-t") == 0)
929 else if (strncmp (*p, "-t", 2) == 0)
930 cr16_debug = atoi (*p + 2);
933 (*cr16_callback->printf_filtered) (cr16_callback, "ERROR: unsupported option(s): %s\n",*p);
937 /* put all the opcodes in the hash table. */
940 for (s = Simops; s->func; s++)
945 h = &hash_table[hash(s->opcode, 0)];
949 if (((s->opcode << 1) >> 4) != 0)
950 h = &hash_table[hash((s->opcode << 1) >> 4, 0)];
952 h = &hash_table[hash((s->opcode << 1), 0)];
956 if ((s->opcode >> 4) != 0)
957 h = &hash_table[hash(s->opcode >> 4, 0)];
959 h = &hash_table[hash(s->opcode, 0)];
963 if (((s->opcode >> 1) >> 4) != 0)
964 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
966 h = &hash_table[hash((s->opcode >> 1), 0)];
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)];
975 h = &hash_table[hash(s->opcode, 0)];
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)];
984 h = &hash_table[hash(s->opcode, 0)];
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)];
993 h = &hash_table[hash((s->opcode >>1), 0)];
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)];
1004 h = &hash_table[hash(s->opcode, 0)];
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)];
1017 h = &hash_table[hash(s->opcode, 0)];
1023 /* go to the last entry in the chain. */
1029 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
1031 perror ("malloc failure");
1037 h->opcode = s->opcode;
1038 h->format = s->format;
1043 /* reset the processor state */
1044 if (!State.mem.data[0])
1046 sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL);
1048 /* Fudge our descriptor. */
1049 return (SIM_DESC) 1;
1054 sim_close (sd, quitting)
1058 if (prog_bfd != NULL && prog_bfd_was_opened_p)
1060 bfd_close (prog_bfd);
1062 prog_bfd_was_opened_p = 0;
1067 sim_set_profile (int n)
1069 (*cr16_callback->printf_filtered) (cr16_callback, "sim_set_profile %d\n",n);
1073 sim_set_profile_size (int n)
1075 (*cr16_callback->printf_filtered) (cr16_callback, "sim_set_profile_size %d\n",n);
1079 dmem_addr (uint32 offset)
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. */
1089 phys_size = sim_cr16_translate_dmap_addr (offset, 1, &phys, NULL,
1093 mem = State.mem.fault;
1096 mem = map_memory (phys);
1098 if ((cr16_debug & DEBUG_MEMORY))
1100 (*cr16_callback->printf_filtered)
1102 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1104 phys, phys_size, last_to,
1105 (long) mem, last_segname);
1112 imem_addr (uint32 offset)
1116 int phys_size = sim_cr16_translate_imap_addr (offset, 1, &phys, NULL,
1120 return State.mem.fault;
1122 mem = map_memory (phys);
1124 if ((cr16_debug & DEBUG_MEMORY))
1126 (*cr16_callback->printf_filtered)
1128 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1130 phys, phys_size, last_to,
1131 (long) mem, last_segname);
1137 static int stop_simulator = 0;
1148 /* Run (or resume) the program. */
1150 sim_resume (SIM_DESC sd, int step, int siggnal)
1152 uint32 curr_ins_size = 0;
1157 // (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
1160 State.exception = 0;
1174 JMP (AE_VECTOR_START);
1180 SET_HW_PSR ((PSR & (PSR_C_BIT)));
1181 JMP (RIE_VECTOR_START);
1185 /* just ignore it */
1191 iaddr = imem_addr ((uint32)PC);
1192 if (iaddr == State.mem.fault)
1194 State.exception = SIGBUS;
1198 mcode = get_longword( iaddr );
1200 State.pc_changed = 0;
1202 curr_ins_size = do_run(mcode);
1205 (*cr16_callback->printf_filtered) (cr16_callback, "INS: PC=0x%X, mcode=0x%X\n",PC,mcode);
1208 if (!State.pc_changed)
1210 if (curr_ins_size == 0)
1212 State.exception = SIG_CR16_EXIT; /* exit trap */
1216 SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */
1220 /* Check for a breakpoint trap on this instruction. This
1221 overrides any pending branches or loops */
1222 if (PSR_DB && PC == DBS)
1226 SET_PC (SDBT_VECTOR_START);
1230 /* Writeback all the DATA / PC changes */
1233 #ifdef NEED_UI_LOOP_HOOK
1234 if (deprecated_ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
1236 ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
1237 deprecated_ui_loop_hook (0);
1239 #endif /* NEED_UI_LOOP_HOOK */
1241 while ( !State.exception && !stop_simulator);
1243 if (step && !State.exception)
1244 State.exception = SIGTRAP;
1248 sim_set_trace (void)
1256 sim_info (SIM_DESC sd, int verbose)
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;
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;
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);
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));
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));
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));
1311 (*cr16_callback->printf_filtered) (cr16_callback,
1312 "executed %*s long instruction(s)\n",
1313 size, add_commas (buf1, sizeof (buf1), ins_long));
1316 (*cr16_callback->printf_filtered) (cr16_callback,
1317 "executed %*s parallel instruction(s)\n",
1318 size, add_commas (buf1, sizeof (buf1), parallel));
1321 (*cr16_callback->printf_filtered) (cr16_callback,
1322 "executed %*s instruction(s) encoded L->R\n",
1323 size, add_commas (buf1, sizeof (buf1), leftright));
1326 (*cr16_callback->printf_filtered) (cr16_callback,
1327 "executed %*s instruction(s) encoded R->L\n",
1328 size, add_commas (buf1, sizeof (buf1), rightleft));
1331 (*cr16_callback->printf_filtered) (cr16_callback,
1332 "executed %*s unknown instruction(s)\n",
1333 size, add_commas (buf1, sizeof (buf1), unknown));
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));
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));
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));
1350 (*cr16_callback->printf_filtered) (cr16_callback,
1351 "executed %*s cycle(s)\n",
1352 size, add_commas (buf1, sizeof (buf1), cycles));
1354 (*cr16_callback->printf_filtered) (cr16_callback,
1355 "executed %*s total instructions\n",
1356 size, add_commas (buf1, sizeof (buf1), total));
1361 sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
1363 bfd_vma start_address;
1365 /* reset all state information */
1366 memset (&State.regs, 0, (int)&State.mem - (int)&State.regs);
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
1378 start_address = bfd_get_start_address (abfd);
1380 start_address = 0x0;
1383 (*cr16_callback->printf_filtered) (cr16_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
1385 SET_CREG (PC_CR, start_address);
1393 sim_set_callbacks (p)
1400 sim_stop_reason (sd, reason, sigrc)
1402 enum sim_stop *reason;
1405 /* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1407 switch (State.exception)
1409 case SIG_CR16_STOP: /* stop instruction */
1410 *reason = sim_stopped;
1414 case SIG_CR16_EXIT: /* exit trap */
1415 *reason = sim_exited;
1420 *reason = sim_stopped;
1421 *sigrc = TARGET_SIGNAL_BUS;
1424 // case SIG_CR16_IAD:
1425 // *reason = sim_stopped;
1426 // *sigrc = TARGET_SIGNAL_IAD;
1429 default: /* some signal */
1430 *reason = sim_stopped;
1431 if (stop_simulator && !State.exception)
1432 *sigrc = TARGET_SIGNAL_INT;
1434 *sigrc = State.exception;
1442 sim_fetch_register (sd, rn, memory, length)
1445 unsigned char *memory;
1449 switch ((enum sim_cr16_regs) rn)
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));
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));
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));
1497 sim_store_register (sd, rn, memory, length)
1500 unsigned char *memory;
1504 switch ((enum sim_cr16_regs) rn)
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));
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));
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));
1552 sim_do_command (sd, cmd)
1556 (*cr16_callback->printf_filtered) (cr16_callback, "sim_do_command: %s\n",cmd);
1560 sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
1562 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1564 if (prog_bfd != NULL && prog_bfd_was_opened_p)
1566 bfd_close (prog_bfd);
1567 prog_bfd_was_opened_p = 0;
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)
1574 prog_bfd_was_opened_p = abfd == NULL;