1 /* Simulation code for the CR16 processor.
2 Copyright (C) 2008-2021 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/>. */
20 /* This must come before any other includes. */
28 #include "sim/callback.h"
32 #include "sim-options.h"
34 #include "gdb/sim-cr16.h"
35 #include "gdb/signals.h"
36 #include "opcode/cr16.h"
45 static struct hash_entry
*lookup_hash (SIM_DESC
, SIM_CPU
*, uint64 ins
, int size
);
46 static void get_operands (operand_desc
*s
, uint64 mcode
, int isize
, int nops
);
52 struct hash_entry
*next
;
60 struct hash_entry hash_table
[MAX_HASH
+1];
63 hash(unsigned long long insn
, int format
)
65 unsigned int i
= 4, tmp
;
68 while ((insn
>> i
) != 0) i
+=4;
70 return ((insn
>> (i
-4)) & 0xf); /* Use last 4 bits as hask key. */
72 return ((insn
& 0xF)); /* Use last 4 bits as hask key. */
76 INLINE
static struct hash_entry
*
77 lookup_hash (SIM_DESC sd
, SIM_CPU
*cpu
, uint64 ins
, int size
)
82 h
= &hash_table
[hash(ins
,1)];
85 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
87 /* Adjuest mask for branch with 2 word instructions. */
88 if ((h
->ops
->mnimonic
!= NULL
) &&
89 ((streq(h
->ops
->mnimonic
,"b") && h
->size
== 2)))
93 while ((ins
& mask
) != (BIN(h
->opcode
, h
->mask
)))
96 sim_engine_halt (sd
, cpu
, NULL
, PC
, sim_stopped
, SIM_SIGILL
);
99 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
100 /* Adjuest mask for branch with 2 word instructions. */
101 if ((streq(h
->ops
->mnimonic
,"b")) && h
->size
== 2)
109 get_operands (operand_desc
*s
, uint64 ins
, int isize
, int nops
)
111 uint32 i
, opn
= 0, start_bit
= 0, op_type
= 0;
112 int32 op_size
= 0, mask
= 0;
114 if (isize
== 1) /* Trunkcate the extra 16 bits of INS. */
117 for (i
=0; i
< 4; ++i
,++opn
)
119 if (s
[opn
].op_type
== dummy
) break;
121 op_type
= s
[opn
].op_type
;
122 start_bit
= s
[opn
].shift
;
123 op_size
= cr16_optab
[op_type
].bit_size
;
127 case imm3
: case imm4
: case imm5
: case imm6
:
130 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
132 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));
134 if (OP
[i
] & ((long)1 << (op_size
-1)))
137 OP
[i
] = ~(OP
[i
]) + 1;
139 OP
[i
] = (unsigned long int)(OP
[i
] & (((long)1 << op_size
) -1));
143 case uimm3
: case uimm3_1
: case uimm4_1
:
147 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1)); break;
149 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));break;
150 default: /* for case 3. */
151 OP
[i
] = ((ins
>> (16 + start_bit
)) & ((1 << op_size
) -1)); break;
161 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
163 OP
[i
] = (ins
& ((1 << op_size
) -1));
166 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
169 OP
[i
] = ((ins
>> (start_bit
+ 16)) & ((1 << op_size
) -1));
172 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
177 case imm16
: case uimm16
:
178 OP
[i
] = ins
& 0xFFFF;
181 case uimm20
: case imm20
:
182 OP
[i
] = ins
& (((long)1 << op_size
) - 1);
185 case imm32
: case uimm32
:
186 OP
[i
] = ins
& 0xFFFFFFFF;
189 case uimm5
: break; /*NOT USED. */
190 OP
[i
] = ins
& ((1 << op_size
) - 1); break;
193 OP
[i
] = (ins
>> 4) & ((1 << 4) - 1);
194 OP
[i
] = (OP
[i
] * 2) + 2;
195 if (OP
[i
] & ((long)1 << 5))
198 OP
[i
] = ~(OP
[i
]) + 1;
199 OP
[i
] = (unsigned long int)(OP
[i
] & 0x1F);
204 OP
[i
] = ((((ins
>> 8) & 0xf) << 4) | (ins
& 0xf));
206 if (OP
[i
] & ((long)1 << 8))
209 OP
[i
] = ~(OP
[i
]) + 1;
210 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFF);
215 OP
[i
] = (ins
& 0xFFFF);
218 OP
[i
] = (OP
[i
] & 0xFFFE);
220 OP
[i
] = ~(OP
[i
]) + 1;
221 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFF);
227 OP
[i
] = (ins
& 0xFFFFFF);
229 OP
[i
] = (ins
& 0xFFFF) | (((ins
>> 24) & 0xf) << 16) |
230 (((ins
>> 16) & 0xf) << 20);
234 OP
[i
] = (OP
[i
] & 0xFFFFFE);
236 OP
[i
] = ~(OP
[i
]) + 1;
237 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFFFF);
243 OP
[i
] = (ins
) & 0xFFFFF;
245 OP
[i
] = (ins
>> start_bit
) & 0xFFFFF;
249 OP
[i
] = ((ins
& 0xFFFF) | (((ins
>> 16) & 0xf) << 20)
250 | (((ins
>> 24) & 0xf) << 16));
252 OP
[i
] = (ins
>> 16) & 0xFFFFFF;
256 case rbase
: break; /* NOT USED. */
257 case rbase_disps20
: case rbase_dispe20
:
258 case rpbase_disps20
: case rpindex_disps20
:
259 OP
[i
] = ((((ins
>> 24)&0xf) << 16)|((ins
) & 0xFFFF));
260 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
263 OP
[i
] = 0; /* 4 bit disp const. */
264 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
267 OP
[i
] = ((ins
>> 8) & 0xF) * 2; /* 4 bit disp const. */
268 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
271 OP
[i
] = ((ins
>> 8) & 0xF); /* 4 bit disp const. */
272 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
275 OP
[i
] = (ins
) & 0xFFFF;
276 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
280 OP
[++i
] = (ins
>> 4) & 0xF; /* get 4 bit for reg. */
281 OP
[++i
] = (ins
>> 8) & 0x1; /* get 1 bit for index-reg. */
283 case rpindex_disps14
:
284 OP
[i
] = (ins
) & 0x3FFF;
285 OP
[++i
] = (ins
>> 14) & 0x1; /* get 1 bit for index-reg. */
286 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
289 OP
[i
] = (ins
) & 0xFFFFF;
290 OP
[++i
] = (ins
>> 24) & 0x1; /* get 1 bit for index-reg. */
291 OP
[++i
] = (ins
>> 20) & 0xF; /* get 4 bit for reg. */
293 case regr
: case regp
: case pregr
: case pregrp
:
297 if (start_bit
== 20) OP
[i
] = (ins
>> 4) & 0xF;
298 else if (start_bit
== 16) OP
[i
] = ins
& 0xF;
300 case 2: OP
[i
] = (ins
>> start_bit
) & 0xF; break;
301 case 3: OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF; break;
306 if (isize
== 1) OP
[i
] = (ins
>> 4) & 0xF;
307 else if (isize
== 2) OP
[i
] = (ins
>> start_bit
) & 0xF;
308 else OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF;
314 /* For ESC on uimm4_1 operand. */
315 if (op_type
== uimm4_1
)
319 /* For increment by 1. */
320 if ((op_type
== pregr
) || (op_type
== pregrp
))
323 /* FIXME: for tracing, update values that need to be updated each
324 instruction decode cycle */
325 State
.trace
.psw
= PSR
;
329 do_run (SIM_DESC sd
, SIM_CPU
*cpu
, uint64 mcode
)
331 struct hash_entry
*h
;
334 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
335 sim_io_printf (sd
, "do_long 0x%" PRIx64
"\n", mcode
);
338 h
= lookup_hash (sd
, cpu
, mcode
, 1);
340 if ((h
== NULL
) || (h
->opcode
== 0))
344 mcode
= (mcode
<< 16) | RW (PC
+ 4);
346 /* Re-set OP list. */
347 OP
[0] = OP
[1] = OP
[2] = OP
[3] = sign_flag
= 0;
349 /* for push/pop/pushrtn with RA instructions. */
350 if ((h
->format
& REG_LIST
) && (mcode
& 0x800000))
351 OP
[2] = 1; /* Set 1 for RA operand. */
353 /* numops == 0 means, no operands. */
354 if (((h
->ops
) != NULL
) && (((h
->ops
)->numops
) != 0))
355 get_operands ((h
->ops
)->operands
, mcode
, h
->size
, (h
->ops
)->numops
);
357 //State.ins_type = h->flags;
359 (h
->ops
->func
) (sd
, cpu
);
365 cr16_pc_get (sim_cpu
*cpu
)
371 cr16_pc_set (sim_cpu
*cpu
, sim_cia pc
)
373 SIM_DESC sd
= CPU_STATE (cpu
);
378 free_state (SIM_DESC sd
)
380 if (STATE_MODULES (sd
) != NULL
)
381 sim_module_uninstall (sd
);
382 sim_cpu_free_all (sd
);
386 static int cr16_reg_fetch (SIM_CPU
*, int, unsigned char *, int);
387 static int cr16_reg_store (SIM_CPU
*, int, unsigned char *, int);
390 sim_open (SIM_OPEN_KIND kind
, struct host_callback_struct
*cb
,
391 struct bfd
*abfd
, char * const *argv
)
394 struct hash_entry
*h
;
395 static int init_p
= 0;
398 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
399 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
401 /* Set default options before parsing user options. */
402 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
404 /* The cpu data is kept in a separately allocated chunk of memory. */
405 if (sim_cpu_alloc_all (sd
, 1) != SIM_RC_OK
)
411 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
417 /* The parser will print an error message for us, so we silently return. */
418 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
424 /* Check for/establish the a reference program image. */
425 if (sim_analyze_program (sd
,
426 (STATE_PROG_ARGV (sd
) != NULL
427 ? *STATE_PROG_ARGV (sd
)
428 : NULL
), abfd
) != SIM_RC_OK
)
434 /* Configure/verify the target byte order and other runtime
435 configuration options. */
436 if (sim_config (sd
) != SIM_RC_OK
)
438 sim_module_uninstall (sd
);
442 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
444 /* Uninstall the modules to avoid memory leaks,
445 file descriptor leaks, etc. */
446 sim_module_uninstall (sd
);
450 /* CPU specific initialization. */
451 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
453 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
455 CPU_REG_FETCH (cpu
) = cr16_reg_fetch
;
456 CPU_REG_STORE (cpu
) = cr16_reg_store
;
457 CPU_PC_FETCH (cpu
) = cr16_pc_get
;
458 CPU_PC_STORE (cpu
) = cr16_pc_set
;
461 /* The CR16 has an interrupt controller at 0xFC00, but we don't currently
462 handle that. Revisit if anyone ever implements operating mode. */
463 /* cr16 memory: There are three separate cr16 memory regions IMEM,
464 UMEM and DMEM. The IMEM and DMEM are further broken down into
465 blocks (very like VM pages). This might not match the hardware,
466 but it matches what the toolchain currently expects. Ugh. */
467 sim_do_commandf (sd
, "memory-size %#x", 20 * 1024 * 1024);
469 /* put all the opcodes in the hash table. */
472 for (s
= Simops
; s
->func
; s
++)
477 h
= &hash_table
[hash(s
->opcode
, 0)];
481 if (((s
->opcode
<< 1) >> 4) != 0)
482 h
= &hash_table
[hash((s
->opcode
<< 1) >> 4, 0)];
484 h
= &hash_table
[hash((s
->opcode
<< 1), 0)];
488 if ((s
->opcode
>> 4) != 0)
489 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
491 h
= &hash_table
[hash(s
->opcode
, 0)];
495 if (((s
->opcode
>> 1) >> 4) != 0)
496 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
498 h
= &hash_table
[hash((s
->opcode
>> 1), 0)];
502 if ((s
->opcode
>> 8) != 0)
503 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
504 else if ((s
->opcode
>> 4) != 0)
505 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
507 h
= &hash_table
[hash(s
->opcode
, 0)];
511 if ((s
->opcode
>> 8) != 0)
512 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
513 else if ((s
->opcode
>> 4) != 0)
514 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
516 h
= &hash_table
[hash(s
->opcode
, 0)];
520 if (((s
->opcode
>> 1) >> 8) != 0)
521 h
= &hash_table
[hash((s
->opcode
>>1) >> 8, 0)];
522 else if (((s
->opcode
>> 1) >> 4) != 0)
523 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
525 h
= &hash_table
[hash((s
->opcode
>>1), 0)];
529 if ((s
->opcode
>> 0xc) != 0)
530 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
531 else if ((s
->opcode
>> 8) != 0)
532 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
533 else if ((s
->opcode
>> 4) != 0)
534 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
536 h
= &hash_table
[hash(s
->opcode
, 0)];
540 if ((s
->opcode
>> 16) != 0)
541 h
= &hash_table
[hash(s
->opcode
>> 16, 0)];
542 else if ((s
->opcode
>> 12) != 0)
543 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
544 else if ((s
->opcode
>> 8) != 0)
545 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
546 else if ((s
->opcode
>> 4) != 0)
547 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
549 h
= &hash_table
[hash(s
->opcode
, 0)];
556 /* go to the last entry in the chain. */
562 h
->next
= (struct hash_entry
*) calloc(1,sizeof(struct hash_entry
));
564 perror ("malloc failure");
570 h
->opcode
= s
->opcode
;
571 h
->format
= s
->format
;
580 step_once (SIM_DESC sd
, SIM_CPU
*cpu
)
582 uint32 curr_ins_size
= 0;
583 uint64 mcode
= RLW (PC
);
585 State
.pc_changed
= 0;
587 curr_ins_size
= do_run (sd
, cpu
, mcode
);
590 sim_io_printf (sd
, "INS: PC=0x%X, mcode=0x%X\n", PC
, mcode
);
593 if (curr_ins_size
== 0)
594 sim_engine_halt (sd
, cpu
, NULL
, PC
, sim_exited
, GPR (2));
595 else if (!State
.pc_changed
)
596 SET_PC (PC
+ (curr_ins_size
* 2)); /* For word instructions. */
599 /* Check for a breakpoint trap on this instruction. This
600 overrides any pending branches or loops */
601 if (PSR_DB
&& PC
== DBS
)
605 SET_PC (SDBT_VECTOR_START
);
609 /* Writeback all the DATA / PC changes */
614 sim_engine_run (SIM_DESC sd
,
615 int next_cpu_nr
, /* ignore */
616 int nr_cpus
, /* ignore */
621 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
623 cpu
= STATE_CPU (sd
, 0);
630 case GDB_SIGNAL_SEGV
:
633 JMP (AE_VECTOR_START
);
639 SET_HW_PSR ((PSR
& (PSR_C_BIT
)));
640 JMP (RIE_VECTOR_START
);
651 if (sim_events_tick (sd
))
652 sim_events_process (sd
);
657 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
658 char * const *argv
, char * const *env
)
660 bfd_vma start_address
;
662 /* reset all state information */
663 memset (&State
, 0, sizeof (State
));
665 /* There was a hack here to copy the values of argc and argv into r0
666 and r1. The values were also saved into some high memory that
667 won't be overwritten by the stack (0x7C00). The reason for doing
668 this was to allow the 'run' program to accept arguments. Without
669 the hack, this is not possible anymore. If the simulator is run
670 from the debugger, arguments cannot be passed in, so this makes
675 start_address
= bfd_get_start_address (abfd
);
680 sim_io_printf (sd
, "sim_create_inferior: PC=0x%" BFD_VMA_FMT
"x\n",
684 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
685 SET_CREG (PC_CR
, start_address
);
693 cr16_extract_unsigned_integer (unsigned char *addr
, int len
)
697 unsigned char * startaddr
= (unsigned char *)addr
;
698 unsigned char * endaddr
= startaddr
+ len
;
702 for (p
= endaddr
; p
> startaddr
;)
703 retval
= (retval
<< 8) | *--p
;
709 cr16_store_unsigned_integer (unsigned char *addr
, int len
, uint32 val
)
712 unsigned char *startaddr
= addr
;
713 unsigned char *endaddr
= startaddr
+ len
;
715 for (p
= startaddr
; p
< endaddr
;)
723 cr16_reg_fetch (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
726 switch ((enum sim_cr16_regs
) rn
)
728 case SIM_CR16_R0_REGNUM
:
729 case SIM_CR16_R1_REGNUM
:
730 case SIM_CR16_R2_REGNUM
:
731 case SIM_CR16_R3_REGNUM
:
732 case SIM_CR16_R4_REGNUM
:
733 case SIM_CR16_R5_REGNUM
:
734 case SIM_CR16_R6_REGNUM
:
735 case SIM_CR16_R7_REGNUM
:
736 case SIM_CR16_R8_REGNUM
:
737 case SIM_CR16_R9_REGNUM
:
738 case SIM_CR16_R10_REGNUM
:
739 case SIM_CR16_R11_REGNUM
:
740 cr16_store_unsigned_integer (memory
, 2, GPR (rn
- SIM_CR16_R0_REGNUM
));
743 case SIM_CR16_R12_REGNUM
:
744 case SIM_CR16_R13_REGNUM
:
745 case SIM_CR16_R14_REGNUM
:
746 case SIM_CR16_R15_REGNUM
:
747 cr16_store_unsigned_integer (memory
, 4, GPR (rn
- SIM_CR16_R0_REGNUM
));
750 case SIM_CR16_PC_REGNUM
:
751 case SIM_CR16_ISP_REGNUM
:
752 case SIM_CR16_USP_REGNUM
:
753 case SIM_CR16_INTBASE_REGNUM
:
754 case SIM_CR16_PSR_REGNUM
:
755 case SIM_CR16_CFG_REGNUM
:
756 case SIM_CR16_DBS_REGNUM
:
757 case SIM_CR16_DCR_REGNUM
:
758 case SIM_CR16_DSR_REGNUM
:
759 case SIM_CR16_CAR0_REGNUM
:
760 case SIM_CR16_CAR1_REGNUM
:
761 cr16_store_unsigned_integer (memory
, 4, CREG (rn
- SIM_CR16_PC_REGNUM
));
772 cr16_reg_store (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
774 SIM_DESC sd
= CPU_STATE (cpu
);
776 switch ((enum sim_cr16_regs
) rn
)
778 case SIM_CR16_R0_REGNUM
:
779 case SIM_CR16_R1_REGNUM
:
780 case SIM_CR16_R2_REGNUM
:
781 case SIM_CR16_R3_REGNUM
:
782 case SIM_CR16_R4_REGNUM
:
783 case SIM_CR16_R5_REGNUM
:
784 case SIM_CR16_R6_REGNUM
:
785 case SIM_CR16_R7_REGNUM
:
786 case SIM_CR16_R8_REGNUM
:
787 case SIM_CR16_R9_REGNUM
:
788 case SIM_CR16_R10_REGNUM
:
789 case SIM_CR16_R11_REGNUM
:
790 SET_GPR (rn
- SIM_CR16_R0_REGNUM
, cr16_extract_unsigned_integer (memory
, 2));
793 case SIM_CR16_R12_REGNUM
:
794 case SIM_CR16_R13_REGNUM
:
795 case SIM_CR16_R14_REGNUM
:
796 case SIM_CR16_R15_REGNUM
:
797 SET_GPR32 (rn
- SIM_CR16_R0_REGNUM
, cr16_extract_unsigned_integer (memory
, 2));
800 case SIM_CR16_PC_REGNUM
:
801 case SIM_CR16_ISP_REGNUM
:
802 case SIM_CR16_USP_REGNUM
:
803 case SIM_CR16_INTBASE_REGNUM
:
804 case SIM_CR16_PSR_REGNUM
:
805 case SIM_CR16_CFG_REGNUM
:
806 case SIM_CR16_DBS_REGNUM
:
807 case SIM_CR16_DCR_REGNUM
:
808 case SIM_CR16_DSR_REGNUM
:
809 case SIM_CR16_CAR0_REGNUM
:
810 case SIM_CR16_CAR1_REGNUM
:
811 SET_CREG (rn
- SIM_CR16_PC_REGNUM
, cr16_extract_unsigned_integer (memory
, 4));