]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/cr16/interp.c
sim: split sim-signal.h include out
[thirdparty/binutils-gdb.git] / sim / cr16 / interp.c
CommitLineData
fee8ec00 1/* Simulation code for the CR16 processor.
3666a048 2 Copyright (C) 2008-2021 Free Software Foundation, Inc.
fee8ec00
SR
3 Contributed by M Ranga Swami Reddy <MR.Swami.Reddy@nsc.com>
4
5 This file is part of GDB, the GNU debugger.
6
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
dc3cf14f 9 the Free Software Foundation; either version 3, or (at your option)
fee8ec00
SR
10 any later version.
11
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.
16
052d9a54
SR
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/>. */
fee8ec00 19
6df01ab8
MF
20/* This must come before any other includes. */
21#include "defs.h"
22
5aedb83b 23#include <inttypes.h>
fee8ec00 24#include <signal.h>
26687999
MF
25#include <stdlib.h>
26#include <string.h>
fee8ec00 27#include "bfd.h"
df68e12b
MF
28#include "sim/callback.h"
29#include "sim/sim.h"
fee8ec00 30
247ac9ee
MF
31#include "sim-main.h"
32#include "sim-options.h"
1fef66b0 33#include "sim-signal.h"
247ac9ee 34
fee8ec00
SR
35#include "gdb/sim-cr16.h"
36#include "gdb/signals.h"
37#include "opcode/cr16.h"
38
7eb99e5e
MF
39struct _state State;
40
fee8ec00
SR
41int cr16_debug;
42
fee8ec00
SR
43uint32 OP[4];
44uint32 sign_flag;
45
267b3b8e 46static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint64 ins, int size);
bdca5ee4 47static void get_operands (operand_desc *s, uint64 mcode, int isize, int nops);
fee8ec00 48
052d9a54
SR
49#define MAX_HASH 16
50
51struct hash_entry
52{
53 struct hash_entry *next;
54 uint32 opcode;
55 uint32 mask;
56 int format;
57 int size;
58 struct simops *ops;
59};
60
61struct hash_entry hash_table[MAX_HASH+1];
62
63INLINE static long
64hash(unsigned long long insn, int format)
65{
66 unsigned int i = 4, tmp;
67 if (format)
68 {
69 while ((insn >> i) != 0) i +=4;
70
71 return ((insn >> (i-4)) & 0xf); /* Use last 4 bits as hask key. */
72 }
73 return ((insn & 0xF)); /* Use last 4 bits as hask key. */
74}
75
76
77INLINE static struct hash_entry *
267b3b8e 78lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint64 ins, int size)
052d9a54
SR
79{
80 uint32 mask;
81 struct hash_entry *h;
82
83 h = &hash_table[hash(ins,1)];
84
85
86 mask = (((1 << (32 - h->mask)) -1) << h->mask);
87
88 /* Adjuest mask for branch with 2 word instructions. */
89 if ((h->ops->mnimonic != NULL) &&
90 ((streq(h->ops->mnimonic,"b") && h->size == 2)))
91 mask = 0xff0f0000;
92
93
94 while ((ins & mask) != (BIN(h->opcode, h->mask)))
95 {
96 if (h->next == NULL)
0ef7f981 97 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL);
052d9a54
SR
98 h = h->next;
99
100 mask = (((1 << (32 - h->mask)) -1) << h->mask);
101 /* Adjuest mask for branch with 2 word instructions. */
102 if ((streq(h->ops->mnimonic,"b")) && h->size == 2)
103 mask = 0xff0f0000;
104
105 }
106 return (h);
107}
fee8ec00
SR
108
109INLINE static void
052d9a54 110get_operands (operand_desc *s, uint64 ins, int isize, int nops)
fee8ec00
SR
111{
112 uint32 i, opn = 0, start_bit = 0, op_type = 0;
113 int32 op_size = 0, mask = 0;
114
115 if (isize == 1) /* Trunkcate the extra 16 bits of INS. */
116 ins = ins >> 16;
117
052d9a54 118 for (i=0; i < 4; ++i,++opn)
fee8ec00 119 {
052d9a54 120 if (s[opn].op_type == dummy) break;
fee8ec00 121
052d9a54 122 op_type = s[opn].op_type;
fee8ec00
SR
123 start_bit = s[opn].shift;
124 op_size = cr16_optab[op_type].bit_size;
125
126 switch (op_type)
052d9a54 127 {
fee8ec00 128 case imm3: case imm4: case imm5: case imm6:
052d9a54
SR
129 {
130 if (isize == 1)
131 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
fee8ec00 132 else
052d9a54
SR
133 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));
134
135 if (OP[i] & ((long)1 << (op_size -1)))
136 {
137 sign_flag = 1;
138 OP[i] = ~(OP[i]) + 1;
139 }
140 OP[i] = (unsigned long int)(OP[i] & (((long)1 << op_size) -1));
fee8ec00 141 }
052d9a54 142 break;
fee8ec00
SR
143
144 case uimm3: case uimm3_1: case uimm4_1:
052d9a54
SR
145 switch (isize)
146 {
147 case 1:
148 OP[i] = ((ins >> 4) & ((1 << op_size) -1)); break;
149 case 2:
150 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));break;
151 default: /* for case 3. */
152 OP[i] = ((ins >> (16 + start_bit)) & ((1 << op_size) -1)); break;
153 break;
154 }
155 break;
fee8ec00
SR
156
157 case uimm4:
052d9a54
SR
158 switch (isize)
159 {
160 case 1:
161 if (start_bit == 20)
162 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
163 else
164 OP[i] = (ins & ((1 << op_size) -1));
165 break;
166 case 2:
167 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
168 break;
169 case 3:
170 OP[i] = ((ins >> (start_bit + 16)) & ((1 << op_size) -1));
171 break;
172 default:
173 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
174 break;
175 }
176 break;
fee8ec00
SR
177
178 case imm16: case uimm16:
179 OP[i] = ins & 0xFFFF;
052d9a54 180 break;
fee8ec00
SR
181
182 case uimm20: case imm20:
052d9a54
SR
183 OP[i] = ins & (((long)1 << op_size) - 1);
184 break;
fee8ec00
SR
185
186 case imm32: case uimm32:
187 OP[i] = ins & 0xFFFFFFFF;
052d9a54 188 break;
fee8ec00 189
052d9a54 190 case uimm5: break; /*NOT USED. */
fee8ec00
SR
191 OP[i] = ins & ((1 << op_size) - 1); break;
192
193 case disps5:
194 OP[i] = (ins >> 4) & ((1 << 4) - 1);
195 OP[i] = (OP[i] * 2) + 2;
052d9a54
SR
196 if (OP[i] & ((long)1 << 5))
197 {
198 sign_flag = 1;
199 OP[i] = ~(OP[i]) + 1;
200 OP[i] = (unsigned long int)(OP[i] & 0x1F);
201 }
202 break;
203
204 case dispe9:
205 OP[i] = ((((ins >> 8) & 0xf) << 4) | (ins & 0xf));
206 OP[i] <<= 1;
207 if (OP[i] & ((long)1 << 8))
208 {
209 sign_flag = 1;
210 OP[i] = ~(OP[i]) + 1;
211 OP[i] = (unsigned long int)(OP[i] & 0xFF);
212 }
213 break;
214
215 case disps17:
216 OP[i] = (ins & 0xFFFF);
217 if (OP[i] & 1)
218 {
219 OP[i] = (OP[i] & 0xFFFE);
220 sign_flag = 1;
221 OP[i] = ~(OP[i]) + 1;
222 OP[i] = (unsigned long int)(OP[i] & 0xFFFF);
fee8ec00 223 }
052d9a54
SR
224 break;
225
226 case disps25:
227 if (isize == 2)
228 OP[i] = (ins & 0xFFFFFF);
229 else
230 OP[i] = (ins & 0xFFFF) | (((ins >> 24) & 0xf) << 16) |
231 (((ins >> 16) & 0xf) << 20);
232
233 if (OP[i] & 1)
234 {
235 OP[i] = (OP[i] & 0xFFFFFE);
236 sign_flag = 1;
237 OP[i] = ~(OP[i]) + 1;
238 OP[i] = (unsigned long int)(OP[i] & 0xFFFFFF);
fee8ec00 239 }
052d9a54 240 break;
fee8ec00
SR
241
242 case abs20:
052d9a54 243 if (isize == 3)
fee8ec00 244 OP[i] = (ins) & 0xFFFFF;
052d9a54 245 else
fee8ec00 246 OP[i] = (ins >> start_bit) & 0xFFFFF;
052d9a54 247 break;
fee8ec00 248 case abs24:
052d9a54
SR
249 if (isize == 3)
250 OP[i] = ((ins & 0xFFFF) | (((ins >> 16) & 0xf) << 20)
251 | (((ins >> 24) & 0xf) << 16));
252 else
253 OP[i] = (ins >> 16) & 0xFFFFFF;
254 break;
fee8ec00
SR
255
256 case rra:
257 case rbase: break; /* NOT USED. */
258 case rbase_disps20: case rbase_dispe20:
259 case rpbase_disps20: case rpindex_disps20:
052d9a54
SR
260 OP[i] = ((((ins >> 24)&0xf) << 16)|((ins) & 0xFFFF));
261 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
262 break;
fee8ec00 263 case rpbase_disps0:
052d9a54
SR
264 OP[i] = 0; /* 4 bit disp const. */
265 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
266 break;
fee8ec00 267 case rpbase_dispe4:
052d9a54
SR
268 OP[i] = ((ins >> 8) & 0xF) * 2; /* 4 bit disp const. */
269 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
270 break;
fee8ec00 271 case rpbase_disps4:
052d9a54
SR
272 OP[i] = ((ins >> 8) & 0xF); /* 4 bit disp const. */
273 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
274 break;
fee8ec00 275 case rpbase_disps16:
052d9a54
SR
276 OP[i] = (ins) & 0xFFFF;
277 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
278 break;
fee8ec00 279 case rpindex_disps0:
052d9a54
SR
280 OP[i] = 0;
281 OP[++i] = (ins >> 4) & 0xF; /* get 4 bit for reg. */
282 OP[++i] = (ins >> 8) & 0x1; /* get 1 bit for index-reg. */
283 break;
fee8ec00 284 case rpindex_disps14:
052d9a54
SR
285 OP[i] = (ins) & 0x3FFF;
286 OP[++i] = (ins >> 14) & 0x1; /* get 1 bit for index-reg. */
287 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
fee8ec00
SR
288 case rindex7_abs20:
289 case rindex8_abs20:
052d9a54
SR
290 OP[i] = (ins) & 0xFFFFF;
291 OP[++i] = (ins >> 24) & 0x1; /* get 1 bit for index-reg. */
292 OP[++i] = (ins >> 20) & 0xF; /* get 4 bit for reg. */
293 break;
fee8ec00 294 case regr: case regp: case pregr: case pregrp:
052d9a54
SR
295 switch(isize)
296 {
297 case 1:
298 if (start_bit == 20) OP[i] = (ins >> 4) & 0xF;
299 else if (start_bit == 16) OP[i] = ins & 0xF;
300 break;
301 case 2: OP[i] = (ins >> start_bit) & 0xF; break;
302 case 3: OP[i] = (ins >> (start_bit + 16)) & 0xF; break;
303 }
304 break;
fee8ec00 305 case cc:
052d9a54
SR
306 {
307 if (isize == 1) OP[i] = (ins >> 4) & 0xF;
308 else if (isize == 2) OP[i] = (ins >> start_bit) & 0xF;
309 else OP[i] = (ins >> (start_bit + 16)) & 0xF;
310 break;
311 }
312 default: break;
313 }
fee8ec00 314
052d9a54 315 /* For ESC on uimm4_1 operand. */
fee8ec00 316 if (op_type == uimm4_1)
052d9a54
SR
317 if (OP[i] == 9)
318 OP[i] = -1;
319
320 /* For increment by 1. */
321 if ((op_type == pregr) || (op_type == pregrp))
322 OP[i] += 1;
fee8ec00
SR
323 }
324 /* FIXME: for tracing, update values that need to be updated each
325 instruction decode cycle */
fee8ec00 326 State.trace.psw = PSR;
fee8ec00
SR
327}
328
052d9a54 329static int
267b3b8e 330do_run (SIM_DESC sd, SIM_CPU *cpu, uint64 mcode)
fee8ec00 331{
052d9a54 332 struct hash_entry *h;
0ef7f981 333
fee8ec00
SR
334#ifdef DEBUG
335 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
3912a8db 336 sim_io_printf (sd, "do_long 0x%" PRIx64 "\n", mcode);
fee8ec00 337#endif
267b3b8e
MF
338
339 h = lookup_hash (sd, cpu, mcode, 1);
052d9a54 340
5aedb83b
MF
341 if ((h == NULL) || (h->opcode == 0))
342 return 0;
052d9a54 343
761e171a
MF
344 if (h->size == 3)
345 mcode = (mcode << 16) | RW (PC + 4);
052d9a54
SR
346
347 /* Re-set OP list. */
fee8ec00
SR
348 OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0;
349
052d9a54
SR
350 /* for push/pop/pushrtn with RA instructions. */
351 if ((h->format & REG_LIST) && (mcode & 0x800000))
352 OP[2] = 1; /* Set 1 for RA operand. */
fee8ec00 353
052d9a54
SR
354 /* numops == 0 means, no operands. */
355 if (((h->ops) != NULL) && (((h->ops)->numops) != 0))
356 get_operands ((h->ops)->operands, mcode, h->size, (h->ops)->numops);
fee8ec00 357
052d9a54
SR
358 //State.ins_type = h->flags;
359
267b3b8e 360 (h->ops->func) (sd, cpu);
052d9a54
SR
361
362 return h->size;
fee8ec00
SR
363}
364
27b97b40
MF
365static sim_cia
366cr16_pc_get (sim_cpu *cpu)
367{
368 return PC;
369}
370
371static void
372cr16_pc_set (sim_cpu *cpu, sim_cia pc)
373{
267b3b8e 374 SIM_DESC sd = CPU_STATE (cpu);
27b97b40
MF
375 SET_PC (pc);
376}
377
247ac9ee
MF
378static void
379free_state (SIM_DESC sd)
380{
381 if (STATE_MODULES (sd) != NULL)
382 sim_module_uninstall (sd);
383 sim_cpu_free_all (sd);
384 sim_state_free (sd);
385}
386
c2270cd8
MF
387static int cr16_reg_fetch (SIM_CPU *, int, unsigned char *, int);
388static int cr16_reg_store (SIM_CPU *, int, unsigned char *, int);
389
fee8ec00 390SIM_DESC
2e3d4f4d
MF
391sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb,
392 struct bfd *abfd, char * const *argv)
fee8ec00
SR
393{
394 struct simops *s;
052d9a54 395 struct hash_entry *h;
fee8ec00
SR
396 static int init_p = 0;
397 char **p;
247ac9ee
MF
398 int i;
399 SIM_DESC sd = sim_state_alloc (kind, cb);
400 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
401
f9a4d543
MF
402 /* Set default options before parsing user options. */
403 current_target_byte_order = BFD_ENDIAN_LITTLE;
404
247ac9ee 405 /* The cpu data is kept in a separately allocated chunk of memory. */
d5a71b11 406 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
247ac9ee
MF
407 {
408 free_state (sd);
409 return 0;
410 }
411
412 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
413 {
414 free_state (sd);
415 return 0;
416 }
417
77cf2ef5 418 /* The parser will print an error message for us, so we silently return. */
247ac9ee
MF
419 if (sim_parse_args (sd, argv) != SIM_RC_OK)
420 {
421 free_state (sd);
422 return 0;
423 }
424
425 /* Check for/establish the a reference program image. */
426 if (sim_analyze_program (sd,
427 (STATE_PROG_ARGV (sd) != NULL
428 ? *STATE_PROG_ARGV (sd)
429 : NULL), abfd) != SIM_RC_OK)
430 {
431 free_state (sd);
432 return 0;
433 }
434
435 /* Configure/verify the target byte order and other runtime
436 configuration options. */
437 if (sim_config (sd) != SIM_RC_OK)
438 {
439 sim_module_uninstall (sd);
440 return 0;
441 }
442
443 if (sim_post_argv_init (sd) != SIM_RC_OK)
444 {
445 /* Uninstall the modules to avoid memory leaks,
446 file descriptor leaks, etc. */
447 sim_module_uninstall (sd);
448 return 0;
449 }
fee8ec00 450
27b97b40
MF
451 /* CPU specific initialization. */
452 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
453 {
454 SIM_CPU *cpu = STATE_CPU (sd, i);
455
c2270cd8
MF
456 CPU_REG_FETCH (cpu) = cr16_reg_fetch;
457 CPU_REG_STORE (cpu) = cr16_reg_store;
27b97b40
MF
458 CPU_PC_FETCH (cpu) = cr16_pc_get;
459 CPU_PC_STORE (cpu) = cr16_pc_set;
460 }
461
761e171a
MF
462 /* The CR16 has an interrupt controller at 0xFC00, but we don't currently
463 handle that. Revisit if anyone ever implements operating mode. */
464 /* cr16 memory: There are three separate cr16 memory regions IMEM,
465 UMEM and DMEM. The IMEM and DMEM are further broken down into
466 blocks (very like VM pages). This might not match the hardware,
467 but it matches what the toolchain currently expects. Ugh. */
468 sim_do_commandf (sd, "memory-size %#x", 20 * 1024 * 1024);
469
052d9a54
SR
470 /* put all the opcodes in the hash table. */
471 if (!init_p++)
472 {
473 for (s = Simops; s->func; s++)
474 {
475 switch(32 - s->mask)
476 {
477 case 0x4:
478 h = &hash_table[hash(s->opcode, 0)];
479 break;
480
481 case 0x7:
482 if (((s->opcode << 1) >> 4) != 0)
483 h = &hash_table[hash((s->opcode << 1) >> 4, 0)];
484 else
485 h = &hash_table[hash((s->opcode << 1), 0)];
486 break;
487
488 case 0x8:
489 if ((s->opcode >> 4) != 0)
490 h = &hash_table[hash(s->opcode >> 4, 0)];
491 else
492 h = &hash_table[hash(s->opcode, 0)];
493 break;
494
495 case 0x9:
496 if (((s->opcode >> 1) >> 4) != 0)
497 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
498 else
499 h = &hash_table[hash((s->opcode >> 1), 0)];
500 break;
501
502 case 0xa:
503 if ((s->opcode >> 8) != 0)
504 h = &hash_table[hash(s->opcode >> 8, 0)];
505 else if ((s->opcode >> 4) != 0)
506 h = &hash_table[hash(s->opcode >> 4, 0)];
507 else
508 h = &hash_table[hash(s->opcode, 0)];
509 break;
510
511 case 0xc:
512 if ((s->opcode >> 8) != 0)
513 h = &hash_table[hash(s->opcode >> 8, 0)];
514 else if ((s->opcode >> 4) != 0)
515 h = &hash_table[hash(s->opcode >> 4, 0)];
516 else
517 h = &hash_table[hash(s->opcode, 0)];
518 break;
519
520 case 0xd:
521 if (((s->opcode >> 1) >> 8) != 0)
522 h = &hash_table[hash((s->opcode >>1) >> 8, 0)];
523 else if (((s->opcode >> 1) >> 4) != 0)
524 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
525 else
526 h = &hash_table[hash((s->opcode >>1), 0)];
527 break;
528
529 case 0x10:
530 if ((s->opcode >> 0xc) != 0)
531 h = &hash_table[hash(s->opcode >> 12, 0)];
532 else if ((s->opcode >> 8) != 0)
533 h = &hash_table[hash(s->opcode >> 8, 0)];
534 else if ((s->opcode >> 4) != 0)
535 h = &hash_table[hash(s->opcode >> 4, 0)];
536 else
537 h = &hash_table[hash(s->opcode, 0)];
538 break;
539
540 case 0x14:
541 if ((s->opcode >> 16) != 0)
542 h = &hash_table[hash(s->opcode >> 16, 0)];
543 else if ((s->opcode >> 12) != 0)
544 h = &hash_table[hash(s->opcode >> 12, 0)];
545 else if ((s->opcode >> 8) != 0)
546 h = &hash_table[hash(s->opcode >> 8, 0)];
547 else if ((s->opcode >> 4) != 0)
548 h = &hash_table[hash(s->opcode >> 4, 0)];
549 else
550 h = &hash_table[hash(s->opcode, 0)];
551 break;
3912a8db 552
052d9a54 553 default:
3912a8db 554 continue;
052d9a54
SR
555 }
556
557 /* go to the last entry in the chain. */
558 while (h->next)
559 h = h->next;
560
561 if (h->ops)
562 {
563 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
564 if (!h->next)
565 perror ("malloc failure");
566
567 h = h->next;
568 }
569 h->ops = s;
570 h->mask = s->mask;
571 h->opcode = s->opcode;
572 h->format = s->format;
573 h->size = s->size;
574 }
575 }
576
247ac9ee 577 return sd;
fee8ec00
SR
578}
579
0ef7f981
MF
580static void
581step_once (SIM_DESC sd, SIM_CPU *cpu)
fee8ec00 582{
0ef7f981
MF
583 uint32 curr_ins_size = 0;
584 uint64 mcode = RLW (PC);
fee8ec00 585
0ef7f981
MF
586 State.pc_changed = 0;
587
588 curr_ins_size = do_run (sd, cpu, mcode);
589
590#if CR16_DEBUG
9db36cf8 591 sim_io_printf (sd, "INS: PC=0x%X, mcode=0x%X\n", PC, mcode);
0ef7f981
MF
592#endif
593
594 if (curr_ins_size == 0)
595 sim_engine_halt (sd, cpu, NULL, PC, sim_exited, GPR (2));
596 else if (!State.pc_changed)
597 SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */
598
599#if 0
600 /* Check for a breakpoint trap on this instruction. This
601 overrides any pending branches or loops */
602 if (PSR_DB && PC == DBS)
603 {
604 SET_BPC (PC);
605 SET_BPSR (PSR);
606 SET_PC (SDBT_VECTOR_START);
607 }
608#endif
609
610 /* Writeback all the DATA / PC changes */
611 SLOT_FLUSH ();
612}
fee8ec00 613
fee8ec00 614void
0ef7f981
MF
615sim_engine_run (SIM_DESC sd,
616 int next_cpu_nr, /* ignore */
617 int nr_cpus, /* ignore */
618 int siggnal)
fee8ec00 619{
0ef7f981 620 sim_cpu *cpu;
fee8ec00 621
0ef7f981 622 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
fee8ec00 623
0ef7f981 624 cpu = STATE_CPU (sd, 0);
fee8ec00
SR
625
626 switch (siggnal)
627 {
628 case 0:
629 break;
0ef7f981
MF
630 case GDB_SIGNAL_BUS:
631 case GDB_SIGNAL_SEGV:
fee8ec00
SR
632 SET_PC (PC);
633 SET_PSR (PSR);
634 JMP (AE_VECTOR_START);
635 SLOT_FLUSH ();
636 break;
0ef7f981 637 case GDB_SIGNAL_ILL:
fee8ec00
SR
638 SET_PC (PC);
639 SET_PSR (PSR);
640 SET_HW_PSR ((PSR & (PSR_C_BIT)));
641 JMP (RIE_VECTOR_START);
642 SLOT_FLUSH ();
643 break;
644 default:
645 /* just ignore it */
646 break;
647 }
648
0ef7f981 649 while (1)
fee8ec00 650 {
0ef7f981
MF
651 step_once (sd, cpu);
652 if (sim_events_tick (sd))
653 sim_events_process (sd);
fee8ec00 654 }
fee8ec00
SR
655}
656
fee8ec00 657SIM_RC
2e3d4f4d
MF
658sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
659 char * const *argv, char * const *env)
fee8ec00
SR
660{
661 bfd_vma start_address;
662
663 /* reset all state information */
761e171a 664 memset (&State, 0, sizeof (State));
fee8ec00
SR
665
666 /* There was a hack here to copy the values of argc and argv into r0
667 and r1. The values were also saved into some high memory that
668 won't be overwritten by the stack (0x7C00). The reason for doing
669 this was to allow the 'run' program to accept arguments. Without
670 the hack, this is not possible anymore. If the simulator is run
671 from the debugger, arguments cannot be passed in, so this makes
672 no difference. */
673
674 /* set PC */
675 if (abfd != NULL)
676 start_address = bfd_get_start_address (abfd);
677 else
678 start_address = 0x0;
679#ifdef DEBUG
680 if (cr16_debug)
5ee0bc23
MF
681 sim_io_printf (sd, "sim_create_inferior: PC=0x%" BFD_VMA_FMT "x\n",
682 start_address);
fee8ec00 683#endif
267b3b8e
MF
684 {
685 SIM_CPU *cpu = STATE_CPU (sd, 0);
686 SET_CREG (PC_CR, start_address);
687 }
fee8ec00
SR
688
689 SLOT_FLUSH ();
690 return SIM_RC_OK;
691}
692
c2270cd8
MF
693static uint32
694cr16_extract_unsigned_integer (unsigned char *addr, int len)
695{
696 uint32 retval;
697 unsigned char * p;
698 unsigned char * startaddr = (unsigned char *)addr;
699 unsigned char * endaddr = startaddr + len;
700
701 retval = 0;
702
703 for (p = endaddr; p > startaddr;)
704 retval = (retval << 8) | *--p;
705
706 return retval;
707}
708
709static void
710cr16_store_unsigned_integer (unsigned char *addr, int len, uint32 val)
711{
712 unsigned char *p;
713 unsigned char *startaddr = addr;
714 unsigned char *endaddr = startaddr + len;
715
716 for (p = startaddr; p < endaddr;)
717 {
718 *p++ = val & 0xff;
719 val >>= 8;
720 }
721}
722
723static int
724cr16_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
fee8ec00
SR
725{
726 int size;
727 switch ((enum sim_cr16_regs) rn)
728 {
729 case SIM_CR16_R0_REGNUM:
730 case SIM_CR16_R1_REGNUM:
731 case SIM_CR16_R2_REGNUM:
732 case SIM_CR16_R3_REGNUM:
733 case SIM_CR16_R4_REGNUM:
734 case SIM_CR16_R5_REGNUM:
735 case SIM_CR16_R6_REGNUM:
736 case SIM_CR16_R7_REGNUM:
737 case SIM_CR16_R8_REGNUM:
738 case SIM_CR16_R9_REGNUM:
739 case SIM_CR16_R10_REGNUM:
740 case SIM_CR16_R11_REGNUM:
c2270cd8 741 cr16_store_unsigned_integer (memory, 2, GPR (rn - SIM_CR16_R0_REGNUM));
fee8ec00
SR
742 size = 2;
743 break;
744 case SIM_CR16_R12_REGNUM:
745 case SIM_CR16_R13_REGNUM:
746 case SIM_CR16_R14_REGNUM:
747 case SIM_CR16_R15_REGNUM:
c2270cd8 748 cr16_store_unsigned_integer (memory, 4, GPR (rn - SIM_CR16_R0_REGNUM));
fee8ec00
SR
749 size = 4;
750 break;
751 case SIM_CR16_PC_REGNUM:
752 case SIM_CR16_ISP_REGNUM:
753 case SIM_CR16_USP_REGNUM:
754 case SIM_CR16_INTBASE_REGNUM:
755 case SIM_CR16_PSR_REGNUM:
756 case SIM_CR16_CFG_REGNUM:
757 case SIM_CR16_DBS_REGNUM:
758 case SIM_CR16_DCR_REGNUM:
759 case SIM_CR16_DSR_REGNUM:
760 case SIM_CR16_CAR0_REGNUM:
761 case SIM_CR16_CAR1_REGNUM:
c2270cd8 762 cr16_store_unsigned_integer (memory, 4, CREG (rn - SIM_CR16_PC_REGNUM));
fee8ec00
SR
763 size = 4;
764 break;
765 default:
766 size = 0;
767 break;
768 }
769 return size;
770}
c2270cd8
MF
771
772static int
773cr16_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
fee8ec00 774{
267b3b8e 775 SIM_DESC sd = CPU_STATE (cpu);
fee8ec00
SR
776 int size;
777 switch ((enum sim_cr16_regs) rn)
778 {
779 case SIM_CR16_R0_REGNUM:
780 case SIM_CR16_R1_REGNUM:
781 case SIM_CR16_R2_REGNUM:
782 case SIM_CR16_R3_REGNUM:
783 case SIM_CR16_R4_REGNUM:
784 case SIM_CR16_R5_REGNUM:
785 case SIM_CR16_R6_REGNUM:
786 case SIM_CR16_R7_REGNUM:
787 case SIM_CR16_R8_REGNUM:
788 case SIM_CR16_R9_REGNUM:
789 case SIM_CR16_R10_REGNUM:
790 case SIM_CR16_R11_REGNUM:
c2270cd8 791 SET_GPR (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
fee8ec00
SR
792 size = 2;
793 break;
794 case SIM_CR16_R12_REGNUM:
795 case SIM_CR16_R13_REGNUM:
796 case SIM_CR16_R14_REGNUM:
797 case SIM_CR16_R15_REGNUM:
c2270cd8 798 SET_GPR32 (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
fee8ec00
SR
799 size = 4;
800 break;
801 case SIM_CR16_PC_REGNUM:
802 case SIM_CR16_ISP_REGNUM:
803 case SIM_CR16_USP_REGNUM:
804 case SIM_CR16_INTBASE_REGNUM:
805 case SIM_CR16_PSR_REGNUM:
806 case SIM_CR16_CFG_REGNUM:
807 case SIM_CR16_DBS_REGNUM:
808 case SIM_CR16_DCR_REGNUM:
809 case SIM_CR16_DSR_REGNUM:
810 case SIM_CR16_CAR0_REGNUM:
811 case SIM_CR16_CAR1_REGNUM:
c2270cd8 812 SET_CREG (rn - SIM_CR16_PC_REGNUM, cr16_extract_unsigned_integer (memory, 4));
fee8ec00
SR
813 size = 4;
814 break;
815 default:
816 size = 0;
817 break;
818 }
819 SLOT_FLUSH ();
820 return size;
821}