]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/cr16/interp.c
7f5e044eca14e64efabd792db4ee8a20e7f3ca76
1 /* Simulation code for the CR16 processor.
2 Copyright (C) 2008-2015 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/>. */
26 #include "gdb/callback.h"
27 #include "gdb/remote-sim.h"
30 #include "sim-options.h"
32 #include "gdb/sim-cr16.h"
33 #include "gdb/signals.h"
34 #include "opcode/cr16.h"
38 host_callback
*cr16_callback
;
43 static struct hash_entry
*lookup_hash (SIM_DESC
, SIM_CPU
*, uint64 ins
, int size
);
44 static void get_operands (operand_desc
*s
, uint64 mcode
, int isize
, int nops
);
45 static INLINE uint8
*map_memory (SIM_DESC
, SIM_CPU
*, unsigned phys_addr
);
51 struct hash_entry
*next
;
59 struct hash_entry hash_table
[MAX_HASH
+1];
62 hash(unsigned long long insn
, int format
)
64 unsigned int i
= 4, tmp
;
67 while ((insn
>> i
) != 0) i
+=4;
69 return ((insn
>> (i
-4)) & 0xf); /* Use last 4 bits as hask key. */
71 return ((insn
& 0xF)); /* Use last 4 bits as hask key. */
75 INLINE
static struct hash_entry
*
76 lookup_hash (SIM_DESC sd
, SIM_CPU
*cpu
, uint64 ins
, int size
)
81 h
= &hash_table
[hash(ins
,1)];
84 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
86 /* Adjuest mask for branch with 2 word instructions. */
87 if ((h
->ops
->mnimonic
!= NULL
) &&
88 ((streq(h
->ops
->mnimonic
,"b") && h
->size
== 2)))
92 while ((ins
& mask
) != (BIN(h
->opcode
, h
->mask
)))
96 State
.exception
= SIGILL
;
97 State
.pc_changed
= 1; /* Don't increment the PC. */
102 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
103 /* Adjuest mask for branch with 2 word instructions. */
104 if ((streq(h
->ops
->mnimonic
,"b")) && h
->size
== 2)
112 get_operands (operand_desc
*s
, uint64 ins
, int isize
, int nops
)
114 uint32 i
, opn
= 0, start_bit
= 0, op_type
= 0;
115 int32 op_size
= 0, mask
= 0;
117 if (isize
== 1) /* Trunkcate the extra 16 bits of INS. */
120 for (i
=0; i
< 4; ++i
,++opn
)
122 if (s
[opn
].op_type
== dummy
) break;
124 op_type
= s
[opn
].op_type
;
125 start_bit
= s
[opn
].shift
;
126 op_size
= cr16_optab
[op_type
].bit_size
;
130 case imm3
: case imm4
: case imm5
: case imm6
:
133 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
135 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));
137 if (OP
[i
] & ((long)1 << (op_size
-1)))
140 OP
[i
] = ~(OP
[i
]) + 1;
142 OP
[i
] = (unsigned long int)(OP
[i
] & (((long)1 << op_size
) -1));
146 case uimm3
: case uimm3_1
: case uimm4_1
:
150 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1)); break;
152 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));break;
153 default: /* for case 3. */
154 OP
[i
] = ((ins
>> (16 + start_bit
)) & ((1 << op_size
) -1)); break;
164 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
166 OP
[i
] = (ins
& ((1 << op_size
) -1));
169 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
172 OP
[i
] = ((ins
>> (start_bit
+ 16)) & ((1 << op_size
) -1));
175 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
180 case imm16
: case uimm16
:
181 OP
[i
] = ins
& 0xFFFF;
184 case uimm20
: case imm20
:
185 OP
[i
] = ins
& (((long)1 << op_size
) - 1);
188 case imm32
: case uimm32
:
189 OP
[i
] = ins
& 0xFFFFFFFF;
192 case uimm5
: break; /*NOT USED. */
193 OP
[i
] = ins
& ((1 << op_size
) - 1); break;
196 OP
[i
] = (ins
>> 4) & ((1 << 4) - 1);
197 OP
[i
] = (OP
[i
] * 2) + 2;
198 if (OP
[i
] & ((long)1 << 5))
201 OP
[i
] = ~(OP
[i
]) + 1;
202 OP
[i
] = (unsigned long int)(OP
[i
] & 0x1F);
207 OP
[i
] = ((((ins
>> 8) & 0xf) << 4) | (ins
& 0xf));
209 if (OP
[i
] & ((long)1 << 8))
212 OP
[i
] = ~(OP
[i
]) + 1;
213 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFF);
218 OP
[i
] = (ins
& 0xFFFF);
221 OP
[i
] = (OP
[i
] & 0xFFFE);
223 OP
[i
] = ~(OP
[i
]) + 1;
224 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFF);
230 OP
[i
] = (ins
& 0xFFFFFF);
232 OP
[i
] = (ins
& 0xFFFF) | (((ins
>> 24) & 0xf) << 16) |
233 (((ins
>> 16) & 0xf) << 20);
237 OP
[i
] = (OP
[i
] & 0xFFFFFE);
239 OP
[i
] = ~(OP
[i
]) + 1;
240 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFFFF);
246 OP
[i
] = (ins
) & 0xFFFFF;
248 OP
[i
] = (ins
>> start_bit
) & 0xFFFFF;
252 OP
[i
] = ((ins
& 0xFFFF) | (((ins
>> 16) & 0xf) << 20)
253 | (((ins
>> 24) & 0xf) << 16));
255 OP
[i
] = (ins
>> 16) & 0xFFFFFF;
259 case rbase
: break; /* NOT USED. */
260 case rbase_disps20
: case rbase_dispe20
:
261 case rpbase_disps20
: case rpindex_disps20
:
262 OP
[i
] = ((((ins
>> 24)&0xf) << 16)|((ins
) & 0xFFFF));
263 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
266 OP
[i
] = 0; /* 4 bit disp const. */
267 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
270 OP
[i
] = ((ins
>> 8) & 0xF) * 2; /* 4 bit disp const. */
271 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
274 OP
[i
] = ((ins
>> 8) & 0xF); /* 4 bit disp const. */
275 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
278 OP
[i
] = (ins
) & 0xFFFF;
279 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
283 OP
[++i
] = (ins
>> 4) & 0xF; /* get 4 bit for reg. */
284 OP
[++i
] = (ins
>> 8) & 0x1; /* get 1 bit for index-reg. */
286 case rpindex_disps14
:
287 OP
[i
] = (ins
) & 0x3FFF;
288 OP
[++i
] = (ins
>> 14) & 0x1; /* get 1 bit for index-reg. */
289 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
292 OP
[i
] = (ins
) & 0xFFFFF;
293 OP
[++i
] = (ins
>> 24) & 0x1; /* get 1 bit for index-reg. */
294 OP
[++i
] = (ins
>> 20) & 0xF; /* get 4 bit for reg. */
296 case regr
: case regp
: case pregr
: case pregrp
:
300 if (start_bit
== 20) OP
[i
] = (ins
>> 4) & 0xF;
301 else if (start_bit
== 16) OP
[i
] = ins
& 0xF;
303 case 2: OP
[i
] = (ins
>> start_bit
) & 0xF; break;
304 case 3: OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF; break;
309 if (isize
== 1) OP
[i
] = (ins
>> 4) & 0xF;
310 else if (isize
== 2) OP
[i
] = (ins
>> start_bit
) & 0xF;
311 else OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF;
317 /* For ESC on uimm4_1 operand. */
318 if (op_type
== uimm4_1
)
322 /* For increment by 1. */
323 if ((op_type
== pregr
) || (op_type
== pregrp
))
326 /* FIXME: for tracing, update values that need to be updated each
327 instruction decode cycle */
328 State
.trace
.psw
= PSR
;
332 do_run (SIM_DESC sd
, SIM_CPU
*cpu
, uint64 mcode
)
334 host_callback
*cr16_callback
= STATE_CALLBACK (sd
);
335 struct simops
*s
= Simops
;
336 struct hash_entry
*h
;
340 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
341 (*cr16_callback
->printf_filtered
) (cr16_callback
, "do_long 0x%x\n", mcode
);
344 h
= lookup_hash (sd
, cpu
, mcode
, 1);
346 if ((h
== NULL
) || (h
->opcode
== 0))
351 iaddr
= imem_addr (sd
, cpu
, (uint32
)PC
+ 2);
352 mcode
= (mcode
<< 16) | get_longword( iaddr
);
355 /* Re-set OP list. */
356 OP
[0] = OP
[1] = OP
[2] = OP
[3] = sign_flag
= 0;
358 /* for push/pop/pushrtn with RA instructions. */
359 if ((h
->format
& REG_LIST
) && (mcode
& 0x800000))
360 OP
[2] = 1; /* Set 1 for RA operand. */
362 /* numops == 0 means, no operands. */
363 if (((h
->ops
) != NULL
) && (((h
->ops
)->numops
) != 0))
364 get_operands ((h
->ops
)->operands
, mcode
, h
->size
, (h
->ops
)->numops
);
366 //State.ins_type = h->flags;
368 (h
->ops
->func
) (sd
, cpu
);
377 for (i
= 0; i
< IMEM_SEGMENTS
; i
++)
379 if (State
.mem
.insn
[i
])
380 free (State
.mem
.insn
[i
]);
382 for (i
= 0; i
< DMEM_SEGMENTS
; i
++)
384 if (State
.mem
.data
[i
])
385 free (State
.mem
.data
[i
]);
387 for (i
= 0; i
< UMEM_SEGMENTS
; i
++)
389 if (State
.mem
.unif
[i
])
390 free (State
.mem
.unif
[i
]);
392 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
394 State
.mem
.data
[0] = calloc (1, SEGMENT_SIZE
);
397 /* For tracing - leave info on last access around. */
398 static char *last_segname
= "invalid";
399 static char *last_from
= "invalid";
400 static char *last_to
= "invalid";
404 IMAP0_OFFSET
= 0xff00,
405 DMAP0_OFFSET
= 0xff08,
406 DMAP2_SHADDOW
= 0xff04,
407 DMAP2_OFFSET
= 0xff0c
411 dmap_register (SIM_DESC sd
, SIM_CPU
*cpu
, void *regcache
, int reg_nr
)
413 uint8
*raw
= map_memory (sd
, cpu
, SIM_CR16_MEMORY_DATA
414 + DMAP0_OFFSET
+ 2 * reg_nr
);
415 return READ_16 (raw
);
419 imap_register (SIM_DESC sd
, SIM_CPU
*cpu
, void *regcache
, int reg_nr
)
421 uint8
*raw
= map_memory (sd
, cpu
, SIM_CR16_MEMORY_DATA
422 + IMAP0_OFFSET
+ 2 * reg_nr
);
423 return READ_16 (raw
);
426 /* Given a virtual address in the DMAP address space, translate it
427 into a physical address. */
430 sim_cr16_translate_dmap_addr (SIM_DESC sd
,
432 unsigned long offset
,
436 unsigned long (*dmap_register
) (SIM_DESC
,
443 last_from
= "logical-data";
444 if (offset
>= DMAP_BLOCK_SIZE
* SIM_CR16_NR_DMAP_REGS
)
446 /* Logical address out side of data segments, not supported */
449 regno
= (offset
/ DMAP_BLOCK_SIZE
);
450 offset
= (offset
% DMAP_BLOCK_SIZE
);
453 if ((offset
% DMAP_BLOCK_SIZE
) + nr_bytes
> DMAP_BLOCK_SIZE
)
455 /* Don't cross a BLOCK boundary */
456 nr_bytes
= DMAP_BLOCK_SIZE
- (offset
% DMAP_BLOCK_SIZE
);
458 map
= dmap_register (sd
, cpu
, regcache
, regno
);
461 /* Always maps to data memory */
462 int iospi
= (offset
/ 0x1000) % 4;
463 int iosp
= (map
>> (4 * (3 - iospi
))) % 0x10;
464 last_to
= "io-space";
465 *phys
= (SIM_CR16_MEMORY_DATA
+ (iosp
* 0x10000) + 0xc000 + offset
);
469 int sp
= ((map
& 0x3000) >> 12);
470 int segno
= (map
& 0x3ff);
473 case 0: /* 00: Unified memory */
474 *phys
= SIM_CR16_MEMORY_UNIFIED
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
477 case 1: /* 01: Instruction Memory */
478 *phys
= SIM_CR16_MEMORY_INSN
+ (segno
* DMAP_BLOCK_SIZE
) + offset
;
479 last_to
= "chip-insn";
481 case 2: /* 10: Internal data memory */
482 *phys
= SIM_CR16_MEMORY_DATA
+ (segno
<< 16) + (regno
* DMAP_BLOCK_SIZE
) + offset
;
483 last_to
= "chip-data";
485 case 3: /* 11: Reserved */
493 /* Given a virtual address in the IMAP address space, translate it
494 into a physical address. */
497 sim_cr16_translate_imap_addr (SIM_DESC sd
,
499 unsigned long offset
,
503 unsigned long (*imap_register
) (SIM_DESC
,
512 last_from
= "logical-insn";
513 if (offset
>= (IMAP_BLOCK_SIZE
* SIM_CR16_NR_IMAP_REGS
))
515 /* Logical address outside of IMAP segments, not supported */
518 regno
= (offset
/ IMAP_BLOCK_SIZE
);
519 offset
= (offset
% IMAP_BLOCK_SIZE
);
520 if (offset
+ nr_bytes
> IMAP_BLOCK_SIZE
)
522 /* Don't cross a BLOCK boundary */
523 nr_bytes
= IMAP_BLOCK_SIZE
- offset
;
525 map
= imap_register (sd
, cpu
, regcache
, regno
);
526 sp
= (map
& 0x3000) >> 12;
527 segno
= (map
& 0x007f);
530 case 0: /* 00: unified memory */
531 *phys
= SIM_CR16_MEMORY_UNIFIED
+ (segno
<< 17) + offset
;
534 case 1: /* 01: instruction memory */
535 *phys
= SIM_CR16_MEMORY_INSN
+ (IMAP_BLOCK_SIZE
* regno
) + offset
;
536 last_to
= "chip-insn";
541 case 3: /* 11: for testing - instruction memory */
542 offset
= (offset
% 0x800);
543 *phys
= SIM_CR16_MEMORY_INSN
+ offset
;
544 if (offset
+ nr_bytes
> 0x800)
545 /* don't cross VM boundary */
546 nr_bytes
= 0x800 - offset
;
547 last_to
= "test-insn";
554 sim_cr16_translate_addr (SIM_DESC sd
,
556 unsigned long memaddr
,
558 unsigned long *targ_addr
,
560 unsigned long (*dmap_register
) (SIM_DESC
,
564 unsigned long (*imap_register
) (SIM_DESC
,
573 last_from
= "unknown";
576 seg
= (memaddr
>> 24);
577 off
= (memaddr
& 0xffffffL
);
581 case 0x00: /* Physical unified memory */
582 last_from
= "phys-unified";
584 phys
= SIM_CR16_MEMORY_UNIFIED
+ off
;
585 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
586 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
589 case 0x01: /* Physical instruction memory */
590 last_from
= "phys-insn";
591 last_to
= "chip-insn";
592 phys
= SIM_CR16_MEMORY_INSN
+ off
;
593 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
594 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
597 case 0x02: /* Physical data memory segment */
598 last_from
= "phys-data";
599 last_to
= "chip-data";
600 phys
= SIM_CR16_MEMORY_DATA
+ off
;
601 if ((off
% SEGMENT_SIZE
) + nr_bytes
> SEGMENT_SIZE
)
602 nr_bytes
= SEGMENT_SIZE
- (off
% SEGMENT_SIZE
);
605 case 0x10: /* in logical data address segment */
606 nr_bytes
= sim_cr16_translate_dmap_addr (sd
, cpu
, off
, nr_bytes
, &phys
,
607 regcache
, dmap_register
);
610 case 0x11: /* in logical instruction address segment */
611 nr_bytes
= sim_cr16_translate_imap_addr (sd
, cpu
, off
, nr_bytes
, &phys
,
612 regcache
, imap_register
);
623 /* Return a pointer into the raw buffer designated by phys_addr. It
624 is assumed that the client has already ensured that the access
625 isn't going to cross a segment boundary. */
628 map_memory (SIM_DESC sd
, SIM_CPU
*cpu
, unsigned phys_addr
)
633 int segment
= ((phys_addr
>> 24) & 0xff);
638 case 0x00: /* Unified memory */
640 memory
= &State
.mem
.unif
[(phys_addr
/ SEGMENT_SIZE
) % UMEM_SEGMENTS
];
641 last_segname
= "umem";
645 case 0x01: /* On-chip insn memory */
647 memory
= &State
.mem
.insn
[(phys_addr
/ SEGMENT_SIZE
) % IMEM_SEGMENTS
];
648 last_segname
= "imem";
652 case 0x02: /* On-chip data memory */
654 if ((phys_addr
& 0xff00) == 0xff00)
656 phys_addr
= (phys_addr
& 0xffff);
657 if (phys_addr
== DMAP2_SHADDOW
)
659 phys_addr
= DMAP2_OFFSET
;
660 last_segname
= "dmap";
663 last_segname
= "reg";
666 last_segname
= "dmem";
667 memory
= &State
.mem
.data
[(phys_addr
/ SEGMENT_SIZE
) % DMEM_SEGMENTS
];
673 last_segname
= "scrap";
674 return State
.mem
.fault
;
679 *memory
= calloc (1, SEGMENT_SIZE
);
682 (*cr16_callback
->printf_filtered
) (cr16_callback
, "Malloc failed.\n");
683 return State
.mem
.fault
;
687 offset
= (phys_addr
% SEGMENT_SIZE
);
688 raw
= *memory
+ offset
;
692 /* Transfer data to/from simulated memory. Since a bug in either the
693 simulated program or in gdb or the simulator itself may cause a
694 bogus address to be passed in, we need to do some sanity checking
695 on addresses to make sure they are within bounds. When an address
696 fails the bounds check, treat it as a zero length read/write rather
697 than aborting the entire run. */
700 xfer_mem (SIM_DESC sd
, SIM_ADDR virt
,
701 unsigned char *buffer
,
705 host_callback
*cr16_callback
= STATE_CALLBACK (sd
);
709 phys_size
= sim_cr16_translate_addr (sd
, NULL
, virt
, size
, &phys
, NULL
,
710 dmap_register
, imap_register
);
714 memory
= map_memory (sd
, NULL
, phys
);
717 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
719 (*cr16_callback
->printf_filtered
)
721 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
722 (write_p
? "write" : "read"),
723 phys_size
, virt
, last_from
,
725 (long) memory
, last_segname
);
731 memcpy (memory
, buffer
, phys_size
);
735 memcpy (buffer
, memory
, phys_size
);
743 sim_write (SIM_DESC sd
, SIM_ADDR addr
, const unsigned char *buffer
, int size
)
745 /* FIXME: this should be performing a virtual transfer */
746 return xfer_mem (sd
, addr
, buffer
, size
, 1);
750 sim_read (SIM_DESC sd
, SIM_ADDR addr
, unsigned char *buffer
, int size
)
752 /* FIXME: this should be performing a virtual transfer */
753 return xfer_mem (sd
, addr
, buffer
, size
, 0);
757 cr16_pc_get (sim_cpu
*cpu
)
763 cr16_pc_set (sim_cpu
*cpu
, sim_cia pc
)
765 SIM_DESC sd
= CPU_STATE (cpu
);
770 free_state (SIM_DESC sd
)
772 if (STATE_MODULES (sd
) != NULL
)
773 sim_module_uninstall (sd
);
774 sim_cpu_free_all (sd
);
778 static int cr16_reg_fetch (SIM_CPU
*, int, unsigned char *, int);
779 static int cr16_reg_store (SIM_CPU
*, int, unsigned char *, int);
782 sim_open (SIM_OPEN_KIND kind
, struct host_callback_struct
*cb
, struct bfd
*abfd
, char **argv
)
785 struct hash_entry
*h
;
786 static int init_p
= 0;
789 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
790 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
792 /* The cpu data is kept in a separately allocated chunk of memory. */
793 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
799 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
805 /* getopt will print the error message so we just have to exit if this fails.
806 FIXME: Hmmm... in the case of gdb we need getopt to call
808 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
814 /* Check for/establish the a reference program image. */
815 if (sim_analyze_program (sd
,
816 (STATE_PROG_ARGV (sd
) != NULL
817 ? *STATE_PROG_ARGV (sd
)
818 : NULL
), abfd
) != SIM_RC_OK
)
824 /* Configure/verify the target byte order and other runtime
825 configuration options. */
826 if (sim_config (sd
) != SIM_RC_OK
)
828 sim_module_uninstall (sd
);
832 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
834 /* Uninstall the modules to avoid memory leaks,
835 file descriptor leaks, etc. */
836 sim_module_uninstall (sd
);
840 /* CPU specific initialization. */
841 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
843 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
845 CPU_REG_FETCH (cpu
) = cr16_reg_fetch
;
846 CPU_REG_STORE (cpu
) = cr16_reg_store
;
847 CPU_PC_FETCH (cpu
) = cr16_pc_get
;
848 CPU_PC_STORE (cpu
) = cr16_pc_set
;
853 /* put all the opcodes in the hash table. */
856 for (s
= Simops
; s
->func
; s
++)
861 h
= &hash_table
[hash(s
->opcode
, 0)];
865 if (((s
->opcode
<< 1) >> 4) != 0)
866 h
= &hash_table
[hash((s
->opcode
<< 1) >> 4, 0)];
868 h
= &hash_table
[hash((s
->opcode
<< 1), 0)];
872 if ((s
->opcode
>> 4) != 0)
873 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
875 h
= &hash_table
[hash(s
->opcode
, 0)];
879 if (((s
->opcode
>> 1) >> 4) != 0)
880 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
882 h
= &hash_table
[hash((s
->opcode
>> 1), 0)];
886 if ((s
->opcode
>> 8) != 0)
887 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
888 else if ((s
->opcode
>> 4) != 0)
889 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
891 h
= &hash_table
[hash(s
->opcode
, 0)];
895 if ((s
->opcode
>> 8) != 0)
896 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
897 else if ((s
->opcode
>> 4) != 0)
898 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
900 h
= &hash_table
[hash(s
->opcode
, 0)];
904 if (((s
->opcode
>> 1) >> 8) != 0)
905 h
= &hash_table
[hash((s
->opcode
>>1) >> 8, 0)];
906 else if (((s
->opcode
>> 1) >> 4) != 0)
907 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
909 h
= &hash_table
[hash((s
->opcode
>>1), 0)];
913 if ((s
->opcode
>> 0xc) != 0)
914 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
915 else if ((s
->opcode
>> 8) != 0)
916 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
917 else if ((s
->opcode
>> 4) != 0)
918 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
920 h
= &hash_table
[hash(s
->opcode
, 0)];
924 if ((s
->opcode
>> 16) != 0)
925 h
= &hash_table
[hash(s
->opcode
>> 16, 0)];
926 else if ((s
->opcode
>> 12) != 0)
927 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
928 else if ((s
->opcode
>> 8) != 0)
929 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
930 else if ((s
->opcode
>> 4) != 0)
931 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
933 h
= &hash_table
[hash(s
->opcode
, 0)];
939 /* go to the last entry in the chain. */
945 h
->next
= (struct hash_entry
*) calloc(1,sizeof(struct hash_entry
));
947 perror ("malloc failure");
953 h
->opcode
= s
->opcode
;
954 h
->format
= s
->format
;
959 /* reset the processor state */
960 if (!State
.mem
.data
[0])
967 dmem_addr (SIM_DESC sd
, SIM_CPU
*cpu
, uint32 offset
)
973 /* Note: DMEM address range is 0..0x10000. Calling code can compute
974 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
975 is uint16 this is modulo'ed onto 0x0e5d. */
977 phys_size
= sim_cr16_translate_dmap_addr (sd
, cpu
, offset
, 1, &phys
, NULL
,
981 mem
= State
.mem
.fault
;
984 mem
= map_memory (sd
, cpu
, phys
);
986 if ((cr16_debug
& DEBUG_MEMORY
))
988 (*cr16_callback
->printf_filtered
)
990 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
992 phys
, phys_size
, last_to
,
993 (long) mem
, last_segname
);
1000 imem_addr (SIM_DESC sd
, SIM_CPU
*cpu
, uint32 offset
)
1004 int phys_size
= sim_cr16_translate_imap_addr (sd
, cpu
, offset
, 1, &phys
, NULL
,
1008 return State
.mem
.fault
;
1010 mem
= map_memory (sd
, cpu
, phys
);
1012 if ((cr16_debug
& DEBUG_MEMORY
))
1014 (*cr16_callback
->printf_filtered
)
1016 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1018 phys
, phys_size
, last_to
,
1019 (long) mem
, last_segname
);
1025 static int stop_simulator
= 0;
1028 sim_stop (SIM_DESC sd
)
1035 /* Run (or resume) the program. */
1037 sim_resume (SIM_DESC sd
, int step
, int siggnal
)
1039 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1040 uint32 curr_ins_size
= 0;
1045 // (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
1048 State
.exception
= 0;
1062 JMP (AE_VECTOR_START
);
1068 SET_HW_PSR ((PSR
& (PSR_C_BIT
)));
1069 JMP (RIE_VECTOR_START
);
1073 /* just ignore it */
1079 iaddr
= imem_addr (sd
, cpu
, (uint32
)PC
);
1080 if (iaddr
== State
.mem
.fault
)
1083 State
.exception
= SIGBUS
;
1085 State
.exception
= SIGSEGV
;
1090 mcode
= get_longword( iaddr
);
1092 State
.pc_changed
= 0;
1094 curr_ins_size
= do_run (sd
, cpu
, mcode
);
1097 (*cr16_callback
->printf_filtered
) (cr16_callback
, "INS: PC=0x%X, mcode=0x%X\n",PC
,mcode
);
1100 if (!State
.pc_changed
)
1102 if (curr_ins_size
== 0)
1104 State
.exception
= SIG_CR16_EXIT
; /* exit trap */
1108 SET_PC (PC
+ (curr_ins_size
* 2)); /* For word instructions. */
1112 /* Check for a breakpoint trap on this instruction. This
1113 overrides any pending branches or loops */
1114 if (PSR_DB
&& PC
== DBS
)
1118 SET_PC (SDBT_VECTOR_START
);
1122 /* Writeback all the DATA / PC changes */
1125 while ( !State
.exception
&& !stop_simulator
);
1127 if (step
&& !State
.exception
)
1128 State
.exception
= SIGTRAP
;
1132 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
, char **argv
, char **env
)
1134 bfd_vma start_address
;
1136 /* reset all state information */
1137 memset (&State
.regs
, 0, (uintptr_t)&State
.mem
- (uintptr_t)&State
.regs
);
1139 /* There was a hack here to copy the values of argc and argv into r0
1140 and r1. The values were also saved into some high memory that
1141 won't be overwritten by the stack (0x7C00). The reason for doing
1142 this was to allow the 'run' program to accept arguments. Without
1143 the hack, this is not possible anymore. If the simulator is run
1144 from the debugger, arguments cannot be passed in, so this makes
1149 start_address
= bfd_get_start_address (abfd
);
1151 start_address
= 0x0;
1154 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_create_inferior: PC=0x%lx\n", (long) start_address
);
1157 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1158 SET_CREG (PC_CR
, start_address
);
1166 sim_stop_reason (SIM_DESC sd
, enum sim_stop
*reason
, int *sigrc
)
1168 /* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1170 switch (State
.exception
)
1172 case SIG_CR16_STOP
: /* stop instruction */
1173 *reason
= sim_stopped
;
1177 case SIG_CR16_EXIT
: /* exit trap */
1178 *reason
= sim_exited
;
1183 *reason
= sim_stopped
;
1184 *sigrc
= GDB_SIGNAL_BUS
;
1187 // case SIG_CR16_IAD:
1188 // *reason = sim_stopped;
1189 // *sigrc = GDB_SIGNAL_IAD;
1192 default: /* some signal */
1193 *reason
= sim_stopped
;
1194 if (stop_simulator
&& !State
.exception
)
1195 *sigrc
= GDB_SIGNAL_INT
;
1197 *sigrc
= State
.exception
;
1205 cr16_extract_unsigned_integer (unsigned char *addr
, int len
)
1209 unsigned char * startaddr
= (unsigned char *)addr
;
1210 unsigned char * endaddr
= startaddr
+ len
;
1214 for (p
= endaddr
; p
> startaddr
;)
1215 retval
= (retval
<< 8) | *--p
;
1221 cr16_store_unsigned_integer (unsigned char *addr
, int len
, uint32 val
)
1224 unsigned char *startaddr
= addr
;
1225 unsigned char *endaddr
= startaddr
+ len
;
1227 for (p
= startaddr
; p
< endaddr
;)
1235 cr16_reg_fetch (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
1238 switch ((enum sim_cr16_regs
) rn
)
1240 case SIM_CR16_R0_REGNUM
:
1241 case SIM_CR16_R1_REGNUM
:
1242 case SIM_CR16_R2_REGNUM
:
1243 case SIM_CR16_R3_REGNUM
:
1244 case SIM_CR16_R4_REGNUM
:
1245 case SIM_CR16_R5_REGNUM
:
1246 case SIM_CR16_R6_REGNUM
:
1247 case SIM_CR16_R7_REGNUM
:
1248 case SIM_CR16_R8_REGNUM
:
1249 case SIM_CR16_R9_REGNUM
:
1250 case SIM_CR16_R10_REGNUM
:
1251 case SIM_CR16_R11_REGNUM
:
1252 cr16_store_unsigned_integer (memory
, 2, GPR (rn
- SIM_CR16_R0_REGNUM
));
1255 case SIM_CR16_R12_REGNUM
:
1256 case SIM_CR16_R13_REGNUM
:
1257 case SIM_CR16_R14_REGNUM
:
1258 case SIM_CR16_R15_REGNUM
:
1259 cr16_store_unsigned_integer (memory
, 4, GPR (rn
- SIM_CR16_R0_REGNUM
));
1262 case SIM_CR16_PC_REGNUM
:
1263 case SIM_CR16_ISP_REGNUM
:
1264 case SIM_CR16_USP_REGNUM
:
1265 case SIM_CR16_INTBASE_REGNUM
:
1266 case SIM_CR16_PSR_REGNUM
:
1267 case SIM_CR16_CFG_REGNUM
:
1268 case SIM_CR16_DBS_REGNUM
:
1269 case SIM_CR16_DCR_REGNUM
:
1270 case SIM_CR16_DSR_REGNUM
:
1271 case SIM_CR16_CAR0_REGNUM
:
1272 case SIM_CR16_CAR1_REGNUM
:
1273 cr16_store_unsigned_integer (memory
, 4, CREG (rn
- SIM_CR16_PC_REGNUM
));
1284 cr16_reg_store (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
1286 SIM_DESC sd
= CPU_STATE (cpu
);
1288 switch ((enum sim_cr16_regs
) rn
)
1290 case SIM_CR16_R0_REGNUM
:
1291 case SIM_CR16_R1_REGNUM
:
1292 case SIM_CR16_R2_REGNUM
:
1293 case SIM_CR16_R3_REGNUM
:
1294 case SIM_CR16_R4_REGNUM
:
1295 case SIM_CR16_R5_REGNUM
:
1296 case SIM_CR16_R6_REGNUM
:
1297 case SIM_CR16_R7_REGNUM
:
1298 case SIM_CR16_R8_REGNUM
:
1299 case SIM_CR16_R9_REGNUM
:
1300 case SIM_CR16_R10_REGNUM
:
1301 case SIM_CR16_R11_REGNUM
:
1302 SET_GPR (rn
- SIM_CR16_R0_REGNUM
, cr16_extract_unsigned_integer (memory
, 2));
1305 case SIM_CR16_R12_REGNUM
:
1306 case SIM_CR16_R13_REGNUM
:
1307 case SIM_CR16_R14_REGNUM
:
1308 case SIM_CR16_R15_REGNUM
:
1309 SET_GPR32 (rn
- SIM_CR16_R0_REGNUM
, cr16_extract_unsigned_integer (memory
, 2));
1312 case SIM_CR16_PC_REGNUM
:
1313 case SIM_CR16_ISP_REGNUM
:
1314 case SIM_CR16_USP_REGNUM
:
1315 case SIM_CR16_INTBASE_REGNUM
:
1316 case SIM_CR16_PSR_REGNUM
:
1317 case SIM_CR16_CFG_REGNUM
:
1318 case SIM_CR16_DBS_REGNUM
:
1319 case SIM_CR16_DCR_REGNUM
:
1320 case SIM_CR16_DSR_REGNUM
:
1321 case SIM_CR16_CAR0_REGNUM
:
1322 case SIM_CR16_CAR1_REGNUM
:
1323 SET_CREG (rn
- SIM_CR16_PC_REGNUM
, cr16_extract_unsigned_integer (memory
, 4));