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