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: */
86 #define LOADDRMASK (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3)
93 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
98 /* The following reserved instruction value is used when a simulator
99 trap is required. NOTE: Care must be taken, since this value may be
100 used in later revisions of the MIPS ISA. */
101 #define RSVD_INSTRUCTION (0x00000005)
102 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
104 #define RSVD_INSTRUCTION_ARG_SHIFT 6
105 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
108 /* Bits in the Debug register */
109 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
110 #define Debug_DM 0x40000000 /* Debug Mode */
111 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
117 /*---------------------------------------------------------------------------*/
118 /*-- GDB simulator interface ------------------------------------------------*/
119 /*---------------------------------------------------------------------------*/
121 static void ColdReset
PARAMS((SIM_DESC sd
));
123 /*---------------------------------------------------------------------------*/
127 #define DELAYSLOT() {\
128 if (STATE & simDELAYSLOT)\
129 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
130 STATE |= simDELAYSLOT;\
133 #define JALDELAYSLOT() {\
135 STATE |= simJALDELAYSLOT;\
139 STATE &= ~simDELAYSLOT;\
140 STATE |= simSKIPNEXT;\
143 #define CANCELDELAYSLOT() {\
145 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
148 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
149 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
151 #define K0BASE (0x80000000)
152 #define K0SIZE (0x20000000)
153 #define K1BASE (0xA0000000)
154 #define K1SIZE (0x20000000)
155 #define MONITOR_BASE (0xBFC00000)
156 #define MONITOR_SIZE (1 << 11)
157 #define MEM_SIZE (2 << 20)
159 /* start-sanitize-sky */
162 #define MEM_SIZE (16 << 20) /* 16 MB */
164 /* end-sanitize-sky */
167 static char *tracefile
= "trace.din"; /* default filename for trace log */
168 FILE *tracefh
= NULL
;
169 static void open_trace
PARAMS((SIM_DESC sd
));
172 static DECLARE_OPTION_HANDLER (mips_option_handler
);
175 OPTION_DINERO_TRACE
= OPTION_START
,
177 /* start-sanitize-sky */
179 /* end-sanitize-sky */
183 mips_option_handler (sd
, cpu
, opt
, arg
, is_command
)
193 case OPTION_DINERO_TRACE
: /* ??? */
195 /* Eventually the simTRACE flag could be treated as a toggle, to
196 allow external control of the program points being traced
197 (i.e. only from main onwards, excluding the run-time setup,
199 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
201 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
204 else if (strcmp (arg
, "yes") == 0)
206 else if (strcmp (arg
, "no") == 0)
208 else if (strcmp (arg
, "on") == 0)
210 else if (strcmp (arg
, "off") == 0)
214 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
221 Simulator constructed without dinero tracing support (for performance).\n\
222 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
226 case OPTION_DINERO_FILE
:
228 if (optarg
!= NULL
) {
230 tmp
= (char *)malloc(strlen(optarg
) + 1);
233 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
239 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
245 /* start-sanitize-sky */
246 case OPTION_FLOAT_TYPE
:
247 /* Use host (fast) or target (accurate) floating point implementation. */
248 if (arg
&& strcmp (arg
, "host") == 0)
249 STATE_FP_TYPE_OPT (sd
) &= ~STATE_FP_TYPE_OPT_TARGET
;
250 else if (arg
&& strcmp (arg
, "target") == 0)
251 STATE_FP_TYPE_OPT (sd
) |= STATE_FP_TYPE_OPT_TARGET
;
254 fprintf (stderr
, "Unrecognized float-type option `%s'\n", arg
);
258 /* end-sanitize-sky */
264 static const OPTION mips_options
[] =
266 { {"dinero-trace", optional_argument
, NULL
, OPTION_DINERO_TRACE
},
267 '\0', "on|off", "Enable dinero tracing",
268 mips_option_handler
},
269 { {"dinero-file", required_argument
, NULL
, OPTION_DINERO_FILE
},
270 '\0', "FILE", "Write dinero trace to FILE",
271 mips_option_handler
},
272 /* start-sanitize-sky */
273 { {"float-type", required_argument
, NULL
, OPTION_FLOAT_TYPE
},
274 '\0', "host|target", "Use host (fast) or target (accurate) floating point",
275 mips_option_handler
},
276 /* end-sanitize-sky */
277 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
281 int interrupt_pending
;
284 interrupt_event (SIM_DESC sd
, void *data
)
286 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
289 interrupt_pending
= 0;
290 SignalExceptionInterrupt ();
292 else if (!interrupt_pending
)
293 sim_events_schedule (sd
, 1, interrupt_event
, data
);
297 /*---------------------------------------------------------------------------*/
298 /*-- Device registration hook -----------------------------------------------*/
299 /*---------------------------------------------------------------------------*/
300 static void device_init(SIM_DESC sd
) {
302 extern void register_devices(SIM_DESC
);
303 register_devices(sd
);
307 /*---------------------------------------------------------------------------*/
308 /*-- GDB simulator interface ------------------------------------------------*/
309 /*---------------------------------------------------------------------------*/
312 sim_open (kind
, cb
, abfd
, argv
)
318 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
319 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
321 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
323 /* FIXME: watchpoints code shouldn't need this */
324 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
325 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
326 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
330 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
332 sim_add_option_table (sd
, NULL
, mips_options
);
334 /* Allocate core managed memory */
337 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
, MONITOR_SIZE
);
338 /* For compatibility with the old code - under this (at level one)
339 are the kernel spaces K0 & K1. Both of these map to a single
340 smaller sub region */
341 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
342 /* start-sanitize-sky */
344 /* end-sanitize-sky */
345 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
347 MEM_SIZE
, /* actual size */
349 /* start-sanitize-sky */
351 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x",
353 MEM_SIZE
, /* actual size */
355 0); /* add alias at 0x0000 */
357 /* end-sanitize-sky */
361 /* getopt will print the error message so we just have to exit if this fails.
362 FIXME: Hmmm... in the case of gdb we need getopt to call
364 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
366 /* Uninstall the modules to avoid memory leaks,
367 file descriptor leaks, etc. */
368 sim_module_uninstall (sd
);
372 /* check for/establish the a reference program image */
373 if (sim_analyze_program (sd
,
374 (STATE_PROG_ARGV (sd
) != NULL
375 ? *STATE_PROG_ARGV (sd
)
379 sim_module_uninstall (sd
);
383 /* Configure/verify the target byte order and other runtime
384 configuration options */
385 if (sim_config (sd
) != SIM_RC_OK
)
387 sim_module_uninstall (sd
);
391 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
393 /* Uninstall the modules to avoid memory leaks,
394 file descriptor leaks, etc. */
395 sim_module_uninstall (sd
);
399 /* verify assumptions the simulator made about the host type system.
400 This macro does not return if there is a problem */
401 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
402 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
404 /* This is NASTY, in that we are assuming the size of specific
408 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
411 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
412 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ NR_FGR
)))
413 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
414 else if ((rn
>= 33) && (rn
<= 37))
415 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
416 else if ((rn
== SRIDX
)
419 || ((rn
>= 72) && (rn
<= 89)))
420 cpu
->register_widths
[rn
] = 32;
422 cpu
->register_widths
[rn
] = 0;
424 /* start-sanitize-r5900 */
426 /* set the 5900 "upper" registers to 64 bits */
427 for( rn
= LAST_EMBED_REGNUM
+1; rn
< NUM_REGS
; rn
++)
428 cpu
->register_widths
[rn
] = 64;
429 /* end-sanitize-r5900 */
431 /* start-sanitize-sky */
433 /* Now the VU registers */
434 for( rn
= 0; rn
< NUM_VU_INTEGER_REGS
; rn
++ ) {
435 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 16;
436 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 16;
439 for( rn
= NUM_VU_INTEGER_REGS
; rn
< NUM_VU_REGS
; rn
++ ) {
440 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
441 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 32;
444 /* end-sanitize-sky */
448 if (STATE
& simTRACE
)
452 /* Write the monitor trap address handlers into the monitor (eeprom)
453 address space. This can only be done once the target endianness
454 has been determined. */
457 /* Entry into the IDT monitor is via fixed address vectors, and
458 not using machine instructions. To avoid clashing with use of
459 the MIPS TRAP system, we place our own (simulator specific)
460 "undefined" instructions into the relevant vector slots. */
461 for (loop
= 0; (loop
< MONITOR_SIZE
); loop
+= 4)
463 address_word vaddr
= (MONITOR_BASE
+ loop
);
464 unsigned32 insn
= (RSVD_INSTRUCTION
| (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
) << RSVD_INSTRUCTION_ARG_SHIFT
));
466 sim_write (sd
, vaddr
, (char *)&insn
, sizeof (insn
));
468 /* The PMON monitor uses the same address space, but rather than
469 branching into it the address of a routine is loaded. We can
470 cheat for the moment, and direct the PMON routine to IDT style
471 instructions within the monitor space. This relies on the IDT
472 monitor not using the locations from 0xBFC00500 onwards as its
474 for (loop
= 0; (loop
< 24); loop
++)
476 address_word vaddr
= (MONITOR_BASE
+ 0x500 + (loop
* 4));
477 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
493 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
495 case 8: /* cliexit */
498 case 11: /* flush_cache */
502 /* FIXME - should monitor_base be SIM_ADDR?? */
503 value
= ((unsigned int)MONITOR_BASE
+ (value
* 8));
505 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
507 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
509 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
521 tracefh
= fopen(tracefile
,"wb+");
524 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
531 sim_close (sd
, quitting
)
536 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
539 /* "quitting" is non-zero if we cannot hang on errors */
541 /* Ensure that any resources allocated through the callback
542 mechanism are released: */
543 sim_io_shutdown (sd
);
546 if (tracefh
!= NULL
&& tracefh
!= stderr
)
551 /* FIXME - free SD */
558 sim_write (sd
,addr
,buffer
,size
)
561 unsigned char *buffer
;
565 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
567 /* Return the number of bytes written, or zero if error. */
569 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
572 /* We use raw read and write routines, since we do not want to count
573 the GDB memory accesses in our statistics gathering. */
575 for (index
= 0; index
< size
; index
++)
577 address_word vaddr
= (address_word
)addr
+ index
;
580 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
582 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
590 sim_read (sd
,addr
,buffer
,size
)
593 unsigned char *buffer
;
597 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
599 /* Return the number of bytes read, or zero if error. */
601 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
604 for (index
= 0; (index
< size
); index
++)
606 address_word vaddr
= (address_word
)addr
+ index
;
609 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isLOAD
, &paddr
, &cca
, isRAW
))
611 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
619 sim_store_register (sd
,rn
,memory
,length
)
622 unsigned char *memory
;
625 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
626 /* NOTE: gdb (the client) stores registers in target byte order
627 while the simulator uses host byte order */
629 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
632 /* Unfortunately this suffers from the same problem as the register
633 numbering one. We need to know what the width of each logical
634 register number is for the architecture being simulated. */
636 if (cpu
->register_widths
[rn
] == 0)
638 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
642 /* start-sanitize-r5900 */
643 if (rn
>= 90 && rn
< 90 + 32)
645 GPR1
[rn
- 90] = T2H_8 (*(unsigned64
*)memory
);
651 SA
= T2H_8(*(unsigned64
*)memory
);
653 case 122: /* FIXME */
654 LO1
= T2H_8(*(unsigned64
*)memory
);
656 case 123: /* FIXME */
657 HI1
= T2H_8(*(unsigned64
*)memory
);
660 /* end-sanitize-r5900 */
662 /* start-sanitize-sky */
664 if (rn
>= NUM_R5900_REGS
)
666 int size
= 4; /* Default register size */
668 rn
= rn
- NUM_R5900_REGS
;
670 if (rn
< NUM_VU_INTEGER_REGS
)
671 size
= write_vu_int_reg (&(vu0_device
.state
->regs
), rn
, memory
);
672 else if( rn
< NUM_VU_REGS
)
674 if (rn
>= FIRST_VEC_REG
)
677 size
= write_vu_vec_reg (&(vu0_device
.state
->regs
), rn
>>2, rn
&3,
680 else switch (rn
- NUM_VU_INTEGER_REGS
)
683 size
= write_vu_special_reg (vu0_device
.state
, VU_REG_CIA
,
687 size
= write_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MR
,
690 case 2: /* VU0 has no P register */
693 size
= write_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MI
,
697 size
= write_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MQ
,
701 size
= write_vu_acc_reg (&(vu0_device
.state
->regs
),
702 rn
- (NUM_VU_INTEGER_REGS
+ 5),
708 rn
= rn
- NUM_VU_REGS
;
710 if( rn
< NUM_VU_INTEGER_REGS
)
711 size
= write_vu_int_reg (&(vu1_device
.state
->regs
), rn
, memory
);
712 else if( rn
< NUM_VU_REGS
)
714 if (rn
>= FIRST_VEC_REG
)
717 size
= write_vu_vec_reg (&(vu1_device
.state
->regs
),
718 rn
>> 2, rn
& 3, memory
);
720 else switch (rn
- NUM_VU_INTEGER_REGS
)
723 size
= write_vu_special_reg (vu1_device
.state
, VU_REG_CIA
,
727 size
= write_vu_misc_reg (&(vu1_device
.state
->regs
),
731 size
= write_vu_misc_reg (&(vu1_device
.state
->regs
),
735 size
= write_vu_misc_reg (&(vu1_device
.state
->regs
),
739 size
= write_vu_misc_reg (&(vu1_device
.state
->regs
),
743 size
= write_vu_acc_reg (&(vu1_device
.state
->regs
),
744 rn
- (NUM_VU_INTEGER_REGS
+ 5),
750 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
756 /* end-sanitize-sky */
758 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
760 if (cpu
->register_widths
[rn
] == 32)
762 cpu
->fgr
[rn
- FGRIDX
] = T2H_4 (*(unsigned32
*)memory
);
767 cpu
->fgr
[rn
- FGRIDX
] = T2H_8 (*(unsigned64
*)memory
);
772 if (cpu
->register_widths
[rn
] == 32)
774 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
779 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
785 sim_fetch_register (sd
,rn
,memory
,length
)
788 unsigned char *memory
;
791 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
792 /* NOTE: gdb (the client) stores registers in target byte order
793 while the simulator uses host byte order */
795 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
798 if (cpu
->register_widths
[rn
] == 0)
800 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
804 /* start-sanitize-r5900 */
805 if (rn
>= 90 && rn
< 90 + 32)
807 *(unsigned64
*)memory
= GPR1
[rn
- 90];
813 *((unsigned64
*)memory
) = H2T_8(SA
);
815 case 122: /* FIXME */
816 *((unsigned64
*)memory
) = H2T_8(LO1
);
818 case 123: /* FIXME */
819 *((unsigned64
*)memory
) = H2T_8(HI1
);
822 /* end-sanitize-r5900 */
824 /* start-sanitize-sky */
826 if (rn
>= NUM_R5900_REGS
)
828 int size
= 4; /* default register width */
830 rn
= rn
- NUM_R5900_REGS
;
832 if (rn
< NUM_VU_INTEGER_REGS
)
833 size
= read_vu_int_reg (&(vu0_device
.state
->regs
), rn
, memory
);
834 else if (rn
< NUM_VU_REGS
)
836 if (rn
>= FIRST_VEC_REG
)
839 size
= read_vu_vec_reg (&(vu0_device
.state
->regs
), rn
>>2, rn
& 3,
842 else switch (rn
- NUM_VU_INTEGER_REGS
)
845 size
= read_vu_special_reg (vu0_device
.state
, VU_REG_CIA
,
850 size
= read_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MR
,
853 case 2: /* VU0 has no P register */
856 size
= read_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MI
,
860 size
= read_vu_misc_reg (&(vu0_device
.state
->regs
), VU_REG_MQ
,
864 size
= read_vu_acc_reg (&(vu0_device
.state
->regs
),
865 rn
- (NUM_VU_INTEGER_REGS
+ 5),
872 rn
= rn
- NUM_VU_REGS
;
874 if (rn
< NUM_VU_INTEGER_REGS
)
875 size
= read_vu_int_reg (&(vu1_device
.state
->regs
), rn
, memory
);
876 else if (rn
< NUM_VU_REGS
)
878 if (rn
>= FIRST_VEC_REG
)
881 size
= read_vu_vec_reg (&(vu1_device
.state
->regs
),
882 rn
>> 2, rn
& 3, memory
);
884 else switch (rn
- NUM_VU_INTEGER_REGS
)
887 size
= read_vu_special_reg (vu1_device
.state
, VU_REG_CIA
,
891 size
= read_vu_misc_reg (&(vu1_device
.state
->regs
),
895 size
= read_vu_misc_reg (&(vu1_device
.state
->regs
),
899 size
= read_vu_misc_reg (&(vu1_device
.state
->regs
),
903 size
= read_vu_misc_reg (&(vu1_device
.state
->regs
),
907 size
= read_vu_acc_reg (&(vu1_device
.state
->regs
),
908 rn
- (NUM_VU_INTEGER_REGS
+ 5),
914 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
920 /* end-sanitize-sky */
922 /* Any floating point register */
923 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
925 if (cpu
->register_widths
[rn
] == 32)
927 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGRIDX
]);
932 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGRIDX
]);
937 if (cpu
->register_widths
[rn
] == 32)
939 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
944 *(unsigned64
*)memory
= H2T_8 ((unsigned64
)(cpu
->registers
[rn
]));
951 sim_create_inferior (sd
, abfd
, argv
,env
)
959 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
967 /* override PC value set by ColdReset () */
969 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
971 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
972 CIA_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
976 #if 0 /* def DEBUG */
979 /* We should really place the argv slot values into the argument
980 registers, and onto the stack as required. However, this
981 assumes that we have a stack defined, which is not
982 necessarily true at the moment. */
984 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
985 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
986 printf("DBG: arg \"%s\"\n",*cptr
);
994 sim_do_command (sd
,cmd
)
998 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
999 sim_io_printf (sd
, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1003 /*---------------------------------------------------------------------------*/
1004 /*-- Private simulator support interface ------------------------------------*/
1005 /*---------------------------------------------------------------------------*/
1007 /* Read a null terminated string from memory, return in a buffer */
1009 fetch_str (sd
, addr
)
1016 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1018 buf
= NZALLOC (char, nr
+ 1);
1019 sim_read (sd
, addr
, buf
, nr
);
1023 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1025 sim_monitor (SIM_DESC sd
,
1028 unsigned int reason
)
1031 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1034 /* The IDT monitor actually allows two instructions per vector
1035 slot. However, the simulator currently causes a trap on each
1036 individual instruction. We cheat, and lose the bottom bit. */
1039 /* The following callback functions are available, however the
1040 monitor we are simulating does not make use of them: get_errno,
1041 isatty, lseek, rename, system, time and unlink */
1045 case 6: /* int open(char *path,int flags) */
1047 char *path
= fetch_str (sd
, A0
);
1048 V0
= sim_io_open (sd
, path
, (int)A1
);
1053 case 7: /* int read(int file,char *ptr,int len) */
1057 char *buf
= zalloc (nr
);
1058 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1059 sim_write (sd
, A1
, buf
, nr
);
1064 case 8: /* int write(int file,char *ptr,int len) */
1068 char *buf
= zalloc (nr
);
1069 sim_read (sd
, A1
, buf
, nr
);
1070 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1075 case 10: /* int close(int file) */
1077 V0
= sim_io_close (sd
, (int)A0
);
1081 case 2: /* Densan monitor: char inbyte(int waitflag) */
1083 if (A0
== 0) /* waitflag == NOWAIT */
1084 V0
= (unsigned_word
)-1;
1086 /* Drop through to case 11 */
1088 case 11: /* char inbyte(void) */
1091 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1093 sim_io_error(sd
,"Invalid return from character read");
1094 V0
= (unsigned_word
)-1;
1097 V0
= (unsigned_word
)tmp
;
1101 case 3: /* Densan monitor: void co(char chr) */
1102 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1104 char tmp
= (char)(A0
& 0xFF);
1105 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1109 case 17: /* void _exit() */
1111 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1112 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1113 (unsigned int)(A0
& 0xFFFFFFFF));
1117 case 28 : /* PMON flush_cache */
1120 case 55: /* void get_mem_info(unsigned int *ptr) */
1121 /* in: A0 = pointer to three word memory location */
1122 /* out: [A0 + 0] = size */
1123 /* [A0 + 4] = instruction cache size */
1124 /* [A0 + 8] = data cache size */
1126 unsigned_4 value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1127 unsigned_4 zero
= 0;
1129 sim_write (sd
, A0
+ 0, (char *)&value
, 4);
1130 sim_write (sd
, A0
+ 4, (char *)&zero
, 4);
1131 sim_write (sd
, A0
+ 8, (char *)&zero
, 4);
1132 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1136 case 158 : /* PMON printf */
1137 /* in: A0 = pointer to format string */
1138 /* A1 = optional argument 1 */
1139 /* A2 = optional argument 2 */
1140 /* A3 = optional argument 3 */
1142 /* The following is based on the PMON printf source */
1144 address_word s
= A0
;
1146 signed_word
*ap
= &A1
; /* 1st argument */
1147 /* This isn't the quickest way, since we call the host print
1148 routine for every character almost. But it does avoid
1149 having to allocate and manage a temporary string buffer. */
1150 /* TODO: Include check that we only use three arguments (A1,
1152 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1157 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1158 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1159 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1161 if (strchr ("dobxXulscefg%", s
))
1176 else if (c
>= '1' && c
<= '9')
1180 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1183 n
= (unsigned int)strtol(tmp
,NULL
,10);
1196 sim_io_printf (sd
, "%%");
1201 address_word p
= *ap
++;
1203 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1204 sim_io_printf(sd
, "%c", ch
);
1207 sim_io_printf(sd
,"(null)");
1210 sim_io_printf (sd
, "%c", (int)*ap
++);
1215 sim_read (sd
, s
++, &c
, 1);
1219 sim_read (sd
, s
++, &c
, 1);
1222 if (strchr ("dobxXu", c
))
1224 word64 lv
= (word64
) *ap
++;
1226 sim_io_printf(sd
,"<binary not supported>");
1229 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1231 sim_io_printf(sd
, tmp
, lv
);
1233 sim_io_printf(sd
, tmp
, (int)lv
);
1236 else if (strchr ("eEfgG", c
))
1238 double dbl
= *(double*)(ap
++);
1239 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1240 sim_io_printf (sd
, tmp
, dbl
);
1246 sim_io_printf(sd
, "%c", c
);
1252 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1253 reason
, pr_addr(cia
));
1259 /* Store a word into memory. */
1262 store_word (SIM_DESC sd
,
1271 if ((vaddr
& 3) != 0)
1272 SignalExceptionAddressStore ();
1275 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1278 const uword64 mask
= 7;
1282 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1283 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1284 memval
= ((uword64
) val
) << (8 * byte
);
1285 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1291 /* Load a word from memory. */
1294 load_word (SIM_DESC sd
,
1299 if ((vaddr
& 3) != 0)
1300 SignalExceptionAddressLoad ();
1306 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1309 const uword64 mask
= 0x7;
1310 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1311 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1315 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1316 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1318 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1319 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1326 /* Simulate the mips16 entry and exit pseudo-instructions. These
1327 would normally be handled by the reserved instruction exception
1328 code, but for ease of simulation we just handle them directly. */
1331 mips16_entry (SIM_DESC sd
,
1336 int aregs
, sregs
, rreg
;
1339 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1342 aregs
= (insn
& 0x700) >> 8;
1343 sregs
= (insn
& 0x0c0) >> 6;
1344 rreg
= (insn
& 0x020) >> 5;
1346 /* This should be checked by the caller. */
1355 /* This is the entry pseudo-instruction. */
1357 for (i
= 0; i
< aregs
; i
++)
1358 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1366 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1369 for (i
= 0; i
< sregs
; i
++)
1372 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1380 /* This is the exit pseudo-instruction. */
1387 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1390 for (i
= 0; i
< sregs
; i
++)
1393 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1398 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1402 FGR
[0] = WORD64LO (GPR
[4]);
1403 FPR_STATE
[0] = fmt_uninterpreted
;
1405 else if (aregs
== 6)
1407 FGR
[0] = WORD64LO (GPR
[5]);
1408 FGR
[1] = WORD64LO (GPR
[4]);
1409 FPR_STATE
[0] = fmt_uninterpreted
;
1410 FPR_STATE
[1] = fmt_uninterpreted
;
1419 /*-- trace support ----------------------------------------------------------*/
1421 /* The TRACE support is provided (if required) in the memory accessing
1422 routines. Since we are also providing the architecture specific
1423 features, the architecture simulation code can also deal with
1424 notifying the TRACE world of cache flushes, etc. Similarly we do
1425 not need to provide profiling support in the simulator engine,
1426 since we can sample in the instruction fetch control loop. By
1427 defining the TRACE manifest, we add tracing as a run-time
1431 /* Tracing by default produces "din" format (as required by
1432 dineroIII). Each line of such a trace file *MUST* have a din label
1433 and address field. The rest of the line is ignored, so comments can
1434 be included if desired. The first field is the label which must be
1435 one of the following values:
1440 3 escape record (treated as unknown access type)
1441 4 escape record (causes cache flush)
1443 The address field is a 32bit (lower-case) hexadecimal address
1444 value. The address should *NOT* be preceded by "0x".
1446 The size of the memory transfer is not important when dealing with
1447 cache lines (as long as no more than a cache line can be
1448 transferred in a single operation :-), however more information
1449 could be given following the dineroIII requirement to allow more
1450 complete memory and cache simulators to provide better
1451 results. i.e. the University of Pisa has a cache simulator that can
1452 also take bus size and speed as (variable) inputs to calculate
1453 complete system performance (a much more useful ability when trying
1454 to construct an end product, rather than a processor). They
1455 currently have an ARM version of their tool called ChARM. */
1459 dotrace (SIM_DESC sd
,
1467 if (STATE
& simTRACE
) {
1469 fprintf(tracefh
,"%d %s ; width %d ; ",
1473 va_start(ap
,comment
);
1474 vfprintf(tracefh
,comment
,ap
);
1476 fprintf(tracefh
,"\n");
1478 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1479 we may be generating 64bit ones, we should put the hi-32bits of the
1480 address into the comment field. */
1482 /* TODO: Provide a buffer for the trace lines. We can then avoid
1483 performing writes until the buffer is filled, or the file is
1486 /* NOTE: We could consider adding a comment field to the "din" file
1487 produced using type 3 markers (unknown access). This would then
1488 allow information about the program that the "din" is for, and
1489 the MIPs world that was being simulated, to be placed into the
1496 /*---------------------------------------------------------------------------*/
1497 /*-- simulator engine -------------------------------------------------------*/
1498 /*---------------------------------------------------------------------------*/
1501 ColdReset (SIM_DESC sd
)
1504 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1506 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1507 /* RESET: Fixed PC address: */
1508 PC
= UNSIGNED64 (0xFFFFFFFFBFC00000);
1509 /* The reset vector address is in the unmapped, uncached memory space. */
1511 SR
&= ~(status_SR
| status_TS
| status_RP
);
1512 SR
|= (status_ERL
| status_BEV
);
1514 /* Cheat and allow access to the complete register set immediately */
1515 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1516 && WITH_TARGET_WORD_BITSIZE
== 64)
1517 SR
|= status_FR
; /* 64bit registers */
1519 /* Ensure that any instructions with pending register updates are
1521 PENDING_INVALIDATE();
1523 /* Initialise the FPU registers to the unknown state */
1524 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1527 for (rn
= 0; (rn
< 32); rn
++)
1528 FPR_STATE
[rn
] = fmt_uninterpreted
;
1534 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
1536 /* Translate a virtual address to a physical address and cache
1537 coherence algorithm describing the mechanism used to resolve the
1538 memory reference. Given the virtual address vAddr, and whether the
1539 reference is to Instructions ot Data (IorD), find the corresponding
1540 physical address (pAddr) and the cache coherence algorithm (CCA)
1541 used to resolve the reference. If the virtual address is in one of
1542 the unmapped address spaces the physical address and the CCA are
1543 determined directly by the virtual address. If the virtual address
1544 is in one of the mapped address spaces then the TLB is used to
1545 determine the physical address and access type; if the required
1546 translation is not present in the TLB or the desired access is not
1547 permitted the function fails and an exception is taken.
1549 NOTE: Normally (RAW == 0), when address translation fails, this
1550 function raises an exception and does not return. */
1553 address_translation (SIM_DESC sd
,
1559 address_word
*pAddr
,
1563 int res
= -1; /* TRUE : Assume good return */
1566 sim_io_printf(sd
,"AddressTranslation(0x%s,%s,%s,...);\n",pr_addr(vAddr
),(IorD
? "isDATA" : "isINSTRUCTION"),(LorS
? "iSTORE" : "isLOAD"));
1569 /* Check that the address is valid for this memory model */
1571 /* For a simple (flat) memory model, we simply pass virtual
1572 addressess through (mostly) unchanged. */
1573 vAddr
&= 0xFFFFFFFF;
1575 *pAddr
= vAddr
; /* default for isTARGET */
1576 *CCA
= Uncached
; /* not used for isHOST */
1581 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
1583 /* Prefetch data from memory. Prefetch is an advisory instruction for
1584 which an implementation specific action is taken. The action taken
1585 may increase performance, but must not change the meaning of the
1586 program, or alter architecturally-visible state. */
1589 prefetch (SIM_DESC sd
,
1599 sim_io_printf(sd
,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA
,pr_addr(pAddr
),pr_addr(vAddr
),DATA
,hint
);
1602 /* For our simple memory model we do nothing */
1606 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
1608 /* Load a value from memory. Use the cache and main memory as
1609 specified in the Cache Coherence Algorithm (CCA) and the sort of
1610 access (IorD) to find the contents of AccessLength memory bytes
1611 starting at physical location pAddr. The data is returned in the
1612 fixed width naturally-aligned memory element (MemElem). The
1613 low-order two (or three) bits of the address and the AccessLength
1614 indicate which of the bytes within MemElem needs to be given to the
1615 processor. If the memory access type of the reference is uncached
1616 then only the referenced bytes are read from memory and valid
1617 within the memory element. If the access type is cached, and the
1618 data is not present in cache, an implementation specific size and
1619 alignment block of memory is read and loaded into the cache to
1620 satisfy a load reference. At a minimum, the block is the entire
1623 load_memory (SIM_DESC sd
,
1638 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"));
1641 #if defined(WARN_MEM)
1642 if (CCA
!= uncached
)
1643 sim_io_eprintf(sd
,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA
);
1644 #endif /* WARN_MEM */
1646 /* If instruction fetch then we need to check that the two lo-order
1647 bits are zero, otherwise raise a InstructionFetch exception: */
1648 if ((IorD
== isINSTRUCTION
)
1649 && ((pAddr
& 0x3) != 0)
1650 && (((pAddr
& 0x1) != 0) || ((vAddr
& 0x1) == 0)))
1651 SignalExceptionInstructionFetch ();
1653 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
)
1655 /* In reality this should be a Bus Error */
1656 sim_io_error (sd
, "AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",
1658 (LOADDRMASK
+ 1) << 2,
1663 dotrace (SD
, CPU
, tracefh
,((IorD
== isDATA
) ? 0 : 2),(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"load%s",((IorD
== isDATA
) ? "" : " instruction"));
1666 /* Read the specified number of bytes from memory. Adjust for
1667 host/target byte ordering/ Align the least significant byte
1670 switch (AccessLength
)
1672 case AccessLength_QUADWORD
:
1674 unsigned_16 val
= sim_core_read_aligned_16 (cpu
, NULL_CIA
, read_map
, pAddr
);
1675 value1
= VH8_16 (val
);
1676 value
= VL8_16 (val
);
1679 case AccessLength_DOUBLEWORD
:
1680 value
= sim_core_read_aligned_8 (cpu
, NULL_CIA
,
1683 case AccessLength_SEPTIBYTE
:
1684 value
= sim_core_read_misaligned_7 (cpu
, NULL_CIA
,
1687 case AccessLength_SEXTIBYTE
:
1688 value
= sim_core_read_misaligned_6 (cpu
, NULL_CIA
,
1691 case AccessLength_QUINTIBYTE
:
1692 value
= sim_core_read_misaligned_5 (cpu
, NULL_CIA
,
1695 case AccessLength_WORD
:
1696 value
= sim_core_read_aligned_4 (cpu
, NULL_CIA
,
1699 case AccessLength_TRIPLEBYTE
:
1700 value
= sim_core_read_misaligned_3 (cpu
, NULL_CIA
,
1703 case AccessLength_HALFWORD
:
1704 value
= sim_core_read_aligned_2 (cpu
, NULL_CIA
,
1707 case AccessLength_BYTE
:
1708 value
= sim_core_read_aligned_1 (cpu
, NULL_CIA
,
1716 printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
1717 (int)(pAddr
& LOADDRMASK
),pr_uword64(value1
),pr_uword64(value
));
1720 /* See also store_memory. */
1721 if (AccessLength
<= AccessLength_DOUBLEWORD
)
1724 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
1725 shifted to the most significant byte position. */
1726 value
<<= (((7 - (pAddr
& LOADDRMASK
)) - AccessLength
) * 8);
1728 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
1729 is already in the correct postition. */
1730 value
<<= ((pAddr
& LOADDRMASK
) * 8);
1734 printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
1735 pr_uword64(value1
),pr_uword64(value
));
1739 if (memval1p
) *memval1p
= value1
;
1743 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
1745 /* Store a value to memory. The specified data is stored into the
1746 physical location pAddr using the memory hierarchy (data caches and
1747 main memory) as specified by the Cache Coherence Algorithm
1748 (CCA). The MemElem contains the data for an aligned, fixed-width
1749 memory element (word for 32-bit processors, doubleword for 64-bit
1750 processors), though only the bytes that will actually be stored to
1751 memory need to be valid. The low-order two (or three) bits of pAddr
1752 and the AccessLength field indicates which of the bytes within the
1753 MemElem data should actually be stored; only these bytes in memory
1757 store_memory (SIM_DESC sd
,
1763 uword64 MemElem1
, /* High order 64 bits */
1768 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
));
1771 #if defined(WARN_MEM)
1772 if (CCA
!= uncached
)
1773 sim_io_eprintf(sd
,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA
);
1774 #endif /* WARN_MEM */
1776 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
)
1777 sim_io_error(sd
,"AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength
,(LOADDRMASK
+ 1)<<2,pr_addr(pAddr
));
1780 dotrace (SD
, CPU
, tracefh
,1,(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"store");
1784 printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr
& LOADDRMASK
),pr_uword64(MemElem1
),pr_uword64(MemElem
));
1787 /* See also load_memory */
1788 if (AccessLength
<= AccessLength_DOUBLEWORD
)
1791 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
1792 shifted to the most significant byte position. */
1793 MemElem
>>= (((7 - (pAddr
& LOADDRMASK
)) - AccessLength
) * 8);
1795 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
1796 is already in the correct postition. */
1797 MemElem
>>= ((pAddr
& LOADDRMASK
) * 8);
1801 printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift
,pr_uword64(MemElem1
),pr_uword64(MemElem
));
1804 switch (AccessLength
)
1806 case AccessLength_QUADWORD
:
1808 unsigned_16 val
= U16_8 (MemElem1
, MemElem
);
1809 sim_core_write_aligned_16 (cpu
, NULL_CIA
, write_map
, pAddr
, val
);
1812 case AccessLength_DOUBLEWORD
:
1813 sim_core_write_aligned_8 (cpu
, NULL_CIA
,
1814 write_map
, pAddr
, MemElem
);
1816 case AccessLength_SEPTIBYTE
:
1817 sim_core_write_misaligned_7 (cpu
, NULL_CIA
,
1818 write_map
, pAddr
, MemElem
);
1820 case AccessLength_SEXTIBYTE
:
1821 sim_core_write_misaligned_6 (cpu
, NULL_CIA
,
1822 write_map
, pAddr
, MemElem
);
1824 case AccessLength_QUINTIBYTE
:
1825 sim_core_write_misaligned_5 (cpu
, NULL_CIA
,
1826 write_map
, pAddr
, MemElem
);
1828 case AccessLength_WORD
:
1829 sim_core_write_aligned_4 (cpu
, NULL_CIA
,
1830 write_map
, pAddr
, MemElem
);
1832 case AccessLength_TRIPLEBYTE
:
1833 sim_core_write_misaligned_3 (cpu
, NULL_CIA
,
1834 write_map
, pAddr
, MemElem
);
1836 case AccessLength_HALFWORD
:
1837 sim_core_write_aligned_2 (cpu
, NULL_CIA
,
1838 write_map
, pAddr
, MemElem
);
1840 case AccessLength_BYTE
:
1841 sim_core_write_aligned_1 (cpu
, NULL_CIA
,
1842 write_map
, pAddr
, MemElem
);
1853 ifetch32 (SIM_DESC sd
,
1858 /* Copy the action of the LW instruction */
1859 address_word reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
1860 address_word bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
1863 unsigned32 instruction
;
1866 AddressTranslation (vaddr
, isINSTRUCTION
, isLOAD
, &paddr
, &cca
, isTARGET
, isREAL
);
1867 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
1868 LoadMemory (&value
, NULL
, cca
, AccessLength_WORD
, paddr
, vaddr
, isINSTRUCTION
, isREAL
);
1869 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
1870 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
1876 ifetch16 (SIM_DESC sd
,
1881 /* Copy the action of the LW instruction */
1882 address_word reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
1883 address_word bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
1886 unsigned16 instruction
;
1889 AddressTranslation (vaddr
, isINSTRUCTION
, isLOAD
, &paddr
, &cca
, isTARGET
, isREAL
);
1890 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
1891 LoadMemory (&value
, NULL
, cca
, AccessLength_WORD
, paddr
, vaddr
, isINSTRUCTION
, isREAL
);
1892 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
1893 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
1898 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1899 /* Order loads and stores to synchronise shared memory. Perform the
1900 action necessary to make the effects of groups of synchronizable
1901 loads and stores indicated by stype occur in the same order for all
1904 sync_operation (SIM_DESC sd
,
1910 sim_io_printf(sd
,"SyncOperation(%d) : TODO\n",stype
);
1915 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1916 /* Signal an exception condition. This will result in an exception
1917 that aborts the instruction. The instruction operation pseudocode
1918 will never see a return from this function call. */
1921 signal_exception (SIM_DESC sd
,
1929 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1932 /* Ensure that any active atomic read/modify/write operation will fail: */
1935 switch (exception
) {
1936 /* TODO: For testing purposes I have been ignoring TRAPs. In
1937 reality we should either simulate them, or allow the user to
1938 ignore them at run-time.
1941 sim_io_eprintf(sd
,"Ignoring instruction TRAP (PC 0x%s)\n",pr_addr(cia
));
1947 unsigned int instruction
;
1950 va_start(ap
,exception
);
1951 instruction
= va_arg(ap
,unsigned int);
1954 code
= (instruction
>> 6) & 0xFFFFF;
1956 sim_io_eprintf(sd
,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
1957 code
, pr_addr(cia
));
1961 case DebugBreakPoint
:
1962 if (! (Debug
& Debug_DM
))
1968 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1969 DEPC
= cia
- 4; /* reference the branch instruction */
1973 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1977 Debug
|= Debug_DM
; /* in debugging mode */
1978 Debug
|= Debug_DBp
; /* raising a DBp exception */
1980 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1984 case ReservedInstruction
:
1987 unsigned int instruction
;
1988 va_start(ap
,exception
);
1989 instruction
= va_arg(ap
,unsigned int);
1991 /* Provide simple monitor support using ReservedInstruction
1992 exceptions. The following code simulates the fixed vector
1993 entry points into the IDT monitor by causing a simulator
1994 trap, performing the monitor operation, and returning to
1995 the address held in the $ra register (standard PCS return
1996 address). This means we only need to pre-load the vector
1997 space with suitable instruction values. For systems were
1998 actual trap instructions are used, we would not need to
1999 perform this magic. */
2000 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
2002 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
2003 /* NOTE: This assumes that a branch-and-link style
2004 instruction was used to enter the vector (which is the
2005 case with the current IDT monitor). */
2006 sim_engine_restart (SD
, CPU
, NULL
, RA
);
2008 /* Look for the mips16 entry and exit instructions, and
2009 simulate a handler for them. */
2010 else if ((cia
& 1) != 0
2011 && (instruction
& 0xf81f) == 0xe809
2012 && (instruction
& 0x0c0) != 0x0c0)
2014 mips16_entry (SD
, CPU
, cia
, instruction
);
2015 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
2017 /* else fall through to normal exception processing */
2018 sim_io_eprintf(sd
,"ReservedInstruction 0x%08X at PC = 0x%s\n",instruction
,pr_addr(cia
));
2023 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
2025 /* Keep a copy of the current A0 in-case this is the program exit
2029 unsigned int instruction
;
2030 va_start(ap
,exception
);
2031 instruction
= va_arg(ap
,unsigned int);
2033 /* Check for our special terminating BREAK: */
2034 if ((instruction
& 0x03FFFFC0) == 0x03ff0000) {
2035 sim_engine_halt (SD
, CPU
, NULL
, cia
,
2036 sim_exited
, (unsigned int)(A0
& 0xFFFFFFFF));
2039 if (STATE
& simDELAYSLOT
)
2040 PC
= cia
- 4; /* reference the branch instruction */
2043 sim_engine_halt (SD
, CPU
, NULL
, cia
,
2044 sim_stopped
, SIM_SIGTRAP
);
2047 /* Store exception code into current exception id variable (used
2050 /* TODO: If not simulating exceptions then stop the simulator
2051 execution. At the moment we always stop the simulation. */
2053 /* See figure 5-17 for an outline of the code below */
2054 if (! (SR
& status_EXL
))
2056 CAUSE
= (exception
<< 2);
2057 if (STATE
& simDELAYSLOT
)
2059 STATE
&= ~simDELAYSLOT
;
2061 EPC
= (cia
- 4); /* reference the branch instruction */
2065 /* FIXME: TLB et.al. */
2070 CAUSE
= (exception
<< 2);
2074 /* Store exception code into current exception id variable (used
2076 if (SR
& status_BEV
)
2077 PC
= (signed)0xBFC00200 + 0x180;
2079 PC
= (signed)0x80000000 + 0x180;
2081 switch ((CAUSE
>> 2) & 0x1F)
2084 /* Interrupts arrive during event processing, no need to
2088 case TLBModification
:
2093 case InstructionFetch
:
2095 /* The following is so that the simulator will continue from the
2096 exception address on breakpoint operations. */
2098 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2099 sim_stopped
, SIM_SIGBUS
);
2101 case ReservedInstruction
:
2102 case CoProcessorUnusable
:
2104 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2105 sim_stopped
, SIM_SIGILL
);
2107 case IntegerOverflow
:
2109 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2110 sim_stopped
, SIM_SIGFPE
);
2116 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2117 sim_stopped
, SIM_SIGTRAP
);
2121 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2122 "FATAL: Should not encounter a breakpoint\n");
2124 default : /* Unknown internal exception */
2126 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2127 sim_stopped
, SIM_SIGABRT
);
2131 case SimulatorFault
:
2135 va_start(ap
,exception
);
2136 msg
= va_arg(ap
,char *);
2138 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2139 "FATAL: Simulator error \"%s\"\n",msg
);
2146 #if defined(WARN_RESULT)
2147 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2148 /* This function indicates that the result of the operation is
2149 undefined. However, this should not affect the instruction
2150 stream. All that is meant to happen is that the destination
2151 register is set to an undefined result. To keep the simulator
2152 simple, we just don't bother updating the destination register, so
2153 the overall result will be undefined. If desired we can stop the
2154 simulator by raising a pseudo-exception. */
2155 #define UndefinedResult() undefined_result (sd,cia)
2157 undefined_result(sd
,cia
)
2161 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
2162 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2167 #endif /* WARN_RESULT */
2170 cache_op (SIM_DESC sd
,
2176 unsigned int instruction
)
2178 #if 1 /* stop warning message being displayed (we should really just remove the code) */
2179 static int icache_warning
= 1;
2180 static int dcache_warning
= 1;
2182 static int icache_warning
= 0;
2183 static int dcache_warning
= 0;
2186 /* If CP0 is not useable (User or Supervisor mode) and the CP0
2187 enable bit in the Status Register is clear - a coprocessor
2188 unusable exception is taken. */
2190 sim_io_printf(sd
,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia
));
2194 case 0: /* instruction cache */
2196 case 0: /* Index Invalidate */
2197 case 1: /* Index Load Tag */
2198 case 2: /* Index Store Tag */
2199 case 4: /* Hit Invalidate */
2201 case 6: /* Hit Writeback */
2202 if (!icache_warning
)
2204 sim_io_eprintf(sd
,"Instruction CACHE operation %d to be coded\n",(op
>> 2));
2210 SignalException(ReservedInstruction
,instruction
);
2215 case 1: /* data cache */
2217 case 0: /* Index Writeback Invalidate */
2218 case 1: /* Index Load Tag */
2219 case 2: /* Index Store Tag */
2220 case 3: /* Create Dirty */
2221 case 4: /* Hit Invalidate */
2222 case 5: /* Hit Writeback Invalidate */
2223 case 6: /* Hit Writeback */
2224 if (!dcache_warning
)
2226 sim_io_eprintf(sd
,"Data CACHE operation %d to be coded\n",(op
>> 2));
2232 SignalException(ReservedInstruction
,instruction
);
2237 default: /* unrecognised cache ID */
2238 SignalException(ReservedInstruction
,instruction
);
2245 /*-- FPU support routines ---------------------------------------------------*/
2247 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
2248 formats conform to ANSI/IEEE Std 754-1985. */
2249 /* SINGLE precision floating:
2250 * seeeeeeeefffffffffffffffffffffff
2252 * e = 8bits = exponent
2253 * f = 23bits = fraction
2255 /* SINGLE precision fixed:
2256 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2258 * i = 31bits = integer
2260 /* DOUBLE precision floating:
2261 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
2263 * e = 11bits = exponent
2264 * f = 52bits = fraction
2266 /* DOUBLE precision fixed:
2267 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2269 * i = 63bits = integer
2272 /* Extract sign-bit: */
2273 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
2274 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
2275 /* Extract biased exponent: */
2276 #define FP_S_be(v) (((v) >> 23) & 0xFF)
2277 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
2278 /* Extract unbiased Exponent: */
2279 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
2280 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
2281 /* Extract complete fraction field: */
2282 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
2283 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
2284 /* Extract numbered fraction bit: */
2285 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
2286 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
2288 /* Explicit QNaN values used when value required: */
2289 #define FPQNaN_SINGLE (0x7FBFFFFF)
2290 #define FPQNaN_WORD (0x7FFFFFFF)
2291 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
2292 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
2294 /* Explicit Infinity values used when required: */
2295 #define FPINF_SINGLE (0x7F800000)
2296 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
2298 #if 1 /* def DEBUG */
2299 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
2300 #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>"))))))
2304 value_fpr (SIM_DESC sd
,
2313 /* Treat unused register values, as fixed-point 64bit values: */
2314 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
2316 /* If request to read data as "uninterpreted", then use the current
2318 fmt
= FPR_STATE
[fpr
];
2323 /* For values not yet accessed, set to the desired format: */
2324 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
2325 FPR_STATE
[fpr
] = fmt
;
2327 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
2330 if (fmt
!= FPR_STATE
[fpr
]) {
2331 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
));
2332 FPR_STATE
[fpr
] = fmt_unknown
;
2335 if (FPR_STATE
[fpr
] == fmt_unknown
) {
2336 /* Set QNaN value: */
2339 value
= FPQNaN_SINGLE
;
2343 value
= FPQNaN_DOUBLE
;
2347 value
= FPQNaN_WORD
;
2351 value
= FPQNaN_LONG
;
2358 } else if (SizeFGR() == 64) {
2362 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2365 case fmt_uninterpreted
:
2379 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2382 case fmt_uninterpreted
:
2385 if ((fpr
& 1) == 0) { /* even registers only */
2386 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
2388 SignalException(ReservedInstruction
,0);
2399 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2402 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());
2409 store_fpr (SIM_DESC sd
,
2419 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());
2422 if (SizeFGR() == 64) {
2424 case fmt_uninterpreted_32
:
2425 fmt
= fmt_uninterpreted
;
2428 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2429 FPR_STATE
[fpr
] = fmt
;
2432 case fmt_uninterpreted_64
:
2433 fmt
= fmt_uninterpreted
;
2434 case fmt_uninterpreted
:
2438 FPR_STATE
[fpr
] = fmt
;
2442 FPR_STATE
[fpr
] = fmt_unknown
;
2448 case fmt_uninterpreted_32
:
2449 fmt
= fmt_uninterpreted
;
2452 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2453 FPR_STATE
[fpr
] = fmt
;
2456 case fmt_uninterpreted_64
:
2457 fmt
= fmt_uninterpreted
;
2458 case fmt_uninterpreted
:
2461 if ((fpr
& 1) == 0) { /* even register number only */
2462 FGR
[fpr
+1] = (value
>> 32);
2463 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2464 FPR_STATE
[fpr
+ 1] = fmt
;
2465 FPR_STATE
[fpr
] = fmt
;
2467 FPR_STATE
[fpr
] = fmt_unknown
;
2468 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2469 SignalException(ReservedInstruction
,0);
2474 FPR_STATE
[fpr
] = fmt_unknown
;
2479 #if defined(WARN_RESULT)
2482 #endif /* WARN_RESULT */
2485 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2488 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_addr(FGR
[fpr
]),DOFMT(fmt
));
2505 sim_fpu_32to (&wop
, op
);
2506 boolean
= sim_fpu_is_nan (&wop
);
2513 sim_fpu_64to (&wop
, op
);
2514 boolean
= sim_fpu_is_nan (&wop
);
2518 fprintf (stderr
, "Bad switch\n");
2523 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2537 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2544 sim_fpu_32to (&wop
, op
);
2545 boolean
= sim_fpu_is_infinity (&wop
);
2551 sim_fpu_64to (&wop
, op
);
2552 boolean
= sim_fpu_is_infinity (&wop
);
2556 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2561 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2575 /* Argument checking already performed by the FPCOMPARE code */
2578 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2581 /* The format type should already have been checked: */
2587 sim_fpu_32to (&wop1
, op1
);
2588 sim_fpu_32to (&wop2
, op2
);
2589 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2596 sim_fpu_64to (&wop1
, op1
);
2597 sim_fpu_64to (&wop2
, op2
);
2598 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2602 fprintf (stderr
, "Bad switch\n");
2607 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2621 /* Argument checking already performed by the FPCOMPARE code */
2624 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2627 /* The format type should already have been checked: */
2633 sim_fpu_32to (&wop1
, op1
);
2634 sim_fpu_32to (&wop2
, op2
);
2635 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2642 sim_fpu_64to (&wop1
, op1
);
2643 sim_fpu_64to (&wop2
, op2
);
2644 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2648 fprintf (stderr
, "Bad switch\n");
2653 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2660 AbsoluteValue(op
,fmt
)
2667 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2670 /* The format type should already have been checked: */
2676 sim_fpu_32to (&wop
, op
);
2677 sim_fpu_abs (&wop
, &wop
);
2678 sim_fpu_to32 (&ans
, &wop
);
2686 sim_fpu_64to (&wop
, op
);
2687 sim_fpu_abs (&wop
, &wop
);
2688 sim_fpu_to64 (&ans
, &wop
);
2693 fprintf (stderr
, "Bad switch\n");
2708 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2711 /* The format type should already have been checked: */
2717 sim_fpu_32to (&wop
, op
);
2718 sim_fpu_neg (&wop
, &wop
);
2719 sim_fpu_to32 (&ans
, &wop
);
2727 sim_fpu_64to (&wop
, op
);
2728 sim_fpu_neg (&wop
, &wop
);
2729 sim_fpu_to64 (&ans
, &wop
);
2734 fprintf (stderr
, "Bad switch\n");
2750 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2753 /* The registers must specify FPRs valid for operands of type
2754 "fmt". If they are not valid, the result is undefined. */
2756 /* The format type should already have been checked: */
2764 sim_fpu_32to (&wop1
, op1
);
2765 sim_fpu_32to (&wop2
, op2
);
2766 sim_fpu_add (&ans
, &wop1
, &wop2
);
2767 sim_fpu_to32 (&res
, &ans
);
2777 sim_fpu_64to (&wop1
, op1
);
2778 sim_fpu_64to (&wop2
, op2
);
2779 sim_fpu_add (&ans
, &wop1
, &wop2
);
2780 sim_fpu_to64 (&res
, &ans
);
2785 fprintf (stderr
, "Bad switch\n");
2790 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2805 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2808 /* The registers must specify FPRs valid for operands of type
2809 "fmt". If they are not valid, the result is undefined. */
2811 /* The format type should already have been checked: */
2819 sim_fpu_32to (&wop1
, op1
);
2820 sim_fpu_32to (&wop2
, op2
);
2821 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2822 sim_fpu_to32 (&res
, &ans
);
2832 sim_fpu_64to (&wop1
, op1
);
2833 sim_fpu_64to (&wop2
, op2
);
2834 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2835 sim_fpu_to64 (&res
, &ans
);
2840 fprintf (stderr
, "Bad switch\n");
2845 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2852 Multiply(op1
,op2
,fmt
)
2860 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2863 /* The registers must specify FPRs valid for operands of type
2864 "fmt". If they are not valid, the result is undefined. */
2866 /* The format type should already have been checked: */
2874 sim_fpu_32to (&wop1
, op1
);
2875 sim_fpu_32to (&wop2
, op2
);
2876 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2877 sim_fpu_to32 (&res
, &ans
);
2887 sim_fpu_64to (&wop1
, op1
);
2888 sim_fpu_64to (&wop2
, op2
);
2889 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2890 sim_fpu_to64 (&res
, &ans
);
2895 fprintf (stderr
, "Bad switch\n");
2900 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2915 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2918 /* The registers must specify FPRs valid for operands of type
2919 "fmt". If they are not valid, the result is undefined. */
2921 /* The format type should already have been checked: */
2929 sim_fpu_32to (&wop1
, op1
);
2930 sim_fpu_32to (&wop2
, op2
);
2931 sim_fpu_div (&ans
, &wop1
, &wop2
);
2932 sim_fpu_to32 (&res
, &ans
);
2942 sim_fpu_64to (&wop1
, op1
);
2943 sim_fpu_64to (&wop2
, op2
);
2944 sim_fpu_div (&ans
, &wop1
, &wop2
);
2945 sim_fpu_to64 (&res
, &ans
);
2950 fprintf (stderr
, "Bad switch\n");
2955 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2969 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2972 /* The registers must specify FPRs valid for operands of type
2973 "fmt". If they are not valid, the result is undefined. */
2975 /* The format type should already have been checked: */
2982 sim_fpu_32to (&wop
, op
);
2983 sim_fpu_inv (&ans
, &wop
);
2984 sim_fpu_to32 (&res
, &ans
);
2993 sim_fpu_64to (&wop
, op
);
2994 sim_fpu_inv (&ans
, &wop
);
2995 sim_fpu_to64 (&res
, &ans
);
3000 fprintf (stderr
, "Bad switch\n");
3005 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3019 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
3022 /* The registers must specify FPRs valid for operands of type
3023 "fmt". If they are not valid, the result is undefined. */
3025 /* The format type should already have been checked: */
3032 sim_fpu_32to (&wop
, op
);
3033 sim_fpu_sqrt (&ans
, &wop
);
3034 sim_fpu_to32 (&res
, &ans
);
3043 sim_fpu_64to (&wop
, op
);
3044 sim_fpu_sqrt (&ans
, &wop
);
3045 sim_fpu_to64 (&res
, &ans
);
3050 fprintf (stderr
, "Bad switch\n");
3055 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3071 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3074 /* The registers must specify FPRs valid for operands of type
3075 "fmt". If they are not valid, the result is undefined. */
3077 /* The format type should already have been checked: */
3084 sim_fpu_32to (&wop1
, op1
);
3085 sim_fpu_32to (&wop2
, op2
);
3086 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3093 sim_fpu_64to (&wop1
, op1
);
3094 sim_fpu_64to (&wop2
, op2
);
3095 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3099 fprintf (stderr
, "Bad switch\n");
3105 case SIM_FPU_IS_SNAN
:
3106 case SIM_FPU_IS_QNAN
:
3108 case SIM_FPU_IS_NINF
:
3109 case SIM_FPU_IS_NNUMBER
:
3110 case SIM_FPU_IS_NDENORM
:
3111 case SIM_FPU_IS_NZERO
:
3112 result
= op2
; /* op1 - op2 < 0 */
3113 case SIM_FPU_IS_PINF
:
3114 case SIM_FPU_IS_PNUMBER
:
3115 case SIM_FPU_IS_PDENORM
:
3116 case SIM_FPU_IS_PZERO
:
3117 result
= op1
; /* op1 - op2 > 0 */
3119 fprintf (stderr
, "Bad switch\n");
3124 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3141 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3144 /* The registers must specify FPRs valid for operands of type
3145 "fmt". If they are not valid, the result is undefined. */
3147 /* The format type should already have been checked: */
3154 sim_fpu_32to (&wop1
, op1
);
3155 sim_fpu_32to (&wop2
, op2
);
3156 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3163 sim_fpu_64to (&wop1
, op1
);
3164 sim_fpu_64to (&wop2
, op2
);
3165 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3169 fprintf (stderr
, "Bad switch\n");
3175 case SIM_FPU_IS_SNAN
:
3176 case SIM_FPU_IS_QNAN
:
3178 case SIM_FPU_IS_NINF
:
3179 case SIM_FPU_IS_NNUMBER
:
3180 case SIM_FPU_IS_NDENORM
:
3181 case SIM_FPU_IS_NZERO
:
3182 result
= op1
; /* op1 - op2 < 0 */
3183 case SIM_FPU_IS_PINF
:
3184 case SIM_FPU_IS_PNUMBER
:
3185 case SIM_FPU_IS_PDENORM
:
3186 case SIM_FPU_IS_PZERO
:
3187 result
= op2
; /* op1 - op2 > 0 */
3189 fprintf (stderr
, "Bad switch\n");
3194 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3202 convert (SIM_DESC sd
,
3211 sim_fpu_round round
;
3212 unsigned32 result32
;
3213 unsigned64 result64
;
3216 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
));
3222 /* Round result to nearest representable value. When two
3223 representable values are equally near, round to the value
3224 that has a least significant bit of zero (i.e. is even). */
3225 round
= sim_fpu_round_near
;
3228 /* Round result to the value closest to, and not greater in
3229 magnitude than, the result. */
3230 round
= sim_fpu_round_zero
;
3233 /* Round result to the value closest to, and not less than,
3235 round
= sim_fpu_round_up
;
3239 /* Round result to the value closest to, and not greater than,
3241 round
= sim_fpu_round_down
;
3245 fprintf (stderr
, "Bad switch\n");
3249 /* Convert the input to sim_fpu internal format */
3253 sim_fpu_64to (&wop
, op
);
3256 sim_fpu_32to (&wop
, op
);
3259 sim_fpu_i32to (&wop
, op
, round
);
3262 sim_fpu_i64to (&wop
, op
, round
);
3265 fprintf (stderr
, "Bad switch\n");
3269 /* Convert sim_fpu format into the output */
3270 /* The value WOP is converted to the destination format, rounding
3271 using mode RM. When the destination is a fixed-point format, then
3272 a source value of Infinity, NaN or one which would round to an
3273 integer outside the fixed point range then an IEEE Invalid
3274 Operation condition is raised. */
3278 sim_fpu_round_32 (&wop
, round
, 0);
3279 sim_fpu_to32 (&result32
, &wop
);
3280 result64
= result32
;
3283 sim_fpu_round_64 (&wop
, round
, 0);
3284 sim_fpu_to64 (&result64
, &wop
);
3287 sim_fpu_to32i (&result32
, &wop
, round
);
3288 result64
= result32
;
3291 sim_fpu_to64i (&result64
, &wop
, round
);
3295 fprintf (stderr
, "Bad switch\n");
3300 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
3307 /*-- co-processor support routines ------------------------------------------*/
3310 CoProcPresent(coproc_number
)
3311 unsigned int coproc_number
;
3313 /* Return TRUE if simulator provides a model for the given co-processor number */
3318 cop_lw (SIM_DESC sd
,
3323 unsigned int memword
)
3328 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3331 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
3333 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
3334 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
3339 #if 0 /* this should be controlled by a configuration option */
3340 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
));
3349 cop_ld (SIM_DESC sd
,
3356 switch (coproc_num
) {
3358 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3360 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
3365 #if 0 /* this message should be controlled by a configuration option */
3366 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
));
3375 /* start-sanitize-sky */
3378 cop_lq (SIM_DESC sd
,
3383 unsigned128 memword
)
3392 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3393 coproc_num
,coproc_reg
,pr_addr(cia
));
3399 #endif /* TARGET_SKY */
3400 /* end-sanitize-sky */
3404 cop_sw (SIM_DESC sd
,
3410 unsigned int value
= 0;
3415 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3418 hold
= FPR_STATE
[coproc_reg
];
3419 FPR_STATE
[coproc_reg
] = fmt_word
;
3420 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3421 FPR_STATE
[coproc_reg
] = hold
;
3426 #if 0 /* should be controlled by configuration option */
3427 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3436 cop_sd (SIM_DESC sd
,
3446 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3448 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3453 #if 0 /* should be controlled by configuration option */
3454 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3463 /* start-sanitize-sky */
3466 cop_sq (SIM_DESC sd
,
3472 unsigned128 value
= U16_8(0, 0);
3480 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3481 coproc_num
,coproc_reg
,pr_addr(cia
));
3487 #endif /* TARGET_SKY */
3488 /* end-sanitize-sky */
3492 decode_coproc (SIM_DESC sd
,
3495 unsigned int instruction
)
3497 int coprocnum
= ((instruction
>> 26) & 3);
3501 case 0: /* standard CPU control and cache registers */
3503 int code
= ((instruction
>> 21) & 0x1F);
3504 /* R4000 Users Manual (second edition) lists the following CP0
3506 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3507 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3508 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3509 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3510 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3511 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3512 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3513 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3514 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3515 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3517 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0))
3519 int rt
= ((instruction
>> 16) & 0x1F);
3520 int rd
= ((instruction
>> 11) & 0x1F);
3522 switch (rd
) /* NOTEs: Standard CP0 registers */
3524 /* 0 = Index R4000 VR4100 VR4300 */
3525 /* 1 = Random R4000 VR4100 VR4300 */
3526 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3527 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3528 /* 4 = Context R4000 VR4100 VR4300 */
3529 /* 5 = PageMask R4000 VR4100 VR4300 */
3530 /* 6 = Wired R4000 VR4100 VR4300 */
3531 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3532 /* 9 = Count R4000 VR4100 VR4300 */
3533 /* 10 = EntryHi R4000 VR4100 VR4300 */
3534 /* 11 = Compare R4000 VR4100 VR4300 */
3535 /* 12 = SR R4000 VR4100 VR4300 */
3542 /* 13 = Cause R4000 VR4100 VR4300 */
3549 /* 14 = EPC R4000 VR4100 VR4300 */
3550 /* 15 = PRId R4000 VR4100 VR4300 */
3551 #ifdef SUBTARGET_R3900
3560 /* 16 = Config R4000 VR4100 VR4300 */
3563 GPR
[rt
] = C0_CONFIG
;
3565 C0_CONFIG
= GPR
[rt
];
3568 #ifdef SUBTARGET_R3900
3577 /* 17 = LLAddr R4000 VR4100 VR4300 */
3579 /* 18 = WatchLo R4000 VR4100 VR4300 */
3580 /* 19 = WatchHi R4000 VR4100 VR4300 */
3581 /* 20 = XContext R4000 VR4100 VR4300 */
3582 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3583 /* 27 = CacheErr R4000 VR4100 */
3584 /* 28 = TagLo R4000 VR4100 VR4300 */
3585 /* 29 = TagHi R4000 VR4100 VR4300 */
3586 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3587 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3588 /* CPR[0,rd] = GPR[rt]; */
3591 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3593 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3596 else if (code
== 0x10 && (instruction
& 0x3f) == 0x18)
3599 if (SR
& status_ERL
)
3601 /* Oops, not yet available */
3602 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3612 else if (code
== 0x10 && (instruction
& 0x3f) == 0x10)
3616 else if (code
== 0x10 && (instruction
& 0x3f) == 0x1F)
3624 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3625 /* TODO: When executing an ERET or RFE instruction we should
3626 clear LLBIT, to ensure that any out-standing atomic
3627 read/modify/write sequence fails. */
3631 case 2: /* undefined co-processor */
3635 /* start-sanitize-sky */
3637 /* On the R5900, this refers to a "VU" vector co-processor. */
3639 int i_25_21
= (instruction
>> 21) & 0x1f;
3640 int i_20_16
= (instruction
>> 16) & 0x1f;
3641 int i_15_11
= (instruction
>> 11) & 0x1f;
3642 int i_15_0
= instruction
& 0xffff;
3643 int i_10_1
= (instruction
>> 1) & 0x3ff;
3644 int i_5_0
= instruction
& 0x03f;
3645 int interlock
= instruction
& 0x01;
3646 int co
= (instruction
>> 25) & 0x01;
3647 /* setup for semantic.c-like actions below */
3648 typedef unsigned_4 instruction_word
;
3651 sim_cpu
* CPU_
= cpu
;
3655 /* test COP2 usability */
3656 if(! (SR
& status_CU2
))
3658 SignalException(CoProcessorUnusable
,instruction
);
3662 /* classify & execute basic COP2 instructions */
3663 if(i_25_21
== 0x08 && i_20_16
== 0x00) /* BC2F */
3665 address_word offset
= EXTEND16(i_15_0
) << 2;
3666 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3668 else if(i_25_21
== 0x08 && i_20_16
==0x02) /* BC2FL */
3670 address_word offset
= EXTEND16(i_15_0
) << 2;
3671 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3672 else NULLIFY_NEXT_INSTRUCTION();
3674 else if(i_25_21
== 0x08 && i_20_16
== 0x01) /* BC2T */
3676 address_word offset
= EXTEND16(i_15_0
) << 2;
3677 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3679 else if(i_25_21
== 0x08 && i_20_16
== 0x03) /* BC2TL */
3681 address_word offset
= EXTEND16(i_15_0
) << 2;
3682 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3683 else NULLIFY_NEXT_INSTRUCTION();
3685 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3686 (i_25_21
== 0x01)) /* QMFC2 */
3690 address_word vu_cr_addr
; /* VU control register address */
3693 /* interlock checking */
3694 if(vu0_busy_in_macro_mode()) /* busy in macro mode */
3696 /* interlock bit invalid here */
3698 ; /* XXX: warning */
3700 /* always check data hazard */
3701 while(vu0_macro_hazard_check(id
))
3704 else if(vu0_busy_in_micro_mode() && interlock
)
3706 while(vu0_busy_in_micro_mode())
3710 /* compute VU register address */
3711 if(i_25_21
== 0x01) /* QMFC2 */
3712 vu_cr_addr
= VU0_REGISTER_WINDOW_START
+ (id
* 16);
3714 vu_cr_addr
= VU0_MST
+ (id
* 16);
3716 /* read or write word */
3717 data
= sim_core_read_aligned_4(cpu
, cia
, read_map
, vu_cr_addr
);
3718 GPR
[rt
] = EXTEND64(data
);
3720 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3721 (i_25_21
== 0x05)) /* QMTC2 */
3725 address_word vu_cr_addr
; /* VU control register address */
3728 /* interlock checking */
3729 if(vu0_busy_in_macro_mode()) /* busy in macro mode */
3731 /* interlock bit invalid here */
3733 ; /* XXX: warning */
3735 /* always check data hazard */
3736 while(vu0_macro_hazard_check(id
))
3739 else if(vu0_busy_in_micro_mode())
3743 while(! vu0_micro_interlock_released())
3748 /* compute VU register address */
3749 if(i_25_21
== 0x05) /* QMTC2 */
3750 vu_cr_addr
= VU0_REGISTER_WINDOW_START
+ (id
* 16);
3752 vu_cr_addr
= VU0_MST
+ (id
* 16);
3755 sim_core_write_aligned_4(cpu
, cia
, write_map
, vu_cr_addr
, data
);
3757 else if( 0 /* XXX: ... upper ... */)
3759 unsigned_4 vu_upper
, vu_lower
;
3761 0x00000000 | /* bits 31 .. 25 */
3762 instruction
& 0x01ffffff; /* bits 24 .. 0 */
3763 vu_lower
= 0x8000033c; /* NOP */
3765 while(vu0_busy_in_micro_mode())
3768 vu0_macro_issue(vu_upper
, vu_lower
);
3770 else if( 0 /* XXX: ... lower ... */)
3772 unsigned_4 vu_upper
, vu_lower
;
3773 vu_upper
= 0x000002ff; /* NOP */
3775 0x10000000 | /* bits 31 .. 25 */
3776 instruction
& 0x01ffffff; /* bits 24 .. 0 */
3778 while(vu0_busy_in_micro_mode())
3781 vu0_macro_issue(vu_upper
, vu_lower
);
3784 /* ... other COP2 instructions ... */
3787 SignalException(ReservedInstruction
, instruction
);
3791 /* cleanup for semantic.c-like actions above */
3794 #endif /* TARGET_SKY */
3795 /* end-sanitize-sky */
3799 sim_io_eprintf(sd
,"COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3800 instruction
,pr_addr(cia
));
3805 case 1: /* should not occur (FPU co-processor) */
3806 case 3: /* should not occur (FPU co-processor) */
3807 SignalException(ReservedInstruction
,instruction
);
3815 /*-- instruction simulation -------------------------------------------------*/
3817 /* When the IGEN simulator is being built, the function below is be
3818 replaced by a generated version. However, WITH_IGEN == 2 indicates
3819 that the fubction below should be compiled but under a different
3820 name (to allow backward compatibility) */
3822 #if (WITH_IGEN != 1)
3824 void old_engine_run
PARAMS ((SIM_DESC sd
, int next_cpu_nr
, int siggnal
));
3826 old_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3829 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3832 int next_cpu_nr
; /* ignore */
3833 int nr_cpus
; /* ignore */
3834 int siggnal
; /* ignore */
3836 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* hardwire to cpu 0 */
3837 #if !defined(FASTSIM)
3838 unsigned int pipeline_count
= 1;
3842 if (STATE_MEMORY (sd
) == NULL
) {
3843 printf("DBG: simulate() entered with no memory\n");
3848 #if 0 /* Disabled to check that everything works OK */
3849 /* The VR4300 seems to sign-extend the PC on its first
3850 access. However, this may just be because it is currently
3851 configured in 32bit mode. However... */
3852 PC
= SIGNEXTEND(PC
,32);
3855 /* main controlling loop */
3857 /* vaddr is slowly being replaced with cia - current instruction
3859 address_word cia
= (uword64
)PC
;
3860 address_word vaddr
= cia
;
3863 unsigned int instruction
; /* uword64? what's this used for? FIXME! */
3867 printf("DBG: state = 0x%08X :",state
);
3868 if (state
& simHALTEX
) printf(" simHALTEX");
3869 if (state
& simHALTIN
) printf(" simHALTIN");
3874 DSSTATE
= (STATE
& simDELAYSLOT
);
3877 sim_io_printf(sd
,"DBG: DSPC = 0x%s\n",pr_addr(DSPC
));
3880 /* Fetch the next instruction from the simulator memory: */
3881 if (AddressTranslation(cia
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) {
3882 if ((vaddr
& 1) == 0) {
3883 /* Copy the action of the LW instruction */
3884 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3885 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3888 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3889 LoadMemory(&value
,NULL
,cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3890 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3891 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3893 /* Copy the action of the LH instruction */
3894 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 1) : 0);
3895 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 1) : 0);
3898 paddr
= (((paddr
& ~ (uword64
) 1) & ~LOADDRMASK
)
3899 | (((paddr
& ~ (uword64
) 1) & LOADDRMASK
) ^ (reverse
<< 1)));
3900 LoadMemory(&value
,NULL
,cca
, AccessLength_HALFWORD
,
3901 paddr
& ~ (uword64
) 1,
3902 vaddr
, isINSTRUCTION
, isREAL
);
3903 byte
= (((vaddr
&~ (uword64
) 1) & LOADDRMASK
) ^ (bigend
<< 1));
3904 instruction
= ((value
>> (8 * byte
)) & 0xFFFF);
3907 fprintf(stderr
,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC
));
3912 sim_io_printf(sd
,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction
,pr_addr(PC
));
3915 /* This is required by exception processing, to ensure that we can
3916 cope with exceptions in the delay slots of branches that may
3917 already have changed the PC. */
3918 if ((vaddr
& 1) == 0)
3919 PC
+= 4; /* increment ready for the next fetch */
3922 /* NOTE: If we perform a delay slot change to the PC, this
3923 increment is not requuired. However, it would make the
3924 simulator more complicated to try and avoid this small hit. */
3926 /* Currently this code provides a simple model. For more
3927 complicated models we could perform exception status checks at
3928 this point, and set the simSTOP state as required. This could
3929 also include processing any hardware interrupts raised by any
3930 I/O model attached to the simulator context.
3932 Support for "asynchronous" I/O events within the simulated world
3933 could be providing by managing a counter, and calling a I/O
3934 specific handler when a particular threshold is reached. On most
3935 architectures a decrement and check for zero operation is
3936 usually quicker than an increment and compare. However, the
3937 process of managing a known value decrement to zero, is higher
3938 than the cost of using an explicit value UINT_MAX into the
3939 future. Which system is used will depend on how complicated the
3940 I/O model is, and how much it is likely to affect the simulator
3943 If events need to be scheduled further in the future than
3944 UINT_MAX event ticks, then the I/O model should just provide its
3945 own counter, triggered from the event system. */
3947 /* MIPS pipeline ticks. To allow for future support where the
3948 pipeline hit of individual instructions is known, this control
3949 loop manages a "pipeline_count" variable. It is initialised to
3950 1 (one), and will only be changed by the simulator engine when
3951 executing an instruction. If the engine does not have access to
3952 pipeline cycle count information then all instructions will be
3953 treated as using a single cycle. NOTE: A standard system is not
3954 provided by the default simulator because different MIPS
3955 architectures have different cycle counts for the same
3958 [NOTE: pipeline_count has been replaced the event queue] */
3960 /* shuffle the floating point status pipeline state */
3961 ENGINE_ISSUE_PREFIX_HOOK();
3963 /* NOTE: For multi-context simulation environments the "instruction"
3964 variable should be local to this routine. */
3966 /* Shorthand accesses for engine. Note: If we wanted to use global
3967 variables (and a single-threaded simulator engine), then we can
3968 create the actual variables with these names. */
3970 if (!(STATE
& simSKIPNEXT
)) {
3971 /* Include the simulator engine */
3972 #include "oengine.c"
3973 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3974 #error "Mismatch between run-time simulator code and simulation engine"
3976 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3977 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3979 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3980 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3983 #if defined(WARN_LOHI)
3984 /* Decrement the HI/LO validity ticks */
3989 /* start-sanitize-r5900 */
3994 /* end-sanitize-r5900 */
3995 #endif /* WARN_LOHI */
3997 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3998 should check for it being changed. It is better doing it here,
3999 than within the simulator, since it will help keep the simulator
4002 #if defined(WARN_ZERO)
4003 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
));
4004 #endif /* WARN_ZERO */
4005 ZERO
= 0; /* reset back to zero before next instruction */
4007 } else /* simSKIPNEXT check */
4008 STATE
&= ~simSKIPNEXT
;
4010 /* If the delay slot was active before the instruction is
4011 executed, then update the PC to its new value: */
4014 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC
));
4023 #if !defined(FASTSIM)
4024 if (sim_events_tickn (sd
, pipeline_count
))
4026 /* cpu->cia = cia; */
4027 sim_events_process (sd
);
4030 if (sim_events_tick (sd
))
4032 /* cpu->cia = cia; */
4033 sim_events_process (sd
);
4035 #endif /* FASTSIM */
4041 /* This code copied from gdb's utils.c. Would like to share this code,
4042 but don't know of a common place where both could get to it. */
4044 /* Temporary storage using circular buffer */
4050 static char buf
[NUMCELLS
][CELLSIZE
];
4052 if (++cell
>=NUMCELLS
) cell
=0;
4056 /* Print routines to handle variable size regs, etc */
4058 /* Eliminate warning from compiler on 32-bit systems */
4059 static int thirty_two
= 32;
4065 char *paddr_str
=get_cell();
4066 switch (sizeof(addr
))
4069 sprintf(paddr_str
,"%08lx%08lx",
4070 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
4073 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
4076 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
4079 sprintf(paddr_str
,"%x",addr
);
4088 char *paddr_str
=get_cell();
4089 sprintf(paddr_str
,"%08lx%08lx",
4090 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
4096 pending_tick (SIM_DESC sd
,
4101 sim_io_printf (sd
, "PENDING_DRAIN - pending_in = %d, pending_out = %d, pending_total = %d\n", PENDING_IN
, PENDING_OUT
, PENDING_TOTAL
);
4102 if (PENDING_OUT
!= PENDING_IN
)
4105 int index
= PENDING_OUT
;
4106 int total
= PENDING_TOTAL
;
4107 if (PENDING_TOTAL
== 0)
4108 sim_engine_abort (SD
, CPU
, cia
, "PENDING_DRAIN - Mis-match on pending update pointers\n");
4109 for (loop
= 0; (loop
< total
); loop
++)
4111 if (PENDING_SLOT_DEST
[index
] != NULL
)
4113 PENDING_SLOT_DELAY
[index
] -= 1;
4114 if (PENDING_SLOT_DELAY
[index
] == 0)
4116 if (PENDING_SLOT_BIT
[index
] >= 0)
4117 switch (PENDING_SLOT_SIZE
[index
])
4120 if (PENDING_SLOT_VALUE
[index
])
4121 *(unsigned32
*)PENDING_SLOT_DEST
[index
] |=
4122 BIT32 (PENDING_SLOT_BIT
[index
]);
4124 *(unsigned32
*)PENDING_SLOT_DEST
[index
] &=
4125 BIT32 (PENDING_SLOT_BIT
[index
]);
4128 if (PENDING_SLOT_VALUE
[index
])
4129 *(unsigned64
*)PENDING_SLOT_DEST
[index
] |=
4130 BIT64 (PENDING_SLOT_BIT
[index
]);
4132 *(unsigned64
*)PENDING_SLOT_DEST
[index
] &=
4133 BIT64 (PENDING_SLOT_BIT
[index
]);
4138 switch (PENDING_SLOT_SIZE
[index
])
4141 *(unsigned32
*)PENDING_SLOT_DEST
[index
] =
4142 PENDING_SLOT_VALUE
[index
];
4145 *(unsigned64
*)PENDING_SLOT_DEST
[index
] =
4146 PENDING_SLOT_VALUE
[index
];
4150 if (PENDING_OUT
== index
)
4152 PENDING_SLOT_DEST
[index
] = NULL
;
4153 PENDING_OUT
= (PENDING_OUT
+ 1) % PSLOTS
;
4158 index
= (index
+ 1) % PSLOTS
;
4162 /*---------------------------------------------------------------------------*/
4163 /*> EOF interp.c <*/