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