sim: overhaul alignment settings management
[deliverable/binutils-gdb.git] / sim / d10v / interp.c
CommitLineData
6df01ab8
MF
1/* This must come before any other includes. */
2#include "defs.h"
3
11558abc 4#include <inttypes.h>
c906108c 5#include <signal.h>
c906108c 6#include "bfd.h"
df68e12b
MF
7#include "sim/callback.h"
8#include "sim/sim.h"
c906108c 9
541ebcee
MF
10#include "sim-main.h"
11#include "sim-options.h"
12
b91b96f4 13#include "gdb/sim-d10v.h"
aba6488e 14#include "gdb/signals.h"
c906108c 15
d0a5a356 16#include <string.h>
d0a5a356 17#include <stdlib.h>
e7e40ced 18#include <assert.h>
d0a5a356 19
c906108c
SS
20enum _leftright { LEFT_FIRST, RIGHT_FIRST };
21
7eb99e5e
MF
22struct _state State;
23
c906108c 24int d10v_debug;
cff3e48b
JM
25
26/* Set this to true to get the previous segment layout. */
27
28int old_segment_mapping;
29
c906108c
SS
30unsigned long ins_type_counters[ (int)INS_MAX ];
31
32uint16 OP[4];
33
bdca5ee4 34static long hash (long insn, int format);
67954606 35static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint32 ins, int size);
bdca5ee4 36static void get_operands (struct simops *s, uint32 ins);
67954606
MF
37static void do_long (SIM_DESC, SIM_CPU *, uint32 ins);
38static void do_2_short (SIM_DESC, SIM_CPU *, uint16 ins1, uint16 ins2, enum _leftright leftright);
39static void do_parallel (SIM_DESC, SIM_CPU *, uint16 ins1, uint16 ins2);
bdca5ee4 40static char *add_commas (char *buf, int sizeof_buf, unsigned long value);
67954606 41static INLINE uint8 *map_memory (SIM_DESC, SIM_CPU *, unsigned phys_addr);
c906108c 42
c906108c
SS
43#define MAX_HASH 63
44struct hash_entry
45{
46 struct hash_entry *next;
47 uint32 opcode;
48 uint32 mask;
49 int size;
50 struct simops *ops;
51};
52
53struct hash_entry hash_table[MAX_HASH+1];
54
55INLINE static long
11558abc 56hash (long insn, int format)
c906108c
SS
57{
58 if (format & LONG_OPCODE)
59 return ((insn & 0x3F000000) >> 24);
60 else
61 return((insn & 0x7E00) >> 9);
62}
63
64INLINE static struct hash_entry *
67954606 65lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint32 ins, int size)
c906108c
SS
66{
67 struct hash_entry *h;
68
69 if (size)
70 h = &hash_table[(ins & 0x3F000000) >> 24];
71 else
72 h = &hash_table[(ins & 0x7E00) >> 9];
73
74 while ((ins & h->mask) != h->opcode || h->size != size)
75 {
76 if (h->next == NULL)
aadc1740 77 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL);
c906108c
SS
78 h = h->next;
79 }
80 return (h);
81}
82
83INLINE static void
84get_operands (struct simops *s, uint32 ins)
85{
86 int i, shift, bits, flags;
87 uint32 mask;
88 for (i=0; i < s->numops; i++)
89 {
90 shift = s->operands[3*i];
91 bits = s->operands[3*i+1];
92 flags = s->operands[3*i+2];
93 mask = 0x7FFFFFFF >> (31 - bits);
94 OP[i] = (ins >> shift) & mask;
95 }
96 /* FIXME: for tracing, update values that need to be updated each
97 instruction decode cycle */
98 State.trace.psw = PSW;
99}
100
c906108c 101static void
67954606 102do_long (SIM_DESC sd, SIM_CPU *cpu, uint32 ins)
c906108c
SS
103{
104 struct hash_entry *h;
105#ifdef DEBUG
106 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
e9b0081f 107 sim_io_printf (sd, "do_long 0x%x\n", ins);
c906108c 108#endif
67954606 109 h = lookup_hash (sd, cpu, ins, 1);
4ce44c66
JM
110 if (h == NULL)
111 return;
c906108c
SS
112 get_operands (h->ops, ins);
113 State.ins_type = INS_LONG;
114 ins_type_counters[ (int)State.ins_type ]++;
67954606 115 (h->ops->func) (sd, cpu);
c906108c
SS
116}
117
118static void
67954606 119do_2_short (SIM_DESC sd, SIM_CPU *cpu, uint16 ins1, uint16 ins2, enum _leftright leftright)
c906108c
SS
120{
121 struct hash_entry *h;
122 enum _ins_type first, second;
123
124#ifdef DEBUG
125 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
e9b0081f
MF
126 sim_io_printf (sd, "do_2_short 0x%x (%s) -> 0x%x\n", ins1,
127 leftright ? "left" : "right", ins2);
c906108c
SS
128#endif
129
130 if (leftright == LEFT_FIRST)
131 {
132 first = INS_LEFT;
133 second = INS_RIGHT;
134 ins_type_counters[ (int)INS_LEFTRIGHT ]++;
135 }
136 else
137 {
138 first = INS_RIGHT;
139 second = INS_LEFT;
140 ins_type_counters[ (int)INS_RIGHTLEFT ]++;
141 }
142
143 /* Issue the first instruction */
67954606 144 h = lookup_hash (sd, cpu, ins1, 0);
4ce44c66
JM
145 if (h == NULL)
146 return;
c906108c
SS
147 get_operands (h->ops, ins1);
148 State.ins_type = first;
149 ins_type_counters[ (int)State.ins_type ]++;
67954606 150 (h->ops->func) (sd, cpu);
c906108c
SS
151
152 /* Issue the second instruction (if the PC hasn't changed) */
aadc1740 153 if (!State.pc_changed)
c906108c
SS
154 {
155 /* finish any existing instructions */
156 SLOT_FLUSH ();
67954606 157 h = lookup_hash (sd, cpu, ins2, 0);
4ce44c66
JM
158 if (h == NULL)
159 return;
c906108c
SS
160 get_operands (h->ops, ins2);
161 State.ins_type = second;
162 ins_type_counters[ (int)State.ins_type ]++;
163 ins_type_counters[ (int)INS_CYCLES ]++;
67954606 164 (h->ops->func) (sd, cpu);
c906108c 165 }
aadc1740 166 else
c906108c
SS
167 ins_type_counters[ (int)INS_COND_JUMP ]++;
168}
169
170static void
67954606 171do_parallel (SIM_DESC sd, SIM_CPU *cpu, uint16 ins1, uint16 ins2)
c906108c
SS
172{
173 struct hash_entry *h1, *h2;
174#ifdef DEBUG
175 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
e9b0081f 176 sim_io_printf (sd, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
c906108c
SS
177#endif
178 ins_type_counters[ (int)INS_PARALLEL ]++;
67954606 179 h1 = lookup_hash (sd, cpu, ins1, 0);
4ce44c66
JM
180 if (h1 == NULL)
181 return;
67954606 182 h2 = lookup_hash (sd, cpu, ins2, 0);
4ce44c66
JM
183 if (h2 == NULL)
184 return;
c906108c
SS
185
186 if (h1->ops->exec_type == PARONLY)
187 {
188 get_operands (h1->ops, ins1);
189 State.ins_type = INS_LEFT_COND_TEST;
190 ins_type_counters[ (int)State.ins_type ]++;
67954606 191 (h1->ops->func) (sd, cpu);
c906108c
SS
192 if (State.exe)
193 {
194 ins_type_counters[ (int)INS_COND_TRUE ]++;
195 get_operands (h2->ops, ins2);
196 State.ins_type = INS_RIGHT_COND_EXE;
197 ins_type_counters[ (int)State.ins_type ]++;
67954606 198 (h2->ops->func) (sd, cpu);
c906108c
SS
199 }
200 else
201 ins_type_counters[ (int)INS_COND_FALSE ]++;
202 }
203 else if (h2->ops->exec_type == PARONLY)
204 {
205 get_operands (h2->ops, ins2);
206 State.ins_type = INS_RIGHT_COND_TEST;
207 ins_type_counters[ (int)State.ins_type ]++;
67954606 208 (h2->ops->func) (sd, cpu);
c906108c
SS
209 if (State.exe)
210 {
211 ins_type_counters[ (int)INS_COND_TRUE ]++;
212 get_operands (h1->ops, ins1);
213 State.ins_type = INS_LEFT_COND_EXE;
214 ins_type_counters[ (int)State.ins_type ]++;
67954606 215 (h1->ops->func) (sd, cpu);
c906108c
SS
216 }
217 else
218 ins_type_counters[ (int)INS_COND_FALSE ]++;
219 }
220 else
221 {
222 get_operands (h1->ops, ins1);
223 State.ins_type = INS_LEFT_PARALLEL;
224 ins_type_counters[ (int)State.ins_type ]++;
67954606 225 (h1->ops->func) (sd, cpu);
aadc1740
MF
226 get_operands (h2->ops, ins2);
227 State.ins_type = INS_RIGHT_PARALLEL;
228 ins_type_counters[ (int)State.ins_type ]++;
229 (h2->ops->func) (sd, cpu);
c906108c
SS
230 }
231}
232
233static char *
11558abc 234add_commas (char *buf, int sizeof_buf, unsigned long value)
c906108c
SS
235{
236 int comma = 3;
237 char *endbuf = buf + sizeof_buf - 1;
238
239 *--endbuf = '\0';
240 do {
241 if (comma-- == 0)
242 {
243 *--endbuf = ',';
244 comma = 2;
245 }
246
247 *--endbuf = (value % 10) + '0';
248 } while ((value /= 10) != 0);
249
250 return endbuf;
251}
252
aadc1740 253static void
11558abc 254sim_size (int power)
c906108c
SS
255{
256 int i;
4ce44c66 257 for (i = 0; i < IMEM_SEGMENTS; i++)
c906108c 258 {
4ce44c66
JM
259 if (State.mem.insn[i])
260 free (State.mem.insn[i]);
c906108c 261 }
4ce44c66 262 for (i = 0; i < DMEM_SEGMENTS; i++)
c906108c 263 {
4ce44c66
JM
264 if (State.mem.data[i])
265 free (State.mem.data[i]);
c906108c 266 }
4ce44c66
JM
267 for (i = 0; i < UMEM_SEGMENTS; i++)
268 {
269 if (State.mem.unif[i])
270 free (State.mem.unif[i]);
271 }
272 /* Always allocate dmem segment 0. This contains the IMAP and DMAP
273 registers. */
274 State.mem.data[0] = calloc (1, SEGMENT_SIZE);
275}
276
277/* For tracing - leave info on last access around. */
278static char *last_segname = "invalid";
279static char *last_from = "invalid";
280static char *last_to = "invalid";
281
282enum
283 {
284 IMAP0_OFFSET = 0xff00,
285 DMAP0_OFFSET = 0xff08,
286 DMAP2_SHADDOW = 0xff04,
287 DMAP2_OFFSET = 0xff0c
288 };
289
290static void
67954606 291set_dmap_register (SIM_DESC sd, int reg_nr, unsigned long value)
4ce44c66 292{
67954606 293 uint8 *raw = map_memory (sd, NULL, SIM_D10V_MEMORY_DATA
4ce44c66
JM
294 + DMAP0_OFFSET + 2 * reg_nr);
295 WRITE_16 (raw, value);
c906108c 296#ifdef DEBUG
4ce44c66 297 if ((d10v_debug & DEBUG_MEMORY))
c906108c 298 {
e9b0081f 299 sim_io_printf (sd, "mem: dmap%d=0x%04lx\n", reg_nr, value);
4ce44c66
JM
300 }
301#endif
302}
c906108c 303
4ce44c66 304static unsigned long
67954606 305dmap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
4ce44c66 306{
67954606 307 uint8 *raw = map_memory (sd, cpu, SIM_D10V_MEMORY_DATA
4ce44c66
JM
308 + DMAP0_OFFSET + 2 * reg_nr);
309 return READ_16 (raw);
310}
311
312static void
67954606 313set_imap_register (SIM_DESC sd, int reg_nr, unsigned long value)
4ce44c66 314{
67954606 315 uint8 *raw = map_memory (sd, NULL, SIM_D10V_MEMORY_DATA
4ce44c66
JM
316 + IMAP0_OFFSET + 2 * reg_nr);
317 WRITE_16 (raw, value);
318#ifdef DEBUG
319 if ((d10v_debug & DEBUG_MEMORY))
320 {
e9b0081f 321 sim_io_printf (sd, "mem: imap%d=0x%04lx\n", reg_nr, value);
c906108c
SS
322 }
323#endif
324}
325
4ce44c66 326static unsigned long
67954606 327imap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
4ce44c66 328{
67954606 329 uint8 *raw = map_memory (sd, cpu, SIM_D10V_MEMORY_DATA
4ce44c66
JM
330 + IMAP0_OFFSET + 2 * reg_nr);
331 return READ_16 (raw);
332}
c906108c 333
4ce44c66
JM
334enum
335 {
336 HELD_SPI_IDX = 0,
337 HELD_SPU_IDX = 1
338 };
339
340static unsigned long
341spu_register (void)
c906108c 342{
4ce44c66
JM
343 if (PSW_SM)
344 return GPR (SP_IDX);
345 else
346 return HELD_SP (HELD_SPU_IDX);
347}
c906108c 348
4ce44c66
JM
349static unsigned long
350spi_register (void)
351{
352 if (!PSW_SM)
353 return GPR (SP_IDX);
354 else
355 return HELD_SP (HELD_SPI_IDX);
356}
357
358static void
359set_spi_register (unsigned long value)
360{
361 if (!PSW_SM)
362 SET_GPR (SP_IDX, value);
363 SET_HELD_SP (HELD_SPI_IDX, value);
364}
365
366static void
367set_spu_register (unsigned long value)
368{
369 if (PSW_SM)
370 SET_GPR (SP_IDX, value);
371 SET_HELD_SP (HELD_SPU_IDX, value);
372}
373
374/* Given a virtual address in the DMAP address space, translate it
375 into a physical address. */
376
6637a426 377static unsigned long
67954606
MF
378sim_d10v_translate_dmap_addr (SIM_DESC sd,
379 SIM_CPU *cpu,
380 unsigned long offset,
4ce44c66
JM
381 int nr_bytes,
382 unsigned long *phys,
f6684c31 383 void *regcache,
67954606
MF
384 unsigned long (*dmap_register) (SIM_DESC,
385 SIM_CPU *,
386 void *regcache,
f6684c31 387 int reg_nr))
4ce44c66
JM
388{
389 short map;
390 int regno;
391 last_from = "logical-data";
392 if (offset >= DMAP_BLOCK_SIZE * SIM_D10V_NR_DMAP_REGS)
c906108c 393 {
4ce44c66
JM
394 /* Logical address out side of data segments, not supported */
395 return 0;
396 }
397 regno = (offset / DMAP_BLOCK_SIZE);
398 offset = (offset % DMAP_BLOCK_SIZE);
399 if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
400 {
401 /* Don't cross a BLOCK boundary */
402 nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
403 }
67954606 404 map = dmap_register (sd, cpu, regcache, regno);
4ce44c66
JM
405 if (regno == 3)
406 {
407 /* Always maps to data memory */
408 int iospi = (offset / 0x1000) % 4;
409 int iosp = (map >> (4 * (3 - iospi))) % 0x10;
410 last_to = "io-space";
411 *phys = (SIM_D10V_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);
412 }
413 else
414 {
415 int sp = ((map & 0x3000) >> 12);
416 int segno = (map & 0x3ff);
417 switch (sp)
c906108c 418 {
4ce44c66
JM
419 case 0: /* 00: Unified memory */
420 *phys = SIM_D10V_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
421 last_to = "unified";
422 break;
423 case 1: /* 01: Instruction Memory */
424 *phys = SIM_D10V_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
425 last_to = "chip-insn";
426 break;
427 case 2: /* 10: Internal data memory */
428 *phys = SIM_D10V_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;
429 last_to = "chip-data";
430 break;
431 case 3: /* 11: Reserved */
432 return 0;
c906108c
SS
433 }
434 }
4ce44c66
JM
435 return nr_bytes;
436}
c906108c 437
4ce44c66
JM
438/* Given a virtual address in the IMAP address space, translate it
439 into a physical address. */
cff3e48b 440
6637a426 441static unsigned long
67954606
MF
442sim_d10v_translate_imap_addr (SIM_DESC sd,
443 SIM_CPU *cpu,
444 unsigned long offset,
4ce44c66
JM
445 int nr_bytes,
446 unsigned long *phys,
f6684c31 447 void *regcache,
67954606
MF
448 unsigned long (*imap_register) (SIM_DESC,
449 SIM_CPU *,
450 void *regcache,
f6684c31 451 int reg_nr))
4ce44c66
JM
452{
453 short map;
454 int regno;
455 int sp;
456 int segno;
457 last_from = "logical-insn";
458 if (offset >= (IMAP_BLOCK_SIZE * SIM_D10V_NR_IMAP_REGS))
459 {
460 /* Logical address outside of IMAP segments, not supported */
461 return 0;
462 }
463 regno = (offset / IMAP_BLOCK_SIZE);
464 offset = (offset % IMAP_BLOCK_SIZE);
465 if (offset + nr_bytes > IMAP_BLOCK_SIZE)
466 {
467 /* Don't cross a BLOCK boundary */
468 nr_bytes = IMAP_BLOCK_SIZE - offset;
469 }
67954606 470 map = imap_register (sd, cpu, regcache, regno);
4ce44c66
JM
471 sp = (map & 0x3000) >> 12;
472 segno = (map & 0x007f);
473 switch (sp)
474 {
475 case 0: /* 00: unified memory */
476 *phys = SIM_D10V_MEMORY_UNIFIED + (segno << 17) + offset;
477 last_to = "unified";
478 break;
479 case 1: /* 01: instruction memory */
480 *phys = SIM_D10V_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
481 last_to = "chip-insn";
482 break;
483 case 2: /*10*/
484 /* Reserved. */
485 return 0;
486 case 3: /* 11: for testing - instruction memory */
487 offset = (offset % 0x800);
488 *phys = SIM_D10V_MEMORY_INSN + offset;
489 if (offset + nr_bytes > 0x800)
490 /* don't cross VM boundary */
491 nr_bytes = 0x800 - offset;
492 last_to = "test-insn";
493 break;
494 }
495 return nr_bytes;
496}
cff3e48b 497
6637a426 498static unsigned long
67954606
MF
499sim_d10v_translate_addr (SIM_DESC sd,
500 SIM_CPU *cpu,
501 unsigned long memaddr,
4ce44c66
JM
502 int nr_bytes,
503 unsigned long *targ_addr,
f6684c31 504 void *regcache,
67954606
MF
505 unsigned long (*dmap_register) (SIM_DESC,
506 SIM_CPU *,
507 void *regcache,
f6684c31 508 int reg_nr),
67954606
MF
509 unsigned long (*imap_register) (SIM_DESC,
510 SIM_CPU *,
511 void *regcache,
f6684c31 512 int reg_nr))
4ce44c66
JM
513{
514 unsigned long phys;
515 unsigned long seg;
516 unsigned long off;
cff3e48b 517
4ce44c66
JM
518 last_from = "unknown";
519 last_to = "unknown";
cff3e48b 520
4ce44c66
JM
521 seg = (memaddr >> 24);
522 off = (memaddr & 0xffffffL);
c906108c 523
cff3e48b
JM
524 /* However, if we've asked to use the previous generation of segment
525 mapping, rearrange the segments as follows. */
526
527 if (old_segment_mapping)
528 {
4ce44c66 529 switch (seg)
cff3e48b
JM
530 {
531 case 0x00: /* DMAP translated memory */
4ce44c66 532 seg = 0x10;
cff3e48b
JM
533 break;
534 case 0x01: /* IMAP translated memory */
4ce44c66 535 seg = 0x11;
cff3e48b
JM
536 break;
537 case 0x10: /* On-chip data memory */
4ce44c66 538 seg = 0x02;
cff3e48b
JM
539 break;
540 case 0x11: /* On-chip insn memory */
4ce44c66 541 seg = 0x01;
cff3e48b
JM
542 break;
543 case 0x12: /* Unified memory */
4ce44c66 544 seg = 0x00;
cff3e48b
JM
545 break;
546 }
547 }
548
4ce44c66 549 switch (seg)
c906108c 550 {
4ce44c66
JM
551 case 0x00: /* Physical unified memory */
552 last_from = "phys-unified";
553 last_to = "unified";
554 phys = SIM_D10V_MEMORY_UNIFIED + off;
555 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
556 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
557 break;
c906108c 558
4ce44c66
JM
559 case 0x01: /* Physical instruction memory */
560 last_from = "phys-insn";
561 last_to = "chip-insn";
562 phys = SIM_D10V_MEMORY_INSN + off;
563 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
564 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
565 break;
c906108c 566
4ce44c66
JM
567 case 0x02: /* Physical data memory segment */
568 last_from = "phys-data";
569 last_to = "chip-data";
570 phys = SIM_D10V_MEMORY_DATA + off;
571 if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
572 nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
573 break;
574
575 case 0x10: /* in logical data address segment */
67954606
MF
576 nr_bytes = sim_d10v_translate_dmap_addr (sd, cpu, off, nr_bytes, &phys,
577 regcache, dmap_register);
4ce44c66
JM
578 break;
579
580 case 0x11: /* in logical instruction address segment */
67954606
MF
581 nr_bytes = sim_d10v_translate_imap_addr (sd, cpu, off, nr_bytes, &phys,
582 regcache, imap_register);
4ce44c66
JM
583 break;
584
585 default:
586 return 0;
587 }
588
589 *targ_addr = phys;
590 return nr_bytes;
591}
592
593/* Return a pointer into the raw buffer designated by phys_addr. It
594 is assumed that the client has already ensured that the access
595 isn't going to cross a segment boundary. */
596
597uint8 *
67954606 598map_memory (SIM_DESC sd, SIM_CPU *cpu, unsigned phys_addr)
4ce44c66
JM
599{
600 uint8 **memory;
601 uint8 *raw;
602 unsigned offset;
603 int segment = ((phys_addr >> 24) & 0xff);
604
605 switch (segment)
606 {
607
608 case 0x00: /* Unified memory */
c906108c 609 {
4ce44c66
JM
610 memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
611 last_segname = "umem";
c906108c
SS
612 break;
613 }
4ce44c66 614
cff3e48b 615 case 0x01: /* On-chip insn memory */
c906108c 616 {
4ce44c66
JM
617 memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
618 last_segname = "imem";
c906108c
SS
619 break;
620 }
4ce44c66
JM
621
622 case 0x02: /* On-chip data memory */
c906108c 623 {
4ce44c66 624 if ((phys_addr & 0xff00) == 0xff00)
c906108c 625 {
4ce44c66
JM
626 phys_addr = (phys_addr & 0xffff);
627 if (phys_addr == DMAP2_SHADDOW)
c906108c 628 {
4ce44c66
JM
629 phys_addr = DMAP2_OFFSET;
630 last_segname = "dmap";
c906108c 631 }
4ce44c66
JM
632 else
633 last_segname = "reg";
c906108c 634 }
4ce44c66
JM
635 else
636 last_segname = "dmem";
637 memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
c906108c
SS
638 break;
639 }
4ce44c66 640
c906108c 641 default:
4ce44c66
JM
642 /* OOPS! */
643 last_segname = "scrap";
aadc1740 644 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
c906108c 645 }
4ce44c66
JM
646
647 if (*memory == NULL)
aadc1740 648 *memory = xcalloc (1, SEGMENT_SIZE);
4ce44c66
JM
649
650 offset = (phys_addr % SEGMENT_SIZE);
651 raw = *memory + offset;
652 return raw;
653}
654
655/* Transfer data to/from simulated memory. Since a bug in either the
656 simulated program or in gdb or the simulator itself may cause a
657 bogus address to be passed in, we need to do some sanity checking
658 on addresses to make sure they are within bounds. When an address
659 fails the bounds check, treat it as a zero length read/write rather
660 than aborting the entire run. */
661
662static int
67954606
MF
663xfer_mem (SIM_DESC sd,
664 SIM_ADDR virt,
4ce44c66
JM
665 unsigned char *buffer,
666 int size,
667 int write_p)
668{
ea086965
AC
669 uint8 *memory;
670 unsigned long phys;
671 int phys_size;
67954606 672 phys_size = sim_d10v_translate_addr (sd, NULL, virt, size, &phys, NULL,
ea086965
AC
673 dmap_register, imap_register);
674 if (phys_size == 0)
675 return 0;
4ce44c66 676
67954606 677 memory = map_memory (sd, NULL, phys);
4ce44c66
JM
678
679#ifdef DEBUG
ea086965
AC
680 if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
681 {
e9b0081f
MF
682 sim_io_printf
683 (sd,
d3b0ab8b 684 "sim_%s %d bytes: 0x%08" PRIxTA " (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
e9b0081f 685 write_p ? "write" : "read",
ea086965
AC
686 phys_size, virt, last_from,
687 phys, last_to,
688 (long) memory, last_segname);
689 }
4ce44c66
JM
690#endif
691
ea086965
AC
692 if (write_p)
693 {
694 memcpy (memory, buffer, phys_size);
c906108c 695 }
ea086965
AC
696 else
697 {
698 memcpy (buffer, memory, phys_size);
699 }
700
701 return phys_size;
c906108c
SS
702}
703
704
705int
11558abc 706sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
c906108c
SS
707{
708 /* FIXME: this should be performing a virtual transfer */
d3b0ab8b
MF
709 /* FIXME: We cast the const away, but it's safe because xfer_mem only reads
710 when write_p==1. This is still ugly. */
711 return xfer_mem (sd, addr, (void *) buffer, size, 1);
c906108c
SS
712}
713
714int
11558abc 715sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
c906108c
SS
716{
717 /* FIXME: this should be performing a virtual transfer */
67954606 718 return xfer_mem (sd, addr, buffer, size, 0);
c906108c
SS
719}
720
27b97b40
MF
721static sim_cia
722d10v_pc_get (sim_cpu *cpu)
723{
724 return PC;
725}
726
727static void
728d10v_pc_set (sim_cpu *cpu, sim_cia pc)
729{
67954606 730 SIM_DESC sd = CPU_STATE (cpu);
27b97b40
MF
731 SET_PC (pc);
732}
733
541ebcee
MF
734static void
735free_state (SIM_DESC sd)
736{
737 if (STATE_MODULES (sd) != NULL)
738 sim_module_uninstall (sd);
739 sim_cpu_free_all (sd);
740 sim_state_free (sd);
741}
742
e1211e55
MF
743static int d10v_reg_fetch (SIM_CPU *, int, unsigned char *, int);
744static int d10v_reg_store (SIM_CPU *, int, unsigned char *, int);
745
c906108c 746SIM_DESC
2e3d4f4d
MF
747sim_open (SIM_OPEN_KIND kind, host_callback *cb,
748 struct bfd *abfd, char * const *argv)
c906108c
SS
749{
750 struct simops *s;
751 struct hash_entry *h;
752 static int init_p = 0;
d3b0ab8b 753 char * const *p;
27b97b40 754 int i;
541ebcee
MF
755 SIM_DESC sd = sim_state_alloc (kind, cb);
756 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
c906108c 757
ba307cdd
MF
758 /* Set default options before parsing user options. */
759 current_alignment = STRICT_ALIGNMENT;
760
541ebcee 761 /* The cpu data is kept in a separately allocated chunk of memory. */
d5a71b11 762 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
541ebcee
MF
763 {
764 free_state (sd);
765 return 0;
766 }
767
768 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
769 {
770 free_state (sd);
771 return 0;
772 }
773
77cf2ef5 774 /* The parser will print an error message for us, so we silently return. */
541ebcee
MF
775 if (sim_parse_args (sd, argv) != SIM_RC_OK)
776 {
777 free_state (sd);
778 return 0;
779 }
780
781 /* Check for/establish the a reference program image. */
782 if (sim_analyze_program (sd,
783 (STATE_PROG_ARGV (sd) != NULL
784 ? *STATE_PROG_ARGV (sd)
785 : NULL), abfd) != SIM_RC_OK)
786 {
787 free_state (sd);
788 return 0;
789 }
790
791 /* Configure/verify the target byte order and other runtime
792 configuration options. */
793 if (sim_config (sd) != SIM_RC_OK)
794 {
795 sim_module_uninstall (sd);
796 return 0;
797 }
798
799 if (sim_post_argv_init (sd) != SIM_RC_OK)
800 {
801 /* Uninstall the modules to avoid memory leaks,
802 file descriptor leaks, etc. */
803 sim_module_uninstall (sd);
804 return 0;
805 }
806
27b97b40
MF
807 /* CPU specific initialization. */
808 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
809 {
810 SIM_CPU *cpu = STATE_CPU (sd, i);
811
e1211e55
MF
812 CPU_REG_FETCH (cpu) = d10v_reg_fetch;
813 CPU_REG_STORE (cpu) = d10v_reg_store;
27b97b40
MF
814 CPU_PC_FETCH (cpu) = d10v_pc_get;
815 CPU_PC_STORE (cpu) = d10v_pc_set;
816 }
817
cff3e48b 818 old_segment_mapping = 0;
c906108c 819
4ce44c66
JM
820 /* NOTE: This argument parsing is only effective when this function
821 is called by GDB. Standalone argument parsing is handled by
822 sim/common/run.c. */
c906108c
SS
823 for (p = argv + 1; *p; ++p)
824 {
cff3e48b
JM
825 if (strcmp (*p, "-oldseg") == 0)
826 old_segment_mapping = 1;
c906108c 827#ifdef DEBUG
cff3e48b 828 else if (strcmp (*p, "-t") == 0)
c906108c 829 d10v_debug = DEBUG;
4ce44c66
JM
830 else if (strncmp (*p, "-t", 2) == 0)
831 d10v_debug = atoi (*p + 2);
c906108c 832#endif
c906108c
SS
833 }
834
835 /* put all the opcodes in the hash table */
836 if (!init_p++)
837 {
838 for (s = Simops; s->func; s++)
839 {
840 h = &hash_table[hash(s->opcode,s->format)];
841
842 /* go to the last entry in the chain */
843 while (h->next)
844 h = h->next;
845
846 if (h->ops)
847 {
848 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
849 if (!h->next)
850 perror ("malloc failure");
851
852 h = h->next;
853 }
854 h->ops = s;
855 h->mask = s->mask;
856 h->opcode = s->opcode;
857 h->size = s->is_long;
858 }
859 }
860
861 /* reset the processor state */
4ce44c66
JM
862 if (!State.mem.data[0])
863 sim_size (1);
c906108c 864
541ebcee 865 return sd;
c906108c
SS
866}
867
c906108c 868uint8 *
67954606 869dmem_addr (SIM_DESC sd, SIM_CPU *cpu, uint16 offset)
c906108c 870{
4ce44c66
JM
871 unsigned long phys;
872 uint8 *mem;
873 int phys_size;
c906108c 874
4ce44c66
JM
875 /* Note: DMEM address range is 0..0x10000. Calling code can compute
876 things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
877 is uint16 this is modulo'ed onto 0x0e5d. */
c906108c 878
67954606 879 phys_size = sim_d10v_translate_dmap_addr (sd, cpu, offset, 1, &phys, NULL,
4ce44c66
JM
880 dmap_register);
881 if (phys_size == 0)
aadc1740
MF
882 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
883 mem = map_memory (sd, cpu, phys);
c906108c 884#ifdef DEBUG
4ce44c66
JM
885 if ((d10v_debug & DEBUG_MEMORY))
886 {
e9b0081f
MF
887 sim_io_printf
888 (sd,
4ce44c66
JM
889 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
890 offset, last_from,
891 phys, phys_size, last_to,
892 (long) mem, last_segname);
c906108c 893 }
4ce44c66
JM
894#endif
895 return mem;
c906108c
SS
896}
897
c906108c 898uint8 *
67954606 899imem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset)
c906108c 900{
4ce44c66
JM
901 unsigned long phys;
902 uint8 *mem;
67954606 903 int phys_size = sim_d10v_translate_imap_addr (sd, cpu, offset, 1, &phys, NULL,
f6684c31 904 imap_register);
4ce44c66 905 if (phys_size == 0)
aadc1740 906 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
67954606 907 mem = map_memory (sd, cpu, phys);
4ce44c66
JM
908#ifdef DEBUG
909 if ((d10v_debug & DEBUG_MEMORY))
910 {
e9b0081f
MF
911 sim_io_printf
912 (sd,
4ce44c66
JM
913 "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
914 offset, last_from,
915 phys, phys_size, last_to,
916 (long) mem, last_segname);
917 }
918#endif
919 return mem;
c906108c
SS
920}
921
aadc1740
MF
922static void
923step_once (SIM_DESC sd, SIM_CPU *cpu)
c906108c
SS
924{
925 uint32 inst;
926 uint8 *iaddr;
927
aadc1740 928 /* TODO: Unindent this block. */
c906108c 929 {
67954606 930 iaddr = imem_addr (sd, cpu, (uint32)PC << 2);
c906108c
SS
931
932 inst = get_longword( iaddr );
933
934 State.pc_changed = 0;
935 ins_type_counters[ (int)INS_CYCLES ]++;
936
937 switch (inst & 0xC0000000)
938 {
939 case 0xC0000000:
940 /* long instruction */
67954606 941 do_long (sd, cpu, inst & 0x3FFFFFFF);
c906108c
SS
942 break;
943 case 0x80000000:
944 /* R -> L */
67954606 945 do_2_short (sd, cpu, inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
c906108c
SS
946 break;
947 case 0x40000000:
948 /* L -> R */
67954606 949 do_2_short (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
c906108c
SS
950 break;
951 case 0:
67954606 952 do_parallel (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
c906108c
SS
953 break;
954 }
955
956 /* If the PC of the current instruction matches RPT_E then
957 schedule a branch to the loop start. If one of those
958 instructions happens to be a branch, than that instruction
959 will be ignored */
960 if (!State.pc_changed)
961 {
962 if (PSW_RP && PC == RPT_E)
963 {
964 /* Note: The behavour of a branch instruction at RPT_E
965 is implementation dependant, this simulator takes the
966 branch. Branching to RPT_E is valid, the instruction
967 must be executed before the loop is taken. */
968 if (RPT_C == 1)
969 {
970 SET_PSW_RP (0);
971 SET_RPT_C (0);
972 SET_PC (PC + 1);
973 }
974 else
975 {
976 SET_RPT_C (RPT_C - 1);
977 SET_PC (RPT_S);
978 }
979 }
980 else
981 SET_PC (PC + 1);
982 }
983
984 /* Check for a breakpoint trap on this instruction. This
985 overrides any pending branches or loops */
986 if (PSW_DB && PC == IBA)
987 {
988 SET_BPC (PC);
989 SET_BPSW (PSW);
990 SET_PSW (PSW & PSW_SM_BIT);
991 SET_PC (SDBT_VECTOR_START);
992 }
993
994 /* Writeback all the DATA / PC changes */
995 SLOT_FLUSH ();
c906108c 996 }
aadc1740
MF
997}
998
999void
1000sim_engine_run (SIM_DESC sd,
1001 int next_cpu_nr, /* ignore */
1002 int nr_cpus, /* ignore */
1003 int siggnal)
1004{
1005 sim_cpu *cpu;
1006
1007 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1008
1009 cpu = STATE_CPU (sd, 0);
1010
1011 switch (siggnal)
1012 {
1013 case 0:
1014 break;
1015 case GDB_SIGNAL_BUS:
1016 SET_BPC (PC);
1017 SET_BPSW (PSW);
1018 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
1019 JMP (AE_VECTOR_START);
1020 SLOT_FLUSH ();
1021 break;
1022 case GDB_SIGNAL_ILL:
1023 SET_BPC (PC);
1024 SET_BPSW (PSW);
1025 SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
1026 JMP (RIE_VECTOR_START);
1027 SLOT_FLUSH ();
1028 break;
1029 default:
1030 /* just ignore it */
1031 break;
1032 }
1033
1034 while (1)
1035 {
1036 step_once (sd, cpu);
1037 if (sim_events_tick (sd))
1038 sim_events_process (sd);
1039 }
c906108c
SS
1040}
1041
c906108c 1042void
11558abc 1043sim_info (SIM_DESC sd, int verbose)
c906108c
SS
1044{
1045 char buf1[40];
1046 char buf2[40];
1047 char buf3[40];
1048 char buf4[40];
1049 char buf5[40];
1050 unsigned long left = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1051 unsigned long left_nops = ins_type_counters[ (int)INS_LEFT_NOPS ];
1052 unsigned long left_parallel = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1053 unsigned long left_cond = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1054 unsigned long left_total = left + left_parallel + left_cond + left_nops;
1055
1056 unsigned long right = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1057 unsigned long right_nops = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1058 unsigned long right_parallel = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1059 unsigned long right_cond = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1060 unsigned long right_total = right + right_parallel + right_cond + right_nops;
1061
1062 unsigned long unknown = ins_type_counters[ (int)INS_UNKNOWN ];
1063 unsigned long ins_long = ins_type_counters[ (int)INS_LONG ];
1064 unsigned long parallel = ins_type_counters[ (int)INS_PARALLEL ];
1065 unsigned long leftright = ins_type_counters[ (int)INS_LEFTRIGHT ];
1066 unsigned long rightleft = ins_type_counters[ (int)INS_RIGHTLEFT ];
1067 unsigned long cond_true = ins_type_counters[ (int)INS_COND_TRUE ];
1068 unsigned long cond_false = ins_type_counters[ (int)INS_COND_FALSE ];
1069 unsigned long cond_jump = ins_type_counters[ (int)INS_COND_JUMP ];
1070 unsigned long cycles = ins_type_counters[ (int)INS_CYCLES ];
1071 unsigned long total = (unknown + left_total + right_total + ins_long);
1072
1073 int size = strlen (add_commas (buf1, sizeof (buf1), total));
1074 int parallel_size = strlen (add_commas (buf1, sizeof (buf1),
1075 (left_parallel > right_parallel) ? left_parallel : right_parallel));
1076 int cond_size = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1077 int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1078 int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
1079
e9b0081f
MF
1080 sim_io_printf (sd,
1081 "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1082 size, add_commas (buf1, sizeof (buf1), left_total),
1083 normal_size, add_commas (buf2, sizeof (buf2), left),
1084 parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1085 cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1086 nop_size, add_commas (buf5, sizeof (buf5), left_nops));
1087
1088 sim_io_printf (sd,
1089 "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1090 size, add_commas (buf1, sizeof (buf1), right_total),
1091 normal_size, add_commas (buf2, sizeof (buf2), right),
1092 parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1093 cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1094 nop_size, add_commas (buf5, sizeof (buf5), right_nops));
c906108c
SS
1095
1096 if (ins_long)
e9b0081f
MF
1097 sim_io_printf (sd,
1098 "executed %*s long instruction(s)\n",
1099 size, add_commas (buf1, sizeof (buf1), ins_long));
c906108c
SS
1100
1101 if (parallel)
e9b0081f
MF
1102 sim_io_printf (sd,
1103 "executed %*s parallel instruction(s)\n",
1104 size, add_commas (buf1, sizeof (buf1), parallel));
c906108c
SS
1105
1106 if (leftright)
e9b0081f
MF
1107 sim_io_printf (sd,
1108 "executed %*s instruction(s) encoded L->R\n",
1109 size, add_commas (buf1, sizeof (buf1), leftright));
c906108c
SS
1110
1111 if (rightleft)
e9b0081f
MF
1112 sim_io_printf (sd,
1113 "executed %*s instruction(s) encoded R->L\n",
1114 size, add_commas (buf1, sizeof (buf1), rightleft));
c906108c
SS
1115
1116 if (unknown)
e9b0081f
MF
1117 sim_io_printf (sd,
1118 "executed %*s unknown instruction(s)\n",
1119 size, add_commas (buf1, sizeof (buf1), unknown));
c906108c
SS
1120
1121 if (cond_true)
e9b0081f
MF
1122 sim_io_printf (sd,
1123 "executed %*s instruction(s) due to EXExxx condition being true\n",
1124 size, add_commas (buf1, sizeof (buf1), cond_true));
c906108c
SS
1125
1126 if (cond_false)
e9b0081f
MF
1127 sim_io_printf (sd,
1128 "skipped %*s instruction(s) due to EXExxx condition being false\n",
1129 size, add_commas (buf1, sizeof (buf1), cond_false));
c906108c
SS
1130
1131 if (cond_jump)
e9b0081f
MF
1132 sim_io_printf (sd,
1133 "skipped %*s instruction(s) due to conditional branch succeeding\n",
1134 size, add_commas (buf1, sizeof (buf1), cond_jump));
c906108c 1135
e9b0081f
MF
1136 sim_io_printf (sd,
1137 "executed %*s cycle(s)\n",
1138 size, add_commas (buf1, sizeof (buf1), cycles));
c906108c 1139
e9b0081f
MF
1140 sim_io_printf (sd,
1141 "executed %*s total instructions\n",
1142 size, add_commas (buf1, sizeof (buf1), total));
c906108c
SS
1143}
1144
1145SIM_RC
2e3d4f4d
MF
1146sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1147 char * const *argv, char * const *env)
c906108c
SS
1148{
1149 bfd_vma start_address;
1150
e7e40ced 1151 /* Make sure we have the right structure for the following memset. */
39549cae
JB
1152 static_assert (offsetof (struct _state, regs) == 0,
1153 "State.regs is not at offset 0");
e7e40ced
LM
1154
1155 /* Reset state from the regs field until the mem field. */
1156 memset (&State, 0, (uintptr_t) &State.mem - (uintptr_t) &State.regs);
c906108c 1157
1aa5e64f
EZ
1158 /* There was a hack here to copy the values of argc and argv into r0
1159 and r1. The values were also saved into some high memory that
1160 won't be overwritten by the stack (0x7C00). The reason for doing
1161 this was to allow the 'run' program to accept arguments. Without
1162 the hack, this is not possible anymore. If the simulator is run
1163 from the debugger, arguments cannot be passed in, so this makes
1164 no difference. */
1165
c906108c
SS
1166 /* set PC */
1167 if (abfd != NULL)
1168 start_address = bfd_get_start_address (abfd);
1169 else
1170 start_address = 0xffc0 << 2;
1171#ifdef DEBUG
1172 if (d10v_debug)
5ee0bc23
MF
1173 sim_io_printf (sd, "sim_create_inferior: PC=0x%" BFD_VMA_FMT "x\n",
1174 start_address);
c906108c 1175#endif
67954606
MF
1176 {
1177 SIM_CPU *cpu = STATE_CPU (sd, 0);
1178 SET_CREG (PC_CR, start_address >> 2);
1179 }
c906108c 1180
4ce44c66
JM
1181 /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
1182 initializes imap0 and imap1 to 0x1000 as part of its ROM
1183 initialization. */
cff3e48b 1184 if (old_segment_mapping)
c906108c 1185 {
4ce44c66 1186 /* External memory startup. This is the HARD reset state. */
67954606
MF
1187 set_imap_register (sd, 0, 0x0000);
1188 set_imap_register (sd, 1, 0x007f);
1189 set_dmap_register (sd, 0, 0x2000);
1190 set_dmap_register (sd, 1, 0x2000);
1191 set_dmap_register (sd, 2, 0x0000); /* Old DMAP */
1192 set_dmap_register (sd, 3, 0x0000);
c906108c
SS
1193 }
1194 else
1195 {
4ce44c66 1196 /* Internal memory startup. This is the ROM intialized state. */
67954606
MF
1197 set_imap_register (sd, 0, 0x1000);
1198 set_imap_register (sd, 1, 0x1000);
1199 set_dmap_register (sd, 0, 0x2000);
1200 set_dmap_register (sd, 1, 0x2000);
1201 set_dmap_register (sd, 2, 0x2000); /* DMAP2 initial internal value is
1202 0x2000 on the new board. */
1203 set_dmap_register (sd, 3, 0x0000);
c906108c
SS
1204 }
1205
1206 SLOT_FLUSH ();
1207 return SIM_RC_OK;
1208}
1209
e1211e55
MF
1210static int
1211d10v_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c 1212{
e1211e55 1213 SIM_DESC sd = CPU_STATE (cpu);
4ce44c66 1214 int size;
983b727e 1215 switch ((enum sim_d10v_regs) rn)
4ce44c66 1216 {
18c0df9e
AC
1217 case SIM_D10V_R0_REGNUM:
1218 case SIM_D10V_R1_REGNUM:
1219 case SIM_D10V_R2_REGNUM:
1220 case SIM_D10V_R3_REGNUM:
1221 case SIM_D10V_R4_REGNUM:
1222 case SIM_D10V_R5_REGNUM:
1223 case SIM_D10V_R6_REGNUM:
1224 case SIM_D10V_R7_REGNUM:
1225 case SIM_D10V_R8_REGNUM:
1226 case SIM_D10V_R9_REGNUM:
1227 case SIM_D10V_R10_REGNUM:
1228 case SIM_D10V_R11_REGNUM:
1229 case SIM_D10V_R12_REGNUM:
1230 case SIM_D10V_R13_REGNUM:
1231 case SIM_D10V_R14_REGNUM:
1232 case SIM_D10V_R15_REGNUM:
4ce44c66
JM
1233 WRITE_16 (memory, GPR (rn - SIM_D10V_R0_REGNUM));
1234 size = 2;
18c0df9e
AC
1235 break;
1236 case SIM_D10V_CR0_REGNUM:
1237 case SIM_D10V_CR1_REGNUM:
1238 case SIM_D10V_CR2_REGNUM:
1239 case SIM_D10V_CR3_REGNUM:
1240 case SIM_D10V_CR4_REGNUM:
1241 case SIM_D10V_CR5_REGNUM:
1242 case SIM_D10V_CR6_REGNUM:
1243 case SIM_D10V_CR7_REGNUM:
1244 case SIM_D10V_CR8_REGNUM:
1245 case SIM_D10V_CR9_REGNUM:
1246 case SIM_D10V_CR10_REGNUM:
1247 case SIM_D10V_CR11_REGNUM:
1248 case SIM_D10V_CR12_REGNUM:
1249 case SIM_D10V_CR13_REGNUM:
1250 case SIM_D10V_CR14_REGNUM:
1251 case SIM_D10V_CR15_REGNUM:
4ce44c66
JM
1252 WRITE_16 (memory, CREG (rn - SIM_D10V_CR0_REGNUM));
1253 size = 2;
18c0df9e
AC
1254 break;
1255 case SIM_D10V_A0_REGNUM:
1256 case SIM_D10V_A1_REGNUM:
4ce44c66
JM
1257 WRITE_64 (memory, ACC (rn - SIM_D10V_A0_REGNUM));
1258 size = 8;
18c0df9e
AC
1259 break;
1260 case SIM_D10V_SPI_REGNUM:
4ce44c66
JM
1261 /* PSW_SM indicates that the current SP is the USER
1262 stack-pointer. */
1263 WRITE_16 (memory, spi_register ());
1264 size = 2;
18c0df9e
AC
1265 break;
1266 case SIM_D10V_SPU_REGNUM:
4ce44c66
JM
1267 /* PSW_SM indicates that the current SP is the USER
1268 stack-pointer. */
1269 WRITE_16 (memory, spu_register ());
1270 size = 2;
18c0df9e
AC
1271 break;
1272 case SIM_D10V_IMAP0_REGNUM:
1273 case SIM_D10V_IMAP1_REGNUM:
67954606 1274 WRITE_16 (memory, imap_register (sd, cpu, NULL, rn - SIM_D10V_IMAP0_REGNUM));
4ce44c66 1275 size = 2;
18c0df9e
AC
1276 break;
1277 case SIM_D10V_DMAP0_REGNUM:
1278 case SIM_D10V_DMAP1_REGNUM:
1279 case SIM_D10V_DMAP2_REGNUM:
1280 case SIM_D10V_DMAP3_REGNUM:
67954606 1281 WRITE_16 (memory, dmap_register (sd, cpu, NULL, rn - SIM_D10V_DMAP0_REGNUM));
4ce44c66 1282 size = 2;
18c0df9e
AC
1283 break;
1284 case SIM_D10V_TS2_DMAP_REGNUM:
1285 size = 0;
1286 break;
1287 default:
1288 size = 0;
1289 break;
4ce44c66 1290 }
4ce44c66 1291 return size;
c906108c
SS
1292}
1293
e1211e55
MF
1294static int
1295d10v_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c 1296{
e1211e55 1297 SIM_DESC sd = CPU_STATE (cpu);
4ce44c66 1298 int size;
983b727e 1299 switch ((enum sim_d10v_regs) rn)
4ce44c66 1300 {
18c0df9e
AC
1301 case SIM_D10V_R0_REGNUM:
1302 case SIM_D10V_R1_REGNUM:
1303 case SIM_D10V_R2_REGNUM:
1304 case SIM_D10V_R3_REGNUM:
1305 case SIM_D10V_R4_REGNUM:
1306 case SIM_D10V_R5_REGNUM:
1307 case SIM_D10V_R6_REGNUM:
1308 case SIM_D10V_R7_REGNUM:
1309 case SIM_D10V_R8_REGNUM:
1310 case SIM_D10V_R9_REGNUM:
1311 case SIM_D10V_R10_REGNUM:
1312 case SIM_D10V_R11_REGNUM:
1313 case SIM_D10V_R12_REGNUM:
1314 case SIM_D10V_R13_REGNUM:
1315 case SIM_D10V_R14_REGNUM:
1316 case SIM_D10V_R15_REGNUM:
4ce44c66
JM
1317 SET_GPR (rn - SIM_D10V_R0_REGNUM, READ_16 (memory));
1318 size = 2;
18c0df9e
AC
1319 break;
1320 case SIM_D10V_CR0_REGNUM:
1321 case SIM_D10V_CR1_REGNUM:
1322 case SIM_D10V_CR2_REGNUM:
1323 case SIM_D10V_CR3_REGNUM:
1324 case SIM_D10V_CR4_REGNUM:
1325 case SIM_D10V_CR5_REGNUM:
1326 case SIM_D10V_CR6_REGNUM:
1327 case SIM_D10V_CR7_REGNUM:
1328 case SIM_D10V_CR8_REGNUM:
1329 case SIM_D10V_CR9_REGNUM:
1330 case SIM_D10V_CR10_REGNUM:
1331 case SIM_D10V_CR11_REGNUM:
1332 case SIM_D10V_CR12_REGNUM:
1333 case SIM_D10V_CR13_REGNUM:
1334 case SIM_D10V_CR14_REGNUM:
1335 case SIM_D10V_CR15_REGNUM:
4ce44c66
JM
1336 SET_CREG (rn - SIM_D10V_CR0_REGNUM, READ_16 (memory));
1337 size = 2;
18c0df9e
AC
1338 break;
1339 case SIM_D10V_A0_REGNUM:
1340 case SIM_D10V_A1_REGNUM:
4ce44c66
JM
1341 SET_ACC (rn - SIM_D10V_A0_REGNUM, READ_64 (memory) & MASK40);
1342 size = 8;
18c0df9e
AC
1343 break;
1344 case SIM_D10V_SPI_REGNUM:
4ce44c66
JM
1345 /* PSW_SM indicates that the current SP is the USER
1346 stack-pointer. */
1347 set_spi_register (READ_16 (memory));
1348 size = 2;
18c0df9e
AC
1349 break;
1350 case SIM_D10V_SPU_REGNUM:
4ce44c66
JM
1351 set_spu_register (READ_16 (memory));
1352 size = 2;
18c0df9e
AC
1353 break;
1354 case SIM_D10V_IMAP0_REGNUM:
1355 case SIM_D10V_IMAP1_REGNUM:
67954606 1356 set_imap_register (sd, rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory));
4ce44c66 1357 size = 2;
18c0df9e
AC
1358 break;
1359 case SIM_D10V_DMAP0_REGNUM:
1360 case SIM_D10V_DMAP1_REGNUM:
1361 case SIM_D10V_DMAP2_REGNUM:
1362 case SIM_D10V_DMAP3_REGNUM:
67954606 1363 set_dmap_register (sd, rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory));
4ce44c66 1364 size = 2;
18c0df9e
AC
1365 break;
1366 case SIM_D10V_TS2_DMAP_REGNUM:
1367 size = 0;
1368 break;
1369 default:
1370 size = 0;
1371 break;
4ce44c66 1372 }
c906108c 1373 SLOT_FLUSH ();
4ce44c66 1374 return size;
c906108c 1375}
This page took 1.080303 seconds and 4 git commands to generate.