testsuite, threads: fix LD_LIBRARY_PATH in 'tls-sepdebug.exp'
[binutils-gdb.git] / sim / cr16 / interp.c
blob294ba56ae10e079c7a266c8bb625496a7ee261c2
1 /* Simulation code for the CR16 processor.
2 Copyright (C) 2008-2024 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)
10 any later version.
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/>. */
20 /* This must come before any other includes. */
21 #include "defs.h"
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"
31 #include "sim-main.h"
32 #include "sim-options.h"
33 #include "sim-signal.h"
35 #include "sim/sim-cr16.h"
36 #include "gdb/signals.h"
37 #include "opcode/cr16.h"
39 #include "target-newlib-syscall.h"
41 #include "cr16-sim.h"
43 struct _state State;
45 int cr16_debug;
47 uint32_t OP[4];
48 uint32_t sign_flag;
50 static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint64_t ins, int size);
51 static void get_operands (operand_desc *s, uint64_t mcode, int isize, int nops);
53 #define MAX_HASH 16
55 struct hash_entry
57 struct hash_entry *next;
58 uint32_t opcode;
59 uint32_t mask;
60 int format;
61 int size;
62 struct simops *ops;
65 struct hash_entry hash_table[MAX_HASH+1];
67 INLINE static long
68 hash(unsigned long long insn, int format)
70 unsigned int i = 4;
71 if (format)
73 while ((insn >> i) != 0) i +=4;
75 return ((insn >> (i-4)) & 0xf); /* Use last 4 bits as hask key. */
77 return ((insn & 0xF)); /* Use last 4 bits as hask key. */
81 INLINE static struct hash_entry *
82 lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint64_t ins, int size)
84 uint32_t mask;
85 struct hash_entry *h;
87 h = &hash_table[hash(ins,1)];
90 mask = (((1 << (32 - h->mask)) -1) << h->mask);
92 /* Adjuest mask for branch with 2 word instructions. */
93 if (streq(h->ops->mnemonic,"b") && h->size == 2)
94 mask = 0xff0f0000;
97 while ((ins & mask) != (BIN(h->opcode, h->mask)))
99 if (h->next == NULL)
100 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL);
101 h = h->next;
103 mask = (((1 << (32 - h->mask)) -1) << h->mask);
104 /* Adjuest mask for branch with 2 word instructions. */
105 if ((streq(h->ops->mnemonic,"b")) && h->size == 2)
106 mask = 0xff0f0000;
109 return (h);
112 INLINE static void
113 get_operands (operand_desc *s, uint64_t ins, int isize, int nops)
115 uint32_t i, opn = 0, start_bit = 0, op_type = 0;
116 int32_t op_size = 0;
118 if (isize == 1) /* Trunkcate the extra 16 bits of INS. */
119 ins = ins >> 16;
121 for (i=0; i < 4; ++i,++opn)
123 if (s[opn].op_type == dummy) break;
125 op_type = s[opn].op_type;
126 start_bit = s[opn].shift;
127 op_size = cr16_optab[op_type].bit_size;
129 switch (op_type)
131 case imm3: case imm4: case imm5: case imm6:
133 if (isize == 1)
134 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
135 else
136 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));
138 if (OP[i] & ((long)1 << (op_size -1)))
140 sign_flag = 1;
141 OP[i] = ~(OP[i]) + 1;
143 OP[i] = (unsigned long int)(OP[i] & (((long)1 << op_size) -1));
145 break;
147 case uimm3: case uimm3_1: case uimm4_1:
148 switch (isize)
150 case 1:
151 OP[i] = ((ins >> 4) & ((1 << op_size) -1)); break;
152 case 2:
153 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));break;
154 default: /* for case 3. */
155 OP[i] = ((ins >> (16 + start_bit)) & ((1 << op_size) -1)); break;
156 break;
158 break;
160 case uimm4:
161 switch (isize)
163 case 1:
164 if (start_bit == 20)
165 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
166 else
167 OP[i] = (ins & ((1 << op_size) -1));
168 break;
169 case 2:
170 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
171 break;
172 case 3:
173 OP[i] = ((ins >> (start_bit + 16)) & ((1 << op_size) -1));
174 break;
175 default:
176 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
177 break;
179 break;
181 case imm16: case uimm16:
182 OP[i] = ins & 0xFFFF;
183 break;
185 case uimm20: case imm20:
186 OP[i] = ins & (((long)1 << op_size) - 1);
187 break;
189 case imm32: case uimm32:
190 OP[i] = ins & 0xFFFFFFFF;
191 break;
193 case uimm5: break; /*NOT USED. */
194 OP[i] = ins & ((1 << op_size) - 1); break;
196 case disps5:
197 OP[i] = (ins >> 4) & ((1 << 4) - 1);
198 OP[i] = (OP[i] * 2) + 2;
199 if (OP[i] & ((long)1 << 5))
201 sign_flag = 1;
202 OP[i] = ~(OP[i]) + 1;
203 OP[i] = (unsigned long int)(OP[i] & 0x1F);
205 break;
207 case dispe9:
208 OP[i] = ((((ins >> 8) & 0xf) << 4) | (ins & 0xf));
209 OP[i] <<= 1;
210 if (OP[i] & ((long)1 << 8))
212 sign_flag = 1;
213 OP[i] = ~(OP[i]) + 1;
214 OP[i] = (unsigned long int)(OP[i] & 0xFF);
216 break;
218 case disps17:
219 OP[i] = (ins & 0xFFFF);
220 if (OP[i] & 1)
222 OP[i] = (OP[i] & 0xFFFE);
223 sign_flag = 1;
224 OP[i] = ~(OP[i]) + 1;
225 OP[i] = (unsigned long int)(OP[i] & 0xFFFF);
227 break;
229 case disps25:
230 if (isize == 2)
231 OP[i] = (ins & 0xFFFFFF);
232 else
233 OP[i] = (ins & 0xFFFF) | (((ins >> 24) & 0xf) << 16) |
234 (((ins >> 16) & 0xf) << 20);
236 if (OP[i] & 1)
238 OP[i] = (OP[i] & 0xFFFFFE);
239 sign_flag = 1;
240 OP[i] = ~(OP[i]) + 1;
241 OP[i] = (unsigned long int)(OP[i] & 0xFFFFFF);
243 break;
245 case abs20:
246 if (isize == 3)
247 OP[i] = (ins) & 0xFFFFF;
248 else
249 OP[i] = (ins >> start_bit) & 0xFFFFF;
250 break;
251 case abs24:
252 if (isize == 3)
253 OP[i] = ((ins & 0xFFFF) | (((ins >> 16) & 0xf) << 20)
254 | (((ins >> 24) & 0xf) << 16));
255 else
256 OP[i] = (ins >> 16) & 0xFFFFFF;
257 break;
259 case rra:
260 case rbase: break; /* NOT USED. */
261 case rbase_disps20: case rbase_dispe20:
262 case rpbase_disps20: case rpindex_disps20:
263 OP[i] = ((((ins >> 24)&0xf) << 16)|((ins) & 0xFFFF));
264 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
265 break;
266 case rpbase_disps0:
267 OP[i] = 0; /* 4 bit disp const. */
268 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
269 break;
270 case rpbase_dispe4:
271 OP[i] = ((ins >> 8) & 0xF) * 2; /* 4 bit disp const. */
272 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
273 break;
274 case rpbase_disps4:
275 OP[i] = ((ins >> 8) & 0xF); /* 4 bit disp const. */
276 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
277 break;
278 case rpbase_disps16:
279 OP[i] = (ins) & 0xFFFF;
280 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
281 break;
282 case rpindex_disps0:
283 OP[i] = 0;
284 OP[++i] = (ins >> 4) & 0xF; /* get 4 bit for reg. */
285 OP[++i] = (ins >> 8) & 0x1; /* get 1 bit for index-reg. */
286 break;
287 case rpindex_disps14:
288 OP[i] = (ins) & 0x3FFF;
289 OP[++i] = (ins >> 14) & 0x1; /* get 1 bit for index-reg. */
290 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
291 break;
292 case rindex7_abs20:
293 case rindex8_abs20:
294 OP[i] = (ins) & 0xFFFFF;
295 OP[++i] = (ins >> 24) & 0x1; /* get 1 bit for index-reg. */
296 OP[++i] = (ins >> 20) & 0xF; /* get 4 bit for reg. */
297 break;
298 case regr: case regp: case pregr: case pregrp:
299 switch(isize)
301 case 1:
302 if (start_bit == 20) OP[i] = (ins >> 4) & 0xF;
303 else if (start_bit == 16) OP[i] = ins & 0xF;
304 break;
305 case 2: OP[i] = (ins >> start_bit) & 0xF; break;
306 case 3: OP[i] = (ins >> (start_bit + 16)) & 0xF; break;
308 break;
309 case cc:
311 if (isize == 1) OP[i] = (ins >> 4) & 0xF;
312 else if (isize == 2) OP[i] = (ins >> start_bit) & 0xF;
313 else OP[i] = (ins >> (start_bit + 16)) & 0xF;
314 break;
316 default: break;
319 /* For ESC on uimm4_1 operand. */
320 if (op_type == uimm4_1)
321 if (OP[i] == 9)
322 OP[i] = -1;
324 /* For increment by 1. */
325 if ((op_type == pregr) || (op_type == pregrp))
326 OP[i] += 1;
328 /* FIXME: for tracing, update values that need to be updated each
329 instruction decode cycle */
330 State.trace.psw = PSR;
333 static int
334 do_run (SIM_DESC sd, SIM_CPU *cpu, uint64_t mcode)
336 struct hash_entry *h;
338 #ifdef DEBUG
339 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
340 sim_io_printf (sd, "do_long 0x%" PRIx64 "\n", mcode);
341 #endif
343 h = lookup_hash (sd, cpu, mcode, 1);
345 if ((h == NULL) || (h->opcode == 0))
346 return 0;
348 if (h->size == 3)
349 mcode = (mcode << 16) | RW (PC + 4);
351 /* Re-set OP list. */
352 OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0;
354 /* for push/pop/pushrtn with RA instructions. */
355 if ((h->format & REG_LIST) && (mcode & 0x800000))
356 OP[2] = 1; /* Set 1 for RA operand. */
358 /* numops == 0 means, no operands. */
359 if (((h->ops) != NULL) && (((h->ops)->numops) != 0))
360 get_operands ((h->ops)->operands, mcode, h->size, (h->ops)->numops);
362 //State.ins_type = h->flags;
364 (h->ops->func) (sd, cpu);
366 return h->size;
369 static sim_cia
370 cr16_pc_get (sim_cpu *cpu)
372 return PC;
375 static void
376 cr16_pc_set (sim_cpu *cpu, sim_cia pc)
378 SIM_DESC sd = CPU_STATE (cpu);
379 SET_PC (pc);
382 static void
383 free_state (SIM_DESC sd)
385 if (STATE_MODULES (sd) != NULL)
386 sim_module_uninstall (sd);
387 sim_cpu_free_all (sd);
388 sim_state_free (sd);
391 static int cr16_reg_fetch (SIM_CPU *, int, void *, int);
392 static int cr16_reg_store (SIM_CPU *, int, const void *, int);
394 SIM_DESC
395 sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb,
396 struct bfd *abfd, char * const *argv)
398 struct simops *s;
399 struct hash_entry *h;
400 static int init_p = 0;
401 int i;
402 SIM_DESC sd = sim_state_alloc (kind, cb);
403 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
405 /* Set default options before parsing user options. */
406 current_target_byte_order = BFD_ENDIAN_LITTLE;
407 cb->syscall_map = cb_cr16_syscall_map;
409 /* The cpu data is kept in a separately allocated chunk of memory. */
410 if (sim_cpu_alloc_all (sd, 0) != SIM_RC_OK)
412 free_state (sd);
413 return 0;
416 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
418 free_state (sd);
419 return 0;
422 /* The parser will print an error message for us, so we silently return. */
423 if (sim_parse_args (sd, argv) != SIM_RC_OK)
425 free_state (sd);
426 return 0;
429 /* Check for/establish the a reference program image. */
430 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
432 free_state (sd);
433 return 0;
436 /* Configure/verify the target byte order and other runtime
437 configuration options. */
438 if (sim_config (sd) != SIM_RC_OK)
440 sim_module_uninstall (sd);
441 return 0;
444 if (sim_post_argv_init (sd) != SIM_RC_OK)
446 /* Uninstall the modules to avoid memory leaks,
447 file descriptor leaks, etc. */
448 sim_module_uninstall (sd);
449 return 0;
452 /* CPU specific initialization. */
453 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
455 SIM_CPU *cpu = STATE_CPU (sd, i);
457 CPU_REG_FETCH (cpu) = cr16_reg_fetch;
458 CPU_REG_STORE (cpu) = cr16_reg_store;
459 CPU_PC_FETCH (cpu) = cr16_pc_get;
460 CPU_PC_STORE (cpu) = cr16_pc_set;
463 /* The CR16 has an interrupt controller at 0xFC00, but we don't currently
464 handle that. Revisit if anyone ever implements operating mode. */
465 /* cr16 memory: There are three separate cr16 memory regions IMEM,
466 UMEM and DMEM. The IMEM and DMEM are further broken down into
467 blocks (very like VM pages). This might not match the hardware,
468 but it matches what the toolchain currently expects. Ugh. */
469 sim_do_commandf (sd, "memory-size %#x", 20 * 1024 * 1024);
471 /* put all the opcodes in the hash table. */
472 if (!init_p++)
474 for (s = Simops; s->func; s++)
476 switch(32 - s->mask)
478 case 0x4:
479 h = &hash_table[hash(s->opcode, 0)];
480 break;
482 case 0x7:
483 if (((s->opcode << 1) >> 4) != 0)
484 h = &hash_table[hash((s->opcode << 1) >> 4, 0)];
485 else
486 h = &hash_table[hash((s->opcode << 1), 0)];
487 break;
489 case 0x8:
490 if ((s->opcode >> 4) != 0)
491 h = &hash_table[hash(s->opcode >> 4, 0)];
492 else
493 h = &hash_table[hash(s->opcode, 0)];
494 break;
496 case 0x9:
497 if (((s->opcode >> 1) >> 4) != 0)
498 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
499 else
500 h = &hash_table[hash((s->opcode >> 1), 0)];
501 break;
503 case 0xa:
504 if ((s->opcode >> 8) != 0)
505 h = &hash_table[hash(s->opcode >> 8, 0)];
506 else if ((s->opcode >> 4) != 0)
507 h = &hash_table[hash(s->opcode >> 4, 0)];
508 else
509 h = &hash_table[hash(s->opcode, 0)];
510 break;
512 case 0xc:
513 if ((s->opcode >> 8) != 0)
514 h = &hash_table[hash(s->opcode >> 8, 0)];
515 else if ((s->opcode >> 4) != 0)
516 h = &hash_table[hash(s->opcode >> 4, 0)];
517 else
518 h = &hash_table[hash(s->opcode, 0)];
519 break;
521 case 0xd:
522 if (((s->opcode >> 1) >> 8) != 0)
523 h = &hash_table[hash((s->opcode >>1) >> 8, 0)];
524 else if (((s->opcode >> 1) >> 4) != 0)
525 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
526 else
527 h = &hash_table[hash((s->opcode >>1), 0)];
528 break;
530 case 0x10:
531 if ((s->opcode >> 0xc) != 0)
532 h = &hash_table[hash(s->opcode >> 12, 0)];
533 else if ((s->opcode >> 8) != 0)
534 h = &hash_table[hash(s->opcode >> 8, 0)];
535 else if ((s->opcode >> 4) != 0)
536 h = &hash_table[hash(s->opcode >> 4, 0)];
537 else
538 h = &hash_table[hash(s->opcode, 0)];
539 break;
541 case 0x14:
542 if ((s->opcode >> 16) != 0)
543 h = &hash_table[hash(s->opcode >> 16, 0)];
544 else if ((s->opcode >> 12) != 0)
545 h = &hash_table[hash(s->opcode >> 12, 0)];
546 else if ((s->opcode >> 8) != 0)
547 h = &hash_table[hash(s->opcode >> 8, 0)];
548 else if ((s->opcode >> 4) != 0)
549 h = &hash_table[hash(s->opcode >> 4, 0)];
550 else
551 h = &hash_table[hash(s->opcode, 0)];
552 break;
554 default:
555 continue;
558 /* go to the last entry in the chain. */
559 while (h->next)
560 h = h->next;
562 if (h->ops)
564 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
565 if (!h->next)
566 perror ("malloc failure");
568 h = h->next;
570 h->ops = s;
571 h->mask = s->mask;
572 h->opcode = s->opcode;
573 h->format = s->format;
574 h->size = s->size;
578 return sd;
581 static void
582 step_once (SIM_DESC sd, SIM_CPU *cpu)
584 uint32_t curr_ins_size = 0;
585 uint64_t mcode = RLW (PC);
587 State.pc_changed = 0;
589 curr_ins_size = do_run (sd, cpu, mcode);
591 #if CR16_DEBUG
592 sim_io_printf (sd, "INS: PC=0x%X, mcode=0x%X\n", PC, mcode);
593 #endif
595 if (curr_ins_size == 0)
596 sim_engine_halt (sd, cpu, NULL, PC, sim_exited, GPR (2));
597 else if (!State.pc_changed)
598 SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */
600 #if 0
601 /* Check for a breakpoint trap on this instruction. This
602 overrides any pending branches or loops */
603 if (PSR_DB && PC == DBS)
605 SET_BPC (PC);
606 SET_BPSR (PSR);
607 SET_PC (SDBT_VECTOR_START);
609 #endif
611 /* Writeback all the DATA / PC changes */
612 SLOT_FLUSH ();
615 void
616 sim_engine_run (SIM_DESC sd,
617 int next_cpu_nr, /* ignore */
618 int nr_cpus, /* ignore */
619 int siggnal)
621 sim_cpu *cpu;
623 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
625 cpu = STATE_CPU (sd, 0);
627 switch (siggnal)
629 case 0:
630 break;
631 case GDB_SIGNAL_BUS:
632 case GDB_SIGNAL_SEGV:
633 SET_PC (PC);
634 SET_PSR (PSR);
635 JMP (AE_VECTOR_START);
636 SLOT_FLUSH ();
637 break;
638 case GDB_SIGNAL_ILL:
639 SET_PC (PC);
640 SET_PSR (PSR);
641 SET_HW_PSR ((PSR & (PSR_C_BIT)));
642 JMP (RIE_VECTOR_START);
643 SLOT_FLUSH ();
644 break;
645 default:
646 /* just ignore it */
647 break;
650 while (1)
652 step_once (sd, cpu);
653 if (sim_events_tick (sd))
654 sim_events_process (sd);
658 SIM_RC
659 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
660 char * const *argv, char * const *env)
662 bfd_vma start_address;
664 /* reset all state information */
665 memset (&State, 0, sizeof (State));
667 /* There was a hack here to copy the values of argc and argv into r0
668 and r1. The values were also saved into some high memory that
669 won't be overwritten by the stack (0x7C00). The reason for doing
670 this was to allow the 'run' program to accept arguments. Without
671 the hack, this is not possible anymore. If the simulator is run
672 from the debugger, arguments cannot be passed in, so this makes
673 no difference. */
675 /* set PC */
676 if (abfd != NULL)
677 start_address = bfd_get_start_address (abfd);
678 else
679 start_address = 0x0;
680 #ifdef DEBUG
681 if (cr16_debug)
682 sim_io_printf (sd, "sim_create_inferior: PC=0x%" PRIx64 "\n",
683 (uint64_t) start_address);
684 #endif
686 SIM_CPU *cpu = STATE_CPU (sd, 0);
687 SET_CREG (PC_CR, start_address);
690 SLOT_FLUSH ();
691 return SIM_RC_OK;
694 static uint32_t
695 cr16_extract_unsigned_integer (const unsigned char *addr, int len)
697 uint32_t retval;
698 unsigned char * p;
699 unsigned char * startaddr = (unsigned char *)addr;
700 unsigned char * endaddr = startaddr + len;
702 retval = 0;
704 for (p = endaddr; p > startaddr;)
705 retval = (retval << 8) | *--p;
707 return retval;
710 static void
711 cr16_store_unsigned_integer (unsigned char *addr, int len, uint32_t val)
713 unsigned char *p;
714 unsigned char *startaddr = addr;
715 unsigned char *endaddr = startaddr + len;
717 for (p = startaddr; p < endaddr;)
719 *p++ = val & 0xff;
720 val >>= 8;
724 static int
725 cr16_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
727 int size;
728 switch ((enum sim_cr16_regs) rn)
730 case SIM_CR16_R0_REGNUM:
731 case SIM_CR16_R1_REGNUM:
732 case SIM_CR16_R2_REGNUM:
733 case SIM_CR16_R3_REGNUM:
734 case SIM_CR16_R4_REGNUM:
735 case SIM_CR16_R5_REGNUM:
736 case SIM_CR16_R6_REGNUM:
737 case SIM_CR16_R7_REGNUM:
738 case SIM_CR16_R8_REGNUM:
739 case SIM_CR16_R9_REGNUM:
740 case SIM_CR16_R10_REGNUM:
741 case SIM_CR16_R11_REGNUM:
742 cr16_store_unsigned_integer (memory, 2, GPR (rn - SIM_CR16_R0_REGNUM));
743 size = 2;
744 break;
745 case SIM_CR16_R12_REGNUM:
746 case SIM_CR16_R13_REGNUM:
747 case SIM_CR16_R14_REGNUM:
748 case SIM_CR16_R15_REGNUM:
749 cr16_store_unsigned_integer (memory, 4, GPR (rn - SIM_CR16_R0_REGNUM));
750 size = 4;
751 break;
752 case SIM_CR16_PC_REGNUM:
753 case SIM_CR16_ISP_REGNUM:
754 case SIM_CR16_USP_REGNUM:
755 case SIM_CR16_INTBASE_REGNUM:
756 case SIM_CR16_PSR_REGNUM:
757 case SIM_CR16_CFG_REGNUM:
758 case SIM_CR16_DBS_REGNUM:
759 case SIM_CR16_DCR_REGNUM:
760 case SIM_CR16_DSR_REGNUM:
761 case SIM_CR16_CAR0_REGNUM:
762 case SIM_CR16_CAR1_REGNUM:
763 cr16_store_unsigned_integer (memory, 4, CREG (rn - SIM_CR16_PC_REGNUM));
764 size = 4;
765 break;
766 default:
767 size = 0;
768 break;
770 return size;
773 static int
774 cr16_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
776 SIM_DESC sd = CPU_STATE (cpu);
777 int size;
778 switch ((enum sim_cr16_regs) rn)
780 case SIM_CR16_R0_REGNUM:
781 case SIM_CR16_R1_REGNUM:
782 case SIM_CR16_R2_REGNUM:
783 case SIM_CR16_R3_REGNUM:
784 case SIM_CR16_R4_REGNUM:
785 case SIM_CR16_R5_REGNUM:
786 case SIM_CR16_R6_REGNUM:
787 case SIM_CR16_R7_REGNUM:
788 case SIM_CR16_R8_REGNUM:
789 case SIM_CR16_R9_REGNUM:
790 case SIM_CR16_R10_REGNUM:
791 case SIM_CR16_R11_REGNUM:
792 SET_GPR (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
793 size = 2;
794 break;
795 case SIM_CR16_R12_REGNUM:
796 case SIM_CR16_R13_REGNUM:
797 case SIM_CR16_R14_REGNUM:
798 case SIM_CR16_R15_REGNUM:
799 SET_GPR32 (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
800 size = 4;
801 break;
802 case SIM_CR16_PC_REGNUM:
803 case SIM_CR16_ISP_REGNUM:
804 case SIM_CR16_USP_REGNUM:
805 case SIM_CR16_INTBASE_REGNUM:
806 case SIM_CR16_PSR_REGNUM:
807 case SIM_CR16_CFG_REGNUM:
808 case SIM_CR16_DBS_REGNUM:
809 case SIM_CR16_DCR_REGNUM:
810 case SIM_CR16_DSR_REGNUM:
811 case SIM_CR16_CAR0_REGNUM:
812 case SIM_CR16_CAR1_REGNUM:
813 SET_CREG (rn - SIM_CR16_PC_REGNUM, cr16_extract_unsigned_integer (memory, 4));
814 size = 4;
815 break;
816 default:
817 size = 0;
818 break;
820 SLOT_FLUSH ();
821 return size;