2 /* Simulator for the MIPS architecture.
4 This file is part of the MIPS sim
6 THIS SOFTWARE IS NOT COPYRIGHTED
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.
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.
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
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 */
37 #include "sim-utils.h"
38 #include "sim-options.h"
39 #include "sim-assert.h"
41 /* start-sanitize-sky */
45 #include "sky-libvpe.h"
49 /* end-sanitize-sky */
71 #include "libiberty.h"
73 #include "callback.h" /* GDB simulator callback interface */
74 #include "remote-sim.h" /* GDB simulator interface */
82 char* pr_addr
PARAMS ((SIM_ADDR addr
));
83 char* pr_uword64
PARAMS ((uword64 addr
));
86 /* Get the simulator engine description, without including the code: */
93 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
98 /* The following reserved instruction value is used when a simulator
99 trap is required. NOTE: Care must be taken, since this value may be
100 used in later revisions of the MIPS ISA. */
101 #define RSVD_INSTRUCTION (0x00000005)
102 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
104 #define RSVD_INSTRUCTION_ARG_SHIFT 6
105 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
108 /* Bits in the Debug register */
109 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
110 #define Debug_DM 0x40000000 /* Debug Mode */
111 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
117 /*---------------------------------------------------------------------------*/
118 /*-- GDB simulator interface ------------------------------------------------*/
119 /*---------------------------------------------------------------------------*/
121 static void ColdReset
PARAMS((SIM_DESC sd
));
123 /*---------------------------------------------------------------------------*/
127 #define DELAYSLOT() {\
128 if (STATE & simDELAYSLOT)\
129 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
130 STATE |= simDELAYSLOT;\
133 #define JALDELAYSLOT() {\
135 STATE |= simJALDELAYSLOT;\
139 STATE &= ~simDELAYSLOT;\
140 STATE |= simSKIPNEXT;\
143 #define CANCELDELAYSLOT() {\
145 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
148 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
149 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
151 #define K0BASE (0x80000000)
152 #define K0SIZE (0x20000000)
153 #define K1BASE (0xA0000000)
154 #define K1SIZE (0x20000000)
155 #define MONITOR_BASE (0xBFC00000)
156 #define MONITOR_SIZE (1 << 11)
157 #define MEM_SIZE (2 << 20)
159 /* start-sanitize-sky */
162 #define MEM_SIZE (16 << 20) /* 16 MB */
164 /* end-sanitize-sky */
167 static char *tracefile
= "trace.din"; /* default filename for trace log */
168 FILE *tracefh
= NULL
;
169 static void open_trace
PARAMS((SIM_DESC sd
));
172 static DECLARE_OPTION_HANDLER (mips_option_handler
);
175 OPTION_DINERO_TRACE
= OPTION_START
,
177 /* start-sanitize-sky */
179 /* end-sanitize-sky */
183 mips_option_handler (sd
, cpu
, opt
, arg
, is_command
)
193 case OPTION_DINERO_TRACE
: /* ??? */
195 /* Eventually the simTRACE flag could be treated as a toggle, to
196 allow external control of the program points being traced
197 (i.e. only from main onwards, excluding the run-time setup,
199 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
201 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
204 else if (strcmp (arg
, "yes") == 0)
206 else if (strcmp (arg
, "no") == 0)
208 else if (strcmp (arg
, "on") == 0)
210 else if (strcmp (arg
, "off") == 0)
214 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
221 Simulator constructed without dinero tracing support (for performance).\n\
222 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
226 case OPTION_DINERO_FILE
:
228 if (optarg
!= NULL
) {
230 tmp
= (char *)malloc(strlen(optarg
) + 1);
233 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
239 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
245 /* start-sanitize-sky */
246 case OPTION_FLOAT_TYPE
:
247 /* Use host (fast) or target (accurate) floating point implementation. */
248 if (arg
&& strcmp (arg
, "host") == 0)
249 STATE_FP_TYPE_OPT (sd
) &= ~STATE_FP_TYPE_OPT_TARGET
;
250 else if (arg
&& strcmp (arg
, "target") == 0)
251 STATE_FP_TYPE_OPT (sd
) |= STATE_FP_TYPE_OPT_TARGET
;
254 fprintf (stderr
, "Unrecognized float-type option `%s'\n", arg
);
258 /* end-sanitize-sky */
264 static const OPTION mips_options
[] =
266 { {"dinero-trace", optional_argument
, NULL
, OPTION_DINERO_TRACE
},
267 '\0', "on|off", "Enable dinero tracing",
268 mips_option_handler
},
269 { {"dinero-file", required_argument
, NULL
, OPTION_DINERO_FILE
},
270 '\0', "FILE", "Write dinero trace to FILE",
271 mips_option_handler
},
272 /* start-sanitize-sky */
273 { {"float-type", required_argument
, NULL
, OPTION_FLOAT_TYPE
},
274 '\0', "host|target", "Use host (fast) or target (accurate) floating point",
275 mips_option_handler
},
276 /* end-sanitize-sky */
277 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
281 int interrupt_pending
;
284 interrupt_event (SIM_DESC sd
, void *data
)
286 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
289 interrupt_pending
= 0;
290 SignalExceptionInterrupt ();
292 else if (!interrupt_pending
)
293 sim_events_schedule (sd
, 1, interrupt_event
, data
);
297 /*---------------------------------------------------------------------------*/
298 /*-- Device registration hook -----------------------------------------------*/
299 /*---------------------------------------------------------------------------*/
300 static void device_init(SIM_DESC sd
) {
302 extern void register_devices(SIM_DESC
);
303 register_devices(sd
);
307 /*---------------------------------------------------------------------------*/
308 /*-- GDB simulator interface ------------------------------------------------*/
309 /*---------------------------------------------------------------------------*/
312 sim_open (kind
, cb
, abfd
, argv
)
318 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
319 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
321 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
323 /* FIXME: watchpoints code shouldn't need this */
324 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
325 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
326 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
330 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
332 sim_add_option_table (sd
, NULL
, mips_options
);
334 /* Allocate core managed memory */
337 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
, MONITOR_SIZE
);
338 /* For compatibility with the old code - under this (at level one)
339 are the kernel spaces K0 & K1. Both of these map to a single
340 smaller sub region */
341 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
342 /* start-sanitize-sky */
344 /* end-sanitize-sky */
345 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
347 MEM_SIZE
, /* actual size */
349 /* start-sanitize-sky */
351 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x",
353 MEM_SIZE
, /* actual size */
355 0); /* add alias at 0x0000 */
357 /* end-sanitize-sky */
361 /* getopt will print the error message so we just have to exit if this fails.
362 FIXME: Hmmm... in the case of gdb we need getopt to call
364 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
366 /* Uninstall the modules to avoid memory leaks,
367 file descriptor leaks, etc. */
368 sim_module_uninstall (sd
);
372 /* check for/establish the a reference program image */
373 if (sim_analyze_program (sd
,
374 (STATE_PROG_ARGV (sd
) != NULL
375 ? *STATE_PROG_ARGV (sd
)
379 sim_module_uninstall (sd
);
383 /* Configure/verify the target byte order and other runtime
384 configuration options */
385 if (sim_config (sd
) != SIM_RC_OK
)
387 sim_module_uninstall (sd
);
391 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
393 /* Uninstall the modules to avoid memory leaks,
394 file descriptor leaks, etc. */
395 sim_module_uninstall (sd
);
399 /* verify assumptions the simulator made about the host type system.
400 This macro does not return if there is a problem */
401 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
402 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
404 /* This is NASTY, in that we are assuming the size of specific
408 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
411 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
412 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ NR_FGR
)))
413 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
414 else if ((rn
>= 33) && (rn
<= 37))
415 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
416 else if ((rn
== SRIDX
)
419 || ((rn
>= 72) && (rn
<= 89)))
420 cpu
->register_widths
[rn
] = 32;
422 cpu
->register_widths
[rn
] = 0;
424 /* start-sanitize-r5900 */
426 /* set the 5900 "upper" registers to 64 bits */
427 for( rn
= LAST_EMBED_REGNUM
+1; rn
< NUM_REGS
; rn
++)
428 cpu
->register_widths
[rn
] = 64;
429 /* end-sanitize-r5900 */
431 /* start-sanitize-sky */
433 /* Now the VU registers */
434 for( rn
= 0; rn
< NUM_VU_INTEGER_REGS
; rn
++ ) {
435 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 16;
436 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 16;
439 for( rn
= NUM_VU_INTEGER_REGS
; rn
< NUM_VU_REGS
; rn
++ ) {
440 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
441 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 32;
444 /* Finally the VIF registers */
445 for( rn
= 2*NUM_VU_REGS
; rn
< 2*NUM_VU_REGS
+ 2*NUM_VIF_REGS
; rn
++ )
446 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
448 /* end-sanitize-sky */
452 if (STATE
& simTRACE
)
456 /* Write the monitor trap address handlers into the monitor (eeprom)
457 address space. This can only be done once the target endianness
458 has been determined. */
461 /* Entry into the IDT monitor is via fixed address vectors, and
462 not using machine instructions. To avoid clashing with use of
463 the MIPS TRAP system, we place our own (simulator specific)
464 "undefined" instructions into the relevant vector slots. */
465 for (loop
= 0; (loop
< MONITOR_SIZE
); loop
+= 4)
467 address_word vaddr
= (MONITOR_BASE
+ loop
);
468 unsigned32 insn
= (RSVD_INSTRUCTION
| (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
) << RSVD_INSTRUCTION_ARG_SHIFT
));
470 sim_write (sd
, vaddr
, (char *)&insn
, sizeof (insn
));
472 /* The PMON monitor uses the same address space, but rather than
473 branching into it the address of a routine is loaded. We can
474 cheat for the moment, and direct the PMON routine to IDT style
475 instructions within the monitor space. This relies on the IDT
476 monitor not using the locations from 0xBFC00500 onwards as its
478 for (loop
= 0; (loop
< 24); loop
++)
480 address_word vaddr
= (MONITOR_BASE
+ 0x500 + (loop
* 4));
481 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
497 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
499 case 8: /* cliexit */
502 case 11: /* flush_cache */
506 /* FIXME - should monitor_base be SIM_ADDR?? */
507 value
= ((unsigned int)MONITOR_BASE
+ (value
* 8));
509 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
511 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
513 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
525 tracefh
= fopen(tracefile
,"wb+");
528 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
535 sim_close (sd
, quitting
)
540 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
543 /* "quitting" is non-zero if we cannot hang on errors */
545 /* Ensure that any resources allocated through the callback
546 mechanism are released: */
547 sim_io_shutdown (sd
);
550 if (tracefh
!= NULL
&& tracefh
!= stderr
)
555 /* FIXME - free SD */
562 sim_write (sd
,addr
,buffer
,size
)
565 unsigned char *buffer
;
569 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
571 /* Return the number of bytes written, or zero if error. */
573 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
576 /* We use raw read and write routines, since we do not want to count
577 the GDB memory accesses in our statistics gathering. */
579 for (index
= 0; index
< size
; index
++)
581 address_word vaddr
= (address_word
)addr
+ index
;
584 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
586 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
594 sim_read (sd
,addr
,buffer
,size
)
597 unsigned char *buffer
;
601 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
603 /* Return the number of bytes read, or zero if error. */
605 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
608 for (index
= 0; (index
< size
); index
++)
610 address_word vaddr
= (address_word
)addr
+ index
;
613 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isLOAD
, &paddr
, &cca
, isRAW
))
615 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
623 sim_store_register (sd
,rn
,memory
,length
)
626 unsigned char *memory
;
629 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
630 /* NOTE: gdb (the client) stores registers in target byte order
631 while the simulator uses host byte order */
633 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
636 /* Unfortunately this suffers from the same problem as the register
637 numbering one. We need to know what the width of each logical
638 register number is for the architecture being simulated. */
640 if (cpu
->register_widths
[rn
] == 0)
642 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
646 /* start-sanitize-r5900 */
647 if (rn
>= 90 && rn
< 90 + 32)
649 GPR1
[rn
- 90] = T2H_8 (*(unsigned64
*)memory
);
655 SA
= T2H_8(*(unsigned64
*)memory
);
657 case 122: /* FIXME */
658 LO1
= T2H_8(*(unsigned64
*)memory
);
660 case 123: /* FIXME */
661 HI1
= T2H_8(*(unsigned64
*)memory
);
664 /* end-sanitize-r5900 */
666 /* start-sanitize-sky */
668 if (rn
>= NUM_R5900_REGS
)
670 rn
= rn
- NUM_R5900_REGS
;
672 if( rn
< NUM_VU_REGS
)
674 if (rn
< NUM_VU_INTEGER_REGS
)
675 return write_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
676 else if (rn
>= FIRST_VEC_REG
)
679 return write_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
&3,
682 else switch (rn
- NUM_VU_INTEGER_REGS
)
685 return write_vu_special_reg (&vu0_device
, VU_REG_CIA
,
688 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
690 case 2: /* VU0 has no P register */
693 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
696 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
699 return write_vu_acc_reg (&(vu0_device
.regs
),
700 rn
- (NUM_VU_INTEGER_REGS
+ 5),
705 rn
= rn
- NUM_VU_REGS
;
707 if (rn
< NUM_VU_REGS
)
709 if (rn
< NUM_VU_INTEGER_REGS
)
710 return write_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
711 else if (rn
>= FIRST_VEC_REG
)
714 return write_vu_vec_reg (&(vu1_device
.regs
),
715 rn
>> 2, rn
& 3, memory
);
717 else switch (rn
- NUM_VU_INTEGER_REGS
)
720 return write_vu_special_reg (&vu1_device
, VU_REG_CIA
,
723 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MR
,
726 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MP
,
729 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MI
,
732 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MQ
,
735 return write_vu_acc_reg (&(vu1_device
.regs
),
736 rn
- (NUM_VU_INTEGER_REGS
+ 5),
741 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
743 if (rn
< NUM_VIF_REGS
)
745 if (rn
< NUM_VIF_REGS
-1)
746 return write_pke_reg (&pke0_device
, rn
, memory
);
749 sim_io_eprintf( sd
, "Can't write vif0_pc (store ignored)\n" );
754 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
756 if (rn
< NUM_VIF_REGS
)
758 if (rn
< NUM_VIF_REGS
-1)
759 return write_pke_reg (&pke1_device
, rn
, memory
);
762 sim_io_eprintf( sd
, "Can't write vif1_pc (store ignored)\n" );
767 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
771 /* end-sanitize-sky */
773 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
775 if (cpu
->register_widths
[rn
] == 32)
777 cpu
->fgr
[rn
- FGRIDX
] = T2H_4 (*(unsigned32
*)memory
);
782 cpu
->fgr
[rn
- FGRIDX
] = T2H_8 (*(unsigned64
*)memory
);
787 if (cpu
->register_widths
[rn
] == 32)
789 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
794 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
802 sim_fetch_register (sd
,rn
,memory
,length
)
805 unsigned char *memory
;
808 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
809 /* NOTE: gdb (the client) stores registers in target byte order
810 while the simulator uses host byte order */
812 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
815 if (cpu
->register_widths
[rn
] == 0)
817 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
821 /* start-sanitize-r5900 */
822 if (rn
>= 90 && rn
< 90 + 32)
824 *(unsigned64
*)memory
= GPR1
[rn
- 90];
830 *((unsigned64
*)memory
) = H2T_8(SA
);
832 case 122: /* FIXME */
833 *((unsigned64
*)memory
) = H2T_8(LO1
);
835 case 123: /* FIXME */
836 *((unsigned64
*)memory
) = H2T_8(HI1
);
839 /* end-sanitize-r5900 */
841 /* start-sanitize-sky */
843 if (rn
>= NUM_R5900_REGS
)
845 rn
= rn
- NUM_R5900_REGS
;
847 if (rn
< NUM_VU_REGS
)
849 if (rn
< NUM_VU_INTEGER_REGS
)
850 return read_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
851 else if (rn
>= FIRST_VEC_REG
)
854 return read_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
& 3,
857 else switch (rn
- NUM_VU_INTEGER_REGS
)
860 return read_vu_special_reg(&vu0_device
, VU_REG_CIA
, memory
);
862 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
864 case 2: /* VU0 has no P register */
865 *((int *) memory
) = 0;
868 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
871 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
874 return read_vu_acc_reg (&(vu0_device
.regs
),
875 rn
- (NUM_VU_INTEGER_REGS
+ 5),
880 rn
-= NUM_VU_REGS
; /* VU1 registers are next */
882 if (rn
< NUM_VU_REGS
)
884 if (rn
< NUM_VU_INTEGER_REGS
)
885 return read_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
886 else if (rn
>= FIRST_VEC_REG
)
889 return read_vu_vec_reg (&(vu1_device
.regs
),
890 rn
>> 2, rn
& 3, memory
);
892 else switch (rn
- NUM_VU_INTEGER_REGS
)
895 return read_vu_special_reg(&vu1_device
, VU_REG_CIA
, memory
);
897 return read_vu_misc_reg (&(vu1_device
.regs
),
900 return read_vu_misc_reg (&(vu1_device
.regs
),
903 return read_vu_misc_reg (&(vu1_device
.regs
),
906 return read_vu_misc_reg (&(vu1_device
.regs
),
909 return read_vu_acc_reg (&(vu1_device
.regs
),
910 rn
- (NUM_VU_INTEGER_REGS
+ 5),
915 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
917 if (rn
< NUM_VIF_REGS
)
919 if (rn
< NUM_VIF_REGS
-1)
920 return read_pke_reg (&pke0_device
, rn
, memory
);
922 return read_pke_pc (&pke0_device
, memory
);
925 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
927 if (rn
< NUM_VIF_REGS
)
929 if (rn
< NUM_VIF_REGS
-1)
930 return read_pke_reg (&pke1_device
, rn
, memory
);
932 return read_pke_pc (&pke1_device
, memory
);
935 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
938 /* end-sanitize-sky */
940 /* Any floating point register */
941 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
943 if (cpu
->register_widths
[rn
] == 32)
945 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGRIDX
]);
950 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGRIDX
]);
955 if (cpu
->register_widths
[rn
] == 32)
957 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
962 *(unsigned64
*)memory
= H2T_8 ((unsigned64
)(cpu
->registers
[rn
]));
971 sim_create_inferior (sd
, abfd
, argv
,env
)
979 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
987 /* override PC value set by ColdReset () */
989 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
991 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
992 CIA_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
996 #if 0 /* def DEBUG */
999 /* We should really place the argv slot values into the argument
1000 registers, and onto the stack as required. However, this
1001 assumes that we have a stack defined, which is not
1002 necessarily true at the moment. */
1004 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1005 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1006 printf("DBG: arg \"%s\"\n",*cptr
);
1014 sim_do_command (sd
,cmd
)
1018 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1019 sim_io_printf (sd
, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1023 /*---------------------------------------------------------------------------*/
1024 /*-- Private simulator support interface ------------------------------------*/
1025 /*---------------------------------------------------------------------------*/
1027 /* Read a null terminated string from memory, return in a buffer */
1029 fetch_str (sd
, addr
)
1036 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1038 buf
= NZALLOC (char, nr
+ 1);
1039 sim_read (sd
, addr
, buf
, nr
);
1043 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1045 sim_monitor (SIM_DESC sd
,
1048 unsigned int reason
)
1051 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1054 /* The IDT monitor actually allows two instructions per vector
1055 slot. However, the simulator currently causes a trap on each
1056 individual instruction. We cheat, and lose the bottom bit. */
1059 /* The following callback functions are available, however the
1060 monitor we are simulating does not make use of them: get_errno,
1061 isatty, lseek, rename, system, time and unlink */
1065 case 6: /* int open(char *path,int flags) */
1067 char *path
= fetch_str (sd
, A0
);
1068 V0
= sim_io_open (sd
, path
, (int)A1
);
1073 case 7: /* int read(int file,char *ptr,int len) */
1077 char *buf
= zalloc (nr
);
1078 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1079 sim_write (sd
, A1
, buf
, nr
);
1084 case 8: /* int write(int file,char *ptr,int len) */
1088 char *buf
= zalloc (nr
);
1089 sim_read (sd
, A1
, buf
, nr
);
1090 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1095 case 10: /* int close(int file) */
1097 V0
= sim_io_close (sd
, (int)A0
);
1101 case 2: /* Densan monitor: char inbyte(int waitflag) */
1103 if (A0
== 0) /* waitflag == NOWAIT */
1104 V0
= (unsigned_word
)-1;
1106 /* Drop through to case 11 */
1108 case 11: /* char inbyte(void) */
1111 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1113 sim_io_error(sd
,"Invalid return from character read");
1114 V0
= (unsigned_word
)-1;
1117 V0
= (unsigned_word
)tmp
;
1121 case 3: /* Densan monitor: void co(char chr) */
1122 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1124 char tmp
= (char)(A0
& 0xFF);
1125 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1129 case 17: /* void _exit() */
1131 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1132 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1133 (unsigned int)(A0
& 0xFFFFFFFF));
1137 case 28 : /* PMON flush_cache */
1140 case 55: /* void get_mem_info(unsigned int *ptr) */
1141 /* in: A0 = pointer to three word memory location */
1142 /* out: [A0 + 0] = size */
1143 /* [A0 + 4] = instruction cache size */
1144 /* [A0 + 8] = data cache size */
1146 unsigned_4 value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1147 unsigned_4 zero
= 0;
1149 sim_write (sd
, A0
+ 0, (char *)&value
, 4);
1150 sim_write (sd
, A0
+ 4, (char *)&zero
, 4);
1151 sim_write (sd
, A0
+ 8, (char *)&zero
, 4);
1152 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1156 case 158 : /* PMON printf */
1157 /* in: A0 = pointer to format string */
1158 /* A1 = optional argument 1 */
1159 /* A2 = optional argument 2 */
1160 /* A3 = optional argument 3 */
1162 /* The following is based on the PMON printf source */
1164 address_word s
= A0
;
1166 signed_word
*ap
= &A1
; /* 1st argument */
1167 /* This isn't the quickest way, since we call the host print
1168 routine for every character almost. But it does avoid
1169 having to allocate and manage a temporary string buffer. */
1170 /* TODO: Include check that we only use three arguments (A1,
1172 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1177 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1178 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1179 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1181 if (strchr ("dobxXulscefg%", s
))
1196 else if (c
>= '1' && c
<= '9')
1200 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1203 n
= (unsigned int)strtol(tmp
,NULL
,10);
1216 sim_io_printf (sd
, "%%");
1221 address_word p
= *ap
++;
1223 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1224 sim_io_printf(sd
, "%c", ch
);
1227 sim_io_printf(sd
,"(null)");
1230 sim_io_printf (sd
, "%c", (int)*ap
++);
1235 sim_read (sd
, s
++, &c
, 1);
1239 sim_read (sd
, s
++, &c
, 1);
1242 if (strchr ("dobxXu", c
))
1244 word64 lv
= (word64
) *ap
++;
1246 sim_io_printf(sd
,"<binary not supported>");
1249 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1251 sim_io_printf(sd
, tmp
, lv
);
1253 sim_io_printf(sd
, tmp
, (int)lv
);
1256 else if (strchr ("eEfgG", c
))
1258 double dbl
= *(double*)(ap
++);
1259 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1260 sim_io_printf (sd
, tmp
, dbl
);
1266 sim_io_printf(sd
, "%c", c
);
1272 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1273 reason
, pr_addr(cia
));
1279 /* Store a word into memory. */
1282 store_word (SIM_DESC sd
,
1291 if ((vaddr
& 3) != 0)
1292 SignalExceptionAddressStore ();
1295 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1298 const uword64 mask
= 7;
1302 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1303 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1304 memval
= ((uword64
) val
) << (8 * byte
);
1305 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1311 /* Load a word from memory. */
1314 load_word (SIM_DESC sd
,
1319 if ((vaddr
& 3) != 0)
1320 SignalExceptionAddressLoad ();
1326 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1329 const uword64 mask
= 0x7;
1330 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1331 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1335 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1336 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1338 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1339 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1346 /* Simulate the mips16 entry and exit pseudo-instructions. These
1347 would normally be handled by the reserved instruction exception
1348 code, but for ease of simulation we just handle them directly. */
1351 mips16_entry (SIM_DESC sd
,
1356 int aregs
, sregs
, rreg
;
1359 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1362 aregs
= (insn
& 0x700) >> 8;
1363 sregs
= (insn
& 0x0c0) >> 6;
1364 rreg
= (insn
& 0x020) >> 5;
1366 /* This should be checked by the caller. */
1375 /* This is the entry pseudo-instruction. */
1377 for (i
= 0; i
< aregs
; i
++)
1378 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1386 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1389 for (i
= 0; i
< sregs
; i
++)
1392 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1400 /* This is the exit pseudo-instruction. */
1407 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1410 for (i
= 0; i
< sregs
; i
++)
1413 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1418 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1422 FGR
[0] = WORD64LO (GPR
[4]);
1423 FPR_STATE
[0] = fmt_uninterpreted
;
1425 else if (aregs
== 6)
1427 FGR
[0] = WORD64LO (GPR
[5]);
1428 FGR
[1] = WORD64LO (GPR
[4]);
1429 FPR_STATE
[0] = fmt_uninterpreted
;
1430 FPR_STATE
[1] = fmt_uninterpreted
;
1439 /*-- trace support ----------------------------------------------------------*/
1441 /* The TRACE support is provided (if required) in the memory accessing
1442 routines. Since we are also providing the architecture specific
1443 features, the architecture simulation code can also deal with
1444 notifying the TRACE world of cache flushes, etc. Similarly we do
1445 not need to provide profiling support in the simulator engine,
1446 since we can sample in the instruction fetch control loop. By
1447 defining the TRACE manifest, we add tracing as a run-time
1451 /* Tracing by default produces "din" format (as required by
1452 dineroIII). Each line of such a trace file *MUST* have a din label
1453 and address field. The rest of the line is ignored, so comments can
1454 be included if desired. The first field is the label which must be
1455 one of the following values:
1460 3 escape record (treated as unknown access type)
1461 4 escape record (causes cache flush)
1463 The address field is a 32bit (lower-case) hexadecimal address
1464 value. The address should *NOT* be preceded by "0x".
1466 The size of the memory transfer is not important when dealing with
1467 cache lines (as long as no more than a cache line can be
1468 transferred in a single operation :-), however more information
1469 could be given following the dineroIII requirement to allow more
1470 complete memory and cache simulators to provide better
1471 results. i.e. the University of Pisa has a cache simulator that can
1472 also take bus size and speed as (variable) inputs to calculate
1473 complete system performance (a much more useful ability when trying
1474 to construct an end product, rather than a processor). They
1475 currently have an ARM version of their tool called ChARM. */
1479 dotrace (SIM_DESC sd
,
1487 if (STATE
& simTRACE
) {
1489 fprintf(tracefh
,"%d %s ; width %d ; ",
1493 va_start(ap
,comment
);
1494 vfprintf(tracefh
,comment
,ap
);
1496 fprintf(tracefh
,"\n");
1498 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1499 we may be generating 64bit ones, we should put the hi-32bits of the
1500 address into the comment field. */
1502 /* TODO: Provide a buffer for the trace lines. We can then avoid
1503 performing writes until the buffer is filled, or the file is
1506 /* NOTE: We could consider adding a comment field to the "din" file
1507 produced using type 3 markers (unknown access). This would then
1508 allow information about the program that the "din" is for, and
1509 the MIPs world that was being simulated, to be placed into the
1516 /*---------------------------------------------------------------------------*/
1517 /*-- simulator engine -------------------------------------------------------*/
1518 /*---------------------------------------------------------------------------*/
1521 ColdReset (SIM_DESC sd
)
1524 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1526 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1527 /* RESET: Fixed PC address: */
1528 PC
= UNSIGNED64 (0xFFFFFFFFBFC00000);
1529 /* The reset vector address is in the unmapped, uncached memory space. */
1531 SR
&= ~(status_SR
| status_TS
| status_RP
);
1532 SR
|= (status_ERL
| status_BEV
);
1534 /* Cheat and allow access to the complete register set immediately */
1535 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1536 && WITH_TARGET_WORD_BITSIZE
== 64)
1537 SR
|= status_FR
; /* 64bit registers */
1539 /* Ensure that any instructions with pending register updates are
1541 PENDING_INVALIDATE();
1543 /* Initialise the FPU registers to the unknown state */
1544 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1547 for (rn
= 0; (rn
< 32); rn
++)
1548 FPR_STATE
[rn
] = fmt_uninterpreted
;
1554 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1555 /* Signal an exception condition. This will result in an exception
1556 that aborts the instruction. The instruction operation pseudocode
1557 will never see a return from this function call. */
1560 signal_exception (SIM_DESC sd
,
1568 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1571 /* Ensure that any active atomic read/modify/write operation will fail: */
1574 switch (exception
) {
1575 /* TODO: For testing purposes I have been ignoring TRAPs. In
1576 reality we should either simulate them, or allow the user to
1577 ignore them at run-time.
1580 sim_io_eprintf(sd
,"Ignoring instruction TRAP (PC 0x%s)\n",pr_addr(cia
));
1586 unsigned int instruction
;
1589 va_start(ap
,exception
);
1590 instruction
= va_arg(ap
,unsigned int);
1593 code
= (instruction
>> 6) & 0xFFFFF;
1595 sim_io_eprintf(sd
,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
1596 code
, pr_addr(cia
));
1600 case DebugBreakPoint
:
1601 if (! (Debug
& Debug_DM
))
1607 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1608 DEPC
= cia
- 4; /* reference the branch instruction */
1612 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1616 Debug
|= Debug_DM
; /* in debugging mode */
1617 Debug
|= Debug_DBp
; /* raising a DBp exception */
1619 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1623 case ReservedInstruction
:
1626 unsigned int instruction
;
1627 va_start(ap
,exception
);
1628 instruction
= va_arg(ap
,unsigned int);
1630 /* Provide simple monitor support using ReservedInstruction
1631 exceptions. The following code simulates the fixed vector
1632 entry points into the IDT monitor by causing a simulator
1633 trap, performing the monitor operation, and returning to
1634 the address held in the $ra register (standard PCS return
1635 address). This means we only need to pre-load the vector
1636 space with suitable instruction values. For systems were
1637 actual trap instructions are used, we would not need to
1638 perform this magic. */
1639 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1641 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
1642 /* NOTE: This assumes that a branch-and-link style
1643 instruction was used to enter the vector (which is the
1644 case with the current IDT monitor). */
1645 sim_engine_restart (SD
, CPU
, NULL
, RA
);
1647 /* Look for the mips16 entry and exit instructions, and
1648 simulate a handler for them. */
1649 else if ((cia
& 1) != 0
1650 && (instruction
& 0xf81f) == 0xe809
1651 && (instruction
& 0x0c0) != 0x0c0)
1653 mips16_entry (SD
, CPU
, cia
, instruction
);
1654 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1656 /* else fall through to normal exception processing */
1657 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
1662 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1664 /* Keep a copy of the current A0 in-case this is the program exit
1668 unsigned int instruction
;
1669 va_start(ap
,exception
);
1670 instruction
= va_arg(ap
,unsigned int);
1672 /* Check for our special terminating BREAK: */
1673 if ((instruction
& 0x03FFFFC0) == 0x03ff0000) {
1674 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1675 sim_exited
, (unsigned int)(A0
& 0xFFFFFFFF));
1678 if (STATE
& simDELAYSLOT
)
1679 PC
= cia
- 4; /* reference the branch instruction */
1682 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1683 sim_stopped
, SIM_SIGTRAP
);
1686 /* Store exception code into current exception id variable (used
1689 /* TODO: If not simulating exceptions then stop the simulator
1690 execution. At the moment we always stop the simulation. */
1692 /* See figure 5-17 for an outline of the code below */
1693 if (! (SR
& status_EXL
))
1695 CAUSE
= (exception
<< 2);
1696 if (STATE
& simDELAYSLOT
)
1698 STATE
&= ~simDELAYSLOT
;
1700 EPC
= (cia
- 4); /* reference the branch instruction */
1704 /* FIXME: TLB et.al. */
1709 CAUSE
= (exception
<< 2);
1713 /* Store exception code into current exception id variable (used
1715 if (SR
& status_BEV
)
1716 PC
= (signed)0xBFC00200 + 0x180;
1718 PC
= (signed)0x80000000 + 0x180;
1720 switch ((CAUSE
>> 2) & 0x1F)
1723 /* Interrupts arrive during event processing, no need to
1727 case TLBModification
:
1732 case InstructionFetch
:
1734 /* The following is so that the simulator will continue from the
1735 exception address on breakpoint operations. */
1737 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1738 sim_stopped
, SIM_SIGBUS
);
1740 case ReservedInstruction
:
1741 case CoProcessorUnusable
:
1743 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1744 sim_stopped
, SIM_SIGILL
);
1746 case IntegerOverflow
:
1748 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1749 sim_stopped
, SIM_SIGFPE
);
1755 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1756 sim_stopped
, SIM_SIGTRAP
);
1760 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1761 "FATAL: Should not encounter a breakpoint\n");
1763 default : /* Unknown internal exception */
1765 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1766 sim_stopped
, SIM_SIGABRT
);
1770 case SimulatorFault
:
1774 va_start(ap
,exception
);
1775 msg
= va_arg(ap
,char *);
1777 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1778 "FATAL: Simulator error \"%s\"\n",msg
);
1785 #if defined(WARN_RESULT)
1786 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1787 /* This function indicates that the result of the operation is
1788 undefined. However, this should not affect the instruction
1789 stream. All that is meant to happen is that the destination
1790 register is set to an undefined result. To keep the simulator
1791 simple, we just don't bother updating the destination register, so
1792 the overall result will be undefined. If desired we can stop the
1793 simulator by raising a pseudo-exception. */
1794 #define UndefinedResult() undefined_result (sd,cia)
1796 undefined_result(sd
,cia
)
1800 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
1801 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
1806 #endif /* WARN_RESULT */
1808 /*-- FPU support routines ---------------------------------------------------*/
1810 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
1811 formats conform to ANSI/IEEE Std 754-1985. */
1812 /* SINGLE precision floating:
1813 * seeeeeeeefffffffffffffffffffffff
1815 * e = 8bits = exponent
1816 * f = 23bits = fraction
1818 /* SINGLE precision fixed:
1819 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1821 * i = 31bits = integer
1823 /* DOUBLE precision floating:
1824 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
1826 * e = 11bits = exponent
1827 * f = 52bits = fraction
1829 /* DOUBLE precision fixed:
1830 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1832 * i = 63bits = integer
1835 /* Extract sign-bit: */
1836 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
1837 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
1838 /* Extract biased exponent: */
1839 #define FP_S_be(v) (((v) >> 23) & 0xFF)
1840 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
1841 /* Extract unbiased Exponent: */
1842 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
1843 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
1844 /* Extract complete fraction field: */
1845 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
1846 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
1847 /* Extract numbered fraction bit: */
1848 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
1849 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
1851 /* Explicit QNaN values used when value required: */
1852 #define FPQNaN_SINGLE (0x7FBFFFFF)
1853 #define FPQNaN_WORD (0x7FFFFFFF)
1854 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
1855 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
1857 /* Explicit Infinity values used when required: */
1858 #define FPINF_SINGLE (0x7F800000)
1859 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
1861 #if 1 /* def DEBUG */
1862 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
1863 #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>"))))))
1867 value_fpr (SIM_DESC sd
,
1876 /* Treat unused register values, as fixed-point 64bit values: */
1877 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
1879 /* If request to read data as "uninterpreted", then use the current
1881 fmt
= FPR_STATE
[fpr
];
1886 /* For values not yet accessed, set to the desired format: */
1887 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
1888 FPR_STATE
[fpr
] = fmt
;
1890 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
1893 if (fmt
!= FPR_STATE
[fpr
]) {
1894 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
));
1895 FPR_STATE
[fpr
] = fmt_unknown
;
1898 if (FPR_STATE
[fpr
] == fmt_unknown
) {
1899 /* Set QNaN value: */
1902 value
= FPQNaN_SINGLE
;
1906 value
= FPQNaN_DOUBLE
;
1910 value
= FPQNaN_WORD
;
1914 value
= FPQNaN_LONG
;
1921 } else if (SizeFGR() == 64) {
1925 value
= (FGR
[fpr
] & 0xFFFFFFFF);
1928 case fmt_uninterpreted
:
1942 value
= (FGR
[fpr
] & 0xFFFFFFFF);
1945 case fmt_uninterpreted
:
1948 if ((fpr
& 1) == 0) { /* even registers only */
1949 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
1951 SignalException(ReservedInstruction
,0);
1962 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
1965 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());
1972 store_fpr (SIM_DESC sd
,
1982 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());
1985 if (SizeFGR() == 64) {
1987 case fmt_uninterpreted_32
:
1988 fmt
= fmt_uninterpreted
;
1991 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
1992 FPR_STATE
[fpr
] = fmt
;
1995 case fmt_uninterpreted_64
:
1996 fmt
= fmt_uninterpreted
;
1997 case fmt_uninterpreted
:
2001 FPR_STATE
[fpr
] = fmt
;
2005 FPR_STATE
[fpr
] = fmt_unknown
;
2011 case fmt_uninterpreted_32
:
2012 fmt
= fmt_uninterpreted
;
2015 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2016 FPR_STATE
[fpr
] = fmt
;
2019 case fmt_uninterpreted_64
:
2020 fmt
= fmt_uninterpreted
;
2021 case fmt_uninterpreted
:
2024 if ((fpr
& 1) == 0) { /* even register number only */
2025 FGR
[fpr
+1] = (value
>> 32);
2026 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2027 FPR_STATE
[fpr
+ 1] = fmt
;
2028 FPR_STATE
[fpr
] = fmt
;
2030 FPR_STATE
[fpr
] = fmt_unknown
;
2031 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2032 SignalException(ReservedInstruction
,0);
2037 FPR_STATE
[fpr
] = fmt_unknown
;
2042 #if defined(WARN_RESULT)
2045 #endif /* WARN_RESULT */
2048 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2051 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_addr(FGR
[fpr
]),DOFMT(fmt
));
2068 sim_fpu_32to (&wop
, op
);
2069 boolean
= sim_fpu_is_nan (&wop
);
2076 sim_fpu_64to (&wop
, op
);
2077 boolean
= sim_fpu_is_nan (&wop
);
2081 fprintf (stderr
, "Bad switch\n");
2086 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2100 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2107 sim_fpu_32to (&wop
, op
);
2108 boolean
= sim_fpu_is_infinity (&wop
);
2114 sim_fpu_64to (&wop
, op
);
2115 boolean
= sim_fpu_is_infinity (&wop
);
2119 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2124 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2138 /* Argument checking already performed by the FPCOMPARE code */
2141 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2144 /* The format type should already have been checked: */
2150 sim_fpu_32to (&wop1
, op1
);
2151 sim_fpu_32to (&wop2
, op2
);
2152 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2159 sim_fpu_64to (&wop1
, op1
);
2160 sim_fpu_64to (&wop2
, op2
);
2161 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2165 fprintf (stderr
, "Bad switch\n");
2170 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2184 /* Argument checking already performed by the FPCOMPARE code */
2187 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2190 /* The format type should already have been checked: */
2196 sim_fpu_32to (&wop1
, op1
);
2197 sim_fpu_32to (&wop2
, op2
);
2198 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2205 sim_fpu_64to (&wop1
, op1
);
2206 sim_fpu_64to (&wop2
, op2
);
2207 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2211 fprintf (stderr
, "Bad switch\n");
2216 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2223 AbsoluteValue(op
,fmt
)
2230 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2233 /* The format type should already have been checked: */
2239 sim_fpu_32to (&wop
, op
);
2240 sim_fpu_abs (&wop
, &wop
);
2241 sim_fpu_to32 (&ans
, &wop
);
2249 sim_fpu_64to (&wop
, op
);
2250 sim_fpu_abs (&wop
, &wop
);
2251 sim_fpu_to64 (&ans
, &wop
);
2256 fprintf (stderr
, "Bad switch\n");
2271 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2274 /* The format type should already have been checked: */
2280 sim_fpu_32to (&wop
, op
);
2281 sim_fpu_neg (&wop
, &wop
);
2282 sim_fpu_to32 (&ans
, &wop
);
2290 sim_fpu_64to (&wop
, op
);
2291 sim_fpu_neg (&wop
, &wop
);
2292 sim_fpu_to64 (&ans
, &wop
);
2297 fprintf (stderr
, "Bad switch\n");
2313 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2316 /* The registers must specify FPRs valid for operands of type
2317 "fmt". If they are not valid, the result is undefined. */
2319 /* The format type should already have been checked: */
2327 sim_fpu_32to (&wop1
, op1
);
2328 sim_fpu_32to (&wop2
, op2
);
2329 sim_fpu_add (&ans
, &wop1
, &wop2
);
2330 sim_fpu_to32 (&res
, &ans
);
2340 sim_fpu_64to (&wop1
, op1
);
2341 sim_fpu_64to (&wop2
, op2
);
2342 sim_fpu_add (&ans
, &wop1
, &wop2
);
2343 sim_fpu_to64 (&res
, &ans
);
2348 fprintf (stderr
, "Bad switch\n");
2353 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2368 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2371 /* The registers must specify FPRs valid for operands of type
2372 "fmt". If they are not valid, the result is undefined. */
2374 /* The format type should already have been checked: */
2382 sim_fpu_32to (&wop1
, op1
);
2383 sim_fpu_32to (&wop2
, op2
);
2384 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2385 sim_fpu_to32 (&res
, &ans
);
2395 sim_fpu_64to (&wop1
, op1
);
2396 sim_fpu_64to (&wop2
, op2
);
2397 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2398 sim_fpu_to64 (&res
, &ans
);
2403 fprintf (stderr
, "Bad switch\n");
2408 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2415 Multiply(op1
,op2
,fmt
)
2423 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2426 /* The registers must specify FPRs valid for operands of type
2427 "fmt". If they are not valid, the result is undefined. */
2429 /* The format type should already have been checked: */
2437 sim_fpu_32to (&wop1
, op1
);
2438 sim_fpu_32to (&wop2
, op2
);
2439 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2440 sim_fpu_to32 (&res
, &ans
);
2450 sim_fpu_64to (&wop1
, op1
);
2451 sim_fpu_64to (&wop2
, op2
);
2452 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2453 sim_fpu_to64 (&res
, &ans
);
2458 fprintf (stderr
, "Bad switch\n");
2463 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2478 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2481 /* The registers must specify FPRs valid for operands of type
2482 "fmt". If they are not valid, the result is undefined. */
2484 /* The format type should already have been checked: */
2492 sim_fpu_32to (&wop1
, op1
);
2493 sim_fpu_32to (&wop2
, op2
);
2494 sim_fpu_div (&ans
, &wop1
, &wop2
);
2495 sim_fpu_to32 (&res
, &ans
);
2505 sim_fpu_64to (&wop1
, op1
);
2506 sim_fpu_64to (&wop2
, op2
);
2507 sim_fpu_div (&ans
, &wop1
, &wop2
);
2508 sim_fpu_to64 (&res
, &ans
);
2513 fprintf (stderr
, "Bad switch\n");
2518 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2532 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2535 /* The registers must specify FPRs valid for operands of type
2536 "fmt". If they are not valid, the result is undefined. */
2538 /* The format type should already have been checked: */
2545 sim_fpu_32to (&wop
, op
);
2546 sim_fpu_inv (&ans
, &wop
);
2547 sim_fpu_to32 (&res
, &ans
);
2556 sim_fpu_64to (&wop
, op
);
2557 sim_fpu_inv (&ans
, &wop
);
2558 sim_fpu_to64 (&res
, &ans
);
2563 fprintf (stderr
, "Bad switch\n");
2568 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2582 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2585 /* The registers must specify FPRs valid for operands of type
2586 "fmt". If they are not valid, the result is undefined. */
2588 /* The format type should already have been checked: */
2595 sim_fpu_32to (&wop
, op
);
2596 sim_fpu_sqrt (&ans
, &wop
);
2597 sim_fpu_to32 (&res
, &ans
);
2606 sim_fpu_64to (&wop
, op
);
2607 sim_fpu_sqrt (&ans
, &wop
);
2608 sim_fpu_to64 (&res
, &ans
);
2613 fprintf (stderr
, "Bad switch\n");
2618 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2634 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2637 /* The registers must specify FPRs valid for operands of type
2638 "fmt". If they are not valid, the result is undefined. */
2640 /* The format type should already have been checked: */
2647 sim_fpu_32to (&wop1
, op1
);
2648 sim_fpu_32to (&wop2
, op2
);
2649 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2656 sim_fpu_64to (&wop1
, op1
);
2657 sim_fpu_64to (&wop2
, op2
);
2658 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2662 fprintf (stderr
, "Bad switch\n");
2668 case SIM_FPU_IS_SNAN
:
2669 case SIM_FPU_IS_QNAN
:
2671 case SIM_FPU_IS_NINF
:
2672 case SIM_FPU_IS_NNUMBER
:
2673 case SIM_FPU_IS_NDENORM
:
2674 case SIM_FPU_IS_NZERO
:
2675 result
= op2
; /* op1 - op2 < 0 */
2676 case SIM_FPU_IS_PINF
:
2677 case SIM_FPU_IS_PNUMBER
:
2678 case SIM_FPU_IS_PDENORM
:
2679 case SIM_FPU_IS_PZERO
:
2680 result
= op1
; /* op1 - op2 > 0 */
2682 fprintf (stderr
, "Bad switch\n");
2687 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2704 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2707 /* The registers must specify FPRs valid for operands of type
2708 "fmt". If they are not valid, the result is undefined. */
2710 /* The format type should already have been checked: */
2717 sim_fpu_32to (&wop1
, op1
);
2718 sim_fpu_32to (&wop2
, op2
);
2719 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2726 sim_fpu_64to (&wop1
, op1
);
2727 sim_fpu_64to (&wop2
, op2
);
2728 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2732 fprintf (stderr
, "Bad switch\n");
2738 case SIM_FPU_IS_SNAN
:
2739 case SIM_FPU_IS_QNAN
:
2741 case SIM_FPU_IS_NINF
:
2742 case SIM_FPU_IS_NNUMBER
:
2743 case SIM_FPU_IS_NDENORM
:
2744 case SIM_FPU_IS_NZERO
:
2745 result
= op1
; /* op1 - op2 < 0 */
2746 case SIM_FPU_IS_PINF
:
2747 case SIM_FPU_IS_PNUMBER
:
2748 case SIM_FPU_IS_PDENORM
:
2749 case SIM_FPU_IS_PZERO
:
2750 result
= op2
; /* op1 - op2 > 0 */
2752 fprintf (stderr
, "Bad switch\n");
2757 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2765 convert (SIM_DESC sd
,
2774 sim_fpu_round round
;
2775 unsigned32 result32
;
2776 unsigned64 result64
;
2779 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
));
2785 /* Round result to nearest representable value. When two
2786 representable values are equally near, round to the value
2787 that has a least significant bit of zero (i.e. is even). */
2788 round
= sim_fpu_round_near
;
2791 /* Round result to the value closest to, and not greater in
2792 magnitude than, the result. */
2793 round
= sim_fpu_round_zero
;
2796 /* Round result to the value closest to, and not less than,
2798 round
= sim_fpu_round_up
;
2802 /* Round result to the value closest to, and not greater than,
2804 round
= sim_fpu_round_down
;
2808 fprintf (stderr
, "Bad switch\n");
2812 /* Convert the input to sim_fpu internal format */
2816 sim_fpu_64to (&wop
, op
);
2819 sim_fpu_32to (&wop
, op
);
2822 sim_fpu_i32to (&wop
, op
, round
);
2825 sim_fpu_i64to (&wop
, op
, round
);
2828 fprintf (stderr
, "Bad switch\n");
2832 /* Convert sim_fpu format into the output */
2833 /* The value WOP is converted to the destination format, rounding
2834 using mode RM. When the destination is a fixed-point format, then
2835 a source value of Infinity, NaN or one which would round to an
2836 integer outside the fixed point range then an IEEE Invalid
2837 Operation condition is raised. */
2841 sim_fpu_round_32 (&wop
, round
, 0);
2842 sim_fpu_to32 (&result32
, &wop
);
2843 result64
= result32
;
2846 sim_fpu_round_64 (&wop
, round
, 0);
2847 sim_fpu_to64 (&result64
, &wop
);
2850 sim_fpu_to32i (&result32
, &wop
, round
);
2851 result64
= result32
;
2854 sim_fpu_to64i (&result64
, &wop
, round
);
2858 fprintf (stderr
, "Bad switch\n");
2863 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
2870 /*-- co-processor support routines ------------------------------------------*/
2873 CoProcPresent(coproc_number
)
2874 unsigned int coproc_number
;
2876 /* Return TRUE if simulator provides a model for the given co-processor number */
2881 cop_lw (SIM_DESC sd
,
2886 unsigned int memword
)
2891 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2894 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
2896 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
2897 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
2902 #if 0 /* this should be controlled by a configuration option */
2903 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
));
2912 cop_ld (SIM_DESC sd
,
2919 switch (coproc_num
) {
2921 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2923 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
2928 #if 0 /* this message should be controlled by a configuration option */
2929 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
));
2938 /* start-sanitize-sky */
2941 cop_lq (SIM_DESC sd
,
2946 unsigned128 memword
)
2957 memcpy(& xyzw
, & memword
, sizeof(xyzw
));
2958 xyzw
= H2T_16(xyzw
);
2959 /* one word at a time, argh! */
2960 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, 0, A4_16(& xyzw
, 3));
2961 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, 1, A4_16(& xyzw
, 2));
2962 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, 2, A4_16(& xyzw
, 1));
2963 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, 3, A4_16(& xyzw
, 0));
2968 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
2969 coproc_num
,coproc_reg
,pr_addr(cia
));
2975 #endif /* TARGET_SKY */
2976 /* end-sanitize-sky */
2980 cop_sw (SIM_DESC sd
,
2986 unsigned int value
= 0;
2991 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2994 hold
= FPR_STATE
[coproc_reg
];
2995 FPR_STATE
[coproc_reg
] = fmt_word
;
2996 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
2997 FPR_STATE
[coproc_reg
] = hold
;
3002 #if 0 /* should be controlled by configuration option */
3003 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3012 cop_sd (SIM_DESC sd
,
3022 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3024 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3029 #if 0 /* should be controlled by configuration option */
3030 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3039 /* start-sanitize-sky */
3042 cop_sq (SIM_DESC sd
,
3048 unsigned128 value
= U16_8(0, 0);
3058 /* one word at a time, argh! */
3059 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, 0, A4_16(& xyzw
, 3));
3060 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, 1, A4_16(& xyzw
, 2));
3061 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, 2, A4_16(& xyzw
, 1));
3062 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, 3, A4_16(& xyzw
, 0));
3063 xyzw
= T2H_16(xyzw
);
3069 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3070 coproc_num
,coproc_reg
,pr_addr(cia
));
3076 #endif /* TARGET_SKY */
3077 /* end-sanitize-sky */
3081 decode_coproc (SIM_DESC sd
,
3084 unsigned int instruction
)
3086 int coprocnum
= ((instruction
>> 26) & 3);
3090 case 0: /* standard CPU control and cache registers */
3092 int code
= ((instruction
>> 21) & 0x1F);
3093 /* R4000 Users Manual (second edition) lists the following CP0
3095 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3096 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3097 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3098 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3099 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3100 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3101 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3102 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3103 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3104 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3106 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0))
3108 int rt
= ((instruction
>> 16) & 0x1F);
3109 int rd
= ((instruction
>> 11) & 0x1F);
3111 switch (rd
) /* NOTEs: Standard CP0 registers */
3113 /* 0 = Index R4000 VR4100 VR4300 */
3114 /* 1 = Random R4000 VR4100 VR4300 */
3115 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3116 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3117 /* 4 = Context R4000 VR4100 VR4300 */
3118 /* 5 = PageMask R4000 VR4100 VR4300 */
3119 /* 6 = Wired R4000 VR4100 VR4300 */
3120 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3121 /* 9 = Count R4000 VR4100 VR4300 */
3122 /* 10 = EntryHi R4000 VR4100 VR4300 */
3123 /* 11 = Compare R4000 VR4100 VR4300 */
3124 /* 12 = SR R4000 VR4100 VR4300 */
3131 /* 13 = Cause R4000 VR4100 VR4300 */
3138 /* 14 = EPC R4000 VR4100 VR4300 */
3139 /* 15 = PRId R4000 VR4100 VR4300 */
3140 #ifdef SUBTARGET_R3900
3149 /* 16 = Config R4000 VR4100 VR4300 */
3152 GPR
[rt
] = C0_CONFIG
;
3154 C0_CONFIG
= GPR
[rt
];
3157 #ifdef SUBTARGET_R3900
3166 /* 17 = LLAddr R4000 VR4100 VR4300 */
3168 /* 18 = WatchLo R4000 VR4100 VR4300 */
3169 /* 19 = WatchHi R4000 VR4100 VR4300 */
3170 /* 20 = XContext R4000 VR4100 VR4300 */
3171 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3172 /* 27 = CacheErr R4000 VR4100 */
3173 /* 28 = TagLo R4000 VR4100 VR4300 */
3174 /* 29 = TagHi R4000 VR4100 VR4300 */
3175 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3176 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3177 /* CPR[0,rd] = GPR[rt]; */
3180 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3182 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3185 else if (code
== 0x10 && (instruction
& 0x3f) == 0x18)
3188 if (SR
& status_ERL
)
3190 /* Oops, not yet available */
3191 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3201 else if (code
== 0x10 && (instruction
& 0x3f) == 0x10)
3205 else if (code
== 0x10 && (instruction
& 0x3f) == 0x1F)
3213 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3214 /* TODO: When executing an ERET or RFE instruction we should
3215 clear LLBIT, to ensure that any out-standing atomic
3216 read/modify/write sequence fails. */
3220 case 2: /* co-processor 2 */
3224 /* start-sanitize-sky */
3226 /* On the R5900, this refers to a "VU" vector co-processor. */
3228 int i_25_21
= (instruction
>> 21) & 0x1f;
3229 int i_20_16
= (instruction
>> 16) & 0x1f;
3230 int i_20_6
= (instruction
>> 6) & 0x7fff;
3231 int i_15_11
= (instruction
>> 11) & 0x1f;
3232 int i_15_0
= instruction
& 0xffff;
3233 int i_10_1
= (instruction
>> 1) & 0x3ff;
3234 int i_10_0
= instruction
& 0x7ff;
3235 int i_10_6
= (instruction
>> 6) & 0x1f;
3236 int i_5_0
= instruction
& 0x03f;
3237 int interlock
= instruction
& 0x01;
3238 /* setup for semantic.c-like actions below */
3239 typedef unsigned_4 instruction_word
;
3242 sim_cpu
* CPU_
= cpu
;
3246 /* test COP2 usability */
3247 if(! (SR
& status_CU2
))
3249 SignalException(CoProcessorUnusable
,instruction
);
3253 /* classify & execute basic COP2 instructions */
3254 if(i_25_21
== 0x08 && i_20_16
== 0x00) /* BC2F */
3256 address_word offset
= EXTEND16(i_15_0
) << 2;
3257 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3259 else if(i_25_21
== 0x08 && i_20_16
==0x02) /* BC2FL */
3261 address_word offset
= EXTEND16(i_15_0
) << 2;
3262 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3263 else NULLIFY_NEXT_INSTRUCTION();
3265 else if(i_25_21
== 0x08 && i_20_16
== 0x01) /* BC2T */
3267 address_word offset
= EXTEND16(i_15_0
) << 2;
3268 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3270 else if(i_25_21
== 0x08 && i_20_16
== 0x03) /* BC2TL */
3272 address_word offset
= EXTEND16(i_15_0
) << 2;
3273 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3274 else NULLIFY_NEXT_INSTRUCTION();
3276 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3277 (i_25_21
== 0x01)) /* QMFC2 */
3282 /* interlock checking */
3283 /* POLICY: never busy in macro mode */
3284 while(vu0_busy() && interlock
)
3287 /* perform VU register address */
3288 if(i_25_21
== 0x01) /* QMFC2 */
3291 /* one word at a time, argh! */
3292 read_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3293 read_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3294 read_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3295 read_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3296 xyzw
= T2H_16(xyzw
);
3297 memcpy(& GPR
[rt
], & xyzw
, sizeof(xyzw
));
3302 /* enum + int calculation, argh! */
3303 id
= VU_REG_MST
+ 16 * id
;
3304 read_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3305 GPR
[rt
] = EXTEND32(T2H_4(data
));
3308 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3309 (i_25_21
== 0x05)) /* QMTC2 */
3314 /* interlock checking */
3315 /* POLICY: never busy in macro mode */
3316 if(vu0_busy() && interlock
)
3318 while(! vu0_micro_interlock_released())
3322 /* perform VU register address */
3323 if(i_25_21
== 0x05) /* QMTC2 */
3326 memcpy(& xyzw
, & GPR
[rt
], sizeof(xyzw
));
3327 xyzw
= H2T_16(xyzw
);
3328 /* one word at a time, argh! */
3329 write_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3330 write_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3331 write_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3332 write_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3336 unsigned_4 data
= H2T_4(GPR
[rt
]);
3337 /* enum + int calculation, argh! */
3338 id
= VU_REG_MST
+ 16 * id
;
3339 write_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3342 else if(i_10_0
== 0x3bf) /* VWAITQ */
3347 else if(i_5_0
== 0x38) /* VCALLMS */
3349 unsigned_4 data
= H2T_2(i_20_6
);
3354 /* write to reserved CIA register to get VU0 moving */
3355 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3359 else if(i_5_0
== 0x39) /* VCALLMSR */
3366 read_vu_special_reg(& vu0_device
, VU_REG_CMSAR0
, & data
);
3367 /* write to reserved CIA register to get VU0 moving */
3368 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3372 /* handle all remaining UPPER VU instructions in one block */
3373 else if((i_5_0
< 0x30) || /* VADDx .. VMINI */
3374 (i_5_0
>= 0x3c && i_10_6
< 0x0c)) /* VADDAx .. VNOP */
3376 unsigned_4 vu_upper
, vu_lower
;
3378 0x00000000 | /* bits 31 .. 25 */
3379 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3380 vu_lower
= 0x8000033c; /* NOP */
3382 /* POLICY: never busy in macro mode */
3386 vu0_macro_issue(vu_upper
, vu_lower
);
3388 /* POLICY: wait for completion of macro-instruction */
3392 /* handle all remaining LOWER VU instructions in one block */
3393 else if((i_5_0
>= 0x30 && i_5_0
<= 0x35) || /* VIADD .. VIOR */
3394 (i_5_0
>= 0x3c && i_10_6
>= 0x0c)) /* VMOVE .. VRXOR */
3395 { /* N.B.: VWAITQ already covered by prior case */
3396 unsigned_4 vu_upper
, vu_lower
;
3397 vu_upper
= 0x000002ff; /* NOP/NOP */
3399 0x80000000 | /* bits 31 .. 25 */
3400 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3402 /* POLICY: never busy in macro mode */
3406 vu0_macro_issue(vu_upper
, vu_lower
);
3408 /* POLICY: wait for completion of macro-instruction */
3412 /* ... no other COP2 instructions ... */
3415 SignalException(ReservedInstruction
, instruction
);
3419 /* cleanup for semantic.c-like actions above */
3422 #endif /* TARGET_SKY */
3423 /* end-sanitize-sky */
3427 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3428 instruction
,pr_addr(cia
));
3433 case 1: /* should not occur (FPU co-processor) */
3434 case 3: /* should not occur (FPU co-processor) */
3435 SignalException(ReservedInstruction
,instruction
);
3443 /*-- instruction simulation -------------------------------------------------*/
3445 /* When the IGEN simulator is being built, the function below is be
3446 replaced by a generated version. However, WITH_IGEN == 2 indicates
3447 that the fubction below should be compiled but under a different
3448 name (to allow backward compatibility) */
3450 #if (WITH_IGEN != 1)
3452 void old_engine_run
PARAMS ((SIM_DESC sd
, int next_cpu_nr
, int siggnal
));
3454 old_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3457 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3460 int next_cpu_nr
; /* ignore */
3461 int nr_cpus
; /* ignore */
3462 int siggnal
; /* ignore */
3464 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* hardwire to cpu 0 */
3465 #if !defined(FASTSIM)
3466 unsigned int pipeline_count
= 1;
3470 if (STATE_MEMORY (sd
) == NULL
) {
3471 printf("DBG: simulate() entered with no memory\n");
3476 #if 0 /* Disabled to check that everything works OK */
3477 /* The VR4300 seems to sign-extend the PC on its first
3478 access. However, this may just be because it is currently
3479 configured in 32bit mode. However... */
3480 PC
= SIGNEXTEND(PC
,32);
3483 /* main controlling loop */
3485 /* vaddr is slowly being replaced with cia - current instruction
3487 address_word cia
= (uword64
)PC
;
3488 address_word vaddr
= cia
;
3491 unsigned int instruction
; /* uword64? what's this used for? FIXME! */
3495 printf("DBG: state = 0x%08X :",state
);
3496 if (state
& simHALTEX
) printf(" simHALTEX");
3497 if (state
& simHALTIN
) printf(" simHALTIN");
3502 DSSTATE
= (STATE
& simDELAYSLOT
);
3505 sim_io_printf(sd
,"DBG: DSPC = 0x%s\n",pr_addr(DSPC
));
3508 /* Fetch the next instruction from the simulator memory: */
3509 if (AddressTranslation(cia
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) {
3510 if ((vaddr
& 1) == 0) {
3511 /* Copy the action of the LW instruction */
3512 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3513 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3516 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3517 LoadMemory(&value
,NULL
,cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3518 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3519 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3521 /* Copy the action of the LH instruction */
3522 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 1) : 0);
3523 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 1) : 0);
3526 paddr
= (((paddr
& ~ (uword64
) 1) & ~LOADDRMASK
)
3527 | (((paddr
& ~ (uword64
) 1) & LOADDRMASK
) ^ (reverse
<< 1)));
3528 LoadMemory(&value
,NULL
,cca
, AccessLength_HALFWORD
,
3529 paddr
& ~ (uword64
) 1,
3530 vaddr
, isINSTRUCTION
, isREAL
);
3531 byte
= (((vaddr
&~ (uword64
) 1) & LOADDRMASK
) ^ (bigend
<< 1));
3532 instruction
= ((value
>> (8 * byte
)) & 0xFFFF);
3535 fprintf(stderr
,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC
));
3540 sim_io_printf(sd
,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction
,pr_addr(PC
));
3543 /* This is required by exception processing, to ensure that we can
3544 cope with exceptions in the delay slots of branches that may
3545 already have changed the PC. */
3546 if ((vaddr
& 1) == 0)
3547 PC
+= 4; /* increment ready for the next fetch */
3550 /* NOTE: If we perform a delay slot change to the PC, this
3551 increment is not requuired. However, it would make the
3552 simulator more complicated to try and avoid this small hit. */
3554 /* Currently this code provides a simple model. For more
3555 complicated models we could perform exception status checks at
3556 this point, and set the simSTOP state as required. This could
3557 also include processing any hardware interrupts raised by any
3558 I/O model attached to the simulator context.
3560 Support for "asynchronous" I/O events within the simulated world
3561 could be providing by managing a counter, and calling a I/O
3562 specific handler when a particular threshold is reached. On most
3563 architectures a decrement and check for zero operation is
3564 usually quicker than an increment and compare. However, the
3565 process of managing a known value decrement to zero, is higher
3566 than the cost of using an explicit value UINT_MAX into the
3567 future. Which system is used will depend on how complicated the
3568 I/O model is, and how much it is likely to affect the simulator
3571 If events need to be scheduled further in the future than
3572 UINT_MAX event ticks, then the I/O model should just provide its
3573 own counter, triggered from the event system. */
3575 /* MIPS pipeline ticks. To allow for future support where the
3576 pipeline hit of individual instructions is known, this control
3577 loop manages a "pipeline_count" variable. It is initialised to
3578 1 (one), and will only be changed by the simulator engine when
3579 executing an instruction. If the engine does not have access to
3580 pipeline cycle count information then all instructions will be
3581 treated as using a single cycle. NOTE: A standard system is not
3582 provided by the default simulator because different MIPS
3583 architectures have different cycle counts for the same
3586 [NOTE: pipeline_count has been replaced the event queue] */
3588 /* shuffle the floating point status pipeline state */
3589 ENGINE_ISSUE_PREFIX_HOOK();
3591 /* NOTE: For multi-context simulation environments the "instruction"
3592 variable should be local to this routine. */
3594 /* Shorthand accesses for engine. Note: If we wanted to use global
3595 variables (and a single-threaded simulator engine), then we can
3596 create the actual variables with these names. */
3598 if (!(STATE
& simSKIPNEXT
)) {
3599 /* Include the simulator engine */
3600 #include "oengine.c"
3601 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3602 #error "Mismatch between run-time simulator code and simulation engine"
3604 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3605 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3607 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3608 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3611 #if defined(WARN_LOHI)
3612 /* Decrement the HI/LO validity ticks */
3617 /* start-sanitize-r5900 */
3622 /* end-sanitize-r5900 */
3623 #endif /* WARN_LOHI */
3625 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3626 should check for it being changed. It is better doing it here,
3627 than within the simulator, since it will help keep the simulator
3630 #if defined(WARN_ZERO)
3631 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
));
3632 #endif /* WARN_ZERO */
3633 ZERO
= 0; /* reset back to zero before next instruction */
3635 } else /* simSKIPNEXT check */
3636 STATE
&= ~simSKIPNEXT
;
3638 /* If the delay slot was active before the instruction is
3639 executed, then update the PC to its new value: */
3642 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC
));
3651 #if !defined(FASTSIM)
3652 if (sim_events_tickn (sd
, pipeline_count
))
3654 /* cpu->cia = cia; */
3655 sim_events_process (sd
);
3658 if (sim_events_tick (sd
))
3660 /* cpu->cia = cia; */
3661 sim_events_process (sd
);
3663 #endif /* FASTSIM */
3669 /* This code copied from gdb's utils.c. Would like to share this code,
3670 but don't know of a common place where both could get to it. */
3672 /* Temporary storage using circular buffer */
3678 static char buf
[NUMCELLS
][CELLSIZE
];
3680 if (++cell
>=NUMCELLS
) cell
=0;
3684 /* Print routines to handle variable size regs, etc */
3686 /* Eliminate warning from compiler on 32-bit systems */
3687 static int thirty_two
= 32;
3693 char *paddr_str
=get_cell();
3694 switch (sizeof(addr
))
3697 sprintf(paddr_str
,"%08lx%08lx",
3698 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3701 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
3704 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
3707 sprintf(paddr_str
,"%x",addr
);
3716 char *paddr_str
=get_cell();
3717 sprintf(paddr_str
,"%08lx%08lx",
3718 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3724 /*---------------------------------------------------------------------------*/
3725 /*> EOF interp.c <*/