1 /* Simulation code for the CR16 processor.
2 Copyright (C) 2008, 2009, 2010 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 struct hash_entry
*lookup_hash
PARAMS ((uint64 ins
, int size
));
54 static void get_operands
PARAMS ((operand_desc
*s
, uint64 mcode
, int isize
, int nops
));
55 static int do_run
PARAMS ((uint64 mc
));
56 static char *add_commas
PARAMS ((char *buf
, int sizeof_buf
, unsigned long value
));
57 extern void sim_set_profile
PARAMS ((int n
));
58 extern void sim_set_profile_size
PARAMS ((int n
));
59 static INLINE uint8
*map_memory (unsigned phys_addr
);
61 #ifdef NEED_UI_LOOP_HOOK
62 /* How often to run the ui_loop update, when in use */
63 #define UI_LOOP_POLL_INTERVAL 0x14000
65 /* Counter for the ui_loop_hook update */
66 static long ui_loop_hook_counter
= UI_LOOP_POLL_INTERVAL
;
68 /* Actual hook to call to run through gdb's gui event loop */
69 extern int (*deprecated_ui_loop_hook
) PARAMS ((int signo
));
70 #endif /* NEED_UI_LOOP_HOOK */
73 #if defined(__GNUC__) && defined(__OPTIMIZE__)
74 #define INLINE __inline__
83 struct hash_entry
*next
;
91 struct hash_entry hash_table
[MAX_HASH
+1];
94 hash(unsigned long long insn
, int format
)
96 unsigned int i
= 4, tmp
;
99 while ((insn
>> i
) != 0) i
+=4;
101 return ((insn
>> (i
-4)) & 0xf); /* Use last 4 bits as hask key. */
103 return ((insn
& 0xF)); /* Use last 4 bits as hask key. */
107 INLINE
static struct hash_entry
*
108 lookup_hash (uint64 ins
, int size
)
111 struct hash_entry
*h
;
113 h
= &hash_table
[hash(ins
,1)];
116 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
118 /* Adjuest mask for branch with 2 word instructions. */
119 if ((h
->ops
->mnimonic
!= NULL
) &&
120 ((streq(h
->ops
->mnimonic
,"b") && h
->size
== 2)))
124 while ((ins
& mask
) != (BIN(h
->opcode
, h
->mask
)))
128 State
.exception
= SIGILL
;
129 State
.pc_changed
= 1; /* Don't increment the PC. */
134 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
135 /* Adjuest mask for branch with 2 word instructions. */
136 if ((streq(h
->ops
->mnimonic
,"b")) && h
->size
== 2)
144 get_operands (operand_desc
*s
, uint64 ins
, int isize
, int nops
)
146 uint32 i
, opn
= 0, start_bit
= 0, op_type
= 0;
147 int32 op_size
= 0, mask
= 0;
149 if (isize
== 1) /* Trunkcate the extra 16 bits of INS. */
152 for (i
=0; i
< 4; ++i
,++opn
)
154 if (s
[opn
].op_type
== dummy
) break;
156 op_type
= s
[opn
].op_type
;
157 start_bit
= s
[opn
].shift
;
158 op_size
= cr16_optab
[op_type
].bit_size
;
162 case imm3
: case imm4
: case imm5
: case imm6
:
165 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
167 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));
169 if (OP
[i
] & ((long)1 << (op_size
-1)))
172 OP
[i
] = ~(OP
[i
]) + 1;
174 OP
[i
] = (unsigned long int)(OP
[i
] & (((long)1 << op_size
) -1));
178 case uimm3
: case uimm3_1
: case uimm4_1
:
182 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1)); break;
184 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));break;
185 default: /* for case 3. */
186 OP
[i
] = ((ins
>> (16 + start_bit
)) & ((1 << op_size
) -1)); break;
196 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
198 OP
[i
] = (ins
& ((1 << op_size
) -1));
201 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
204 OP
[i
] = ((ins
>> (start_bit
+ 16)) & ((1 << op_size
) -1));
207 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
212 case imm16
: case uimm16
:
213 OP
[i
] = ins
& 0xFFFF;
216 case uimm20
: case imm20
:
217 OP
[i
] = ins
& (((long)1 << op_size
) - 1);
220 case imm32
: case uimm32
:
221 OP
[i
] = ins
& 0xFFFFFFFF;
224 case uimm5
: break; /*NOT USED. */
225 OP
[i
] = ins
& ((1 << op_size
) - 1); break;
228 OP
[i
] = (ins
>> 4) & ((1 << 4) - 1);
229 OP
[i
] = (OP
[i
] * 2) + 2;
230 if (OP
[i
] & ((long)1 << 5))
233 OP
[i
] = ~(OP
[i
]) + 1;
234 OP
[i
] = (unsigned long int)(OP
[i
] & 0x1F);
239 OP
[i
] = ((((ins
>> 8) & 0xf) << 4) | (ins
& 0xf));
241 if (OP
[i
] & ((long)1 << 8))
244 OP
[i
] = ~(OP
[i
]) + 1;
245 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFF);
250 OP
[i
] = (ins
& 0xFFFF);
253 OP
[i
] = (OP
[i
] & 0xFFFE);
255 OP
[i
] = ~(OP
[i
]) + 1;
256 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFF);
262 OP
[i
] = (ins
& 0xFFFFFF);
264 OP
[i
] = (ins
& 0xFFFF) | (((ins
>> 24) & 0xf) << 16) |
265 (((ins
>> 16) & 0xf) << 20);
269 OP
[i
] = (OP
[i
] & 0xFFFFFE);
271 OP
[i
] = ~(OP
[i
]) + 1;
272 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFFFF);
278 OP
[i
] = (ins
) & 0xFFFFF;
280 OP
[i
] = (ins
>> start_bit
) & 0xFFFFF;
284 OP
[i
] = ((ins
& 0xFFFF) | (((ins
>> 16) & 0xf) << 20)
285 | (((ins
>> 24) & 0xf) << 16));
287 OP
[i
] = (ins
>> 16) & 0xFFFFFF;
291 case rbase
: break; /* NOT USED. */
292 case rbase_disps20
: case rbase_dispe20
:
293 case rpbase_disps20
: case rpindex_disps20
:
294 OP
[i
] = ((((ins
>> 24)&0xf) << 16)|((ins
) & 0xFFFF));
295 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
298 OP
[i
] = 0; /* 4 bit disp const. */
299 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
302 OP
[i
] = ((ins
>> 8) & 0xF) * 2; /* 4 bit disp const. */
303 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
306 OP
[i
] = ((ins
>> 8) & 0xF); /* 4 bit disp const. */
307 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
310 OP
[i
] = (ins
) & 0xFFFF;
311 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
315 OP
[++i
] = (ins
>> 4) & 0xF; /* get 4 bit for reg. */
316 OP
[++i
] = (ins
>> 8) & 0x1; /* get 1 bit for index-reg. */
318 case rpindex_disps14
:
319 OP
[i
] = (ins
) & 0x3FFF;
320 OP
[++i
] = (ins
>> 14) & 0x1; /* get 1 bit for index-reg. */
321 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
324 OP
[i
] = (ins
) & 0xFFFFF;
325 OP
[++i
] = (ins
>> 24) & 0x1; /* get 1 bit for index-reg. */
326 OP
[++i
] = (ins
>> 20) & 0xF; /* get 4 bit for reg. */
328 case regr
: case regp
: case pregr
: case pregrp
:
332 if (start_bit
== 20) OP
[i
] = (ins
>> 4) & 0xF;
333 else if (start_bit
== 16) OP
[i
] = ins
& 0xF;
335 case 2: OP
[i
] = (ins
>> start_bit
) & 0xF; break;
336 case 3: OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF; break;
341 if (isize
== 1) OP
[i
] = (ins
>> 4) & 0xF;
342 else if (isize
== 2) OP
[i
] = (ins
>> start_bit
) & 0xF;
343 else OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF;
349 /* For ESC on uimm4_1 operand. */
350 if (op_type
== uimm4_1
)
354 /* For increment by 1. */
355 if ((op_type
== pregr
) || (op_type
== pregrp
))
358 /* FIXME: for tracing, update values that need to be updated each
359 instruction decode cycle */
360 State
.trace
.psw
= PSR
;
367 if (!init_text_p
&& prog_bfd
!= NULL
)
370 for (s
= prog_bfd
->sections
; s
; s
= s
->next
)
371 if (strcmp (bfd_get_section_name (prog_bfd
, s
), ".text") == 0)
374 text_start
= bfd_get_section_vma (prog_bfd
, s
);
375 text_end
= text_start
+ bfd_section_size (prog_bfd
, s
);
380 return (PC
) + text_start
;
388 struct simops
*s
= Simops
;
389 struct hash_entry
*h
;
393 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
394 (*cr16_callback
->printf_filtered
) (cr16_callback
, "do_long 0x%x\n", mcode
);
397 h
= lookup_hash(mcode
, 1);
399 if ((h
== NULL
) || (h
->opcode
== NULL
)) return 0;
403 iaddr
= imem_addr ((uint32
)PC
+ 2);
404 mcode
= (mcode
<< 16) | get_longword( iaddr
);
407 /* Re-set OP list. */
408 OP
[0] = OP
[1] = OP
[2] = OP
[3] = sign_flag
= 0;
410 /* for push/pop/pushrtn with RA instructions. */
411 if ((h
->format
& REG_LIST
) && (mcode
& 0x800000))
412 OP
[2] = 1; /* Set 1 for RA operand. */
414 /* numops == 0 means, no operands. */
415 if (((h
->ops
) != NULL
) && (((h
->ops
)->numops
) != 0))
416 get_operands ((h
->ops
)->operands
, mcode
, h
->size
, (h
->ops
)->numops
);
418 //State.ins_type = h->flags;
426 add_commas(char *buf
, int sizeof_buf
, unsigned long value
)
429 char *endbuf
= buf
+ sizeof_buf
- 1;
439 *--endbuf
= (value
% 10) + '0';
440 } while ((value
/= 10) != 0);
449 for (i
= 0; i
< IMEM_SEGMENTS
; i
++)
451 if (State
.mem
.insn
[i
])
452 free (State
.mem
.insn
[i
]);
454 for (i
= 0; i
< DMEM_SEGMENTS
; i
++)
456 if (State
.mem
.data
[i
])
457 free (State
.mem
.data
[i
]);
459 for (i
= 0; i
< UMEM_SEGMENTS
; i
++)
461 if (State
.mem
.unif
[i
])
462 free (State
.mem
.unif
[i
]);
464 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
466 State
.mem
.data
[0] = calloc (1, SEGMENT_SIZE
);
469 /* For tracing - leave info on last access around. */
470 static char *last_segname
= "invalid";
471 static char *last_from
= "invalid";
472 static char *last_to
= "invalid";
476 IMAP0_OFFSET
= 0xff00,
477 DMAP0_OFFSET
= 0xff08,
478 DMAP2_SHADDOW
= 0xff04,
479 DMAP2_OFFSET
= 0xff0c
483 set_dmap_register (int reg_nr
, unsigned long value
)
485 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
486 + DMAP0_OFFSET
+ 2 * reg_nr
);
487 WRITE_16 (raw
, value
);
489 if ((cr16_debug
& DEBUG_MEMORY
))
491 (*cr16_callback
->printf_filtered
)
492 (cr16_callback
, "mem: dmap%d=0x%04lx\n", reg_nr
, value
);
498 dmap_register (void *regcache
, int reg_nr
)
500 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
501 + DMAP0_OFFSET
+ 2 * reg_nr
);
502 return READ_16 (raw
);
506 set_imap_register (int reg_nr
, unsigned long value
)
508 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
509 + IMAP0_OFFSET
+ 2 * reg_nr
);
510 WRITE_16 (raw
, value
);
512 if ((cr16_debug
& DEBUG_MEMORY
))
514 (*cr16_callback
->printf_filtered
)
515 (cr16_callback
, "mem: imap%d=0x%04lx\n", reg_nr
, value
);
521 imap_register (void *regcache
, int reg_nr
)
523 uint8
*raw
= map_memory (SIM_CR16_MEMORY_DATA
524 + IMAP0_OFFSET
+ 2 * reg_nr
);
525 return READ_16 (raw
);
547 set_spi_register (unsigned long value
)
549 SET_GPR (SP_IDX
, value
);
553 set_spu_register (unsigned long value
)
555 SET_GPR (SP_IDX
, value
);
558 /* Given a virtual address in the DMAP address space, translate it
559 into a physical address. */
562 sim_cr16_translate_dmap_addr (unsigned long offset
,
566 unsigned long (*dmap_register
) (void *regcache
,
571 last_from
= "logical-data";
572 if (offset
>= DMAP_BLOCK_SIZE
* SIM_CR16_NR_DMAP_REGS
)
574 /* Logical address out side of data segments, not supported */
577 regno
= (offset
/ DMAP_BLOCK_SIZE
);
578 offset
= (offset
% DMAP_BLOCK_SIZE
);
581 if ((offset
% DMAP_BLOCK_SIZE
) + nr_bytes
> DMAP_BLOCK_SIZE
)
583 /* Don't cross a BLOCK boundary */
584 nr_bytes
= DMAP_BLOCK_SIZE
- (offset
% DMAP_BLOCK_SIZE
);
586 map
= dmap_register (regcache
, regno
);
589 /* Always maps to data memory */
590 int iospi
= (offset
/ 0x1000) % 4;
591 int iosp
= (map
>> (4 * (3 - iospi
))) % 0x10;
592 last_to
= "io-space";
593 *phys
= (SIM_CR16_MEMORY_DATA
+ (iosp
* 0x10000) + 0xc000 + offset
);
597 int sp
= ((map
& 0x3000) >> 12);
598 int segno
= (map
& 0x3ff);
601 case 0: /* 00: Unified memory */
602 *phys
= SIM_CR16_MEMORY_UNIFIED
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
605 case 1: /* 01: Instruction Memory */
606 *phys
= SIM_CR16_MEMORY_INSN
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
607 last_to
= "chip-insn";
609 case 2: /* 10: Internal data memory */
610 *phys
= SIM_CR16_MEMORY_DATA
+ (segno
<< 16) + (regno
* DMAP_BLOCK_SIZE
) + offset
;
611 last_to
= "chip-data";
613 case 3: /* 11: Reserved */
621 /* Given a virtual address in the IMAP address space, translate it
622 into a physical address. */
625 sim_cr16_translate_imap_addr (unsigned long offset
,
629 unsigned long (*imap_register
) (void *regcache
,
636 last_from
= "logical-insn";
637 if (offset
>= (IMAP_BLOCK_SIZE
* SIM_CR16_NR_IMAP_REGS
))
639 /* Logical address outside of IMAP segments, not supported */
642 regno
= (offset
/ IMAP_BLOCK_SIZE
);
643 offset
= (offset
% IMAP_BLOCK_SIZE
);
644 if (offset
+ nr_bytes
> IMAP_BLOCK_SIZE
)
646 /* Don't cross a BLOCK boundary */
647 nr_bytes
= IMAP_BLOCK_SIZE
- offset
;
649 map
= imap_register (regcache
, regno
);
650 sp
= (map
& 0x3000) >> 12;
651 segno
= (map
& 0x007f);
654 case 0: /* 00: unified memory */
655 *phys
= SIM_CR16_MEMORY_UNIFIED
+ (segno
<< 17) + offset
;
658 case 1: /* 01: instruction memory */
659 *phys
= SIM_CR16_MEMORY_INSN
+ (IMAP_BLOCK_SIZE
* regno
) + offset
;
660 last_to
= "chip-insn";
665 case 3: /* 11: for testing - instruction memory */
666 offset
= (offset
% 0x800);
667 *phys
= SIM_CR16_MEMORY_INSN
+ offset
;
668 if (offset
+ nr_bytes
> 0x800)
669 /* don't cross VM boundary */
670 nr_bytes
= 0x800 - offset
;
671 last_to
= "test-insn";
678 sim_cr16_translate_addr (unsigned long memaddr
, int nr_bytes
,
679 unsigned long *targ_addr
, void *regcache
,
680 unsigned long (*dmap_register
) (void *regcache
,
682 unsigned long (*imap_register
) (void *regcache
,
689 last_from
= "unknown";
692 seg
= (memaddr
>> 24);
693 off
= (memaddr
& 0xffffffL
);
695 /* However, if we've asked to use the previous generation of segment
696 mapping, rearrange the segments as follows. */
698 if (old_segment_mapping
)
702 case 0x00: /* DMAP translated memory */
705 case 0x01: /* IMAP translated memory */
708 case 0x10: /* On-chip data memory */
711 case 0x11: /* On-chip insn memory */
714 case 0x12: /* Unified memory */
722 case 0x00: /* Physical unified memory */
723 last_from
= "phys-unified";
725 phys
= SIM_CR16_MEMORY_UNIFIED
+ off
;
726 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
727 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
730 case 0x01: /* Physical instruction memory */
731 last_from
= "phys-insn";
732 last_to
= "chip-insn";
733 phys
= SIM_CR16_MEMORY_INSN
+ off
;
734 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
735 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
738 case 0x02: /* Physical data memory segment */
739 last_from
= "phys-data";
740 last_to
= "chip-data";
741 phys
= SIM_CR16_MEMORY_DATA
+ off
;
742 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
743 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
746 case 0x10: /* in logical data address segment */
747 nr_bytes
= sim_cr16_translate_dmap_addr (off
, nr_bytes
, &phys
, regcache
,
751 case 0x11: /* in logical instruction address segment */
752 nr_bytes
= sim_cr16_translate_imap_addr (off
, nr_bytes
, &phys
, regcache
,
764 /* Return a pointer into the raw buffer designated by phys_addr. It
765 is assumed that the client has already ensured that the access
766 isn't going to cross a segment boundary. */
769 map_memory (unsigned phys_addr
)
774 int segment
= ((phys_addr
>> 24) & 0xff);
779 case 0x00: /* Unified memory */
781 memory
= &State
.mem
.unif
[(phys_addr
/ SEGMENT_SIZE
) % UMEM_SEGMENTS
];
782 last_segname
= "umem";
786 case 0x01: /* On-chip insn memory */
788 memory
= &State
.mem
.insn
[(phys_addr
/ SEGMENT_SIZE
) % IMEM_SEGMENTS
];
789 last_segname
= "imem";
793 case 0x02: /* On-chip data memory */
795 if ((phys_addr
& 0xff00) == 0xff00)
797 phys_addr
= (phys_addr
& 0xffff);
798 if (phys_addr
== DMAP2_SHADDOW
)
800 phys_addr
= DMAP2_OFFSET
;
801 last_segname
= "dmap";
804 last_segname
= "reg";
807 last_segname
= "dmem";
808 memory
= &State
.mem
.data
[(phys_addr
/ SEGMENT_SIZE
) % DMEM_SEGMENTS
];
814 last_segname
= "scrap";
815 return State
.mem
.fault
;
820 *memory
= calloc (1, SEGMENT_SIZE
);
823 (*cr16_callback
->printf_filtered
) (cr16_callback
, "Malloc failed.\n");
824 return State
.mem
.fault
;
828 offset
= (phys_addr
% SEGMENT_SIZE
);
829 raw
= *memory
+ offset
;
833 /* Transfer data to/from simulated memory. Since a bug in either the
834 simulated program or in gdb or the simulator itself may cause a
835 bogus address to be passed in, we need to do some sanity checking
836 on addresses to make sure they are within bounds. When an address
837 fails the bounds check, treat it as a zero length read/write rather
838 than aborting the entire run. */
841 xfer_mem (SIM_ADDR virt
,
842 unsigned char *buffer
,
849 phys_size
= sim_cr16_translate_addr (virt
, size
, &phys
, NULL
,
850 dmap_register
, imap_register
);
854 memory
= map_memory (phys
);
857 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
859 (*cr16_callback
->printf_filtered
)
861 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
862 (write_p
? "write" : "read"),
863 phys_size
, virt
, last_from
,
865 (long) memory
, last_segname
);
871 memcpy (memory
, buffer
, phys_size
);
875 memcpy (buffer
, memory
, phys_size
);
883 sim_write (sd
, addr
, buffer
, size
)
886 const unsigned char *buffer
;
889 /* FIXME: this should be performing a virtual transfer */
890 return xfer_mem( addr
, buffer
, size
, 1);
894 sim_read (sd
, addr
, buffer
, size
)
897 unsigned char *buffer
;
900 /* FIXME: this should be performing a virtual transfer */
901 return xfer_mem( addr
, buffer
, size
, 0);
905 sim_open (SIM_OPEN_KIND kind
, struct host_callback_struct
*callback
, struct bfd
*abfd
, char **argv
)
908 struct hash_entry
*h
;
909 static int init_p
= 0;
913 cr16_callback
= callback
;
915 old_segment_mapping
= 0;
917 /* NOTE: This argument parsing is only effective when this function
918 is called by GDB. Standalone argument parsing is handled by
921 for (p
= argv
+ 1; *p
; ++p
)
923 if (strcmp (*p
, "-oldseg") == 0)
924 old_segment_mapping
= 1;
926 else if (strcmp (*p
, "-t") == 0)
928 else if (strncmp (*p
, "-t", 2) == 0)
929 cr16_debug
= atoi (*p
+ 2);
932 (*cr16_callback
->printf_filtered
) (cr16_callback
, "ERROR: unsupported option(s): %s\n",*p
);
936 /* put all the opcodes in the hash table. */
939 for (s
= Simops
; s
->func
; s
++)
944 h
= &hash_table
[hash(s
->opcode
, 0)];
948 if (((s
->opcode
<< 1) >> 4) != 0)
949 h
= &hash_table
[hash((s
->opcode
<< 1) >> 4, 0)];
951 h
= &hash_table
[hash((s
->opcode
<< 1), 0)];
955 if ((s
->opcode
>> 4) != 0)
956 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
958 h
= &hash_table
[hash(s
->opcode
, 0)];
962 if (((s
->opcode
>> 1) >> 4) != 0)
963 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
965 h
= &hash_table
[hash((s
->opcode
>> 1), 0)];
969 if ((s
->opcode
>> 8) != 0)
970 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
971 else if ((s
->opcode
>> 4) != 0)
972 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
974 h
= &hash_table
[hash(s
->opcode
, 0)];
978 if ((s
->opcode
>> 8) != 0)
979 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
980 else if ((s
->opcode
>> 4) != 0)
981 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
983 h
= &hash_table
[hash(s
->opcode
, 0)];
987 if (((s
->opcode
>> 1) >> 8) != 0)
988 h
= &hash_table
[hash((s
->opcode
>>1) >> 8, 0)];
989 else if (((s
->opcode
>> 1) >> 4) != 0)
990 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
992 h
= &hash_table
[hash((s
->opcode
>>1), 0)];
996 if ((s
->opcode
>> 0xc) != 0)
997 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
998 else if ((s
->opcode
>> 8) != 0)
999 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
1000 else if ((s
->opcode
>> 4) != 0)
1001 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
1003 h
= &hash_table
[hash(s
->opcode
, 0)];
1007 if ((s
->opcode
>> 16) != 0)
1008 h
= &hash_table
[hash(s
->opcode
>> 16, 0)];
1009 else if ((s
->opcode
>> 12) != 0)
1010 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
1011 else if ((s
->opcode
>> 8) != 0)
1012 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
1013 else if ((s
->opcode
>> 4) != 0)
1014 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
1016 h
= &hash_table
[hash(s
->opcode
, 0)];
1022 /* go to the last entry in the chain. */
1028 h
->next
= (struct hash_entry
*) calloc(1,sizeof(struct hash_entry
));
1030 perror ("malloc failure");
1036 h
->opcode
= s
->opcode
;
1037 h
->format
= s
->format
;
1042 /* reset the processor state */
1043 if (!State
.mem
.data
[0])
1045 sim_create_inferior ((SIM_DESC
) 1, NULL
, NULL
, NULL
);
1047 /* Fudge our descriptor. */
1048 return (SIM_DESC
) 1;
1053 sim_close (sd
, quitting
)
1057 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
1059 bfd_close (prog_bfd
);
1061 prog_bfd_was_opened_p
= 0;
1066 sim_set_profile (int n
)
1068 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_set_profile %d\n",n
);
1072 sim_set_profile_size (int n
)
1074 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_set_profile_size %d\n",n
);
1078 dmem_addr (uint32 offset
)
1084 /* Note: DMEM address range is 0..0x10000. Calling code can compute
1085 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
1086 is uint16 this is modulo'ed onto 0x0e5d. */
1088 phys_size
= sim_cr16_translate_dmap_addr (offset
, 1, &phys
, NULL
,
1092 mem
= State
.mem
.fault
;
1095 mem
= map_memory (phys
);
1097 if ((cr16_debug
& DEBUG_MEMORY
))
1099 (*cr16_callback
->printf_filtered
)
1101 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1103 phys
, phys_size
, last_to
,
1104 (long) mem
, last_segname
);
1111 imem_addr (uint32 offset
)
1115 int phys_size
= sim_cr16_translate_imap_addr (offset
, 1, &phys
, NULL
,
1119 return State
.mem
.fault
;
1121 mem
= map_memory (phys
);
1123 if ((cr16_debug
& DEBUG_MEMORY
))
1125 (*cr16_callback
->printf_filtered
)
1127 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1129 phys
, phys_size
, last_to
,
1130 (long) mem
, last_segname
);
1136 static int stop_simulator
= 0;
1147 /* Run (or resume) the program. */
1149 sim_resume (SIM_DESC sd
, int step
, int siggnal
)
1151 uint32 curr_ins_size
= 0;
1156 // (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
1159 State
.exception
= 0;
1173 JMP (AE_VECTOR_START
);
1179 SET_HW_PSR ((PSR
& (PSR_C_BIT
)));
1180 JMP (RIE_VECTOR_START
);
1184 /* just ignore it */
1190 iaddr
= imem_addr ((uint32
)PC
);
1191 if (iaddr
== State
.mem
.fault
)
1193 State
.exception
= SIGBUS
;
1197 mcode
= get_longword( iaddr
);
1199 State
.pc_changed
= 0;
1201 curr_ins_size
= do_run(mcode
);
1204 (*cr16_callback
->printf_filtered
) (cr16_callback
, "INS: PC=0x%X, mcode=0x%X\n",PC
,mcode
);
1207 if (!State
.pc_changed
)
1209 if (curr_ins_size
== 0)
1211 State
.exception
= SIG_CR16_EXIT
; /* exit trap */
1215 SET_PC (PC
+ (curr_ins_size
* 2)); /* For word instructions. */
1219 /* Check for a breakpoint trap on this instruction. This
1220 overrides any pending branches or loops */
1221 if (PSR_DB
&& PC
== DBS
)
1225 SET_PC (SDBT_VECTOR_START
);
1229 /* Writeback all the DATA / PC changes */
1232 #ifdef NEED_UI_LOOP_HOOK
1233 if (deprecated_ui_loop_hook
!= NULL
&& ui_loop_hook_counter
-- < 0)
1235 ui_loop_hook_counter
= UI_LOOP_POLL_INTERVAL
;
1236 deprecated_ui_loop_hook (0);
1238 #endif /* NEED_UI_LOOP_HOOK */
1240 while ( !State
.exception
&& !stop_simulator
);
1242 if (step
&& !State
.exception
)
1243 State
.exception
= SIGTRAP
;
1247 sim_set_trace (void)
1255 sim_info (SIM_DESC sd
, int verbose
)
1263 unsigned long left
= ins_type_counters
[ (int)INS_LEFT
] + ins_type_counters
[ (int)INS_LEFT_COND_EXE
];
1264 unsigned long left_nops
= ins_type_counters
[ (int)INS_LEFT_NOPS
];
1265 unsigned long left_parallel
= ins_type_counters
[ (int)INS_LEFT_PARALLEL
];
1266 unsigned long left_cond
= ins_type_counters
[ (int)INS_LEFT_COND_TEST
];
1267 unsigned long left_total
= left
+ left_parallel
+ left_cond
+ left_nops
;
1269 unsigned long right
= ins_type_counters
[ (int)INS_RIGHT
] + ins_type_counters
[ (int)INS_RIGHT_COND_EXE
];
1270 unsigned long right_nops
= ins_type_counters
[ (int)INS_RIGHT_NOPS
];
1271 unsigned long right_parallel
= ins_type_counters
[ (int)INS_RIGHT_PARALLEL
];
1272 unsigned long right_cond
= ins_type_counters
[ (int)INS_RIGHT_COND_TEST
];
1273 unsigned long right_total
= right
+ right_parallel
+ right_cond
+ right_nops
;
1275 unsigned long unknown
= ins_type_counters
[ (int)INS_UNKNOWN
];
1276 unsigned long ins_long
= ins_type_counters
[ (int)INS_LONG
];
1277 unsigned long parallel
= ins_type_counters
[ (int)INS_PARALLEL
];
1278 unsigned long leftright
= ins_type_counters
[ (int)INS_LEFTRIGHT
];
1279 unsigned long rightleft
= ins_type_counters
[ (int)INS_RIGHTLEFT
];
1280 unsigned long cond_true
= ins_type_counters
[ (int)INS_COND_TRUE
];
1281 unsigned long cond_false
= ins_type_counters
[ (int)INS_COND_FALSE
];
1282 unsigned long cond_jump
= ins_type_counters
[ (int)INS_COND_JUMP
];
1283 unsigned long cycles
= ins_type_counters
[ (int)INS_CYCLES
];
1284 unsigned long total
= (unknown
+ left_total
+ right_total
+ ins_long
);
1286 int size
= strlen (add_commas (buf1
, sizeof (buf1
), total
));
1287 int parallel_size
= strlen (add_commas (buf1
, sizeof (buf1
),
1288 (left_parallel
> right_parallel
) ? left_parallel
: right_parallel
));
1289 int cond_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_cond
> right_cond
) ? left_cond
: right_cond
));
1290 int nop_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left_nops
> right_nops
) ? left_nops
: right_nops
));
1291 int normal_size
= strlen (add_commas (buf1
, sizeof (buf1
), (left
> right
) ? left
: right
));
1293 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1294 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1295 size
, add_commas (buf1
, sizeof (buf1
), left_total
),
1296 normal_size
, add_commas (buf2
, sizeof (buf2
), left
),
1297 parallel_size
, add_commas (buf3
, sizeof (buf3
), left_parallel
),
1298 cond_size
, add_commas (buf4
, sizeof (buf4
), left_cond
),
1299 nop_size
, add_commas (buf5
, sizeof (buf5
), left_nops
));
1301 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1302 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1303 size
, add_commas (buf1
, sizeof (buf1
), right_total
),
1304 normal_size
, add_commas (buf2
, sizeof (buf2
), right
),
1305 parallel_size
, add_commas (buf3
, sizeof (buf3
), right_parallel
),
1306 cond_size
, add_commas (buf4
, sizeof (buf4
), right_cond
),
1307 nop_size
, add_commas (buf5
, sizeof (buf5
), right_nops
));
1310 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1311 "executed %*s long instruction(s)\n",
1312 size
, add_commas (buf1
, sizeof (buf1
), ins_long
));
1315 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1316 "executed %*s parallel instruction(s)\n",
1317 size
, add_commas (buf1
, sizeof (buf1
), parallel
));
1320 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1321 "executed %*s instruction(s) encoded L->R\n",
1322 size
, add_commas (buf1
, sizeof (buf1
), leftright
));
1325 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1326 "executed %*s instruction(s) encoded R->L\n",
1327 size
, add_commas (buf1
, sizeof (buf1
), rightleft
));
1330 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1331 "executed %*s unknown instruction(s)\n",
1332 size
, add_commas (buf1
, sizeof (buf1
), unknown
));
1335 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1336 "executed %*s instruction(s) due to EXExxx condition being true\n",
1337 size
, add_commas (buf1
, sizeof (buf1
), cond_true
));
1340 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1341 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1342 size
, add_commas (buf1
, sizeof (buf1
), cond_false
));
1345 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1346 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1347 size
, add_commas (buf1
, sizeof (buf1
), cond_jump
));
1349 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1350 "executed %*s cycle(s)\n",
1351 size
, add_commas (buf1
, sizeof (buf1
), cycles
));
1353 (*cr16_callback
->printf_filtered
) (cr16_callback
,
1354 "executed %*s total instructions\n",
1355 size
, add_commas (buf1
, sizeof (buf1
), total
));
1360 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
, char **argv
, char **env
)
1362 bfd_vma start_address
;
1364 /* reset all state information */
1365 memset (&State
.regs
, 0, (int)&State
.mem
- (int)&State
.regs
);
1367 /* There was a hack here to copy the values of argc and argv into r0
1368 and r1. The values were also saved into some high memory that
1369 won't be overwritten by the stack (0x7C00). The reason for doing
1370 this was to allow the 'run' program to accept arguments. Without
1371 the hack, this is not possible anymore. If the simulator is run
1372 from the debugger, arguments cannot be passed in, so this makes
1377 start_address
= bfd_get_start_address (abfd
);
1379 start_address
= 0x0;
1382 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_create_inferior: PC=0x%lx\n", (long) start_address
);
1384 SET_CREG (PC_CR
, start_address
);
1392 sim_set_callbacks (p
)
1399 sim_stop_reason (sd
, reason
, sigrc
)
1401 enum sim_stop
*reason
;
1404 /* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1406 switch (State
.exception
)
1408 case SIG_CR16_STOP
: /* stop instruction */
1409 *reason
= sim_stopped
;
1413 case SIG_CR16_EXIT
: /* exit trap */
1414 *reason
= sim_exited
;
1419 *reason
= sim_stopped
;
1420 *sigrc
= TARGET_SIGNAL_BUS
;
1423 // case SIG_CR16_IAD:
1424 // *reason = sim_stopped;
1425 // *sigrc = TARGET_SIGNAL_IAD;
1428 default: /* some signal */
1429 *reason
= sim_stopped
;
1430 if (stop_simulator
&& !State
.exception
)
1431 *sigrc
= TARGET_SIGNAL_INT
;
1433 *sigrc
= State
.exception
;
1441 sim_fetch_register (sd
, rn
, memory
, length
)
1444 unsigned char *memory
;
1448 switch ((enum sim_cr16_regs
) rn
)
1450 case SIM_CR16_R0_REGNUM
:
1451 case SIM_CR16_R1_REGNUM
:
1452 case SIM_CR16_R2_REGNUM
:
1453 case SIM_CR16_R3_REGNUM
:
1454 case SIM_CR16_R4_REGNUM
:
1455 case SIM_CR16_R5_REGNUM
:
1456 case SIM_CR16_R6_REGNUM
:
1457 case SIM_CR16_R7_REGNUM
:
1458 case SIM_CR16_R8_REGNUM
:
1459 case SIM_CR16_R9_REGNUM
:
1460 case SIM_CR16_R10_REGNUM
:
1461 case SIM_CR16_R11_REGNUM
:
1462 WRITE_16 (memory
, GPR (rn
- SIM_CR16_R0_REGNUM
));
1465 case SIM_CR16_R12_REGNUM
:
1466 case SIM_CR16_R13_REGNUM
:
1467 case SIM_CR16_R14_REGNUM
:
1468 case SIM_CR16_R15_REGNUM
:
1469 //WRITE_32 (memory, GPR (rn - SIM_CR16_R0_REGNUM));
1470 write_longword (memory
, GPR (rn
- SIM_CR16_R0_REGNUM
));
1473 case SIM_CR16_PC_REGNUM
:
1474 case SIM_CR16_ISP_REGNUM
:
1475 case SIM_CR16_USP_REGNUM
:
1476 case SIM_CR16_INTBASE_REGNUM
:
1477 case SIM_CR16_PSR_REGNUM
:
1478 case SIM_CR16_CFG_REGNUM
:
1479 case SIM_CR16_DBS_REGNUM
:
1480 case SIM_CR16_DCR_REGNUM
:
1481 case SIM_CR16_DSR_REGNUM
:
1482 case SIM_CR16_CAR0_REGNUM
:
1483 case SIM_CR16_CAR1_REGNUM
:
1484 //WRITE_32 (memory, CREG (rn - SIM_CR16_PC_REGNUM));
1485 write_longword (memory
, CREG (rn
- SIM_CR16_PC_REGNUM
));
1496 sim_store_register (sd
, rn
, memory
, length
)
1499 unsigned char *memory
;
1503 switch ((enum sim_cr16_regs
) rn
)
1505 case SIM_CR16_R0_REGNUM
:
1506 case SIM_CR16_R1_REGNUM
:
1507 case SIM_CR16_R2_REGNUM
:
1508 case SIM_CR16_R3_REGNUM
:
1509 case SIM_CR16_R4_REGNUM
:
1510 case SIM_CR16_R5_REGNUM
:
1511 case SIM_CR16_R6_REGNUM
:
1512 case SIM_CR16_R7_REGNUM
:
1513 case SIM_CR16_R8_REGNUM
:
1514 case SIM_CR16_R9_REGNUM
:
1515 case SIM_CR16_R10_REGNUM
:
1516 case SIM_CR16_R11_REGNUM
:
1517 SET_GPR (rn
- SIM_CR16_R0_REGNUM
, READ_16 (memory
));
1520 case SIM_CR16_R12_REGNUM
:
1521 case SIM_CR16_R13_REGNUM
:
1522 case SIM_CR16_R14_REGNUM
:
1523 case SIM_CR16_R15_REGNUM
:
1524 SET_GPR32 (rn
- SIM_CR16_R0_REGNUM
, get_longword (memory
));
1527 case SIM_CR16_PC_REGNUM
:
1528 case SIM_CR16_ISP_REGNUM
:
1529 case SIM_CR16_USP_REGNUM
:
1530 case SIM_CR16_INTBASE_REGNUM
:
1531 case SIM_CR16_PSR_REGNUM
:
1532 case SIM_CR16_CFG_REGNUM
:
1533 case SIM_CR16_DBS_REGNUM
:
1534 case SIM_CR16_DCR_REGNUM
:
1535 case SIM_CR16_DSR_REGNUM
:
1536 case SIM_CR16_CAR0_REGNUM
:
1537 case SIM_CR16_CAR1_REGNUM
:
1538 SET_CREG (rn
- SIM_CR16_PC_REGNUM
, get_longword (memory
));
1551 sim_do_command (sd
, cmd
)
1555 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_do_command: %s\n",cmd
);
1559 sim_load (SIM_DESC sd
, char *prog
, struct bfd
*abfd
, int from_tty
)
1561 extern bfd
*sim_load_file (); /* ??? Don't know where this should live. */
1563 if (prog_bfd
!= NULL
&& prog_bfd_was_opened_p
)
1565 bfd_close (prog_bfd
);
1566 prog_bfd_was_opened_p
= 0;
1568 prog_bfd
= sim_load_file (sd
, myname
, cr16_callback
, prog
, abfd
,
1569 sim_kind
== SIM_OPEN_DEBUG
,
1570 1/*LMA*/, sim_write
);
1571 if (prog_bfd
== NULL
)
1573 prog_bfd_was_opened_p
= abfd
== NULL
;
This page took 0.065608 seconds and 4 git commands to generate.