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"
51 /* end-sanitize-sky */
73 #include "libiberty.h"
75 #include "callback.h" /* GDB simulator callback interface */
76 #include "remote-sim.h" /* GDB simulator interface */
84 char* pr_addr
PARAMS ((SIM_ADDR addr
));
85 char* pr_uword64
PARAMS ((uword64 addr
));
88 /* Get the simulator engine description, without including the code: */
95 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
100 /* The following reserved instruction value is used when a simulator
101 trap is required. NOTE: Care must be taken, since this value may be
102 used in later revisions of the MIPS ISA. */
104 #define RSVD_INSTRUCTION (0x00000005)
105 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
107 #define RSVD_INSTRUCTION_ARG_SHIFT 6
108 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
111 /* The following reserved instruction value is used when a simulator
112 halt is required. NOTE: Care must be taken, since this value may
113 be used in later revisions of the MIPS ISA. */
114 #define HALT_INSTRUCTION (0x03ff000d)
115 #define HALT_INSTRUCTION_MASK (0x03FFFFC0)
118 /* Bits in the Debug register */
119 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
120 #define Debug_DM 0x40000000 /* Debug Mode */
121 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
127 /*---------------------------------------------------------------------------*/
128 /*-- GDB simulator interface ------------------------------------------------*/
129 /*---------------------------------------------------------------------------*/
131 static void ColdReset
PARAMS((SIM_DESC sd
));
133 /*---------------------------------------------------------------------------*/
137 #define DELAYSLOT() {\
138 if (STATE & simDELAYSLOT)\
139 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
140 STATE |= simDELAYSLOT;\
143 #define JALDELAYSLOT() {\
145 STATE |= simJALDELAYSLOT;\
149 STATE &= ~simDELAYSLOT;\
150 STATE |= simSKIPNEXT;\
153 #define CANCELDELAYSLOT() {\
155 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
158 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
159 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
161 #define K0BASE (0x80000000)
162 #define K0SIZE (0x20000000)
163 #define K1BASE (0xA0000000)
164 #define K1SIZE (0x20000000)
165 #define MONITOR_BASE (0xBFC00000)
166 #define MONITOR_SIZE (1 << 11)
167 #define MEM_SIZE (2 << 20)
169 /* start-sanitize-sky */
172 #define MEM_SIZE (16 << 20) /* 16 MB */
174 /* end-sanitize-sky */
177 static char *tracefile
= "trace.din"; /* default filename for trace log */
178 FILE *tracefh
= NULL
;
179 static void open_trace
PARAMS((SIM_DESC sd
));
182 static DECLARE_OPTION_HANDLER (mips_option_handler
);
185 OPTION_DINERO_TRACE
= OPTION_START
,
187 /* start-sanitize-sky */
189 /* end-sanitize-sky */
193 mips_option_handler (sd
, cpu
, opt
, arg
, is_command
)
203 case OPTION_DINERO_TRACE
: /* ??? */
205 /* Eventually the simTRACE flag could be treated as a toggle, to
206 allow external control of the program points being traced
207 (i.e. only from main onwards, excluding the run-time setup,
209 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
211 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
214 else if (strcmp (arg
, "yes") == 0)
216 else if (strcmp (arg
, "no") == 0)
218 else if (strcmp (arg
, "on") == 0)
220 else if (strcmp (arg
, "off") == 0)
224 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
231 Simulator constructed without dinero tracing support (for performance).\n\
232 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
236 case OPTION_DINERO_FILE
:
238 if (optarg
!= NULL
) {
240 tmp
= (char *)malloc(strlen(optarg
) + 1);
243 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
249 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
255 /* start-sanitize-sky */
256 case OPTION_FLOAT_TYPE
:
257 /* Use host (fast) or target (accurate) floating point implementation. */
258 if (arg
&& strcmp (arg
, "host") == 0)
259 STATE_FP_TYPE_OPT (sd
) &= ~STATE_FP_TYPE_OPT_TARGET
;
260 else if (arg
&& strcmp (arg
, "target") == 0)
261 STATE_FP_TYPE_OPT (sd
) |= STATE_FP_TYPE_OPT_TARGET
;
264 fprintf (stderr
, "Unrecognized float-type option `%s'\n", arg
);
268 /* end-sanitize-sky */
274 static const OPTION mips_options
[] =
276 { {"dinero-trace", optional_argument
, NULL
, OPTION_DINERO_TRACE
},
277 '\0', "on|off", "Enable dinero tracing",
278 mips_option_handler
},
279 { {"dinero-file", required_argument
, NULL
, OPTION_DINERO_FILE
},
280 '\0', "FILE", "Write dinero trace to FILE",
281 mips_option_handler
},
282 /* start-sanitize-sky */
283 { {"float-type", required_argument
, NULL
, OPTION_FLOAT_TYPE
},
284 '\0', "host|target", "Use host (fast) or target (accurate) floating point",
285 mips_option_handler
},
286 /* end-sanitize-sky */
287 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
291 int interrupt_pending
;
294 interrupt_event (SIM_DESC sd
, void *data
)
296 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
299 interrupt_pending
= 0;
300 SignalExceptionInterrupt ();
302 else if (!interrupt_pending
)
303 sim_events_schedule (sd
, 1, interrupt_event
, data
);
307 /*---------------------------------------------------------------------------*/
308 /*-- Device registration hook -----------------------------------------------*/
309 /*---------------------------------------------------------------------------*/
310 static void device_init(SIM_DESC sd
) {
312 extern void register_devices(SIM_DESC
);
313 register_devices(sd
);
317 /*---------------------------------------------------------------------------*/
318 /*-- GDB simulator interface ------------------------------------------------*/
319 /*---------------------------------------------------------------------------*/
322 sim_open (kind
, cb
, abfd
, argv
)
328 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
329 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
331 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
333 /* FIXME: watchpoints code shouldn't need this */
334 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
335 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
336 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
340 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
342 sim_add_option_table (sd
, NULL
, mips_options
);
344 /* Allocate core managed memory */
347 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
, MONITOR_SIZE
);
348 /* For compatibility with the old code - under this (at level one)
349 are the kernel spaces K0 & K1. Both of these map to a single
350 smaller sub region */
351 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
352 /* start-sanitize-sky */
354 /* end-sanitize-sky */
355 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
357 MEM_SIZE
, /* actual size */
359 /* start-sanitize-sky */
361 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x",
363 MEM_SIZE
, /* actual size */
365 0); /* add alias at 0x0000 */
367 /* end-sanitize-sky */
371 /* getopt will print the error message so we just have to exit if this fails.
372 FIXME: Hmmm... in the case of gdb we need getopt to call
374 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
376 /* Uninstall the modules to avoid memory leaks,
377 file descriptor leaks, etc. */
378 sim_module_uninstall (sd
);
382 /* check for/establish the a reference program image */
383 if (sim_analyze_program (sd
,
384 (STATE_PROG_ARGV (sd
) != NULL
385 ? *STATE_PROG_ARGV (sd
)
389 sim_module_uninstall (sd
);
393 /* Configure/verify the target byte order and other runtime
394 configuration options */
395 if (sim_config (sd
) != SIM_RC_OK
)
397 sim_module_uninstall (sd
);
401 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
403 /* Uninstall the modules to avoid memory leaks,
404 file descriptor leaks, etc. */
405 sim_module_uninstall (sd
);
409 /* verify assumptions the simulator made about the host type system.
410 This macro does not return if there is a problem */
411 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
412 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
414 /* This is NASTY, in that we are assuming the size of specific
418 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
421 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
422 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ NR_FGR
)))
423 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
424 else if ((rn
>= 33) && (rn
<= 37))
425 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
426 else if ((rn
== SRIDX
)
429 || ((rn
>= 72) && (rn
<= 89)))
430 cpu
->register_widths
[rn
] = 32;
432 cpu
->register_widths
[rn
] = 0;
434 /* start-sanitize-r5900 */
436 /* set the 5900 "upper" registers to 64 bits */
437 for( rn
= LAST_EMBED_REGNUM
+1; rn
< NUM_REGS
; rn
++)
438 cpu
->register_widths
[rn
] = 64;
439 /* end-sanitize-r5900 */
441 /* start-sanitize-sky */
443 /* Now the VU registers */
444 for( rn
= 0; rn
< NUM_VU_INTEGER_REGS
; rn
++ ) {
445 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 16;
446 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 16;
449 for( rn
= NUM_VU_INTEGER_REGS
; rn
< NUM_VU_REGS
; rn
++ ) {
450 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
451 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 32;
454 /* Finally the VIF registers */
455 for( rn
= 2*NUM_VU_REGS
; rn
< 2*NUM_VU_REGS
+ 2*NUM_VIF_REGS
; rn
++ )
456 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
458 /* end-sanitize-sky */
462 if (STATE
& simTRACE
)
466 /* Write an abort sequence into the TRAP (common) exception vector
467 addresses. This is to catch code executing a TRAP (et.al.)
468 instruction without installing a trap handler. */
470 unsigned32 halt
[2] = { 0x2404002f /* addiu r4, r0, 47 */,
471 HALT_INSTRUCTION
/* BREAK */ };
474 sim_write (sd
, 0x80000180, (char *) halt
, sizeof (halt
));
475 sim_write (sd
, 0xBFC00380, (char *) halt
, sizeof (halt
));
479 /* Write the monitor trap address handlers into the monitor (eeprom)
480 address space. This can only be done once the target endianness
481 has been determined. */
484 /* Entry into the IDT monitor is via fixed address vectors, and
485 not using machine instructions. To avoid clashing with use of
486 the MIPS TRAP system, we place our own (simulator specific)
487 "undefined" instructions into the relevant vector slots. */
488 for (loop
= 0; (loop
< MONITOR_SIZE
); loop
+= 4)
490 address_word vaddr
= (MONITOR_BASE
+ loop
);
491 unsigned32 insn
= (RSVD_INSTRUCTION
| (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
) << RSVD_INSTRUCTION_ARG_SHIFT
));
493 sim_write (sd
, vaddr
, (char *)&insn
, sizeof (insn
));
495 /* The PMON monitor uses the same address space, but rather than
496 branching into it the address of a routine is loaded. We can
497 cheat for the moment, and direct the PMON routine to IDT style
498 instructions within the monitor space. This relies on the IDT
499 monitor not using the locations from 0xBFC00500 onwards as its
501 for (loop
= 0; (loop
< 24); loop
++)
503 address_word vaddr
= (MONITOR_BASE
+ 0x500 + (loop
* 4));
504 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
520 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
522 case 8: /* cliexit */
525 case 11: /* flush_cache */
529 /* FIXME - should monitor_base be SIM_ADDR?? */
530 value
= ((unsigned int)MONITOR_BASE
+ (value
* 8));
532 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
534 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
536 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
548 tracefh
= fopen(tracefile
,"wb+");
551 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
558 sim_close (sd
, quitting
)
563 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
566 /* "quitting" is non-zero if we cannot hang on errors */
568 /* Ensure that any resources allocated through the callback
569 mechanism are released: */
570 sim_io_shutdown (sd
);
573 if (tracefh
!= NULL
&& tracefh
!= stderr
)
578 /* FIXME - free SD */
585 sim_write (sd
,addr
,buffer
,size
)
588 unsigned char *buffer
;
592 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
594 /* Return the number of bytes written, or zero if error. */
596 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
599 /* We use raw read and write routines, since we do not want to count
600 the GDB memory accesses in our statistics gathering. */
602 for (index
= 0; index
< size
; index
++)
604 address_word vaddr
= (address_word
)addr
+ index
;
607 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
609 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
617 sim_read (sd
,addr
,buffer
,size
)
620 unsigned char *buffer
;
624 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
626 /* Return the number of bytes read, or zero if error. */
628 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
631 for (index
= 0; (index
< size
); index
++)
633 address_word vaddr
= (address_word
)addr
+ index
;
636 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isLOAD
, &paddr
, &cca
, isRAW
))
638 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
646 sim_store_register (sd
,rn
,memory
,length
)
649 unsigned char *memory
;
652 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
653 /* NOTE: gdb (the client) stores registers in target byte order
654 while the simulator uses host byte order */
656 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
659 /* Unfortunately this suffers from the same problem as the register
660 numbering one. We need to know what the width of each logical
661 register number is for the architecture being simulated. */
663 if (cpu
->register_widths
[rn
] == 0)
665 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
669 /* start-sanitize-r5900 */
670 if (rn
>= 90 && rn
< 90 + 32)
672 GPR1
[rn
- 90] = T2H_8 (*(unsigned64
*)memory
);
678 SA
= T2H_8(*(unsigned64
*)memory
);
680 case 122: /* FIXME */
681 LO1
= T2H_8(*(unsigned64
*)memory
);
683 case 123: /* FIXME */
684 HI1
= T2H_8(*(unsigned64
*)memory
);
687 /* end-sanitize-r5900 */
689 /* start-sanitize-sky */
691 if (rn
>= NUM_R5900_REGS
)
693 rn
= rn
- NUM_R5900_REGS
;
695 if( rn
< NUM_VU_REGS
)
697 if (rn
< NUM_VU_INTEGER_REGS
)
698 return write_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
699 else if (rn
>= FIRST_VEC_REG
)
702 return write_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
&3,
705 else switch (rn
- NUM_VU_INTEGER_REGS
)
708 return write_vu_special_reg (&vu0_device
, VU_REG_CIA
,
711 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
713 case 2: /* VU0 has no P register */
716 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
719 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
722 return write_vu_acc_reg (&(vu0_device
.regs
),
723 rn
- (NUM_VU_INTEGER_REGS
+ 5),
728 rn
= rn
- NUM_VU_REGS
;
730 if (rn
< NUM_VU_REGS
)
732 if (rn
< NUM_VU_INTEGER_REGS
)
733 return write_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
734 else if (rn
>= FIRST_VEC_REG
)
737 return write_vu_vec_reg (&(vu1_device
.regs
),
738 rn
>> 2, rn
& 3, memory
);
740 else switch (rn
- NUM_VU_INTEGER_REGS
)
743 return write_vu_special_reg (&vu1_device
, VU_REG_CIA
,
746 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MR
,
749 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MP
,
752 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MI
,
755 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MQ
,
758 return write_vu_acc_reg (&(vu1_device
.regs
),
759 rn
- (NUM_VU_INTEGER_REGS
+ 5),
764 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
766 if (rn
< NUM_VIF_REGS
)
768 if (rn
< NUM_VIF_REGS
-1)
769 return write_pke_reg (&pke0_device
, rn
, memory
);
772 sim_io_eprintf( sd
, "Can't write vif0_pc (store ignored)\n" );
777 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
779 if (rn
< NUM_VIF_REGS
)
781 if (rn
< NUM_VIF_REGS
-1)
782 return write_pke_reg (&pke1_device
, rn
, memory
);
785 sim_io_eprintf( sd
, "Can't write vif1_pc (store ignored)\n" );
790 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
794 /* end-sanitize-sky */
796 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
798 if (cpu
->register_widths
[rn
] == 32)
800 cpu
->fgr
[rn
- FGRIDX
] = T2H_4 (*(unsigned32
*)memory
);
805 cpu
->fgr
[rn
- FGRIDX
] = T2H_8 (*(unsigned64
*)memory
);
810 if (cpu
->register_widths
[rn
] == 32)
812 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
817 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
825 sim_fetch_register (sd
,rn
,memory
,length
)
828 unsigned char *memory
;
831 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
832 /* NOTE: gdb (the client) stores registers in target byte order
833 while the simulator uses host byte order */
835 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
838 if (cpu
->register_widths
[rn
] == 0)
840 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
844 /* start-sanitize-r5900 */
845 if (rn
>= 90 && rn
< 90 + 32)
847 *(unsigned64
*)memory
= GPR1
[rn
- 90];
853 *((unsigned64
*)memory
) = H2T_8(SA
);
855 case 122: /* FIXME */
856 *((unsigned64
*)memory
) = H2T_8(LO1
);
858 case 123: /* FIXME */
859 *((unsigned64
*)memory
) = H2T_8(HI1
);
862 /* end-sanitize-r5900 */
864 /* start-sanitize-sky */
866 if (rn
>= NUM_R5900_REGS
)
868 rn
= rn
- NUM_R5900_REGS
;
870 if (rn
< NUM_VU_REGS
)
872 if (rn
< NUM_VU_INTEGER_REGS
)
873 return read_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
874 else if (rn
>= FIRST_VEC_REG
)
877 return read_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
& 3,
880 else switch (rn
- NUM_VU_INTEGER_REGS
)
883 return read_vu_special_reg(&vu0_device
, VU_REG_CIA
, memory
);
885 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
887 case 2: /* VU0 has no P register */
888 *((int *) memory
) = 0;
891 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
894 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
897 return read_vu_acc_reg (&(vu0_device
.regs
),
898 rn
- (NUM_VU_INTEGER_REGS
+ 5),
903 rn
-= NUM_VU_REGS
; /* VU1 registers are next */
905 if (rn
< NUM_VU_REGS
)
907 if (rn
< NUM_VU_INTEGER_REGS
)
908 return read_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
909 else if (rn
>= FIRST_VEC_REG
)
912 return read_vu_vec_reg (&(vu1_device
.regs
),
913 rn
>> 2, rn
& 3, memory
);
915 else switch (rn
- NUM_VU_INTEGER_REGS
)
918 return read_vu_special_reg(&vu1_device
, VU_REG_CIA
, memory
);
920 return read_vu_misc_reg (&(vu1_device
.regs
),
923 return read_vu_misc_reg (&(vu1_device
.regs
),
926 return read_vu_misc_reg (&(vu1_device
.regs
),
929 return read_vu_misc_reg (&(vu1_device
.regs
),
932 return read_vu_acc_reg (&(vu1_device
.regs
),
933 rn
- (NUM_VU_INTEGER_REGS
+ 5),
938 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
940 if (rn
< NUM_VIF_REGS
)
942 if (rn
< NUM_VIF_REGS
-1)
943 return read_pke_reg (&pke0_device
, rn
, memory
);
945 return read_pke_pc (&pke0_device
, memory
);
948 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
950 if (rn
< NUM_VIF_REGS
)
952 if (rn
< NUM_VIF_REGS
-1)
953 return read_pke_reg (&pke1_device
, rn
, memory
);
955 return read_pke_pc (&pke1_device
, memory
);
958 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
961 /* end-sanitize-sky */
963 /* Any floating point register */
964 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
966 if (cpu
->register_widths
[rn
] == 32)
968 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGRIDX
]);
973 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGRIDX
]);
978 if (cpu
->register_widths
[rn
] == 32)
980 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
985 *(unsigned64
*)memory
= H2T_8 ((unsigned64
)(cpu
->registers
[rn
]));
994 sim_create_inferior (sd
, abfd
, argv
,env
)
1002 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1010 /* override PC value set by ColdReset () */
1012 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1014 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1015 CIA_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
1019 #if 0 /* def DEBUG */
1022 /* We should really place the argv slot values into the argument
1023 registers, and onto the stack as required. However, this
1024 assumes that we have a stack defined, which is not
1025 necessarily true at the moment. */
1027 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1028 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1029 printf("DBG: arg \"%s\"\n",*cptr
);
1037 sim_do_command (sd
,cmd
)
1041 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1042 sim_io_printf (sd
, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1046 /*---------------------------------------------------------------------------*/
1047 /*-- Private simulator support interface ------------------------------------*/
1048 /*---------------------------------------------------------------------------*/
1050 /* Read a null terminated string from memory, return in a buffer */
1052 fetch_str (sd
, addr
)
1059 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1061 buf
= NZALLOC (char, nr
+ 1);
1062 sim_read (sd
, addr
, buf
, nr
);
1066 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1068 sim_monitor (SIM_DESC sd
,
1071 unsigned int reason
)
1074 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1077 /* The IDT monitor actually allows two instructions per vector
1078 slot. However, the simulator currently causes a trap on each
1079 individual instruction. We cheat, and lose the bottom bit. */
1082 /* The following callback functions are available, however the
1083 monitor we are simulating does not make use of them: get_errno,
1084 isatty, lseek, rename, system, time and unlink */
1088 case 6: /* int open(char *path,int flags) */
1090 char *path
= fetch_str (sd
, A0
);
1091 V0
= sim_io_open (sd
, path
, (int)A1
);
1096 case 7: /* int read(int file,char *ptr,int len) */
1100 char *buf
= zalloc (nr
);
1101 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1102 sim_write (sd
, A1
, buf
, nr
);
1107 case 8: /* int write(int file,char *ptr,int len) */
1111 char *buf
= zalloc (nr
);
1112 sim_read (sd
, A1
, buf
, nr
);
1113 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1118 case 10: /* int close(int file) */
1120 V0
= sim_io_close (sd
, (int)A0
);
1124 case 2: /* Densan monitor: char inbyte(int waitflag) */
1126 if (A0
== 0) /* waitflag == NOWAIT */
1127 V0
= (unsigned_word
)-1;
1129 /* Drop through to case 11 */
1131 case 11: /* char inbyte(void) */
1134 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1136 sim_io_error(sd
,"Invalid return from character read");
1137 V0
= (unsigned_word
)-1;
1140 V0
= (unsigned_word
)tmp
;
1144 case 3: /* Densan monitor: void co(char chr) */
1145 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1147 char tmp
= (char)(A0
& 0xFF);
1148 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1152 case 17: /* void _exit() */
1154 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1155 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1156 (unsigned int)(A0
& 0xFFFFFFFF));
1160 case 28 : /* PMON flush_cache */
1163 case 55: /* void get_mem_info(unsigned int *ptr) */
1164 /* in: A0 = pointer to three word memory location */
1165 /* out: [A0 + 0] = size */
1166 /* [A0 + 4] = instruction cache size */
1167 /* [A0 + 8] = data cache size */
1169 unsigned_4 value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1170 unsigned_4 zero
= 0;
1172 sim_write (sd
, A0
+ 0, (char *)&value
, 4);
1173 sim_write (sd
, A0
+ 4, (char *)&zero
, 4);
1174 sim_write (sd
, A0
+ 8, (char *)&zero
, 4);
1175 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1179 case 158 : /* PMON printf */
1180 /* in: A0 = pointer to format string */
1181 /* A1 = optional argument 1 */
1182 /* A2 = optional argument 2 */
1183 /* A3 = optional argument 3 */
1185 /* The following is based on the PMON printf source */
1187 address_word s
= A0
;
1189 signed_word
*ap
= &A1
; /* 1st argument */
1190 /* This isn't the quickest way, since we call the host print
1191 routine for every character almost. But it does avoid
1192 having to allocate and manage a temporary string buffer. */
1193 /* TODO: Include check that we only use three arguments (A1,
1195 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1200 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1201 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1202 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1204 if (strchr ("dobxXulscefg%", s
))
1219 else if (c
>= '1' && c
<= '9')
1223 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1226 n
= (unsigned int)strtol(tmp
,NULL
,10);
1239 sim_io_printf (sd
, "%%");
1244 address_word p
= *ap
++;
1246 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1247 sim_io_printf(sd
, "%c", ch
);
1250 sim_io_printf(sd
,"(null)");
1253 sim_io_printf (sd
, "%c", (int)*ap
++);
1258 sim_read (sd
, s
++, &c
, 1);
1262 sim_read (sd
, s
++, &c
, 1);
1265 if (strchr ("dobxXu", c
))
1267 word64 lv
= (word64
) *ap
++;
1269 sim_io_printf(sd
,"<binary not supported>");
1272 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1274 sim_io_printf(sd
, tmp
, lv
);
1276 sim_io_printf(sd
, tmp
, (int)lv
);
1279 else if (strchr ("eEfgG", c
))
1281 double dbl
= *(double*)(ap
++);
1282 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1283 sim_io_printf (sd
, tmp
, dbl
);
1289 sim_io_printf(sd
, "%c", c
);
1295 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1296 reason
, pr_addr(cia
));
1302 /* Store a word into memory. */
1305 store_word (SIM_DESC sd
,
1314 if ((vaddr
& 3) != 0)
1315 SignalExceptionAddressStore ();
1318 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1321 const uword64 mask
= 7;
1325 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1326 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1327 memval
= ((uword64
) val
) << (8 * byte
);
1328 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1334 /* Load a word from memory. */
1337 load_word (SIM_DESC sd
,
1342 if ((vaddr
& 3) != 0)
1343 SignalExceptionAddressLoad ();
1349 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1352 const uword64 mask
= 0x7;
1353 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1354 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1358 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1359 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1361 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1362 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1369 /* Simulate the mips16 entry and exit pseudo-instructions. These
1370 would normally be handled by the reserved instruction exception
1371 code, but for ease of simulation we just handle them directly. */
1374 mips16_entry (SIM_DESC sd
,
1379 int aregs
, sregs
, rreg
;
1382 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1385 aregs
= (insn
& 0x700) >> 8;
1386 sregs
= (insn
& 0x0c0) >> 6;
1387 rreg
= (insn
& 0x020) >> 5;
1389 /* This should be checked by the caller. */
1398 /* This is the entry pseudo-instruction. */
1400 for (i
= 0; i
< aregs
; i
++)
1401 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1409 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1412 for (i
= 0; i
< sregs
; i
++)
1415 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1423 /* This is the exit pseudo-instruction. */
1430 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1433 for (i
= 0; i
< sregs
; i
++)
1436 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1441 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1445 FGR
[0] = WORD64LO (GPR
[4]);
1446 FPR_STATE
[0] = fmt_uninterpreted
;
1448 else if (aregs
== 6)
1450 FGR
[0] = WORD64LO (GPR
[5]);
1451 FGR
[1] = WORD64LO (GPR
[4]);
1452 FPR_STATE
[0] = fmt_uninterpreted
;
1453 FPR_STATE
[1] = fmt_uninterpreted
;
1462 /*-- trace support ----------------------------------------------------------*/
1464 /* The TRACE support is provided (if required) in the memory accessing
1465 routines. Since we are also providing the architecture specific
1466 features, the architecture simulation code can also deal with
1467 notifying the TRACE world of cache flushes, etc. Similarly we do
1468 not need to provide profiling support in the simulator engine,
1469 since we can sample in the instruction fetch control loop. By
1470 defining the TRACE manifest, we add tracing as a run-time
1474 /* Tracing by default produces "din" format (as required by
1475 dineroIII). Each line of such a trace file *MUST* have a din label
1476 and address field. The rest of the line is ignored, so comments can
1477 be included if desired. The first field is the label which must be
1478 one of the following values:
1483 3 escape record (treated as unknown access type)
1484 4 escape record (causes cache flush)
1486 The address field is a 32bit (lower-case) hexadecimal address
1487 value. The address should *NOT* be preceded by "0x".
1489 The size of the memory transfer is not important when dealing with
1490 cache lines (as long as no more than a cache line can be
1491 transferred in a single operation :-), however more information
1492 could be given following the dineroIII requirement to allow more
1493 complete memory and cache simulators to provide better
1494 results. i.e. the University of Pisa has a cache simulator that can
1495 also take bus size and speed as (variable) inputs to calculate
1496 complete system performance (a much more useful ability when trying
1497 to construct an end product, rather than a processor). They
1498 currently have an ARM version of their tool called ChARM. */
1502 dotrace (SIM_DESC sd
,
1510 if (STATE
& simTRACE
) {
1512 fprintf(tracefh
,"%d %s ; width %d ; ",
1516 va_start(ap
,comment
);
1517 vfprintf(tracefh
,comment
,ap
);
1519 fprintf(tracefh
,"\n");
1521 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1522 we may be generating 64bit ones, we should put the hi-32bits of the
1523 address into the comment field. */
1525 /* TODO: Provide a buffer for the trace lines. We can then avoid
1526 performing writes until the buffer is filled, or the file is
1529 /* NOTE: We could consider adding a comment field to the "din" file
1530 produced using type 3 markers (unknown access). This would then
1531 allow information about the program that the "din" is for, and
1532 the MIPs world that was being simulated, to be placed into the
1539 /*---------------------------------------------------------------------------*/
1540 /*-- simulator engine -------------------------------------------------------*/
1541 /*---------------------------------------------------------------------------*/
1544 ColdReset (SIM_DESC sd
)
1547 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1549 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1550 /* RESET: Fixed PC address: */
1551 PC
= UNSIGNED64 (0xFFFFFFFFBFC00000);
1552 /* The reset vector address is in the unmapped, uncached memory space. */
1554 SR
&= ~(status_SR
| status_TS
| status_RP
);
1555 SR
|= (status_ERL
| status_BEV
);
1557 /* Cheat and allow access to the complete register set immediately */
1558 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1559 && WITH_TARGET_WORD_BITSIZE
== 64)
1560 SR
|= status_FR
; /* 64bit registers */
1562 /* Ensure that any instructions with pending register updates are
1564 PENDING_INVALIDATE();
1566 /* Initialise the FPU registers to the unknown state */
1567 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1570 for (rn
= 0; (rn
< 32); rn
++)
1571 FPR_STATE
[rn
] = fmt_uninterpreted
;
1577 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1578 /* Signal an exception condition. This will result in an exception
1579 that aborts the instruction. The instruction operation pseudocode
1580 will never see a return from this function call. */
1583 signal_exception (SIM_DESC sd
,
1591 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1594 /* Ensure that any active atomic read/modify/write operation will fail: */
1597 switch (exception
) {
1602 unsigned int instruction
;
1605 va_start(ap
,exception
);
1606 instruction
= va_arg(ap
,unsigned int);
1609 code
= (instruction
>> 6) & 0xFFFFF;
1611 sim_io_eprintf(sd
,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
1612 code
, pr_addr(cia
));
1616 case DebugBreakPoint
:
1617 if (! (Debug
& Debug_DM
))
1623 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1624 DEPC
= cia
- 4; /* reference the branch instruction */
1628 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1632 Debug
|= Debug_DM
; /* in debugging mode */
1633 Debug
|= Debug_DBp
; /* raising a DBp exception */
1635 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1639 case ReservedInstruction
:
1642 unsigned int instruction
;
1643 va_start(ap
,exception
);
1644 instruction
= va_arg(ap
,unsigned int);
1646 /* Provide simple monitor support using ReservedInstruction
1647 exceptions. The following code simulates the fixed vector
1648 entry points into the IDT monitor by causing a simulator
1649 trap, performing the monitor operation, and returning to
1650 the address held in the $ra register (standard PCS return
1651 address). This means we only need to pre-load the vector
1652 space with suitable instruction values. For systems were
1653 actual trap instructions are used, we would not need to
1654 perform this magic. */
1655 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1657 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
1658 /* NOTE: This assumes that a branch-and-link style
1659 instruction was used to enter the vector (which is the
1660 case with the current IDT monitor). */
1661 sim_engine_restart (SD
, CPU
, NULL
, RA
);
1663 /* Look for the mips16 entry and exit instructions, and
1664 simulate a handler for them. */
1665 else if ((cia
& 1) != 0
1666 && (instruction
& 0xf81f) == 0xe809
1667 && (instruction
& 0x0c0) != 0x0c0)
1669 mips16_entry (SD
, CPU
, cia
, instruction
);
1670 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1672 /* else fall through to normal exception processing */
1673 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
1678 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1680 /* Keep a copy of the current A0 in-case this is the program exit
1684 unsigned int instruction
;
1685 va_start(ap
, exception
);
1686 instruction
= va_arg(ap
,unsigned int);
1688 /* Check for our special terminating BREAK: */
1689 if ((instruction
& HALT_INSTRUCTION_MASK
)
1690 == (HALT_INSTRUCTION
& HALT_INSTRUCTION_MASK
))
1692 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1693 sim_exited
, (unsigned int)(A0
& 0xFFFFFFFF));
1696 if (STATE
& simDELAYSLOT
)
1697 PC
= cia
- 4; /* reference the branch instruction */
1700 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1701 sim_stopped
, SIM_SIGTRAP
);
1704 /* Store exception code into current exception id variable (used
1707 /* TODO: If not simulating exceptions then stop the simulator
1708 execution. At the moment we always stop the simulation. */
1710 /* See figure 5-17 for an outline of the code below */
1711 if (! (SR
& status_EXL
))
1713 CAUSE
= (exception
<< 2);
1714 if (STATE
& simDELAYSLOT
)
1716 STATE
&= ~simDELAYSLOT
;
1718 EPC
= (cia
- 4); /* reference the branch instruction */
1722 /* FIXME: TLB et.al. */
1727 CAUSE
= (exception
<< 2);
1731 /* Store exception code into current exception id variable (used
1733 if (SR
& status_BEV
)
1734 PC
= (signed)0xBFC00200 + 0x180;
1736 PC
= (signed)0x80000000 + 0x180;
1738 switch ((CAUSE
>> 2) & 0x1F)
1741 /* Interrupts arrive during event processing, no need to
1745 case TLBModification
:
1750 case InstructionFetch
:
1752 /* The following is so that the simulator will continue from the
1753 exception address on breakpoint operations. */
1755 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1756 sim_stopped
, SIM_SIGBUS
);
1758 case ReservedInstruction
:
1759 case CoProcessorUnusable
:
1761 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1762 sim_stopped
, SIM_SIGILL
);
1764 case IntegerOverflow
:
1766 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1767 sim_stopped
, SIM_SIGFPE
);
1770 sim_engine_restart (SD
, CPU
, NULL
, PC
);
1776 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1777 sim_stopped
, SIM_SIGTRAP
);
1781 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1782 "FATAL: Should not encounter a breakpoint\n");
1784 default : /* Unknown internal exception */
1786 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1787 sim_stopped
, SIM_SIGABRT
);
1791 case SimulatorFault
:
1795 va_start(ap
,exception
);
1796 msg
= va_arg(ap
,char *);
1798 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1799 "FATAL: Simulator error \"%s\"\n",msg
);
1806 #if defined(WARN_RESULT)
1807 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1808 /* This function indicates that the result of the operation is
1809 undefined. However, this should not affect the instruction
1810 stream. All that is meant to happen is that the destination
1811 register is set to an undefined result. To keep the simulator
1812 simple, we just don't bother updating the destination register, so
1813 the overall result will be undefined. If desired we can stop the
1814 simulator by raising a pseudo-exception. */
1815 #define UndefinedResult() undefined_result (sd,cia)
1817 undefined_result(sd
,cia
)
1821 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
1822 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
1827 #endif /* WARN_RESULT */
1829 /*-- FPU support routines ---------------------------------------------------*/
1831 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
1832 formats conform to ANSI/IEEE Std 754-1985. */
1833 /* SINGLE precision floating:
1834 * seeeeeeeefffffffffffffffffffffff
1836 * e = 8bits = exponent
1837 * f = 23bits = fraction
1839 /* SINGLE precision fixed:
1840 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1842 * i = 31bits = integer
1844 /* DOUBLE precision floating:
1845 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
1847 * e = 11bits = exponent
1848 * f = 52bits = fraction
1850 /* DOUBLE precision fixed:
1851 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1853 * i = 63bits = integer
1856 /* Extract sign-bit: */
1857 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
1858 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
1859 /* Extract biased exponent: */
1860 #define FP_S_be(v) (((v) >> 23) & 0xFF)
1861 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
1862 /* Extract unbiased Exponent: */
1863 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
1864 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
1865 /* Extract complete fraction field: */
1866 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
1867 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
1868 /* Extract numbered fraction bit: */
1869 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
1870 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
1872 /* Explicit QNaN values used when value required: */
1873 #define FPQNaN_SINGLE (0x7FBFFFFF)
1874 #define FPQNaN_WORD (0x7FFFFFFF)
1875 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
1876 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
1878 /* Explicit Infinity values used when required: */
1879 #define FPINF_SINGLE (0x7F800000)
1880 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
1882 #if 1 /* def DEBUG */
1883 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
1884 #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>"))))))
1888 value_fpr (SIM_DESC sd
,
1897 /* Treat unused register values, as fixed-point 64bit values: */
1898 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
1900 /* If request to read data as "uninterpreted", then use the current
1902 fmt
= FPR_STATE
[fpr
];
1907 /* For values not yet accessed, set to the desired format: */
1908 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
1909 FPR_STATE
[fpr
] = fmt
;
1911 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
1914 if (fmt
!= FPR_STATE
[fpr
]) {
1915 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
));
1916 FPR_STATE
[fpr
] = fmt_unknown
;
1919 if (FPR_STATE
[fpr
] == fmt_unknown
) {
1920 /* Set QNaN value: */
1923 value
= FPQNaN_SINGLE
;
1927 value
= FPQNaN_DOUBLE
;
1931 value
= FPQNaN_WORD
;
1935 value
= FPQNaN_LONG
;
1942 } else if (SizeFGR() == 64) {
1946 value
= (FGR
[fpr
] & 0xFFFFFFFF);
1949 case fmt_uninterpreted
:
1963 value
= (FGR
[fpr
] & 0xFFFFFFFF);
1966 case fmt_uninterpreted
:
1969 if ((fpr
& 1) == 0) { /* even registers only */
1970 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
1972 SignalException(ReservedInstruction
,0);
1983 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
1986 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());
1993 store_fpr (SIM_DESC sd
,
2003 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());
2006 if (SizeFGR() == 64) {
2008 case fmt_uninterpreted_32
:
2009 fmt
= fmt_uninterpreted
;
2012 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2013 FPR_STATE
[fpr
] = fmt
;
2016 case fmt_uninterpreted_64
:
2017 fmt
= fmt_uninterpreted
;
2018 case fmt_uninterpreted
:
2022 FPR_STATE
[fpr
] = fmt
;
2026 FPR_STATE
[fpr
] = fmt_unknown
;
2032 case fmt_uninterpreted_32
:
2033 fmt
= fmt_uninterpreted
;
2036 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2037 FPR_STATE
[fpr
] = fmt
;
2040 case fmt_uninterpreted_64
:
2041 fmt
= fmt_uninterpreted
;
2042 case fmt_uninterpreted
:
2045 if ((fpr
& 1) == 0) { /* even register number only */
2046 FGR
[fpr
+1] = (value
>> 32);
2047 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2048 FPR_STATE
[fpr
+ 1] = fmt
;
2049 FPR_STATE
[fpr
] = fmt
;
2051 FPR_STATE
[fpr
] = fmt_unknown
;
2052 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2053 SignalException(ReservedInstruction
,0);
2058 FPR_STATE
[fpr
] = fmt_unknown
;
2063 #if defined(WARN_RESULT)
2066 #endif /* WARN_RESULT */
2069 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2072 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_addr(FGR
[fpr
]),DOFMT(fmt
));
2089 sim_fpu_32to (&wop
, op
);
2090 boolean
= sim_fpu_is_nan (&wop
);
2097 sim_fpu_64to (&wop
, op
);
2098 boolean
= sim_fpu_is_nan (&wop
);
2102 fprintf (stderr
, "Bad switch\n");
2107 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2121 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2128 sim_fpu_32to (&wop
, op
);
2129 boolean
= sim_fpu_is_infinity (&wop
);
2135 sim_fpu_64to (&wop
, op
);
2136 boolean
= sim_fpu_is_infinity (&wop
);
2140 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2145 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2159 /* Argument checking already performed by the FPCOMPARE code */
2162 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2165 /* The format type should already have been checked: */
2171 sim_fpu_32to (&wop1
, op1
);
2172 sim_fpu_32to (&wop2
, op2
);
2173 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2180 sim_fpu_64to (&wop1
, op1
);
2181 sim_fpu_64to (&wop2
, op2
);
2182 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2186 fprintf (stderr
, "Bad switch\n");
2191 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2205 /* Argument checking already performed by the FPCOMPARE code */
2208 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2211 /* The format type should already have been checked: */
2217 sim_fpu_32to (&wop1
, op1
);
2218 sim_fpu_32to (&wop2
, op2
);
2219 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2226 sim_fpu_64to (&wop1
, op1
);
2227 sim_fpu_64to (&wop2
, op2
);
2228 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2232 fprintf (stderr
, "Bad switch\n");
2237 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2244 AbsoluteValue(op
,fmt
)
2251 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2254 /* The format type should already have been checked: */
2260 sim_fpu_32to (&wop
, op
);
2261 sim_fpu_abs (&wop
, &wop
);
2262 sim_fpu_to32 (&ans
, &wop
);
2270 sim_fpu_64to (&wop
, op
);
2271 sim_fpu_abs (&wop
, &wop
);
2272 sim_fpu_to64 (&ans
, &wop
);
2277 fprintf (stderr
, "Bad switch\n");
2292 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2295 /* The format type should already have been checked: */
2301 sim_fpu_32to (&wop
, op
);
2302 sim_fpu_neg (&wop
, &wop
);
2303 sim_fpu_to32 (&ans
, &wop
);
2311 sim_fpu_64to (&wop
, op
);
2312 sim_fpu_neg (&wop
, &wop
);
2313 sim_fpu_to64 (&ans
, &wop
);
2318 fprintf (stderr
, "Bad switch\n");
2334 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2337 /* The registers must specify FPRs valid for operands of type
2338 "fmt". If they are not valid, the result is undefined. */
2340 /* The format type should already have been checked: */
2348 sim_fpu_32to (&wop1
, op1
);
2349 sim_fpu_32to (&wop2
, op2
);
2350 sim_fpu_add (&ans
, &wop1
, &wop2
);
2351 sim_fpu_to32 (&res
, &ans
);
2361 sim_fpu_64to (&wop1
, op1
);
2362 sim_fpu_64to (&wop2
, op2
);
2363 sim_fpu_add (&ans
, &wop1
, &wop2
);
2364 sim_fpu_to64 (&res
, &ans
);
2369 fprintf (stderr
, "Bad switch\n");
2374 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2389 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2392 /* The registers must specify FPRs valid for operands of type
2393 "fmt". If they are not valid, the result is undefined. */
2395 /* The format type should already have been checked: */
2403 sim_fpu_32to (&wop1
, op1
);
2404 sim_fpu_32to (&wop2
, op2
);
2405 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2406 sim_fpu_to32 (&res
, &ans
);
2416 sim_fpu_64to (&wop1
, op1
);
2417 sim_fpu_64to (&wop2
, op2
);
2418 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2419 sim_fpu_to64 (&res
, &ans
);
2424 fprintf (stderr
, "Bad switch\n");
2429 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2436 Multiply(op1
,op2
,fmt
)
2444 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2447 /* The registers must specify FPRs valid for operands of type
2448 "fmt". If they are not valid, the result is undefined. */
2450 /* The format type should already have been checked: */
2458 sim_fpu_32to (&wop1
, op1
);
2459 sim_fpu_32to (&wop2
, op2
);
2460 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2461 sim_fpu_to32 (&res
, &ans
);
2471 sim_fpu_64to (&wop1
, op1
);
2472 sim_fpu_64to (&wop2
, op2
);
2473 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2474 sim_fpu_to64 (&res
, &ans
);
2479 fprintf (stderr
, "Bad switch\n");
2484 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2499 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2502 /* The registers must specify FPRs valid for operands of type
2503 "fmt". If they are not valid, the result is undefined. */
2505 /* The format type should already have been checked: */
2513 sim_fpu_32to (&wop1
, op1
);
2514 sim_fpu_32to (&wop2
, op2
);
2515 sim_fpu_div (&ans
, &wop1
, &wop2
);
2516 sim_fpu_to32 (&res
, &ans
);
2526 sim_fpu_64to (&wop1
, op1
);
2527 sim_fpu_64to (&wop2
, op2
);
2528 sim_fpu_div (&ans
, &wop1
, &wop2
);
2529 sim_fpu_to64 (&res
, &ans
);
2534 fprintf (stderr
, "Bad switch\n");
2539 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2553 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2556 /* The registers must specify FPRs valid for operands of type
2557 "fmt". If they are not valid, the result is undefined. */
2559 /* The format type should already have been checked: */
2566 sim_fpu_32to (&wop
, op
);
2567 sim_fpu_inv (&ans
, &wop
);
2568 sim_fpu_to32 (&res
, &ans
);
2577 sim_fpu_64to (&wop
, op
);
2578 sim_fpu_inv (&ans
, &wop
);
2579 sim_fpu_to64 (&res
, &ans
);
2584 fprintf (stderr
, "Bad switch\n");
2589 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2603 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2606 /* The registers must specify FPRs valid for operands of type
2607 "fmt". If they are not valid, the result is undefined. */
2609 /* The format type should already have been checked: */
2616 sim_fpu_32to (&wop
, op
);
2617 sim_fpu_sqrt (&ans
, &wop
);
2618 sim_fpu_to32 (&res
, &ans
);
2627 sim_fpu_64to (&wop
, op
);
2628 sim_fpu_sqrt (&ans
, &wop
);
2629 sim_fpu_to64 (&res
, &ans
);
2634 fprintf (stderr
, "Bad switch\n");
2639 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2655 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2658 /* The registers must specify FPRs valid for operands of type
2659 "fmt". If they are not valid, the result is undefined. */
2661 /* The format type should already have been checked: */
2668 sim_fpu_32to (&wop1
, op1
);
2669 sim_fpu_32to (&wop2
, op2
);
2670 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2677 sim_fpu_64to (&wop1
, op1
);
2678 sim_fpu_64to (&wop2
, op2
);
2679 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2683 fprintf (stderr
, "Bad switch\n");
2689 case SIM_FPU_IS_SNAN
:
2690 case SIM_FPU_IS_QNAN
:
2692 case SIM_FPU_IS_NINF
:
2693 case SIM_FPU_IS_NNUMBER
:
2694 case SIM_FPU_IS_NDENORM
:
2695 case SIM_FPU_IS_NZERO
:
2696 result
= op2
; /* op1 - op2 < 0 */
2697 case SIM_FPU_IS_PINF
:
2698 case SIM_FPU_IS_PNUMBER
:
2699 case SIM_FPU_IS_PDENORM
:
2700 case SIM_FPU_IS_PZERO
:
2701 result
= op1
; /* op1 - op2 > 0 */
2703 fprintf (stderr
, "Bad switch\n");
2708 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2725 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2728 /* The registers must specify FPRs valid for operands of type
2729 "fmt". If they are not valid, the result is undefined. */
2731 /* The format type should already have been checked: */
2738 sim_fpu_32to (&wop1
, op1
);
2739 sim_fpu_32to (&wop2
, op2
);
2740 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2747 sim_fpu_64to (&wop1
, op1
);
2748 sim_fpu_64to (&wop2
, op2
);
2749 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2753 fprintf (stderr
, "Bad switch\n");
2759 case SIM_FPU_IS_SNAN
:
2760 case SIM_FPU_IS_QNAN
:
2762 case SIM_FPU_IS_NINF
:
2763 case SIM_FPU_IS_NNUMBER
:
2764 case SIM_FPU_IS_NDENORM
:
2765 case SIM_FPU_IS_NZERO
:
2766 result
= op1
; /* op1 - op2 < 0 */
2767 case SIM_FPU_IS_PINF
:
2768 case SIM_FPU_IS_PNUMBER
:
2769 case SIM_FPU_IS_PDENORM
:
2770 case SIM_FPU_IS_PZERO
:
2771 result
= op2
; /* op1 - op2 > 0 */
2773 fprintf (stderr
, "Bad switch\n");
2778 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2786 convert (SIM_DESC sd
,
2795 sim_fpu_round round
;
2796 unsigned32 result32
;
2797 unsigned64 result64
;
2800 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
));
2806 /* Round result to nearest representable value. When two
2807 representable values are equally near, round to the value
2808 that has a least significant bit of zero (i.e. is even). */
2809 round
= sim_fpu_round_near
;
2812 /* Round result to the value closest to, and not greater in
2813 magnitude than, the result. */
2814 round
= sim_fpu_round_zero
;
2817 /* Round result to the value closest to, and not less than,
2819 round
= sim_fpu_round_up
;
2823 /* Round result to the value closest to, and not greater than,
2825 round
= sim_fpu_round_down
;
2829 fprintf (stderr
, "Bad switch\n");
2833 /* Convert the input to sim_fpu internal format */
2837 sim_fpu_64to (&wop
, op
);
2840 sim_fpu_32to (&wop
, op
);
2843 sim_fpu_i32to (&wop
, op
, round
);
2846 sim_fpu_i64to (&wop
, op
, round
);
2849 fprintf (stderr
, "Bad switch\n");
2853 /* Convert sim_fpu format into the output */
2854 /* The value WOP is converted to the destination format, rounding
2855 using mode RM. When the destination is a fixed-point format, then
2856 a source value of Infinity, NaN or one which would round to an
2857 integer outside the fixed point range then an IEEE Invalid
2858 Operation condition is raised. */
2862 sim_fpu_round_32 (&wop
, round
, 0);
2863 sim_fpu_to32 (&result32
, &wop
);
2864 result64
= result32
;
2867 sim_fpu_round_64 (&wop
, round
, 0);
2868 sim_fpu_to64 (&result64
, &wop
);
2871 sim_fpu_to32i (&result32
, &wop
, round
);
2872 result64
= result32
;
2875 sim_fpu_to64i (&result64
, &wop
, round
);
2879 fprintf (stderr
, "Bad switch\n");
2884 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
2891 /*-- co-processor support routines ------------------------------------------*/
2894 CoProcPresent(coproc_number
)
2895 unsigned int coproc_number
;
2897 /* Return TRUE if simulator provides a model for the given co-processor number */
2902 cop_lw (SIM_DESC sd
,
2907 unsigned int memword
)
2912 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2915 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
2917 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
2918 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
2923 #if 0 /* this should be controlled by a configuration option */
2924 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
));
2933 cop_ld (SIM_DESC sd
,
2940 switch (coproc_num
) {
2942 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2944 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
2949 #if 0 /* this message should be controlled by a configuration option */
2950 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
));
2959 /* start-sanitize-sky */
2962 cop_lq (SIM_DESC sd
,
2967 unsigned128 memword
)
2978 /* one word at a time, argh! */
2982 value
= H2T_4(*A4_16(& memword
, 3-i
));
2983 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
2989 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
2990 coproc_num
,coproc_reg
,pr_addr(cia
));
2996 #endif /* TARGET_SKY */
2997 /* end-sanitize-sky */
3001 cop_sw (SIM_DESC sd
,
3007 unsigned int value
= 0;
3012 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3015 hold
= FPR_STATE
[coproc_reg
];
3016 FPR_STATE
[coproc_reg
] = fmt_word
;
3017 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3018 FPR_STATE
[coproc_reg
] = hold
;
3023 #if 0 /* should be controlled by configuration option */
3024 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3033 cop_sd (SIM_DESC sd
,
3043 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3045 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3050 #if 0 /* should be controlled by configuration option */
3051 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3060 /* start-sanitize-sky */
3063 cop_sq (SIM_DESC sd
,
3069 unsigned128 value
= U16_8(0, 0);
3080 /* one word at a time, argh! */
3084 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3085 *A4_16(& xyzw
, 3-i
) = T2H_4(value
);
3092 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3093 coproc_num
,coproc_reg
,pr_addr(cia
));
3099 #endif /* TARGET_SKY */
3100 /* end-sanitize-sky */
3104 decode_coproc (SIM_DESC sd
,
3107 unsigned int instruction
)
3109 int coprocnum
= ((instruction
>> 26) & 3);
3113 case 0: /* standard CPU control and cache registers */
3115 int code
= ((instruction
>> 21) & 0x1F);
3116 /* R4000 Users Manual (second edition) lists the following CP0
3118 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3119 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3120 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3121 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3122 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3123 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3124 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3125 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3126 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3127 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3129 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0))
3131 int rt
= ((instruction
>> 16) & 0x1F);
3132 int rd
= ((instruction
>> 11) & 0x1F);
3134 switch (rd
) /* NOTEs: Standard CP0 registers */
3136 /* 0 = Index R4000 VR4100 VR4300 */
3137 /* 1 = Random R4000 VR4100 VR4300 */
3138 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3139 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3140 /* 4 = Context R4000 VR4100 VR4300 */
3141 /* 5 = PageMask R4000 VR4100 VR4300 */
3142 /* 6 = Wired R4000 VR4100 VR4300 */
3143 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3144 /* 9 = Count R4000 VR4100 VR4300 */
3145 /* 10 = EntryHi R4000 VR4100 VR4300 */
3146 /* 11 = Compare R4000 VR4100 VR4300 */
3147 /* 12 = SR R4000 VR4100 VR4300 */
3154 /* 13 = Cause R4000 VR4100 VR4300 */
3161 /* 14 = EPC R4000 VR4100 VR4300 */
3164 GPR
[rt
] = (signed_word
) (signed_address
) EPC
;
3168 /* 15 = PRId R4000 VR4100 VR4300 */
3169 #ifdef SUBTARGET_R3900
3178 /* 16 = Config R4000 VR4100 VR4300 */
3181 GPR
[rt
] = C0_CONFIG
;
3183 C0_CONFIG
= GPR
[rt
];
3186 #ifdef SUBTARGET_R3900
3195 /* 17 = LLAddr R4000 VR4100 VR4300 */
3197 /* 18 = WatchLo R4000 VR4100 VR4300 */
3198 /* 19 = WatchHi R4000 VR4100 VR4300 */
3199 /* 20 = XContext R4000 VR4100 VR4300 */
3200 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3201 /* 27 = CacheErr R4000 VR4100 */
3202 /* 28 = TagLo R4000 VR4100 VR4300 */
3203 /* 29 = TagHi R4000 VR4100 VR4300 */
3204 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3205 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3206 /* CPR[0,rd] = GPR[rt]; */
3209 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3211 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3214 else if (code
== 0x10 && (instruction
& 0x3f) == 0x18)
3217 if (SR
& status_ERL
)
3219 /* Oops, not yet available */
3220 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3230 else if (code
== 0x10 && (instruction
& 0x3f) == 0x10)
3234 else if (code
== 0x10 && (instruction
& 0x3f) == 0x1F)
3242 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3243 /* TODO: When executing an ERET or RFE instruction we should
3244 clear LLBIT, to ensure that any out-standing atomic
3245 read/modify/write sequence fails. */
3249 case 2: /* co-processor 2 */
3253 /* start-sanitize-sky */
3255 /* On the R5900, this refers to a "VU" vector co-processor. */
3257 int i_25_21
= (instruction
>> 21) & 0x1f;
3258 int i_20_16
= (instruction
>> 16) & 0x1f;
3259 int i_20_6
= (instruction
>> 6) & 0x7fff;
3260 int i_15_11
= (instruction
>> 11) & 0x1f;
3261 int i_15_0
= instruction
& 0xffff;
3262 int i_10_1
= (instruction
>> 1) & 0x3ff;
3263 int i_10_0
= instruction
& 0x7ff;
3264 int i_10_6
= (instruction
>> 6) & 0x1f;
3265 int i_5_0
= instruction
& 0x03f;
3266 int interlock
= instruction
& 0x01;
3267 /* setup for semantic.c-like actions below */
3268 typedef unsigned_4 instruction_word
;
3274 /* test COP2 usability */
3275 if(! (SR
& status_CU2
))
3277 SignalException(CoProcessorUnusable
,instruction
);
3281 #define MY_INDEX itable_COPz_NORMAL
3282 #define MY_PREFIX COPz_NORMAL
3283 #define MY_NAME "COPz_NORMAL"
3285 /* classify & execute basic COP2 instructions */
3286 if(i_25_21
== 0x08 && i_20_16
== 0x00) /* BC2F */
3288 address_word offset
= EXTEND16(i_15_0
) << 2;
3289 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3291 else if(i_25_21
== 0x08 && i_20_16
==0x02) /* BC2FL */
3293 address_word offset
= EXTEND16(i_15_0
) << 2;
3294 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3295 else NULLIFY_NEXT_INSTRUCTION();
3297 else if(i_25_21
== 0x08 && i_20_16
== 0x01) /* BC2T */
3299 address_word offset
= EXTEND16(i_15_0
) << 2;
3300 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3302 else if(i_25_21
== 0x08 && i_20_16
== 0x03) /* BC2TL */
3304 address_word offset
= EXTEND16(i_15_0
) << 2;
3305 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3306 else NULLIFY_NEXT_INSTRUCTION();
3308 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3309 (i_25_21
== 0x01)) /* QMFC2 */
3314 /* interlock checking */
3315 /* POLICY: never busy in macro mode */
3316 while(vu0_busy() && interlock
)
3319 /* perform VU register address */
3320 if(i_25_21
== 0x01) /* QMFC2 */
3323 /* one word at a time, argh! */
3324 read_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3325 read_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3326 read_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3327 read_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3328 GPR
[rt
] = T2H_8(* A8_16(& xyzw
, 1));
3329 GPR1
[rt
] = T2H_8(* A8_16(& xyzw
, 0));
3334 /* enum + int calculation, argh! */
3335 id
= VU_REG_MST
+ 16 * id
;
3336 read_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3337 GPR
[rt
] = EXTEND32(T2H_4(data
));
3340 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3341 (i_25_21
== 0x05)) /* QMTC2 */
3346 /* interlock checking: wait until M or E bits set */
3347 /* POLICY: never busy in macro mode */
3348 while(vu0_busy() && interlock
)
3350 if(vu0_micro_interlock_released())
3352 vu0_micro_interlock_clear();
3359 /* perform VU register address */
3360 if(i_25_21
== 0x05) /* QMTC2 */
3362 unsigned_16 xyzw
= U16_8(GPR1
[rt
], GPR
[rt
]);
3364 xyzw
= H2T_16(xyzw
);
3365 /* one word at a time, argh! */
3366 write_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3367 write_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3368 write_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3369 write_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3373 unsigned_4 data
= H2T_4(GPR
[rt
]);
3374 /* enum + int calculation, argh! */
3375 id
= VU_REG_MST
+ 16 * id
;
3376 write_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3379 else if(i_10_0
== 0x3bf) /* VWAITQ */
3384 else if(i_5_0
== 0x38) /* VCALLMS */
3386 unsigned_4 data
= H2T_2(i_20_6
);
3391 /* write to reserved CIA register to get VU0 moving */
3392 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3396 else if(i_5_0
== 0x39) /* VCALLMSR */
3403 read_vu_special_reg(& vu0_device
, VU_REG_CMSAR0
, & data
);
3404 /* write to reserved CIA register to get VU0 moving */
3405 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3409 /* handle all remaining UPPER VU instructions in one block */
3410 else if((i_5_0
< 0x30) || /* VADDx .. VMINI */
3411 (i_5_0
>= 0x3c && i_10_6
< 0x0c)) /* VADDAx .. VNOP */
3413 unsigned_4 vu_upper
, vu_lower
;
3415 0x00000000 | /* bits 31 .. 25 */
3416 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3417 vu_lower
= 0x8000033c; /* NOP */
3419 /* POLICY: never busy in macro mode */
3423 vu0_macro_issue(vu_upper
, vu_lower
);
3425 /* POLICY: wait for completion of macro-instruction */
3429 /* handle all remaining LOWER VU instructions in one block */
3430 else if((i_5_0
>= 0x30 && i_5_0
<= 0x35) || /* VIADD .. VIOR */
3431 (i_5_0
>= 0x3c && i_10_6
>= 0x0c)) /* VMOVE .. VRXOR */
3432 { /* N.B.: VWAITQ already covered by prior case */
3433 unsigned_4 vu_upper
, vu_lower
;
3434 vu_upper
= 0x000002ff; /* NOP/NOP */
3436 0x80000000 | /* bits 31 .. 25 */
3437 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3439 /* POLICY: never busy in macro mode */
3443 vu0_macro_issue(vu_upper
, vu_lower
);
3445 /* POLICY: wait for completion of macro-instruction */
3449 /* ... no other COP2 instructions ... */
3452 SignalException(ReservedInstruction
, instruction
);
3456 /* cleanup for semantic.c-like actions above */
3463 #endif /* TARGET_SKY */
3464 /* end-sanitize-sky */
3468 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3469 instruction
,pr_addr(cia
));
3474 case 1: /* should not occur (FPU co-processor) */
3475 case 3: /* should not occur (FPU co-processor) */
3476 SignalException(ReservedInstruction
,instruction
);
3484 /*-- instruction simulation -------------------------------------------------*/
3486 /* When the IGEN simulator is being built, the function below is be
3487 replaced by a generated version. However, WITH_IGEN == 2 indicates
3488 that the fubction below should be compiled but under a different
3489 name (to allow backward compatibility) */
3491 #if (WITH_IGEN != 1)
3493 void old_engine_run
PARAMS ((SIM_DESC sd
, int next_cpu_nr
, int siggnal
));
3495 old_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3498 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3501 int next_cpu_nr
; /* ignore */
3502 int nr_cpus
; /* ignore */
3503 int siggnal
; /* ignore */
3505 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* hardwire to cpu 0 */
3506 #if !defined(FASTSIM)
3507 unsigned int pipeline_count
= 1;
3511 if (STATE_MEMORY (sd
) == NULL
) {
3512 printf("DBG: simulate() entered with no memory\n");
3517 #if 0 /* Disabled to check that everything works OK */
3518 /* The VR4300 seems to sign-extend the PC on its first
3519 access. However, this may just be because it is currently
3520 configured in 32bit mode. However... */
3521 PC
= SIGNEXTEND(PC
,32);
3524 /* main controlling loop */
3526 /* vaddr is slowly being replaced with cia - current instruction
3528 address_word cia
= (uword64
)PC
;
3529 address_word vaddr
= cia
;
3532 unsigned int instruction
; /* uword64? what's this used for? FIXME! */
3536 printf("DBG: state = 0x%08X :",state
);
3537 if (state
& simHALTEX
) printf(" simHALTEX");
3538 if (state
& simHALTIN
) printf(" simHALTIN");
3543 DSSTATE
= (STATE
& simDELAYSLOT
);
3546 sim_io_printf(sd
,"DBG: DSPC = 0x%s\n",pr_addr(DSPC
));
3549 /* Fetch the next instruction from the simulator memory: */
3550 if (AddressTranslation(cia
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) {
3551 if ((vaddr
& 1) == 0) {
3552 /* Copy the action of the LW instruction */
3553 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3554 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3557 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3558 LoadMemory(&value
,NULL
,cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3559 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3560 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3562 /* Copy the action of the LH instruction */
3563 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 1) : 0);
3564 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 1) : 0);
3567 paddr
= (((paddr
& ~ (uword64
) 1) & ~LOADDRMASK
)
3568 | (((paddr
& ~ (uword64
) 1) & LOADDRMASK
) ^ (reverse
<< 1)));
3569 LoadMemory(&value
,NULL
,cca
, AccessLength_HALFWORD
,
3570 paddr
& ~ (uword64
) 1,
3571 vaddr
, isINSTRUCTION
, isREAL
);
3572 byte
= (((vaddr
&~ (uword64
) 1) & LOADDRMASK
) ^ (bigend
<< 1));
3573 instruction
= ((value
>> (8 * byte
)) & 0xFFFF);
3576 fprintf(stderr
,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC
));
3581 sim_io_printf(sd
,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction
,pr_addr(PC
));
3584 /* This is required by exception processing, to ensure that we can
3585 cope with exceptions in the delay slots of branches that may
3586 already have changed the PC. */
3587 if ((vaddr
& 1) == 0)
3588 PC
+= 4; /* increment ready for the next fetch */
3591 /* NOTE: If we perform a delay slot change to the PC, this
3592 increment is not requuired. However, it would make the
3593 simulator more complicated to try and avoid this small hit. */
3595 /* Currently this code provides a simple model. For more
3596 complicated models we could perform exception status checks at
3597 this point, and set the simSTOP state as required. This could
3598 also include processing any hardware interrupts raised by any
3599 I/O model attached to the simulator context.
3601 Support for "asynchronous" I/O events within the simulated world
3602 could be providing by managing a counter, and calling a I/O
3603 specific handler when a particular threshold is reached. On most
3604 architectures a decrement and check for zero operation is
3605 usually quicker than an increment and compare. However, the
3606 process of managing a known value decrement to zero, is higher
3607 than the cost of using an explicit value UINT_MAX into the
3608 future. Which system is used will depend on how complicated the
3609 I/O model is, and how much it is likely to affect the simulator
3612 If events need to be scheduled further in the future than
3613 UINT_MAX event ticks, then the I/O model should just provide its
3614 own counter, triggered from the event system. */
3616 /* MIPS pipeline ticks. To allow for future support where the
3617 pipeline hit of individual instructions is known, this control
3618 loop manages a "pipeline_count" variable. It is initialised to
3619 1 (one), and will only be changed by the simulator engine when
3620 executing an instruction. If the engine does not have access to
3621 pipeline cycle count information then all instructions will be
3622 treated as using a single cycle. NOTE: A standard system is not
3623 provided by the default simulator because different MIPS
3624 architectures have different cycle counts for the same
3627 [NOTE: pipeline_count has been replaced the event queue] */
3629 /* shuffle the floating point status pipeline state */
3630 ENGINE_ISSUE_PREFIX_HOOK();
3632 /* NOTE: For multi-context simulation environments the "instruction"
3633 variable should be local to this routine. */
3635 /* Shorthand accesses for engine. Note: If we wanted to use global
3636 variables (and a single-threaded simulator engine), then we can
3637 create the actual variables with these names. */
3639 if (!(STATE
& simSKIPNEXT
)) {
3640 /* Include the simulator engine */
3641 #include "oengine.c"
3642 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3643 #error "Mismatch between run-time simulator code and simulation engine"
3645 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3646 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3648 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3649 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3652 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3653 should check for it being changed. It is better doing it here,
3654 than within the simulator, since it will help keep the simulator
3657 #if defined(WARN_ZERO)
3658 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
));
3659 #endif /* WARN_ZERO */
3660 ZERO
= 0; /* reset back to zero before next instruction */
3662 } else /* simSKIPNEXT check */
3663 STATE
&= ~simSKIPNEXT
;
3665 /* If the delay slot was active before the instruction is
3666 executed, then update the PC to its new value: */
3669 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC
));
3678 #if !defined(FASTSIM)
3679 if (sim_events_tickn (sd
, pipeline_count
))
3681 /* cpu->cia = cia; */
3682 sim_events_process (sd
);
3685 if (sim_events_tick (sd
))
3687 /* cpu->cia = cia; */
3688 sim_events_process (sd
);
3690 #endif /* FASTSIM */
3696 /* This code copied from gdb's utils.c. Would like to share this code,
3697 but don't know of a common place where both could get to it. */
3699 /* Temporary storage using circular buffer */
3705 static char buf
[NUMCELLS
][CELLSIZE
];
3707 if (++cell
>=NUMCELLS
) cell
=0;
3711 /* Print routines to handle variable size regs, etc */
3713 /* Eliminate warning from compiler on 32-bit systems */
3714 static int thirty_two
= 32;
3720 char *paddr_str
=get_cell();
3721 switch (sizeof(addr
))
3724 sprintf(paddr_str
,"%08lx%08lx",
3725 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3728 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
3731 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
3734 sprintf(paddr_str
,"%x",addr
);
3743 char *paddr_str
=get_cell();
3744 sprintf(paddr_str
,"%08lx%08lx",
3745 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3751 /*---------------------------------------------------------------------------*/
3752 /*> EOF interp.c <*/