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"
47 /* end-sanitize-sky */
69 #include "libiberty.h"
71 #include "callback.h" /* GDB simulator callback interface */
72 #include "remote-sim.h" /* GDB simulator interface */
80 char* pr_addr
PARAMS ((SIM_ADDR addr
));
81 char* pr_uword64
PARAMS ((uword64 addr
));
84 /* Get the simulator engine description, without including the code: */
91 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
96 /* The following reserved instruction value is used when a simulator
97 trap is required. NOTE: Care must be taken, since this value may be
98 used in later revisions of the MIPS ISA. */
99 #define RSVD_INSTRUCTION (0x00000005)
100 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
102 #define RSVD_INSTRUCTION_ARG_SHIFT 6
103 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
106 /* Bits in the Debug register */
107 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
108 #define Debug_DM 0x40000000 /* Debug Mode */
109 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
115 /*---------------------------------------------------------------------------*/
116 /*-- GDB simulator interface ------------------------------------------------*/
117 /*---------------------------------------------------------------------------*/
119 static void ColdReset
PARAMS((SIM_DESC sd
));
121 /*---------------------------------------------------------------------------*/
125 #define DELAYSLOT() {\
126 if (STATE & simDELAYSLOT)\
127 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
128 STATE |= simDELAYSLOT;\
131 #define JALDELAYSLOT() {\
133 STATE |= simJALDELAYSLOT;\
137 STATE &= ~simDELAYSLOT;\
138 STATE |= simSKIPNEXT;\
141 #define CANCELDELAYSLOT() {\
143 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
146 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
147 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
149 #define K0BASE (0x80000000)
150 #define K0SIZE (0x20000000)
151 #define K1BASE (0xA0000000)
152 #define K1SIZE (0x20000000)
153 #define MONITOR_BASE (0xBFC00000)
154 #define MONITOR_SIZE (1 << 11)
155 #define MEM_SIZE (2 << 20)
157 /* start-sanitize-sky */
160 #define MEM_SIZE (16 << 20) /* 16 MB */
162 /* end-sanitize-sky */
165 static char *tracefile
= "trace.din"; /* default filename for trace log */
166 FILE *tracefh
= NULL
;
167 static void open_trace
PARAMS((SIM_DESC sd
));
170 static DECLARE_OPTION_HANDLER (mips_option_handler
);
173 OPTION_DINERO_TRACE
= OPTION_START
,
175 /* start-sanitize-sky */
177 /* end-sanitize-sky */
181 mips_option_handler (sd
, cpu
, opt
, arg
, is_command
)
191 case OPTION_DINERO_TRACE
: /* ??? */
193 /* Eventually the simTRACE flag could be treated as a toggle, to
194 allow external control of the program points being traced
195 (i.e. only from main onwards, excluding the run-time setup,
197 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
199 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
202 else if (strcmp (arg
, "yes") == 0)
204 else if (strcmp (arg
, "no") == 0)
206 else if (strcmp (arg
, "on") == 0)
208 else if (strcmp (arg
, "off") == 0)
212 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
219 Simulator constructed without dinero tracing support (for performance).\n\
220 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
224 case OPTION_DINERO_FILE
:
226 if (optarg
!= NULL
) {
228 tmp
= (char *)malloc(strlen(optarg
) + 1);
231 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
237 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
243 /* start-sanitize-sky */
244 case OPTION_FLOAT_TYPE
:
245 /* Use host (fast) or target (accurate) floating point implementation. */
246 if (arg
&& strcmp (arg
, "host") == 0)
247 STATE_FP_TYPE_OPT (sd
) &= ~STATE_FP_TYPE_OPT_TARGET
;
248 else if (arg
&& strcmp (arg
, "target") == 0)
249 STATE_FP_TYPE_OPT (sd
) |= STATE_FP_TYPE_OPT_TARGET
;
252 fprintf (stderr
, "Unrecognized float-type option `%s'\n", arg
);
256 /* end-sanitize-sky */
262 static const OPTION mips_options
[] =
264 { {"dinero-trace", optional_argument
, NULL
, OPTION_DINERO_TRACE
},
265 '\0', "on|off", "Enable dinero tracing",
266 mips_option_handler
},
267 { {"dinero-file", required_argument
, NULL
, OPTION_DINERO_FILE
},
268 '\0', "FILE", "Write dinero trace to FILE",
269 mips_option_handler
},
270 /* start-sanitize-sky */
271 { {"float-type", required_argument
, NULL
, OPTION_FLOAT_TYPE
},
272 '\0', "host|target", "Use host (fast) or target (accurate) floating point",
273 mips_option_handler
},
274 /* end-sanitize-sky */
275 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
279 int interrupt_pending
;
282 interrupt_event (SIM_DESC sd
, void *data
)
284 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
287 interrupt_pending
= 0;
288 SignalExceptionInterrupt ();
290 else if (!interrupt_pending
)
291 sim_events_schedule (sd
, 1, interrupt_event
, data
);
295 /*---------------------------------------------------------------------------*/
296 /*-- Device registration hook -----------------------------------------------*/
297 /*---------------------------------------------------------------------------*/
298 static void device_init(SIM_DESC sd
) {
300 extern void register_devices(SIM_DESC
);
301 register_devices(sd
);
305 /*---------------------------------------------------------------------------*/
306 /*-- GDB simulator interface ------------------------------------------------*/
307 /*---------------------------------------------------------------------------*/
310 sim_open (kind
, cb
, abfd
, argv
)
316 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
317 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
319 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
321 /* FIXME: watchpoints code shouldn't need this */
322 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
323 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
324 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
328 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
330 sim_add_option_table (sd
, NULL
, mips_options
);
332 /* Allocate core managed memory */
335 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
, MONITOR_SIZE
);
336 /* For compatibility with the old code - under this (at level one)
337 are the kernel spaces K0 & K1. Both of these map to a single
338 smaller sub region */
339 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
340 /* start-sanitize-sky */
342 /* end-sanitize-sky */
343 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
345 MEM_SIZE
, /* actual size */
347 /* start-sanitize-sky */
349 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x",
351 MEM_SIZE
, /* actual size */
353 0); /* add alias at 0x0000 */
355 /* end-sanitize-sky */
359 /* getopt will print the error message so we just have to exit if this fails.
360 FIXME: Hmmm... in the case of gdb we need getopt to call
362 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
364 /* Uninstall the modules to avoid memory leaks,
365 file descriptor leaks, etc. */
366 sim_module_uninstall (sd
);
370 /* check for/establish the a reference program image */
371 if (sim_analyze_program (sd
,
372 (STATE_PROG_ARGV (sd
) != NULL
373 ? *STATE_PROG_ARGV (sd
)
377 sim_module_uninstall (sd
);
381 /* Configure/verify the target byte order and other runtime
382 configuration options */
383 if (sim_config (sd
) != SIM_RC_OK
)
385 sim_module_uninstall (sd
);
389 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
391 /* Uninstall the modules to avoid memory leaks,
392 file descriptor leaks, etc. */
393 sim_module_uninstall (sd
);
397 /* verify assumptions the simulator made about the host type system.
398 This macro does not return if there is a problem */
399 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
400 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
402 /* This is NASTY, in that we are assuming the size of specific
406 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
409 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
410 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ NR_FGR
)))
411 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
412 else if ((rn
>= 33) && (rn
<= 37))
413 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
414 else if ((rn
== SRIDX
)
417 || ((rn
>= 72) && (rn
<= 89)))
418 cpu
->register_widths
[rn
] = 32;
420 cpu
->register_widths
[rn
] = 0;
422 /* start-sanitize-r5900 */
424 /* set the 5900 "upper" registers to 64 bits */
425 for( rn
= LAST_EMBED_REGNUM
+1; rn
< NUM_REGS
; rn
++)
426 cpu
->register_widths
[rn
] = 64;
427 /* end-sanitize-r5900 */
429 /* start-sanitize-sky */
431 /* Now the VU registers */
432 for( rn
= 0; rn
< NUM_VU_INTEGER_REGS
; rn
++ ) {
433 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 16;
434 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 16;
437 for( rn
= NUM_VU_INTEGER_REGS
; rn
< NUM_VU_REGS
; rn
++ ) {
438 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
439 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 32;
442 /* end-sanitize-sky */
446 if (STATE
& simTRACE
)
450 /* Write the monitor trap address handlers into the monitor (eeprom)
451 address space. This can only be done once the target endianness
452 has been determined. */
455 /* Entry into the IDT monitor is via fixed address vectors, and
456 not using machine instructions. To avoid clashing with use of
457 the MIPS TRAP system, we place our own (simulator specific)
458 "undefined" instructions into the relevant vector slots. */
459 for (loop
= 0; (loop
< MONITOR_SIZE
); loop
+= 4)
461 address_word vaddr
= (MONITOR_BASE
+ loop
);
462 unsigned32 insn
= (RSVD_INSTRUCTION
| (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
) << RSVD_INSTRUCTION_ARG_SHIFT
));
464 sim_write (sd
, vaddr
, (char *)&insn
, sizeof (insn
));
466 /* The PMON monitor uses the same address space, but rather than
467 branching into it the address of a routine is loaded. We can
468 cheat for the moment, and direct the PMON routine to IDT style
469 instructions within the monitor space. This relies on the IDT
470 monitor not using the locations from 0xBFC00500 onwards as its
472 for (loop
= 0; (loop
< 24); loop
++)
474 address_word vaddr
= (MONITOR_BASE
+ 0x500 + (loop
* 4));
475 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
491 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
493 case 8: /* cliexit */
496 case 11: /* flush_cache */
500 /* FIXME - should monitor_base be SIM_ADDR?? */
501 value
= ((unsigned int)MONITOR_BASE
+ (value
* 8));
503 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
505 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
507 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
519 tracefh
= fopen(tracefile
,"wb+");
522 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
529 sim_close (sd
, quitting
)
534 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
537 /* "quitting" is non-zero if we cannot hang on errors */
539 /* Ensure that any resources allocated through the callback
540 mechanism are released: */
541 sim_io_shutdown (sd
);
544 if (tracefh
!= NULL
&& tracefh
!= stderr
)
549 /* FIXME - free SD */
556 sim_write (sd
,addr
,buffer
,size
)
559 unsigned char *buffer
;
563 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
565 /* Return the number of bytes written, or zero if error. */
567 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
570 /* We use raw read and write routines, since we do not want to count
571 the GDB memory accesses in our statistics gathering. */
573 for (index
= 0; index
< size
; index
++)
575 address_word vaddr
= (address_word
)addr
+ index
;
578 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
580 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
588 sim_read (sd
,addr
,buffer
,size
)
591 unsigned char *buffer
;
595 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
597 /* Return the number of bytes read, or zero if error. */
599 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
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
, isLOAD
, &paddr
, &cca
, isRAW
))
609 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
617 sim_store_register (sd
,rn
,memory
,length
)
620 unsigned char *memory
;
623 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
624 /* NOTE: gdb (the client) stores registers in target byte order
625 while the simulator uses host byte order */
627 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
630 /* Unfortunately this suffers from the same problem as the register
631 numbering one. We need to know what the width of each logical
632 register number is for the architecture being simulated. */
634 if (cpu
->register_widths
[rn
] == 0)
636 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
640 /* start-sanitize-r5900 */
641 if (rn
>= 90 && rn
< 90 + 32)
643 GPR1
[rn
- 90] = T2H_8 (*(unsigned64
*)memory
);
649 SA
= T2H_8(*(unsigned64
*)memory
);
651 case 122: /* FIXME */
652 LO1
= T2H_8(*(unsigned64
*)memory
);
654 case 123: /* FIXME */
655 HI1
= T2H_8(*(unsigned64
*)memory
);
658 /* end-sanitize-r5900 */
660 /* start-sanitize-sky */
662 if (rn
>= NUM_R5900_REGS
)
664 int size
= 4; /* Default register size */
666 rn
= rn
- NUM_R5900_REGS
;
668 if (rn
< NUM_VU_INTEGER_REGS
)
669 size
= write_vu_int_reg (&(vu0_device
.state
->regs
), rn
, memory
);
670 else if( rn
< NUM_VU_REGS
)
672 if (rn
>= FIRST_VEC_REG
)
675 size
= write_vu_vec_reg (&(vu0_device
.state
->regs
), rn
>>2, rn
&3,
678 else switch (rn
- NUM_VU_INTEGER_REGS
)
681 size
= write_vu_special_reg (vu0_device
.state
, VU_REG_CIA
,
685 size
= write_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MR
,
688 case 2: /* VU0 has no P register */
691 size
= write_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MI
,
695 size
= write_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MQ
,
699 size
= write_vu_acc_reg (&(vu0_device
.state
->regs
),
700 rn
- (NUM_VU_INTEGER_REGS
+ 5),
706 rn
= rn
- NUM_VU_REGS
;
708 if( rn
< NUM_VU_INTEGER_REGS
)
709 size
= write_vu_int_reg (&(vu1_device
.state
->regs
), rn
, memory
);
710 else if( rn
< NUM_VU_REGS
)
712 if (rn
>= FIRST_VEC_REG
)
715 size
= write_vu_vec_reg (&(vu1_device
.state
->regs
),
716 rn
>> 2, rn
& 3, memory
);
718 else switch (rn
- NUM_VU_INTEGER_REGS
)
721 size
= write_vu_special_reg (vu1_device
.state
, VU_REG_CIA
,
725 size
= write_vu_misc_reg (&(vu1_device
.state
->regs
),
729 size
= write_vu_misc_reg (&(vu1_device
.state
->regs
),
733 size
= write_vu_misc_reg (&(vu1_device
.state
->regs
),
737 size
= write_vu_misc_reg (&(vu1_device
.state
->regs
),
741 size
= write_vu_acc_reg (&(vu1_device
.state
->regs
),
742 rn
- (NUM_VU_INTEGER_REGS
+ 5),
748 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
754 /* end-sanitize-sky */
756 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
758 if (cpu
->register_widths
[rn
] == 32)
760 cpu
->fgr
[rn
- FGRIDX
] = T2H_4 (*(unsigned32
*)memory
);
765 cpu
->fgr
[rn
- FGRIDX
] = T2H_8 (*(unsigned64
*)memory
);
770 if (cpu
->register_widths
[rn
] == 32)
772 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
777 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
783 sim_fetch_register (sd
,rn
,memory
,length
)
786 unsigned char *memory
;
789 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
790 /* NOTE: gdb (the client) stores registers in target byte order
791 while the simulator uses host byte order */
793 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
796 if (cpu
->register_widths
[rn
] == 0)
798 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
802 /* start-sanitize-r5900 */
803 if (rn
>= 90 && rn
< 90 + 32)
805 *(unsigned64
*)memory
= GPR1
[rn
- 90];
811 *((unsigned64
*)memory
) = H2T_8(SA
);
813 case 122: /* FIXME */
814 *((unsigned64
*)memory
) = H2T_8(LO1
);
816 case 123: /* FIXME */
817 *((unsigned64
*)memory
) = H2T_8(HI1
);
820 /* end-sanitize-r5900 */
822 /* start-sanitize-sky */
824 if (rn
>= NUM_R5900_REGS
)
826 int size
= 4; /* default register width */
828 rn
= rn
- NUM_R5900_REGS
;
830 if (rn
< NUM_VU_INTEGER_REGS
)
831 size
= read_vu_int_reg (&(vu0_device
.state
->regs
), rn
, memory
);
832 else if (rn
< NUM_VU_REGS
)
834 if (rn
>= FIRST_VEC_REG
)
837 size
= read_vu_vec_reg (&(vu0_device
.state
->regs
), rn
>>2, rn
& 3,
840 else switch (rn
- NUM_VU_INTEGER_REGS
)
843 size
= read_vu_special_reg (vu0_device
.state
, VU_REG_CIA
,
848 size
= read_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MR
,
851 case 2: /* VU0 has no P register */
854 size
= read_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MI
,
858 size
= read_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MQ
,
862 size
= read_vu_acc_reg (&(vu0_device
.state
->regs
),
863 rn
- (NUM_VU_INTEGER_REGS
+ 5),
870 rn
= rn
- NUM_VU_REGS
;
872 if (rn
< NUM_VU_INTEGER_REGS
)
873 size
= read_vu_int_reg (&(vu1_device
.state
->regs
), rn
, memory
);
874 else if (rn
< NUM_VU_REGS
)
876 if (rn
>= FIRST_VEC_REG
)
879 size
= read_vu_vec_reg (&(vu1_device
.state
->regs
),
880 rn
>> 2, rn
& 3, memory
);
882 else switch (rn
- NUM_VU_INTEGER_REGS
)
885 size
= read_vu_special_reg (vu1_device
.state
, VU_REG_CIA
,
889 size
= read_vu_misc_reg (&(vu1_device
.state
->regs
),
893 size
= read_vu_misc_reg (&(vu1_device
.state
->regs
),
897 size
= read_vu_misc_reg (&(vu1_device
.state
->regs
),
901 size
= read_vu_misc_reg (&(vu1_device
.state
->regs
),
905 size
= read_vu_acc_reg (&(vu1_device
.state
->regs
),
906 rn
- (NUM_VU_INTEGER_REGS
+ 5),
912 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
918 /* end-sanitize-sky */
920 /* Any floating point register */
921 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
923 if (cpu
->register_widths
[rn
] == 32)
925 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGRIDX
]);
930 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGRIDX
]);
935 if (cpu
->register_widths
[rn
] == 32)
937 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
942 *(unsigned64
*)memory
= H2T_8 ((unsigned64
)(cpu
->registers
[rn
]));
949 sim_create_inferior (sd
, abfd
, argv
,env
)
957 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
965 /* override PC value set by ColdReset () */
967 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
969 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
970 CIA_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
974 #if 0 /* def DEBUG */
977 /* We should really place the argv slot values into the argument
978 registers, and onto the stack as required. However, this
979 assumes that we have a stack defined, which is not
980 necessarily true at the moment. */
982 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
983 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
984 printf("DBG: arg \"%s\"\n",*cptr
);
992 sim_do_command (sd
,cmd
)
996 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
997 sim_io_printf (sd
, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1001 /*---------------------------------------------------------------------------*/
1002 /*-- Private simulator support interface ------------------------------------*/
1003 /*---------------------------------------------------------------------------*/
1005 /* Read a null terminated string from memory, return in a buffer */
1007 fetch_str (sd
, addr
)
1014 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1016 buf
= NZALLOC (char, nr
+ 1);
1017 sim_read (sd
, addr
, buf
, nr
);
1021 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1023 sim_monitor (SIM_DESC sd
,
1026 unsigned int reason
)
1029 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1032 /* The IDT monitor actually allows two instructions per vector
1033 slot. However, the simulator currently causes a trap on each
1034 individual instruction. We cheat, and lose the bottom bit. */
1037 /* The following callback functions are available, however the
1038 monitor we are simulating does not make use of them: get_errno,
1039 isatty, lseek, rename, system, time and unlink */
1043 case 6: /* int open(char *path,int flags) */
1045 char *path
= fetch_str (sd
, A0
);
1046 V0
= sim_io_open (sd
, path
, (int)A1
);
1051 case 7: /* int read(int file,char *ptr,int len) */
1055 char *buf
= zalloc (nr
);
1056 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1057 sim_write (sd
, A1
, buf
, nr
);
1062 case 8: /* int write(int file,char *ptr,int len) */
1066 char *buf
= zalloc (nr
);
1067 sim_read (sd
, A1
, buf
, nr
);
1068 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1073 case 10: /* int close(int file) */
1075 V0
= sim_io_close (sd
, (int)A0
);
1079 case 2: /* Densan monitor: char inbyte(int waitflag) */
1081 if (A0
== 0) /* waitflag == NOWAIT */
1082 V0
= (unsigned_word
)-1;
1084 /* Drop through to case 11 */
1086 case 11: /* char inbyte(void) */
1089 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1091 sim_io_error(sd
,"Invalid return from character read");
1092 V0
= (unsigned_word
)-1;
1095 V0
= (unsigned_word
)tmp
;
1099 case 3: /* Densan monitor: void co(char chr) */
1100 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1102 char tmp
= (char)(A0
& 0xFF);
1103 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1107 case 17: /* void _exit() */
1109 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1110 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1111 (unsigned int)(A0
& 0xFFFFFFFF));
1115 case 28 : /* PMON flush_cache */
1118 case 55: /* void get_mem_info(unsigned int *ptr) */
1119 /* in: A0 = pointer to three word memory location */
1120 /* out: [A0 + 0] = size */
1121 /* [A0 + 4] = instruction cache size */
1122 /* [A0 + 8] = data cache size */
1124 unsigned_4 value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1125 unsigned_4 zero
= 0;
1127 sim_write (sd
, A0
+ 0, (char *)&value
, 4);
1128 sim_write (sd
, A0
+ 4, (char *)&zero
, 4);
1129 sim_write (sd
, A0
+ 8, (char *)&zero
, 4);
1130 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1134 case 158 : /* PMON printf */
1135 /* in: A0 = pointer to format string */
1136 /* A1 = optional argument 1 */
1137 /* A2 = optional argument 2 */
1138 /* A3 = optional argument 3 */
1140 /* The following is based on the PMON printf source */
1142 address_word s
= A0
;
1144 signed_word
*ap
= &A1
; /* 1st argument */
1145 /* This isn't the quickest way, since we call the host print
1146 routine for every character almost. But it does avoid
1147 having to allocate and manage a temporary string buffer. */
1148 /* TODO: Include check that we only use three arguments (A1,
1150 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1155 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1156 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1157 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1159 if (strchr ("dobxXulscefg%", s
))
1174 else if (c
>= '1' && c
<= '9')
1178 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1181 n
= (unsigned int)strtol(tmp
,NULL
,10);
1194 sim_io_printf (sd
, "%%");
1199 address_word p
= *ap
++;
1201 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1202 sim_io_printf(sd
, "%c", ch
);
1205 sim_io_printf(sd
,"(null)");
1208 sim_io_printf (sd
, "%c", (int)*ap
++);
1213 sim_read (sd
, s
++, &c
, 1);
1217 sim_read (sd
, s
++, &c
, 1);
1220 if (strchr ("dobxXu", c
))
1222 word64 lv
= (word64
) *ap
++;
1224 sim_io_printf(sd
,"<binary not supported>");
1227 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1229 sim_io_printf(sd
, tmp
, lv
);
1231 sim_io_printf(sd
, tmp
, (int)lv
);
1234 else if (strchr ("eEfgG", c
))
1236 double dbl
= *(double*)(ap
++);
1237 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1238 sim_io_printf (sd
, tmp
, dbl
);
1244 sim_io_printf(sd
, "%c", c
);
1250 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1251 reason
, pr_addr(cia
));
1257 /* Store a word into memory. */
1260 store_word (SIM_DESC sd
,
1269 if ((vaddr
& 3) != 0)
1270 SignalExceptionAddressStore ();
1273 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1276 const uword64 mask
= 7;
1280 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1281 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1282 memval
= ((uword64
) val
) << (8 * byte
);
1283 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1289 /* Load a word from memory. */
1292 load_word (SIM_DESC sd
,
1297 if ((vaddr
& 3) != 0)
1298 SignalExceptionAddressLoad ();
1304 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1307 const uword64 mask
= 0x7;
1308 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1309 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1313 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1314 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1316 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1317 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1324 /* Simulate the mips16 entry and exit pseudo-instructions. These
1325 would normally be handled by the reserved instruction exception
1326 code, but for ease of simulation we just handle them directly. */
1329 mips16_entry (SIM_DESC sd
,
1334 int aregs
, sregs
, rreg
;
1337 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1340 aregs
= (insn
& 0x700) >> 8;
1341 sregs
= (insn
& 0x0c0) >> 6;
1342 rreg
= (insn
& 0x020) >> 5;
1344 /* This should be checked by the caller. */
1353 /* This is the entry pseudo-instruction. */
1355 for (i
= 0; i
< aregs
; i
++)
1356 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1364 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1367 for (i
= 0; i
< sregs
; i
++)
1370 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1378 /* This is the exit pseudo-instruction. */
1385 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1388 for (i
= 0; i
< sregs
; i
++)
1391 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1396 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1400 FGR
[0] = WORD64LO (GPR
[4]);
1401 FPR_STATE
[0] = fmt_uninterpreted
;
1403 else if (aregs
== 6)
1405 FGR
[0] = WORD64LO (GPR
[5]);
1406 FGR
[1] = WORD64LO (GPR
[4]);
1407 FPR_STATE
[0] = fmt_uninterpreted
;
1408 FPR_STATE
[1] = fmt_uninterpreted
;
1417 /*-- trace support ----------------------------------------------------------*/
1419 /* The TRACE support is provided (if required) in the memory accessing
1420 routines. Since we are also providing the architecture specific
1421 features, the architecture simulation code can also deal with
1422 notifying the TRACE world of cache flushes, etc. Similarly we do
1423 not need to provide profiling support in the simulator engine,
1424 since we can sample in the instruction fetch control loop. By
1425 defining the TRACE manifest, we add tracing as a run-time
1429 /* Tracing by default produces "din" format (as required by
1430 dineroIII). Each line of such a trace file *MUST* have a din label
1431 and address field. The rest of the line is ignored, so comments can
1432 be included if desired. The first field is the label which must be
1433 one of the following values:
1438 3 escape record (treated as unknown access type)
1439 4 escape record (causes cache flush)
1441 The address field is a 32bit (lower-case) hexadecimal address
1442 value. The address should *NOT* be preceded by "0x".
1444 The size of the memory transfer is not important when dealing with
1445 cache lines (as long as no more than a cache line can be
1446 transferred in a single operation :-), however more information
1447 could be given following the dineroIII requirement to allow more
1448 complete memory and cache simulators to provide better
1449 results. i.e. the University of Pisa has a cache simulator that can
1450 also take bus size and speed as (variable) inputs to calculate
1451 complete system performance (a much more useful ability when trying
1452 to construct an end product, rather than a processor). They
1453 currently have an ARM version of their tool called ChARM. */
1457 dotrace (SIM_DESC sd
,
1465 if (STATE
& simTRACE
) {
1467 fprintf(tracefh
,"%d %s ; width %d ; ",
1471 va_start(ap
,comment
);
1472 vfprintf(tracefh
,comment
,ap
);
1474 fprintf(tracefh
,"\n");
1476 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1477 we may be generating 64bit ones, we should put the hi-32bits of the
1478 address into the comment field. */
1480 /* TODO: Provide a buffer for the trace lines. We can then avoid
1481 performing writes until the buffer is filled, or the file is
1484 /* NOTE: We could consider adding a comment field to the "din" file
1485 produced using type 3 markers (unknown access). This would then
1486 allow information about the program that the "din" is for, and
1487 the MIPs world that was being simulated, to be placed into the
1494 /*---------------------------------------------------------------------------*/
1495 /*-- simulator engine -------------------------------------------------------*/
1496 /*---------------------------------------------------------------------------*/
1499 ColdReset (SIM_DESC sd
)
1502 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1504 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1505 /* RESET: Fixed PC address: */
1506 PC
= UNSIGNED64 (0xFFFFFFFFBFC00000);
1507 /* The reset vector address is in the unmapped, uncached memory space. */
1509 SR
&= ~(status_SR
| status_TS
| status_RP
);
1510 SR
|= (status_ERL
| status_BEV
);
1512 /* Cheat and allow access to the complete register set immediately */
1513 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1514 && WITH_TARGET_WORD_BITSIZE
== 64)
1515 SR
|= status_FR
; /* 64bit registers */
1517 /* Ensure that any instructions with pending register updates are
1519 PENDING_INVALIDATE();
1521 /* Initialise the FPU registers to the unknown state */
1522 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1525 for (rn
= 0; (rn
< 32); rn
++)
1526 FPR_STATE
[rn
] = fmt_uninterpreted
;
1532 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
1534 /* Translate a virtual address to a physical address and cache
1535 coherence algorithm describing the mechanism used to resolve the
1536 memory reference. Given the virtual address vAddr, and whether the
1537 reference is to Instructions ot Data (IorD), find the corresponding
1538 physical address (pAddr) and the cache coherence algorithm (CCA)
1539 used to resolve the reference. If the virtual address is in one of
1540 the unmapped address spaces the physical address and the CCA are
1541 determined directly by the virtual address. If the virtual address
1542 is in one of the mapped address spaces then the TLB is used to
1543 determine the physical address and access type; if the required
1544 translation is not present in the TLB or the desired access is not
1545 permitted the function fails and an exception is taken.
1547 NOTE: Normally (RAW == 0), when address translation fails, this
1548 function raises an exception and does not return. */
1551 address_translation (SIM_DESC sd
,
1557 address_word
*pAddr
,
1561 int res
= -1; /* TRUE : Assume good return */
1564 sim_io_printf(sd
,"AddressTranslation(0x%s,%s,%s,...);\n",pr_addr(vAddr
),(IorD
? "isDATA" : "isINSTRUCTION"),(LorS
? "iSTORE" : "isLOAD"));
1567 /* Check that the address is valid for this memory model */
1569 /* For a simple (flat) memory model, we simply pass virtual
1570 addressess through (mostly) unchanged. */
1571 vAddr
&= 0xFFFFFFFF;
1573 *pAddr
= vAddr
; /* default for isTARGET */
1574 *CCA
= Uncached
; /* not used for isHOST */
1579 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
1581 /* Prefetch data from memory. Prefetch is an advisory instruction for
1582 which an implementation specific action is taken. The action taken
1583 may increase performance, but must not change the meaning of the
1584 program, or alter architecturally-visible state. */
1587 prefetch (SIM_DESC sd
,
1597 sim_io_printf(sd
,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA
,pr_addr(pAddr
),pr_addr(vAddr
),DATA
,hint
);
1600 /* For our simple memory model we do nothing */
1604 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
1606 /* Load a value from memory. Use the cache and main memory as
1607 specified in the Cache Coherence Algorithm (CCA) and the sort of
1608 access (IorD) to find the contents of AccessLength memory bytes
1609 starting at physical location pAddr. The data is returned in the
1610 fixed width naturally-aligned memory element (MemElem). The
1611 low-order two (or three) bits of the address and the AccessLength
1612 indicate which of the bytes within MemElem needs to be given to the
1613 processor. If the memory access type of the reference is uncached
1614 then only the referenced bytes are read from memory and valid
1615 within the memory element. If the access type is cached, and the
1616 data is not present in cache, an implementation specific size and
1617 alignment block of memory is read and loaded into the cache to
1618 satisfy a load reference. At a minimum, the block is the entire
1621 load_memory (SIM_DESC sd
,
1627 unsigned int AccessLength
,
1636 sim_io_printf(sd
,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s)\n",memvalp
,memval1p
,CCA
,AccessLength
,pr_addr(pAddr
),pr_addr(vAddr
),(IorD
? "isDATA" : "isINSTRUCTION"));
1639 #if defined(WARN_MEM)
1640 if (CCA
!= uncached
)
1641 sim_io_eprintf(sd
,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA
);
1642 #endif /* WARN_MEM */
1644 /* If instruction fetch then we need to check that the two lo-order
1645 bits are zero, otherwise raise a InstructionFetch exception: */
1646 if ((IorD
== isINSTRUCTION
)
1647 && ((pAddr
& 0x3) != 0)
1648 && (((pAddr
& 0x1) != 0) || ((vAddr
& 0x1) == 0)))
1649 SignalExceptionInstructionFetch ();
1651 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
)
1653 /* In reality this should be a Bus Error */
1654 sim_io_error (sd
, "LOAD AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
1656 (LOADDRMASK
+ 1) << 3,
1661 dotrace (SD
, CPU
, tracefh
,((IorD
== isDATA
) ? 0 : 2),(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"load%s",((IorD
== isDATA
) ? "" : " instruction"));
1664 /* Read the specified number of bytes from memory. Adjust for
1665 host/target byte ordering/ Align the least significant byte
1668 switch (AccessLength
)
1670 case AccessLength_QUADWORD
:
1672 unsigned_16 val
= sim_core_read_aligned_16 (cpu
, NULL_CIA
, read_map
, pAddr
);
1673 value1
= VH8_16 (val
);
1674 value
= VL8_16 (val
);
1677 case AccessLength_DOUBLEWORD
:
1678 value
= sim_core_read_aligned_8 (cpu
, NULL_CIA
,
1681 case AccessLength_SEPTIBYTE
:
1682 value
= sim_core_read_misaligned_7 (cpu
, NULL_CIA
,
1685 case AccessLength_SEXTIBYTE
:
1686 value
= sim_core_read_misaligned_6 (cpu
, NULL_CIA
,
1689 case AccessLength_QUINTIBYTE
:
1690 value
= sim_core_read_misaligned_5 (cpu
, NULL_CIA
,
1693 case AccessLength_WORD
:
1694 value
= sim_core_read_aligned_4 (cpu
, NULL_CIA
,
1697 case AccessLength_TRIPLEBYTE
:
1698 value
= sim_core_read_misaligned_3 (cpu
, NULL_CIA
,
1701 case AccessLength_HALFWORD
:
1702 value
= sim_core_read_aligned_2 (cpu
, NULL_CIA
,
1705 case AccessLength_BYTE
:
1706 value
= sim_core_read_aligned_1 (cpu
, NULL_CIA
,
1714 printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
1715 (int)(pAddr
& LOADDRMASK
),pr_uword64(value1
),pr_uword64(value
));
1718 /* See also store_memory. Position data in correct byte lanes. */
1719 if (AccessLength
<= LOADDRMASK
)
1722 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
1723 shifted to the most significant byte position. */
1724 value
<<= (((LOADDRMASK
- (pAddr
& LOADDRMASK
)) - AccessLength
) * 8);
1726 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
1727 is already in the correct postition. */
1728 value
<<= ((pAddr
& LOADDRMASK
) * 8);
1732 printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
1733 pr_uword64(value1
),pr_uword64(value
));
1737 if (memval1p
) *memval1p
= value1
;
1741 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
1743 /* Store a value to memory. The specified data is stored into the
1744 physical location pAddr using the memory hierarchy (data caches and
1745 main memory) as specified by the Cache Coherence Algorithm
1746 (CCA). The MemElem contains the data for an aligned, fixed-width
1747 memory element (word for 32-bit processors, doubleword for 64-bit
1748 processors), though only the bytes that will actually be stored to
1749 memory need to be valid. The low-order two (or three) bits of pAddr
1750 and the AccessLength field indicates which of the bytes within the
1751 MemElem data should actually be stored; only these bytes in memory
1755 store_memory (SIM_DESC sd
,
1759 unsigned int AccessLength
,
1761 uword64 MemElem1
, /* High order 64 bits */
1766 sim_io_printf(sd
,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s)\n",CCA
,AccessLength
,pr_uword64(MemElem
),pr_uword64(MemElem1
),pr_addr(pAddr
),pr_addr(vAddr
));
1769 #if defined(WARN_MEM)
1770 if (CCA
!= uncached
)
1771 sim_io_eprintf(sd
,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA
);
1772 #endif /* WARN_MEM */
1774 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
)
1775 sim_io_error (sd
, "STORE AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
1777 (LOADDRMASK
+ 1) << 3,
1781 dotrace (SD
, CPU
, tracefh
,1,(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"store");
1785 printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr
& LOADDRMASK
),pr_uword64(MemElem1
),pr_uword64(MemElem
));
1788 /* See also load_memory. Position data in correct byte lanes. */
1789 if (AccessLength
<= LOADDRMASK
)
1792 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
1793 shifted to the most significant byte position. */
1794 MemElem
>>= (((LOADDRMASK
- (pAddr
& LOADDRMASK
)) - AccessLength
) * 8);
1796 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
1797 is already in the correct postition. */
1798 MemElem
>>= ((pAddr
& LOADDRMASK
) * 8);
1802 printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift
,pr_uword64(MemElem1
),pr_uword64(MemElem
));
1805 switch (AccessLength
)
1807 case AccessLength_QUADWORD
:
1809 unsigned_16 val
= U16_8 (MemElem1
, MemElem
);
1810 sim_core_write_aligned_16 (cpu
, NULL_CIA
, write_map
, pAddr
, val
);
1813 case AccessLength_DOUBLEWORD
:
1814 sim_core_write_aligned_8 (cpu
, NULL_CIA
,
1815 write_map
, pAddr
, MemElem
);
1817 case AccessLength_SEPTIBYTE
:
1818 sim_core_write_misaligned_7 (cpu
, NULL_CIA
,
1819 write_map
, pAddr
, MemElem
);
1821 case AccessLength_SEXTIBYTE
:
1822 sim_core_write_misaligned_6 (cpu
, NULL_CIA
,
1823 write_map
, pAddr
, MemElem
);
1825 case AccessLength_QUINTIBYTE
:
1826 sim_core_write_misaligned_5 (cpu
, NULL_CIA
,
1827 write_map
, pAddr
, MemElem
);
1829 case AccessLength_WORD
:
1830 sim_core_write_aligned_4 (cpu
, NULL_CIA
,
1831 write_map
, pAddr
, MemElem
);
1833 case AccessLength_TRIPLEBYTE
:
1834 sim_core_write_misaligned_3 (cpu
, NULL_CIA
,
1835 write_map
, pAddr
, MemElem
);
1837 case AccessLength_HALFWORD
:
1838 sim_core_write_aligned_2 (cpu
, NULL_CIA
,
1839 write_map
, pAddr
, MemElem
);
1841 case AccessLength_BYTE
:
1842 sim_core_write_aligned_1 (cpu
, NULL_CIA
,
1843 write_map
, pAddr
, MemElem
);
1854 ifetch32 (SIM_DESC sd
,
1859 /* Copy the action of the LW instruction */
1860 address_word reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
1861 address_word bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
1864 unsigned32 instruction
;
1867 AddressTranslation (vaddr
, isINSTRUCTION
, isLOAD
, &paddr
, &cca
, isTARGET
, isREAL
);
1868 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
1869 LoadMemory (&value
, NULL
, cca
, AccessLength_WORD
, paddr
, vaddr
, isINSTRUCTION
, isREAL
);
1870 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
1871 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
1877 ifetch16 (SIM_DESC sd
,
1882 /* Copy the action of the LW instruction */
1883 address_word reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
1884 address_word bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
1887 unsigned16 instruction
;
1890 AddressTranslation (vaddr
, isINSTRUCTION
, isLOAD
, &paddr
, &cca
, isTARGET
, isREAL
);
1891 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
1892 LoadMemory (&value
, NULL
, cca
, AccessLength_WORD
, paddr
, vaddr
, isINSTRUCTION
, isREAL
);
1893 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
1894 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
1899 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1900 /* Order loads and stores to synchronise shared memory. Perform the
1901 action necessary to make the effects of groups of synchronizable
1902 loads and stores indicated by stype occur in the same order for all
1905 sync_operation (SIM_DESC sd
,
1911 sim_io_printf(sd
,"SyncOperation(%d) : TODO\n",stype
);
1916 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1917 /* Signal an exception condition. This will result in an exception
1918 that aborts the instruction. The instruction operation pseudocode
1919 will never see a return from this function call. */
1922 signal_exception (SIM_DESC sd
,
1930 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1933 /* Ensure that any active atomic read/modify/write operation will fail: */
1936 switch (exception
) {
1937 /* TODO: For testing purposes I have been ignoring TRAPs. In
1938 reality we should either simulate them, or allow the user to
1939 ignore them at run-time.
1942 sim_io_eprintf(sd
,"Ignoring instruction TRAP (PC 0x%s)\n",pr_addr(cia
));
1948 unsigned int instruction
;
1951 va_start(ap
,exception
);
1952 instruction
= va_arg(ap
,unsigned int);
1955 code
= (instruction
>> 6) & 0xFFFFF;
1957 sim_io_eprintf(sd
,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
1958 code
, pr_addr(cia
));
1962 case DebugBreakPoint
:
1963 if (! (Debug
& Debug_DM
))
1969 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1970 DEPC
= cia
- 4; /* reference the branch instruction */
1974 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1978 Debug
|= Debug_DM
; /* in debugging mode */
1979 Debug
|= Debug_DBp
; /* raising a DBp exception */
1981 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1985 case ReservedInstruction
:
1988 unsigned int instruction
;
1989 va_start(ap
,exception
);
1990 instruction
= va_arg(ap
,unsigned int);
1992 /* Provide simple monitor support using ReservedInstruction
1993 exceptions. The following code simulates the fixed vector
1994 entry points into the IDT monitor by causing a simulator
1995 trap, performing the monitor operation, and returning to
1996 the address held in the $ra register (standard PCS return
1997 address). This means we only need to pre-load the vector
1998 space with suitable instruction values. For systems were
1999 actual trap instructions are used, we would not need to
2000 perform this magic. */
2001 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
2003 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
2004 /* NOTE: This assumes that a branch-and-link style
2005 instruction was used to enter the vector (which is the
2006 case with the current IDT monitor). */
2007 sim_engine_restart (SD
, CPU
, NULL
, RA
);
2009 /* Look for the mips16 entry and exit instructions, and
2010 simulate a handler for them. */
2011 else if ((cia
& 1) != 0
2012 && (instruction
& 0xf81f) == 0xe809
2013 && (instruction
& 0x0c0) != 0x0c0)
2015 mips16_entry (SD
, CPU
, cia
, instruction
);
2016 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
2018 /* else fall through to normal exception processing */
2019 sim_io_eprintf(sd
,"ReservedInstruction 0x%08X at PC = 0x%s\n",instruction
,pr_addr(cia
));
2024 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
2026 /* Keep a copy of the current A0 in-case this is the program exit
2030 unsigned int instruction
;
2031 va_start(ap
,exception
);
2032 instruction
= va_arg(ap
,unsigned int);
2034 /* Check for our special terminating BREAK: */
2035 if ((instruction
& 0x03FFFFC0) == 0x03ff0000) {
2036 sim_engine_halt (SD
, CPU
, NULL
, cia
,
2037 sim_exited
, (unsigned int)(A0
& 0xFFFFFFFF));
2040 if (STATE
& simDELAYSLOT
)
2041 PC
= cia
- 4; /* reference the branch instruction */
2044 sim_engine_halt (SD
, CPU
, NULL
, cia
,
2045 sim_stopped
, SIM_SIGTRAP
);
2048 /* Store exception code into current exception id variable (used
2051 /* TODO: If not simulating exceptions then stop the simulator
2052 execution. At the moment we always stop the simulation. */
2054 /* See figure 5-17 for an outline of the code below */
2055 if (! (SR
& status_EXL
))
2057 CAUSE
= (exception
<< 2);
2058 if (STATE
& simDELAYSLOT
)
2060 STATE
&= ~simDELAYSLOT
;
2062 EPC
= (cia
- 4); /* reference the branch instruction */
2066 /* FIXME: TLB et.al. */
2071 CAUSE
= (exception
<< 2);
2075 /* Store exception code into current exception id variable (used
2077 if (SR
& status_BEV
)
2078 PC
= (signed)0xBFC00200 + 0x180;
2080 PC
= (signed)0x80000000 + 0x180;
2082 switch ((CAUSE
>> 2) & 0x1F)
2085 /* Interrupts arrive during event processing, no need to
2089 case TLBModification
:
2094 case InstructionFetch
:
2096 /* The following is so that the simulator will continue from the
2097 exception address on breakpoint operations. */
2099 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2100 sim_stopped
, SIM_SIGBUS
);
2102 case ReservedInstruction
:
2103 case CoProcessorUnusable
:
2105 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2106 sim_stopped
, SIM_SIGILL
);
2108 case IntegerOverflow
:
2110 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2111 sim_stopped
, SIM_SIGFPE
);
2117 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2118 sim_stopped
, SIM_SIGTRAP
);
2122 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2123 "FATAL: Should not encounter a breakpoint\n");
2125 default : /* Unknown internal exception */
2127 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2128 sim_stopped
, SIM_SIGABRT
);
2132 case SimulatorFault
:
2136 va_start(ap
,exception
);
2137 msg
= va_arg(ap
,char *);
2139 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2140 "FATAL: Simulator error \"%s\"\n",msg
);
2147 #if defined(WARN_RESULT)
2148 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2149 /* This function indicates that the result of the operation is
2150 undefined. However, this should not affect the instruction
2151 stream. All that is meant to happen is that the destination
2152 register is set to an undefined result. To keep the simulator
2153 simple, we just don't bother updating the destination register, so
2154 the overall result will be undefined. If desired we can stop the
2155 simulator by raising a pseudo-exception. */
2156 #define UndefinedResult() undefined_result (sd,cia)
2158 undefined_result(sd
,cia
)
2162 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
2163 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2168 #endif /* WARN_RESULT */
2171 cache_op (SIM_DESC sd
,
2177 unsigned int instruction
)
2179 #if 1 /* stop warning message being displayed (we should really just remove the code) */
2180 static int icache_warning
= 1;
2181 static int dcache_warning
= 1;
2183 static int icache_warning
= 0;
2184 static int dcache_warning
= 0;
2187 /* If CP0 is not useable (User or Supervisor mode) and the CP0
2188 enable bit in the Status Register is clear - a coprocessor
2189 unusable exception is taken. */
2191 sim_io_printf(sd
,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia
));
2195 case 0: /* instruction cache */
2197 case 0: /* Index Invalidate */
2198 case 1: /* Index Load Tag */
2199 case 2: /* Index Store Tag */
2200 case 4: /* Hit Invalidate */
2202 case 6: /* Hit Writeback */
2203 if (!icache_warning
)
2205 sim_io_eprintf(sd
,"Instruction CACHE operation %d to be coded\n",(op
>> 2));
2211 SignalException(ReservedInstruction
,instruction
);
2216 case 1: /* data cache */
2218 case 0: /* Index Writeback Invalidate */
2219 case 1: /* Index Load Tag */
2220 case 2: /* Index Store Tag */
2221 case 3: /* Create Dirty */
2222 case 4: /* Hit Invalidate */
2223 case 5: /* Hit Writeback Invalidate */
2224 case 6: /* Hit Writeback */
2225 if (!dcache_warning
)
2227 sim_io_eprintf(sd
,"Data CACHE operation %d to be coded\n",(op
>> 2));
2233 SignalException(ReservedInstruction
,instruction
);
2238 default: /* unrecognised cache ID */
2239 SignalException(ReservedInstruction
,instruction
);
2246 /*-- FPU support routines ---------------------------------------------------*/
2248 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
2249 formats conform to ANSI/IEEE Std 754-1985. */
2250 /* SINGLE precision floating:
2251 * seeeeeeeefffffffffffffffffffffff
2253 * e = 8bits = exponent
2254 * f = 23bits = fraction
2256 /* SINGLE precision fixed:
2257 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2259 * i = 31bits = integer
2261 /* DOUBLE precision floating:
2262 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
2264 * e = 11bits = exponent
2265 * f = 52bits = fraction
2267 /* DOUBLE precision fixed:
2268 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2270 * i = 63bits = integer
2273 /* Extract sign-bit: */
2274 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
2275 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
2276 /* Extract biased exponent: */
2277 #define FP_S_be(v) (((v) >> 23) & 0xFF)
2278 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
2279 /* Extract unbiased Exponent: */
2280 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
2281 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
2282 /* Extract complete fraction field: */
2283 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
2284 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
2285 /* Extract numbered fraction bit: */
2286 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
2287 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
2289 /* Explicit QNaN values used when value required: */
2290 #define FPQNaN_SINGLE (0x7FBFFFFF)
2291 #define FPQNaN_WORD (0x7FFFFFFF)
2292 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
2293 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
2295 /* Explicit Infinity values used when required: */
2296 #define FPINF_SINGLE (0x7F800000)
2297 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
2299 #if 1 /* def DEBUG */
2300 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
2301 #define DOFMT(v) (((v) == fmt_single) ? "single" : (((v) == fmt_double) ? "double" : (((v) == fmt_word) ? "word" : (((v) == fmt_long) ? "long" : (((v) == fmt_unknown) ? "<unknown>" : (((v) == fmt_uninterpreted) ? "<uninterpreted>" : "<format error>"))))))
2305 value_fpr (SIM_DESC sd
,
2314 /* Treat unused register values, as fixed-point 64bit values: */
2315 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
2317 /* If request to read data as "uninterpreted", then use the current
2319 fmt
= FPR_STATE
[fpr
];
2324 /* For values not yet accessed, set to the desired format: */
2325 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
2326 FPR_STATE
[fpr
] = fmt
;
2328 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
2331 if (fmt
!= FPR_STATE
[fpr
]) {
2332 sim_io_eprintf(sd
,"FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",fpr
,DOFMT(FPR_STATE
[fpr
]),DOFMT(fmt
),pr_addr(cia
));
2333 FPR_STATE
[fpr
] = fmt_unknown
;
2336 if (FPR_STATE
[fpr
] == fmt_unknown
) {
2337 /* Set QNaN value: */
2340 value
= FPQNaN_SINGLE
;
2344 value
= FPQNaN_DOUBLE
;
2348 value
= FPQNaN_WORD
;
2352 value
= FPQNaN_LONG
;
2359 } else if (SizeFGR() == 64) {
2363 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2366 case fmt_uninterpreted
:
2380 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2383 case fmt_uninterpreted
:
2386 if ((fpr
& 1) == 0) { /* even registers only */
2387 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
2389 SignalException(ReservedInstruction
,0);
2400 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2403 printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr
,DOFMT(fmt
),pr_addr(value
),pr_addr(cia
),SizeFGR());
2410 store_fpr (SIM_DESC sd
,
2420 printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr
,DOFMT(fmt
),pr_addr(value
),pr_addr(cia
),SizeFGR());
2423 if (SizeFGR() == 64) {
2425 case fmt_uninterpreted_32
:
2426 fmt
= fmt_uninterpreted
;
2429 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2430 FPR_STATE
[fpr
] = fmt
;
2433 case fmt_uninterpreted_64
:
2434 fmt
= fmt_uninterpreted
;
2435 case fmt_uninterpreted
:
2439 FPR_STATE
[fpr
] = fmt
;
2443 FPR_STATE
[fpr
] = fmt_unknown
;
2449 case fmt_uninterpreted_32
:
2450 fmt
= fmt_uninterpreted
;
2453 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2454 FPR_STATE
[fpr
] = fmt
;
2457 case fmt_uninterpreted_64
:
2458 fmt
= fmt_uninterpreted
;
2459 case fmt_uninterpreted
:
2462 if ((fpr
& 1) == 0) { /* even register number only */
2463 FGR
[fpr
+1] = (value
>> 32);
2464 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2465 FPR_STATE
[fpr
+ 1] = fmt
;
2466 FPR_STATE
[fpr
] = fmt
;
2468 FPR_STATE
[fpr
] = fmt_unknown
;
2469 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2470 SignalException(ReservedInstruction
,0);
2475 FPR_STATE
[fpr
] = fmt_unknown
;
2480 #if defined(WARN_RESULT)
2483 #endif /* WARN_RESULT */
2486 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2489 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_addr(FGR
[fpr
]),DOFMT(fmt
));
2506 sim_fpu_32to (&wop
, op
);
2507 boolean
= sim_fpu_is_nan (&wop
);
2514 sim_fpu_64to (&wop
, op
);
2515 boolean
= sim_fpu_is_nan (&wop
);
2519 fprintf (stderr
, "Bad switch\n");
2524 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2538 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2545 sim_fpu_32to (&wop
, op
);
2546 boolean
= sim_fpu_is_infinity (&wop
);
2552 sim_fpu_64to (&wop
, op
);
2553 boolean
= sim_fpu_is_infinity (&wop
);
2557 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2562 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2576 /* Argument checking already performed by the FPCOMPARE code */
2579 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2582 /* The format type should already have been checked: */
2588 sim_fpu_32to (&wop1
, op1
);
2589 sim_fpu_32to (&wop2
, op2
);
2590 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2597 sim_fpu_64to (&wop1
, op1
);
2598 sim_fpu_64to (&wop2
, op2
);
2599 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2603 fprintf (stderr
, "Bad switch\n");
2608 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2622 /* Argument checking already performed by the FPCOMPARE code */
2625 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2628 /* The format type should already have been checked: */
2634 sim_fpu_32to (&wop1
, op1
);
2635 sim_fpu_32to (&wop2
, op2
);
2636 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2643 sim_fpu_64to (&wop1
, op1
);
2644 sim_fpu_64to (&wop2
, op2
);
2645 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2649 fprintf (stderr
, "Bad switch\n");
2654 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2661 AbsoluteValue(op
,fmt
)
2668 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2671 /* The format type should already have been checked: */
2677 sim_fpu_32to (&wop
, op
);
2678 sim_fpu_abs (&wop
, &wop
);
2679 sim_fpu_to32 (&ans
, &wop
);
2687 sim_fpu_64to (&wop
, op
);
2688 sim_fpu_abs (&wop
, &wop
);
2689 sim_fpu_to64 (&ans
, &wop
);
2694 fprintf (stderr
, "Bad switch\n");
2709 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2712 /* The format type should already have been checked: */
2718 sim_fpu_32to (&wop
, op
);
2719 sim_fpu_neg (&wop
, &wop
);
2720 sim_fpu_to32 (&ans
, &wop
);
2728 sim_fpu_64to (&wop
, op
);
2729 sim_fpu_neg (&wop
, &wop
);
2730 sim_fpu_to64 (&ans
, &wop
);
2735 fprintf (stderr
, "Bad switch\n");
2751 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2754 /* The registers must specify FPRs valid for operands of type
2755 "fmt". If they are not valid, the result is undefined. */
2757 /* The format type should already have been checked: */
2765 sim_fpu_32to (&wop1
, op1
);
2766 sim_fpu_32to (&wop2
, op2
);
2767 sim_fpu_add (&ans
, &wop1
, &wop2
);
2768 sim_fpu_to32 (&res
, &ans
);
2778 sim_fpu_64to (&wop1
, op1
);
2779 sim_fpu_64to (&wop2
, op2
);
2780 sim_fpu_add (&ans
, &wop1
, &wop2
);
2781 sim_fpu_to64 (&res
, &ans
);
2786 fprintf (stderr
, "Bad switch\n");
2791 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2806 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2809 /* The registers must specify FPRs valid for operands of type
2810 "fmt". If they are not valid, the result is undefined. */
2812 /* The format type should already have been checked: */
2820 sim_fpu_32to (&wop1
, op1
);
2821 sim_fpu_32to (&wop2
, op2
);
2822 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2823 sim_fpu_to32 (&res
, &ans
);
2833 sim_fpu_64to (&wop1
, op1
);
2834 sim_fpu_64to (&wop2
, op2
);
2835 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2836 sim_fpu_to64 (&res
, &ans
);
2841 fprintf (stderr
, "Bad switch\n");
2846 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2853 Multiply(op1
,op2
,fmt
)
2861 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2864 /* The registers must specify FPRs valid for operands of type
2865 "fmt". If they are not valid, the result is undefined. */
2867 /* The format type should already have been checked: */
2875 sim_fpu_32to (&wop1
, op1
);
2876 sim_fpu_32to (&wop2
, op2
);
2877 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2878 sim_fpu_to32 (&res
, &ans
);
2888 sim_fpu_64to (&wop1
, op1
);
2889 sim_fpu_64to (&wop2
, op2
);
2890 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2891 sim_fpu_to64 (&res
, &ans
);
2896 fprintf (stderr
, "Bad switch\n");
2901 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2916 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2919 /* The registers must specify FPRs valid for operands of type
2920 "fmt". If they are not valid, the result is undefined. */
2922 /* The format type should already have been checked: */
2930 sim_fpu_32to (&wop1
, op1
);
2931 sim_fpu_32to (&wop2
, op2
);
2932 sim_fpu_div (&ans
, &wop1
, &wop2
);
2933 sim_fpu_to32 (&res
, &ans
);
2943 sim_fpu_64to (&wop1
, op1
);
2944 sim_fpu_64to (&wop2
, op2
);
2945 sim_fpu_div (&ans
, &wop1
, &wop2
);
2946 sim_fpu_to64 (&res
, &ans
);
2951 fprintf (stderr
, "Bad switch\n");
2956 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2970 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2973 /* The registers must specify FPRs valid for operands of type
2974 "fmt". If they are not valid, the result is undefined. */
2976 /* The format type should already have been checked: */
2983 sim_fpu_32to (&wop
, op
);
2984 sim_fpu_inv (&ans
, &wop
);
2985 sim_fpu_to32 (&res
, &ans
);
2994 sim_fpu_64to (&wop
, op
);
2995 sim_fpu_inv (&ans
, &wop
);
2996 sim_fpu_to64 (&res
, &ans
);
3001 fprintf (stderr
, "Bad switch\n");
3006 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3020 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
3023 /* The registers must specify FPRs valid for operands of type
3024 "fmt". If they are not valid, the result is undefined. */
3026 /* The format type should already have been checked: */
3033 sim_fpu_32to (&wop
, op
);
3034 sim_fpu_sqrt (&ans
, &wop
);
3035 sim_fpu_to32 (&res
, &ans
);
3044 sim_fpu_64to (&wop
, op
);
3045 sim_fpu_sqrt (&ans
, &wop
);
3046 sim_fpu_to64 (&res
, &ans
);
3051 fprintf (stderr
, "Bad switch\n");
3056 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3072 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3075 /* The registers must specify FPRs valid for operands of type
3076 "fmt". If they are not valid, the result is undefined. */
3078 /* The format type should already have been checked: */
3085 sim_fpu_32to (&wop1
, op1
);
3086 sim_fpu_32to (&wop2
, op2
);
3087 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3094 sim_fpu_64to (&wop1
, op1
);
3095 sim_fpu_64to (&wop2
, op2
);
3096 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3100 fprintf (stderr
, "Bad switch\n");
3106 case SIM_FPU_IS_SNAN
:
3107 case SIM_FPU_IS_QNAN
:
3109 case SIM_FPU_IS_NINF
:
3110 case SIM_FPU_IS_NNUMBER
:
3111 case SIM_FPU_IS_NDENORM
:
3112 case SIM_FPU_IS_NZERO
:
3113 result
= op2
; /* op1 - op2 < 0 */
3114 case SIM_FPU_IS_PINF
:
3115 case SIM_FPU_IS_PNUMBER
:
3116 case SIM_FPU_IS_PDENORM
:
3117 case SIM_FPU_IS_PZERO
:
3118 result
= op1
; /* op1 - op2 > 0 */
3120 fprintf (stderr
, "Bad switch\n");
3125 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3142 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3145 /* The registers must specify FPRs valid for operands of type
3146 "fmt". If they are not valid, the result is undefined. */
3148 /* The format type should already have been checked: */
3155 sim_fpu_32to (&wop1
, op1
);
3156 sim_fpu_32to (&wop2
, op2
);
3157 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3164 sim_fpu_64to (&wop1
, op1
);
3165 sim_fpu_64to (&wop2
, op2
);
3166 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3170 fprintf (stderr
, "Bad switch\n");
3176 case SIM_FPU_IS_SNAN
:
3177 case SIM_FPU_IS_QNAN
:
3179 case SIM_FPU_IS_NINF
:
3180 case SIM_FPU_IS_NNUMBER
:
3181 case SIM_FPU_IS_NDENORM
:
3182 case SIM_FPU_IS_NZERO
:
3183 result
= op1
; /* op1 - op2 < 0 */
3184 case SIM_FPU_IS_PINF
:
3185 case SIM_FPU_IS_PNUMBER
:
3186 case SIM_FPU_IS_PDENORM
:
3187 case SIM_FPU_IS_PZERO
:
3188 result
= op2
; /* op1 - op2 > 0 */
3190 fprintf (stderr
, "Bad switch\n");
3195 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3203 convert (SIM_DESC sd
,
3212 sim_fpu_round round
;
3213 unsigned32 result32
;
3214 unsigned64 result64
;
3217 printf("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",RMMODE(rm
),pr_addr(op
),DOFMT(from
),DOFMT(to
),pr_addr(IPC
));
3223 /* Round result to nearest representable value. When two
3224 representable values are equally near, round to the value
3225 that has a least significant bit of zero (i.e. is even). */
3226 round
= sim_fpu_round_near
;
3229 /* Round result to the value closest to, and not greater in
3230 magnitude than, the result. */
3231 round
= sim_fpu_round_zero
;
3234 /* Round result to the value closest to, and not less than,
3236 round
= sim_fpu_round_up
;
3240 /* Round result to the value closest to, and not greater than,
3242 round
= sim_fpu_round_down
;
3246 fprintf (stderr
, "Bad switch\n");
3250 /* Convert the input to sim_fpu internal format */
3254 sim_fpu_64to (&wop
, op
);
3257 sim_fpu_32to (&wop
, op
);
3260 sim_fpu_i32to (&wop
, op
, round
);
3263 sim_fpu_i64to (&wop
, op
, round
);
3266 fprintf (stderr
, "Bad switch\n");
3270 /* Convert sim_fpu format into the output */
3271 /* The value WOP is converted to the destination format, rounding
3272 using mode RM. When the destination is a fixed-point format, then
3273 a source value of Infinity, NaN or one which would round to an
3274 integer outside the fixed point range then an IEEE Invalid
3275 Operation condition is raised. */
3279 sim_fpu_round_32 (&wop
, round
, 0);
3280 sim_fpu_to32 (&result32
, &wop
);
3281 result64
= result32
;
3284 sim_fpu_round_64 (&wop
, round
, 0);
3285 sim_fpu_to64 (&result64
, &wop
);
3288 sim_fpu_to32i (&result32
, &wop
, round
);
3289 result64
= result32
;
3292 sim_fpu_to64i (&result64
, &wop
, round
);
3296 fprintf (stderr
, "Bad switch\n");
3301 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
3308 /*-- co-processor support routines ------------------------------------------*/
3311 CoProcPresent(coproc_number
)
3312 unsigned int coproc_number
;
3314 /* Return TRUE if simulator provides a model for the given co-processor number */
3319 cop_lw (SIM_DESC sd
,
3324 unsigned int memword
)
3329 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3332 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
3334 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
3335 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
3340 #if 0 /* this should be controlled by a configuration option */
3341 sim_io_printf(sd
,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,memword
,pr_addr(cia
));
3350 cop_ld (SIM_DESC sd
,
3357 switch (coproc_num
) {
3359 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3361 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
3366 #if 0 /* this message should be controlled by a configuration option */
3367 sim_io_printf(sd
,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(memword
),pr_addr(cia
));
3376 /* start-sanitize-sky */
3379 cop_lq (SIM_DESC sd
,
3384 unsigned128 memword
)
3393 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3394 coproc_num
,coproc_reg
,pr_addr(cia
));
3400 #endif /* TARGET_SKY */
3401 /* end-sanitize-sky */
3405 cop_sw (SIM_DESC sd
,
3411 unsigned int value
= 0;
3416 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3419 hold
= FPR_STATE
[coproc_reg
];
3420 FPR_STATE
[coproc_reg
] = fmt_word
;
3421 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3422 FPR_STATE
[coproc_reg
] = hold
;
3427 #if 0 /* should be controlled by configuration option */
3428 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3437 cop_sd (SIM_DESC sd
,
3447 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3449 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3454 #if 0 /* should be controlled by configuration option */
3455 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3464 /* start-sanitize-sky */
3467 cop_sq (SIM_DESC sd
,
3473 unsigned128 value
= U16_8(0, 0);
3481 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3482 coproc_num
,coproc_reg
,pr_addr(cia
));
3488 #endif /* TARGET_SKY */
3489 /* end-sanitize-sky */
3493 decode_coproc (SIM_DESC sd
,
3496 unsigned int instruction
)
3498 int coprocnum
= ((instruction
>> 26) & 3);
3502 case 0: /* standard CPU control and cache registers */
3504 int code
= ((instruction
>> 21) & 0x1F);
3505 /* R4000 Users Manual (second edition) lists the following CP0
3507 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3508 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3509 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3510 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3511 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3512 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3513 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3514 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3515 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3516 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3518 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0))
3520 int rt
= ((instruction
>> 16) & 0x1F);
3521 int rd
= ((instruction
>> 11) & 0x1F);
3523 switch (rd
) /* NOTEs: Standard CP0 registers */
3525 /* 0 = Index R4000 VR4100 VR4300 */
3526 /* 1 = Random R4000 VR4100 VR4300 */
3527 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3528 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3529 /* 4 = Context R4000 VR4100 VR4300 */
3530 /* 5 = PageMask R4000 VR4100 VR4300 */
3531 /* 6 = Wired R4000 VR4100 VR4300 */
3532 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3533 /* 9 = Count R4000 VR4100 VR4300 */
3534 /* 10 = EntryHi R4000 VR4100 VR4300 */
3535 /* 11 = Compare R4000 VR4100 VR4300 */
3536 /* 12 = SR R4000 VR4100 VR4300 */
3543 /* 13 = Cause R4000 VR4100 VR4300 */
3550 /* 14 = EPC R4000 VR4100 VR4300 */
3551 /* 15 = PRId R4000 VR4100 VR4300 */
3552 #ifdef SUBTARGET_R3900
3561 /* 16 = Config R4000 VR4100 VR4300 */
3564 GPR
[rt
] = C0_CONFIG
;
3566 C0_CONFIG
= GPR
[rt
];
3569 #ifdef SUBTARGET_R3900
3578 /* 17 = LLAddr R4000 VR4100 VR4300 */
3580 /* 18 = WatchLo R4000 VR4100 VR4300 */
3581 /* 19 = WatchHi R4000 VR4100 VR4300 */
3582 /* 20 = XContext R4000 VR4100 VR4300 */
3583 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3584 /* 27 = CacheErr R4000 VR4100 */
3585 /* 28 = TagLo R4000 VR4100 VR4300 */
3586 /* 29 = TagHi R4000 VR4100 VR4300 */
3587 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3588 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3589 /* CPR[0,rd] = GPR[rt]; */
3592 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3594 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3597 else if (code
== 0x10 && (instruction
& 0x3f) == 0x18)
3600 if (SR
& status_ERL
)
3602 /* Oops, not yet available */
3603 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3613 else if (code
== 0x10 && (instruction
& 0x3f) == 0x10)
3617 else if (code
== 0x10 && (instruction
& 0x3f) == 0x1F)
3625 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3626 /* TODO: When executing an ERET or RFE instruction we should
3627 clear LLBIT, to ensure that any out-standing atomic
3628 read/modify/write sequence fails. */
3632 case 2: /* undefined co-processor */
3636 /* start-sanitize-sky */
3638 /* On the R5900, this refers to a "VU" vector co-processor. */
3640 int i_25_21
= (instruction
>> 21) & 0x1f;
3641 int i_20_16
= (instruction
>> 16) & 0x1f;
3642 int i_15_11
= (instruction
>> 11) & 0x1f;
3643 int i_15_0
= instruction
& 0xffff;
3644 int i_10_1
= (instruction
>> 1) & 0x3ff;
3645 int i_5_0
= instruction
& 0x03f;
3646 int interlock
= instruction
& 0x01;
3647 int co
= (instruction
>> 25) & 0x01;
3648 /* setup for semantic.c-like actions below */
3649 typedef unsigned_4 instruction_word
;
3652 sim_cpu
* CPU_
= cpu
;
3656 /* test COP2 usability */
3657 if(! (SR
& status_CU2
))
3659 SignalException(CoProcessorUnusable
,instruction
);
3663 /* classify & execute basic COP2 instructions */
3664 if(i_25_21
== 0x08 && i_20_16
== 0x00) /* BC2F */
3666 address_word offset
= EXTEND16(i_15_0
) << 2;
3667 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3669 else if(i_25_21
== 0x08 && i_20_16
==0x02) /* BC2FL */
3671 address_word offset
= EXTEND16(i_15_0
) << 2;
3672 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3673 else NULLIFY_NEXT_INSTRUCTION();
3675 else if(i_25_21
== 0x08 && i_20_16
== 0x01) /* BC2T */
3677 address_word offset
= EXTEND16(i_15_0
) << 2;
3678 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3680 else if(i_25_21
== 0x08 && i_20_16
== 0x03) /* BC2TL */
3682 address_word offset
= EXTEND16(i_15_0
) << 2;
3683 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3684 else NULLIFY_NEXT_INSTRUCTION();
3686 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3687 (i_25_21
== 0x01)) /* QMFC2 */
3691 address_word vu_cr_addr
; /* VU control register address */
3694 /* interlock checking */
3695 if(vu0_busy_in_macro_mode()) /* busy in macro mode */
3697 /* interlock bit invalid here */
3699 ; /* XXX: warning */
3701 /* always check data hazard */
3702 while(vu0_macro_hazard_check(id
))
3705 else if(vu0_busy_in_micro_mode() && interlock
)
3707 while(vu0_busy_in_micro_mode())
3711 /* compute VU register address */
3712 if(i_25_21
== 0x01) /* QMFC2 */
3713 vu_cr_addr
= VU0_REGISTER_WINDOW_START
+ (id
* 16);
3715 vu_cr_addr
= VU0_MST
+ (id
* 16);
3717 /* read or write word */
3718 data
= sim_core_read_aligned_4(cpu
, cia
, read_map
, vu_cr_addr
);
3719 GPR
[rt
] = EXTEND64(data
);
3721 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3722 (i_25_21
== 0x05)) /* QMTC2 */
3726 address_word vu_cr_addr
; /* VU control register address */
3729 /* interlock checking */
3730 if(vu0_busy_in_macro_mode()) /* busy in macro mode */
3732 /* interlock bit invalid here */
3734 ; /* XXX: warning */
3736 /* always check data hazard */
3737 while(vu0_macro_hazard_check(id
))
3740 else if(vu0_busy_in_micro_mode())
3744 while(! vu0_micro_interlock_released())
3749 /* compute VU register address */
3750 if(i_25_21
== 0x05) /* QMTC2 */
3751 vu_cr_addr
= VU0_REGISTER_WINDOW_START
+ (id
* 16);
3753 vu_cr_addr
= VU0_MST
+ (id
* 16);
3756 sim_core_write_aligned_4(cpu
, cia
, write_map
, vu_cr_addr
, data
);
3758 else if( 0 /* XXX: ... upper ... */)
3760 unsigned_4 vu_upper
, vu_lower
;
3762 0x00000000 | /* bits 31 .. 25 */
3763 instruction
& 0x01ffffff; /* bits 24 .. 0 */
3764 vu_lower
= 0x8000033c; /* NOP */
3766 while(vu0_busy_in_micro_mode())
3769 vu0_macro_issue(vu_upper
, vu_lower
);
3771 else if( 0 /* XXX: ... lower ... */)
3773 unsigned_4 vu_upper
, vu_lower
;
3774 vu_upper
= 0x000002ff; /* NOP */
3776 0x10000000 | /* bits 31 .. 25 */
3777 instruction
& 0x01ffffff; /* bits 24 .. 0 */
3779 while(vu0_busy_in_micro_mode())
3782 vu0_macro_issue(vu_upper
, vu_lower
);
3785 /* ... other COP2 instructions ... */
3788 SignalException(ReservedInstruction
, instruction
);
3792 /* cleanup for semantic.c-like actions above */
3795 #endif /* TARGET_SKY */
3796 /* end-sanitize-sky */
3800 sim_io_eprintf(sd
,"COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3801 instruction
,pr_addr(cia
));
3806 case 1: /* should not occur (FPU co-processor) */
3807 case 3: /* should not occur (FPU co-processor) */
3808 SignalException(ReservedInstruction
,instruction
);
3816 /*-- instruction simulation -------------------------------------------------*/
3818 /* When the IGEN simulator is being built, the function below is be
3819 replaced by a generated version. However, WITH_IGEN == 2 indicates
3820 that the fubction below should be compiled but under a different
3821 name (to allow backward compatibility) */
3823 #if (WITH_IGEN != 1)
3825 void old_engine_run
PARAMS ((SIM_DESC sd
, int next_cpu_nr
, int siggnal
));
3827 old_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3830 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3833 int next_cpu_nr
; /* ignore */
3834 int nr_cpus
; /* ignore */
3835 int siggnal
; /* ignore */
3837 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* hardwire to cpu 0 */
3838 #if !defined(FASTSIM)
3839 unsigned int pipeline_count
= 1;
3843 if (STATE_MEMORY (sd
) == NULL
) {
3844 printf("DBG: simulate() entered with no memory\n");
3849 #if 0 /* Disabled to check that everything works OK */
3850 /* The VR4300 seems to sign-extend the PC on its first
3851 access. However, this may just be because it is currently
3852 configured in 32bit mode. However... */
3853 PC
= SIGNEXTEND(PC
,32);
3856 /* main controlling loop */
3858 /* vaddr is slowly being replaced with cia - current instruction
3860 address_word cia
= (uword64
)PC
;
3861 address_word vaddr
= cia
;
3864 unsigned int instruction
; /* uword64? what's this used for? FIXME! */
3868 printf("DBG: state = 0x%08X :",state
);
3869 if (state
& simHALTEX
) printf(" simHALTEX");
3870 if (state
& simHALTIN
) printf(" simHALTIN");
3875 DSSTATE
= (STATE
& simDELAYSLOT
);
3878 sim_io_printf(sd
,"DBG: DSPC = 0x%s\n",pr_addr(DSPC
));
3881 /* Fetch the next instruction from the simulator memory: */
3882 if (AddressTranslation(cia
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) {
3883 if ((vaddr
& 1) == 0) {
3884 /* Copy the action of the LW instruction */
3885 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3886 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3889 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3890 LoadMemory(&value
,NULL
,cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3891 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3892 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3894 /* Copy the action of the LH instruction */
3895 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 1) : 0);
3896 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 1) : 0);
3899 paddr
= (((paddr
& ~ (uword64
) 1) & ~LOADDRMASK
)
3900 | (((paddr
& ~ (uword64
) 1) & LOADDRMASK
) ^ (reverse
<< 1)));
3901 LoadMemory(&value
,NULL
,cca
, AccessLength_HALFWORD
,
3902 paddr
& ~ (uword64
) 1,
3903 vaddr
, isINSTRUCTION
, isREAL
);
3904 byte
= (((vaddr
&~ (uword64
) 1) & LOADDRMASK
) ^ (bigend
<< 1));
3905 instruction
= ((value
>> (8 * byte
)) & 0xFFFF);
3908 fprintf(stderr
,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC
));
3913 sim_io_printf(sd
,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction
,pr_addr(PC
));
3916 /* This is required by exception processing, to ensure that we can
3917 cope with exceptions in the delay slots of branches that may
3918 already have changed the PC. */
3919 if ((vaddr
& 1) == 0)
3920 PC
+= 4; /* increment ready for the next fetch */
3923 /* NOTE: If we perform a delay slot change to the PC, this
3924 increment is not requuired. However, it would make the
3925 simulator more complicated to try and avoid this small hit. */
3927 /* Currently this code provides a simple model. For more
3928 complicated models we could perform exception status checks at
3929 this point, and set the simSTOP state as required. This could
3930 also include processing any hardware interrupts raised by any
3931 I/O model attached to the simulator context.
3933 Support for "asynchronous" I/O events within the simulated world
3934 could be providing by managing a counter, and calling a I/O
3935 specific handler when a particular threshold is reached. On most
3936 architectures a decrement and check for zero operation is
3937 usually quicker than an increment and compare. However, the
3938 process of managing a known value decrement to zero, is higher
3939 than the cost of using an explicit value UINT_MAX into the
3940 future. Which system is used will depend on how complicated the
3941 I/O model is, and how much it is likely to affect the simulator
3944 If events need to be scheduled further in the future than
3945 UINT_MAX event ticks, then the I/O model should just provide its
3946 own counter, triggered from the event system. */
3948 /* MIPS pipeline ticks. To allow for future support where the
3949 pipeline hit of individual instructions is known, this control
3950 loop manages a "pipeline_count" variable. It is initialised to
3951 1 (one), and will only be changed by the simulator engine when
3952 executing an instruction. If the engine does not have access to
3953 pipeline cycle count information then all instructions will be
3954 treated as using a single cycle. NOTE: A standard system is not
3955 provided by the default simulator because different MIPS
3956 architectures have different cycle counts for the same
3959 [NOTE: pipeline_count has been replaced the event queue] */
3961 /* shuffle the floating point status pipeline state */
3962 ENGINE_ISSUE_PREFIX_HOOK();
3964 /* NOTE: For multi-context simulation environments the "instruction"
3965 variable should be local to this routine. */
3967 /* Shorthand accesses for engine. Note: If we wanted to use global
3968 variables (and a single-threaded simulator engine), then we can
3969 create the actual variables with these names. */
3971 if (!(STATE
& simSKIPNEXT
)) {
3972 /* Include the simulator engine */
3973 #include "oengine.c"
3974 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3975 #error "Mismatch between run-time simulator code and simulation engine"
3977 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3978 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3980 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3981 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3984 #if defined(WARN_LOHI)
3985 /* Decrement the HI/LO validity ticks */
3990 /* start-sanitize-r5900 */
3995 /* end-sanitize-r5900 */
3996 #endif /* WARN_LOHI */
3998 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3999 should check for it being changed. It is better doing it here,
4000 than within the simulator, since it will help keep the simulator
4003 #if defined(WARN_ZERO)
4004 sim_io_eprintf(sd
,"The ZERO register has been updated with 0x%s (PC = 0x%s) (reset back to zero)\n",pr_addr(ZERO
),pr_addr(cia
));
4005 #endif /* WARN_ZERO */
4006 ZERO
= 0; /* reset back to zero before next instruction */
4008 } else /* simSKIPNEXT check */
4009 STATE
&= ~simSKIPNEXT
;
4011 /* If the delay slot was active before the instruction is
4012 executed, then update the PC to its new value: */
4015 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC
));
4024 #if !defined(FASTSIM)
4025 if (sim_events_tickn (sd
, pipeline_count
))
4027 /* cpu->cia = cia; */
4028 sim_events_process (sd
);
4031 if (sim_events_tick (sd
))
4033 /* cpu->cia = cia; */
4034 sim_events_process (sd
);
4036 #endif /* FASTSIM */
4042 /* This code copied from gdb's utils.c. Would like to share this code,
4043 but don't know of a common place where both could get to it. */
4045 /* Temporary storage using circular buffer */
4051 static char buf
[NUMCELLS
][CELLSIZE
];
4053 if (++cell
>=NUMCELLS
) cell
=0;
4057 /* Print routines to handle variable size regs, etc */
4059 /* Eliminate warning from compiler on 32-bit systems */
4060 static int thirty_two
= 32;
4066 char *paddr_str
=get_cell();
4067 switch (sizeof(addr
))
4070 sprintf(paddr_str
,"%08lx%08lx",
4071 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
4074 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
4077 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
4080 sprintf(paddr_str
,"%x",addr
);
4089 char *paddr_str
=get_cell();
4090 sprintf(paddr_str
,"%08lx%08lx",
4091 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
4097 pending_tick (SIM_DESC sd
,
4102 sim_io_printf (sd
, "PENDING_DRAIN - pending_in = %d, pending_out = %d, pending_total = %d\n", PENDING_IN
, PENDING_OUT
, PENDING_TOTAL
);
4103 if (PENDING_OUT
!= PENDING_IN
)
4106 int index
= PENDING_OUT
;
4107 int total
= PENDING_TOTAL
;
4108 if (PENDING_TOTAL
== 0)
4109 sim_engine_abort (SD
, CPU
, cia
, "PENDING_DRAIN - Mis-match on pending update pointers\n");
4110 for (loop
= 0; (loop
< total
); loop
++)
4112 if (PENDING_SLOT_DEST
[index
] != NULL
)
4114 PENDING_SLOT_DELAY
[index
] -= 1;
4115 if (PENDING_SLOT_DELAY
[index
] == 0)
4117 if (PENDING_SLOT_BIT
[index
] >= 0)
4118 switch (PENDING_SLOT_SIZE
[index
])
4121 if (PENDING_SLOT_VALUE
[index
])
4122 *(unsigned32
*)PENDING_SLOT_DEST
[index
] |=
4123 BIT32 (PENDING_SLOT_BIT
[index
]);
4125 *(unsigned32
*)PENDING_SLOT_DEST
[index
] &=
4126 BIT32 (PENDING_SLOT_BIT
[index
]);
4129 if (PENDING_SLOT_VALUE
[index
])
4130 *(unsigned64
*)PENDING_SLOT_DEST
[index
] |=
4131 BIT64 (PENDING_SLOT_BIT
[index
]);
4133 *(unsigned64
*)PENDING_SLOT_DEST
[index
] &=
4134 BIT64 (PENDING_SLOT_BIT
[index
]);
4139 switch (PENDING_SLOT_SIZE
[index
])
4142 *(unsigned32
*)PENDING_SLOT_DEST
[index
] =
4143 PENDING_SLOT_VALUE
[index
];
4146 *(unsigned64
*)PENDING_SLOT_DEST
[index
] =
4147 PENDING_SLOT_VALUE
[index
];
4151 if (PENDING_OUT
== index
)
4153 PENDING_SLOT_DEST
[index
] = NULL
;
4154 PENDING_OUT
= (PENDING_OUT
+ 1) % PSLOTS
;
4159 index
= (index
+ 1) % PSLOTS
;
4163 /*---------------------------------------------------------------------------*/
4164 /*> EOF interp.c <*/