8925d856de13ca3e8b0480005b13f1860fe6ddf9
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
);
50 struct hash_entry
*next
;
58 struct hash_entry hash_table
[MAX_HASH
+1];
61 hash(unsigned long long insn
, int format
)
63 unsigned int i
= 4, tmp
;
66 while ((insn
>> i
) != 0) i
+=4;
68 return ((insn
>> (i
-4)) & 0xf); /* Use last 4 bits as hask key. */
70 return ((insn
& 0xF)); /* Use last 4 bits as hask key. */
74 INLINE
static struct hash_entry
*
75 lookup_hash (SIM_DESC sd
, SIM_CPU
*cpu
, uint64 ins
, int size
)
80 h
= &hash_table
[hash(ins
,1)];
83 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
85 /* Adjuest mask for branch with 2 word instructions. */
86 if ((h
->ops
->mnimonic
!= NULL
) &&
87 ((streq(h
->ops
->mnimonic
,"b") && h
->size
== 2)))
91 while ((ins
& mask
) != (BIN(h
->opcode
, h
->mask
)))
94 sim_engine_halt (sd
, cpu
, NULL
, PC
, sim_stopped
, SIM_SIGILL
);
97 mask
= (((1 << (32 - h
->mask
)) -1) << h
->mask
);
98 /* Adjuest mask for branch with 2 word instructions. */
99 if ((streq(h
->ops
->mnimonic
,"b")) && h
->size
== 2)
107 get_operands (operand_desc
*s
, uint64 ins
, int isize
, int nops
)
109 uint32 i
, opn
= 0, start_bit
= 0, op_type
= 0;
110 int32 op_size
= 0, mask
= 0;
112 if (isize
== 1) /* Trunkcate the extra 16 bits of INS. */
115 for (i
=0; i
< 4; ++i
,++opn
)
117 if (s
[opn
].op_type
== dummy
) break;
119 op_type
= s
[opn
].op_type
;
120 start_bit
= s
[opn
].shift
;
121 op_size
= cr16_optab
[op_type
].bit_size
;
125 case imm3
: case imm4
: case imm5
: case imm6
:
128 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
130 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));
132 if (OP
[i
] & ((long)1 << (op_size
-1)))
135 OP
[i
] = ~(OP
[i
]) + 1;
137 OP
[i
] = (unsigned long int)(OP
[i
] & (((long)1 << op_size
) -1));
141 case uimm3
: case uimm3_1
: case uimm4_1
:
145 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1)); break;
147 OP
[i
] = ((ins
>> (32 - start_bit
)) & ((1 << op_size
) -1));break;
148 default: /* for case 3. */
149 OP
[i
] = ((ins
>> (16 + start_bit
)) & ((1 << op_size
) -1)); break;
159 OP
[i
] = ((ins
>> 4) & ((1 << op_size
) -1));
161 OP
[i
] = (ins
& ((1 << op_size
) -1));
164 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
167 OP
[i
] = ((ins
>> (start_bit
+ 16)) & ((1 << op_size
) -1));
170 OP
[i
] = ((ins
>> start_bit
) & ((1 << op_size
) -1));
175 case imm16
: case uimm16
:
176 OP
[i
] = ins
& 0xFFFF;
179 case uimm20
: case imm20
:
180 OP
[i
] = ins
& (((long)1 << op_size
) - 1);
183 case imm32
: case uimm32
:
184 OP
[i
] = ins
& 0xFFFFFFFF;
187 case uimm5
: break; /*NOT USED. */
188 OP
[i
] = ins
& ((1 << op_size
) - 1); break;
191 OP
[i
] = (ins
>> 4) & ((1 << 4) - 1);
192 OP
[i
] = (OP
[i
] * 2) + 2;
193 if (OP
[i
] & ((long)1 << 5))
196 OP
[i
] = ~(OP
[i
]) + 1;
197 OP
[i
] = (unsigned long int)(OP
[i
] & 0x1F);
202 OP
[i
] = ((((ins
>> 8) & 0xf) << 4) | (ins
& 0xf));
204 if (OP
[i
] & ((long)1 << 8))
207 OP
[i
] = ~(OP
[i
]) + 1;
208 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFF);
213 OP
[i
] = (ins
& 0xFFFF);
216 OP
[i
] = (OP
[i
] & 0xFFFE);
218 OP
[i
] = ~(OP
[i
]) + 1;
219 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFF);
225 OP
[i
] = (ins
& 0xFFFFFF);
227 OP
[i
] = (ins
& 0xFFFF) | (((ins
>> 24) & 0xf) << 16) |
228 (((ins
>> 16) & 0xf) << 20);
232 OP
[i
] = (OP
[i
] & 0xFFFFFE);
234 OP
[i
] = ~(OP
[i
]) + 1;
235 OP
[i
] = (unsigned long int)(OP
[i
] & 0xFFFFFF);
241 OP
[i
] = (ins
) & 0xFFFFF;
243 OP
[i
] = (ins
>> start_bit
) & 0xFFFFF;
247 OP
[i
] = ((ins
& 0xFFFF) | (((ins
>> 16) & 0xf) << 20)
248 | (((ins
>> 24) & 0xf) << 16));
250 OP
[i
] = (ins
>> 16) & 0xFFFFFF;
254 case rbase
: break; /* NOT USED. */
255 case rbase_disps20
: case rbase_dispe20
:
256 case rpbase_disps20
: case rpindex_disps20
:
257 OP
[i
] = ((((ins
>> 24)&0xf) << 16)|((ins
) & 0xFFFF));
258 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
261 OP
[i
] = 0; /* 4 bit disp const. */
262 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
265 OP
[i
] = ((ins
>> 8) & 0xF) * 2; /* 4 bit disp const. */
266 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
269 OP
[i
] = ((ins
>> 8) & 0xF); /* 4 bit disp const. */
270 OP
[++i
] = (ins
) & 0xF; /* get 4 bit for reg. */
273 OP
[i
] = (ins
) & 0xFFFF;
274 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
278 OP
[++i
] = (ins
>> 4) & 0xF; /* get 4 bit for reg. */
279 OP
[++i
] = (ins
>> 8) & 0x1; /* get 1 bit for index-reg. */
281 case rpindex_disps14
:
282 OP
[i
] = (ins
) & 0x3FFF;
283 OP
[++i
] = (ins
>> 14) & 0x1; /* get 1 bit for index-reg. */
284 OP
[++i
] = (ins
>> 16) & 0xF; /* get 4 bit for reg. */
287 OP
[i
] = (ins
) & 0xFFFFF;
288 OP
[++i
] = (ins
>> 24) & 0x1; /* get 1 bit for index-reg. */
289 OP
[++i
] = (ins
>> 20) & 0xF; /* get 4 bit for reg. */
291 case regr
: case regp
: case pregr
: case pregrp
:
295 if (start_bit
== 20) OP
[i
] = (ins
>> 4) & 0xF;
296 else if (start_bit
== 16) OP
[i
] = ins
& 0xF;
298 case 2: OP
[i
] = (ins
>> start_bit
) & 0xF; break;
299 case 3: OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF; break;
304 if (isize
== 1) OP
[i
] = (ins
>> 4) & 0xF;
305 else if (isize
== 2) OP
[i
] = (ins
>> start_bit
) & 0xF;
306 else OP
[i
] = (ins
>> (start_bit
+ 16)) & 0xF;
312 /* For ESC on uimm4_1 operand. */
313 if (op_type
== uimm4_1
)
317 /* For increment by 1. */
318 if ((op_type
== pregr
) || (op_type
== pregrp
))
321 /* FIXME: for tracing, update values that need to be updated each
322 instruction decode cycle */
323 State
.trace
.psw
= PSR
;
327 do_run (SIM_DESC sd
, SIM_CPU
*cpu
, uint64 mcode
)
329 host_callback
*cr16_callback
= STATE_CALLBACK (sd
);
330 struct hash_entry
*h
;
333 if ((cr16_debug
& DEBUG_INSTRUCTION
) != 0)
334 (*cr16_callback
->printf_filtered
) (cr16_callback
, "do_long 0x%x\n", mcode
);
337 h
= lookup_hash (sd
, cpu
, mcode
, 1);
339 if ((h
== NULL
) || (h
->opcode
== 0))
343 mcode
= (mcode
<< 16) | RW (PC
+ 4);
345 /* Re-set OP list. */
346 OP
[0] = OP
[1] = OP
[2] = OP
[3] = sign_flag
= 0;
348 /* for push/pop/pushrtn with RA instructions. */
349 if ((h
->format
& REG_LIST
) && (mcode
& 0x800000))
350 OP
[2] = 1; /* Set 1 for RA operand. */
352 /* numops == 0 means, no operands. */
353 if (((h
->ops
) != NULL
) && (((h
->ops
)->numops
) != 0))
354 get_operands ((h
->ops
)->operands
, mcode
, h
->size
, (h
->ops
)->numops
);
356 //State.ins_type = h->flags;
358 (h
->ops
->func
) (sd
, cpu
);
364 cr16_pc_get (sim_cpu
*cpu
)
370 cr16_pc_set (sim_cpu
*cpu
, sim_cia pc
)
372 SIM_DESC sd
= CPU_STATE (cpu
);
377 free_state (SIM_DESC sd
)
379 if (STATE_MODULES (sd
) != NULL
)
380 sim_module_uninstall (sd
);
381 sim_cpu_free_all (sd
);
385 static int cr16_reg_fetch (SIM_CPU
*, int, unsigned char *, int);
386 static int cr16_reg_store (SIM_CPU
*, int, unsigned char *, int);
389 sim_open (SIM_OPEN_KIND kind
, struct host_callback_struct
*cb
, struct bfd
*abfd
, char **argv
)
392 struct hash_entry
*h
;
393 static int init_p
= 0;
396 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
397 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
399 /* The cpu data is kept in a separately allocated chunk of memory. */
400 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
406 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
412 /* getopt will print the error message so we just have to exit if this fails.
413 FIXME: Hmmm... in the case of gdb we need getopt to call
415 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
421 /* Check for/establish the a reference program image. */
422 if (sim_analyze_program (sd
,
423 (STATE_PROG_ARGV (sd
) != NULL
424 ? *STATE_PROG_ARGV (sd
)
425 : NULL
), abfd
) != SIM_RC_OK
)
431 /* Configure/verify the target byte order and other runtime
432 configuration options. */
433 if (sim_config (sd
) != SIM_RC_OK
)
435 sim_module_uninstall (sd
);
439 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
441 /* Uninstall the modules to avoid memory leaks,
442 file descriptor leaks, etc. */
443 sim_module_uninstall (sd
);
447 /* CPU specific initialization. */
448 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
450 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
452 CPU_REG_FETCH (cpu
) = cr16_reg_fetch
;
453 CPU_REG_STORE (cpu
) = cr16_reg_store
;
454 CPU_PC_FETCH (cpu
) = cr16_pc_get
;
455 CPU_PC_STORE (cpu
) = cr16_pc_set
;
458 /* The CR16 has an interrupt controller at 0xFC00, but we don't currently
459 handle that. Revisit if anyone ever implements operating mode. */
460 /* cr16 memory: There are three separate cr16 memory regions IMEM,
461 UMEM and DMEM. The IMEM and DMEM are further broken down into
462 blocks (very like VM pages). This might not match the hardware,
463 but it matches what the toolchain currently expects. Ugh. */
464 sim_do_commandf (sd
, "memory-size %#x", 20 * 1024 * 1024);
468 /* put all the opcodes in the hash table. */
471 for (s
= Simops
; s
->func
; s
++)
476 h
= &hash_table
[hash(s
->opcode
, 0)];
480 if (((s
->opcode
<< 1) >> 4) != 0)
481 h
= &hash_table
[hash((s
->opcode
<< 1) >> 4, 0)];
483 h
= &hash_table
[hash((s
->opcode
<< 1), 0)];
487 if ((s
->opcode
>> 4) != 0)
488 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
490 h
= &hash_table
[hash(s
->opcode
, 0)];
494 if (((s
->opcode
>> 1) >> 4) != 0)
495 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
497 h
= &hash_table
[hash((s
->opcode
>> 1), 0)];
501 if ((s
->opcode
>> 8) != 0)
502 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
503 else if ((s
->opcode
>> 4) != 0)
504 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
506 h
= &hash_table
[hash(s
->opcode
, 0)];
510 if ((s
->opcode
>> 8) != 0)
511 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
512 else if ((s
->opcode
>> 4) != 0)
513 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
515 h
= &hash_table
[hash(s
->opcode
, 0)];
519 if (((s
->opcode
>> 1) >> 8) != 0)
520 h
= &hash_table
[hash((s
->opcode
>>1) >> 8, 0)];
521 else if (((s
->opcode
>> 1) >> 4) != 0)
522 h
= &hash_table
[hash((s
->opcode
>>1) >> 4, 0)];
524 h
= &hash_table
[hash((s
->opcode
>>1), 0)];
528 if ((s
->opcode
>> 0xc) != 0)
529 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
530 else if ((s
->opcode
>> 8) != 0)
531 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
532 else if ((s
->opcode
>> 4) != 0)
533 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
535 h
= &hash_table
[hash(s
->opcode
, 0)];
539 if ((s
->opcode
>> 16) != 0)
540 h
= &hash_table
[hash(s
->opcode
>> 16, 0)];
541 else if ((s
->opcode
>> 12) != 0)
542 h
= &hash_table
[hash(s
->opcode
>> 12, 0)];
543 else if ((s
->opcode
>> 8) != 0)
544 h
= &hash_table
[hash(s
->opcode
>> 8, 0)];
545 else if ((s
->opcode
>> 4) != 0)
546 h
= &hash_table
[hash(s
->opcode
>> 4, 0)];
548 h
= &hash_table
[hash(s
->opcode
, 0)];
554 /* go to the last entry in the chain. */
560 h
->next
= (struct hash_entry
*) calloc(1,sizeof(struct hash_entry
));
562 perror ("malloc failure");
568 h
->opcode
= s
->opcode
;
569 h
->format
= s
->format
;
578 step_once (SIM_DESC sd
, SIM_CPU
*cpu
)
580 uint32 curr_ins_size
= 0;
581 uint64 mcode
= RLW (PC
);
583 State
.pc_changed
= 0;
585 curr_ins_size
= do_run (sd
, cpu
, mcode
);
588 (*cr16_callback
->printf_filtered
) (cr16_callback
, "INS: PC=0x%X, mcode=0x%X\n", PC
, mcode
);
591 if (curr_ins_size
== 0)
592 sim_engine_halt (sd
, cpu
, NULL
, PC
, sim_exited
, GPR (2));
593 else if (!State
.pc_changed
)
594 SET_PC (PC
+ (curr_ins_size
* 2)); /* For word instructions. */
597 /* Check for a breakpoint trap on this instruction. This
598 overrides any pending branches or loops */
599 if (PSR_DB
&& PC
== DBS
)
603 SET_PC (SDBT_VECTOR_START
);
607 /* Writeback all the DATA / PC changes */
612 sim_engine_run (SIM_DESC sd
,
613 int next_cpu_nr
, /* ignore */
614 int nr_cpus
, /* ignore */
619 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
621 cpu
= STATE_CPU (sd
, 0);
628 case GDB_SIGNAL_SEGV
:
631 JMP (AE_VECTOR_START
);
637 SET_HW_PSR ((PSR
& (PSR_C_BIT
)));
638 JMP (RIE_VECTOR_START
);
649 if (sim_events_tick (sd
))
650 sim_events_process (sd
);
655 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
, char **argv
, char **env
)
657 bfd_vma start_address
;
659 /* reset all state information */
660 memset (&State
, 0, sizeof (State
));
662 /* There was a hack here to copy the values of argc and argv into r0
663 and r1. The values were also saved into some high memory that
664 won't be overwritten by the stack (0x7C00). The reason for doing
665 this was to allow the 'run' program to accept arguments. Without
666 the hack, this is not possible anymore. If the simulator is run
667 from the debugger, arguments cannot be passed in, so this makes
672 start_address
= bfd_get_start_address (abfd
);
677 (*cr16_callback
->printf_filtered
) (cr16_callback
, "sim_create_inferior: PC=0x%lx\n", (long) start_address
);
680 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
681 SET_CREG (PC_CR
, start_address
);
689 cr16_extract_unsigned_integer (unsigned char *addr
, int len
)
693 unsigned char * startaddr
= (unsigned char *)addr
;
694 unsigned char * endaddr
= startaddr
+ len
;
698 for (p
= endaddr
; p
> startaddr
;)
699 retval
= (retval
<< 8) | *--p
;
705 cr16_store_unsigned_integer (unsigned char *addr
, int len
, uint32 val
)
708 unsigned char *startaddr
= addr
;
709 unsigned char *endaddr
= startaddr
+ len
;
711 for (p
= startaddr
; p
< endaddr
;)
719 cr16_reg_fetch (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
722 switch ((enum sim_cr16_regs
) rn
)
724 case SIM_CR16_R0_REGNUM
:
725 case SIM_CR16_R1_REGNUM
:
726 case SIM_CR16_R2_REGNUM
:
727 case SIM_CR16_R3_REGNUM
:
728 case SIM_CR16_R4_REGNUM
:
729 case SIM_CR16_R5_REGNUM
:
730 case SIM_CR16_R6_REGNUM
:
731 case SIM_CR16_R7_REGNUM
:
732 case SIM_CR16_R8_REGNUM
:
733 case SIM_CR16_R9_REGNUM
:
734 case SIM_CR16_R10_REGNUM
:
735 case SIM_CR16_R11_REGNUM
:
736 cr16_store_unsigned_integer (memory
, 2, GPR (rn
- SIM_CR16_R0_REGNUM
));
739 case SIM_CR16_R12_REGNUM
:
740 case SIM_CR16_R13_REGNUM
:
741 case SIM_CR16_R14_REGNUM
:
742 case SIM_CR16_R15_REGNUM
:
743 cr16_store_unsigned_integer (memory
, 4, GPR (rn
- SIM_CR16_R0_REGNUM
));
746 case SIM_CR16_PC_REGNUM
:
747 case SIM_CR16_ISP_REGNUM
:
748 case SIM_CR16_USP_REGNUM
:
749 case SIM_CR16_INTBASE_REGNUM
:
750 case SIM_CR16_PSR_REGNUM
:
751 case SIM_CR16_CFG_REGNUM
:
752 case SIM_CR16_DBS_REGNUM
:
753 case SIM_CR16_DCR_REGNUM
:
754 case SIM_CR16_DSR_REGNUM
:
755 case SIM_CR16_CAR0_REGNUM
:
756 case SIM_CR16_CAR1_REGNUM
:
757 cr16_store_unsigned_integer (memory
, 4, CREG (rn
- SIM_CR16_PC_REGNUM
));
768 cr16_reg_store (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
770 SIM_DESC sd
= CPU_STATE (cpu
);
772 switch ((enum sim_cr16_regs
) rn
)
774 case SIM_CR16_R0_REGNUM
:
775 case SIM_CR16_R1_REGNUM
:
776 case SIM_CR16_R2_REGNUM
:
777 case SIM_CR16_R3_REGNUM
:
778 case SIM_CR16_R4_REGNUM
:
779 case SIM_CR16_R5_REGNUM
:
780 case SIM_CR16_R6_REGNUM
:
781 case SIM_CR16_R7_REGNUM
:
782 case SIM_CR16_R8_REGNUM
:
783 case SIM_CR16_R9_REGNUM
:
784 case SIM_CR16_R10_REGNUM
:
785 case SIM_CR16_R11_REGNUM
:
786 SET_GPR (rn
- SIM_CR16_R0_REGNUM
, cr16_extract_unsigned_integer (memory
, 2));
789 case SIM_CR16_R12_REGNUM
:
790 case SIM_CR16_R13_REGNUM
:
791 case SIM_CR16_R14_REGNUM
:
792 case SIM_CR16_R15_REGNUM
:
793 SET_GPR32 (rn
- SIM_CR16_R0_REGNUM
, cr16_extract_unsigned_integer (memory
, 2));
796 case SIM_CR16_PC_REGNUM
:
797 case SIM_CR16_ISP_REGNUM
:
798 case SIM_CR16_USP_REGNUM
:
799 case SIM_CR16_INTBASE_REGNUM
:
800 case SIM_CR16_PSR_REGNUM
:
801 case SIM_CR16_CFG_REGNUM
:
802 case SIM_CR16_DBS_REGNUM
:
803 case SIM_CR16_DCR_REGNUM
:
804 case SIM_CR16_DSR_REGNUM
:
805 case SIM_CR16_CAR0_REGNUM
:
806 case SIM_CR16_CAR1_REGNUM
:
807 SET_CREG (rn
- SIM_CR16_PC_REGNUM
, cr16_extract_unsigned_integer (memory
, 4));
This page took 0.045261 seconds and 4 git commands to generate.