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