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