e2aef013d16016b681ea574cc8ea8bbd29a4be2e
[deliverable/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 /* This must come before any other includes. */
21 #include "defs.h"
22
23 #include <inttypes.h>
24 #include <signal.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "bfd.h"
28 #include "sim/callback.h"
29 #include "sim/sim.h"
30
31 #include "sim-main.h"
32 #include "sim-options.h"
33 #include "sim-signal.h"
34
35 #include "gdb/sim-cr16.h"
36 #include "gdb/signals.h"
37 #include "opcode/cr16.h"
38
39 struct _state State;
40
41 int cr16_debug;
42
43 uint32 OP[4];
44 uint32 sign_flag;
45
46 static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint64 ins, int size);
47 static void get_operands (operand_desc *s, uint64 mcode, int isize, int nops);
48
49 #define MAX_HASH 16
50
51 struct 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
61 struct hash_entry hash_table[MAX_HASH+1];
62
63 INLINE static long
64 hash(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
77 INLINE static struct hash_entry *
78 lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint64 ins, int size)
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)
97 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL);
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 }
108
109 INLINE static void
110 get_operands (operand_desc *s, uint64 ins, int isize, int nops)
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
118 for (i=0; i < 4; ++i,++opn)
119 {
120 if (s[opn].op_type == dummy) break;
121
122 op_type = s[opn].op_type;
123 start_bit = s[opn].shift;
124 op_size = cr16_optab[op_type].bit_size;
125
126 switch (op_type)
127 {
128 case imm3: case imm4: case imm5: case imm6:
129 {
130 if (isize == 1)
131 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
132 else
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));
141 }
142 break;
143
144 case uimm3: case uimm3_1: case uimm4_1:
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;
156
157 case uimm4:
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;
177
178 case imm16: case uimm16:
179 OP[i] = ins & 0xFFFF;
180 break;
181
182 case uimm20: case imm20:
183 OP[i] = ins & (((long)1 << op_size) - 1);
184 break;
185
186 case imm32: case uimm32:
187 OP[i] = ins & 0xFFFFFFFF;
188 break;
189
190 case uimm5: break; /*NOT USED. */
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;
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);
223 }
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);
239 }
240 break;
241
242 case abs20:
243 if (isize == 3)
244 OP[i] = (ins) & 0xFFFFF;
245 else
246 OP[i] = (ins >> start_bit) & 0xFFFFF;
247 break;
248 case abs24:
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;
255
256 case rra:
257 case rbase: break; /* NOT USED. */
258 case rbase_disps20: case rbase_dispe20:
259 case rpbase_disps20: case rpindex_disps20:
260 OP[i] = ((((ins >> 24)&0xf) << 16)|((ins) & 0xFFFF));
261 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
262 break;
263 case rpbase_disps0:
264 OP[i] = 0; /* 4 bit disp const. */
265 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
266 break;
267 case rpbase_dispe4:
268 OP[i] = ((ins >> 8) & 0xF) * 2; /* 4 bit disp const. */
269 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
270 break;
271 case rpbase_disps4:
272 OP[i] = ((ins >> 8) & 0xF); /* 4 bit disp const. */
273 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
274 break;
275 case rpbase_disps16:
276 OP[i] = (ins) & 0xFFFF;
277 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
278 break;
279 case rpindex_disps0:
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;
284 case rpindex_disps14:
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. */
288 case rindex7_abs20:
289 case rindex8_abs20:
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;
294 case regr: case regp: case pregr: case pregrp:
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;
305 case cc:
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 }
314
315 /* For ESC on uimm4_1 operand. */
316 if (op_type == uimm4_1)
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;
323 }
324 /* FIXME: for tracing, update values that need to be updated each
325 instruction decode cycle */
326 State.trace.psw = PSR;
327 }
328
329 static int
330 do_run (SIM_DESC sd, SIM_CPU *cpu, uint64 mcode)
331 {
332 struct hash_entry *h;
333
334 #ifdef DEBUG
335 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
336 sim_io_printf (sd, "do_long 0x%" PRIx64 "\n", mcode);
337 #endif
338
339 h = lookup_hash (sd, cpu, mcode, 1);
340
341 if ((h == NULL) || (h->opcode == 0))
342 return 0;
343
344 if (h->size == 3)
345 mcode = (mcode << 16) | RW (PC + 4);
346
347 /* Re-set OP list. */
348 OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0;
349
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. */
353
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);
357
358 //State.ins_type = h->flags;
359
360 (h->ops->func) (sd, cpu);
361
362 return h->size;
363 }
364
365 static sim_cia
366 cr16_pc_get (sim_cpu *cpu)
367 {
368 return PC;
369 }
370
371 static void
372 cr16_pc_set (sim_cpu *cpu, sim_cia pc)
373 {
374 SIM_DESC sd = CPU_STATE (cpu);
375 SET_PC (pc);
376 }
377
378 static void
379 free_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
387 static int cr16_reg_fetch (SIM_CPU *, int, unsigned char *, int);
388 static int cr16_reg_store (SIM_CPU *, int, unsigned char *, int);
389
390 SIM_DESC
391 sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb,
392 struct bfd *abfd, char * const *argv)
393 {
394 struct simops *s;
395 struct hash_entry *h;
396 static int init_p = 0;
397 char **p;
398 int i;
399 SIM_DESC sd = sim_state_alloc (kind, cb);
400 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
401
402 /* Set default options before parsing user options. */
403 current_target_byte_order = BFD_ENDIAN_LITTLE;
404
405 /* The cpu data is kept in a separately allocated chunk of memory. */
406 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
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
418 /* The parser will print an error message for us, so we silently return. */
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 }
450
451 /* CPU specific initialization. */
452 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
453 {
454 SIM_CPU *cpu = STATE_CPU (sd, i);
455
456 CPU_REG_FETCH (cpu) = cr16_reg_fetch;
457 CPU_REG_STORE (cpu) = cr16_reg_store;
458 CPU_PC_FETCH (cpu) = cr16_pc_get;
459 CPU_PC_STORE (cpu) = cr16_pc_set;
460 }
461
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
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;
552
553 default:
554 continue;
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
577 return sd;
578 }
579
580 static void
581 step_once (SIM_DESC sd, SIM_CPU *cpu)
582 {
583 uint32 curr_ins_size = 0;
584 uint64 mcode = RLW (PC);
585
586 State.pc_changed = 0;
587
588 curr_ins_size = do_run (sd, cpu, mcode);
589
590 #if CR16_DEBUG
591 sim_io_printf (sd, "INS: PC=0x%X, mcode=0x%X\n", PC, mcode);
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 }
613
614 void
615 sim_engine_run (SIM_DESC sd,
616 int next_cpu_nr, /* ignore */
617 int nr_cpus, /* ignore */
618 int siggnal)
619 {
620 sim_cpu *cpu;
621
622 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
623
624 cpu = STATE_CPU (sd, 0);
625
626 switch (siggnal)
627 {
628 case 0:
629 break;
630 case GDB_SIGNAL_BUS:
631 case GDB_SIGNAL_SEGV:
632 SET_PC (PC);
633 SET_PSR (PSR);
634 JMP (AE_VECTOR_START);
635 SLOT_FLUSH ();
636 break;
637 case GDB_SIGNAL_ILL:
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
649 while (1)
650 {
651 step_once (sd, cpu);
652 if (sim_events_tick (sd))
653 sim_events_process (sd);
654 }
655 }
656
657 SIM_RC
658 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
659 char * const *argv, char * const *env)
660 {
661 bfd_vma start_address;
662
663 /* reset all state information */
664 memset (&State, 0, sizeof (State));
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)
681 sim_io_printf (sd, "sim_create_inferior: PC=0x%" BFD_VMA_FMT "x\n",
682 start_address);
683 #endif
684 {
685 SIM_CPU *cpu = STATE_CPU (sd, 0);
686 SET_CREG (PC_CR, start_address);
687 }
688
689 SLOT_FLUSH ();
690 return SIM_RC_OK;
691 }
692
693 static uint32
694 cr16_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
709 static void
710 cr16_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
723 static int
724 cr16_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
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:
741 cr16_store_unsigned_integer (memory, 2, GPR (rn - SIM_CR16_R0_REGNUM));
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:
748 cr16_store_unsigned_integer (memory, 4, GPR (rn - SIM_CR16_R0_REGNUM));
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:
762 cr16_store_unsigned_integer (memory, 4, CREG (rn - SIM_CR16_PC_REGNUM));
763 size = 4;
764 break;
765 default:
766 size = 0;
767 break;
768 }
769 return size;
770 }
771
772 static int
773 cr16_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
774 {
775 SIM_DESC sd = CPU_STATE (cpu);
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:
791 SET_GPR (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
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:
798 SET_GPR32 (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
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:
812 SET_CREG (rn - SIM_CR16_PC_REGNUM, cr16_extract_unsigned_integer (memory, 4));
813 size = 4;
814 break;
815 default:
816 size = 0;
817 break;
818 }
819 SLOT_FLUSH ();
820 return size;
821 }
This page took 0.046217 seconds and 3 git commands to generate.