1 /* Simulation code for the CR16 processor.
2 Copyright (C) 2008-2014 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/>. */
25 #include "gdb/callback.h"
26 #include "gdb/remote-sim.h"
29 #include "gdb/sim-cr16.h"
30 #include "gdb/signals.h"
31 #include "opcode/cr16.h"
34 static SIM_OPEN_KIND sim_kind
;
37 /* Set this to true to get the previous segment layout. */
39 int old_segment_mapping
;
41 host_callback
*cr16_callback
;
42 unsigned long ins_type_counters
[ (int)INS_MAX
];
47 static int init_text_p
= 0;
48 /* non-zero if we opened prog_bfd */
49 static int prog_bfd_was_opened_p
;
55 static struct hash_entry
*lookup_hash (uint64 ins
, int size
);
56 static void get_operands (operand_desc
*s
, uint64 mcode
, int isize
, int nops
);
57 static int do_run (uint64 mc
);
58 static char *add_commas (char *buf
, int sizeof_buf
, unsigned long value
);
59 extern void sim_set_profile (int n
);
60 extern void sim_set_profile_size (int n
);
61 static INLINE uint8
*map_memory (unsigned phys_addr
);
63 #ifdef NEED_UI_LOOP_HOOK
64 /* How often to run the ui_loop update, when in use */
65 #define UI_LOOP_POLL_INTERVAL 0x14000
67 /* Counter for the ui_loop_hook update */
68 static long ui_loop_hook_counter
= UI_LOOP_POLL_INTERVAL
;
70 /* Actual hook to call to run through gdb's gui event loop */
71 extern int (*deprecated_ui_loop_hook
) (int signo
);
72 #endif /* NEED_UI_LOOP_HOOK */
75 #if defined(__GNUC__) && defined(__OPTIMIZE__)
76 #define INLINE __inline__
85 struct hash_entry
*next
;
93 struct hash_entry hash_table
[MAX_HASH
+1];
96 hash(unsigned long long insn
, int format
)
98 unsigned int i
= 4, tmp
;
101 while ((insn
>> i
) != 0) i
+=4;
103 return ((insn
>> (i
-4)) & 0xf); /* Use last 4 bits as hask key. */
105 return ((insn
& 0xF)); /* Use last 4 bits as hask key. */
109 INLINE
static struct hash_entry
*
110 lookup_hash (uint64 ins
, int size
)
113 struct hash_entry
*h
;
115 h
= &hash_table
[hash(ins
,1)];
118 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
120 /* Adjuest mask for branch with 2 word instructions. */
121 if ((h
->ops
->mnimonic
!= NULL
) &&
122 ((streq(h
->ops
->mnimonic
,"b") && h
->size
== 2)))
126 while ((ins
& mask
) != (BIN(h
->opcode
, h
->mask
)))
130 State
.exception
= SIGILL
;
131 State
.pc_changed
= 1; /* Don't increment the PC. */
136 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
137 /* Adjuest mask for branch with 2 word instructions. */
138 if ((streq(h
->ops
->mnimonic
,"b")) && h
->size
== 2)
146 get_operands (operand_desc
*s
, uint64 ins
, int isize
, int nops
)
148 uint32 i
, opn
= 0, start_bit
= 0, op_type
= 0;
149 int32 op_size
= 0, mask
= 0;
151 if (isize
== 1) /* Trunkcate the extra 16 bits of INS. */
154 for (i
=0; i
< 4; ++i
,++opn
)
156 if (s
[opn
].op_type
== dummy
) break;
158 op_type
= s
[opn
].op_type
;
159 start_bit
= s
[opn
].shift
;
160 op_size
= cr16_optab
[op_type
].bit_size
;
164 case imm3
: case imm4
: case imm5
: case imm6
:
167 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
169 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));
171 if (OP
[i
] & ((long)1 << (op_size
-1)))
174 OP
[i
] = ~(OP
[i
]) + 1;
176 OP
[i
] = (unsigned long int)(OP
[i
] & (((long)1 << op_size
) -1));
180 case uimm3
: case uimm3_1
: case uimm4_1
:
184 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1)); break;
186 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));break;
187 default: /* for case 3. */
188 OP
[i
] = ((ins
>> (16 + start_bit
)) & ((1 << op_size
) -1)); break;
198 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
200 OP
[i
] = (ins
& ((1 << op_size
) -1));
203 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
206 OP
[i
] = ((ins
>> (start_bit
+ 16)) & ((1 << op_size
) -1));
209 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
214 case imm16
: case uimm16
:
215 OP
[i
] = ins
& 0xFFFF;
218 case uimm20
: case imm20
:
219 OP
[i
] = ins
& (((long)1 << op_size
) - 1);
222 case imm32
: case uimm32
:
223 OP
[i
] = ins
& 0xFFFFFFFF;
226 case uimm5
: break; /*NOT USED. */
227 OP
[i
] = ins
& ((1 << op_size
) - 1); break;
230 OP
[i
] = (ins
>> 4) & ((1 << 4) - 1);
231 OP
[i
] = (OP
[i
] * 2) + 2;
232 if (OP
[i
] & ((long)1 << 5))
235 OP
[i
] = ~(OP
[i
]) + 1;
236 OP
[i
] = (unsigned long int)(OP
[i
] & 0x1F);
241 OP
[i
] = ((((ins
>> 8) & 0xf) << 4) | (ins
& 0xf));
243 if (OP
[i
] & ((long)1 << 8))
246 OP
[i
] = ~(OP
[i
]) + 1;
247 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFF);
252 OP
[i
] = (ins
& 0xFFFF);
255 OP
[i
] = (OP
[i
] & 0xFFFE);
257 OP
[i
] = ~(OP
[i
]) + 1;
258 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFF);
264 OP
[i
] = (ins
& 0xFFFFFF);
266 OP
[i
] = (ins
& 0xFFFF) | (((ins
>> 24) & 0xf) << 16) |
267 (((ins
>> 16) & 0xf) << 20);
271 OP
[i
] = (OP
[i
] & 0xFFFFFE);
273 OP
[i
] = ~(OP
[i
]) + 1;
274 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFFFF);
280 OP
[i
] = (ins
) & 0xFFFFF;
282 OP
[i
] = (ins
>> start_bit
) & 0xFFFFF;
286 OP
[i
] = ((ins
& 0xFFFF) | (((ins
>> 16) & 0xf) << 20)
287 | (((ins
>> 24) & 0xf) << 16));
289 OP
[i
] = (ins
>> 16) & 0xFFFFFF;
293 case rbase
: break; /* NOT USED. */
294 case rbase_disps20
: case rbase_dispe20
:
295 case rpbase_disps20
: case rpindex_disps20
:
296 OP
[i
] = ((((ins
>> 24)&0xf) << 16)|((ins
) & 0xFFFF));
297 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
300 OP
[i
] = 0; /* 4 bit disp const. */
301 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
304 OP
[i
] = ((ins
>> 8) & 0xF) * 2; /* 4 bit disp const. */
305 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
308 OP
[i
] = ((ins
>> 8) & 0xF); /* 4 bit disp const. */
309 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
312 OP
[i
] = (ins
) & 0xFFFF;
313 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
317 OP
[++i
] = (ins
>> 4) & 0xF; /* get 4 bit for reg. */
318 OP
[++i
] = (ins
>> 8) & 0x1; /* get 1 bit for index-reg. */
320 case rpindex_disps14
:
321 OP
[i
] = (ins
) & 0x3FFF;
322 OP
[++i
] = (ins
>> 14) & 0x1; /* get 1 bit for index-reg. */
323 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
326 OP
[i
] = (ins
) & 0xFFFFF;
327 OP
[++i
] = (ins
>> 24) & 0x1; /* get 1 bit for index-reg. */
328 OP
[++i
] = (ins
>> 20) & 0xF; /* get 4 bit for reg. */
330 case regr
: case regp
: case pregr
: case pregrp
:
334 if (start_bit
== 20) OP
[i
] = (ins
>> 4) & 0xF;
335 else if (start_bit
== 16) OP
[i
] = ins
& 0xF;
337 case 2: OP
[i
] = (ins
>> start_bit
) & 0xF; break;
338 case 3: OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF; break;
343 if (isize
== 1) OP
[i
] = (ins
>> 4) & 0xF;
344 else if (isize
== 2) OP
[i
] = (ins
>> start_bit
) & 0xF;
345 else OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF;
351 /* For ESC on uimm4_1 operand. */
352 if (op_type
== uimm4_1
)
356 /* For increment by 1. */
357 if ((op_type
== pregr
) || (op_type
== pregrp
))
360 /* FIXME: for tracing, update values that need to be updated each
361 instruction decode cycle */
362 State
.trace
.psw
= PSR
;
369 if (!init_text_p
&& prog_bfd
!= NULL
)
372 for (s
= prog_bfd
->sections
; s
; s
= s
->next
)
373 if (strcmp (bfd_get_section_name (prog_bfd
, s
), ".text") == 0)
376 text_start
= bfd_get_section_vma (prog_bfd
, s
);
377 text_end
= text_start
+ bfd_section_size (prog_bfd
, s
);
382 return (PC
) + text_start
;
390 struct simops
*s
= Simops
;
391 struct hash_entry
*h
;
395 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
396 (*cr16_callback
->printf_filtered
) (cr16_callback
, "do_long 0x%x\n", mcode
);
399 h
= lookup_hash(mcode
, 1);
401 if ((h
== NULL
) || (h
->opcode
== NULL
)) return 0;
405 iaddr
= imem_addr ((uint32
)PC
+ 2);
406 mcode
= (mcode
<< 16) | get_longword( iaddr
);
409 /* Re-set OP list. */
410 OP
[0] = OP
[1] = OP
[2] = OP
[3] = sign_flag
= 0;
412 /* for push/pop/pushrtn with RA instructions. */
413 if ((h
->format
& REG_LIST
) && (mcode
& 0x800000))
414 OP
[2] = 1; /* Set 1 for RA operand. */
416 /* numops == 0 means, no operands. */
417 if (((h
->ops
) != NULL
) && (((h
->ops
)->numops
) != 0))
418 get_operands ((h
->ops
)->operands
, mcode
, h
->size
, (h
->ops
)->numops
);
420 //State.ins_type = h->flags;
428 add_commas(char *buf
, int sizeof_buf
, unsigned long value
)
431 char *endbuf
= buf
+ sizeof_buf
- 1;
441 *--endbuf
= (value
% 10) + '0';
442 } while ((value
/= 10) != 0);
451 for (i
= 0; i
< IMEM_SEGMENTS
; i
++)
453 if (State
.mem
.insn
[i
])
454 free (State
.mem
.insn
[i
]);
456 for (i
= 0; i
< DMEM_SEGMENTS
; i
++)
458 if (State
.mem
.data
[i
])
459 free (State
.mem
.data
[i
]);
461 for (i
= 0; i
< UMEM_SEGMENTS
; i
++)
463 if (State
.mem
.unif
[i
])
464 free (State
.mem
.unif
[i
]);
466 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
468 State
.mem
.data
[0] = calloc (1, SEGMENT_SIZE
);
471 /* For tracing - leave info on last access around. */
472 static char *last_segname
= "invalid";
473 static char *last_from
= "invalid";
474 static char *last_to
= "invalid";
478 IMAP0_OFFSET
= 0xff00,
479 DMAP0_OFFSET
= 0xff08,
480 DMAP2_SHADDOW
= 0xff04,
481 DMAP2_OFFSET
= 0xff0c
485 set_dmap_register (int reg_nr
, unsigned long value
)
487 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
488 + DMAP0_OFFSET
+ 2 * reg_nr
);
489 WRITE_16 (raw
, value
);
491 if ((cr16_debug
& DEBUG_MEMORY
))
493 (*cr16_callback
->printf_filtered
)
494 (cr16_callback
, "mem: dmap%d=0x%04lx\n", reg_nr
, value
);
500 dmap_register (void *regcache
, int reg_nr
)
502 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
503 + DMAP0_OFFSET
+ 2 * reg_nr
);
504 return READ_16 (raw
);
508 set_imap_register (int reg_nr
, unsigned long value
)
510 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
511 + IMAP0_OFFSET
+ 2 * reg_nr
);
512 WRITE_16 (raw
, value
);
514 if ((cr16_debug
& DEBUG_MEMORY
))
516 (*cr16_callback
->printf_filtered
)
517 (cr16_callback
, "mem: imap%d=0x%04lx\n", reg_nr
, value
);
523 imap_register (void *regcache
, int reg_nr
)
525 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
526 + IMAP0_OFFSET
+ 2 * reg_nr
);
527 return READ_16 (raw
);
549 set_spi_register (unsigned long value
)
551 SET_GPR (SP_IDX
, value
);
555 set_spu_register (unsigned long value
)
557 SET_GPR (SP_IDX
, value
);
560 /* Given a virtual address in the DMAP address space, translate it
561 into a physical address. */
564 sim_cr16_translate_dmap_addr (unsigned long offset
,
568 unsigned long (*dmap_register
) (void *regcache
,
573 last_from
= "logical-data";
574 if (offset
>= DMAP_BLOCK_SIZE
* SIM_CR16_NR_DMAP_REGS
)
576 /* Logical address out side of data segments, not supported */
579 regno
= (offset
/ DMAP_BLOCK_SIZE
);
580 offset
= (offset
% DMAP_BLOCK_SIZE
);
583 if ((offset
% DMAP_BLOCK_SIZE
) + nr_bytes
> DMAP_BLOCK_SIZE
)
585 /* Don't cross a BLOCK boundary */
586 nr_bytes
= DMAP_BLOCK_SIZE
- (offset
% DMAP_BLOCK_SIZE
);
588 map
= dmap_register (regcache
, regno
);
591 /* Always maps to data memory */
592 int iospi
= (offset
/ 0x1000) % 4;
593 int iosp
= (map
>> (4 * (3 - iospi
))) % 0x10;
594 last_to
= "io-space";
595 *phys
= (SIM_CR16_MEMORY_DATA
+ (iosp
* 0x10000) + 0xc000 + offset
);
599 int sp
= ((map
& 0x3000) >> 12);
600 int segno
= (map
& 0x3ff);
603 case 0: /* 00: Unified memory */
604 *phys
= SIM_CR16_MEMORY_UNIFIED
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
607 case 1: /* 01: Instruction Memory */
608 *phys
= SIM_CR16_MEMORY_INSN
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
609 last_to
= "chip-insn";
611 case 2: /* 10: Internal data memory */
612 *phys
= SIM_CR16_MEMORY_DATA
+ (segno
<< 16) + (regno
* DMAP_BLOCK_SIZE
) + offset
;
613 last_to
= "chip-data";
615 case 3: /* 11: Reserved */
623 /* Given a virtual address in the IMAP address space, translate it
624 into a physical address. */
627 sim_cr16_translate_imap_addr (unsigned long offset
,
631 unsigned long (*imap_register
) (void *regcache
,
638 last_from
= "logical-insn";
639 if (offset
>= (IMAP_BLOCK_SIZE
* SIM_CR16_NR_IMAP_REGS
))
641 /* Logical address outside of IMAP segments, not supported */
644 regno
= (offset
/ IMAP_BLOCK_SIZE
);
645 offset
= (offset
% IMAP_BLOCK_SIZE
);
646 if (offset
+ nr_bytes
> IMAP_BLOCK_SIZE
)
648 /* Don't cross a BLOCK boundary */
649 nr_bytes
= IMAP_BLOCK_SIZE
- offset
;
651 map
= imap_register (regcache
, regno
);
652 sp
= (map
& 0x3000) >> 12;
653 segno
= (map
& 0x007f);
656 case 0: /* 00: unified memory */
657 *phys
= SIM_CR16_MEMORY_UNIFIED
+ (segno
<< 17) + offset
;
660 case 1: /* 01: instruction memory */
661 *phys
= SIM_CR16_MEMORY_INSN
+ (IMAP_BLOCK_SIZE
* regno
) + offset
;
662 last_to
= "chip-insn";
667 case 3: /* 11: for testing - instruction memory */
668 offset
= (offset
% 0x800);
669 *phys
= SIM_CR16_MEMORY_INSN
+ offset
;
670 if (offset
+ nr_bytes
> 0x800)
671 /* don't cross VM boundary */
672 nr_bytes
= 0x800 - offset
;
673 last_to
= "test-insn";
680 sim_cr16_translate_addr (unsigned long memaddr
, int nr_bytes
,
681 unsigned long *targ_addr
, void *regcache
,
682 unsigned long (*dmap_register
) (void *regcache
,
684 unsigned long (*imap_register
) (void *regcache
,
691 last_from
= "unknown";
694 seg
= (memaddr
>> 24);
695 off
= (memaddr
& 0xffffffL
);
697 /* However, if we've asked to use the previous generation of segment
698 mapping, rearrange the segments as follows. */
700 if (old_segment_mapping
)
704 case 0x00: /* DMAP translated memory */
707 case 0x01: /* IMAP translated memory */
710 case 0x10: /* On-chip data memory */
713 case 0x11: /* On-chip insn memory */
716 case 0x12: /* Unified memory */
724 case 0x00: /* Physical unified memory */
725 last_from
= "phys-unified";
727 phys
= SIM_CR16_MEMORY_UNIFIED
+ off
;
728 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
729 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
732 case 0x01: /* Physical instruction memory */
733 last_from
= "phys-insn";
734 last_to
= "chip-insn";
735 phys
= SIM_CR16_MEMORY_INSN
+ off
;
736 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
737 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
740 case 0x02: /* Physical data memory segment */
741 last_from
= "phys-data";
742 last_to
= "chip-data";
743 phys
= SIM_CR16_MEMORY_DATA
+ off
;
744 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
745 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
748 case 0x10: /* in logical data address segment */
749 nr_bytes
= sim_cr16_translate_dmap_addr (off
, nr_bytes
, &phys
, regcache
,
753 case 0x11: /* in logical instruction address segment */
754 nr_bytes
= sim_cr16_translate_imap_addr (off
, nr_bytes
, &phys
, regcache
,
766 /* Return a pointer into the raw buffer designated by phys_addr. It
767 is assumed that the client has already ensured that the access
768 isn't going to cross a segment boundary. */
771 map_memory (unsigned phys_addr
)
776 int segment
= ((phys_addr
>> 24) & 0xff);
781 case 0x00: /* Unified memory */
783 memory
= &State
.mem
.unif
[(phys_addr
/ SEGMENT_SIZE
) % UMEM_SEGMENTS
];
784 last_segname
= "umem";
788 case 0x01: /* On-chip insn memory */
790 memory
= &State
.mem
.insn
[(phys_addr
/ SEGMENT_SIZE
) % IMEM_SEGMENTS
];
791 last_segname
= "imem";
795 case 0x02: /* On-chip data memory */
797 if ((phys_addr
& 0xff00) == 0xff00)
799 phys_addr
= (phys_addr
& 0xffff);
800 if (phys_addr
== DMAP2_SHADDOW
)
802 phys_addr
= DMAP2_OFFSET
;
803 last_segname
= "dmap";
806 last_segname
= "reg";
809 last_segname
= "dmem";
810 memory
= &State
.mem
.data
[(phys_addr
/ SEGMENT_SIZE
) % DMEM_SEGMENTS
];
816 last_segname
= "scrap";
817 return State
.mem
.fault
;
822 *memory
= calloc (1, SEGMENT_SIZE
);
825 (*cr16_callback
->printf_filtered
) (cr16_callback
, "Malloc failed.\n");
826 return State
.mem
.fault
;
830 offset
= (phys_addr
% SEGMENT_SIZE
);
831 raw
= *memory
+ offset
;
835 /* Transfer data to/from simulated memory. Since a bug in either the
836 simulated program or in gdb or the simulator itself may cause a
837 bogus address to be passed in, we need to do some sanity checking
838 on addresses to make sure they are within bounds. When an address
839 fails the bounds check, treat it as a zero length read/write rather
840 than aborting the entire run. */
843 xfer_mem (SIM_ADDR virt
,
844 unsigned char *buffer
,
851 phys_size
= sim_cr16_translate_addr (virt
, size
, &phys
, NULL
,
852 dmap_register
, imap_register
);
856 memory
= map_memory (phys
);
859 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
861 (*cr16_callback
->printf_filtered
)
863 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
864 (write_p
? "write" : "read"),
865 phys_size
, virt
, last_from
,
867 (long) memory
, last_segname
);
873 memcpy (memory
, buffer
, phys_size
);
877 memcpy (buffer
, memory
, phys_size
);
885 sim_write (sd
, addr
, buffer
, size
)
888 const unsigned char *buffer
;
891 /* FIXME: this should be performing a virtual transfer */
892 return xfer_mem( addr
, buffer
, size
, 1);
896 sim_read (sd
, addr
, buffer
, size
)
899 unsigned char *buffer
;
902 /* FIXME: this should be performing a virtual transfer */
903 return xfer_mem( addr
, buffer
, size
, 0);
907 sim_open (SIM_OPEN_KIND kind
, struct host_callback_struct
*callback
, struct bfd
*abfd
, char **argv
)
910 struct hash_entry
*h
;
911 static int init_p
= 0;
915 cr16_callback
= callback
;
917 old_segment_mapping
= 0;
919 /* NOTE: This argument parsing is only effective when this function
920 is called by GDB. Standalone argument parsing is handled by
923 for (p
= argv
+ 1; *p
; ++p
)
925 if (strcmp (*p
, "-oldseg") == 0)
926 old_segment_mapping
= 1;
928 else if (strcmp (*p
, "-t") == 0)
930 else if (strncmp (*p
, "-t", 2) == 0)
931 cr16_debug
= atoi (*p
+ 2);
934 (*cr16_callback
->printf_filtered
) (cr16_callback
, "ERROR: unsupported option(s): %s\n",*p
);
938 /* put all the opcodes in the hash table. */
941 for (s
= Simops
; s
->func
; s
++)
946 h
= &hash_table
[hash(s
->opcode
, 0)];
950 if (((s
->opcode
<< 1) >> 4) != 0)
951 h
= &hash_table
[hash((s
->opcode
<< 1) >> 4, 0)];
953 h
= &hash_table
[hash((s
->opcode
<< 1), 0)];
957 if ((s
->opcode
>> 4) != 0)
958 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
960 h
= &hash_table
[hash(s
->opcode
, 0)];
964 if (((s
->opcode
>> 1) >> 4) != 0)
965 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
967 h
= &hash_table
[hash((s
->opcode
>> 1), 0)];
971 if ((s
->opcode
>> 8) != 0)
972 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
973 else if ((s
->opcode
>> 4) != 0)
974 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
976 h
= &hash_table
[hash(s
->opcode
, 0)];
980 if ((s
->opcode
>> 8) != 0)
981 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
982 else if ((s
->opcode
>> 4) != 0)
983 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
985 h
= &hash_table
[hash(s
->opcode
, 0)];
989 if (((s
->opcode
>> 1) >> 8) != 0)
990 h
= &hash_table
[hash((s
->opcode
>>1) >> 8, 0)];
991 else if (((s
->opcode
>> 1) >> 4) != 0)
992 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
994 h
= &hash_table
[hash((s
->opcode
>>1), 0)];
998 if ((s
->opcode
>> 0xc) != 0)
999 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
1000 else if ((s
->opcode
>> 8) != 0)
1001 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
1002 else if ((s
->opcode
>> 4) != 0)
1003 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
1005 h
= &hash_table
[hash(s
->opcode
, 0)];
1009 if ((s
->opcode
>> 16) != 0)
1010 h
= &hash_table
[hash(s
->opcode
>> 16, 0)];
1011 else if ((s
->opcode
>> 12) != 0)
1012 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
1013 else if ((s
->opcode
>> 8) != 0)
1014 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
1015 else if ((s
->opcode
>> 4) != 0)
1016 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
1018 h
= &hash_table
[hash(s
->opcode
, 0)];
1024 /* go to the last entry in the chain. */
1030 h
->next
= (struct hash_entry
*) calloc(1,sizeof(struct hash_entry
));
1032 perror ("malloc failure");
1038 h
->opcode
= s
->opcode
;
1039 h
->format
= s
->format
;
1044 /* reset the processor state */
1045 if (!State
.mem
.data
[0])
1047 sim_create_inferior ((SIM_DESC
) 1, NULL
, NULL
, NULL
);
1049 /* Fudge our descriptor. */
1050 return (SIM_DESC
) 1;
1055 sim_close (sd
, quitting
)
1059 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
1061 bfd_close (prog_bfd
);
1063 prog_bfd_was_opened_p
= 0;
1068 sim_set_profile (int n
)
1070 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_set_profile %d\n",n
);
1074 sim_set_profile_size (int n
)
1076 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_set_profile_size %d\n",n
);
1080 dmem_addr (uint32 offset
)
1086 /* Note: DMEM address range is 0..0x10000. Calling code can compute
1087 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
1088 is uint16 this is modulo'ed onto 0x0e5d. */
1090 phys_size
= sim_cr16_translate_dmap_addr (offset
, 1, &phys
, NULL
,
1094 mem
= State
.mem
.fault
;
1097 mem
= map_memory (phys
);
1099 if ((cr16_debug
& DEBUG_MEMORY
))
1101 (*cr16_callback
->printf_filtered
)
1103 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1105 phys
, phys_size
, last_to
,
1106 (long) mem
, last_segname
);
1113 imem_addr (uint32 offset
)
1117 int phys_size
= sim_cr16_translate_imap_addr (offset
, 1, &phys
, NULL
,
1121 return State
.mem
.fault
;
1123 mem
= map_memory (phys
);
1125 if ((cr16_debug
& DEBUG_MEMORY
))
1127 (*cr16_callback
->printf_filtered
)
1129 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1131 phys
, phys_size
, last_to
,
1132 (long) mem
, last_segname
);
1138 static int stop_simulator
= 0;
1149 /* Run (or resume) the program. */
1151 sim_resume (SIM_DESC sd
, int step
, int siggnal
)
1153 uint32 curr_ins_size
= 0;
1158 // (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
1161 State
.exception
= 0;
1175 JMP (AE_VECTOR_START
);
1181 SET_HW_PSR ((PSR
& (PSR_C_BIT
)));
1182 JMP (RIE_VECTOR_START
);
1186 /* just ignore it */
1192 iaddr
= imem_addr ((uint32
)PC
);
1193 if (iaddr
== State
.mem
.fault
)
1196 State
.exception
= SIGBUS
;
1198 State
.exception
= SIGSEGV
;
1203 mcode
= get_longword( iaddr
);
1205 State
.pc_changed
= 0;
1207 curr_ins_size
= do_run(mcode
);
1210 (*cr16_callback
->printf_filtered
) (cr16_callback
, "INS: PC=0x%X, mcode=0x%X\n",PC
,mcode
);
1213 if (!State
.pc_changed
)
1215 if (curr_ins_size
== 0)
1217 State
.exception
= SIG_CR16_EXIT
; /* exit trap */
1221 SET_PC (PC
+ (curr_ins_size
* 2)); /* For word instructions. */
1225 /* Check for a breakpoint trap on this instruction. This
1226 overrides any pending branches or loops */
1227 if (PSR_DB
&& PC
== DBS
)
1231 SET_PC (SDBT_VECTOR_START
);
1235 /* Writeback all the DATA / PC changes */
1238 #ifdef NEED_UI_LOOP_HOOK
1239 if (deprecated_ui_loop_hook
!= NULL
&& ui_loop_hook_counter
-- < 0)
1241 ui_loop_hook_counter
= UI_LOOP_POLL_INTERVAL
;
1242 deprecated_ui_loop_hook (0);
1244 #endif /* NEED_UI_LOOP_HOOK */
1246 while ( !State
.exception
&& !stop_simulator
);
1248 if (step
&& !State
.exception
)
1249 State
.exception
= SIGTRAP
;
1253 sim_set_trace (void)
1261 sim_info (SIM_DESC sd
, int verbose
)
1269 unsigned long left
= ins_type_counters
[ (int)INS_LEFT
] + ins_type_counters
[ (int)INS_LEFT_COND_EXE
];
1270 unsigned long left_nops
= ins_type_counters
[ (int)INS_LEFT_NOPS
];
1271 unsigned long left_parallel
= ins_type_counters
[ (int)INS_LEFT_PARALLEL
];
1272 unsigned long left_cond
= ins_type_counters
[ (int)INS_LEFT_COND_TEST
];
1273 unsigned long left_total
= left
+ left_parallel
+ left_cond
+ left_nops
;
1275 unsigned long right
= ins_type_counters
[ (int)INS_RIGHT
] + ins_type_counters
[ (int)INS_RIGHT_COND_EXE
];
1276 unsigned long right_nops
= ins_type_counters
[ (int)INS_RIGHT_NOPS
];
1277 unsigned long right_parallel
= ins_type_counters
[ (int)INS_RIGHT_PARALLEL
];
1278 unsigned long right_cond
= ins_type_counters
[ (int)INS_RIGHT_COND_TEST
];
1279 unsigned long right_total
= right
+ right_parallel
+ right_cond
+ right_nops
;
1281 unsigned long unknown
= ins_type_counters
[ (int)INS_UNKNOWN
];
1282 unsigned long ins_long
= ins_type_counters
[ (int)INS_LONG
];
1283 unsigned long parallel
= ins_type_counters
[ (int)INS_PARALLEL
];
1284 unsigned long leftright
= ins_type_counters
[ (int)INS_LEFTRIGHT
];
1285 unsigned long rightleft
= ins_type_counters
[ (int)INS_RIGHTLEFT
];
1286 unsigned long cond_true
= ins_type_counters
[ (int)INS_COND_TRUE
];
1287 unsigned long cond_false
= ins_type_counters
[ (int)INS_COND_FALSE
];
1288 unsigned long cond_jump
= ins_type_counters
[ (int)INS_COND_JUMP
];
1289 unsigned long cycles
= ins_type_counters
[ (int)INS_CYCLES
];
1290 unsigned long total
= (unknown
+ left_total
+ right_total
+ ins_long
);
1292 int size
= strlen (add_commas (buf1
, sizeof (buf1
), total
));
1293 int parallel_size
= strlen (add_commas (buf1
, sizeof (buf1
),
1294 (left_parallel
> right_parallel
) ? left_parallel
: right_parallel
));
1295 int cond_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_cond
> right_cond
) ? left_cond
: right_cond
));
1296 int nop_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_nops
> right_nops
) ? left_nops
: right_nops
));
1297 int normal_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left
> right
) ? left
: right
));
1299 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1300 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1301 size
, add_commas (buf1
, sizeof (buf1
), left_total
),
1302 normal_size
, add_commas (buf2
, sizeof (buf2
), left
),
1303 parallel_size
, add_commas (buf3
, sizeof (buf3
), left_parallel
),
1304 cond_size
, add_commas (buf4
, sizeof (buf4
), left_cond
),
1305 nop_size
, add_commas (buf5
, sizeof (buf5
), left_nops
));
1307 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1308 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1309 size
, add_commas (buf1
, sizeof (buf1
), right_total
),
1310 normal_size
, add_commas (buf2
, sizeof (buf2
), right
),
1311 parallel_size
, add_commas (buf3
, sizeof (buf3
), right_parallel
),
1312 cond_size
, add_commas (buf4
, sizeof (buf4
), right_cond
),
1313 nop_size
, add_commas (buf5
, sizeof (buf5
), right_nops
));
1316 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1317 "executed %*s long instruction(s)\n",
1318 size
, add_commas (buf1
, sizeof (buf1
), ins_long
));
1321 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1322 "executed %*s parallel instruction(s)\n",
1323 size
, add_commas (buf1
, sizeof (buf1
), parallel
));
1326 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1327 "executed %*s instruction(s) encoded L->R\n",
1328 size
, add_commas (buf1
, sizeof (buf1
), leftright
));
1331 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1332 "executed %*s instruction(s) encoded R->L\n",
1333 size
, add_commas (buf1
, sizeof (buf1
), rightleft
));
1336 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1337 "executed %*s unknown instruction(s)\n",
1338 size
, add_commas (buf1
, sizeof (buf1
), unknown
));
1341 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1342 "executed %*s instruction(s) due to EXExxx condition being true\n",
1343 size
, add_commas (buf1
, sizeof (buf1
), cond_true
));
1346 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1347 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1348 size
, add_commas (buf1
, sizeof (buf1
), cond_false
));
1351 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1352 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1353 size
, add_commas (buf1
, sizeof (buf1
), cond_jump
));
1355 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1356 "executed %*s cycle(s)\n",
1357 size
, add_commas (buf1
, sizeof (buf1
), cycles
));
1359 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1360 "executed %*s total instructions\n",
1361 size
, add_commas (buf1
, sizeof (buf1
), total
));
1366 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
, char **argv
, char **env
)
1368 bfd_vma start_address
;
1370 /* reset all state information */
1371 memset (&State
.regs
, 0, (int)&State
.mem
- (int)&State
.regs
);
1373 /* There was a hack here to copy the values of argc and argv into r0
1374 and r1. The values were also saved into some high memory that
1375 won't be overwritten by the stack (0x7C00). The reason for doing
1376 this was to allow the 'run' program to accept arguments. Without
1377 the hack, this is not possible anymore. If the simulator is run
1378 from the debugger, arguments cannot be passed in, so this makes
1383 start_address
= bfd_get_start_address (abfd
);
1385 start_address
= 0x0;
1388 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_create_inferior: PC=0x%lx\n", (long) start_address
);
1390 SET_CREG (PC_CR
, start_address
);
1398 sim_set_callbacks (p
)
1405 sim_stop_reason (sd
, reason
, sigrc
)
1407 enum sim_stop
*reason
;
1410 /* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1412 switch (State
.exception
)
1414 case SIG_CR16_STOP
: /* stop instruction */
1415 *reason
= sim_stopped
;
1419 case SIG_CR16_EXIT
: /* exit trap */
1420 *reason
= sim_exited
;
1425 *reason
= sim_stopped
;
1426 *sigrc
= GDB_SIGNAL_BUS
;
1429 // case SIG_CR16_IAD:
1430 // *reason = sim_stopped;
1431 // *sigrc = GDB_SIGNAL_IAD;
1434 default: /* some signal */
1435 *reason
= sim_stopped
;
1436 if (stop_simulator
&& !State
.exception
)
1437 *sigrc
= GDB_SIGNAL_INT
;
1439 *sigrc
= State
.exception
;
1447 sim_fetch_register (sd
, rn
, memory
, length
)
1450 unsigned char *memory
;
1454 switch ((enum sim_cr16_regs
) rn
)
1456 case SIM_CR16_R0_REGNUM
:
1457 case SIM_CR16_R1_REGNUM
:
1458 case SIM_CR16_R2_REGNUM
:
1459 case SIM_CR16_R3_REGNUM
:
1460 case SIM_CR16_R4_REGNUM
:
1461 case SIM_CR16_R5_REGNUM
:
1462 case SIM_CR16_R6_REGNUM
:
1463 case SIM_CR16_R7_REGNUM
:
1464 case SIM_CR16_R8_REGNUM
:
1465 case SIM_CR16_R9_REGNUM
:
1466 case SIM_CR16_R10_REGNUM
:
1467 case SIM_CR16_R11_REGNUM
:
1468 WRITE_16 (memory
, GPR (rn
- SIM_CR16_R0_REGNUM
));
1471 case SIM_CR16_R12_REGNUM
:
1472 case SIM_CR16_R13_REGNUM
:
1473 case SIM_CR16_R14_REGNUM
:
1474 case SIM_CR16_R15_REGNUM
:
1475 //WRITE_32 (memory, GPR (rn - SIM_CR16_R0_REGNUM));
1476 write_longword (memory
, GPR (rn
- SIM_CR16_R0_REGNUM
));
1479 case SIM_CR16_PC_REGNUM
:
1480 case SIM_CR16_ISP_REGNUM
:
1481 case SIM_CR16_USP_REGNUM
:
1482 case SIM_CR16_INTBASE_REGNUM
:
1483 case SIM_CR16_PSR_REGNUM
:
1484 case SIM_CR16_CFG_REGNUM
:
1485 case SIM_CR16_DBS_REGNUM
:
1486 case SIM_CR16_DCR_REGNUM
:
1487 case SIM_CR16_DSR_REGNUM
:
1488 case SIM_CR16_CAR0_REGNUM
:
1489 case SIM_CR16_CAR1_REGNUM
:
1490 //WRITE_32 (memory, CREG (rn - SIM_CR16_PC_REGNUM));
1491 write_longword (memory
, CREG (rn
- SIM_CR16_PC_REGNUM
));
1502 sim_store_register (sd
, rn
, memory
, length
)
1505 unsigned char *memory
;
1509 switch ((enum sim_cr16_regs
) rn
)
1511 case SIM_CR16_R0_REGNUM
:
1512 case SIM_CR16_R1_REGNUM
:
1513 case SIM_CR16_R2_REGNUM
:
1514 case SIM_CR16_R3_REGNUM
:
1515 case SIM_CR16_R4_REGNUM
:
1516 case SIM_CR16_R5_REGNUM
:
1517 case SIM_CR16_R6_REGNUM
:
1518 case SIM_CR16_R7_REGNUM
:
1519 case SIM_CR16_R8_REGNUM
:
1520 case SIM_CR16_R9_REGNUM
:
1521 case SIM_CR16_R10_REGNUM
:
1522 case SIM_CR16_R11_REGNUM
:
1523 SET_GPR (rn
- SIM_CR16_R0_REGNUM
, READ_16 (memory
));
1526 case SIM_CR16_R12_REGNUM
:
1527 case SIM_CR16_R13_REGNUM
:
1528 case SIM_CR16_R14_REGNUM
:
1529 case SIM_CR16_R15_REGNUM
:
1530 SET_GPR32 (rn
- SIM_CR16_R0_REGNUM
, get_longword (memory
));
1533 case SIM_CR16_PC_REGNUM
:
1534 case SIM_CR16_ISP_REGNUM
:
1535 case SIM_CR16_USP_REGNUM
:
1536 case SIM_CR16_INTBASE_REGNUM
:
1537 case SIM_CR16_PSR_REGNUM
:
1538 case SIM_CR16_CFG_REGNUM
:
1539 case SIM_CR16_DBS_REGNUM
:
1540 case SIM_CR16_DCR_REGNUM
:
1541 case SIM_CR16_DSR_REGNUM
:
1542 case SIM_CR16_CAR0_REGNUM
:
1543 case SIM_CR16_CAR1_REGNUM
:
1544 SET_CREG (rn
- SIM_CR16_PC_REGNUM
, get_longword (memory
));
1556 sim_complete_command (SIM_DESC sd
, const char *text
, const char *word
)
1562 sim_do_command (sd
, cmd
)
1566 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_do_command: %s\n",cmd
);
1570 sim_load (SIM_DESC sd
, char *prog
, struct bfd
*abfd
, int from_tty
)
1572 extern bfd
*sim_load_file (); /* ??? Don't know where this should live. */
1574 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
1576 bfd_close (prog_bfd
);
1577 prog_bfd_was_opened_p
= 0;
1579 prog_bfd
= sim_load_file (sd
, myname
, cr16_callback
, prog
, abfd
,
1580 sim_kind
== SIM_OPEN_DEBUG
,
1581 1/*LMA*/, sim_write
);
1582 if (prog_bfd
== NULL
)
1584 prog_bfd_was_opened_p
= abfd
== NULL
;
This page took 0.059865 seconds and 4 git commands to generate.