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