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