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