sim: cr16: delete unused memory helpers
[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
bdca5ee4
TT
43static struct hash_entry *lookup_hash (uint64 ins, int size);
44static void get_operands (operand_desc *s, uint64 mcode, int isize, int nops);
fee8ec00
SR
45static INLINE uint8 *map_memory (unsigned phys_addr);
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 *
76lookup_hash (uint64 ins, int size)
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
247ac9ee 332do_run (SIM_DESC sd, 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
SR
342#endif
343
052d9a54
SR
344 h = lookup_hash(mcode, 1);
345
5aedb83b
MF
346 if ((h == NULL) || (h->opcode == 0))
347 return 0;
052d9a54
SR
348
349 if (h->size == 3)
350 {
351 iaddr = imem_addr ((uint32)PC + 2);
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
368 (h->ops->func)();
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
SR
410static unsigned long
411dmap_register (void *regcache, int reg_nr)
412{
413 uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA
052d9a54 414 + DMAP0_OFFSET + 2 * reg_nr);
fee8ec00
SR
415 return READ_16 (raw);
416}
417
fee8ec00
SR
418static unsigned long
419imap_register (void *regcache, int reg_nr)
420{
421 uint8 *raw = map_memory (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
fee8ec00 430sim_cr16_translate_dmap_addr (unsigned long offset,
052d9a54
SR
431 int nr_bytes,
432 unsigned long *phys,
433 void *regcache,
434 unsigned long (*dmap_register) (void *regcache,
435 int reg_nr))
fee8ec00
SR
436{
437 short map;
438 int regno;
439 last_from = "logical-data";
440 if (offset >= DMAP_BLOCK_SIZE * SIM_CR16_NR_DMAP_REGS)
441 {
442 /* Logical address out side of data segments, not supported */
443 return 0;
444 }
445 regno = (offset / DMAP_BLOCK_SIZE);
446 offset = (offset % DMAP_BLOCK_SIZE);
447
448#if 1
449 if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
450 {
451 /* Don't cross a BLOCK boundary */
452 nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
453 }
454 map = dmap_register (regcache, regno);
455 if (regno == 3)
456 {
457 /* Always maps to data memory */
458 int iospi = (offset / 0x1000) % 4;
459 int iosp = (map >> (4 * (3 - iospi))) % 0x10;
460 last_to = "io-space";
461 *phys = (SIM_CR16_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);
462 }
463 else
464 {
465 int sp = ((map & 0x3000) >> 12);
466 int segno = (map & 0x3ff);
467 switch (sp)
052d9a54
SR
468 {
469 case 0: /* 00: Unified memory */
470 *phys = SIM_CR16_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
471 last_to = "unified";
472 break;
473 case 1: /* 01: Instruction Memory */
474 *phys = SIM_CR16_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
475 last_to = "chip-insn";
476 break;
477 case 2: /* 10: Internal data memory */
478 *phys = SIM_CR16_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;
479 last_to = "chip-data";
480 break;
481 case 3: /* 11: Reserved */
482 return 0;
483 }
fee8ec00
SR
484 }
485#endif
486 return nr_bytes;
487}
488
489/* Given a virtual address in the IMAP address space, translate it
490 into a physical address. */
491
6637a426 492static unsigned long
fee8ec00 493sim_cr16_translate_imap_addr (unsigned long offset,
052d9a54
SR
494 int nr_bytes,
495 unsigned long *phys,
496 void *regcache,
497 unsigned long (*imap_register) (void *regcache,
498 int reg_nr))
fee8ec00
SR
499{
500 short map;
501 int regno;
502 int sp;
503 int segno;
504 last_from = "logical-insn";
505 if (offset >= (IMAP_BLOCK_SIZE * SIM_CR16_NR_IMAP_REGS))
506 {
507 /* Logical address outside of IMAP segments, not supported */
508 return 0;
509 }
510 regno = (offset / IMAP_BLOCK_SIZE);
511 offset = (offset % IMAP_BLOCK_SIZE);
512 if (offset + nr_bytes > IMAP_BLOCK_SIZE)
513 {
514 /* Don't cross a BLOCK boundary */
515 nr_bytes = IMAP_BLOCK_SIZE - offset;
516 }
517 map = imap_register (regcache, regno);
518 sp = (map & 0x3000) >> 12;
519 segno = (map & 0x007f);
520 switch (sp)
521 {
522 case 0: /* 00: unified memory */
523 *phys = SIM_CR16_MEMORY_UNIFIED + (segno << 17) + offset;
524 last_to = "unified";
525 break;
526 case 1: /* 01: instruction memory */
527 *phys = SIM_CR16_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
528 last_to = "chip-insn";
529 break;
530 case 2: /*10*/
531 /* Reserved. */
532 return 0;
533 case 3: /* 11: for testing - instruction memory */
534 offset = (offset % 0x800);
535 *phys = SIM_CR16_MEMORY_INSN + offset;
536 if (offset + nr_bytes > 0x800)
052d9a54
SR
537 /* don't cross VM boundary */
538 nr_bytes = 0x800 - offset;
fee8ec00
SR
539 last_to = "test-insn";
540 break;
541 }
542 return nr_bytes;
543}
544
6637a426 545static unsigned long
052d9a54
SR
546sim_cr16_translate_addr (unsigned long memaddr, int nr_bytes,
547 unsigned long *targ_addr, void *regcache,
548 unsigned long (*dmap_register) (void *regcache,
549 int reg_nr),
550 unsigned long (*imap_register) (void *regcache,
551 int reg_nr))
fee8ec00
SR
552{
553 unsigned long phys;
554 unsigned long seg;
555 unsigned long off;
556
557 last_from = "unknown";
558 last_to = "unknown";
559
560 seg = (memaddr >> 24);
561 off = (memaddr & 0xffffffL);
562
fee8ec00
SR
563 switch (seg)
564 {
052d9a54 565 case 0x00: /* Physical unified memory */
fee8ec00
SR
566 last_from = "phys-unified";
567 last_to = "unified";
568 phys = SIM_CR16_MEMORY_UNIFIED + off;
569 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
052d9a54 570 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
fee8ec00
SR
571 break;
572
052d9a54 573 case 0x01: /* Physical instruction memory */
fee8ec00
SR
574 last_from = "phys-insn";
575 last_to = "chip-insn";
576 phys = SIM_CR16_MEMORY_INSN + off;
577 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
052d9a54 578 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
fee8ec00
SR
579 break;
580
052d9a54 581 case 0x02: /* Physical data memory segment */
fee8ec00
SR
582 last_from = "phys-data";
583 last_to = "chip-data";
584 phys = SIM_CR16_MEMORY_DATA + 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 0x10: /* in logical data address segment */
fee8ec00 590 nr_bytes = sim_cr16_translate_dmap_addr (off, nr_bytes, &phys, regcache,
052d9a54 591 dmap_register);
fee8ec00
SR
592 break;
593
052d9a54 594 case 0x11: /* in logical instruction address segment */
fee8ec00 595 nr_bytes = sim_cr16_translate_imap_addr (off, nr_bytes, &phys, regcache,
052d9a54 596 imap_register);
fee8ec00
SR
597 break;
598
599 default:
600 return 0;
601 }
602
603 *targ_addr = phys;
604 return nr_bytes;
605}
606
607/* Return a pointer into the raw buffer designated by phys_addr. It
608 is assumed that the client has already ensured that the access
609 isn't going to cross a segment boundary. */
610
611uint8 *
612map_memory (unsigned phys_addr)
613{
614 uint8 **memory;
615 uint8 *raw;
616 unsigned offset;
617 int segment = ((phys_addr >> 24) & 0xff);
618
619 switch (segment)
620 {
621
622 case 0x00: /* Unified memory */
623 {
052d9a54
SR
624 memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
625 last_segname = "umem";
626 break;
fee8ec00
SR
627 }
628
629 case 0x01: /* On-chip insn memory */
630 {
052d9a54
SR
631 memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
632 last_segname = "imem";
633 break;
fee8ec00
SR
634 }
635
636 case 0x02: /* On-chip data memory */
637 {
052d9a54
SR
638 if ((phys_addr & 0xff00) == 0xff00)
639 {
640 phys_addr = (phys_addr & 0xffff);
641 if (phys_addr == DMAP2_SHADDOW)
642 {
643 phys_addr = DMAP2_OFFSET;
644 last_segname = "dmap";
645 }
646 else
647 last_segname = "reg";
648 }
649 else
650 last_segname = "dmem";
651 memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
652 break;
fee8ec00
SR
653 }
654
655 default:
656 /* OOPS! */
657 last_segname = "scrap";
658 return State.mem.fault;
659 }
660
661 if (*memory == NULL)
662 {
663 *memory = calloc (1, SEGMENT_SIZE);
664 if (*memory == NULL)
052d9a54
SR
665 {
666 (*cr16_callback->printf_filtered) (cr16_callback, "Malloc failed.\n");
667 return State.mem.fault;
668 }
fee8ec00
SR
669 }
670
671 offset = (phys_addr % SEGMENT_SIZE);
672 raw = *memory + offset;
673 return raw;
674}
675
676/* Transfer data to/from simulated memory. Since a bug in either the
677 simulated program or in gdb or the simulator itself may cause a
678 bogus address to be passed in, we need to do some sanity checking
679 on addresses to make sure they are within bounds. When an address
680 fails the bounds check, treat it as a zero length read/write rather
681 than aborting the entire run. */
682
683static int
247ac9ee 684xfer_mem (SIM_DESC sd, SIM_ADDR virt,
052d9a54
SR
685 unsigned char *buffer,
686 int size,
687 int write_p)
fee8ec00 688{
247ac9ee 689 host_callback *cr16_callback = STATE_CALLBACK (sd);
fee8ec00
SR
690 uint8 *memory;
691 unsigned long phys;
692 int phys_size;
693 phys_size = sim_cr16_translate_addr (virt, size, &phys, NULL,
052d9a54 694 dmap_register, imap_register);
fee8ec00
SR
695 if (phys_size == 0)
696 return 0;
697
698 memory = map_memory (phys);
699
700#ifdef DEBUG
701 if ((cr16_debug & DEBUG_INSTRUCTION) != 0)
702 {
703 (*cr16_callback->printf_filtered)
052d9a54
SR
704 (cr16_callback,
705 "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
706 (write_p ? "write" : "read"),
707 phys_size, virt, last_from,
708 phys, last_to,
709 (long) memory, last_segname);
fee8ec00
SR
710 }
711#endif
712
713 if (write_p)
714 {
715 memcpy (memory, buffer, phys_size);
716 }
717 else
718 {
719 memcpy (buffer, memory, phys_size);
720 }
721
722 return phys_size;
723}
724
725
726int
5aedb83b 727sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
fee8ec00
SR
728{
729 /* FIXME: this should be performing a virtual transfer */
247ac9ee 730 return xfer_mem (sd, addr, buffer, size, 1);
fee8ec00
SR
731}
732
733int
5aedb83b 734sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
fee8ec00
SR
735{
736 /* FIXME: this should be performing a virtual transfer */
247ac9ee 737 return xfer_mem (sd, addr, buffer, size, 0);
fee8ec00
SR
738}
739
27b97b40
MF
740static sim_cia
741cr16_pc_get (sim_cpu *cpu)
742{
743 return PC;
744}
745
746static void
747cr16_pc_set (sim_cpu *cpu, sim_cia pc)
748{
749 SET_PC (pc);
750}
751
247ac9ee
MF
752static void
753free_state (SIM_DESC sd)
754{
755 if (STATE_MODULES (sd) != NULL)
756 sim_module_uninstall (sd);
757 sim_cpu_free_all (sd);
758 sim_state_free (sd);
759}
760
c2270cd8
MF
761static int cr16_reg_fetch (SIM_CPU *, int, unsigned char *, int);
762static int cr16_reg_store (SIM_CPU *, int, unsigned char *, int);
763
247ac9ee
MF
764SIM_DESC trace_sd = NULL;
765
fee8ec00 766SIM_DESC
247ac9ee 767sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, struct bfd *abfd, char **argv)
fee8ec00
SR
768{
769 struct simops *s;
052d9a54 770 struct hash_entry *h;
fee8ec00
SR
771 static int init_p = 0;
772 char **p;
247ac9ee
MF
773 int i;
774 SIM_DESC sd = sim_state_alloc (kind, cb);
775 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
776
777 /* The cpu data is kept in a separately allocated chunk of memory. */
778 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
779 {
780 free_state (sd);
781 return 0;
782 }
783
784 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
785 {
786 free_state (sd);
787 return 0;
788 }
789
790 /* getopt will print the error message so we just have to exit if this fails.
791 FIXME: Hmmm... in the case of gdb we need getopt to call
792 print_filtered. */
793 if (sim_parse_args (sd, argv) != SIM_RC_OK)
794 {
795 free_state (sd);
796 return 0;
797 }
798
799 /* Check for/establish the a reference program image. */
800 if (sim_analyze_program (sd,
801 (STATE_PROG_ARGV (sd) != NULL
802 ? *STATE_PROG_ARGV (sd)
803 : NULL), abfd) != SIM_RC_OK)
804 {
805 free_state (sd);
806 return 0;
807 }
808
809 /* Configure/verify the target byte order and other runtime
810 configuration options. */
811 if (sim_config (sd) != SIM_RC_OK)
812 {
813 sim_module_uninstall (sd);
814 return 0;
815 }
816
817 if (sim_post_argv_init (sd) != SIM_RC_OK)
818 {
819 /* Uninstall the modules to avoid memory leaks,
820 file descriptor leaks, etc. */
821 sim_module_uninstall (sd);
822 return 0;
823 }
fee8ec00 824
27b97b40
MF
825 /* CPU specific initialization. */
826 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
827 {
828 SIM_CPU *cpu = STATE_CPU (sd, i);
829
c2270cd8
MF
830 CPU_REG_FETCH (cpu) = cr16_reg_fetch;
831 CPU_REG_STORE (cpu) = cr16_reg_store;
27b97b40
MF
832 CPU_PC_FETCH (cpu) = cr16_pc_get;
833 CPU_PC_STORE (cpu) = cr16_pc_set;
834 }
835
247ac9ee
MF
836 trace_sd = sd;
837 cr16_callback = cb;
fee8ec00 838
052d9a54
SR
839 /* put all the opcodes in the hash table. */
840 if (!init_p++)
841 {
842 for (s = Simops; s->func; s++)
843 {
844 switch(32 - s->mask)
845 {
846 case 0x4:
847 h = &hash_table[hash(s->opcode, 0)];
848 break;
849
850 case 0x7:
851 if (((s->opcode << 1) >> 4) != 0)
852 h = &hash_table[hash((s->opcode << 1) >> 4, 0)];
853 else
854 h = &hash_table[hash((s->opcode << 1), 0)];
855 break;
856
857 case 0x8:
858 if ((s->opcode >> 4) != 0)
859 h = &hash_table[hash(s->opcode >> 4, 0)];
860 else
861 h = &hash_table[hash(s->opcode, 0)];
862 break;
863
864 case 0x9:
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 0xa:
872 if ((s->opcode >> 8) != 0)
873 h = &hash_table[hash(s->opcode >> 8, 0)];
874 else if ((s->opcode >> 4) != 0)
875 h = &hash_table[hash(s->opcode >> 4, 0)];
876 else
877 h = &hash_table[hash(s->opcode, 0)];
878 break;
879
880 case 0xc:
881 if ((s->opcode >> 8) != 0)
882 h = &hash_table[hash(s->opcode >> 8, 0)];
883 else if ((s->opcode >> 4) != 0)
884 h = &hash_table[hash(s->opcode >> 4, 0)];
885 else
886 h = &hash_table[hash(s->opcode, 0)];
887 break;
888
889 case 0xd:
890 if (((s->opcode >> 1) >> 8) != 0)
891 h = &hash_table[hash((s->opcode >>1) >> 8, 0)];
892 else if (((s->opcode >> 1) >> 4) != 0)
893 h = &hash_table[hash((s->opcode >>1) >> 4, 0)];
894 else
895 h = &hash_table[hash((s->opcode >>1), 0)];
896 break;
897
898 case 0x10:
899 if ((s->opcode >> 0xc) != 0)
900 h = &hash_table[hash(s->opcode >> 12, 0)];
901 else if ((s->opcode >> 8) != 0)
902 h = &hash_table[hash(s->opcode >> 8, 0)];
903 else if ((s->opcode >> 4) != 0)
904 h = &hash_table[hash(s->opcode >> 4, 0)];
905 else
906 h = &hash_table[hash(s->opcode, 0)];
907 break;
908
909 case 0x14:
910 if ((s->opcode >> 16) != 0)
911 h = &hash_table[hash(s->opcode >> 16, 0)];
912 else if ((s->opcode >> 12) != 0)
913 h = &hash_table[hash(s->opcode >> 12, 0)];
914 else if ((s->opcode >> 8) != 0)
915 h = &hash_table[hash(s->opcode >> 8, 0)];
916 else if ((s->opcode >> 4) != 0)
917 h = &hash_table[hash(s->opcode >> 4, 0)];
918 else
919 h = &hash_table[hash(s->opcode, 0)];
920 break;
921 default:
922 break;
923 }
924
925 /* go to the last entry in the chain. */
926 while (h->next)
927 h = h->next;
928
929 if (h->ops)
930 {
931 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
932 if (!h->next)
933 perror ("malloc failure");
934
935 h = h->next;
936 }
937 h->ops = s;
938 h->mask = s->mask;
939 h->opcode = s->opcode;
940 h->format = s->format;
941 h->size = s->size;
942 }
943 }
944
fee8ec00
SR
945 /* reset the processor state */
946 if (!State.mem.data[0])
947 sim_size (1);
fee8ec00 948
247ac9ee 949 return sd;
fee8ec00
SR
950}
951
fee8ec00
SR
952uint8 *
953dmem_addr (uint32 offset)
954{
955 unsigned long phys;
956 uint8 *mem;
957 int phys_size;
958
959 /* Note: DMEM address range is 0..0x10000. Calling code can compute
960 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
961 is uint16 this is modulo'ed onto 0x0e5d. */
962
963 phys_size = sim_cr16_translate_dmap_addr (offset, 1, &phys, NULL,
052d9a54 964 dmap_register);
fee8ec00
SR
965 if (phys_size == 0)
966 {
967 mem = State.mem.fault;
968 }
969 else
970 mem = map_memory (phys);
971#ifdef DEBUG
972 if ((cr16_debug & DEBUG_MEMORY))
973 {
974 (*cr16_callback->printf_filtered)
052d9a54
SR
975 (cr16_callback,
976 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
977 offset, last_from,
978 phys, phys_size, last_to,
979 (long) mem, last_segname);
fee8ec00
SR
980 }
981#endif
982 return mem;
983}
984
985uint8 *
986imem_addr (uint32 offset)
987{
988 unsigned long phys;
989 uint8 *mem;
990 int phys_size = sim_cr16_translate_imap_addr (offset, 1, &phys, NULL,
052d9a54 991 imap_register);
fee8ec00
SR
992 if (phys_size == 0)
993 {
994 return State.mem.fault;
995 }
996 mem = map_memory (phys);
997#ifdef DEBUG
998 if ((cr16_debug & DEBUG_MEMORY))
999 {
1000 (*cr16_callback->printf_filtered)
052d9a54
SR
1001 (cr16_callback,
1002 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
1003 offset, last_from,
1004 phys, phys_size, last_to,
1005 (long) mem, last_segname);
fee8ec00
SR
1006 }
1007#endif
1008 return mem;
1009}
1010
1011static int stop_simulator = 0;
1012
1013int
5aedb83b 1014sim_stop (SIM_DESC sd)
fee8ec00
SR
1015{
1016 stop_simulator = 1;
1017 return 1;
1018}
1019
1020
1021/* Run (or resume) the program. */
1022void
1023sim_resume (SIM_DESC sd, int step, int siggnal)
1024{
052d9a54
SR
1025 uint32 curr_ins_size = 0;
1026 uint64 mcode = 0;
fee8ec00
SR
1027 uint8 *iaddr;
1028
1029#ifdef DEBUG
1030// (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC);
1031#endif
1032
1033 State.exception = 0;
1034 if (step)
1035 sim_stop (sd);
1036
1037 switch (siggnal)
1038 {
1039 case 0:
1040 break;
1041#ifdef SIGBUS
1042 case SIGBUS:
1043#endif
1044 case SIGSEGV:
1045 SET_PC (PC);
1046 SET_PSR (PSR);
1047 JMP (AE_VECTOR_START);
1048 SLOT_FLUSH ();
1049 break;
1050 case SIGILL:
1051 SET_PC (PC);
1052 SET_PSR (PSR);
1053 SET_HW_PSR ((PSR & (PSR_C_BIT)));
1054 JMP (RIE_VECTOR_START);
1055 SLOT_FLUSH ();
1056 break;
1057 default:
1058 /* just ignore it */
1059 break;
1060 }
1061
1062 do
1063 {
1064 iaddr = imem_addr ((uint32)PC);
fee8ec00 1065 if (iaddr == State.mem.fault)
052d9a54 1066 {
5a06d7c4 1067#ifdef SIGBUS
052d9a54 1068 State.exception = SIGBUS;
5a06d7c4
MF
1069#else
1070 State.exception = SIGSEGV;
1071#endif
052d9a54
SR
1072 break;
1073 }
fee8ec00
SR
1074
1075 mcode = get_longword( iaddr );
1076
1077 State.pc_changed = 0;
1078
247ac9ee 1079 curr_ins_size = do_run(sd, mcode);
fee8ec00
SR
1080
1081#if CR16_DEBUG
1082 (*cr16_callback->printf_filtered) (cr16_callback, "INS: PC=0x%X, mcode=0x%X\n",PC,mcode);
1083#endif
fee8ec00 1084
fee8ec00 1085 if (!State.pc_changed)
052d9a54
SR
1086 {
1087 if (curr_ins_size == 0)
1088 {
1089 State.exception = SIG_CR16_EXIT; /* exit trap */
1090 break;
1091 }
1092 else
1093 SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */
1094 }
1095
fee8ec00 1096#if 0
052d9a54
SR
1097 /* Check for a breakpoint trap on this instruction. This
1098 overrides any pending branches or loops */
fee8ec00 1099 if (PSR_DB && PC == DBS)
052d9a54
SR
1100 {
1101 SET_BPC (PC);
1102 SET_BPSR (PSR);
1103 SET_PC (SDBT_VECTOR_START);
1104 }
fee8ec00
SR
1105#endif
1106
1107 /* Writeback all the DATA / PC changes */
1108 SLOT_FLUSH ();
fee8ec00
SR
1109 }
1110 while ( !State.exception && !stop_simulator);
1111
1112 if (step && !State.exception)
1113 State.exception = SIGTRAP;
1114}
1115
fee8ec00
SR
1116SIM_RC
1117sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
1118{
1119 bfd_vma start_address;
1120
1121 /* reset all state information */
5aedb83b 1122 memset (&State.regs, 0, (uintptr_t)&State.mem - (uintptr_t)&State.regs);
fee8ec00
SR
1123
1124 /* There was a hack here to copy the values of argc and argv into r0
1125 and r1. The values were also saved into some high memory that
1126 won't be overwritten by the stack (0x7C00). The reason for doing
1127 this was to allow the 'run' program to accept arguments. Without
1128 the hack, this is not possible anymore. If the simulator is run
1129 from the debugger, arguments cannot be passed in, so this makes
1130 no difference. */
1131
1132 /* set PC */
1133 if (abfd != NULL)
1134 start_address = bfd_get_start_address (abfd);
1135 else
1136 start_address = 0x0;
1137#ifdef DEBUG
1138 if (cr16_debug)
1139 (*cr16_callback->printf_filtered) (cr16_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
1140#endif
1141 SET_CREG (PC_CR, start_address);
1142
1143 SLOT_FLUSH ();
1144 return SIM_RC_OK;
1145}
1146
fee8ec00 1147void
5aedb83b 1148sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
fee8ec00
SR
1149{
1150/* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
1151
1152 switch (State.exception)
1153 {
052d9a54 1154 case SIG_CR16_STOP: /* stop instruction */
fee8ec00
SR
1155 *reason = sim_stopped;
1156 *sigrc = 0;
1157 break;
1158
052d9a54 1159 case SIG_CR16_EXIT: /* exit trap */
fee8ec00
SR
1160 *reason = sim_exited;
1161 *sigrc = GPR (2);
1162 break;
1163
1164 case SIG_CR16_BUS:
1165 *reason = sim_stopped;
a493e3e2 1166 *sigrc = GDB_SIGNAL_BUS;
fee8ec00
SR
1167 break;
1168//
1169// case SIG_CR16_IAD:
1170// *reason = sim_stopped;
a493e3e2 1171// *sigrc = GDB_SIGNAL_IAD;
fee8ec00
SR
1172// break;
1173
052d9a54 1174 default: /* some signal */
fee8ec00
SR
1175 *reason = sim_stopped;
1176 if (stop_simulator && !State.exception)
a493e3e2 1177 *sigrc = GDB_SIGNAL_INT;
fee8ec00 1178 else
052d9a54 1179 *sigrc = State.exception;
fee8ec00
SR
1180 break;
1181 }
1182
1183 stop_simulator = 0;
1184}
1185
c2270cd8
MF
1186static uint32
1187cr16_extract_unsigned_integer (unsigned char *addr, int len)
1188{
1189 uint32 retval;
1190 unsigned char * p;
1191 unsigned char * startaddr = (unsigned char *)addr;
1192 unsigned char * endaddr = startaddr + len;
1193
1194 retval = 0;
1195
1196 for (p = endaddr; p > startaddr;)
1197 retval = (retval << 8) | *--p;
1198
1199 return retval;
1200}
1201
1202static void
1203cr16_store_unsigned_integer (unsigned char *addr, int len, uint32 val)
1204{
1205 unsigned char *p;
1206 unsigned char *startaddr = addr;
1207 unsigned char *endaddr = startaddr + len;
1208
1209 for (p = startaddr; p < endaddr;)
1210 {
1211 *p++ = val & 0xff;
1212 val >>= 8;
1213 }
1214}
1215
1216static int
1217cr16_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
fee8ec00
SR
1218{
1219 int size;
1220 switch ((enum sim_cr16_regs) rn)
1221 {
1222 case SIM_CR16_R0_REGNUM:
1223 case SIM_CR16_R1_REGNUM:
1224 case SIM_CR16_R2_REGNUM:
1225 case SIM_CR16_R3_REGNUM:
1226 case SIM_CR16_R4_REGNUM:
1227 case SIM_CR16_R5_REGNUM:
1228 case SIM_CR16_R6_REGNUM:
1229 case SIM_CR16_R7_REGNUM:
1230 case SIM_CR16_R8_REGNUM:
1231 case SIM_CR16_R9_REGNUM:
1232 case SIM_CR16_R10_REGNUM:
1233 case SIM_CR16_R11_REGNUM:
c2270cd8 1234 cr16_store_unsigned_integer (memory, 2, GPR (rn - SIM_CR16_R0_REGNUM));
fee8ec00
SR
1235 size = 2;
1236 break;
1237 case SIM_CR16_R12_REGNUM:
1238 case SIM_CR16_R13_REGNUM:
1239 case SIM_CR16_R14_REGNUM:
1240 case SIM_CR16_R15_REGNUM:
c2270cd8 1241 cr16_store_unsigned_integer (memory, 4, GPR (rn - SIM_CR16_R0_REGNUM));
fee8ec00
SR
1242 size = 4;
1243 break;
1244 case SIM_CR16_PC_REGNUM:
1245 case SIM_CR16_ISP_REGNUM:
1246 case SIM_CR16_USP_REGNUM:
1247 case SIM_CR16_INTBASE_REGNUM:
1248 case SIM_CR16_PSR_REGNUM:
1249 case SIM_CR16_CFG_REGNUM:
1250 case SIM_CR16_DBS_REGNUM:
1251 case SIM_CR16_DCR_REGNUM:
1252 case SIM_CR16_DSR_REGNUM:
1253 case SIM_CR16_CAR0_REGNUM:
1254 case SIM_CR16_CAR1_REGNUM:
c2270cd8 1255 cr16_store_unsigned_integer (memory, 4, CREG (rn - SIM_CR16_PC_REGNUM));
fee8ec00
SR
1256 size = 4;
1257 break;
1258 default:
1259 size = 0;
1260 break;
1261 }
1262 return size;
1263}
c2270cd8
MF
1264
1265static int
1266cr16_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
fee8ec00
SR
1267{
1268 int size;
1269 switch ((enum sim_cr16_regs) rn)
1270 {
1271 case SIM_CR16_R0_REGNUM:
1272 case SIM_CR16_R1_REGNUM:
1273 case SIM_CR16_R2_REGNUM:
1274 case SIM_CR16_R3_REGNUM:
1275 case SIM_CR16_R4_REGNUM:
1276 case SIM_CR16_R5_REGNUM:
1277 case SIM_CR16_R6_REGNUM:
1278 case SIM_CR16_R7_REGNUM:
1279 case SIM_CR16_R8_REGNUM:
1280 case SIM_CR16_R9_REGNUM:
1281 case SIM_CR16_R10_REGNUM:
1282 case SIM_CR16_R11_REGNUM:
c2270cd8 1283 SET_GPR (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
fee8ec00
SR
1284 size = 2;
1285 break;
1286 case SIM_CR16_R12_REGNUM:
1287 case SIM_CR16_R13_REGNUM:
1288 case SIM_CR16_R14_REGNUM:
1289 case SIM_CR16_R15_REGNUM:
c2270cd8 1290 SET_GPR32 (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2));
fee8ec00
SR
1291 size = 4;
1292 break;
1293 case SIM_CR16_PC_REGNUM:
1294 case SIM_CR16_ISP_REGNUM:
1295 case SIM_CR16_USP_REGNUM:
1296 case SIM_CR16_INTBASE_REGNUM:
1297 case SIM_CR16_PSR_REGNUM:
1298 case SIM_CR16_CFG_REGNUM:
1299 case SIM_CR16_DBS_REGNUM:
1300 case SIM_CR16_DCR_REGNUM:
1301 case SIM_CR16_DSR_REGNUM:
1302 case SIM_CR16_CAR0_REGNUM:
1303 case SIM_CR16_CAR1_REGNUM:
c2270cd8 1304 SET_CREG (rn - SIM_CR16_PC_REGNUM, cr16_extract_unsigned_integer (memory, 4));
fee8ec00
SR
1305 size = 4;
1306 break;
1307 default:
1308 size = 0;
1309 break;
1310 }
1311 SLOT_FLUSH ();
1312 return size;
1313}
This page took 0.450066 seconds and 4 git commands to generate.