Re-do load/store operations so that they work for both 32 and 64 bit
[deliverable/binutils-gdb.git] / sim / mips / interp.c
1 /*> interp.c <*/
2 /* Simulator for the MIPS architecture.
3
4 This file is part of the MIPS sim
5
6 THIS SOFTWARE IS NOT COPYRIGHTED
7
8 Cygnus offers the following for use in the public domain. Cygnus
9 makes no warranty with regard to the software or it's performance
10 and the user accepts the software "AS IS" with all faults.
11
12 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
13 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
16 $Revision$
17 $Date$
18
19 NOTEs:
20
21 The IDT monitor (found on the VR4300 board), seems to lie about
22 register contents. It seems to treat the registers as sign-extended
23 32-bit values. This cause *REAL* problems when single-stepping 64-bit
24 code on the hardware.
25
26 */
27
28 /* The TRACE manifests enable the provision of extra features. If they
29 are not defined then a simpler (quicker) simulator is constructed
30 without the required run-time checks, etc. */
31 #if 1 /* 0 to allow user build selection, 1 to force inclusion */
32 #define TRACE (1)
33 #endif
34
35 #include "bfd.h"
36 #include "sim-main.h"
37 #include "sim-utils.h"
38 #include "sim-options.h"
39 #include "sim-assert.h"
40
41 /* start-sanitize-sky */
42 #ifdef TARGET_SKY
43 #include "sky-vu.h"
44 #include "sky-vpe.h"
45 #include "sky-libvpe.h"
46 #endif
47 /* end-sanitize-sky */
48
49 #include "config.h"
50
51 #include <stdio.h>
52 #include <stdarg.h>
53 #include <ansidecl.h>
54 #include <ctype.h>
55 #include <limits.h>
56 #include <math.h>
57 #ifdef HAVE_STDLIB_H
58 #include <stdlib.h>
59 #endif
60 #ifdef HAVE_STRING_H
61 #include <string.h>
62 #else
63 #ifdef HAVE_STRINGS_H
64 #include <strings.h>
65 #endif
66 #endif
67
68 #include "getopt.h"
69 #include "libiberty.h"
70 #include "bfd.h"
71 #include "callback.h" /* GDB simulator callback interface */
72 #include "remote-sim.h" /* GDB simulator interface */
73
74 #include "sysdep.h"
75
76 #ifndef PARAMS
77 #define PARAMS(x)
78 #endif
79
80 char* pr_addr PARAMS ((SIM_ADDR addr));
81 char* pr_uword64 PARAMS ((uword64 addr));
82
83
84 /* Get the simulator engine description, without including the code: */
85 #if !(WITH_IGEN)
86 #define SIM_MANIFESTS
87 #include "oengine.c"
88 #undef SIM_MANIFESTS
89 #endif
90
91 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
92 #define SD sd
93 #define CPU cpu
94
95
96 /* The following reserved instruction value is used when a simulator
97 trap is required. NOTE: Care must be taken, since this value may be
98 used in later revisions of the MIPS ISA. */
99 #define RSVD_INSTRUCTION (0x00000005)
100 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
101
102 #define RSVD_INSTRUCTION_ARG_SHIFT 6
103 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
104
105
106 /* Bits in the Debug register */
107 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
108 #define Debug_DM 0x40000000 /* Debug Mode */
109 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
110
111
112
113
114
115 /*---------------------------------------------------------------------------*/
116 /*-- GDB simulator interface ------------------------------------------------*/
117 /*---------------------------------------------------------------------------*/
118
119 static void ColdReset PARAMS((SIM_DESC sd));
120
121 /*---------------------------------------------------------------------------*/
122
123
124
125 #define DELAYSLOT() {\
126 if (STATE & simDELAYSLOT)\
127 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
128 STATE |= simDELAYSLOT;\
129 }
130
131 #define JALDELAYSLOT() {\
132 DELAYSLOT ();\
133 STATE |= simJALDELAYSLOT;\
134 }
135
136 #define NULLIFY() {\
137 STATE &= ~simDELAYSLOT;\
138 STATE |= simSKIPNEXT;\
139 }
140
141 #define CANCELDELAYSLOT() {\
142 DSSTATE = 0;\
143 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
144 }
145
146 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
147 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
148
149 #define K0BASE (0x80000000)
150 #define K0SIZE (0x20000000)
151 #define K1BASE (0xA0000000)
152 #define K1SIZE (0x20000000)
153 #define MONITOR_BASE (0xBFC00000)
154 #define MONITOR_SIZE (1 << 11)
155 #define MEM_SIZE (2 << 20)
156
157 /* start-sanitize-sky */
158 #ifdef TARGET_SKY
159 #undef MEM_SIZE
160 #define MEM_SIZE (16 << 20) /* 16 MB */
161 #endif
162 /* end-sanitize-sky */
163
164 #if defined(TRACE)
165 static char *tracefile = "trace.din"; /* default filename for trace log */
166 FILE *tracefh = NULL;
167 static void open_trace PARAMS((SIM_DESC sd));
168 #endif /* TRACE */
169
170 static DECLARE_OPTION_HANDLER (mips_option_handler);
171
172 enum {
173 OPTION_DINERO_TRACE = OPTION_START,
174 OPTION_DINERO_FILE
175 /* start-sanitize-sky */
176 ,OPTION_FLOAT_TYPE
177 /* end-sanitize-sky */
178 };
179
180 static SIM_RC
181 mips_option_handler (sd, cpu, opt, arg, is_command)
182 SIM_DESC sd;
183 sim_cpu *cpu;
184 int opt;
185 char *arg;
186 int is_command;
187 {
188 int cpu_nr;
189 switch (opt)
190 {
191 case OPTION_DINERO_TRACE: /* ??? */
192 #if defined(TRACE)
193 /* Eventually the simTRACE flag could be treated as a toggle, to
194 allow external control of the program points being traced
195 (i.e. only from main onwards, excluding the run-time setup,
196 etc.). */
197 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
198 {
199 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
200 if (arg == NULL)
201 STATE |= simTRACE;
202 else if (strcmp (arg, "yes") == 0)
203 STATE |= simTRACE;
204 else if (strcmp (arg, "no") == 0)
205 STATE &= ~simTRACE;
206 else if (strcmp (arg, "on") == 0)
207 STATE |= simTRACE;
208 else if (strcmp (arg, "off") == 0)
209 STATE &= ~simTRACE;
210 else
211 {
212 fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
213 return SIM_RC_FAIL;
214 }
215 }
216 return SIM_RC_OK;
217 #else /* !TRACE */
218 fprintf(stderr,"\
219 Simulator constructed without dinero tracing support (for performance).\n\
220 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
221 return SIM_RC_FAIL;
222 #endif /* !TRACE */
223
224 case OPTION_DINERO_FILE:
225 #if defined(TRACE)
226 if (optarg != NULL) {
227 char *tmp;
228 tmp = (char *)malloc(strlen(optarg) + 1);
229 if (tmp == NULL)
230 {
231 sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
232 return SIM_RC_FAIL;
233 }
234 else {
235 strcpy(tmp,optarg);
236 tracefile = tmp;
237 sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
238 }
239 }
240 #endif /* TRACE */
241 return SIM_RC_OK;
242
243 /* start-sanitize-sky */
244 case OPTION_FLOAT_TYPE:
245 /* Use host (fast) or target (accurate) floating point implementation. */
246 if (arg && strcmp (arg, "host") == 0)
247 STATE_FP_TYPE_OPT (sd) &= ~STATE_FP_TYPE_OPT_TARGET;
248 else if (arg && strcmp (arg, "target") == 0)
249 STATE_FP_TYPE_OPT (sd) |= STATE_FP_TYPE_OPT_TARGET;
250 else
251 {
252 fprintf (stderr, "Unrecognized float-type option `%s'\n", arg);
253 return SIM_RC_FAIL;
254 }
255 return SIM_RC_OK;
256 /* end-sanitize-sky */
257 }
258
259 return SIM_RC_OK;
260 }
261
262 static const OPTION mips_options[] =
263 {
264 { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
265 '\0', "on|off", "Enable dinero tracing",
266 mips_option_handler },
267 { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
268 '\0', "FILE", "Write dinero trace to FILE",
269 mips_option_handler },
270 /* start-sanitize-sky */
271 { {"float-type", required_argument, NULL, OPTION_FLOAT_TYPE},
272 '\0', "host|target", "Use host (fast) or target (accurate) floating point",
273 mips_option_handler },
274 /* end-sanitize-sky */
275 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
276 };
277
278
279 int interrupt_pending;
280
281 static void
282 interrupt_event (SIM_DESC sd, void *data)
283 {
284 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
285 if (SR & status_IE)
286 {
287 interrupt_pending = 0;
288 SignalExceptionInterrupt ();
289 }
290 else if (!interrupt_pending)
291 sim_events_schedule (sd, 1, interrupt_event, data);
292 }
293
294
295 /*---------------------------------------------------------------------------*/
296 /*-- Device registration hook -----------------------------------------------*/
297 /*---------------------------------------------------------------------------*/
298 static void device_init(SIM_DESC sd) {
299 #ifdef DEVICE_INIT
300 extern void register_devices(SIM_DESC);
301 register_devices(sd);
302 #endif
303 }
304
305 /*---------------------------------------------------------------------------*/
306 /*-- GDB simulator interface ------------------------------------------------*/
307 /*---------------------------------------------------------------------------*/
308
309 SIM_DESC
310 sim_open (kind, cb, abfd, argv)
311 SIM_OPEN_KIND kind;
312 host_callback *cb;
313 struct _bfd *abfd;
314 char **argv;
315 {
316 SIM_DESC sd = sim_state_alloc (kind, cb);
317 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
318
319 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
320
321 /* FIXME: watchpoints code shouldn't need this */
322 STATE_WATCHPOINTS (sd)->pc = &(PC);
323 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
324 STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
325
326 STATE = 0;
327
328 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
329 return 0;
330 sim_add_option_table (sd, NULL, mips_options);
331
332 /* Allocate core managed memory */
333
334 /* the monitor */
335 sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE, MONITOR_SIZE);
336 /* For compatibility with the old code - under this (at level one)
337 are the kernel spaces K0 & K1. Both of these map to a single
338 smaller sub region */
339 sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
340 /* start-sanitize-sky */
341 #ifndef TARGET_SKY
342 /* end-sanitize-sky */
343 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
344 K1BASE, K0SIZE,
345 MEM_SIZE, /* actual size */
346 K0BASE);
347 /* start-sanitize-sky */
348 #else
349 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x",
350 K1BASE, K0SIZE,
351 MEM_SIZE, /* actual size */
352 K0BASE,
353 0); /* add alias at 0x0000 */
354 #endif
355 /* end-sanitize-sky */
356
357 device_init(sd);
358
359 /* getopt will print the error message so we just have to exit if this fails.
360 FIXME: Hmmm... in the case of gdb we need getopt to call
361 print_filtered. */
362 if (sim_parse_args (sd, argv) != SIM_RC_OK)
363 {
364 /* Uninstall the modules to avoid memory leaks,
365 file descriptor leaks, etc. */
366 sim_module_uninstall (sd);
367 return 0;
368 }
369
370 /* check for/establish the a reference program image */
371 if (sim_analyze_program (sd,
372 (STATE_PROG_ARGV (sd) != NULL
373 ? *STATE_PROG_ARGV (sd)
374 : NULL),
375 abfd) != SIM_RC_OK)
376 {
377 sim_module_uninstall (sd);
378 return 0;
379 }
380
381 /* Configure/verify the target byte order and other runtime
382 configuration options */
383 if (sim_config (sd) != SIM_RC_OK)
384 {
385 sim_module_uninstall (sd);
386 return 0;
387 }
388
389 if (sim_post_argv_init (sd) != SIM_RC_OK)
390 {
391 /* Uninstall the modules to avoid memory leaks,
392 file descriptor leaks, etc. */
393 sim_module_uninstall (sd);
394 return 0;
395 }
396
397 /* verify assumptions the simulator made about the host type system.
398 This macro does not return if there is a problem */
399 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
400 SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
401
402 /* This is NASTY, in that we are assuming the size of specific
403 registers: */
404 {
405 int rn;
406 for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
407 {
408 if (rn < 32)
409 cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
410 else if ((rn >= FGRIDX) && (rn < (FGRIDX + NR_FGR)))
411 cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
412 else if ((rn >= 33) && (rn <= 37))
413 cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
414 else if ((rn == SRIDX)
415 || (rn == FCR0IDX)
416 || (rn == FCR31IDX)
417 || ((rn >= 72) && (rn <= 89)))
418 cpu->register_widths[rn] = 32;
419 else
420 cpu->register_widths[rn] = 0;
421 }
422 /* start-sanitize-r5900 */
423
424 /* set the 5900 "upper" registers to 64 bits */
425 for( rn = LAST_EMBED_REGNUM+1; rn < NUM_REGS; rn++)
426 cpu->register_widths[rn] = 64;
427 /* end-sanitize-r5900 */
428
429 /* start-sanitize-sky */
430 #ifdef TARGET_SKY
431 /* Now the VU registers */
432 for( rn = 0; rn < NUM_VU_INTEGER_REGS; rn++ ) {
433 cpu->register_widths[rn + NUM_R5900_REGS] = 16;
434 cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 16;
435 }
436
437 for( rn = NUM_VU_INTEGER_REGS; rn < NUM_VU_REGS; rn++ ) {
438 cpu->register_widths[rn + NUM_R5900_REGS] = 32;
439 cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 32;
440 }
441 #endif
442 /* end-sanitize-sky */
443 }
444
445 #if defined(TRACE)
446 if (STATE & simTRACE)
447 open_trace(sd);
448 #endif /* TRACE */
449
450 /* Write the monitor trap address handlers into the monitor (eeprom)
451 address space. This can only be done once the target endianness
452 has been determined. */
453 {
454 unsigned loop;
455 /* Entry into the IDT monitor is via fixed address vectors, and
456 not using machine instructions. To avoid clashing with use of
457 the MIPS TRAP system, we place our own (simulator specific)
458 "undefined" instructions into the relevant vector slots. */
459 for (loop = 0; (loop < MONITOR_SIZE); loop += 4)
460 {
461 address_word vaddr = (MONITOR_BASE + loop);
462 unsigned32 insn = (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT));
463 H2T (insn);
464 sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
465 }
466 /* The PMON monitor uses the same address space, but rather than
467 branching into it the address of a routine is loaded. We can
468 cheat for the moment, and direct the PMON routine to IDT style
469 instructions within the monitor space. This relies on the IDT
470 monitor not using the locations from 0xBFC00500 onwards as its
471 entry points.*/
472 for (loop = 0; (loop < 24); loop++)
473 {
474 address_word vaddr = (MONITOR_BASE + 0x500 + (loop * 4));
475 unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
476 switch (loop)
477 {
478 case 0: /* read */
479 value = 7;
480 break;
481 case 1: /* write */
482 value = 8;
483 break;
484 case 2: /* open */
485 value = 6;
486 break;
487 case 3: /* close */
488 value = 10;
489 break;
490 case 5: /* printf */
491 value = ((0x500 - 16) / 8); /* not an IDT reason code */
492 break;
493 case 8: /* cliexit */
494 value = 17;
495 break;
496 case 11: /* flush_cache */
497 value = 28;
498 break;
499 }
500 /* FIXME - should monitor_base be SIM_ADDR?? */
501 value = ((unsigned int)MONITOR_BASE + (value * 8));
502 H2T (value);
503 sim_write (sd, vaddr, (char *)&value, sizeof (value));
504
505 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
506 vaddr -= 0x300;
507 sim_write (sd, vaddr, (char *)&value, sizeof (value));
508 }
509 }
510
511 return sd;
512 }
513
514 #if defined(TRACE)
515 static void
516 open_trace(sd)
517 SIM_DESC sd;
518 {
519 tracefh = fopen(tracefile,"wb+");
520 if (tracefh == NULL)
521 {
522 sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
523 tracefh = stderr;
524 }
525 }
526 #endif /* TRACE */
527
528 void
529 sim_close (sd, quitting)
530 SIM_DESC sd;
531 int quitting;
532 {
533 #ifdef DEBUG
534 printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
535 #endif
536
537 /* "quitting" is non-zero if we cannot hang on errors */
538
539 /* Ensure that any resources allocated through the callback
540 mechanism are released: */
541 sim_io_shutdown (sd);
542
543 #if defined(TRACE)
544 if (tracefh != NULL && tracefh != stderr)
545 fclose(tracefh);
546 tracefh = NULL;
547 #endif /* TRACE */
548
549 /* FIXME - free SD */
550
551 return;
552 }
553
554
555 int
556 sim_write (sd,addr,buffer,size)
557 SIM_DESC sd;
558 SIM_ADDR addr;
559 unsigned char *buffer;
560 int size;
561 {
562 int index;
563 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
564
565 /* Return the number of bytes written, or zero if error. */
566 #ifdef DEBUG
567 sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
568 #endif
569
570 /* We use raw read and write routines, since we do not want to count
571 the GDB memory accesses in our statistics gathering. */
572
573 for (index = 0; index < size; index++)
574 {
575 address_word vaddr = (address_word)addr + index;
576 address_word paddr;
577 int cca;
578 if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
579 break;
580 if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
581 break;
582 }
583
584 return(index);
585 }
586
587 int
588 sim_read (sd,addr,buffer,size)
589 SIM_DESC sd;
590 SIM_ADDR addr;
591 unsigned char *buffer;
592 int size;
593 {
594 int index;
595 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
596
597 /* Return the number of bytes read, or zero if error. */
598 #ifdef DEBUG
599 sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
600 #endif /* DEBUG */
601
602 for (index = 0; (index < size); index++)
603 {
604 address_word vaddr = (address_word)addr + index;
605 address_word paddr;
606 int cca;
607 if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
608 break;
609 if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
610 break;
611 }
612
613 return(index);
614 }
615
616 int
617 sim_store_register (sd,rn,memory,length)
618 SIM_DESC sd;
619 int rn;
620 unsigned char *memory;
621 int length;
622 {
623 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
624 /* NOTE: gdb (the client) stores registers in target byte order
625 while the simulator uses host byte order */
626 #ifdef DEBUG
627 sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
628 #endif /* DEBUG */
629
630 /* Unfortunately this suffers from the same problem as the register
631 numbering one. We need to know what the width of each logical
632 register number is for the architecture being simulated. */
633
634 if (cpu->register_widths[rn] == 0)
635 {
636 sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
637 return 0;
638 }
639
640 /* start-sanitize-r5900 */
641 if (rn >= 90 && rn < 90 + 32)
642 {
643 GPR1[rn - 90] = T2H_8 (*(unsigned64*)memory);
644 return 8;
645 }
646 switch (rn)
647 {
648 case REGISTER_SA:
649 SA = T2H_8(*(unsigned64*)memory);
650 return 8;
651 case 122: /* FIXME */
652 LO1 = T2H_8(*(unsigned64*)memory);
653 return 8;
654 case 123: /* FIXME */
655 HI1 = T2H_8(*(unsigned64*)memory);
656 return 8;
657 }
658 /* end-sanitize-r5900 */
659
660 /* start-sanitize-sky */
661 #ifdef TARGET_SKY
662 if (rn >= NUM_R5900_REGS)
663 {
664 int size = 4; /* Default register size */
665
666 rn = rn - NUM_R5900_REGS;
667
668 if (rn < NUM_VU_INTEGER_REGS)
669 size = write_vu_int_reg (&(vu0_device.state->regs), rn, memory);
670 else if( rn < NUM_VU_REGS )
671 {
672 if (rn >= FIRST_VEC_REG)
673 {
674 rn -= FIRST_VEC_REG;
675 size = write_vu_vec_reg (&(vu0_device.state->regs), rn>>2, rn&3,
676 memory);
677 }
678 else switch (rn - NUM_VU_INTEGER_REGS)
679 {
680 case 0:
681 size = write_vu_special_reg (vu0_device.state, VU_REG_CIA,
682 memory);
683 break;
684 case 1:
685 size = write_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MR,
686 memory);
687 break;
688 case 2: /* VU0 has no P register */
689 break;
690 case 3:
691 size = write_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MI,
692 memory);
693 break;
694 case 4:
695 size = write_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MQ,
696 memory);
697 break;
698 default:
699 size = write_vu_acc_reg (&(vu0_device.state->regs),
700 rn - (NUM_VU_INTEGER_REGS + 5),
701 memory);
702 break;
703 }
704 }
705 else {
706 rn = rn - NUM_VU_REGS;
707
708 if( rn < NUM_VU_INTEGER_REGS )
709 size = write_vu_int_reg (&(vu1_device.state->regs), rn, memory);
710 else if( rn < NUM_VU_REGS )
711 {
712 if (rn >= FIRST_VEC_REG)
713 {
714 rn -= FIRST_VEC_REG;
715 size = write_vu_vec_reg (&(vu1_device.state->regs),
716 rn >> 2, rn & 3, memory);
717 }
718 else switch (rn - NUM_VU_INTEGER_REGS)
719 {
720 case 0:
721 size = write_vu_special_reg (vu1_device.state, VU_REG_CIA,
722 memory);
723 break;
724 case 1:
725 size = write_vu_misc_reg (&(vu1_device.state->regs),
726 VU_REG_MR, memory);
727 break;
728 case 2:
729 size = write_vu_misc_reg (&(vu1_device.state->regs),
730 VU_REG_MP, memory);
731 break;
732 case 3:
733 size = write_vu_misc_reg (&(vu1_device.state->regs),
734 VU_REG_MI, memory);
735 break;
736 case 4:
737 size = write_vu_misc_reg (&(vu1_device.state->regs),
738 VU_REG_MQ, memory);
739 break;
740 default:
741 size = write_vu_acc_reg (&(vu1_device.state->regs),
742 rn - (NUM_VU_INTEGER_REGS + 5),
743 memory);
744 break;
745 }
746 }
747 else
748 sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" );
749 }
750
751 return size;
752 }
753 #endif
754 /* end-sanitize-sky */
755
756 if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
757 {
758 if (cpu->register_widths[rn] == 32)
759 {
760 cpu->fgr[rn - FGRIDX] = T2H_4 (*(unsigned32*)memory);
761 return 4;
762 }
763 else
764 {
765 cpu->fgr[rn - FGRIDX] = T2H_8 (*(unsigned64*)memory);
766 return 8;
767 }
768 }
769
770 if (cpu->register_widths[rn] == 32)
771 {
772 cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
773 return 4;
774 }
775 else
776 {
777 cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
778 return 8;
779 }
780 }
781
782 int
783 sim_fetch_register (sd,rn,memory,length)
784 SIM_DESC sd;
785 int rn;
786 unsigned char *memory;
787 int length;
788 {
789 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
790 /* NOTE: gdb (the client) stores registers in target byte order
791 while the simulator uses host byte order */
792 #ifdef DEBUG
793 sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
794 #endif /* DEBUG */
795
796 if (cpu->register_widths[rn] == 0)
797 {
798 sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
799 return 0;
800 }
801
802 /* start-sanitize-r5900 */
803 if (rn >= 90 && rn < 90 + 32)
804 {
805 *(unsigned64*)memory = GPR1[rn - 90];
806 return 8;
807 }
808 switch (rn)
809 {
810 case REGISTER_SA:
811 *((unsigned64*)memory) = H2T_8(SA);
812 return 8;
813 case 122: /* FIXME */
814 *((unsigned64*)memory) = H2T_8(LO1);
815 return 8;
816 case 123: /* FIXME */
817 *((unsigned64*)memory) = H2T_8(HI1);
818 return 8;
819 }
820 /* end-sanitize-r5900 */
821
822 /* start-sanitize-sky */
823 #ifdef TARGET_SKY
824 if (rn >= NUM_R5900_REGS)
825 {
826 int size = 4; /* default register width */
827
828 rn = rn - NUM_R5900_REGS;
829
830 if (rn < NUM_VU_INTEGER_REGS)
831 size = read_vu_int_reg (&(vu0_device.state->regs), rn, memory);
832 else if (rn < NUM_VU_REGS)
833 {
834 if (rn >= FIRST_VEC_REG)
835 {
836 rn -= FIRST_VEC_REG;
837 size = read_vu_vec_reg (&(vu0_device.state->regs), rn>>2, rn & 3,
838 memory);
839 }
840 else switch (rn - NUM_VU_INTEGER_REGS)
841 {
842 case 0:
843 size = read_vu_special_reg (vu0_device.state, VU_REG_CIA,
844 memory);
845
846 break;
847 case 1:
848 size = read_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MR,
849 memory);
850 break;
851 case 2: /* VU0 has no P register */
852 break;
853 case 3:
854 size = read_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MI,
855 memory);
856 break;
857 case 4:
858 size = read_vu_misc_reg (&(vu0_device.state->regs), VU_REG_MQ,
859 memory);
860 break;
861 default:
862 size = read_vu_acc_reg (&(vu0_device.state->regs),
863 rn - (NUM_VU_INTEGER_REGS + 5),
864 memory);
865 break;
866 }
867 }
868 else
869 {
870 rn = rn - NUM_VU_REGS;
871
872 if (rn < NUM_VU_INTEGER_REGS)
873 size = read_vu_int_reg (&(vu1_device.state->regs), rn, memory);
874 else if (rn < NUM_VU_REGS)
875 {
876 if (rn >= FIRST_VEC_REG)
877 {
878 rn -= FIRST_VEC_REG;
879 size = read_vu_vec_reg (&(vu1_device.state->regs),
880 rn >> 2, rn & 3, memory);
881 }
882 else switch (rn - NUM_VU_INTEGER_REGS)
883 {
884 case 0:
885 size = read_vu_special_reg (vu1_device.state, VU_REG_CIA,
886 memory);
887 break;
888 case 1:
889 size = read_vu_misc_reg (&(vu1_device.state->regs),
890 VU_REG_MR, memory);
891 break;
892 case 2:
893 size = read_vu_misc_reg (&(vu1_device.state->regs),
894 VU_REG_MP, memory);
895 break;
896 case 3:
897 size = read_vu_misc_reg (&(vu1_device.state->regs),
898 VU_REG_MI, memory);
899 break;
900 case 4:
901 size = read_vu_misc_reg (&(vu1_device.state->regs),
902 VU_REG_MQ, memory);
903 break;
904 default:
905 size = read_vu_acc_reg (&(vu1_device.state->regs),
906 rn - (NUM_VU_INTEGER_REGS + 5),
907 memory);
908 break;
909 }
910 }
911 else
912 sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
913 }
914
915 return size;
916 }
917 #endif
918 /* end-sanitize-sky */
919
920 /* Any floating point register */
921 if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
922 {
923 if (cpu->register_widths[rn] == 32)
924 {
925 *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGRIDX]);
926 return 4;
927 }
928 else
929 {
930 *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGRIDX]);
931 return 8;
932 }
933 }
934
935 if (cpu->register_widths[rn] == 32)
936 {
937 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
938 return 4;
939 }
940 else
941 {
942 *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
943 return 8;
944 }
945 }
946
947
948 SIM_RC
949 sim_create_inferior (sd, abfd, argv,env)
950 SIM_DESC sd;
951 struct _bfd *abfd;
952 char **argv;
953 char **env;
954 {
955
956 #ifdef DEBUG
957 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
958 pr_addr(PC));
959 #endif /* DEBUG */
960
961 ColdReset(sd);
962
963 if (abfd != NULL)
964 {
965 /* override PC value set by ColdReset () */
966 int cpu_nr;
967 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
968 {
969 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
970 CIA_SET (cpu, (unsigned64) bfd_get_start_address (abfd));
971 }
972 }
973
974 #if 0 /* def DEBUG */
975 if (argv || env)
976 {
977 /* We should really place the argv slot values into the argument
978 registers, and onto the stack as required. However, this
979 assumes that we have a stack defined, which is not
980 necessarily true at the moment. */
981 char **cptr;
982 sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
983 for (cptr = argv; (cptr && *cptr); cptr++)
984 printf("DBG: arg \"%s\"\n",*cptr);
985 }
986 #endif /* DEBUG */
987
988 return SIM_RC_OK;
989 }
990
991 void
992 sim_do_command (sd,cmd)
993 SIM_DESC sd;
994 char *cmd;
995 {
996 if (sim_args_command (sd, cmd) != SIM_RC_OK)
997 sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n",
998 cmd);
999 }
1000
1001 /*---------------------------------------------------------------------------*/
1002 /*-- Private simulator support interface ------------------------------------*/
1003 /*---------------------------------------------------------------------------*/
1004
1005 /* Read a null terminated string from memory, return in a buffer */
1006 static char *
1007 fetch_str (sd, addr)
1008 SIM_DESC sd;
1009 address_word addr;
1010 {
1011 char *buf;
1012 int nr = 0;
1013 char null;
1014 while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
1015 nr++;
1016 buf = NZALLOC (char, nr + 1);
1017 sim_read (sd, addr, buf, nr);
1018 return buf;
1019 }
1020
1021 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1022 static void
1023 sim_monitor (SIM_DESC sd,
1024 sim_cpu *cpu,
1025 address_word cia,
1026 unsigned int reason)
1027 {
1028 #ifdef DEBUG
1029 printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1030 #endif /* DEBUG */
1031
1032 /* The IDT monitor actually allows two instructions per vector
1033 slot. However, the simulator currently causes a trap on each
1034 individual instruction. We cheat, and lose the bottom bit. */
1035 reason >>= 1;
1036
1037 /* The following callback functions are available, however the
1038 monitor we are simulating does not make use of them: get_errno,
1039 isatty, lseek, rename, system, time and unlink */
1040 switch (reason)
1041 {
1042
1043 case 6: /* int open(char *path,int flags) */
1044 {
1045 char *path = fetch_str (sd, A0);
1046 V0 = sim_io_open (sd, path, (int)A1);
1047 zfree (path);
1048 break;
1049 }
1050
1051 case 7: /* int read(int file,char *ptr,int len) */
1052 {
1053 int fd = A0;
1054 int nr = A2;
1055 char *buf = zalloc (nr);
1056 V0 = sim_io_read (sd, fd, buf, nr);
1057 sim_write (sd, A1, buf, nr);
1058 zfree (buf);
1059 }
1060 break;
1061
1062 case 8: /* int write(int file,char *ptr,int len) */
1063 {
1064 int fd = A0;
1065 int nr = A2;
1066 char *buf = zalloc (nr);
1067 sim_read (sd, A1, buf, nr);
1068 V0 = sim_io_write (sd, fd, buf, nr);
1069 zfree (buf);
1070 break;
1071 }
1072
1073 case 10: /* int close(int file) */
1074 {
1075 V0 = sim_io_close (sd, (int)A0);
1076 break;
1077 }
1078
1079 case 2: /* Densan monitor: char inbyte(int waitflag) */
1080 {
1081 if (A0 == 0) /* waitflag == NOWAIT */
1082 V0 = (unsigned_word)-1;
1083 }
1084 /* Drop through to case 11 */
1085
1086 case 11: /* char inbyte(void) */
1087 {
1088 char tmp;
1089 if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
1090 {
1091 sim_io_error(sd,"Invalid return from character read");
1092 V0 = (unsigned_word)-1;
1093 }
1094 else
1095 V0 = (unsigned_word)tmp;
1096 break;
1097 }
1098
1099 case 3: /* Densan monitor: void co(char chr) */
1100 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1101 {
1102 char tmp = (char)(A0 & 0xFF);
1103 sim_io_write_stdout (sd, &tmp, sizeof(char));
1104 break;
1105 }
1106
1107 case 17: /* void _exit() */
1108 {
1109 sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
1110 sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited,
1111 (unsigned int)(A0 & 0xFFFFFFFF));
1112 break;
1113 }
1114
1115 case 28 : /* PMON flush_cache */
1116 break;
1117
1118 case 55: /* void get_mem_info(unsigned int *ptr) */
1119 /* in: A0 = pointer to three word memory location */
1120 /* out: [A0 + 0] = size */
1121 /* [A0 + 4] = instruction cache size */
1122 /* [A0 + 8] = data cache size */
1123 {
1124 unsigned_4 value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
1125 unsigned_4 zero = 0;
1126 H2T (value);
1127 sim_write (sd, A0 + 0, (char *)&value, 4);
1128 sim_write (sd, A0 + 4, (char *)&zero, 4);
1129 sim_write (sd, A0 + 8, (char *)&zero, 4);
1130 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1131 break;
1132 }
1133
1134 case 158 : /* PMON printf */
1135 /* in: A0 = pointer to format string */
1136 /* A1 = optional argument 1 */
1137 /* A2 = optional argument 2 */
1138 /* A3 = optional argument 3 */
1139 /* out: void */
1140 /* The following is based on the PMON printf source */
1141 {
1142 address_word s = A0;
1143 char c;
1144 signed_word *ap = &A1; /* 1st argument */
1145 /* This isn't the quickest way, since we call the host print
1146 routine for every character almost. But it does avoid
1147 having to allocate and manage a temporary string buffer. */
1148 /* TODO: Include check that we only use three arguments (A1,
1149 A2 and A3) */
1150 while (sim_read (sd, s++, &c, 1) && c != '\0')
1151 {
1152 if (c == '%')
1153 {
1154 char tmp[40];
1155 enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
1156 int width = 0, trunc = 0, haddot = 0, longlong = 0;
1157 while (sim_read (sd, s++, &c, 1) && c != '\0')
1158 {
1159 if (strchr ("dobxXulscefg%", s))
1160 break;
1161 else if (c == '-')
1162 fmt = FMT_LJUST;
1163 else if (c == '0')
1164 fmt = FMT_RJUST0;
1165 else if (c == '~')
1166 fmt = FMT_CENTER;
1167 else if (c == '*')
1168 {
1169 if (haddot)
1170 trunc = (int)*ap++;
1171 else
1172 width = (int)*ap++;
1173 }
1174 else if (c >= '1' && c <= '9')
1175 {
1176 address_word t = s;
1177 unsigned int n;
1178 while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
1179 tmp[s - t] = c;
1180 tmp[s - t] = '\0';
1181 n = (unsigned int)strtol(tmp,NULL,10);
1182 if (haddot)
1183 trunc = n;
1184 else
1185 width = n;
1186 s--;
1187 }
1188 else if (c == '.')
1189 haddot = 1;
1190 }
1191 switch (c)
1192 {
1193 case '%':
1194 sim_io_printf (sd, "%%");
1195 break;
1196 case 's':
1197 if ((int)*ap != 0)
1198 {
1199 address_word p = *ap++;
1200 char ch;
1201 while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
1202 sim_io_printf(sd, "%c", ch);
1203 }
1204 else
1205 sim_io_printf(sd,"(null)");
1206 break;
1207 case 'c':
1208 sim_io_printf (sd, "%c", (int)*ap++);
1209 break;
1210 default:
1211 if (c == 'l')
1212 {
1213 sim_read (sd, s++, &c, 1);
1214 if (c == 'l')
1215 {
1216 longlong = 1;
1217 sim_read (sd, s++, &c, 1);
1218 }
1219 }
1220 if (strchr ("dobxXu", c))
1221 {
1222 word64 lv = (word64) *ap++;
1223 if (c == 'b')
1224 sim_io_printf(sd,"<binary not supported>");
1225 else
1226 {
1227 sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
1228 if (longlong)
1229 sim_io_printf(sd, tmp, lv);
1230 else
1231 sim_io_printf(sd, tmp, (int)lv);
1232 }
1233 }
1234 else if (strchr ("eEfgG", c))
1235 {
1236 double dbl = *(double*)(ap++);
1237 sprintf (tmp, "%%%d.%d%c", width, trunc, c);
1238 sim_io_printf (sd, tmp, dbl);
1239 trunc = 0;
1240 }
1241 }
1242 }
1243 else
1244 sim_io_printf(sd, "%c", c);
1245 }
1246 break;
1247 }
1248
1249 default:
1250 sim_io_error (sd, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1251 reason, pr_addr(cia));
1252 break;
1253 }
1254 return;
1255 }
1256
1257 /* Store a word into memory. */
1258
1259 static void
1260 store_word (SIM_DESC sd,
1261 sim_cpu *cpu,
1262 address_word cia,
1263 uword64 vaddr,
1264 signed_word val)
1265 {
1266 address_word paddr;
1267 int uncached;
1268
1269 if ((vaddr & 3) != 0)
1270 SignalExceptionAddressStore ();
1271 else
1272 {
1273 if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1274 isTARGET, isREAL))
1275 {
1276 const uword64 mask = 7;
1277 uword64 memval;
1278 unsigned int byte;
1279
1280 paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1281 byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1282 memval = ((uword64) val) << (8 * byte);
1283 StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
1284 isREAL);
1285 }
1286 }
1287 }
1288
1289 /* Load a word from memory. */
1290
1291 static signed_word
1292 load_word (SIM_DESC sd,
1293 sim_cpu *cpu,
1294 address_word cia,
1295 uword64 vaddr)
1296 {
1297 if ((vaddr & 3) != 0)
1298 SignalExceptionAddressLoad ();
1299 else
1300 {
1301 address_word paddr;
1302 int uncached;
1303
1304 if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
1305 isTARGET, isREAL))
1306 {
1307 const uword64 mask = 0x7;
1308 const unsigned int reverse = ReverseEndian ? 1 : 0;
1309 const unsigned int bigend = BigEndianCPU ? 1 : 0;
1310 uword64 memval;
1311 unsigned int byte;
1312
1313 paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1314 LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
1315 isDATA, isREAL);
1316 byte = (vaddr & mask) ^ (bigend << 2);
1317 return SIGNEXTEND (((memval >> (8 * byte)) & 0xffffffff), 32);
1318 }
1319 }
1320
1321 return 0;
1322 }
1323
1324 /* Simulate the mips16 entry and exit pseudo-instructions. These
1325 would normally be handled by the reserved instruction exception
1326 code, but for ease of simulation we just handle them directly. */
1327
1328 static void
1329 mips16_entry (SIM_DESC sd,
1330 sim_cpu *cpu,
1331 address_word cia,
1332 unsigned int insn)
1333 {
1334 int aregs, sregs, rreg;
1335
1336 #ifdef DEBUG
1337 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1338 #endif /* DEBUG */
1339
1340 aregs = (insn & 0x700) >> 8;
1341 sregs = (insn & 0x0c0) >> 6;
1342 rreg = (insn & 0x020) >> 5;
1343
1344 /* This should be checked by the caller. */
1345 if (sregs == 3)
1346 abort ();
1347
1348 if (aregs < 5)
1349 {
1350 int i;
1351 signed_word tsp;
1352
1353 /* This is the entry pseudo-instruction. */
1354
1355 for (i = 0; i < aregs; i++)
1356 store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
1357
1358 tsp = SP;
1359 SP -= 32;
1360
1361 if (rreg)
1362 {
1363 tsp -= 4;
1364 store_word (SD, CPU, cia, (uword64) tsp, RA);
1365 }
1366
1367 for (i = 0; i < sregs; i++)
1368 {
1369 tsp -= 4;
1370 store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1371 }
1372 }
1373 else
1374 {
1375 int i;
1376 signed_word tsp;
1377
1378 /* This is the exit pseudo-instruction. */
1379
1380 tsp = SP + 32;
1381
1382 if (rreg)
1383 {
1384 tsp -= 4;
1385 RA = load_word (SD, CPU, cia, (uword64) tsp);
1386 }
1387
1388 for (i = 0; i < sregs; i++)
1389 {
1390 tsp -= 4;
1391 GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1392 }
1393
1394 SP += 32;
1395
1396 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1397 {
1398 if (aregs == 5)
1399 {
1400 FGR[0] = WORD64LO (GPR[4]);
1401 FPR_STATE[0] = fmt_uninterpreted;
1402 }
1403 else if (aregs == 6)
1404 {
1405 FGR[0] = WORD64LO (GPR[5]);
1406 FGR[1] = WORD64LO (GPR[4]);
1407 FPR_STATE[0] = fmt_uninterpreted;
1408 FPR_STATE[1] = fmt_uninterpreted;
1409 }
1410 }
1411
1412 PC = RA;
1413 }
1414
1415 }
1416
1417 /*-- trace support ----------------------------------------------------------*/
1418
1419 /* The TRACE support is provided (if required) in the memory accessing
1420 routines. Since we are also providing the architecture specific
1421 features, the architecture simulation code can also deal with
1422 notifying the TRACE world of cache flushes, etc. Similarly we do
1423 not need to provide profiling support in the simulator engine,
1424 since we can sample in the instruction fetch control loop. By
1425 defining the TRACE manifest, we add tracing as a run-time
1426 option. */
1427
1428 #if defined(TRACE)
1429 /* Tracing by default produces "din" format (as required by
1430 dineroIII). Each line of such a trace file *MUST* have a din label
1431 and address field. The rest of the line is ignored, so comments can
1432 be included if desired. The first field is the label which must be
1433 one of the following values:
1434
1435 0 read data
1436 1 write data
1437 2 instruction fetch
1438 3 escape record (treated as unknown access type)
1439 4 escape record (causes cache flush)
1440
1441 The address field is a 32bit (lower-case) hexadecimal address
1442 value. The address should *NOT* be preceded by "0x".
1443
1444 The size of the memory transfer is not important when dealing with
1445 cache lines (as long as no more than a cache line can be
1446 transferred in a single operation :-), however more information
1447 could be given following the dineroIII requirement to allow more
1448 complete memory and cache simulators to provide better
1449 results. i.e. the University of Pisa has a cache simulator that can
1450 also take bus size and speed as (variable) inputs to calculate
1451 complete system performance (a much more useful ability when trying
1452 to construct an end product, rather than a processor). They
1453 currently have an ARM version of their tool called ChARM. */
1454
1455
1456 void
1457 dotrace (SIM_DESC sd,
1458 sim_cpu *cpu,
1459 FILE *tracefh,
1460 int type,
1461 SIM_ADDR address,
1462 int width,
1463 char *comment,...)
1464 {
1465 if (STATE & simTRACE) {
1466 va_list ap;
1467 fprintf(tracefh,"%d %s ; width %d ; ",
1468 type,
1469 pr_addr(address),
1470 width);
1471 va_start(ap,comment);
1472 vfprintf(tracefh,comment,ap);
1473 va_end(ap);
1474 fprintf(tracefh,"\n");
1475 }
1476 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1477 we may be generating 64bit ones, we should put the hi-32bits of the
1478 address into the comment field. */
1479
1480 /* TODO: Provide a buffer for the trace lines. We can then avoid
1481 performing writes until the buffer is filled, or the file is
1482 being closed. */
1483
1484 /* NOTE: We could consider adding a comment field to the "din" file
1485 produced using type 3 markers (unknown access). This would then
1486 allow information about the program that the "din" is for, and
1487 the MIPs world that was being simulated, to be placed into the
1488 trace file. */
1489
1490 return;
1491 }
1492 #endif /* TRACE */
1493
1494 /*---------------------------------------------------------------------------*/
1495 /*-- simulator engine -------------------------------------------------------*/
1496 /*---------------------------------------------------------------------------*/
1497
1498 static void
1499 ColdReset (SIM_DESC sd)
1500 {
1501 int cpu_nr;
1502 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1503 {
1504 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1505 /* RESET: Fixed PC address: */
1506 PC = UNSIGNED64 (0xFFFFFFFFBFC00000);
1507 /* The reset vector address is in the unmapped, uncached memory space. */
1508
1509 SR &= ~(status_SR | status_TS | status_RP);
1510 SR |= (status_ERL | status_BEV);
1511
1512 /* Cheat and allow access to the complete register set immediately */
1513 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
1514 && WITH_TARGET_WORD_BITSIZE == 64)
1515 SR |= status_FR; /* 64bit registers */
1516
1517 /* Ensure that any instructions with pending register updates are
1518 cleared: */
1519 PENDING_INVALIDATE();
1520
1521 /* Initialise the FPU registers to the unknown state */
1522 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1523 {
1524 int rn;
1525 for (rn = 0; (rn < 32); rn++)
1526 FPR_STATE[rn] = fmt_uninterpreted;
1527 }
1528
1529 }
1530 }
1531
1532 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
1533 (revision 3.1) */
1534 /* Translate a virtual address to a physical address and cache
1535 coherence algorithm describing the mechanism used to resolve the
1536 memory reference. Given the virtual address vAddr, and whether the
1537 reference is to Instructions ot Data (IorD), find the corresponding
1538 physical address (pAddr) and the cache coherence algorithm (CCA)
1539 used to resolve the reference. If the virtual address is in one of
1540 the unmapped address spaces the physical address and the CCA are
1541 determined directly by the virtual address. If the virtual address
1542 is in one of the mapped address spaces then the TLB is used to
1543 determine the physical address and access type; if the required
1544 translation is not present in the TLB or the desired access is not
1545 permitted the function fails and an exception is taken.
1546
1547 NOTE: Normally (RAW == 0), when address translation fails, this
1548 function raises an exception and does not return. */
1549
1550 int
1551 address_translation (SIM_DESC sd,
1552 sim_cpu *cpu,
1553 address_word cia,
1554 address_word vAddr,
1555 int IorD,
1556 int LorS,
1557 address_word *pAddr,
1558 int *CCA,
1559 int raw)
1560 {
1561 int res = -1; /* TRUE : Assume good return */
1562
1563 #ifdef DEBUG
1564 sim_io_printf(sd,"AddressTranslation(0x%s,%s,%s,...);\n",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "iSTORE" : "isLOAD"));
1565 #endif
1566
1567 /* Check that the address is valid for this memory model */
1568
1569 /* For a simple (flat) memory model, we simply pass virtual
1570 addressess through (mostly) unchanged. */
1571 vAddr &= 0xFFFFFFFF;
1572
1573 *pAddr = vAddr; /* default for isTARGET */
1574 *CCA = Uncached; /* not used for isHOST */
1575
1576 return(res);
1577 }
1578
1579 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
1580 (revision 3.1) */
1581 /* Prefetch data from memory. Prefetch is an advisory instruction for
1582 which an implementation specific action is taken. The action taken
1583 may increase performance, but must not change the meaning of the
1584 program, or alter architecturally-visible state. */
1585
1586 void
1587 prefetch (SIM_DESC sd,
1588 sim_cpu *cpu,
1589 address_word cia,
1590 int CCA,
1591 address_word pAddr,
1592 address_word vAddr,
1593 int DATA,
1594 int hint)
1595 {
1596 #ifdef DEBUG
1597 sim_io_printf(sd,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint);
1598 #endif /* DEBUG */
1599
1600 /* For our simple memory model we do nothing */
1601 return;
1602 }
1603
1604 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
1605 (revision 3.1) */
1606 /* Load a value from memory. Use the cache and main memory as
1607 specified in the Cache Coherence Algorithm (CCA) and the sort of
1608 access (IorD) to find the contents of AccessLength memory bytes
1609 starting at physical location pAddr. The data is returned in the
1610 fixed width naturally-aligned memory element (MemElem). The
1611 low-order two (or three) bits of the address and the AccessLength
1612 indicate which of the bytes within MemElem needs to be given to the
1613 processor. If the memory access type of the reference is uncached
1614 then only the referenced bytes are read from memory and valid
1615 within the memory element. If the access type is cached, and the
1616 data is not present in cache, an implementation specific size and
1617 alignment block of memory is read and loaded into the cache to
1618 satisfy a load reference. At a minimum, the block is the entire
1619 memory element. */
1620 void
1621 load_memory (SIM_DESC sd,
1622 sim_cpu *cpu,
1623 address_word cia,
1624 uword64* memvalp,
1625 uword64* memval1p,
1626 int CCA,
1627 unsigned int AccessLength,
1628 address_word pAddr,
1629 address_word vAddr,
1630 int IorD)
1631 {
1632 uword64 value = 0;
1633 uword64 value1 = 0;
1634
1635 #ifdef DEBUG
1636 sim_io_printf(sd,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"));
1637 #endif /* DEBUG */
1638
1639 #if defined(WARN_MEM)
1640 if (CCA != uncached)
1641 sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
1642 #endif /* WARN_MEM */
1643
1644 /* If instruction fetch then we need to check that the two lo-order
1645 bits are zero, otherwise raise a InstructionFetch exception: */
1646 if ((IorD == isINSTRUCTION)
1647 && ((pAddr & 0x3) != 0)
1648 && (((pAddr & 0x1) != 0) || ((vAddr & 0x1) == 0)))
1649 SignalExceptionInstructionFetch ();
1650
1651 if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
1652 {
1653 /* In reality this should be a Bus Error */
1654 sim_io_error (sd, "LOAD AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
1655 AccessLength,
1656 (LOADDRMASK + 1) << 3,
1657 pr_addr (pAddr));
1658 }
1659
1660 #if defined(TRACE)
1661 dotrace (SD, CPU, tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
1662 #endif /* TRACE */
1663
1664 /* Read the specified number of bytes from memory. Adjust for
1665 host/target byte ordering/ Align the least significant byte
1666 read. */
1667
1668 switch (AccessLength)
1669 {
1670 case AccessLength_QUADWORD :
1671 {
1672 unsigned_16 val = sim_core_read_aligned_16 (cpu, NULL_CIA, read_map, pAddr);
1673 value1 = VH8_16 (val);
1674 value = VL8_16 (val);
1675 break;
1676 }
1677 case AccessLength_DOUBLEWORD :
1678 value = sim_core_read_aligned_8 (cpu, NULL_CIA,
1679 read_map, pAddr);
1680 break;
1681 case AccessLength_SEPTIBYTE :
1682 value = sim_core_read_misaligned_7 (cpu, NULL_CIA,
1683 read_map, pAddr);
1684 break;
1685 case AccessLength_SEXTIBYTE :
1686 value = sim_core_read_misaligned_6 (cpu, NULL_CIA,
1687 read_map, pAddr);
1688 break;
1689 case AccessLength_QUINTIBYTE :
1690 value = sim_core_read_misaligned_5 (cpu, NULL_CIA,
1691 read_map, pAddr);
1692 break;
1693 case AccessLength_WORD :
1694 value = sim_core_read_aligned_4 (cpu, NULL_CIA,
1695 read_map, pAddr);
1696 break;
1697 case AccessLength_TRIPLEBYTE :
1698 value = sim_core_read_misaligned_3 (cpu, NULL_CIA,
1699 read_map, pAddr);
1700 break;
1701 case AccessLength_HALFWORD :
1702 value = sim_core_read_aligned_2 (cpu, NULL_CIA,
1703 read_map, pAddr);
1704 break;
1705 case AccessLength_BYTE :
1706 value = sim_core_read_aligned_1 (cpu, NULL_CIA,
1707 read_map, pAddr);
1708 break;
1709 default:
1710 abort ();
1711 }
1712
1713 #ifdef DEBUG
1714 printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
1715 (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
1716 #endif /* DEBUG */
1717
1718 /* See also store_memory. Position data in correct byte lanes. */
1719 if (AccessLength <= LOADDRMASK)
1720 {
1721 if (BigEndianMem)
1722 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
1723 shifted to the most significant byte position. */
1724 value <<= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
1725 else
1726 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
1727 is already in the correct postition. */
1728 value <<= ((pAddr & LOADDRMASK) * 8);
1729 }
1730
1731 #ifdef DEBUG
1732 printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
1733 pr_uword64(value1),pr_uword64(value));
1734 #endif /* DEBUG */
1735
1736 *memvalp = value;
1737 if (memval1p) *memval1p = value1;
1738 }
1739
1740
1741 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
1742 (revision 3.1) */
1743 /* Store a value to memory. The specified data is stored into the
1744 physical location pAddr using the memory hierarchy (data caches and
1745 main memory) as specified by the Cache Coherence Algorithm
1746 (CCA). The MemElem contains the data for an aligned, fixed-width
1747 memory element (word for 32-bit processors, doubleword for 64-bit
1748 processors), though only the bytes that will actually be stored to
1749 memory need to be valid. The low-order two (or three) bits of pAddr
1750 and the AccessLength field indicates which of the bytes within the
1751 MemElem data should actually be stored; only these bytes in memory
1752 will be changed. */
1753
1754 void
1755 store_memory (SIM_DESC sd,
1756 sim_cpu *cpu,
1757 address_word cia,
1758 int CCA,
1759 unsigned int AccessLength,
1760 uword64 MemElem,
1761 uword64 MemElem1, /* High order 64 bits */
1762 address_word pAddr,
1763 address_word vAddr)
1764 {
1765 #ifdef DEBUG
1766 sim_io_printf(sd,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr));
1767 #endif /* DEBUG */
1768
1769 #if defined(WARN_MEM)
1770 if (CCA != uncached)
1771 sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
1772 #endif /* WARN_MEM */
1773
1774 if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
1775 sim_io_error (sd, "STORE AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
1776 AccessLength,
1777 (LOADDRMASK + 1) << 3,
1778 pr_addr(pAddr));
1779
1780 #if defined(TRACE)
1781 dotrace (SD, CPU, tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
1782 #endif /* TRACE */
1783
1784 #ifdef DEBUG
1785 printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem));
1786 #endif /* DEBUG */
1787
1788 /* See also load_memory. Position data in correct byte lanes. */
1789 if (AccessLength <= LOADDRMASK)
1790 {
1791 if (BigEndianMem)
1792 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
1793 shifted to the most significant byte position. */
1794 MemElem >>= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
1795 else
1796 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
1797 is already in the correct postition. */
1798 MemElem >>= ((pAddr & LOADDRMASK) * 8);
1799 }
1800
1801 #ifdef DEBUG
1802 printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem));
1803 #endif /* DEBUG */
1804
1805 switch (AccessLength)
1806 {
1807 case AccessLength_QUADWORD :
1808 {
1809 unsigned_16 val = U16_8 (MemElem1, MemElem);
1810 sim_core_write_aligned_16 (cpu, NULL_CIA, write_map, pAddr, val);
1811 break;
1812 }
1813 case AccessLength_DOUBLEWORD :
1814 sim_core_write_aligned_8 (cpu, NULL_CIA,
1815 write_map, pAddr, MemElem);
1816 break;
1817 case AccessLength_SEPTIBYTE :
1818 sim_core_write_misaligned_7 (cpu, NULL_CIA,
1819 write_map, pAddr, MemElem);
1820 break;
1821 case AccessLength_SEXTIBYTE :
1822 sim_core_write_misaligned_6 (cpu, NULL_CIA,
1823 write_map, pAddr, MemElem);
1824 break;
1825 case AccessLength_QUINTIBYTE :
1826 sim_core_write_misaligned_5 (cpu, NULL_CIA,
1827 write_map, pAddr, MemElem);
1828 break;
1829 case AccessLength_WORD :
1830 sim_core_write_aligned_4 (cpu, NULL_CIA,
1831 write_map, pAddr, MemElem);
1832 break;
1833 case AccessLength_TRIPLEBYTE :
1834 sim_core_write_misaligned_3 (cpu, NULL_CIA,
1835 write_map, pAddr, MemElem);
1836 break;
1837 case AccessLength_HALFWORD :
1838 sim_core_write_aligned_2 (cpu, NULL_CIA,
1839 write_map, pAddr, MemElem);
1840 break;
1841 case AccessLength_BYTE :
1842 sim_core_write_aligned_1 (cpu, NULL_CIA,
1843 write_map, pAddr, MemElem);
1844 break;
1845 default:
1846 abort ();
1847 }
1848
1849 return;
1850 }
1851
1852
1853 unsigned32
1854 ifetch32 (SIM_DESC sd,
1855 sim_cpu *cpu,
1856 address_word cia,
1857 address_word vaddr)
1858 {
1859 /* Copy the action of the LW instruction */
1860 address_word reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
1861 address_word bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
1862 unsigned64 value;
1863 address_word paddr;
1864 unsigned32 instruction;
1865 unsigned byte;
1866 int cca;
1867 AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &cca, isTARGET, isREAL);
1868 paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
1869 LoadMemory (&value, NULL, cca, AccessLength_WORD, paddr, vaddr, isINSTRUCTION, isREAL);
1870 byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
1871 instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
1872 return instruction;
1873 }
1874
1875
1876 unsigned16
1877 ifetch16 (SIM_DESC sd,
1878 sim_cpu *cpu,
1879 address_word cia,
1880 address_word vaddr)
1881 {
1882 /* Copy the action of the LW instruction */
1883 address_word reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
1884 address_word bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
1885 unsigned64 value;
1886 address_word paddr;
1887 unsigned16 instruction;
1888 unsigned byte;
1889 int cca;
1890 AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &cca, isTARGET, isREAL);
1891 paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
1892 LoadMemory (&value, NULL, cca, AccessLength_WORD, paddr, vaddr, isINSTRUCTION, isREAL);
1893 byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
1894 instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
1895 return instruction;
1896 }
1897
1898
1899 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1900 /* Order loads and stores to synchronise shared memory. Perform the
1901 action necessary to make the effects of groups of synchronizable
1902 loads and stores indicated by stype occur in the same order for all
1903 processors. */
1904 void
1905 sync_operation (SIM_DESC sd,
1906 sim_cpu *cpu,
1907 address_word cia,
1908 int stype)
1909 {
1910 #ifdef DEBUG
1911 sim_io_printf(sd,"SyncOperation(%d) : TODO\n",stype);
1912 #endif /* DEBUG */
1913 return;
1914 }
1915
1916 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1917 /* Signal an exception condition. This will result in an exception
1918 that aborts the instruction. The instruction operation pseudocode
1919 will never see a return from this function call. */
1920
1921 void
1922 signal_exception (SIM_DESC sd,
1923 sim_cpu *cpu,
1924 address_word cia,
1925 int exception,...)
1926 {
1927 int vector;
1928
1929 #ifdef DEBUG
1930 sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1931 #endif /* DEBUG */
1932
1933 /* Ensure that any active atomic read/modify/write operation will fail: */
1934 LLBIT = 0;
1935
1936 switch (exception) {
1937 /* TODO: For testing purposes I have been ignoring TRAPs. In
1938 reality we should either simulate them, or allow the user to
1939 ignore them at run-time.
1940 Same for SYSCALL */
1941 case Trap :
1942 sim_io_eprintf(sd,"Ignoring instruction TRAP (PC 0x%s)\n",pr_addr(cia));
1943 break;
1944
1945 case SystemCall :
1946 {
1947 va_list ap;
1948 unsigned int instruction;
1949 unsigned int code;
1950
1951 va_start(ap,exception);
1952 instruction = va_arg(ap,unsigned int);
1953 va_end(ap);
1954
1955 code = (instruction >> 6) & 0xFFFFF;
1956
1957 sim_io_eprintf(sd,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
1958 code, pr_addr(cia));
1959 }
1960 break;
1961
1962 case DebugBreakPoint :
1963 if (! (Debug & Debug_DM))
1964 {
1965 if (INDELAYSLOT())
1966 {
1967 CANCELDELAYSLOT();
1968
1969 Debug |= Debug_DBD; /* signaled from within in delay slot */
1970 DEPC = cia - 4; /* reference the branch instruction */
1971 }
1972 else
1973 {
1974 Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1975 DEPC = cia;
1976 }
1977
1978 Debug |= Debug_DM; /* in debugging mode */
1979 Debug |= Debug_DBp; /* raising a DBp exception */
1980 PC = 0xBFC00200;
1981 sim_engine_restart (SD, CPU, NULL, NULL_CIA);
1982 }
1983 break;
1984
1985 case ReservedInstruction :
1986 {
1987 va_list ap;
1988 unsigned int instruction;
1989 va_start(ap,exception);
1990 instruction = va_arg(ap,unsigned int);
1991 va_end(ap);
1992 /* Provide simple monitor support using ReservedInstruction
1993 exceptions. The following code simulates the fixed vector
1994 entry points into the IDT monitor by causing a simulator
1995 trap, performing the monitor operation, and returning to
1996 the address held in the $ra register (standard PCS return
1997 address). This means we only need to pre-load the vector
1998 space with suitable instruction values. For systems were
1999 actual trap instructions are used, we would not need to
2000 perform this magic. */
2001 if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
2002 {
2003 sim_monitor (SD, CPU, cia, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
2004 /* NOTE: This assumes that a branch-and-link style
2005 instruction was used to enter the vector (which is the
2006 case with the current IDT monitor). */
2007 sim_engine_restart (SD, CPU, NULL, RA);
2008 }
2009 /* Look for the mips16 entry and exit instructions, and
2010 simulate a handler for them. */
2011 else if ((cia & 1) != 0
2012 && (instruction & 0xf81f) == 0xe809
2013 && (instruction & 0x0c0) != 0x0c0)
2014 {
2015 mips16_entry (SD, CPU, cia, instruction);
2016 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
2017 }
2018 /* else fall through to normal exception processing */
2019 sim_io_eprintf(sd,"ReservedInstruction 0x%08X at PC = 0x%s\n",instruction,pr_addr(cia));
2020 }
2021
2022 case BreakPoint:
2023 #ifdef DEBUG
2024 sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
2025 #endif /* DEBUG */
2026 /* Keep a copy of the current A0 in-case this is the program exit
2027 breakpoint: */
2028 {
2029 va_list ap;
2030 unsigned int instruction;
2031 va_start(ap,exception);
2032 instruction = va_arg(ap,unsigned int);
2033 va_end(ap);
2034 /* Check for our special terminating BREAK: */
2035 if ((instruction & 0x03FFFFC0) == 0x03ff0000) {
2036 sim_engine_halt (SD, CPU, NULL, cia,
2037 sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
2038 }
2039 }
2040 if (STATE & simDELAYSLOT)
2041 PC = cia - 4; /* reference the branch instruction */
2042 else
2043 PC = cia;
2044 sim_engine_halt (SD, CPU, NULL, cia,
2045 sim_stopped, SIM_SIGTRAP);
2046
2047 default:
2048 /* Store exception code into current exception id variable (used
2049 by exit code): */
2050
2051 /* TODO: If not simulating exceptions then stop the simulator
2052 execution. At the moment we always stop the simulation. */
2053
2054 /* See figure 5-17 for an outline of the code below */
2055 if (! (SR & status_EXL))
2056 {
2057 CAUSE = (exception << 2);
2058 if (STATE & simDELAYSLOT)
2059 {
2060 STATE &= ~simDELAYSLOT;
2061 CAUSE |= cause_BD;
2062 EPC = (cia - 4); /* reference the branch instruction */
2063 }
2064 else
2065 EPC = cia;
2066 /* FIXME: TLB et.al. */
2067 vector = 0x180;
2068 }
2069 else
2070 {
2071 CAUSE = (exception << 2);
2072 vector = 0x180;
2073 }
2074 SR |= status_EXL;
2075 /* Store exception code into current exception id variable (used
2076 by exit code): */
2077 if (SR & status_BEV)
2078 PC = (signed)0xBFC00200 + 0x180;
2079 else
2080 PC = (signed)0x80000000 + 0x180;
2081
2082 switch ((CAUSE >> 2) & 0x1F)
2083 {
2084 case Interrupt:
2085 /* Interrupts arrive during event processing, no need to
2086 restart */
2087 return;
2088
2089 case TLBModification:
2090 case TLBLoad:
2091 case TLBStore:
2092 case AddressLoad:
2093 case AddressStore:
2094 case InstructionFetch:
2095 case DataReference:
2096 /* The following is so that the simulator will continue from the
2097 exception address on breakpoint operations. */
2098 PC = EPC;
2099 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
2100 sim_stopped, SIM_SIGBUS);
2101
2102 case ReservedInstruction:
2103 case CoProcessorUnusable:
2104 PC = EPC;
2105 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
2106 sim_stopped, SIM_SIGILL);
2107
2108 case IntegerOverflow:
2109 case FPE:
2110 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
2111 sim_stopped, SIM_SIGFPE);
2112
2113 case Trap:
2114 case Watch:
2115 case SystemCall:
2116 PC = EPC;
2117 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
2118 sim_stopped, SIM_SIGTRAP);
2119
2120 case BreakPoint:
2121 PC = EPC;
2122 sim_engine_abort (SD, CPU, NULL_CIA,
2123 "FATAL: Should not encounter a breakpoint\n");
2124
2125 default : /* Unknown internal exception */
2126 PC = EPC;
2127 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
2128 sim_stopped, SIM_SIGABRT);
2129
2130 }
2131
2132 case SimulatorFault:
2133 {
2134 va_list ap;
2135 char *msg;
2136 va_start(ap,exception);
2137 msg = va_arg(ap,char *);
2138 va_end(ap);
2139 sim_engine_abort (SD, CPU, NULL_CIA,
2140 "FATAL: Simulator error \"%s\"\n",msg);
2141 }
2142 }
2143
2144 return;
2145 }
2146
2147 #if defined(WARN_RESULT)
2148 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2149 /* This function indicates that the result of the operation is
2150 undefined. However, this should not affect the instruction
2151 stream. All that is meant to happen is that the destination
2152 register is set to an undefined result. To keep the simulator
2153 simple, we just don't bother updating the destination register, so
2154 the overall result will be undefined. If desired we can stop the
2155 simulator by raising a pseudo-exception. */
2156 #define UndefinedResult() undefined_result (sd,cia)
2157 static void
2158 undefined_result(sd,cia)
2159 SIM_DESC sd;
2160 address_word cia;
2161 {
2162 sim_io_eprintf(sd,"UndefinedResult: PC = 0x%s\n",pr_addr(cia));
2163 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2164 state |= simSTOP;
2165 #endif
2166 return;
2167 }
2168 #endif /* WARN_RESULT */
2169
2170 void
2171 cache_op (SIM_DESC sd,
2172 sim_cpu *cpu,
2173 address_word cia,
2174 int op,
2175 address_word pAddr,
2176 address_word vAddr,
2177 unsigned int instruction)
2178 {
2179 #if 1 /* stop warning message being displayed (we should really just remove the code) */
2180 static int icache_warning = 1;
2181 static int dcache_warning = 1;
2182 #else
2183 static int icache_warning = 0;
2184 static int dcache_warning = 0;
2185 #endif
2186
2187 /* If CP0 is not useable (User or Supervisor mode) and the CP0
2188 enable bit in the Status Register is clear - a coprocessor
2189 unusable exception is taken. */
2190 #if 0
2191 sim_io_printf(sd,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia));
2192 #endif
2193
2194 switch (op & 0x3) {
2195 case 0: /* instruction cache */
2196 switch (op >> 2) {
2197 case 0: /* Index Invalidate */
2198 case 1: /* Index Load Tag */
2199 case 2: /* Index Store Tag */
2200 case 4: /* Hit Invalidate */
2201 case 5: /* Fill */
2202 case 6: /* Hit Writeback */
2203 if (!icache_warning)
2204 {
2205 sim_io_eprintf(sd,"Instruction CACHE operation %d to be coded\n",(op >> 2));
2206 icache_warning = 1;
2207 }
2208 break;
2209
2210 default:
2211 SignalException(ReservedInstruction,instruction);
2212 break;
2213 }
2214 break;
2215
2216 case 1: /* data cache */
2217 switch (op >> 2) {
2218 case 0: /* Index Writeback Invalidate */
2219 case 1: /* Index Load Tag */
2220 case 2: /* Index Store Tag */
2221 case 3: /* Create Dirty */
2222 case 4: /* Hit Invalidate */
2223 case 5: /* Hit Writeback Invalidate */
2224 case 6: /* Hit Writeback */
2225 if (!dcache_warning)
2226 {
2227 sim_io_eprintf(sd,"Data CACHE operation %d to be coded\n",(op >> 2));
2228 dcache_warning = 1;
2229 }
2230 break;
2231
2232 default:
2233 SignalException(ReservedInstruction,instruction);
2234 break;
2235 }
2236 break;
2237
2238 default: /* unrecognised cache ID */
2239 SignalException(ReservedInstruction,instruction);
2240 break;
2241 }
2242
2243 return;
2244 }
2245
2246 /*-- FPU support routines ---------------------------------------------------*/
2247
2248 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
2249 formats conform to ANSI/IEEE Std 754-1985. */
2250 /* SINGLE precision floating:
2251 * seeeeeeeefffffffffffffffffffffff
2252 * s = 1bit = sign
2253 * e = 8bits = exponent
2254 * f = 23bits = fraction
2255 */
2256 /* SINGLE precision fixed:
2257 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2258 * s = 1bit = sign
2259 * i = 31bits = integer
2260 */
2261 /* DOUBLE precision floating:
2262 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
2263 * s = 1bit = sign
2264 * e = 11bits = exponent
2265 * f = 52bits = fraction
2266 */
2267 /* DOUBLE precision fixed:
2268 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2269 * s = 1bit = sign
2270 * i = 63bits = integer
2271 */
2272
2273 /* Extract sign-bit: */
2274 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
2275 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
2276 /* Extract biased exponent: */
2277 #define FP_S_be(v) (((v) >> 23) & 0xFF)
2278 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
2279 /* Extract unbiased Exponent: */
2280 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
2281 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
2282 /* Extract complete fraction field: */
2283 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
2284 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
2285 /* Extract numbered fraction bit: */
2286 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
2287 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
2288
2289 /* Explicit QNaN values used when value required: */
2290 #define FPQNaN_SINGLE (0x7FBFFFFF)
2291 #define FPQNaN_WORD (0x7FFFFFFF)
2292 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
2293 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
2294
2295 /* Explicit Infinity values used when required: */
2296 #define FPINF_SINGLE (0x7F800000)
2297 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
2298
2299 #if 1 /* def DEBUG */
2300 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
2301 #define DOFMT(v) (((v) == fmt_single) ? "single" : (((v) == fmt_double) ? "double" : (((v) == fmt_word) ? "word" : (((v) == fmt_long) ? "long" : (((v) == fmt_unknown) ? "<unknown>" : (((v) == fmt_uninterpreted) ? "<uninterpreted>" : "<format error>"))))))
2302 #endif /* DEBUG */
2303
2304 uword64
2305 value_fpr (SIM_DESC sd,
2306 sim_cpu *cpu,
2307 address_word cia,
2308 int fpr,
2309 FP_formats fmt)
2310 {
2311 uword64 value = 0;
2312 int err = 0;
2313
2314 /* Treat unused register values, as fixed-point 64bit values: */
2315 if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
2316 #if 1
2317 /* If request to read data as "uninterpreted", then use the current
2318 encoding: */
2319 fmt = FPR_STATE[fpr];
2320 #else
2321 fmt = fmt_long;
2322 #endif
2323
2324 /* For values not yet accessed, set to the desired format: */
2325 if (FPR_STATE[fpr] == fmt_uninterpreted) {
2326 FPR_STATE[fpr] = fmt;
2327 #ifdef DEBUG
2328 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr,DOFMT(fmt));
2329 #endif /* DEBUG */
2330 }
2331 if (fmt != FPR_STATE[fpr]) {
2332 sim_io_eprintf(sd,"FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",fpr,DOFMT(FPR_STATE[fpr]),DOFMT(fmt),pr_addr(cia));
2333 FPR_STATE[fpr] = fmt_unknown;
2334 }
2335
2336 if (FPR_STATE[fpr] == fmt_unknown) {
2337 /* Set QNaN value: */
2338 switch (fmt) {
2339 case fmt_single:
2340 value = FPQNaN_SINGLE;
2341 break;
2342
2343 case fmt_double:
2344 value = FPQNaN_DOUBLE;
2345 break;
2346
2347 case fmt_word:
2348 value = FPQNaN_WORD;
2349 break;
2350
2351 case fmt_long:
2352 value = FPQNaN_LONG;
2353 break;
2354
2355 default:
2356 err = -1;
2357 break;
2358 }
2359 } else if (SizeFGR() == 64) {
2360 switch (fmt) {
2361 case fmt_single:
2362 case fmt_word:
2363 value = (FGR[fpr] & 0xFFFFFFFF);
2364 break;
2365
2366 case fmt_uninterpreted:
2367 case fmt_double:
2368 case fmt_long:
2369 value = FGR[fpr];
2370 break;
2371
2372 default :
2373 err = -1;
2374 break;
2375 }
2376 } else {
2377 switch (fmt) {
2378 case fmt_single:
2379 case fmt_word:
2380 value = (FGR[fpr] & 0xFFFFFFFF);
2381 break;
2382
2383 case fmt_uninterpreted:
2384 case fmt_double:
2385 case fmt_long:
2386 if ((fpr & 1) == 0) { /* even registers only */
2387 value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF));
2388 } else {
2389 SignalException(ReservedInstruction,0);
2390 }
2391 break;
2392
2393 default :
2394 err = -1;
2395 break;
2396 }
2397 }
2398
2399 if (err)
2400 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2401
2402 #ifdef DEBUG
2403 printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_addr(value),pr_addr(cia),SizeFGR());
2404 #endif /* DEBUG */
2405
2406 return(value);
2407 }
2408
2409 void
2410 store_fpr (SIM_DESC sd,
2411 sim_cpu *cpu,
2412 address_word cia,
2413 int fpr,
2414 FP_formats fmt,
2415 uword64 value)
2416 {
2417 int err = 0;
2418
2419 #ifdef DEBUG
2420 printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_addr(value),pr_addr(cia),SizeFGR());
2421 #endif /* DEBUG */
2422
2423 if (SizeFGR() == 64) {
2424 switch (fmt) {
2425 case fmt_uninterpreted_32:
2426 fmt = fmt_uninterpreted;
2427 case fmt_single :
2428 case fmt_word :
2429 FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
2430 FPR_STATE[fpr] = fmt;
2431 break;
2432
2433 case fmt_uninterpreted_64:
2434 fmt = fmt_uninterpreted;
2435 case fmt_uninterpreted:
2436 case fmt_double :
2437 case fmt_long :
2438 FGR[fpr] = value;
2439 FPR_STATE[fpr] = fmt;
2440 break;
2441
2442 default :
2443 FPR_STATE[fpr] = fmt_unknown;
2444 err = -1;
2445 break;
2446 }
2447 } else {
2448 switch (fmt) {
2449 case fmt_uninterpreted_32:
2450 fmt = fmt_uninterpreted;
2451 case fmt_single :
2452 case fmt_word :
2453 FGR[fpr] = (value & 0xFFFFFFFF);
2454 FPR_STATE[fpr] = fmt;
2455 break;
2456
2457 case fmt_uninterpreted_64:
2458 fmt = fmt_uninterpreted;
2459 case fmt_uninterpreted:
2460 case fmt_double :
2461 case fmt_long :
2462 if ((fpr & 1) == 0) { /* even register number only */
2463 FGR[fpr+1] = (value >> 32);
2464 FGR[fpr] = (value & 0xFFFFFFFF);
2465 FPR_STATE[fpr + 1] = fmt;
2466 FPR_STATE[fpr] = fmt;
2467 } else {
2468 FPR_STATE[fpr] = fmt_unknown;
2469 FPR_STATE[fpr + 1] = fmt_unknown;
2470 SignalException(ReservedInstruction,0);
2471 }
2472 break;
2473
2474 default :
2475 FPR_STATE[fpr] = fmt_unknown;
2476 err = -1;
2477 break;
2478 }
2479 }
2480 #if defined(WARN_RESULT)
2481 else
2482 UndefinedResult();
2483 #endif /* WARN_RESULT */
2484
2485 if (err)
2486 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2487
2488 #ifdef DEBUG
2489 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_addr(FGR[fpr]),DOFMT(fmt));
2490 #endif /* DEBUG */
2491
2492 return;
2493 }
2494
2495 int
2496 NaN(op,fmt)
2497 uword64 op;
2498 FP_formats fmt;
2499 {
2500 int boolean = 0;
2501 switch (fmt) {
2502 case fmt_single:
2503 case fmt_word:
2504 {
2505 sim_fpu wop;
2506 sim_fpu_32to (&wop, op);
2507 boolean = sim_fpu_is_nan (&wop);
2508 break;
2509 }
2510 case fmt_double:
2511 case fmt_long:
2512 {
2513 sim_fpu wop;
2514 sim_fpu_64to (&wop, op);
2515 boolean = sim_fpu_is_nan (&wop);
2516 break;
2517 }
2518 default:
2519 fprintf (stderr, "Bad switch\n");
2520 abort ();
2521 }
2522
2523 #ifdef DEBUG
2524 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
2525 #endif /* DEBUG */
2526
2527 return(boolean);
2528 }
2529
2530 int
2531 Infinity(op,fmt)
2532 uword64 op;
2533 FP_formats fmt;
2534 {
2535 int boolean = 0;
2536
2537 #ifdef DEBUG
2538 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt),pr_addr(op));
2539 #endif /* DEBUG */
2540
2541 switch (fmt) {
2542 case fmt_single:
2543 {
2544 sim_fpu wop;
2545 sim_fpu_32to (&wop, op);
2546 boolean = sim_fpu_is_infinity (&wop);
2547 break;
2548 }
2549 case fmt_double:
2550 {
2551 sim_fpu wop;
2552 sim_fpu_64to (&wop, op);
2553 boolean = sim_fpu_is_infinity (&wop);
2554 break;
2555 }
2556 default:
2557 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt));
2558 break;
2559 }
2560
2561 #ifdef DEBUG
2562 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
2563 #endif /* DEBUG */
2564
2565 return(boolean);
2566 }
2567
2568 int
2569 Less(op1,op2,fmt)
2570 uword64 op1;
2571 uword64 op2;
2572 FP_formats fmt;
2573 {
2574 int boolean = 0;
2575
2576 /* Argument checking already performed by the FPCOMPARE code */
2577
2578 #ifdef DEBUG
2579 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2580 #endif /* DEBUG */
2581
2582 /* The format type should already have been checked: */
2583 switch (fmt) {
2584 case fmt_single:
2585 {
2586 sim_fpu wop1;
2587 sim_fpu wop2;
2588 sim_fpu_32to (&wop1, op1);
2589 sim_fpu_32to (&wop2, op2);
2590 boolean = sim_fpu_is_lt (&wop1, &wop2);
2591 break;
2592 }
2593 case fmt_double:
2594 {
2595 sim_fpu wop1;
2596 sim_fpu wop2;
2597 sim_fpu_64to (&wop1, op1);
2598 sim_fpu_64to (&wop2, op2);
2599 boolean = sim_fpu_is_lt (&wop1, &wop2);
2600 break;
2601 }
2602 default:
2603 fprintf (stderr, "Bad switch\n");
2604 abort ();
2605 }
2606
2607 #ifdef DEBUG
2608 printf("DBG: Less: returning %d (format = %s)\n",boolean,DOFMT(fmt));
2609 #endif /* DEBUG */
2610
2611 return(boolean);
2612 }
2613
2614 int
2615 Equal(op1,op2,fmt)
2616 uword64 op1;
2617 uword64 op2;
2618 FP_formats fmt;
2619 {
2620 int boolean = 0;
2621
2622 /* Argument checking already performed by the FPCOMPARE code */
2623
2624 #ifdef DEBUG
2625 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2626 #endif /* DEBUG */
2627
2628 /* The format type should already have been checked: */
2629 switch (fmt) {
2630 case fmt_single:
2631 {
2632 sim_fpu wop1;
2633 sim_fpu wop2;
2634 sim_fpu_32to (&wop1, op1);
2635 sim_fpu_32to (&wop2, op2);
2636 boolean = sim_fpu_is_eq (&wop1, &wop2);
2637 break;
2638 }
2639 case fmt_double:
2640 {
2641 sim_fpu wop1;
2642 sim_fpu wop2;
2643 sim_fpu_64to (&wop1, op1);
2644 sim_fpu_64to (&wop2, op2);
2645 boolean = sim_fpu_is_eq (&wop1, &wop2);
2646 break;
2647 }
2648 default:
2649 fprintf (stderr, "Bad switch\n");
2650 abort ();
2651 }
2652
2653 #ifdef DEBUG
2654 printf("DBG: Equal: returning %d (format = %s)\n",boolean,DOFMT(fmt));
2655 #endif /* DEBUG */
2656
2657 return(boolean);
2658 }
2659
2660 uword64
2661 AbsoluteValue(op,fmt)
2662 uword64 op;
2663 FP_formats fmt;
2664 {
2665 uword64 result = 0;
2666
2667 #ifdef DEBUG
2668 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2669 #endif /* DEBUG */
2670
2671 /* The format type should already have been checked: */
2672 switch (fmt) {
2673 case fmt_single:
2674 {
2675 sim_fpu wop;
2676 unsigned32 ans;
2677 sim_fpu_32to (&wop, op);
2678 sim_fpu_abs (&wop, &wop);
2679 sim_fpu_to32 (&ans, &wop);
2680 result = ans;
2681 break;
2682 }
2683 case fmt_double:
2684 {
2685 sim_fpu wop;
2686 unsigned64 ans;
2687 sim_fpu_64to (&wop, op);
2688 sim_fpu_abs (&wop, &wop);
2689 sim_fpu_to64 (&ans, &wop);
2690 result = ans;
2691 break;
2692 }
2693 default:
2694 fprintf (stderr, "Bad switch\n");
2695 abort ();
2696 }
2697
2698 return(result);
2699 }
2700
2701 uword64
2702 Negate(op,fmt)
2703 uword64 op;
2704 FP_formats fmt;
2705 {
2706 uword64 result = 0;
2707
2708 #ifdef DEBUG
2709 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2710 #endif /* DEBUG */
2711
2712 /* The format type should already have been checked: */
2713 switch (fmt) {
2714 case fmt_single:
2715 {
2716 sim_fpu wop;
2717 unsigned32 ans;
2718 sim_fpu_32to (&wop, op);
2719 sim_fpu_neg (&wop, &wop);
2720 sim_fpu_to32 (&ans, &wop);
2721 result = ans;
2722 break;
2723 }
2724 case fmt_double:
2725 {
2726 sim_fpu wop;
2727 unsigned64 ans;
2728 sim_fpu_64to (&wop, op);
2729 sim_fpu_neg (&wop, &wop);
2730 sim_fpu_to64 (&ans, &wop);
2731 result = ans;
2732 break;
2733 }
2734 default:
2735 fprintf (stderr, "Bad switch\n");
2736 abort ();
2737 }
2738
2739 return(result);
2740 }
2741
2742 uword64
2743 Add(op1,op2,fmt)
2744 uword64 op1;
2745 uword64 op2;
2746 FP_formats fmt;
2747 {
2748 uword64 result = 0;
2749
2750 #ifdef DEBUG
2751 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2752 #endif /* DEBUG */
2753
2754 /* The registers must specify FPRs valid for operands of type
2755 "fmt". If they are not valid, the result is undefined. */
2756
2757 /* The format type should already have been checked: */
2758 switch (fmt) {
2759 case fmt_single:
2760 {
2761 sim_fpu wop1;
2762 sim_fpu wop2;
2763 sim_fpu ans;
2764 unsigned32 res;
2765 sim_fpu_32to (&wop1, op1);
2766 sim_fpu_32to (&wop2, op2);
2767 sim_fpu_add (&ans, &wop1, &wop2);
2768 sim_fpu_to32 (&res, &ans);
2769 result = res;
2770 break;
2771 }
2772 case fmt_double:
2773 {
2774 sim_fpu wop1;
2775 sim_fpu wop2;
2776 sim_fpu ans;
2777 unsigned64 res;
2778 sim_fpu_64to (&wop1, op1);
2779 sim_fpu_64to (&wop2, op2);
2780 sim_fpu_add (&ans, &wop1, &wop2);
2781 sim_fpu_to64 (&res, &ans);
2782 result = res;
2783 break;
2784 }
2785 default:
2786 fprintf (stderr, "Bad switch\n");
2787 abort ();
2788 }
2789
2790 #ifdef DEBUG
2791 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2792 #endif /* DEBUG */
2793
2794 return(result);
2795 }
2796
2797 uword64
2798 Sub(op1,op2,fmt)
2799 uword64 op1;
2800 uword64 op2;
2801 FP_formats fmt;
2802 {
2803 uword64 result = 0;
2804
2805 #ifdef DEBUG
2806 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2807 #endif /* DEBUG */
2808
2809 /* The registers must specify FPRs valid for operands of type
2810 "fmt". If they are not valid, the result is undefined. */
2811
2812 /* The format type should already have been checked: */
2813 switch (fmt) {
2814 case fmt_single:
2815 {
2816 sim_fpu wop1;
2817 sim_fpu wop2;
2818 sim_fpu ans;
2819 unsigned32 res;
2820 sim_fpu_32to (&wop1, op1);
2821 sim_fpu_32to (&wop2, op2);
2822 sim_fpu_sub (&ans, &wop1, &wop2);
2823 sim_fpu_to32 (&res, &ans);
2824 result = res;
2825 }
2826 break;
2827 case fmt_double:
2828 {
2829 sim_fpu wop1;
2830 sim_fpu wop2;
2831 sim_fpu ans;
2832 unsigned64 res;
2833 sim_fpu_64to (&wop1, op1);
2834 sim_fpu_64to (&wop2, op2);
2835 sim_fpu_sub (&ans, &wop1, &wop2);
2836 sim_fpu_to64 (&res, &ans);
2837 result = res;
2838 }
2839 break;
2840 default:
2841 fprintf (stderr, "Bad switch\n");
2842 abort ();
2843 }
2844
2845 #ifdef DEBUG
2846 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2847 #endif /* DEBUG */
2848
2849 return(result);
2850 }
2851
2852 uword64
2853 Multiply(op1,op2,fmt)
2854 uword64 op1;
2855 uword64 op2;
2856 FP_formats fmt;
2857 {
2858 uword64 result = 0;
2859
2860 #ifdef DEBUG
2861 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2862 #endif /* DEBUG */
2863
2864 /* The registers must specify FPRs valid for operands of type
2865 "fmt". If they are not valid, the result is undefined. */
2866
2867 /* The format type should already have been checked: */
2868 switch (fmt) {
2869 case fmt_single:
2870 {
2871 sim_fpu wop1;
2872 sim_fpu wop2;
2873 sim_fpu ans;
2874 unsigned32 res;
2875 sim_fpu_32to (&wop1, op1);
2876 sim_fpu_32to (&wop2, op2);
2877 sim_fpu_mul (&ans, &wop1, &wop2);
2878 sim_fpu_to32 (&res, &ans);
2879 result = res;
2880 break;
2881 }
2882 case fmt_double:
2883 {
2884 sim_fpu wop1;
2885 sim_fpu wop2;
2886 sim_fpu ans;
2887 unsigned64 res;
2888 sim_fpu_64to (&wop1, op1);
2889 sim_fpu_64to (&wop2, op2);
2890 sim_fpu_mul (&ans, &wop1, &wop2);
2891 sim_fpu_to64 (&res, &ans);
2892 result = res;
2893 break;
2894 }
2895 default:
2896 fprintf (stderr, "Bad switch\n");
2897 abort ();
2898 }
2899
2900 #ifdef DEBUG
2901 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2902 #endif /* DEBUG */
2903
2904 return(result);
2905 }
2906
2907 uword64
2908 Divide(op1,op2,fmt)
2909 uword64 op1;
2910 uword64 op2;
2911 FP_formats fmt;
2912 {
2913 uword64 result = 0;
2914
2915 #ifdef DEBUG
2916 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2917 #endif /* DEBUG */
2918
2919 /* The registers must specify FPRs valid for operands of type
2920 "fmt". If they are not valid, the result is undefined. */
2921
2922 /* The format type should already have been checked: */
2923 switch (fmt) {
2924 case fmt_single:
2925 {
2926 sim_fpu wop1;
2927 sim_fpu wop2;
2928 sim_fpu ans;
2929 unsigned32 res;
2930 sim_fpu_32to (&wop1, op1);
2931 sim_fpu_32to (&wop2, op2);
2932 sim_fpu_div (&ans, &wop1, &wop2);
2933 sim_fpu_to32 (&res, &ans);
2934 result = res;
2935 break;
2936 }
2937 case fmt_double:
2938 {
2939 sim_fpu wop1;
2940 sim_fpu wop2;
2941 sim_fpu ans;
2942 unsigned64 res;
2943 sim_fpu_64to (&wop1, op1);
2944 sim_fpu_64to (&wop2, op2);
2945 sim_fpu_div (&ans, &wop1, &wop2);
2946 sim_fpu_to64 (&res, &ans);
2947 result = res;
2948 break;
2949 }
2950 default:
2951 fprintf (stderr, "Bad switch\n");
2952 abort ();
2953 }
2954
2955 #ifdef DEBUG
2956 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2957 #endif /* DEBUG */
2958
2959 return(result);
2960 }
2961
2962 uword64 UNUSED
2963 Recip(op,fmt)
2964 uword64 op;
2965 FP_formats fmt;
2966 {
2967 uword64 result = 0;
2968
2969 #ifdef DEBUG
2970 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2971 #endif /* DEBUG */
2972
2973 /* The registers must specify FPRs valid for operands of type
2974 "fmt". If they are not valid, the result is undefined. */
2975
2976 /* The format type should already have been checked: */
2977 switch (fmt) {
2978 case fmt_single:
2979 {
2980 sim_fpu wop;
2981 sim_fpu ans;
2982 unsigned32 res;
2983 sim_fpu_32to (&wop, op);
2984 sim_fpu_inv (&ans, &wop);
2985 sim_fpu_to32 (&res, &ans);
2986 result = res;
2987 break;
2988 }
2989 case fmt_double:
2990 {
2991 sim_fpu wop;
2992 sim_fpu ans;
2993 unsigned64 res;
2994 sim_fpu_64to (&wop, op);
2995 sim_fpu_inv (&ans, &wop);
2996 sim_fpu_to64 (&res, &ans);
2997 result = res;
2998 break;
2999 }
3000 default:
3001 fprintf (stderr, "Bad switch\n");
3002 abort ();
3003 }
3004
3005 #ifdef DEBUG
3006 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3007 #endif /* DEBUG */
3008
3009 return(result);
3010 }
3011
3012 uword64
3013 SquareRoot(op,fmt)
3014 uword64 op;
3015 FP_formats fmt;
3016 {
3017 uword64 result = 0;
3018
3019 #ifdef DEBUG
3020 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
3021 #endif /* DEBUG */
3022
3023 /* The registers must specify FPRs valid for operands of type
3024 "fmt". If they are not valid, the result is undefined. */
3025
3026 /* The format type should already have been checked: */
3027 switch (fmt) {
3028 case fmt_single:
3029 {
3030 sim_fpu wop;
3031 sim_fpu ans;
3032 unsigned32 res;
3033 sim_fpu_32to (&wop, op);
3034 sim_fpu_sqrt (&ans, &wop);
3035 sim_fpu_to32 (&res, &ans);
3036 result = res;
3037 break;
3038 }
3039 case fmt_double:
3040 {
3041 sim_fpu wop;
3042 sim_fpu ans;
3043 unsigned64 res;
3044 sim_fpu_64to (&wop, op);
3045 sim_fpu_sqrt (&ans, &wop);
3046 sim_fpu_to64 (&res, &ans);
3047 result = res;
3048 break;
3049 }
3050 default:
3051 fprintf (stderr, "Bad switch\n");
3052 abort ();
3053 }
3054
3055 #ifdef DEBUG
3056 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3057 #endif /* DEBUG */
3058
3059 return(result);
3060 }
3061
3062 #if 0
3063 uword64
3064 Max (uword64 op1,
3065 uword64 op2,
3066 FP_formats fmt)
3067 {
3068 int cmp;
3069 unsigned64 result;
3070
3071 #ifdef DEBUG
3072 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3073 #endif /* DEBUG */
3074
3075 /* The registers must specify FPRs valid for operands of type
3076 "fmt". If they are not valid, the result is undefined. */
3077
3078 /* The format type should already have been checked: */
3079 switch (fmt)
3080 {
3081 case fmt_single:
3082 {
3083 sim_fpu wop1;
3084 sim_fpu wop2;
3085 sim_fpu_32to (&wop1, op1);
3086 sim_fpu_32to (&wop2, op2);
3087 cmp = sim_fpu_cmp (&wop1, &wop2);
3088 break;
3089 }
3090 case fmt_double:
3091 {
3092 sim_fpu wop1;
3093 sim_fpu wop2;
3094 sim_fpu_64to (&wop1, op1);
3095 sim_fpu_64to (&wop2, op2);
3096 cmp = sim_fpu_cmp (&wop1, &wop2);
3097 break;
3098 }
3099 default:
3100 fprintf (stderr, "Bad switch\n");
3101 abort ();
3102 }
3103
3104 switch (cmp)
3105 {
3106 case SIM_FPU_IS_SNAN:
3107 case SIM_FPU_IS_QNAN:
3108 result = op1;
3109 case SIM_FPU_IS_NINF:
3110 case SIM_FPU_IS_NNUMBER:
3111 case SIM_FPU_IS_NDENORM:
3112 case SIM_FPU_IS_NZERO:
3113 result = op2; /* op1 - op2 < 0 */
3114 case SIM_FPU_IS_PINF:
3115 case SIM_FPU_IS_PNUMBER:
3116 case SIM_FPU_IS_PDENORM:
3117 case SIM_FPU_IS_PZERO:
3118 result = op1; /* op1 - op2 > 0 */
3119 default:
3120 fprintf (stderr, "Bad switch\n");
3121 abort ();
3122 }
3123
3124 #ifdef DEBUG
3125 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3126 #endif /* DEBUG */
3127
3128 return(result);
3129 }
3130 #endif
3131
3132 #if 0
3133 uword64
3134 Min (uword64 op1,
3135 uword64 op2,
3136 FP_formats fmt)
3137 {
3138 int cmp;
3139 unsigned64 result;
3140
3141 #ifdef DEBUG
3142 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
3143 #endif /* DEBUG */
3144
3145 /* The registers must specify FPRs valid for operands of type
3146 "fmt". If they are not valid, the result is undefined. */
3147
3148 /* The format type should already have been checked: */
3149 switch (fmt)
3150 {
3151 case fmt_single:
3152 {
3153 sim_fpu wop1;
3154 sim_fpu wop2;
3155 sim_fpu_32to (&wop1, op1);
3156 sim_fpu_32to (&wop2, op2);
3157 cmp = sim_fpu_cmp (&wop1, &wop2);
3158 break;
3159 }
3160 case fmt_double:
3161 {
3162 sim_fpu wop1;
3163 sim_fpu wop2;
3164 sim_fpu_64to (&wop1, op1);
3165 sim_fpu_64to (&wop2, op2);
3166 cmp = sim_fpu_cmp (&wop1, &wop2);
3167 break;
3168 }
3169 default:
3170 fprintf (stderr, "Bad switch\n");
3171 abort ();
3172 }
3173
3174 switch (cmp)
3175 {
3176 case SIM_FPU_IS_SNAN:
3177 case SIM_FPU_IS_QNAN:
3178 result = op1;
3179 case SIM_FPU_IS_NINF:
3180 case SIM_FPU_IS_NNUMBER:
3181 case SIM_FPU_IS_NDENORM:
3182 case SIM_FPU_IS_NZERO:
3183 result = op1; /* op1 - op2 < 0 */
3184 case SIM_FPU_IS_PINF:
3185 case SIM_FPU_IS_PNUMBER:
3186 case SIM_FPU_IS_PDENORM:
3187 case SIM_FPU_IS_PZERO:
3188 result = op2; /* op1 - op2 > 0 */
3189 default:
3190 fprintf (stderr, "Bad switch\n");
3191 abort ();
3192 }
3193
3194 #ifdef DEBUG
3195 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
3196 #endif /* DEBUG */
3197
3198 return(result);
3199 }
3200 #endif
3201
3202 uword64
3203 convert (SIM_DESC sd,
3204 sim_cpu *cpu,
3205 address_word cia,
3206 int rm,
3207 uword64 op,
3208 FP_formats from,
3209 FP_formats to)
3210 {
3211 sim_fpu wop;
3212 sim_fpu_round round;
3213 unsigned32 result32;
3214 unsigned64 result64;
3215
3216 #ifdef DEBUG
3217 printf("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",RMMODE(rm),pr_addr(op),DOFMT(from),DOFMT(to),pr_addr(IPC));
3218 #endif /* DEBUG */
3219
3220 switch (rm)
3221 {
3222 case FP_RM_NEAREST:
3223 /* Round result to nearest representable value. When two
3224 representable values are equally near, round to the value
3225 that has a least significant bit of zero (i.e. is even). */
3226 round = sim_fpu_round_near;
3227 break;
3228 case FP_RM_TOZERO:
3229 /* Round result to the value closest to, and not greater in
3230 magnitude than, the result. */
3231 round = sim_fpu_round_zero;
3232 break;
3233 case FP_RM_TOPINF:
3234 /* Round result to the value closest to, and not less than,
3235 the result. */
3236 round = sim_fpu_round_up;
3237 break;
3238
3239 case FP_RM_TOMINF:
3240 /* Round result to the value closest to, and not greater than,
3241 the result. */
3242 round = sim_fpu_round_down;
3243 break;
3244 default:
3245 round = 0;
3246 fprintf (stderr, "Bad switch\n");
3247 abort ();
3248 }
3249
3250 /* Convert the input to sim_fpu internal format */
3251 switch (from)
3252 {
3253 case fmt_double:
3254 sim_fpu_64to (&wop, op);
3255 break;
3256 case fmt_single:
3257 sim_fpu_32to (&wop, op);
3258 break;
3259 case fmt_word:
3260 sim_fpu_i32to (&wop, op, round);
3261 break;
3262 case fmt_long:
3263 sim_fpu_i64to (&wop, op, round);
3264 break;
3265 default:
3266 fprintf (stderr, "Bad switch\n");
3267 abort ();
3268 }
3269
3270 /* Convert sim_fpu format into the output */
3271 /* The value WOP is converted to the destination format, rounding
3272 using mode RM. When the destination is a fixed-point format, then
3273 a source value of Infinity, NaN or one which would round to an
3274 integer outside the fixed point range then an IEEE Invalid
3275 Operation condition is raised. */
3276 switch (to)
3277 {
3278 case fmt_single:
3279 sim_fpu_round_32 (&wop, round, 0);
3280 sim_fpu_to32 (&result32, &wop);
3281 result64 = result32;
3282 break;
3283 case fmt_double:
3284 sim_fpu_round_64 (&wop, round, 0);
3285 sim_fpu_to64 (&result64, &wop);
3286 break;
3287 case fmt_word:
3288 sim_fpu_to32i (&result32, &wop, round);
3289 result64 = result32;
3290 break;
3291 case fmt_long:
3292 sim_fpu_to64i (&result64, &wop, round);
3293 break;
3294 default:
3295 result64 = 0;
3296 fprintf (stderr, "Bad switch\n");
3297 abort ();
3298 }
3299
3300 #ifdef DEBUG
3301 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64),DOFMT(to));
3302 #endif /* DEBUG */
3303
3304 return(result64);
3305 }
3306
3307
3308 /*-- co-processor support routines ------------------------------------------*/
3309
3310 static int UNUSED
3311 CoProcPresent(coproc_number)
3312 unsigned int coproc_number;
3313 {
3314 /* Return TRUE if simulator provides a model for the given co-processor number */
3315 return(0);
3316 }
3317
3318 void
3319 cop_lw (SIM_DESC sd,
3320 sim_cpu *cpu,
3321 address_word cia,
3322 int coproc_num,
3323 int coproc_reg,
3324 unsigned int memword)
3325 {
3326 switch (coproc_num)
3327 {
3328 case 1:
3329 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3330 {
3331 #ifdef DEBUG
3332 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
3333 #endif
3334 StoreFPR(coproc_reg,fmt_word,(uword64)memword);
3335 FPR_STATE[coproc_reg] = fmt_uninterpreted;
3336 break;
3337 }
3338
3339 default:
3340 #if 0 /* this should be controlled by a configuration option */
3341 sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(cia));
3342 #endif
3343 break;
3344 }
3345
3346 return;
3347 }
3348
3349 void
3350 cop_ld (SIM_DESC sd,
3351 sim_cpu *cpu,
3352 address_word cia,
3353 int coproc_num,
3354 int coproc_reg,
3355 uword64 memword)
3356 {
3357 switch (coproc_num) {
3358 case 1:
3359 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3360 {
3361 StoreFPR(coproc_reg,fmt_uninterpreted,memword);
3362 break;
3363 }
3364
3365 default:
3366 #if 0 /* this message should be controlled by a configuration option */
3367 sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(cia));
3368 #endif
3369 break;
3370 }
3371
3372 return;
3373 }
3374
3375
3376 /* start-sanitize-sky */
3377 #ifdef TARGET_SKY
3378 void
3379 cop_lq (SIM_DESC sd,
3380 sim_cpu *cpu,
3381 address_word cia,
3382 int coproc_num,
3383 int coproc_reg,
3384 unsigned128 memword)
3385 {
3386 switch (coproc_num)
3387 {
3388 case 2:
3389 /* XXX COP2 */
3390 break;
3391
3392 default:
3393 sim_io_printf(sd,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3394 coproc_num,coproc_reg,pr_addr(cia));
3395 break;
3396 }
3397
3398 return;
3399 }
3400 #endif /* TARGET_SKY */
3401 /* end-sanitize-sky */
3402
3403
3404 unsigned int
3405 cop_sw (SIM_DESC sd,
3406 sim_cpu *cpu,
3407 address_word cia,
3408 int coproc_num,
3409 int coproc_reg)
3410 {
3411 unsigned int value = 0;
3412
3413 switch (coproc_num)
3414 {
3415 case 1:
3416 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3417 {
3418 FP_formats hold;
3419 hold = FPR_STATE[coproc_reg];
3420 FPR_STATE[coproc_reg] = fmt_word;
3421 value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
3422 FPR_STATE[coproc_reg] = hold;
3423 break;
3424 }
3425
3426 default:
3427 #if 0 /* should be controlled by configuration option */
3428 sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
3429 #endif
3430 break;
3431 }
3432
3433 return(value);
3434 }
3435
3436 uword64
3437 cop_sd (SIM_DESC sd,
3438 sim_cpu *cpu,
3439 address_word cia,
3440 int coproc_num,
3441 int coproc_reg)
3442 {
3443 uword64 value = 0;
3444 switch (coproc_num)
3445 {
3446 case 1:
3447 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3448 {
3449 value = ValueFPR(coproc_reg,fmt_uninterpreted);
3450 break;
3451 }
3452
3453 default:
3454 #if 0 /* should be controlled by configuration option */
3455 sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
3456 #endif
3457 break;
3458 }
3459
3460 return(value);
3461 }
3462
3463
3464 /* start-sanitize-sky */
3465 #ifdef TARGET_SKY
3466 unsigned128
3467 cop_sq (SIM_DESC sd,
3468 sim_cpu *cpu,
3469 address_word cia,
3470 int coproc_num,
3471 int coproc_reg)
3472 {
3473 unsigned128 value = U16_8(0, 0);
3474 switch (coproc_num)
3475 {
3476 case 2:
3477 /* XXX COP2 */
3478 break;
3479
3480 default:
3481 sim_io_printf(sd,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3482 coproc_num,coproc_reg,pr_addr(cia));
3483 break;
3484 }
3485
3486 return(value);
3487 }
3488 #endif /* TARGET_SKY */
3489 /* end-sanitize-sky */
3490
3491
3492 void
3493 decode_coproc (SIM_DESC sd,
3494 sim_cpu *cpu,
3495 address_word cia,
3496 unsigned int instruction)
3497 {
3498 int coprocnum = ((instruction >> 26) & 3);
3499
3500 switch (coprocnum)
3501 {
3502 case 0: /* standard CPU control and cache registers */
3503 {
3504 int code = ((instruction >> 21) & 0x1F);
3505 /* R4000 Users Manual (second edition) lists the following CP0
3506 instructions:
3507 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3508 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3509 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3510 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3511 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3512 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3513 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3514 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3515 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3516 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3517 */
3518 if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0))
3519 {
3520 int rt = ((instruction >> 16) & 0x1F);
3521 int rd = ((instruction >> 11) & 0x1F);
3522
3523 switch (rd) /* NOTEs: Standard CP0 registers */
3524 {
3525 /* 0 = Index R4000 VR4100 VR4300 */
3526 /* 1 = Random R4000 VR4100 VR4300 */
3527 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3528 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3529 /* 4 = Context R4000 VR4100 VR4300 */
3530 /* 5 = PageMask R4000 VR4100 VR4300 */
3531 /* 6 = Wired R4000 VR4100 VR4300 */
3532 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3533 /* 9 = Count R4000 VR4100 VR4300 */
3534 /* 10 = EntryHi R4000 VR4100 VR4300 */
3535 /* 11 = Compare R4000 VR4100 VR4300 */
3536 /* 12 = SR R4000 VR4100 VR4300 */
3537 case 12:
3538 if (code == 0x00)
3539 GPR[rt] = SR;
3540 else
3541 SR = GPR[rt];
3542 break;
3543 /* 13 = Cause R4000 VR4100 VR4300 */
3544 case 13:
3545 if (code == 0x00)
3546 GPR[rt] = CAUSE;
3547 else
3548 CAUSE = GPR[rt];
3549 break;
3550 /* 14 = EPC R4000 VR4100 VR4300 */
3551 /* 15 = PRId R4000 VR4100 VR4300 */
3552 #ifdef SUBTARGET_R3900
3553 /* 16 = Debug */
3554 case 16:
3555 if (code == 0x00)
3556 GPR[rt] = Debug;
3557 else
3558 Debug = GPR[rt];
3559 break;
3560 #else
3561 /* 16 = Config R4000 VR4100 VR4300 */
3562 case 16:
3563 if (code == 0x00)
3564 GPR[rt] = C0_CONFIG;
3565 else
3566 C0_CONFIG = GPR[rt];
3567 break;
3568 #endif
3569 #ifdef SUBTARGET_R3900
3570 /* 17 = Debug */
3571 case 17:
3572 if (code == 0x00)
3573 GPR[rt] = DEPC;
3574 else
3575 DEPC = GPR[rt];
3576 break;
3577 #else
3578 /* 17 = LLAddr R4000 VR4100 VR4300 */
3579 #endif
3580 /* 18 = WatchLo R4000 VR4100 VR4300 */
3581 /* 19 = WatchHi R4000 VR4100 VR4300 */
3582 /* 20 = XContext R4000 VR4100 VR4300 */
3583 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3584 /* 27 = CacheErr R4000 VR4100 */
3585 /* 28 = TagLo R4000 VR4100 VR4300 */
3586 /* 29 = TagHi R4000 VR4100 VR4300 */
3587 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3588 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
3589 /* CPR[0,rd] = GPR[rt]; */
3590 default:
3591 if (code == 0x00)
3592 sim_io_printf(sd,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt,rd);
3593 else
3594 sim_io_printf(sd,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt,rd);
3595 }
3596 }
3597 else if (code == 0x10 && (instruction & 0x3f) == 0x18)
3598 {
3599 /* ERET */
3600 if (SR & status_ERL)
3601 {
3602 /* Oops, not yet available */
3603 sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
3604 PC = EPC;
3605 SR &= ~status_ERL;
3606 }
3607 else
3608 {
3609 PC = EPC;
3610 SR &= ~status_EXL;
3611 }
3612 }
3613 else if (code == 0x10 && (instruction & 0x3f) == 0x10)
3614 {
3615 /* RFE */
3616 }
3617 else if (code == 0x10 && (instruction & 0x3f) == 0x1F)
3618 {
3619 /* DERET */
3620 Debug &= ~Debug_DM;
3621 DELAYSLOT();
3622 DSPC = DEPC;
3623 }
3624 else
3625 sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
3626 /* TODO: When executing an ERET or RFE instruction we should
3627 clear LLBIT, to ensure that any out-standing atomic
3628 read/modify/write sequence fails. */
3629 }
3630 break;
3631
3632 case 2: /* undefined co-processor */
3633 {
3634 int handle = 0;
3635
3636 /* start-sanitize-sky */
3637 #ifdef TARGET_SKY
3638 /* On the R5900, this refers to a "VU" vector co-processor. */
3639
3640 int i_25_21 = (instruction >> 21) & 0x1f;
3641 int i_20_16 = (instruction >> 16) & 0x1f;
3642 int i_15_11 = (instruction >> 11) & 0x1f;
3643 int i_15_0 = instruction & 0xffff;
3644 int i_10_1 = (instruction >> 1) & 0x3ff;
3645 int i_5_0 = instruction & 0x03f;
3646 int interlock = instruction & 0x01;
3647 int co = (instruction >> 25) & 0x01;
3648 /* setup for semantic.c-like actions below */
3649 typedef unsigned_4 instruction_word;
3650 int CIA = cia;
3651 int NIA = cia + 4;
3652 sim_cpu* CPU_ = cpu;
3653
3654 handle = 1;
3655
3656 /* test COP2 usability */
3657 if(! (SR & status_CU2))
3658 {
3659 SignalException(CoProcessorUnusable,instruction);
3660 /* NOTREACHED */
3661 }
3662
3663 /* classify & execute basic COP2 instructions */
3664 if(i_25_21 == 0x08 && i_20_16 == 0x00) /* BC2F */
3665 {
3666 address_word offset = EXTEND16(i_15_0) << 2;
3667 if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset);
3668 }
3669 else if(i_25_21 == 0x08 && i_20_16==0x02) /* BC2FL */
3670 {
3671 address_word offset = EXTEND16(i_15_0) << 2;
3672 if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset);
3673 else NULLIFY_NEXT_INSTRUCTION();
3674 }
3675 else if(i_25_21 == 0x08 && i_20_16 == 0x01) /* BC2T */
3676 {
3677 address_word offset = EXTEND16(i_15_0) << 2;
3678 if(vu0_busy()) DELAY_SLOT(cia + 4 + offset);
3679 }
3680 else if(i_25_21 == 0x08 && i_20_16 == 0x03) /* BC2TL */
3681 {
3682 address_word offset = EXTEND16(i_15_0) << 2;
3683 if(vu0_busy()) DELAY_SLOT(cia + 4 + offset);
3684 else NULLIFY_NEXT_INSTRUCTION();
3685 }
3686 else if((i_25_21 == 0x02 && i_10_1 == 0x000) || /* CFC2 */
3687 (i_25_21 == 0x01)) /* QMFC2 */
3688 {
3689 int rt = i_20_16;
3690 int id = i_15_11;
3691 address_word vu_cr_addr; /* VU control register address */
3692 unsigned_4 data;
3693
3694 /* interlock checking */
3695 if(vu0_busy_in_macro_mode()) /* busy in macro mode */
3696 {
3697 /* interlock bit invalid here */
3698 if(interlock)
3699 ; /* XXX: warning */
3700
3701 /* always check data hazard */
3702 while(vu0_macro_hazard_check(id))
3703 vu0_issue(sd);
3704 }
3705 else if(vu0_busy_in_micro_mode() && interlock)
3706 {
3707 while(vu0_busy_in_micro_mode())
3708 vu0_issue(sd);
3709 }
3710
3711 /* compute VU register address */
3712 if(i_25_21 == 0x01) /* QMFC2 */
3713 vu_cr_addr = VU0_REGISTER_WINDOW_START + (id * 16);
3714 else /* CFC2 */
3715 vu_cr_addr = VU0_MST + (id * 16);
3716
3717 /* read or write word */
3718 data = sim_core_read_aligned_4(cpu, cia, read_map, vu_cr_addr);
3719 GPR[rt] = EXTEND64(data);
3720 }
3721 else if((i_25_21 == 0x06 && i_10_1 == 0x000) || /* CTC2 */
3722 (i_25_21 == 0x05)) /* QMTC2 */
3723 {
3724 int rt = i_20_16;
3725 int id = i_15_11;
3726 address_word vu_cr_addr; /* VU control register address */
3727 unsigned_4 data;
3728
3729 /* interlock checking */
3730 if(vu0_busy_in_macro_mode()) /* busy in macro mode */
3731 {
3732 /* interlock bit invalid here */
3733 if(interlock)
3734 ; /* XXX: warning */
3735
3736 /* always check data hazard */
3737 while(vu0_macro_hazard_check(id))
3738 vu0_issue(sd);
3739 }
3740 else if(vu0_busy_in_micro_mode())
3741 {
3742 if(interlock)
3743 {
3744 while(! vu0_micro_interlock_released())
3745 vu0_issue(sd);
3746 }
3747 }
3748
3749 /* compute VU register address */
3750 if(i_25_21 == 0x05) /* QMTC2 */
3751 vu_cr_addr = VU0_REGISTER_WINDOW_START + (id * 16);
3752 else /* CTC2 */
3753 vu_cr_addr = VU0_MST + (id * 16);
3754
3755 data = GPR[rt];
3756 sim_core_write_aligned_4(cpu, cia, write_map, vu_cr_addr, data);
3757 }
3758 else if( 0 /* XXX: ... upper ... */)
3759 {
3760 unsigned_4 vu_upper, vu_lower;
3761 vu_upper =
3762 0x00000000 | /* bits 31 .. 25 */
3763 instruction & 0x01ffffff; /* bits 24 .. 0 */
3764 vu_lower = 0x8000033c; /* NOP */
3765
3766 while(vu0_busy_in_micro_mode())
3767 vu0_issue(sd);
3768
3769 vu0_macro_issue(vu_upper, vu_lower);
3770 }
3771 else if( 0 /* XXX: ... lower ... */)
3772 {
3773 unsigned_4 vu_upper, vu_lower;
3774 vu_upper = 0x000002ff; /* NOP */
3775 vu_lower =
3776 0x10000000 | /* bits 31 .. 25 */
3777 instruction & 0x01ffffff; /* bits 24 .. 0 */
3778
3779 while(vu0_busy_in_micro_mode())
3780 vu0_issue(sd);
3781
3782 vu0_macro_issue(vu_upper, vu_lower);
3783 }
3784 /* XXX */
3785 /* ... other COP2 instructions ... */
3786 else
3787 {
3788 SignalException(ReservedInstruction, instruction);
3789 /* NOTREACHED */
3790 }
3791
3792 /* cleanup for semantic.c-like actions above */
3793 PC = NIA;
3794
3795 #endif /* TARGET_SKY */
3796 /* end-sanitize-sky */
3797
3798 if(! handle)
3799 {
3800 sim_io_eprintf(sd,"COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3801 instruction,pr_addr(cia));
3802 }
3803 }
3804 break;
3805
3806 case 1: /* should not occur (FPU co-processor) */
3807 case 3: /* should not occur (FPU co-processor) */
3808 SignalException(ReservedInstruction,instruction);
3809 break;
3810 }
3811
3812 return;
3813 }
3814
3815
3816 /*-- instruction simulation -------------------------------------------------*/
3817
3818 /* When the IGEN simulator is being built, the function below is be
3819 replaced by a generated version. However, WITH_IGEN == 2 indicates
3820 that the fubction below should be compiled but under a different
3821 name (to allow backward compatibility) */
3822
3823 #if (WITH_IGEN != 1)
3824 #if (WITH_IGEN > 1)
3825 void old_engine_run PARAMS ((SIM_DESC sd, int next_cpu_nr, int siggnal));
3826 void
3827 old_engine_run (sd, next_cpu_nr, nr_cpus, siggnal)
3828 #else
3829 void
3830 sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal)
3831 #endif
3832 SIM_DESC sd;
3833 int next_cpu_nr; /* ignore */
3834 int nr_cpus; /* ignore */
3835 int siggnal; /* ignore */
3836 {
3837 sim_cpu *cpu = STATE_CPU (sd, 0); /* hardwire to cpu 0 */
3838 #if !defined(FASTSIM)
3839 unsigned int pipeline_count = 1;
3840 #endif
3841
3842 #ifdef DEBUG
3843 if (STATE_MEMORY (sd) == NULL) {
3844 printf("DBG: simulate() entered with no memory\n");
3845 exit(1);
3846 }
3847 #endif /* DEBUG */
3848
3849 #if 0 /* Disabled to check that everything works OK */
3850 /* The VR4300 seems to sign-extend the PC on its first
3851 access. However, this may just be because it is currently
3852 configured in 32bit mode. However... */
3853 PC = SIGNEXTEND(PC,32);
3854 #endif
3855
3856 /* main controlling loop */
3857 while (1) {
3858 /* vaddr is slowly being replaced with cia - current instruction
3859 address */
3860 address_word cia = (uword64)PC;
3861 address_word vaddr = cia;
3862 address_word paddr;
3863 int cca;
3864 unsigned int instruction; /* uword64? what's this used for? FIXME! */
3865
3866 #ifdef DEBUG
3867 {
3868 printf("DBG: state = 0x%08X :",state);
3869 if (state & simHALTEX) printf(" simHALTEX");
3870 if (state & simHALTIN) printf(" simHALTIN");
3871 printf("\n");
3872 }
3873 #endif /* DEBUG */
3874
3875 DSSTATE = (STATE & simDELAYSLOT);
3876 #ifdef DEBUG
3877 if (dsstate)
3878 sim_io_printf(sd,"DBG: DSPC = 0x%s\n",pr_addr(DSPC));
3879 #endif /* DEBUG */
3880
3881 /* Fetch the next instruction from the simulator memory: */
3882 if (AddressTranslation(cia,isINSTRUCTION,isLOAD,&paddr,&cca,isTARGET,isREAL)) {
3883 if ((vaddr & 1) == 0) {
3884 /* Copy the action of the LW instruction */
3885 unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
3886 unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
3887 uword64 value;
3888 unsigned int byte;
3889 paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
3890 LoadMemory(&value,NULL,cca,AccessLength_WORD,paddr,vaddr,isINSTRUCTION,isREAL);
3891 byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
3892 instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
3893 } else {
3894 /* Copy the action of the LH instruction */
3895 unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 1) : 0);
3896 unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 1) : 0);
3897 uword64 value;
3898 unsigned int byte;
3899 paddr = (((paddr & ~ (uword64) 1) & ~LOADDRMASK)
3900 | (((paddr & ~ (uword64) 1) & LOADDRMASK) ^ (reverse << 1)));
3901 LoadMemory(&value,NULL,cca, AccessLength_HALFWORD,
3902 paddr & ~ (uword64) 1,
3903 vaddr, isINSTRUCTION, isREAL);
3904 byte = (((vaddr &~ (uword64) 1) & LOADDRMASK) ^ (bigend << 1));
3905 instruction = ((value >> (8 * byte)) & 0xFFFF);
3906 }
3907 } else {
3908 fprintf(stderr,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC));
3909 exit(1);
3910 }
3911
3912 #ifdef DEBUG
3913 sim_io_printf(sd,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction,pr_addr(PC));
3914 #endif /* DEBUG */
3915
3916 /* This is required by exception processing, to ensure that we can
3917 cope with exceptions in the delay slots of branches that may
3918 already have changed the PC. */
3919 if ((vaddr & 1) == 0)
3920 PC += 4; /* increment ready for the next fetch */
3921 else
3922 PC += 2;
3923 /* NOTE: If we perform a delay slot change to the PC, this
3924 increment is not requuired. However, it would make the
3925 simulator more complicated to try and avoid this small hit. */
3926
3927 /* Currently this code provides a simple model. For more
3928 complicated models we could perform exception status checks at
3929 this point, and set the simSTOP state as required. This could
3930 also include processing any hardware interrupts raised by any
3931 I/O model attached to the simulator context.
3932
3933 Support for "asynchronous" I/O events within the simulated world
3934 could be providing by managing a counter, and calling a I/O
3935 specific handler when a particular threshold is reached. On most
3936 architectures a decrement and check for zero operation is
3937 usually quicker than an increment and compare. However, the
3938 process of managing a known value decrement to zero, is higher
3939 than the cost of using an explicit value UINT_MAX into the
3940 future. Which system is used will depend on how complicated the
3941 I/O model is, and how much it is likely to affect the simulator
3942 bandwidth.
3943
3944 If events need to be scheduled further in the future than
3945 UINT_MAX event ticks, then the I/O model should just provide its
3946 own counter, triggered from the event system. */
3947
3948 /* MIPS pipeline ticks. To allow for future support where the
3949 pipeline hit of individual instructions is known, this control
3950 loop manages a "pipeline_count" variable. It is initialised to
3951 1 (one), and will only be changed by the simulator engine when
3952 executing an instruction. If the engine does not have access to
3953 pipeline cycle count information then all instructions will be
3954 treated as using a single cycle. NOTE: A standard system is not
3955 provided by the default simulator because different MIPS
3956 architectures have different cycle counts for the same
3957 instructions.
3958
3959 [NOTE: pipeline_count has been replaced the event queue] */
3960
3961 /* shuffle the floating point status pipeline state */
3962 ENGINE_ISSUE_PREFIX_HOOK();
3963
3964 /* NOTE: For multi-context simulation environments the "instruction"
3965 variable should be local to this routine. */
3966
3967 /* Shorthand accesses for engine. Note: If we wanted to use global
3968 variables (and a single-threaded simulator engine), then we can
3969 create the actual variables with these names. */
3970
3971 if (!(STATE & simSKIPNEXT)) {
3972 /* Include the simulator engine */
3973 #include "oengine.c"
3974 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3975 #error "Mismatch between run-time simulator code and simulation engine"
3976 #endif
3977 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3978 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3979 #endif
3980 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3981 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3982 #endif
3983
3984 #if defined(WARN_LOHI)
3985 /* Decrement the HI/LO validity ticks */
3986 if (HIACCESS > 0)
3987 HIACCESS--;
3988 if (LOACCESS > 0)
3989 LOACCESS--;
3990 /* start-sanitize-r5900 */
3991 if (HI1ACCESS > 0)
3992 HI1ACCESS--;
3993 if (LO1ACCESS > 0)
3994 LO1ACCESS--;
3995 /* end-sanitize-r5900 */
3996 #endif /* WARN_LOHI */
3997
3998 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3999 should check for it being changed. It is better doing it here,
4000 than within the simulator, since it will help keep the simulator
4001 small. */
4002 if (ZERO != 0) {
4003 #if defined(WARN_ZERO)
4004 sim_io_eprintf(sd,"The ZERO register has been updated with 0x%s (PC = 0x%s) (reset back to zero)\n",pr_addr(ZERO),pr_addr(cia));
4005 #endif /* WARN_ZERO */
4006 ZERO = 0; /* reset back to zero before next instruction */
4007 }
4008 } else /* simSKIPNEXT check */
4009 STATE &= ~simSKIPNEXT;
4010
4011 /* If the delay slot was active before the instruction is
4012 executed, then update the PC to its new value: */
4013 if (DSSTATE) {
4014 #ifdef DEBUG
4015 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC));
4016 #endif /* DEBUG */
4017 PC = DSPC;
4018 CANCELDELAYSLOT();
4019 }
4020
4021 if (MIPSISA < 4)
4022 PENDING_TICK();
4023
4024 #if !defined(FASTSIM)
4025 if (sim_events_tickn (sd, pipeline_count))
4026 {
4027 /* cpu->cia = cia; */
4028 sim_events_process (sd);
4029 }
4030 #else
4031 if (sim_events_tick (sd))
4032 {
4033 /* cpu->cia = cia; */
4034 sim_events_process (sd);
4035 }
4036 #endif /* FASTSIM */
4037 }
4038 }
4039 #endif
4040
4041
4042 /* This code copied from gdb's utils.c. Would like to share this code,
4043 but don't know of a common place where both could get to it. */
4044
4045 /* Temporary storage using circular buffer */
4046 #define NUMCELLS 16
4047 #define CELLSIZE 32
4048 static char*
4049 get_cell()
4050 {
4051 static char buf[NUMCELLS][CELLSIZE];
4052 static int cell=0;
4053 if (++cell>=NUMCELLS) cell=0;
4054 return buf[cell];
4055 }
4056
4057 /* Print routines to handle variable size regs, etc */
4058
4059 /* Eliminate warning from compiler on 32-bit systems */
4060 static int thirty_two = 32;
4061
4062 char*
4063 pr_addr(addr)
4064 SIM_ADDR addr;
4065 {
4066 char *paddr_str=get_cell();
4067 switch (sizeof(addr))
4068 {
4069 case 8:
4070 sprintf(paddr_str,"%08lx%08lx",
4071 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
4072 break;
4073 case 4:
4074 sprintf(paddr_str,"%08lx",(unsigned long)addr);
4075 break;
4076 case 2:
4077 sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
4078 break;
4079 default:
4080 sprintf(paddr_str,"%x",addr);
4081 }
4082 return paddr_str;
4083 }
4084
4085 char*
4086 pr_uword64(addr)
4087 uword64 addr;
4088 {
4089 char *paddr_str=get_cell();
4090 sprintf(paddr_str,"%08lx%08lx",
4091 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
4092 return paddr_str;
4093 }
4094
4095
4096 void
4097 pending_tick (SIM_DESC sd,
4098 sim_cpu *cpu,
4099 address_word cia)
4100 {
4101 if (PENDING_TRACE)
4102 sim_io_printf (sd, "PENDING_DRAIN - pending_in = %d, pending_out = %d, pending_total = %d\n", PENDING_IN, PENDING_OUT, PENDING_TOTAL);
4103 if (PENDING_OUT != PENDING_IN)
4104 {
4105 int loop;
4106 int index = PENDING_OUT;
4107 int total = PENDING_TOTAL;
4108 if (PENDING_TOTAL == 0)
4109 sim_engine_abort (SD, CPU, cia, "PENDING_DRAIN - Mis-match on pending update pointers\n");
4110 for (loop = 0; (loop < total); loop++)
4111 {
4112 if (PENDING_SLOT_DEST[index] != NULL)
4113 {
4114 PENDING_SLOT_DELAY[index] -= 1;
4115 if (PENDING_SLOT_DELAY[index] == 0)
4116 {
4117 if (PENDING_SLOT_BIT[index] >= 0)
4118 switch (PENDING_SLOT_SIZE[index])
4119 {
4120 case 32:
4121 if (PENDING_SLOT_VALUE[index])
4122 *(unsigned32*)PENDING_SLOT_DEST[index] |=
4123 BIT32 (PENDING_SLOT_BIT[index]);
4124 else
4125 *(unsigned32*)PENDING_SLOT_DEST[index] &=
4126 BIT32 (PENDING_SLOT_BIT[index]);
4127 break;
4128 case 64:
4129 if (PENDING_SLOT_VALUE[index])
4130 *(unsigned64*)PENDING_SLOT_DEST[index] |=
4131 BIT64 (PENDING_SLOT_BIT[index]);
4132 else
4133 *(unsigned64*)PENDING_SLOT_DEST[index] &=
4134 BIT64 (PENDING_SLOT_BIT[index]);
4135 break;
4136 break;
4137 }
4138 else
4139 switch (PENDING_SLOT_SIZE[index])
4140 {
4141 case 32:
4142 *(unsigned32*)PENDING_SLOT_DEST[index] =
4143 PENDING_SLOT_VALUE[index];
4144 break;
4145 case 64:
4146 *(unsigned64*)PENDING_SLOT_DEST[index] =
4147 PENDING_SLOT_VALUE[index];
4148 break;
4149 }
4150 }
4151 if (PENDING_OUT == index)
4152 {
4153 PENDING_SLOT_DEST[index] = NULL;
4154 PENDING_OUT = (PENDING_OUT + 1) % PSLOTS;
4155 PENDING_TOTAL--;
4156 }
4157 }
4158 }
4159 index = (index + 1) % PSLOTS;
4160 }
4161 }
4162
4163 /*---------------------------------------------------------------------------*/
4164 /*> EOF interp.c <*/
This page took 0.136174 seconds and 4 git commands to generate.