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 along
18 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"
31 enum _leftright
{ LEFT_FIRST
, RIGHT_FIRST
};
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 void get_operands
PARAMS ((operand_desc
*s
, uint64 mcode
, int isize
));
56 static void do_run
PARAMS ((inst
*ins
, 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__
82 get_operands (operand_desc
*s
, uint64 ins
, int isize
)
84 uint32 i
, opn
= 0, start_bit
= 0, op_type
= 0;
85 int32 op_size
= 0, mask
= 0;
87 if (isize
== 1) /* Trunkcate the extra 16 bits of INS. */
90 for (i
=0; i
< 3; ++i
,++opn
)
92 if ((s
[opn
].op_type
== dummy
) || (s
[opn
].op_type
> cr16_num_optab
))
95 op_type
= s
[opn
].op_type
;
97 start_bit
= s
[opn
].shift
;
98 op_size
= cr16_optab
[op_type
].bit_size
;
102 case imm3
: case imm4
: case imm5
: case imm6
:
105 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
107 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));
109 if (OP
[i
] & ((long)1 << (op_size
-1)))
112 OP
[i
] = ~(OP
[i
]) + 1;
114 OP
[i
] = (unsigned long int)(OP
[i
] & (((long)1 << op_size
) -1));
118 case uimm3
: case uimm3_1
: case uimm4_1
:
120 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
122 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));
130 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
132 OP
[i
] = (ins
& ((1 << op_size
) -1));
135 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
138 OP
[i
] = ((ins
>> (start_bit
+ 16)) & ((1 << op_size
) -1));
141 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
146 case imm16
: case uimm16
:
147 OP
[i
] = ins
& 0xFFFF;
150 case uimm20
: case imm20
:
151 OP
[i
] = ins
& (((long)1 << op_size
) - 1);
154 case imm32
: case uimm32
:
155 OP
[i
] = ins
& 0xFFFFFFFF;
158 case uimm5
: break; /*NOT USED. */
159 OP
[i
] = ins
& ((1 << op_size
) - 1); break;
162 OP
[i
] = (ins
>> 4) & ((1 << 4) - 1);
163 OP
[i
] = (OP
[i
] * 2) + 2;
164 if (OP
[i
] & ((long)1 << 5))
167 OP
[i
] = ~(OP
[i
]) + 1;
168 OP
[i
] = (unsigned long int)(OP
[i
] & 0x1F);
173 OP
[i
] = ((((ins
>> 8) & 0xf) << 4) | (ins
& 0xf));
175 if (OP
[i
] & ((long)1 << 8))
178 OP
[i
] = ~(OP
[i
]) + 1;
179 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFF);
184 OP
[i
] = (ins
& 0xFFFF);
187 OP
[i
] = (OP
[i
] & 0xFFFE);
189 OP
[i
] = ~(OP
[i
]) + 1;
190 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFF);
196 OP
[i
] = (ins
& 0xFFFFFF);
198 OP
[i
] = (ins
& 0xFFFF) | (((ins
>> 24) & 0xf) << 16) |
199 (((ins
>> 16) & 0xf) << 20);
203 OP
[i
] = (OP
[i
] & 0xFFFFFE);
205 OP
[i
] = ~(OP
[i
]) + 1;
206 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFFFF);
212 OP
[i
] = (ins
) & 0xFFFFF;
214 OP
[i
] = (ins
>> start_bit
) & 0xFFFFF;
218 OP
[i
] = ((ins
& 0xFFFF) | (((ins
>> 16) & 0xf) << 20)
219 | (((ins
>> 24) & 0xf) << 16));
221 OP
[i
] = (ins
>> 16) & 0xFFFFFF;
225 case rbase
: break; /* NOT USED. */
226 case rbase_disps20
: case rbase_dispe20
:
227 case rpbase_disps20
: case rpindex_disps20
:
228 OP
[i
] = ((((ins
>> 24)&0xf) << 16)|((ins
) & 0xFFFF));
229 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
232 OP
[i
] = 0; /* 4 bit disp const. */
233 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
236 OP
[i
] = ((ins
>> 8) & 0xF) * 2; /* 4 bit disp const. */
237 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
240 OP
[i
] = ((ins
>> 8) & 0xF); /* 4 bit disp const. */
241 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
244 OP
[i
] = (ins
) & 0xFFFF;
245 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
249 OP
[++i
] = (ins
>> 4) & 0xF; /* get 4 bit for reg. */
250 OP
[++i
] = (ins
>> 8) & 0x1; /* get 1 bit for index-reg. */
252 case rpindex_disps14
:
253 OP
[i
] = (ins
) & 0x3FFF;
254 OP
[++i
] = (ins
>> 14) & 0x1; /* get 1 bit for index-reg. */
255 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
258 OP
[i
] = (ins
) & 0xFFFFF;
259 OP
[++i
] = (ins
>> 24) & 0x1; /* get 1 bit for index-reg. */
260 OP
[++i
] = (ins
>> 20) & 0xF; /* get 4 bit for reg. */
262 case regr
: case regp
: case pregr
: case pregrp
:
266 if (start_bit
== 20) OP
[i
] = (ins
>> 4) & 0xF;
267 else if (start_bit
== 16) OP
[i
] = ins
& 0xF;
269 case 2: OP
[i
] = (ins
>> start_bit
) & 0xF; break;
270 case 3: OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF; break;
275 if (isize
== 1) OP
[i
] = (ins
>> 4) & 0xF;
276 else if (isize
== 2) OP
[i
] = (ins
>> start_bit
) & 0xF;
277 else OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF;
283 /* For ESC on uimm4_1 operand */
284 if (op_type
== uimm4_1
)
288 /* FIXME: for tracing, update values that need to be updated each
289 instruction decode cycle */
291 (*cr16_callback
->printf_filtered
) (cr16_callback
, "OP0=0x%X\t,OP1=0x%X\t,OP2=0x%X\t,OP3=0X%X\n",OP
[0],OP
[1],OP
[2],OP
[3]);
293 State
.trace
.psw
= PSR
;
301 if (!init_text_p
&& prog_bfd
!= NULL
)
304 for (s
= prog_bfd
->sections
; s
; s
= s
->next
)
305 if (strcmp (bfd_get_section_name (prog_bfd
, s
), ".text") == 0)
308 text_start
= bfd_get_section_vma (prog_bfd
, s
);
309 text_end
= text_start
+ bfd_section_size (prog_bfd
, s
);
314 return (PC
) + text_start
;
320 do_run(inst
*instruction
, uint64 mcode
)
322 struct simops
*s
= Simops
;
325 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
326 (*cr16_callback
->printf_filtered
) (cr16_callback
, "do_long 0x%x\n", instruction
);
330 OP
[0] = OP
[1] = OP
[2] = OP
[3] = sign_flag
= 0;
332 /* for push/pop/pushrtn with RA instructions */
333 if ((INST_HAS_REG_LIST
) && (mcode
& 0x800000))
334 OP
[2] = 1; /* Set 1 for RA operand */
336 get_operands (&instruction
->operands
, mcode
, instruction
->size
);
338 State
.ins_type
= instruction
->flags
;
339 //ins_type_counters[ (int)State.ins_type ]++;
340 sprintf(func
,"OP_%X_%X",instruction
->match
,(32 - instruction
->match_bits
));
341 /* Check for appropriate opcode function */
342 for ( ;s
->opcode
!=0;s
++)
344 if (strcmp(s
->fname
,func
) == 0)
351 add_commas(char *buf
, int sizeof_buf
, unsigned long value
)
354 char *endbuf
= buf
+ sizeof_buf
- 1;
364 *--endbuf
= (value
% 10) + '0';
365 } while ((value
/= 10) != 0);
374 for (i
= 0; i
< IMEM_SEGMENTS
; i
++)
376 if (State
.mem
.insn
[i
])
377 free (State
.mem
.insn
[i
]);
379 for (i
= 0; i
< DMEM_SEGMENTS
; i
++)
381 if (State
.mem
.data
[i
])
382 free (State
.mem
.data
[i
]);
384 for (i
= 0; i
< UMEM_SEGMENTS
; i
++)
386 if (State
.mem
.unif
[i
])
387 free (State
.mem
.unif
[i
]);
389 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
391 State
.mem
.data
[0] = calloc (1, SEGMENT_SIZE
);
394 /* For tracing - leave info on last access around. */
395 static char *last_segname
= "invalid";
396 static char *last_from
= "invalid";
397 static char *last_to
= "invalid";
401 IMAP0_OFFSET
= 0xff00,
402 DMAP0_OFFSET
= 0xff08,
403 DMAP2_SHADDOW
= 0xff04,
404 DMAP2_OFFSET
= 0xff0c
408 set_dmap_register (int reg_nr
, unsigned long value
)
410 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
411 + DMAP0_OFFSET
+ 2 * reg_nr
);
412 WRITE_16 (raw
, value
);
414 if ((cr16_debug
& DEBUG_MEMORY
))
416 (*cr16_callback
->printf_filtered
)
417 (cr16_callback
, "mem: dmap%d=0x%04lx\n", reg_nr
, value
);
423 dmap_register (void *regcache
, int reg_nr
)
425 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
426 + DMAP0_OFFSET
+ 2 * reg_nr
);
427 return READ_16 (raw
);
431 set_imap_register (int reg_nr
, unsigned long value
)
433 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
434 + IMAP0_OFFSET
+ 2 * reg_nr
);
435 WRITE_16 (raw
, value
);
437 if ((cr16_debug
& DEBUG_MEMORY
))
439 (*cr16_callback
->printf_filtered
)
440 (cr16_callback
, "mem: imap%d=0x%04lx\n", reg_nr
, value
);
446 imap_register (void *regcache
, int reg_nr
)
448 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
449 + IMAP0_OFFSET
+ 2 * reg_nr
);
450 return READ_16 (raw
);
472 set_spi_register (unsigned long value
)
474 SET_GPR (SP_IDX
, value
);
478 set_spu_register (unsigned long value
)
480 SET_GPR (SP_IDX
, value
);
483 /* Given a virtual address in the DMAP address space, translate it
484 into a physical address. */
487 sim_cr16_translate_dmap_addr (unsigned long offset
,
491 unsigned long (*dmap_register
) (void *regcache
,
496 last_from
= "logical-data";
497 if (offset
>= DMAP_BLOCK_SIZE
* SIM_CR16_NR_DMAP_REGS
)
499 /* Logical address out side of data segments, not supported */
502 regno
= (offset
/ DMAP_BLOCK_SIZE
);
503 offset
= (offset
% DMAP_BLOCK_SIZE
);
506 if ((offset
% DMAP_BLOCK_SIZE
) + nr_bytes
> DMAP_BLOCK_SIZE
)
508 /* Don't cross a BLOCK boundary */
509 nr_bytes
= DMAP_BLOCK_SIZE
- (offset
% DMAP_BLOCK_SIZE
);
511 map
= dmap_register (regcache
, regno
);
514 /* Always maps to data memory */
515 int iospi
= (offset
/ 0x1000) % 4;
516 int iosp
= (map
>> (4 * (3 - iospi
))) % 0x10;
517 last_to
= "io-space";
518 *phys
= (SIM_CR16_MEMORY_DATA
+ (iosp
* 0x10000) + 0xc000 + offset
);
522 int sp
= ((map
& 0x3000) >> 12);
523 int segno
= (map
& 0x3ff);
526 case 0: /* 00: Unified memory */
527 *phys
= SIM_CR16_MEMORY_UNIFIED
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
530 case 1: /* 01: Instruction Memory */
531 *phys
= SIM_CR16_MEMORY_INSN
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
532 last_to
= "chip-insn";
534 case 2: /* 10: Internal data memory */
535 *phys
= SIM_CR16_MEMORY_DATA
+ (segno
<< 16) + (regno
* DMAP_BLOCK_SIZE
) + offset
;
536 last_to
= "chip-data";
538 case 3: /* 11: Reserved */
546 /* Given a virtual address in the IMAP address space, translate it
547 into a physical address. */
550 sim_cr16_translate_imap_addr (unsigned long offset
,
554 unsigned long (*imap_register
) (void *regcache
,
561 last_from
= "logical-insn";
562 if (offset
>= (IMAP_BLOCK_SIZE
* SIM_CR16_NR_IMAP_REGS
))
564 /* Logical address outside of IMAP segments, not supported */
567 regno
= (offset
/ IMAP_BLOCK_SIZE
);
568 offset
= (offset
% IMAP_BLOCK_SIZE
);
569 if (offset
+ nr_bytes
> IMAP_BLOCK_SIZE
)
571 /* Don't cross a BLOCK boundary */
572 nr_bytes
= IMAP_BLOCK_SIZE
- offset
;
574 map
= imap_register (regcache
, regno
);
575 sp
= (map
& 0x3000) >> 12;
576 segno
= (map
& 0x007f);
579 case 0: /* 00: unified memory */
580 *phys
= SIM_CR16_MEMORY_UNIFIED
+ (segno
<< 17) + offset
;
583 case 1: /* 01: instruction memory */
584 *phys
= SIM_CR16_MEMORY_INSN
+ (IMAP_BLOCK_SIZE
* regno
) + offset
;
585 last_to
= "chip-insn";
590 case 3: /* 11: for testing - instruction memory */
591 offset
= (offset
% 0x800);
592 *phys
= SIM_CR16_MEMORY_INSN
+ offset
;
593 if (offset
+ nr_bytes
> 0x800)
594 /* don't cross VM boundary */
595 nr_bytes
= 0x800 - offset
;
596 last_to
= "test-insn";
603 sim_cr16_translate_addr (unsigned long memaddr
,
605 unsigned long *targ_addr
,
607 unsigned long (*dmap_register
) (void *regcache
,
609 unsigned long (*imap_register
) (void *regcache
,
616 last_from
= "unknown";
619 seg
= (memaddr
>> 24);
620 off
= (memaddr
& 0xffffffL
);
622 /* However, if we've asked to use the previous generation of segment
623 mapping, rearrange the segments as follows. */
625 if (old_segment_mapping
)
629 case 0x00: /* DMAP translated memory */
632 case 0x01: /* IMAP translated memory */
635 case 0x10: /* On-chip data memory */
638 case 0x11: /* On-chip insn memory */
641 case 0x12: /* Unified memory */
649 case 0x00: /* Physical unified memory */
650 last_from
= "phys-unified";
652 phys
= SIM_CR16_MEMORY_UNIFIED
+ off
;
653 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
654 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
657 case 0x01: /* Physical instruction memory */
658 last_from
= "phys-insn";
659 last_to
= "chip-insn";
660 phys
= SIM_CR16_MEMORY_INSN
+ off
;
661 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
662 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
665 case 0x02: /* Physical data memory segment */
666 last_from
= "phys-data";
667 last_to
= "chip-data";
668 phys
= SIM_CR16_MEMORY_DATA
+ off
;
669 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
670 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
673 case 0x10: /* in logical data address segment */
674 nr_bytes
= sim_cr16_translate_dmap_addr (off
, nr_bytes
, &phys
, regcache
,
678 case 0x11: /* in logical instruction address segment */
679 nr_bytes
= sim_cr16_translate_imap_addr (off
, nr_bytes
, &phys
, regcache
,
691 /* Return a pointer into the raw buffer designated by phys_addr. It
692 is assumed that the client has already ensured that the access
693 isn't going to cross a segment boundary. */
696 map_memory (unsigned phys_addr
)
701 int segment
= ((phys_addr
>> 24) & 0xff);
706 case 0x00: /* Unified memory */
708 memory
= &State
.mem
.unif
[(phys_addr
/ SEGMENT_SIZE
) % UMEM_SEGMENTS
];
709 last_segname
= "umem";
713 case 0x01: /* On-chip insn memory */
715 memory
= &State
.mem
.insn
[(phys_addr
/ SEGMENT_SIZE
) % IMEM_SEGMENTS
];
716 last_segname
= "imem";
720 case 0x02: /* On-chip data memory */
722 if ((phys_addr
& 0xff00) == 0xff00)
724 phys_addr
= (phys_addr
& 0xffff);
725 if (phys_addr
== DMAP2_SHADDOW
)
727 phys_addr
= DMAP2_OFFSET
;
728 last_segname
= "dmap";
731 last_segname
= "reg";
734 last_segname
= "dmem";
735 memory
= &State
.mem
.data
[(phys_addr
/ SEGMENT_SIZE
) % DMEM_SEGMENTS
];
741 last_segname
= "scrap";
742 return State
.mem
.fault
;
747 *memory
= calloc (1, SEGMENT_SIZE
);
750 (*cr16_callback
->printf_filtered
) (cr16_callback
, "Malloc failed.\n");
751 return State
.mem
.fault
;
755 offset
= (phys_addr
% SEGMENT_SIZE
);
756 raw
= *memory
+ offset
;
760 /* Transfer data to/from simulated memory. Since a bug in either the
761 simulated program or in gdb or the simulator itself may cause a
762 bogus address to be passed in, we need to do some sanity checking
763 on addresses to make sure they are within bounds. When an address
764 fails the bounds check, treat it as a zero length read/write rather
765 than aborting the entire run. */
768 xfer_mem (SIM_ADDR virt
,
769 unsigned char *buffer
,
776 phys_size
= sim_cr16_translate_addr (virt
, size
, &phys
, NULL
,
777 dmap_register
, imap_register
);
781 memory
= map_memory (phys
);
784 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
786 (*cr16_callback
->printf_filtered
)
788 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
789 (write_p
? "write" : "read"),
790 phys_size
, virt
, last_from
,
792 (long) memory
, last_segname
);
798 memcpy (memory
, buffer
, phys_size
);
802 memcpy (buffer
, memory
, phys_size
);
810 sim_write (sd
, addr
, buffer
, size
)
813 unsigned char *buffer
;
816 /* FIXME: this should be performing a virtual transfer */
817 return xfer_mem( addr
, buffer
, size
, 1);
821 sim_read (sd
, addr
, buffer
, size
)
824 unsigned char *buffer
;
827 /* FIXME: this should be performing a virtual transfer */
828 return xfer_mem( addr
, buffer
, size
, 0);
833 sim_open (SIM_OPEN_KIND kind
, struct host_callback_struct
*callback
, struct bfd
*abfd
, char **argv
)
836 static int init_p
= 0;
840 cr16_callback
= callback
;
842 old_segment_mapping
= 0;
844 /* NOTE: This argument parsing is only effective when this function
845 is called by GDB. Standalone argument parsing is handled by
848 for (p
= argv
+ 1; *p
; ++p
)
850 if (strcmp (*p
, "-oldseg") == 0)
851 old_segment_mapping
= 1;
853 else if (strcmp (*p
, "-t") == 0)
855 else if (strncmp (*p
, "-t", 2) == 0)
856 cr16_debug
= atoi (*p
+ 2);
859 (*cr16_callback
->printf_filtered
) (cr16_callback
, "ERROR: unsupported option(s): %s\n",*p
);
863 /* reset the processor state */
864 if (!State
.mem
.data
[0])
866 sim_create_inferior ((SIM_DESC
) 1, NULL
, NULL
, NULL
);
868 /* Fudge our descriptor. */
874 sim_close (sd
, quitting
)
878 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
880 bfd_close (prog_bfd
);
882 prog_bfd_was_opened_p
= 0;
887 sim_set_profile (int n
)
889 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_set_profile %d\n",n
);
893 sim_set_profile_size (int n
)
895 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_set_profile_size %d\n",n
);
899 dmem_addr (uint32 offset
)
905 /* Note: DMEM address range is 0..0x10000. Calling code can compute
906 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
907 is uint16 this is modulo'ed onto 0x0e5d. */
909 phys_size
= sim_cr16_translate_dmap_addr (offset
, 1, &phys
, NULL
,
913 mem
= State
.mem
.fault
;
916 mem
= map_memory (phys
);
918 if ((cr16_debug
& DEBUG_MEMORY
))
920 (*cr16_callback
->printf_filtered
)
922 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
924 phys
, phys_size
, last_to
,
925 (long) mem
, last_segname
);
932 imem_addr (uint32 offset
)
936 int phys_size
= sim_cr16_translate_imap_addr (offset
, 1, &phys
, NULL
,
940 return State
.mem
.fault
;
942 mem
= map_memory (phys
);
944 if ((cr16_debug
& DEBUG_MEMORY
))
946 (*cr16_callback
->printf_filtered
)
948 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
950 phys
, phys_size
, last_to
,
951 (long) mem
, last_segname
);
957 static int stop_simulator
= 0;
968 /* Run (or resume) the program. */
970 sim_resume (SIM_DESC sd
, int step
, int siggnal
)
972 uint32 mask
= 0, ins_found
= 0;
977 // (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
994 JMP (AE_VECTOR_START
);
1000 SET_HW_PSR ((PSR
& (PSR_C_BIT
)));
1001 JMP (RIE_VECTOR_START
);
1005 /* just ignore it */
1011 iaddr
= imem_addr ((uint32
)PC
);
1013 if (iaddr
== State
.mem
.fault
)
1015 State
.exception
= SIGBUS
;
1019 mcode
= get_longword( iaddr
);
1021 State
.pc_changed
= 0;
1023 /* Start searching from end of instruction table. */
1024 const inst
*instruction
= &cr16_instruction
[NUMOPCODES
- 2];
1026 /* Loop over instruction table until a full match is found. */
1027 while (instruction
>= cr16_instruction
)
1029 mask
= (((1 << (32 - instruction
->match_bits
)) -1) <<
1030 instruction
->match_bits
);
1032 /* Adjuest mask for branch with 2 word instructions. */
1033 if ((IS_INSN_MNEMONIC("b") && instruction
->size
== 2))
1036 if ((mcode
& mask
) == (BIN(instruction
->match
, instruction
->match_bits
)))
1046 (*cr16_callback
->printf_filtered
) (cr16_callback
, "INS: PC=0x%X, mcode=0x%X\n",PC
,mcode
);
1048 if ((mcode
== 0x0L
) /*|| (!ins_found )*/)
1050 State
.exception
= SIG_CR16_EXIT
; /* exit trap */
1054 /* Check if the ins_found is '0', then set illigel instruction trap */
1056 State
.exception
= SIGILL
;
1059 /* For 3 word instructions only */
1060 if (instruction
->size
== 3)
1062 iaddr
= imem_addr ((uint32
)PC
+ 2);
1063 mcode
= (mcode
<< 16) | get_longword( iaddr
);
1066 do_run(instruction
, mcode
);
1069 /* If the PC of the current instruction matches RPT_E then
1070 schedule a branch to the loop start. If one of those
1071 instructions happens to be a branch, than that instruction
1073 if (!State
.pc_changed
)
1075 switch (instruction
->size
)
1078 SET_PC (PC
+ 2); /* For 1 word instructions */
1081 SET_PC (PC
+ 4); /* For 2 word instructions */
1084 SET_PC (PC
+ 6); /* For 3 word instructions */
1091 /* Check for a breakpoint trap on this instruction. This
1092 overrides any pending branches or loops */
1094 if (PSR_DB
&& PC
== DBS
)
1098 SET_PC (SDBT_VECTOR_START
);
1102 /* Writeback all the DATA / PC changes */
1105 #ifdef NEED_UI_LOOP_HOOK
1106 if (deprecated_ui_loop_hook
!= NULL
&& ui_loop_hook_counter
-- < 0)
1108 ui_loop_hook_counter
= UI_LOOP_POLL_INTERVAL
;
1109 deprecated_ui_loop_hook (0);
1111 #endif /* NEED_UI_LOOP_HOOK */
1113 while ( !State
.exception
&& !stop_simulator
);
1115 if (step
&& !State
.exception
)
1116 State
.exception
= SIGTRAP
;
1120 sim_set_trace (void)
1128 sim_info (SIM_DESC sd
, int verbose
)
1136 unsigned long left
= ins_type_counters
[ (int)INS_LEFT
] + ins_type_counters
[ (int)INS_LEFT_COND_EXE
];
1137 unsigned long left_nops
= ins_type_counters
[ (int)INS_LEFT_NOPS
];
1138 unsigned long left_parallel
= ins_type_counters
[ (int)INS_LEFT_PARALLEL
];
1139 unsigned long left_cond
= ins_type_counters
[ (int)INS_LEFT_COND_TEST
];
1140 unsigned long left_total
= left
+ left_parallel
+ left_cond
+ left_nops
;
1142 unsigned long right
= ins_type_counters
[ (int)INS_RIGHT
] + ins_type_counters
[ (int)INS_RIGHT_COND_EXE
];
1143 unsigned long right_nops
= ins_type_counters
[ (int)INS_RIGHT_NOPS
];
1144 unsigned long right_parallel
= ins_type_counters
[ (int)INS_RIGHT_PARALLEL
];
1145 unsigned long right_cond
= ins_type_counters
[ (int)INS_RIGHT_COND_TEST
];
1146 unsigned long right_total
= right
+ right_parallel
+ right_cond
+ right_nops
;
1148 unsigned long unknown
= ins_type_counters
[ (int)INS_UNKNOWN
];
1149 unsigned long ins_long
= ins_type_counters
[ (int)INS_LONG
];
1150 unsigned long parallel
= ins_type_counters
[ (int)INS_PARALLEL
];
1151 unsigned long leftright
= ins_type_counters
[ (int)INS_LEFTRIGHT
];
1152 unsigned long rightleft
= ins_type_counters
[ (int)INS_RIGHTLEFT
];
1153 unsigned long cond_true
= ins_type_counters
[ (int)INS_COND_TRUE
];
1154 unsigned long cond_false
= ins_type_counters
[ (int)INS_COND_FALSE
];
1155 unsigned long cond_jump
= ins_type_counters
[ (int)INS_COND_JUMP
];
1156 unsigned long cycles
= ins_type_counters
[ (int)INS_CYCLES
];
1157 unsigned long total
= (unknown
+ left_total
+ right_total
+ ins_long
);
1159 int size
= strlen (add_commas (buf1
, sizeof (buf1
), total
));
1160 int parallel_size
= strlen (add_commas (buf1
, sizeof (buf1
),
1161 (left_parallel
> right_parallel
) ? left_parallel
: right_parallel
));
1162 int cond_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_cond
> right_cond
) ? left_cond
: right_cond
));
1163 int nop_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_nops
> right_nops
) ? left_nops
: right_nops
));
1164 int normal_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left
> right
) ? left
: right
));
1166 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1167 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1168 size
, add_commas (buf1
, sizeof (buf1
), left_total
),
1169 normal_size
, add_commas (buf2
, sizeof (buf2
), left
),
1170 parallel_size
, add_commas (buf3
, sizeof (buf3
), left_parallel
),
1171 cond_size
, add_commas (buf4
, sizeof (buf4
), left_cond
),
1172 nop_size
, add_commas (buf5
, sizeof (buf5
), left_nops
));
1174 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1175 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1176 size
, add_commas (buf1
, sizeof (buf1
), right_total
),
1177 normal_size
, add_commas (buf2
, sizeof (buf2
), right
),
1178 parallel_size
, add_commas (buf3
, sizeof (buf3
), right_parallel
),
1179 cond_size
, add_commas (buf4
, sizeof (buf4
), right_cond
),
1180 nop_size
, add_commas (buf5
, sizeof (buf5
), right_nops
));
1183 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1184 "executed %*s long instruction(s)\n",
1185 size
, add_commas (buf1
, sizeof (buf1
), ins_long
));
1188 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1189 "executed %*s parallel instruction(s)\n",
1190 size
, add_commas (buf1
, sizeof (buf1
), parallel
));
1193 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1194 "executed %*s instruction(s) encoded L->R\n",
1195 size
, add_commas (buf1
, sizeof (buf1
), leftright
));
1198 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1199 "executed %*s instruction(s) encoded R->L\n",
1200 size
, add_commas (buf1
, sizeof (buf1
), rightleft
));
1203 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1204 "executed %*s unknown instruction(s)\n",
1205 size
, add_commas (buf1
, sizeof (buf1
), unknown
));
1208 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1209 "executed %*s instruction(s) due to EXExxx condition being true\n",
1210 size
, add_commas (buf1
, sizeof (buf1
), cond_true
));
1213 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1214 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1215 size
, add_commas (buf1
, sizeof (buf1
), cond_false
));
1218 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1219 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1220 size
, add_commas (buf1
, sizeof (buf1
), cond_jump
));
1222 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1223 "executed %*s cycle(s)\n",
1224 size
, add_commas (buf1
, sizeof (buf1
), cycles
));
1226 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1227 "executed %*s total instructions\n",
1228 size
, add_commas (buf1
, sizeof (buf1
), total
));
1233 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
, char **argv
, char **env
)
1235 bfd_vma start_address
;
1237 /* reset all state information */
1238 memset (&State
.regs
, 0, (int)&State
.mem
- (int)&State
.regs
);
1240 /* There was a hack here to copy the values of argc and argv into r0
1241 and r1. The values were also saved into some high memory that
1242 won't be overwritten by the stack (0x7C00). The reason for doing
1243 this was to allow the 'run' program to accept arguments. Without
1244 the hack, this is not possible anymore. If the simulator is run
1245 from the debugger, arguments cannot be passed in, so this makes
1250 start_address
= bfd_get_start_address (abfd
);
1252 start_address
= 0x0;
1255 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_create_inferior: PC=0x%lx\n", (long) start_address
);
1257 SET_CREG (PC_CR
, start_address
);
1265 sim_set_callbacks (p
)
1272 sim_stop_reason (sd
, reason
, sigrc
)
1274 enum sim_stop
*reason
;
1277 /* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1279 switch (State
.exception
)
1281 case SIG_CR16_STOP
: /* stop instruction */
1282 *reason
= sim_stopped
;
1286 case SIG_CR16_EXIT
: /* exit trap */
1287 *reason
= sim_exited
;
1292 *reason
= sim_stopped
;
1293 *sigrc
= TARGET_SIGNAL_BUS
;
1296 // case SIG_CR16_IAD:
1297 // *reason = sim_stopped;
1298 // *sigrc = TARGET_SIGNAL_IAD;
1301 default: /* some signal */
1302 *reason
= sim_stopped
;
1303 if (stop_simulator
&& !State
.exception
)
1304 *sigrc
= TARGET_SIGNAL_INT
;
1306 *sigrc
= State
.exception
;
1314 sim_fetch_register (sd
, rn
, memory
, length
)
1317 unsigned char *memory
;
1321 switch ((enum sim_cr16_regs
) rn
)
1323 case SIM_CR16_R0_REGNUM
:
1324 case SIM_CR16_R1_REGNUM
:
1325 case SIM_CR16_R2_REGNUM
:
1326 case SIM_CR16_R3_REGNUM
:
1327 case SIM_CR16_R4_REGNUM
:
1328 case SIM_CR16_R5_REGNUM
:
1329 case SIM_CR16_R6_REGNUM
:
1330 case SIM_CR16_R7_REGNUM
:
1331 case SIM_CR16_R8_REGNUM
:
1332 case SIM_CR16_R9_REGNUM
:
1333 case SIM_CR16_R10_REGNUM
:
1334 case SIM_CR16_R11_REGNUM
:
1335 WRITE_16 (memory
, GPR (rn
- SIM_CR16_R0_REGNUM
));
1338 case SIM_CR16_R12_REGNUM
:
1339 case SIM_CR16_R13_REGNUM
:
1340 case SIM_CR16_R14_REGNUM
:
1341 case SIM_CR16_R15_REGNUM
:
1342 //WRITE_32 (memory, GPR (rn - SIM_CR16_R0_REGNUM));
1343 write_longword (memory
, GPR (rn
- SIM_CR16_R0_REGNUM
));
1346 case SIM_CR16_PC_REGNUM
:
1347 case SIM_CR16_ISP_REGNUM
:
1348 case SIM_CR16_USP_REGNUM
:
1349 case SIM_CR16_INTBASE_REGNUM
:
1350 case SIM_CR16_PSR_REGNUM
:
1351 case SIM_CR16_CFG_REGNUM
:
1352 case SIM_CR16_DBS_REGNUM
:
1353 case SIM_CR16_DCR_REGNUM
:
1354 case SIM_CR16_DSR_REGNUM
:
1355 case SIM_CR16_CAR0_REGNUM
:
1356 case SIM_CR16_CAR1_REGNUM
:
1357 //WRITE_32 (memory, CREG (rn - SIM_CR16_PC_REGNUM));
1358 write_longword (memory
, CREG (rn
- SIM_CR16_PC_REGNUM
));
1369 sim_store_register (sd
, rn
, memory
, length
)
1372 unsigned char *memory
;
1376 switch ((enum sim_cr16_regs
) rn
)
1378 case SIM_CR16_R0_REGNUM
:
1379 case SIM_CR16_R1_REGNUM
:
1380 case SIM_CR16_R2_REGNUM
:
1381 case SIM_CR16_R3_REGNUM
:
1382 case SIM_CR16_R4_REGNUM
:
1383 case SIM_CR16_R5_REGNUM
:
1384 case SIM_CR16_R6_REGNUM
:
1385 case SIM_CR16_R7_REGNUM
:
1386 case SIM_CR16_R8_REGNUM
:
1387 case SIM_CR16_R9_REGNUM
:
1388 case SIM_CR16_R10_REGNUM
:
1389 case SIM_CR16_R11_REGNUM
:
1390 SET_GPR (rn
- SIM_CR16_R0_REGNUM
, READ_16 (memory
));
1393 case SIM_CR16_R12_REGNUM
:
1394 case SIM_CR16_R13_REGNUM
:
1395 case SIM_CR16_R14_REGNUM
:
1396 case SIM_CR16_R15_REGNUM
:
1397 SET_GPR32 (rn
- SIM_CR16_R0_REGNUM
, get_longword (memory
));
1400 case SIM_CR16_PC_REGNUM
:
1401 case SIM_CR16_ISP_REGNUM
:
1402 case SIM_CR16_USP_REGNUM
:
1403 case SIM_CR16_INTBASE_REGNUM
:
1404 case SIM_CR16_PSR_REGNUM
:
1405 case SIM_CR16_CFG_REGNUM
:
1406 case SIM_CR16_DBS_REGNUM
:
1407 case SIM_CR16_DCR_REGNUM
:
1408 case SIM_CR16_DSR_REGNUM
:
1409 case SIM_CR16_CAR0_REGNUM
:
1410 case SIM_CR16_CAR1_REGNUM
:
1411 SET_CREG (rn
- SIM_CR16_PC_REGNUM
, get_longword (memory
));
1424 sim_do_command (sd
, cmd
)
1428 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_do_command: %s\n",cmd
);
1432 sim_load (SIM_DESC sd
, char *prog
, struct bfd
*abfd
, int from_tty
)
1434 extern bfd
*sim_load_file (); /* ??? Don't know where this should live. */
1436 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
1438 bfd_close (prog_bfd
);
1439 prog_bfd_was_opened_p
= 0;
1441 prog_bfd
= sim_load_file (sd
, myname
, cr16_callback
, prog
, abfd
,
1442 sim_kind
== SIM_OPEN_DEBUG
,
1443 1/*LMA*/, sim_write
);
1444 if (prog_bfd
== NULL
)
1446 prog_bfd_was_opened_p
= abfd
== NULL
;
This page took 0.062619 seconds and 4 git commands to generate.