sim: cr16: push down sd/cpu vars
[deliverable/binutils-gdb.git] / sim / cr16 / interp.c
CommitLineData
fee8ec00 1/* Simulation code for the CR16 processor.
32d0add0 2 Copyright (C) 2008-2015 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
26687999 20#include "config.h"
5aedb83b 21#include <inttypes.h>
fee8ec00 22#include <signal.h>
26687999
MF
23#include <stdlib.h>
24#include <string.h>
fee8ec00
SR
25#include "bfd.h"
26#include "gdb/callback.h"
27#include "gdb/remote-sim.h"
28
247ac9ee
MF
29#include "sim-main.h"
30#include "sim-options.h"
31
fee8ec00
SR
32#include "gdb/sim-cr16.h"
33#include "gdb/signals.h"
34#include "opcode/cr16.h"
35
fee8ec00
SR
36int cr16_debug;
37
fee8ec00 38host_callback *cr16_callback;
fee8ec00
SR
39
40uint32 OP[4];
41uint32 sign_flag;
42
267b3b8e 43static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint64 ins, int size);
bdca5ee4 44static void get_operands (operand_desc *s, uint64 mcode, int isize, int nops);
267b3b8e 45static INLINE uint8 *map_memory (SIM_DESC, SIM_CPU *, unsigned phys_addr);
fee8ec00 46
052d9a54
SR
47#define MAX_HASH 16
48
49struct hash_entry
50{
51 struct hash_entry *next;
52 uint32 opcode;
53 uint32 mask;
54 int format;
55 int size;
56 struct simops *ops;
57};
58
59struct hash_entry hash_table[MAX_HASH+1];
60
61INLINE static long
62hash(unsigned long long insn, int format)
63{
64 unsigned int i = 4, tmp;
65 if (format)
66 {
67 while ((insn >> i) != 0) i +=4;
68
69 return ((insn >> (i-4)) & 0xf); /* Use last 4 bits as hask key. */
70 }
71 return ((insn & 0xF)); /* Use last 4 bits as hask key. */
72}
73
74
75INLINE static struct hash_entry *
267b3b8e 76lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint64 ins, int size)
052d9a54
SR
77{
78 uint32 mask;
79 struct hash_entry *h;
80
81 h = &hash_table[hash(ins,1)];
82
83
84 mask = (((1 << (32 - h->mask)) -1) << h->mask);
85
86 /* Adjuest mask for branch with 2 word instructions. */
87 if ((h->ops->mnimonic != NULL) &&
88 ((streq(h->ops->mnimonic,"b") && h->size == 2)))
89 mask = 0xff0f0000;
90
91
92 while ((ins & mask) != (BIN(h->opcode, h->mask)))
93 {
94 if (h->next == NULL)
95 {
96 State.exception = SIGILL;
97 State.pc_changed = 1; /* Don't increment the PC. */
98 return NULL;
99 }
100 h = h->next;
101
102 mask = (((1 << (32 - h->mask)) -1) << h->mask);
103 /* Adjuest mask for branch with 2 word instructions. */
104 if ((streq(h->ops->mnimonic,"b")) && h->size == 2)
105 mask = 0xff0f0000;
106
107 }
108 return (h);
109}
fee8ec00
SR
110
111INLINE static void
052d9a54 112get_operands (operand_desc *s, uint64 ins, int isize, int nops)
fee8ec00
SR
113{
114 uint32 i, opn = 0, start_bit = 0, op_type = 0;
115 int32 op_size = 0, mask = 0;
116
117 if (isize == 1) /* Trunkcate the extra 16 bits of INS. */
118 ins = ins >> 16;
119
052d9a54 120 for (i=0; i < 4; ++i,++opn)
fee8ec00 121 {
052d9a54 122 if (s[opn].op_type == dummy) break;
fee8ec00 123
052d9a54 124 op_type = s[opn].op_type;
fee8ec00
SR
125 start_bit = s[opn].shift;
126 op_size = cr16_optab[op_type].bit_size;
127
128 switch (op_type)
052d9a54 129 {
fee8ec00 130 case imm3: case imm4: case imm5: case imm6:
052d9a54
SR
131 {
132 if (isize == 1)
133 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
fee8ec00 134 else
052d9a54
SR
135 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));
136
137 if (OP[i] & ((long)1 << (op_size -1)))
138 {
139 sign_flag = 1;
140 OP[i] = ~(OP[i]) + 1;
141 }
142 OP[i] = (unsigned long int)(OP[i] & (((long)1 << op_size) -1));
fee8ec00 143 }
052d9a54 144 break;
fee8ec00
SR
145
146 case uimm3: case uimm3_1: case uimm4_1:
052d9a54
SR
147 switch (isize)
148 {
149 case 1:
150 OP[i] = ((ins >> 4) & ((1 << op_size) -1)); break;
151 case 2:
152 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));break;
153 default: /* for case 3. */
154 OP[i] = ((ins >> (16 + start_bit)) & ((1 << op_size) -1)); break;
155 break;
156 }
157 break;
fee8ec00
SR
158
159 case uimm4:
052d9a54
SR
160 switch (isize)
161 {
162 case 1:
163 if (start_bit == 20)
164 OP[i] = ((ins >> 4) & ((1 << op_size) -1));
165 else
166 OP[i] = (ins & ((1 << op_size) -1));
167 break;
168 case 2:
169 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
170 break;
171 case 3:
172 OP[i] = ((ins >> (start_bit + 16)) & ((1 << op_size) -1));
173 break;
174 default:
175 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1));
176 break;
177 }
178 break;
fee8ec00
SR
179
180 case imm16: case uimm16:
181 OP[i] = ins & 0xFFFF;
052d9a54 182 break;
fee8ec00
SR
183
184 case uimm20: case imm20:
052d9a54
SR
185 OP[i] = ins & (((long)1 << op_size) - 1);
186 break;
fee8ec00
SR
187
188 case imm32: case uimm32:
189 OP[i] = ins & 0xFFFFFFFF;
052d9a54 190 break;
fee8ec00 191
052d9a54 192 case uimm5: break; /*NOT USED. */
fee8ec00
SR
193 OP[i] = ins & ((1 << op_size) - 1); break;
194
195 case disps5:
196 OP[i] = (ins >> 4) & ((1 << 4) - 1);
197 OP[i] = (OP[i] * 2) + 2;
052d9a54
SR
198 if (OP[i] & ((long)1 << 5))
199 {
200 sign_flag = 1;
201 OP[i] = ~(OP[i]) + 1;
202 OP[i] = (unsigned long int)(OP[i] & 0x1F);
203 }
204 break;
205
206 case dispe9:
207 OP[i] = ((((ins >> 8) & 0xf) << 4) | (ins & 0xf));
208 OP[i] <<= 1;
209 if (OP[i] & ((long)1 << 8))
210 {
211 sign_flag = 1;
212 OP[i] = ~(OP[i]) + 1;
213 OP[i] = (unsigned long int)(OP[i] & 0xFF);
214 }
215 break;
216
217 case disps17:
218 OP[i] = (ins & 0xFFFF);
219 if (OP[i] & 1)
220 {
221 OP[i] = (OP[i] & 0xFFFE);
222 sign_flag = 1;
223 OP[i] = ~(OP[i]) + 1;
224 OP[i] = (unsigned long int)(OP[i] & 0xFFFF);
fee8ec00 225 }
052d9a54
SR
226 break;
227
228 case disps25:
229 if (isize == 2)
230 OP[i] = (ins & 0xFFFFFF);
231 else
232 OP[i] = (ins & 0xFFFF) | (((ins >> 24) & 0xf) << 16) |
233 (((ins >> 16) & 0xf) << 20);
234
235 if (OP[i] & 1)
236 {
237 OP[i] = (OP[i] & 0xFFFFFE);
238 sign_flag = 1;
239 OP[i] = ~(OP[i]) + 1;
240 OP[i] = (unsigned long int)(OP[i] & 0xFFFFFF);
fee8ec00 241 }
052d9a54 242 break;
fee8ec00
SR
243
244 case abs20:
052d9a54 245 if (isize == 3)
fee8ec00 246 OP[i] = (ins) & 0xFFFFF;
052d9a54 247 else
fee8ec00 248 OP[i] = (ins >> start_bit) & 0xFFFFF;
052d9a54 249 break;
fee8ec00 250 case abs24:
052d9a54
SR
251 if (isize == 3)
252 OP[i] = ((ins & 0xFFFF) | (((ins >> 16) & 0xf) << 20)
253 | (((ins >> 24) & 0xf) << 16));
254 else
255 OP[i] = (ins >> 16) & 0xFFFFFF;
256 break;
fee8ec00
SR
257
258 case rra:
259 case rbase: break; /* NOT USED. */
260 case rbase_disps20: case rbase_dispe20:
261 case rpbase_disps20: case rpindex_disps20:
052d9a54
SR
262 OP[i] = ((((ins >> 24)&0xf) << 16)|((ins) & 0xFFFF));
263 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
264 break;
fee8ec00 265 case rpbase_disps0:
052d9a54
SR
266 OP[i] = 0; /* 4 bit disp const. */
267 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
268 break;
fee8ec00 269 case rpbase_dispe4:
052d9a54
SR
270 OP[i] = ((ins >> 8) & 0xF) * 2; /* 4 bit disp const. */
271 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
272 break;
fee8ec00 273 case rpbase_disps4:
052d9a54
SR
274 OP[i] = ((ins >> 8) & 0xF); /* 4 bit disp const. */
275 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */
276 break;
fee8ec00 277 case rpbase_disps16:
052d9a54
SR
278 OP[i] = (ins) & 0xFFFF;
279 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
280 break;
fee8ec00 281 case rpindex_disps0:
052d9a54
SR
282 OP[i] = 0;
283 OP[++i] = (ins >> 4) & 0xF; /* get 4 bit for reg. */
284 OP[++i] = (ins >> 8) & 0x1; /* get 1 bit for index-reg. */
285 break;
fee8ec00 286 case rpindex_disps14:
052d9a54
SR
287 OP[i] = (ins) & 0x3FFF;
288 OP[++i] = (ins >> 14) & 0x1; /* get 1 bit for index-reg. */
289 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */
fee8ec00
SR
290 case rindex7_abs20:
291 case rindex8_abs20:
052d9a54
SR
292 OP[i] = (ins) & 0xFFFFF;
293 OP[++i] = (ins >> 24) & 0x1; /* get 1 bit for index-reg. */
294 OP[++i] = (ins >> 20) & 0xF; /* get 4 bit for reg. */
295 break;
fee8ec00 296 case regr: case regp: case pregr: case pregrp:
052d9a54
SR
297 switch(isize)
298 {
299 case 1:
300 if (start_bit == 20) OP[i] = (ins >> 4) & 0xF;
301 else if (start_bit == 16) OP[i] = ins & 0xF;
302 break;
303 case 2: OP[i] = (ins >> start_bit) & 0xF; break;
304 case 3: OP[i] = (ins >> (start_bit + 16)) & 0xF; break;
305 }
306 break;
fee8ec00 307 case cc:
052d9a54
SR
308 {
309 if (isize == 1) OP[i] = (ins >> 4) & 0xF;
310 else if (isize == 2) OP[i] = (ins >> start_bit) & 0xF;
311 else OP[i] = (ins >> (start_bit + 16)) & 0xF;
312 break;
313 }
314 default: break;
315 }
fee8ec00 316
052d9a54 317 /* For ESC on uimm4_1 operand. */
fee8ec00 318 if (op_type == uimm4_1)
052d9a54
SR
319 if (OP[i] == 9)
320 OP[i] = -1;
321
322 /* For increment by 1. */
323 if ((op_type == pregr) || (op_type == pregrp))
324 OP[i] += 1;
fee8ec00
SR
325 }
326 /* FIXME: for tracing, update values that need to be updated each
327 instruction decode cycle */
fee8ec00 328 State.trace.psw = PSR;
fee8ec00
SR
329}
330
052d9a54 331static int
267b3b8e 332do_run (SIM_DESC sd, SIM_CPU *cpu, uint64 mcode)
fee8ec00 333{
247ac9ee 334 host_callback *cr16_callback = STATE_CALLBACK (sd);
fee8ec00 335 struct simops *s= Simops;
052d9a54 336 struct hash_entry *h;
fee8ec00 337 char func[12]="\0";
052d9a54 338 uint8 *iaddr;
fee8ec00
SR
339#ifdef DEBUG
340 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
052d9a54 341 (*cr16_callback->printf_filtered) (cr16_callback, "do_long 0x%x\n", mcode);
fee8ec00 342#endif
267b3b8e
MF
343
344 h = lookup_hash (sd, cpu, mcode, 1);
052d9a54 345
5aedb83b
MF
346 if ((h == NULL) || (h->opcode == 0))
347 return 0;
052d9a54
SR
348
349 if (h->size == 3)
350 {
267b3b8e 351 iaddr = imem_addr (sd, cpu, (uint32)PC + 2);
052d9a54
SR
352 mcode = (mcode << 16) | get_longword( iaddr );
353 }
354
355 /* Re-set OP list. */
fee8ec00
SR
356 OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0;
357
052d9a54
SR
358 /* for push/pop/pushrtn with RA instructions. */
359 if ((h->format & REG_LIST) && (mcode & 0x800000))
360 OP[2] = 1; /* Set 1 for RA operand. */
fee8ec00 361
052d9a54
SR
362 /* numops == 0 means, no operands. */
363 if (((h->ops) != NULL) && (((h->ops)->numops) != 0))
364 get_operands ((h->ops)->operands, mcode, h->size, (h->ops)->numops);
fee8ec00 365
052d9a54
SR
366 //State.ins_type = h->flags;
367
267b3b8e 368 (h->ops->func) (sd, cpu);
052d9a54
SR
369
370 return h->size;
fee8ec00
SR
371}
372
247ac9ee 373static void
fee8ec00
SR
374sim_size (int power)
375{
376 int i;
377 for (i = 0; i < IMEM_SEGMENTS; i++)
378 {
379 if (State.mem.insn[i])
052d9a54 380 free (State.mem.insn[i]);
fee8ec00
SR
381 }
382 for (i = 0; i < DMEM_SEGMENTS; i++)
383 {
384 if (State.mem.data[i])
052d9a54 385 free (State.mem.data[i]);
fee8ec00
SR
386 }
387 for (i = 0; i < UMEM_SEGMENTS; i++)
388 {
389 if (State.mem.unif[i])
052d9a54 390 free (State.mem.unif[i]);
fee8ec00
SR
391 }
392 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
393 registers. */
394 State.mem.data[0] = calloc (1, SEGMENT_SIZE);
395}
396
397/* For tracing - leave info on last access around. */
398static char *last_segname = "invalid";
399static char *last_from = "invalid";
400static char *last_to = "invalid";
401
402enum
403 {
404 IMAP0_OFFSET = 0xff00,
405 DMAP0_OFFSET = 0xff08,
406 DMAP2_SHADDOW = 0xff04,
407 DMAP2_OFFSET = 0xff0c
408 };
409
fee8ec00 410static unsigned long
267b3b8e 411dmap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
fee8ec00 412{
267b3b8e 413 uint8 *raw = map_memory (sd, cpu, SIM_CR16_MEMORY_DATA
052d9a54 414 + DMAP0_OFFSET + 2 * reg_nr);
fee8ec00
SR
415 return READ_16 (raw);
416}
417
fee8ec00 418static unsigned long
267b3b8e 419imap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
fee8ec00 420{
267b3b8e 421 uint8 *raw = map_memory (sd, cpu, SIM_CR16_MEMORY_DATA
052d9a54 422 + IMAP0_OFFSET + 2 * reg_nr);
fee8ec00
SR
423 return READ_16 (raw);
424}
425
fee8ec00
SR
426/* Given a virtual address in the DMAP address space, translate it
427 into a physical address. */
428
6637a426 429static unsigned long
267b3b8e
MF
430sim_cr16_translate_dmap_addr (SIM_DESC sd,
431 SIM_CPU *cpu,
432 unsigned long offset,
052d9a54
SR
433 int nr_bytes,
434 unsigned long *phys,
435 void *regcache,
267b3b8e
MF
436 unsigned long (*dmap_register) (SIM_DESC,
437 SIM_CPU *,
438 void *regcache,
052d9a54 439 int reg_nr))
fee8ec00
SR
440{
441 short map;
442 int regno;
443 last_from = "logical-data";
444 if (offset >= DMAP_BLOCK_SIZE * SIM_CR16_NR_DMAP_REGS)
445 {
446 /* Logical address out side of data segments, not supported */
447 return 0;
448 }
449 regno = (offset / DMAP_BLOCK_SIZE);
450 offset = (offset % DMAP_BLOCK_SIZE);
451
452#if 1
453 if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
454 {
455 /* Don't cross a BLOCK boundary */
456 nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
457 }
267b3b8e 458 map = dmap_register (sd, cpu, regcache, regno);
fee8ec00
SR
459 if (regno == 3)
460 {
461 /* Always maps to data memory */
462 int iospi = (offset / 0x1000) % 4;
463 int iosp = (map >> (4 * (3 - iospi))) % 0x10;
464 last_to = "io-space";
465 *phys = (SIM_CR16_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);
466 }
467 else
468 {
469 int sp = ((map & 0x3000) >> 12);
470 int segno = (map & 0x3ff);
471 switch (sp)
052d9a54
SR
472 {
473 case 0: /* 00: Unified memory */
474 *phys = SIM_CR16_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
475 last_to = "unified";
476 break;
477 case 1: /* 01: Instruction Memory */
478 *phys = SIM_CR16_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
479 last_to = "chip-insn";
480 break;
481 case 2: /* 10: Internal data memory */
482 *phys = SIM_CR16_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;
483 last_to = "chip-data";
484 break;
485 case 3: /* 11: Reserved */
486 return 0;
487 }
fee8ec00
SR
488 }
489#endif
490 return nr_bytes;
491}
492
493/* Given a virtual address in the IMAP address space, translate it
494 into a physical address. */
495
6637a426 496static unsigned long
267b3b8e
MF
497sim_cr16_translate_imap_addr (SIM_DESC sd,
498 SIM_CPU *cpu,
499 unsigned long offset,
052d9a54
SR
500 int nr_bytes,
501 unsigned long *phys,
502 void *regcache,
267b3b8e
MF
503 unsigned long (*imap_register) (SIM_DESC,
504 SIM_CPU *,
505 void *regcache,
052d9a54 506 int reg_nr))
fee8ec00
SR
507{
508 short map;
509 int regno;
510 int sp;
511 int segno;
512 last_from = "logical-insn";
513 if (offset >= (IMAP_BLOCK_SIZE * SIM_CR16_NR_IMAP_REGS))
514 {
515 /* Logical address outside of IMAP segments, not supported */
516 return 0;
517 }
518 regno = (offset / IMAP_BLOCK_SIZE);
519 offset = (offset % IMAP_BLOCK_SIZE);
520 if (offset + nr_bytes > IMAP_BLOCK_SIZE)
521 {
522 /* Don't cross a BLOCK boundary */
523 nr_bytes = IMAP_BLOCK_SIZE - offset;
524 }
267b3b8e 525 map = imap_register (sd, cpu, regcache, regno);
fee8ec00
SR
526 sp = (map & 0x3000) >> 12;
527 segno = (map & 0x007f);
528 switch (sp)
529 {
530 case 0: /* 00: unified memory */
531 *phys = SIM_CR16_MEMORY_UNIFIED + (segno << 17) + offset;
532 last_to = "unified";
533 break;
534 case 1: /* 01: instruction memory */
535 *phys = SIM_CR16_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
536 last_to = "chip-insn";
537 break;
538 case 2: /*10*/
539 /* Reserved. */
540 return 0;
541 case 3: /* 11: for testing - instruction memory */
542 offset = (offset % 0x800);
543 *phys = SIM_CR16_MEMORY_INSN + offset;
544 if (offset + nr_bytes > 0x800)
052d9a54
SR
545 /* don't cross VM boundary */
546 nr_bytes = 0x800 - offset;
fee8ec00
SR
547 last_to = "test-insn";
548 break;
549 }
550 return nr_bytes;
551}
552
6637a426 553static unsigned long
267b3b8e
MF
554sim_cr16_translate_addr (SIM_DESC sd,
555 SIM_CPU *cpu,
556 unsigned long memaddr,
557 int nr_bytes,
558 unsigned long *targ_addr,
559 void *regcache,
560 unsigned long (*dmap_register) (SIM_DESC,
561 SIM_CPU *,
562 void *regcache,
563 int reg_nr),
564 unsigned long (*imap_register) (SIM_DESC,
565 SIM_CPU *,
566 void *regcache,
567 int reg_nr))
fee8ec00
SR
568{
569 unsigned long phys;
570 unsigned long seg;
571 unsigned long off;
572
573 last_from = "unknown";
574 last_to = "unknown";
575
576 seg = (memaddr >> 24);
577 off = (memaddr & 0xffffffL);
578
fee8ec00
SR
579 switch (seg)
580 {
052d9a54 581 case 0x00: /* Physical unified memory */
fee8ec00
SR
582 last_from = "phys-unified";
583 last_to = "unified";
584 phys = SIM_CR16_MEMORY_UNIFIED + off;
585 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
052d9a54 586 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
fee8ec00
SR
587 break;
588
052d9a54 589 case 0x01: /* Physical instruction memory */
fee8ec00
SR
590 last_from = "phys-insn";
591 last_to = "chip-insn";
592 phys = SIM_CR16_MEMORY_INSN + off;
593 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
052d9a54 594 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
fee8ec00
SR
595 break;
596
052d9a54 597 case 0x02: /* Physical data memory segment */
fee8ec00
SR
598 last_from = "phys-data";
599 last_to = "chip-data";
600 phys = SIM_CR16_MEMORY_DATA + off;
601 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
052d9a54 602 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
fee8ec00
SR
603 break;
604
052d9a54 605 case 0x10: /* in logical data address segment */
267b3b8e
MF
606 nr_bytes = sim_cr16_translate_dmap_addr (sd, cpu, off, nr_bytes, &phys,
607 regcache, dmap_register);
fee8ec00
SR
608 break;
609
052d9a54 610 case 0x11: /* in logical instruction address segment */
267b3b8e
MF
611 nr_bytes = sim_cr16_translate_imap_addr (sd, cpu, off, nr_bytes, &phys,
612 regcache, imap_register);
fee8ec00
SR
613 break;
614
615 default:
616 return 0;
617 }
618
619 *targ_addr = phys;
620 return nr_bytes;
621}
622
623/* Return a pointer into the raw buffer designated by phys_addr. It
624 is assumed that the client has already ensured that the access
625 isn't going to cross a segment boundary. */
626
627uint8 *
267b3b8e 628map_memory (SIM_DESC sd, SIM_CPU *cpu, unsigned phys_addr)
fee8ec00
SR
629{
630 uint8 **memory;
631 uint8 *raw;
632 unsigned offset;
633 int segment = ((phys_addr >> 24) & 0xff);
634
635 switch (segment)
636 {
637
638 case 0x00: /* Unified memory */
639 {
052d9a54
SR
640 memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
641 last_segname = "umem";
642 break;
fee8ec00
SR
643 }
644
645 case 0x01: /* On-chip insn memory */
646 {
052d9a54
SR
647 memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
648 last_segname = "imem";
649 break;
fee8ec00
SR
650 }
651
652 case 0x02: /* On-chip data memory */
653 {
052d9a54
SR
654 if ((phys_addr & 0xff00) == 0xff00)
655 {
656 phys_addr = (phys_addr & 0xffff);
657 if (phys_addr == DMAP2_SHADDOW)
658 {
659 phys_addr = DMAP2_OFFSET;
660 last_segname = "dmap";
661 }
662 else
663 last_segname = "reg";
664 }
665 else
666 last_segname = "dmem";
667 memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
668 break;
fee8ec00
SR
669 }
670
671 default:
672 /* OOPS! */
673 last_segname = "scrap";
674 return State.mem.fault;
675 }
676
677 if (*memory == NULL)
678 {
679 *memory = calloc (1, SEGMENT_SIZE);
680 if (*memory == NULL)
052d9a54
SR
681 {
682 (*cr16_callback->printf_filtered) (cr16_callback, "Malloc failed.\n");
683 return State.mem.fault;
684 }
fee8ec00
SR
685 }
686
687 offset = (phys_addr % SEGMENT_SIZE);
688 raw = *memory + offset;
689 return raw;
690}
691
692/* Transfer data to/from simulated memory. Since a bug in either the
693 simulated program or in gdb or the simulator itself may cause a
694 bogus address to be passed in, we need to do some sanity checking
695 on addresses to make sure they are within bounds. When an address
696 fails the bounds check, treat it as a zero length read/write rather
697 than aborting the entire run. */
698
699static int
247ac9ee 700xfer_mem (SIM_DESC sd, SIM_ADDR virt,
052d9a54
SR
701 unsigned char *buffer,
702 int size,
703 int write_p)
fee8ec00 704{
247ac9ee 705 host_callback *cr16_callback = STATE_CALLBACK (sd);
fee8ec00
SR
706 uint8 *memory;
707 unsigned long phys;
708 int phys_size;
267b3b8e 709 phys_size = sim_cr16_translate_addr (sd, NULL, virt, size, &phys, NULL,
052d9a54 710 dmap_register, imap_register);
fee8ec00
SR
711 if (phys_size == 0)
712 return 0;
713
267b3b8e 714 memory = map_memory (sd, NULL, phys);
fee8ec00
SR
715
716#ifdef DEBUG
717 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
718 {
719 (*cr16_callback->printf_filtered)
052d9a54
SR
720 (cr16_callback,
721 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
722 (write_p ? "write" : "read"),
723 phys_size, virt, last_from,
724 phys, last_to,
725 (long) memory, last_segname);
fee8ec00
SR
726 }
727#endif
728
729 if (write_p)
730 {
731 memcpy (memory, buffer, phys_size);
732 }
733 else
734 {
735 memcpy (buffer, memory, phys_size);
736 }
737
738 return phys_size;
739}
740
741
742int
5aedb83b 743sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
fee8ec00
SR
744{
745 /* FIXME: this should be performing a virtual transfer */
247ac9ee 746 return xfer_mem (sd, addr, buffer, size, 1);
fee8ec00
SR
747}
748
749int
5aedb83b 750sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
fee8ec00
SR
751{
752 /* FIXME: this should be performing a virtual transfer */
247ac9ee 753 return xfer_mem (sd, addr, buffer, size, 0);
fee8ec00
SR
754}
755
27b97b40
MF
756static sim_cia
757cr16_pc_get (sim_cpu *cpu)
758{
759 return PC;
760}
761
762static void
763cr16_pc_set (sim_cpu *cpu, sim_cia pc)
764{
267b3b8e 765 SIM_DESC sd = CPU_STATE (cpu);
27b97b40
MF
766 SET_PC (pc);
767}
768
247ac9ee
MF
769static void
770free_state (SIM_DESC sd)
771{
772 if (STATE_MODULES (sd) != NULL)
773 sim_module_uninstall (sd);
774 sim_cpu_free_all (sd);
775 sim_state_free (sd);
776}
777
c2270cd8
MF
778static int cr16_reg_fetch (SIM_CPU *, int, unsigned char *, int);
779static int cr16_reg_store (SIM_CPU *, int, unsigned char *, int);
780
fee8ec00 781SIM_DESC
247ac9ee 782sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, struct bfd *abfd, char **argv)
fee8ec00
SR
783{
784 struct simops *s;
052d9a54 785 struct hash_entry *h;
fee8ec00
SR
786 static int init_p = 0;
787 char **p;
247ac9ee
MF
788 int i;
789 SIM_DESC sd = sim_state_alloc (kind, cb);
790 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
791
792 /* The cpu data is kept in a separately allocated chunk of memory. */
793 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
794 {
795 free_state (sd);
796 return 0;
797 }
798
799 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
800 {
801 free_state (sd);
802 return 0;
803 }
804
805 /* getopt will print the error message so we just have to exit if this fails.
806 FIXME: Hmmm... in the case of gdb we need getopt to call
807 print_filtered. */
808 if (sim_parse_args (sd, argv) != SIM_RC_OK)
809 {
810 free_state (sd);
811 return 0;
812 }
813
814 /* Check for/establish the a reference program image. */
815 if (sim_analyze_program (sd,
816 (STATE_PROG_ARGV (sd) != NULL
817 ? *STATE_PROG_ARGV (sd)
818 : NULL), abfd) != SIM_RC_OK)
819 {
820 free_state (sd);
821 return 0;
822 }
823
824 /* Configure/verify the target byte order and other runtime
825 configuration options. */
826 if (sim_config (sd) != SIM_RC_OK)
827 {
828 sim_module_uninstall (sd);
829 return 0;
830 }
831
832 if (sim_post_argv_init (sd) != SIM_RC_OK)
833 {
834 /* Uninstall the modules to avoid memory leaks,
835 file descriptor leaks, etc. */
836 sim_module_uninstall (sd);
837 return 0;
838 }
fee8ec00 839
27b97b40
MF
840 /* CPU specific initialization. */
841 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
842 {
843 SIM_CPU *cpu = STATE_CPU (sd, i);
844
c2270cd8
MF
845 CPU_REG_FETCH (cpu) = cr16_reg_fetch;
846 CPU_REG_STORE (cpu) = cr16_reg_store;
27b97b40
MF
847 CPU_PC_FETCH (cpu) = cr16_pc_get;
848 CPU_PC_STORE (cpu) = cr16_pc_set;
849 }
850
247ac9ee 851 cr16_callback = cb;
fee8ec00 852
052d9a54
SR
853 /* put all the opcodes in the hash table. */
854 if (!init_p++)
855 {
856 for (s = Simops; s->func; s++)
857 {
858 switch(32 - s->mask)
859 {
860 case 0x4:
861 h = &hash_table[hash(s->opcode, 0)];
862 break;
863
864 case 0x7:
865 if (((s->opcode << 1) >> 4) != 0)
866 h = &hash_table[hash((s->opcode << 1) >> 4, 0)];
867 else
868 h = &hash_table[hash((s->opcode << 1), 0)];
869 break;
870
871 case 0x8:
872 if ((s->opcode >> 4) != 0)
873 h = &hash_table[hash(s->opcode >> 4, 0)];
874 else
875 h = &hash_table[hash(s->opcode, 0)];
876 break;
877
878 case 0x9:
879 if (((s->opcode >> 1) >> 4) != 0)
880 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
881 else
882 h = &hash_table[hash((s->opcode >> 1), 0)];
883 break;
884
885 case 0xa:
886 if ((s->opcode >> 8) != 0)
887 h = &hash_table[hash(s->opcode >> 8, 0)];
888 else if ((s->opcode >> 4) != 0)
889 h = &hash_table[hash(s->opcode >> 4, 0)];
890 else
891 h = &hash_table[hash(s->opcode, 0)];
892 break;
893
894 case 0xc:
895 if ((s->opcode >> 8) != 0)
896 h = &hash_table[hash(s->opcode >> 8, 0)];
897 else if ((s->opcode >> 4) != 0)
898 h = &hash_table[hash(s->opcode >> 4, 0)];
899 else
900 h = &hash_table[hash(s->opcode, 0)];
901 break;
902
903 case 0xd:
904 if (((s->opcode >> 1) >> 8) != 0)
905 h = &hash_table[hash((s->opcode >>1) >> 8, 0)];
906 else if (((s->opcode >> 1) >> 4) != 0)
907 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
908 else
909 h = &hash_table[hash((s->opcode >>1), 0)];
910 break;
911
912 case 0x10:
913 if ((s->opcode >> 0xc) != 0)
914 h = &hash_table[hash(s->opcode >> 12, 0)];
915 else if ((s->opcode >> 8) != 0)
916 h = &hash_table[hash(s->opcode >> 8, 0)];
917 else if ((s->opcode >> 4) != 0)
918 h = &hash_table[hash(s->opcode >> 4, 0)];
919 else
920 h = &hash_table[hash(s->opcode, 0)];
921 break;
922
923 case 0x14:
924 if ((s->opcode >> 16) != 0)
925 h = &hash_table[hash(s->opcode >> 16, 0)];
926 else if ((s->opcode >> 12) != 0)
927 h = &hash_table[hash(s->opcode >> 12, 0)];
928 else if ((s->opcode >> 8) != 0)
929 h = &hash_table[hash(s->opcode >> 8, 0)];
930 else if ((s->opcode >> 4) != 0)
931 h = &hash_table[hash(s->opcode >> 4, 0)];
932 else
933 h = &hash_table[hash(s->opcode, 0)];
934 break;
935 default:
936 break;
937 }
938
939 /* go to the last entry in the chain. */
940 while (h->next)
941 h = h->next;
942
943 if (h->ops)
944 {
945 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
946 if (!h->next)
947 perror ("malloc failure");
948
949 h = h->next;
950 }
951 h->ops = s;
952 h->mask = s->mask;
953 h->opcode = s->opcode;
954 h->format = s->format;
955 h->size = s->size;
956 }
957 }
958
fee8ec00
SR
959 /* reset the processor state */
960 if (!State.mem.data[0])
961 sim_size (1);
fee8ec00 962
247ac9ee 963 return sd;
fee8ec00
SR
964}
965
fee8ec00 966uint8 *
267b3b8e 967dmem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset)
fee8ec00
SR
968{
969 unsigned long phys;
970 uint8 *mem;
971 int phys_size;
972
973 /* Note: DMEM address range is 0..0x10000. Calling code can compute
974 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
975 is uint16 this is modulo'ed onto 0x0e5d. */
976
267b3b8e 977 phys_size = sim_cr16_translate_dmap_addr (sd, cpu, offset, 1, &phys, NULL,
052d9a54 978 dmap_register);
fee8ec00
SR
979 if (phys_size == 0)
980 {
981 mem = State.mem.fault;
982 }
983 else
267b3b8e 984 mem = map_memory (sd, cpu, phys);
fee8ec00
SR
985#ifdef DEBUG
986 if ((cr16_debug & DEBUG_MEMORY))
987 {
988 (*cr16_callback->printf_filtered)
052d9a54
SR
989 (cr16_callback,
990 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
991 offset, last_from,
992 phys, phys_size, last_to,
993 (long) mem, last_segname);
fee8ec00
SR
994 }
995#endif
996 return mem;
997}
998
999uint8 *
267b3b8e 1000imem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset)
fee8ec00
SR
1001{
1002 unsigned long phys;
1003 uint8 *mem;
267b3b8e 1004 int phys_size = sim_cr16_translate_imap_addr (sd, cpu, offset, 1, &phys, NULL,
052d9a54 1005 imap_register);
fee8ec00
SR
1006 if (phys_size == 0)
1007 {
1008 return State.mem.fault;
1009 }
267b3b8e 1010 mem = map_memory (sd, cpu, phys);
fee8ec00
SR
1011#ifdef DEBUG
1012 if ((cr16_debug & DEBUG_MEMORY))
1013 {
1014 (*cr16_callback->printf_filtered)
052d9a54
SR
1015 (cr16_callback,
1016 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1017 offset, last_from,
1018 phys, phys_size, last_to,
1019 (long) mem, last_segname);
fee8ec00
SR
1020 }
1021#endif
1022 return mem;
1023}
1024
1025static int stop_simulator = 0;
1026
1027int
5aedb83b 1028sim_stop (SIM_DESC sd)
fee8ec00
SR
1029{
1030 stop_simulator = 1;
1031 return 1;
1032}
1033
1034
1035/* Run (or resume) the program. */
1036void
1037sim_resume (SIM_DESC sd, int step, int siggnal)
1038{
267b3b8e 1039 SIM_CPU *cpu = STATE_CPU (sd, 0);
052d9a54
SR
1040 uint32 curr_ins_size = 0;
1041 uint64 mcode = 0;
fee8ec00
SR
1042 uint8 *iaddr;
1043
1044#ifdef DEBUG
1045// (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
1046#endif
1047
1048 State.exception = 0;
1049 if (step)
1050 sim_stop (sd);
1051
1052 switch (siggnal)
1053 {
1054 case 0:
1055 break;
1056#ifdef SIGBUS
1057 case SIGBUS:
1058#endif
1059 case SIGSEGV:
1060 SET_PC (PC);
1061 SET_PSR (PSR);
1062 JMP (AE_VECTOR_START);
1063 SLOT_FLUSH ();
1064 break;
1065 case SIGILL:
1066 SET_PC (PC);
1067 SET_PSR (PSR);
1068 SET_HW_PSR ((PSR & (PSR_C_BIT)));
1069 JMP (RIE_VECTOR_START);
1070 SLOT_FLUSH ();
1071 break;
1072 default:
1073 /* just ignore it */
1074 break;
1075 }
1076
1077 do
1078 {
267b3b8e 1079 iaddr = imem_addr (sd, cpu, (uint32)PC);
fee8ec00 1080 if (iaddr == State.mem.fault)
052d9a54 1081 {
5a06d7c4 1082#ifdef SIGBUS
052d9a54 1083 State.exception = SIGBUS;
5a06d7c4
MF
1084#else
1085 State.exception = SIGSEGV;
1086#endif
052d9a54
SR
1087 break;
1088 }
fee8ec00
SR
1089
1090 mcode = get_longword( iaddr );
1091
1092 State.pc_changed = 0;
1093
267b3b8e 1094 curr_ins_size = do_run (sd, cpu, mcode);
fee8ec00
SR
1095
1096#if CR16_DEBUG
1097 (*cr16_callback->printf_filtered) (cr16_callback, "INS: PC=0x%X, mcode=0x%X\n",PC,mcode);
1098#endif
fee8ec00 1099
fee8ec00 1100 if (!State.pc_changed)
052d9a54
SR
1101 {
1102 if (curr_ins_size == 0)
1103 {
1104 State.exception = SIG_CR16_EXIT; /* exit trap */
1105 break;
1106 }
1107 else
1108 SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */
1109 }
1110
fee8ec00 1111#if 0
052d9a54
SR
1112 /* Check for a breakpoint trap on this instruction. This
1113 overrides any pending branches or loops */
fee8ec00 1114 if (PSR_DB && PC == DBS)
052d9a54
SR
1115 {
1116 SET_BPC (PC);
1117 SET_BPSR (PSR);
1118 SET_PC (SDBT_VECTOR_START);
1119 }
fee8ec00
SR
1120#endif
1121
1122 /* Writeback all the DATA / PC changes */
1123 SLOT_FLUSH ();
fee8ec00
SR
1124 }
1125 while ( !State.exception && !stop_simulator);
1126
1127 if (step && !State.exception)
1128 State.exception = SIGTRAP;
1129}
1130
fee8ec00
SR
1131SIM_RC
1132sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
1133{
1134 bfd_vma start_address;
1135
1136 /* reset all state information */
5aedb83b 1137 memset (&State.regs, 0, (uintptr_t)&State.mem - (uintptr_t)&State.regs);
fee8ec00
SR
1138
1139 /* There was a hack here to copy the values of argc and argv into r0
1140 and r1. The values were also saved into some high memory that
1141 won't be overwritten by the stack (0x7C00). The reason for doing
1142 this was to allow the 'run' program to accept arguments. Without
1143 the hack, this is not possible anymore. If the simulator is run
1144 from the debugger, arguments cannot be passed in, so this makes
1145 no difference. */
1146
1147 /* set PC */
1148 if (abfd != NULL)
1149 start_address = bfd_get_start_address (abfd);
1150 else
1151 start_address = 0x0;
1152#ifdef DEBUG
1153 if (cr16_debug)
1154 (*cr16_callback->printf_filtered) (cr16_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
1155#endif
267b3b8e
MF
1156 {
1157 SIM_CPU *cpu = STATE_CPU (sd, 0);
1158 SET_CREG (PC_CR, start_address);
1159 }
fee8ec00
SR
1160
1161 SLOT_FLUSH ();
1162 return SIM_RC_OK;
1163}
1164
fee8ec00 1165void
5aedb83b 1166sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
fee8ec00
SR
1167{
1168/* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1169
1170 switch (State.exception)
1171 {
052d9a54 1172 case SIG_CR16_STOP: /* stop instruction */
fee8ec00
SR
1173 *reason = sim_stopped;
1174 *sigrc = 0;
1175 break;
1176
052d9a54 1177 case SIG_CR16_EXIT: /* exit trap */
fee8ec00
SR
1178 *reason = sim_exited;
1179 *sigrc = GPR (2);
1180 break;
1181
1182 case SIG_CR16_BUS:
1183 *reason = sim_stopped;
a493e3e2 1184 *sigrc = GDB_SIGNAL_BUS;
fee8ec00
SR
1185 break;
1186//
1187// case SIG_CR16_IAD:
1188// *reason = sim_stopped;
a493e3e2 1189// *sigrc = GDB_SIGNAL_IAD;
fee8ec00
SR
1190// break;
1191
052d9a54 1192 default: /* some signal */
fee8ec00
SR
1193 *reason = sim_stopped;
1194 if (stop_simulator && !State.exception)
a493e3e2 1195 *sigrc = GDB_SIGNAL_INT;
fee8ec00 1196 else
052d9a54 1197 *sigrc = State.exception;
fee8ec00
SR
1198 break;
1199 }
1200
1201 stop_simulator = 0;
1202}
1203
c2270cd8
MF
1204static uint32
1205cr16_extract_unsigned_integer (unsigned char *addr, int len)
1206{
1207 uint32 retval;
1208 unsigned char * p;
1209 unsigned char * startaddr = (unsigned char *)addr;
1210 unsigned char * endaddr = startaddr + len;
1211
1212 retval = 0;
1213
1214 for (p = endaddr; p > startaddr;)
1215 retval = (retval << 8) | *--p;
1216
1217 return retval;
1218}
1219
1220static void
1221cr16_store_unsigned_integer (unsigned char *addr, int len, uint32 val)
1222{
1223 unsigned char *p;
1224 unsigned char *startaddr = addr;
1225 unsigned char *endaddr = startaddr + len;
1226
1227 for (p = startaddr; p < endaddr;)
1228 {
1229 *p++ = val & 0xff;
1230 val >>= 8;
1231 }
1232}
1233
1234static int
1235cr16_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
fee8ec00
SR
1236{
1237 int size;
1238 switch ((enum sim_cr16_regs) rn)
1239 {
1240 case SIM_CR16_R0_REGNUM:
1241 case SIM_CR16_R1_REGNUM:
1242 case SIM_CR16_R2_REGNUM:
1243 case SIM_CR16_R3_REGNUM:
1244 case SIM_CR16_R4_REGNUM:
1245 case SIM_CR16_R5_REGNUM:
1246 case SIM_CR16_R6_REGNUM:
1247 case SIM_CR16_R7_REGNUM:
1248 case SIM_CR16_R8_REGNUM:
1249 case SIM_CR16_R9_REGNUM:
1250 case SIM_CR16_R10_REGNUM:
1251 case SIM_CR16_R11_REGNUM:
c2270cd8 1252 cr16_store_unsigned_integer (memory, 2, GPR (rn - SIM_CR16_R0_REGNUM));
fee8ec00
SR
1253 size = 2;
1254 break;
1255 case SIM_CR16_R12_REGNUM:
1256 case SIM_CR16_R13_REGNUM:
1257 case SIM_CR16_R14_REGNUM:
1258 case SIM_CR16_R15_REGNUM:
c2270cd8 1259 cr16_store_unsigned_integer (memory, 4, GPR (rn - SIM_CR16_R0_REGNUM));
fee8ec00
SR
1260 size = 4;
1261 break;
1262 case SIM_CR16_PC_REGNUM:
1263 case SIM_CR16_ISP_REGNUM:
1264 case SIM_CR16_USP_REGNUM:
1265 case SIM_CR16_INTBASE_REGNUM:
1266 case SIM_CR16_PSR_REGNUM:
1267 case SIM_CR16_CFG_REGNUM:
1268 case SIM_CR16_DBS_REGNUM:
1269 case SIM_CR16_DCR_REGNUM:
1270 case SIM_CR16_DSR_REGNUM:
1271 case SIM_CR16_CAR0_REGNUM:
1272 case SIM_CR16_CAR1_REGNUM:
c2270cd8 1273 cr16_store_unsigned_integer (memory, 4, CREG (rn - SIM_CR16_PC_REGNUM));
fee8ec00
SR
1274 size = 4;
1275 break;
1276 default:
1277 size = 0;
1278 break;
1279 }
1280 return size;
1281}
c2270cd8
MF
1282
1283static int
1284cr16_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
fee8ec00 1285{
267b3b8e 1286 SIM_DESC sd = CPU_STATE (cpu);
fee8ec00
SR
1287 int size;
1288 switch ((enum sim_cr16_regs) rn)
1289 {
1290 case SIM_CR16_R0_REGNUM:
1291 case SIM_CR16_R1_REGNUM:
1292 case SIM_CR16_R2_REGNUM:
1293 case SIM_CR16_R3_REGNUM:
1294 case SIM_CR16_R4_REGNUM:
1295 case SIM_CR16_R5_REGNUM:
1296 case SIM_CR16_R6_REGNUM:
1297 case SIM_CR16_R7_REGNUM:
1298 case SIM_CR16_R8_REGNUM:
1299 case SIM_CR16_R9_REGNUM:
1300 case SIM_CR16_R10_REGNUM:
1301 case SIM_CR16_R11_REGNUM:
c2270cd8 1302 SET_GPR (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
fee8ec00
SR
1303 size = 2;
1304 break;
1305 case SIM_CR16_R12_REGNUM:
1306 case SIM_CR16_R13_REGNUM:
1307 case SIM_CR16_R14_REGNUM:
1308 case SIM_CR16_R15_REGNUM:
c2270cd8 1309 SET_GPR32 (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
fee8ec00
SR
1310 size = 4;
1311 break;
1312 case SIM_CR16_PC_REGNUM:
1313 case SIM_CR16_ISP_REGNUM:
1314 case SIM_CR16_USP_REGNUM:
1315 case SIM_CR16_INTBASE_REGNUM:
1316 case SIM_CR16_PSR_REGNUM:
1317 case SIM_CR16_CFG_REGNUM:
1318 case SIM_CR16_DBS_REGNUM:
1319 case SIM_CR16_DCR_REGNUM:
1320 case SIM_CR16_DSR_REGNUM:
1321 case SIM_CR16_CAR0_REGNUM:
1322 case SIM_CR16_CAR1_REGNUM:
c2270cd8 1323 SET_CREG (rn - SIM_CR16_PC_REGNUM, cr16_extract_unsigned_integer (memory, 4));
fee8ec00
SR
1324 size = 4;
1325 break;
1326 default:
1327 size = 0;
1328 break;
1329 }
1330 SLOT_FLUSH ();
1331 return size;
1332}
This page took 0.395969 seconds and 4 git commands to generate.