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 address_word value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1128 sim_write (sd
, A0
, (char *)&value
, sizeof (value
));
1129 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1133 case 158 : /* PMON printf */
1134 /* in: A0 = pointer to format string */
1135 /* A1 = optional argument 1 */
1136 /* A2 = optional argument 2 */
1137 /* A3 = optional argument 3 */
1139 /* The following is based on the PMON printf source */
1141 address_word s
= A0
;
1143 signed_word
*ap
= &A1
; /* 1st argument */
1144 /* This isn't the quickest way, since we call the host print
1145 routine for every character almost. But it does avoid
1146 having to allocate and manage a temporary string buffer. */
1147 /* TODO: Include check that we only use three arguments (A1,
1149 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1154 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1155 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1156 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1158 if (strchr ("dobxXulscefg%", s
))
1173 else if (c
>= '1' && c
<= '9')
1177 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1180 n
= (unsigned int)strtol(tmp
,NULL
,10);
1193 sim_io_printf (sd
, "%%");
1198 address_word p
= *ap
++;
1200 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1201 sim_io_printf(sd
, "%c", ch
);
1204 sim_io_printf(sd
,"(null)");
1207 sim_io_printf (sd
, "%c", (int)*ap
++);
1212 sim_read (sd
, s
++, &c
, 1);
1216 sim_read (sd
, s
++, &c
, 1);
1219 if (strchr ("dobxXu", c
))
1221 word64 lv
= (word64
) *ap
++;
1223 sim_io_printf(sd
,"<binary not supported>");
1226 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1228 sim_io_printf(sd
, tmp
, lv
);
1230 sim_io_printf(sd
, tmp
, (int)lv
);
1233 else if (strchr ("eEfgG", c
))
1235 double dbl
= *(double*)(ap
++);
1236 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1237 sim_io_printf (sd
, tmp
, dbl
);
1243 sim_io_printf(sd
, "%c", c
);
1249 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1250 reason
, pr_addr(cia
));
1256 /* Store a word into memory. */
1259 store_word (SIM_DESC sd
,
1268 if ((vaddr
& 3) != 0)
1269 SignalExceptionAddressStore ();
1272 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1275 const uword64 mask
= 7;
1279 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1280 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1281 memval
= ((uword64
) val
) << (8 * byte
);
1282 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1288 /* Load a word from memory. */
1291 load_word (SIM_DESC sd
,
1296 if ((vaddr
& 3) != 0)
1297 SignalExceptionAddressLoad ();
1303 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1306 const uword64 mask
= 0x7;
1307 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1308 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1312 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1313 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1315 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1316 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1323 /* Simulate the mips16 entry and exit pseudo-instructions. These
1324 would normally be handled by the reserved instruction exception
1325 code, but for ease of simulation we just handle them directly. */
1328 mips16_entry (SIM_DESC sd
,
1333 int aregs
, sregs
, rreg
;
1336 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1339 aregs
= (insn
& 0x700) >> 8;
1340 sregs
= (insn
& 0x0c0) >> 6;
1341 rreg
= (insn
& 0x020) >> 5;
1343 /* This should be checked by the caller. */
1352 /* This is the entry pseudo-instruction. */
1354 for (i
= 0; i
< aregs
; i
++)
1355 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1363 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1366 for (i
= 0; i
< sregs
; i
++)
1369 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1377 /* This is the exit pseudo-instruction. */
1384 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1387 for (i
= 0; i
< sregs
; i
++)
1390 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1395 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1399 FGR
[0] = WORD64LO (GPR
[4]);
1400 FPR_STATE
[0] = fmt_uninterpreted
;
1402 else if (aregs
== 6)
1404 FGR
[0] = WORD64LO (GPR
[5]);
1405 FGR
[1] = WORD64LO (GPR
[4]);
1406 FPR_STATE
[0] = fmt_uninterpreted
;
1407 FPR_STATE
[1] = fmt_uninterpreted
;
1416 /*-- trace support ----------------------------------------------------------*/
1418 /* The TRACE support is provided (if required) in the memory accessing
1419 routines. Since we are also providing the architecture specific
1420 features, the architecture simulation code can also deal with
1421 notifying the TRACE world of cache flushes, etc. Similarly we do
1422 not need to provide profiling support in the simulator engine,
1423 since we can sample in the instruction fetch control loop. By
1424 defining the TRACE manifest, we add tracing as a run-time
1428 /* Tracing by default produces "din" format (as required by
1429 dineroIII). Each line of such a trace file *MUST* have a din label
1430 and address field. The rest of the line is ignored, so comments can
1431 be included if desired. The first field is the label which must be
1432 one of the following values:
1437 3 escape record (treated as unknown access type)
1438 4 escape record (causes cache flush)
1440 The address field is a 32bit (lower-case) hexadecimal address
1441 value. The address should *NOT* be preceded by "0x".
1443 The size of the memory transfer is not important when dealing with
1444 cache lines (as long as no more than a cache line can be
1445 transferred in a single operation :-), however more information
1446 could be given following the dineroIII requirement to allow more
1447 complete memory and cache simulators to provide better
1448 results. i.e. the University of Pisa has a cache simulator that can
1449 also take bus size and speed as (variable) inputs to calculate
1450 complete system performance (a much more useful ability when trying
1451 to construct an end product, rather than a processor). They
1452 currently have an ARM version of their tool called ChARM. */
1456 dotrace (SIM_DESC sd
,
1464 if (STATE
& simTRACE
) {
1466 fprintf(tracefh
,"%d %s ; width %d ; ",
1470 va_start(ap
,comment
);
1471 vfprintf(tracefh
,comment
,ap
);
1473 fprintf(tracefh
,"\n");
1475 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1476 we may be generating 64bit ones, we should put the hi-32bits of the
1477 address into the comment field. */
1479 /* TODO: Provide a buffer for the trace lines. We can then avoid
1480 performing writes until the buffer is filled, or the file is
1483 /* NOTE: We could consider adding a comment field to the "din" file
1484 produced using type 3 markers (unknown access). This would then
1485 allow information about the program that the "din" is for, and
1486 the MIPs world that was being simulated, to be placed into the
1493 /*---------------------------------------------------------------------------*/
1494 /*-- simulator engine -------------------------------------------------------*/
1495 /*---------------------------------------------------------------------------*/
1498 ColdReset (SIM_DESC sd
)
1501 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1503 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1504 /* RESET: Fixed PC address: */
1505 PC
= UNSIGNED64 (0xFFFFFFFFBFC00000);
1506 /* The reset vector address is in the unmapped, uncached memory space. */
1508 SR
&= ~(status_SR
| status_TS
| status_RP
);
1509 SR
|= (status_ERL
| status_BEV
);
1511 /* Cheat and allow access to the complete register set immediately */
1512 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1513 && WITH_TARGET_WORD_BITSIZE
== 64)
1514 SR
|= status_FR
; /* 64bit registers */
1516 /* Ensure that any instructions with pending register updates are
1518 PENDING_INVALIDATE();
1520 /* Initialise the FPU registers to the unknown state */
1521 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1524 for (rn
= 0; (rn
< 32); rn
++)
1525 FPR_STATE
[rn
] = fmt_uninterpreted
;
1531 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
1533 /* Translate a virtual address to a physical address and cache
1534 coherence algorithm describing the mechanism used to resolve the
1535 memory reference. Given the virtual address vAddr, and whether the
1536 reference is to Instructions ot Data (IorD), find the corresponding
1537 physical address (pAddr) and the cache coherence algorithm (CCA)
1538 used to resolve the reference. If the virtual address is in one of
1539 the unmapped address spaces the physical address and the CCA are
1540 determined directly by the virtual address. If the virtual address
1541 is in one of the mapped address spaces then the TLB is used to
1542 determine the physical address and access type; if the required
1543 translation is not present in the TLB or the desired access is not
1544 permitted the function fails and an exception is taken.
1546 NOTE: Normally (RAW == 0), when address translation fails, this
1547 function raises an exception and does not return. */
1550 address_translation (SIM_DESC sd
,
1556 address_word
*pAddr
,
1560 int res
= -1; /* TRUE : Assume good return */
1563 sim_io_printf(sd
,"AddressTranslation(0x%s,%s,%s,...);\n",pr_addr(vAddr
),(IorD
? "isDATA" : "isINSTRUCTION"),(LorS
? "iSTORE" : "isLOAD"));
1566 /* Check that the address is valid for this memory model */
1568 /* For a simple (flat) memory model, we simply pass virtual
1569 addressess through (mostly) unchanged. */
1570 vAddr
&= 0xFFFFFFFF;
1572 *pAddr
= vAddr
; /* default for isTARGET */
1573 *CCA
= Uncached
; /* not used for isHOST */
1578 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
1580 /* Prefetch data from memory. Prefetch is an advisory instruction for
1581 which an implementation specific action is taken. The action taken
1582 may increase performance, but must not change the meaning of the
1583 program, or alter architecturally-visible state. */
1586 prefetch (SIM_DESC sd
,
1596 sim_io_printf(sd
,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA
,pr_addr(pAddr
),pr_addr(vAddr
),DATA
,hint
);
1599 /* For our simple memory model we do nothing */
1603 /* Description from page A-22 of the "MIPS IV Instruction Set" manual
1605 /* Load a value from memory. Use the cache and main memory as
1606 specified in the Cache Coherence Algorithm (CCA) and the sort of
1607 access (IorD) to find the contents of AccessLength memory bytes
1608 starting at physical location pAddr. The data is returned in the
1609 fixed width naturally-aligned memory element (MemElem). The
1610 low-order two (or three) bits of the address and the AccessLength
1611 indicate which of the bytes within MemElem needs to be given to the
1612 processor. If the memory access type of the reference is uncached
1613 then only the referenced bytes are read from memory and valid
1614 within the memory element. If the access type is cached, and the
1615 data is not present in cache, an implementation specific size and
1616 alignment block of memory is read and loaded into the cache to
1617 satisfy a load reference. At a minimum, the block is the entire
1620 load_memory (SIM_DESC sd
,
1635 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"));
1638 #if defined(WARN_MEM)
1639 if (CCA
!= uncached
)
1640 sim_io_eprintf(sd
,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA
);
1641 #endif /* WARN_MEM */
1643 /* If instruction fetch then we need to check that the two lo-order
1644 bits are zero, otherwise raise a InstructionFetch exception: */
1645 if ((IorD
== isINSTRUCTION
)
1646 && ((pAddr
& 0x3) != 0)
1647 && (((pAddr
& 0x1) != 0) || ((vAddr
& 0x1) == 0)))
1648 SignalExceptionInstructionFetch ();
1650 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
)
1652 /* In reality this should be a Bus Error */
1653 sim_io_error (sd
, "AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",
1655 (LOADDRMASK
+ 1) << 2,
1660 dotrace (SD
, CPU
, tracefh
,((IorD
== isDATA
) ? 0 : 2),(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"load%s",((IorD
== isDATA
) ? "" : " instruction"));
1663 /* Read the specified number of bytes from memory. Adjust for
1664 host/target byte ordering/ Align the least significant byte
1667 switch (AccessLength
)
1669 case AccessLength_QUADWORD
:
1671 unsigned_16 val
= sim_core_read_aligned_16 (cpu
, NULL_CIA
, read_map
, pAddr
);
1672 value1
= VH8_16 (val
);
1673 value
= VL8_16 (val
);
1676 case AccessLength_DOUBLEWORD
:
1677 value
= sim_core_read_aligned_8 (cpu
, NULL_CIA
,
1680 case AccessLength_SEPTIBYTE
:
1681 value
= sim_core_read_misaligned_7 (cpu
, NULL_CIA
,
1684 case AccessLength_SEXTIBYTE
:
1685 value
= sim_core_read_misaligned_6 (cpu
, NULL_CIA
,
1688 case AccessLength_QUINTIBYTE
:
1689 value
= sim_core_read_misaligned_5 (cpu
, NULL_CIA
,
1692 case AccessLength_WORD
:
1693 value
= sim_core_read_aligned_4 (cpu
, NULL_CIA
,
1696 case AccessLength_TRIPLEBYTE
:
1697 value
= sim_core_read_misaligned_3 (cpu
, NULL_CIA
,
1700 case AccessLength_HALFWORD
:
1701 value
= sim_core_read_aligned_2 (cpu
, NULL_CIA
,
1704 case AccessLength_BYTE
:
1705 value
= sim_core_read_aligned_1 (cpu
, NULL_CIA
,
1713 printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
1714 (int)(pAddr
& LOADDRMASK
),pr_uword64(value1
),pr_uword64(value
));
1717 /* See also store_memory. */
1718 if (AccessLength
<= AccessLength_DOUBLEWORD
)
1721 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
1722 shifted to the most significant byte position. */
1723 value
<<= (((7 - (pAddr
& LOADDRMASK
)) - AccessLength
) * 8);
1725 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
1726 is already in the correct postition. */
1727 value
<<= ((pAddr
& LOADDRMASK
) * 8);
1731 printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
1732 pr_uword64(value1
),pr_uword64(value
));
1736 if (memval1p
) *memval1p
= value1
;
1740 /* Description from page A-23 of the "MIPS IV Instruction Set" manual
1742 /* Store a value to memory. The specified data is stored into the
1743 physical location pAddr using the memory hierarchy (data caches and
1744 main memory) as specified by the Cache Coherence Algorithm
1745 (CCA). The MemElem contains the data for an aligned, fixed-width
1746 memory element (word for 32-bit processors, doubleword for 64-bit
1747 processors), though only the bytes that will actually be stored to
1748 memory need to be valid. The low-order two (or three) bits of pAddr
1749 and the AccessLength field indicates which of the bytes within the
1750 MemElem data should actually be stored; only these bytes in memory
1754 store_memory (SIM_DESC sd
,
1760 uword64 MemElem1
, /* High order 64 bits */
1765 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
));
1768 #if defined(WARN_MEM)
1769 if (CCA
!= uncached
)
1770 sim_io_eprintf(sd
,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA
);
1771 #endif /* WARN_MEM */
1773 if (((pAddr
& LOADDRMASK
) + AccessLength
) > LOADDRMASK
)
1774 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
));
1777 dotrace (SD
, CPU
, tracefh
,1,(unsigned int)(pAddr
&0xFFFFFFFF),(AccessLength
+ 1),"store");
1781 printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr
& LOADDRMASK
),pr_uword64(MemElem1
),pr_uword64(MemElem
));
1784 /* See also load_memory */
1785 if (AccessLength
<= AccessLength_DOUBLEWORD
)
1788 /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
1789 shifted to the most significant byte position. */
1790 MemElem
>>= (((7 - (pAddr
& LOADDRMASK
)) - AccessLength
) * 8);
1792 /* For little endian target, byte (pAddr&LOADDRMASK == 0)
1793 is already in the correct postition. */
1794 MemElem
>>= ((pAddr
& LOADDRMASK
) * 8);
1798 printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift
,pr_uword64(MemElem1
),pr_uword64(MemElem
));
1801 switch (AccessLength
)
1803 case AccessLength_QUADWORD
:
1805 unsigned_16 val
= U16_8 (MemElem1
, MemElem
);
1806 sim_core_write_aligned_16 (cpu
, NULL_CIA
, write_map
, pAddr
, val
);
1809 case AccessLength_DOUBLEWORD
:
1810 sim_core_write_aligned_8 (cpu
, NULL_CIA
,
1811 write_map
, pAddr
, MemElem
);
1813 case AccessLength_SEPTIBYTE
:
1814 sim_core_write_misaligned_7 (cpu
, NULL_CIA
,
1815 write_map
, pAddr
, MemElem
);
1817 case AccessLength_SEXTIBYTE
:
1818 sim_core_write_misaligned_6 (cpu
, NULL_CIA
,
1819 write_map
, pAddr
, MemElem
);
1821 case AccessLength_QUINTIBYTE
:
1822 sim_core_write_misaligned_5 (cpu
, NULL_CIA
,
1823 write_map
, pAddr
, MemElem
);
1825 case AccessLength_WORD
:
1826 sim_core_write_aligned_4 (cpu
, NULL_CIA
,
1827 write_map
, pAddr
, MemElem
);
1829 case AccessLength_TRIPLEBYTE
:
1830 sim_core_write_misaligned_3 (cpu
, NULL_CIA
,
1831 write_map
, pAddr
, MemElem
);
1833 case AccessLength_HALFWORD
:
1834 sim_core_write_aligned_2 (cpu
, NULL_CIA
,
1835 write_map
, pAddr
, MemElem
);
1837 case AccessLength_BYTE
:
1838 sim_core_write_aligned_1 (cpu
, NULL_CIA
,
1839 write_map
, pAddr
, MemElem
);
1850 ifetch32 (SIM_DESC sd
,
1855 /* Copy the action of the LW instruction */
1856 address_word reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
1857 address_word bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
1860 unsigned32 instruction
;
1863 AddressTranslation (vaddr
, isINSTRUCTION
, isLOAD
, &paddr
, &cca
, isTARGET
, isREAL
);
1864 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
1865 LoadMemory (&value
, NULL
, cca
, AccessLength_WORD
, paddr
, vaddr
, isINSTRUCTION
, isREAL
);
1866 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
1867 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
1873 ifetch16 (SIM_DESC sd
,
1878 /* Copy the action of the LW instruction */
1879 address_word reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
1880 address_word bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
1883 unsigned16 instruction
;
1886 AddressTranslation (vaddr
, isINSTRUCTION
, isLOAD
, &paddr
, &cca
, isTARGET
, isREAL
);
1887 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
1888 LoadMemory (&value
, NULL
, cca
, AccessLength_WORD
, paddr
, vaddr
, isINSTRUCTION
, isREAL
);
1889 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
1890 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
1895 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1896 /* Order loads and stores to synchronise shared memory. Perform the
1897 action necessary to make the effects of groups of synchronizable
1898 loads and stores indicated by stype occur in the same order for all
1901 sync_operation (SIM_DESC sd
,
1907 sim_io_printf(sd
,"SyncOperation(%d) : TODO\n",stype
);
1912 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1913 /* Signal an exception condition. This will result in an exception
1914 that aborts the instruction. The instruction operation pseudocode
1915 will never see a return from this function call. */
1918 signal_exception (SIM_DESC sd
,
1926 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1929 /* Ensure that any active atomic read/modify/write operation will fail: */
1932 switch (exception
) {
1933 /* TODO: For testing purposes I have been ignoring TRAPs. In
1934 reality we should either simulate them, or allow the user to
1935 ignore them at run-time.
1938 sim_io_eprintf(sd
,"Ignoring instruction TRAP (PC 0x%s)\n",pr_addr(cia
));
1944 unsigned int instruction
;
1947 va_start(ap
,exception
);
1948 instruction
= va_arg(ap
,unsigned int);
1951 code
= (instruction
>> 6) & 0xFFFFF;
1953 sim_io_eprintf(sd
,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
1954 code
, pr_addr(cia
));
1958 case DebugBreakPoint
:
1959 if (! (Debug
& Debug_DM
))
1965 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1966 DEPC
= cia
- 4; /* reference the branch instruction */
1970 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1974 Debug
|= Debug_DM
; /* in debugging mode */
1975 Debug
|= Debug_DBp
; /* raising a DBp exception */
1977 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1981 case ReservedInstruction
:
1984 unsigned int instruction
;
1985 va_start(ap
,exception
);
1986 instruction
= va_arg(ap
,unsigned int);
1988 /* Provide simple monitor support using ReservedInstruction
1989 exceptions. The following code simulates the fixed vector
1990 entry points into the IDT monitor by causing a simulator
1991 trap, performing the monitor operation, and returning to
1992 the address held in the $ra register (standard PCS return
1993 address). This means we only need to pre-load the vector
1994 space with suitable instruction values. For systems were
1995 actual trap instructions are used, we would not need to
1996 perform this magic. */
1997 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1999 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
2000 /* NOTE: This assumes that a branch-and-link style
2001 instruction was used to enter the vector (which is the
2002 case with the current IDT monitor). */
2003 sim_engine_restart (SD
, CPU
, NULL
, RA
);
2005 /* Look for the mips16 entry and exit instructions, and
2006 simulate a handler for them. */
2007 else if ((cia
& 1) != 0
2008 && (instruction
& 0xf81f) == 0xe809
2009 && (instruction
& 0x0c0) != 0x0c0)
2011 mips16_entry (SD
, CPU
, cia
, instruction
);
2012 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
2014 /* else fall through to normal exception processing */
2015 sim_io_eprintf(sd
,"ReservedInstruction 0x%08X at PC = 0x%s\n",instruction
,pr_addr(cia
));
2020 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
2022 /* Keep a copy of the current A0 in-case this is the program exit
2026 unsigned int instruction
;
2027 va_start(ap
,exception
);
2028 instruction
= va_arg(ap
,unsigned int);
2030 /* Check for our special terminating BREAK: */
2031 if ((instruction
& 0x03FFFFC0) == 0x03ff0000) {
2032 sim_engine_halt (SD
, CPU
, NULL
, cia
,
2033 sim_exited
, (unsigned int)(A0
& 0xFFFFFFFF));
2036 if (STATE
& simDELAYSLOT
)
2037 PC
= cia
- 4; /* reference the branch instruction */
2040 sim_engine_halt (SD
, CPU
, NULL
, cia
,
2041 sim_stopped
, SIM_SIGTRAP
);
2044 /* Store exception code into current exception id variable (used
2047 /* TODO: If not simulating exceptions then stop the simulator
2048 execution. At the moment we always stop the simulation. */
2050 /* See figure 5-17 for an outline of the code below */
2051 if (! (SR
& status_EXL
))
2053 CAUSE
= (exception
<< 2);
2054 if (STATE
& simDELAYSLOT
)
2056 STATE
&= ~simDELAYSLOT
;
2058 EPC
= (cia
- 4); /* reference the branch instruction */
2062 /* FIXME: TLB et.al. */
2067 CAUSE
= (exception
<< 2);
2071 /* Store exception code into current exception id variable (used
2073 if (SR
& status_BEV
)
2074 PC
= (signed)0xBFC00200 + 0x180;
2076 PC
= (signed)0x80000000 + 0x180;
2078 switch ((CAUSE
>> 2) & 0x1F)
2081 /* Interrupts arrive during event processing, no need to
2085 case TLBModification
:
2090 case InstructionFetch
:
2092 /* The following is so that the simulator will continue from the
2093 exception address on breakpoint operations. */
2095 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2096 sim_stopped
, SIM_SIGBUS
);
2098 case ReservedInstruction
:
2099 case CoProcessorUnusable
:
2101 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2102 sim_stopped
, SIM_SIGILL
);
2104 case IntegerOverflow
:
2106 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2107 sim_stopped
, SIM_SIGFPE
);
2113 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2114 sim_stopped
, SIM_SIGTRAP
);
2118 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2119 "FATAL: Should not encounter a breakpoint\n");
2121 default : /* Unknown internal exception */
2123 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2124 sim_stopped
, SIM_SIGABRT
);
2128 case SimulatorFault
:
2132 va_start(ap
,exception
);
2133 msg
= va_arg(ap
,char *);
2135 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2136 "FATAL: Simulator error \"%s\"\n",msg
);
2143 #if defined(WARN_RESULT)
2144 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2145 /* This function indicates that the result of the operation is
2146 undefined. However, this should not affect the instruction
2147 stream. All that is meant to happen is that the destination
2148 register is set to an undefined result. To keep the simulator
2149 simple, we just don't bother updating the destination register, so
2150 the overall result will be undefined. If desired we can stop the
2151 simulator by raising a pseudo-exception. */
2152 #define UndefinedResult() undefined_result (sd,cia)
2154 undefined_result(sd
,cia
)
2158 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
2159 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2164 #endif /* WARN_RESULT */
2167 cache_op (SIM_DESC sd
,
2173 unsigned int instruction
)
2175 #if 1 /* stop warning message being displayed (we should really just remove the code) */
2176 static int icache_warning
= 1;
2177 static int dcache_warning
= 1;
2179 static int icache_warning
= 0;
2180 static int dcache_warning
= 0;
2183 /* If CP0 is not useable (User or Supervisor mode) and the CP0
2184 enable bit in the Status Register is clear - a coprocessor
2185 unusable exception is taken. */
2187 sim_io_printf(sd
,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia
));
2191 case 0: /* instruction cache */
2193 case 0: /* Index Invalidate */
2194 case 1: /* Index Load Tag */
2195 case 2: /* Index Store Tag */
2196 case 4: /* Hit Invalidate */
2198 case 6: /* Hit Writeback */
2199 if (!icache_warning
)
2201 sim_io_eprintf(sd
,"Instruction CACHE operation %d to be coded\n",(op
>> 2));
2207 SignalException(ReservedInstruction
,instruction
);
2212 case 1: /* data cache */
2214 case 0: /* Index Writeback Invalidate */
2215 case 1: /* Index Load Tag */
2216 case 2: /* Index Store Tag */
2217 case 3: /* Create Dirty */
2218 case 4: /* Hit Invalidate */
2219 case 5: /* Hit Writeback Invalidate */
2220 case 6: /* Hit Writeback */
2221 if (!dcache_warning
)
2223 sim_io_eprintf(sd
,"Data CACHE operation %d to be coded\n",(op
>> 2));
2229 SignalException(ReservedInstruction
,instruction
);
2234 default: /* unrecognised cache ID */
2235 SignalException(ReservedInstruction
,instruction
);
2242 /*-- FPU support routines ---------------------------------------------------*/
2244 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
2245 formats conform to ANSI/IEEE Std 754-1985. */
2246 /* SINGLE precision floating:
2247 * seeeeeeeefffffffffffffffffffffff
2249 * e = 8bits = exponent
2250 * f = 23bits = fraction
2252 /* SINGLE precision fixed:
2253 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2255 * i = 31bits = integer
2257 /* DOUBLE precision floating:
2258 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
2260 * e = 11bits = exponent
2261 * f = 52bits = fraction
2263 /* DOUBLE precision fixed:
2264 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2266 * i = 63bits = integer
2269 /* Extract sign-bit: */
2270 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
2271 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
2272 /* Extract biased exponent: */
2273 #define FP_S_be(v) (((v) >> 23) & 0xFF)
2274 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
2275 /* Extract unbiased Exponent: */
2276 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
2277 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
2278 /* Extract complete fraction field: */
2279 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
2280 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
2281 /* Extract numbered fraction bit: */
2282 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
2283 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
2285 /* Explicit QNaN values used when value required: */
2286 #define FPQNaN_SINGLE (0x7FBFFFFF)
2287 #define FPQNaN_WORD (0x7FFFFFFF)
2288 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
2289 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
2291 /* Explicit Infinity values used when required: */
2292 #define FPINF_SINGLE (0x7F800000)
2293 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
2295 #if 1 /* def DEBUG */
2296 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
2297 #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>"))))))
2301 value_fpr (SIM_DESC sd
,
2310 /* Treat unused register values, as fixed-point 64bit values: */
2311 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
2313 /* If request to read data as "uninterpreted", then use the current
2315 fmt
= FPR_STATE
[fpr
];
2320 /* For values not yet accessed, set to the desired format: */
2321 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
2322 FPR_STATE
[fpr
] = fmt
;
2324 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
2327 if (fmt
!= FPR_STATE
[fpr
]) {
2328 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
));
2329 FPR_STATE
[fpr
] = fmt_unknown
;
2332 if (FPR_STATE
[fpr
] == fmt_unknown
) {
2333 /* Set QNaN value: */
2336 value
= FPQNaN_SINGLE
;
2340 value
= FPQNaN_DOUBLE
;
2344 value
= FPQNaN_WORD
;
2348 value
= FPQNaN_LONG
;
2355 } else if (SizeFGR() == 64) {
2359 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2362 case fmt_uninterpreted
:
2376 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2379 case fmt_uninterpreted
:
2382 if ((fpr
& 1) == 0) { /* even registers only */
2383 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
2385 SignalException(ReservedInstruction
,0);
2396 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2399 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());
2406 store_fpr (SIM_DESC sd
,
2416 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());
2419 if (SizeFGR() == 64) {
2421 case fmt_uninterpreted_32
:
2422 fmt
= fmt_uninterpreted
;
2425 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2426 FPR_STATE
[fpr
] = fmt
;
2429 case fmt_uninterpreted_64
:
2430 fmt
= fmt_uninterpreted
;
2431 case fmt_uninterpreted
:
2435 FPR_STATE
[fpr
] = fmt
;
2439 FPR_STATE
[fpr
] = fmt_unknown
;
2445 case fmt_uninterpreted_32
:
2446 fmt
= fmt_uninterpreted
;
2449 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2450 FPR_STATE
[fpr
] = fmt
;
2453 case fmt_uninterpreted_64
:
2454 fmt
= fmt_uninterpreted
;
2455 case fmt_uninterpreted
:
2458 if ((fpr
& 1) == 0) { /* even register number only */
2459 FGR
[fpr
+1] = (value
>> 32);
2460 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2461 FPR_STATE
[fpr
+ 1] = fmt
;
2462 FPR_STATE
[fpr
] = fmt
;
2464 FPR_STATE
[fpr
] = fmt_unknown
;
2465 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2466 SignalException(ReservedInstruction
,0);
2471 FPR_STATE
[fpr
] = fmt_unknown
;
2476 #if defined(WARN_RESULT)
2479 #endif /* WARN_RESULT */
2482 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2485 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_addr(FGR
[fpr
]),DOFMT(fmt
));
2502 sim_fpu_32to (&wop
, op
);
2503 boolean
= sim_fpu_is_nan (&wop
);
2510 sim_fpu_64to (&wop
, op
);
2511 boolean
= sim_fpu_is_nan (&wop
);
2515 fprintf (stderr
, "Bad switch\n");
2520 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2534 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2541 sim_fpu_32to (&wop
, op
);
2542 boolean
= sim_fpu_is_infinity (&wop
);
2548 sim_fpu_64to (&wop
, op
);
2549 boolean
= sim_fpu_is_infinity (&wop
);
2553 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2558 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2572 /* Argument checking already performed by the FPCOMPARE code */
2575 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2578 /* The format type should already have been checked: */
2584 sim_fpu_32to (&wop1
, op1
);
2585 sim_fpu_32to (&wop2
, op2
);
2586 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2593 sim_fpu_64to (&wop1
, op1
);
2594 sim_fpu_64to (&wop2
, op2
);
2595 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2599 fprintf (stderr
, "Bad switch\n");
2604 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2618 /* Argument checking already performed by the FPCOMPARE code */
2621 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2624 /* The format type should already have been checked: */
2630 sim_fpu_32to (&wop1
, op1
);
2631 sim_fpu_32to (&wop2
, op2
);
2632 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2639 sim_fpu_64to (&wop1
, op1
);
2640 sim_fpu_64to (&wop2
, op2
);
2641 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2645 fprintf (stderr
, "Bad switch\n");
2650 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2657 AbsoluteValue(op
,fmt
)
2664 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2667 /* The format type should already have been checked: */
2673 sim_fpu_32to (&wop
, op
);
2674 sim_fpu_abs (&wop
, &wop
);
2675 sim_fpu_to32 (&ans
, &wop
);
2683 sim_fpu_64to (&wop
, op
);
2684 sim_fpu_abs (&wop
, &wop
);
2685 sim_fpu_to64 (&ans
, &wop
);
2690 fprintf (stderr
, "Bad switch\n");
2705 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2708 /* The format type should already have been checked: */
2714 sim_fpu_32to (&wop
, op
);
2715 sim_fpu_neg (&wop
, &wop
);
2716 sim_fpu_to32 (&ans
, &wop
);
2724 sim_fpu_64to (&wop
, op
);
2725 sim_fpu_neg (&wop
, &wop
);
2726 sim_fpu_to64 (&ans
, &wop
);
2731 fprintf (stderr
, "Bad switch\n");
2747 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2750 /* The registers must specify FPRs valid for operands of type
2751 "fmt". If they are not valid, the result is undefined. */
2753 /* The format type should already have been checked: */
2761 sim_fpu_32to (&wop1
, op1
);
2762 sim_fpu_32to (&wop2
, op2
);
2763 sim_fpu_add (&ans
, &wop1
, &wop2
);
2764 sim_fpu_to32 (&res
, &ans
);
2774 sim_fpu_64to (&wop1
, op1
);
2775 sim_fpu_64to (&wop2
, op2
);
2776 sim_fpu_add (&ans
, &wop1
, &wop2
);
2777 sim_fpu_to64 (&res
, &ans
);
2782 fprintf (stderr
, "Bad switch\n");
2787 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2802 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2805 /* The registers must specify FPRs valid for operands of type
2806 "fmt". If they are not valid, the result is undefined. */
2808 /* The format type should already have been checked: */
2816 sim_fpu_32to (&wop1
, op1
);
2817 sim_fpu_32to (&wop2
, op2
);
2818 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2819 sim_fpu_to32 (&res
, &ans
);
2829 sim_fpu_64to (&wop1
, op1
);
2830 sim_fpu_64to (&wop2
, op2
);
2831 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2832 sim_fpu_to64 (&res
, &ans
);
2837 fprintf (stderr
, "Bad switch\n");
2842 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2849 Multiply(op1
,op2
,fmt
)
2857 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2860 /* The registers must specify FPRs valid for operands of type
2861 "fmt". If they are not valid, the result is undefined. */
2863 /* The format type should already have been checked: */
2871 sim_fpu_32to (&wop1
, op1
);
2872 sim_fpu_32to (&wop2
, op2
);
2873 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2874 sim_fpu_to32 (&res
, &ans
);
2884 sim_fpu_64to (&wop1
, op1
);
2885 sim_fpu_64to (&wop2
, op2
);
2886 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2887 sim_fpu_to64 (&res
, &ans
);
2892 fprintf (stderr
, "Bad switch\n");
2897 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2912 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2915 /* The registers must specify FPRs valid for operands of type
2916 "fmt". If they are not valid, the result is undefined. */
2918 /* The format type should already have been checked: */
2926 sim_fpu_32to (&wop1
, op1
);
2927 sim_fpu_32to (&wop2
, op2
);
2928 sim_fpu_div (&ans
, &wop1
, &wop2
);
2929 sim_fpu_to32 (&res
, &ans
);
2939 sim_fpu_64to (&wop1
, op1
);
2940 sim_fpu_64to (&wop2
, op2
);
2941 sim_fpu_div (&ans
, &wop1
, &wop2
);
2942 sim_fpu_to64 (&res
, &ans
);
2947 fprintf (stderr
, "Bad switch\n");
2952 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2966 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2969 /* The registers must specify FPRs valid for operands of type
2970 "fmt". If they are not valid, the result is undefined. */
2972 /* The format type should already have been checked: */
2979 sim_fpu_32to (&wop
, op
);
2980 sim_fpu_inv (&ans
, &wop
);
2981 sim_fpu_to32 (&res
, &ans
);
2990 sim_fpu_64to (&wop
, op
);
2991 sim_fpu_inv (&ans
, &wop
);
2992 sim_fpu_to64 (&res
, &ans
);
2997 fprintf (stderr
, "Bad switch\n");
3002 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3016 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
3019 /* The registers must specify FPRs valid for operands of type
3020 "fmt". If they are not valid, the result is undefined. */
3022 /* The format type should already have been checked: */
3029 sim_fpu_32to (&wop
, op
);
3030 sim_fpu_sqrt (&ans
, &wop
);
3031 sim_fpu_to32 (&res
, &ans
);
3040 sim_fpu_64to (&wop
, op
);
3041 sim_fpu_sqrt (&ans
, &wop
);
3042 sim_fpu_to64 (&res
, &ans
);
3047 fprintf (stderr
, "Bad switch\n");
3052 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3068 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3071 /* The registers must specify FPRs valid for operands of type
3072 "fmt". If they are not valid, the result is undefined. */
3074 /* The format type should already have been checked: */
3081 sim_fpu_32to (&wop1
, op1
);
3082 sim_fpu_32to (&wop2
, op2
);
3083 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3090 sim_fpu_64to (&wop1
, op1
);
3091 sim_fpu_64to (&wop2
, op2
);
3092 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3096 fprintf (stderr
, "Bad switch\n");
3102 case SIM_FPU_IS_SNAN
:
3103 case SIM_FPU_IS_QNAN
:
3105 case SIM_FPU_IS_NINF
:
3106 case SIM_FPU_IS_NNUMBER
:
3107 case SIM_FPU_IS_NDENORM
:
3108 case SIM_FPU_IS_NZERO
:
3109 result
= op2
; /* op1 - op2 < 0 */
3110 case SIM_FPU_IS_PINF
:
3111 case SIM_FPU_IS_PNUMBER
:
3112 case SIM_FPU_IS_PDENORM
:
3113 case SIM_FPU_IS_PZERO
:
3114 result
= op1
; /* op1 - op2 > 0 */
3116 fprintf (stderr
, "Bad switch\n");
3121 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3138 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3141 /* The registers must specify FPRs valid for operands of type
3142 "fmt". If they are not valid, the result is undefined. */
3144 /* The format type should already have been checked: */
3151 sim_fpu_32to (&wop1
, op1
);
3152 sim_fpu_32to (&wop2
, op2
);
3153 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3160 sim_fpu_64to (&wop1
, op1
);
3161 sim_fpu_64to (&wop2
, op2
);
3162 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3166 fprintf (stderr
, "Bad switch\n");
3172 case SIM_FPU_IS_SNAN
:
3173 case SIM_FPU_IS_QNAN
:
3175 case SIM_FPU_IS_NINF
:
3176 case SIM_FPU_IS_NNUMBER
:
3177 case SIM_FPU_IS_NDENORM
:
3178 case SIM_FPU_IS_NZERO
:
3179 result
= op1
; /* op1 - op2 < 0 */
3180 case SIM_FPU_IS_PINF
:
3181 case SIM_FPU_IS_PNUMBER
:
3182 case SIM_FPU_IS_PDENORM
:
3183 case SIM_FPU_IS_PZERO
:
3184 result
= op2
; /* op1 - op2 > 0 */
3186 fprintf (stderr
, "Bad switch\n");
3191 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3199 convert (SIM_DESC sd
,
3208 sim_fpu_round round
;
3209 unsigned32 result32
;
3210 unsigned64 result64
;
3213 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
));
3219 /* Round result to nearest representable value. When two
3220 representable values are equally near, round to the value
3221 that has a least significant bit of zero (i.e. is even). */
3222 round
= sim_fpu_round_near
;
3225 /* Round result to the value closest to, and not greater in
3226 magnitude than, the result. */
3227 round
= sim_fpu_round_zero
;
3230 /* Round result to the value closest to, and not less than,
3232 round
= sim_fpu_round_up
;
3236 /* Round result to the value closest to, and not greater than,
3238 round
= sim_fpu_round_down
;
3242 fprintf (stderr
, "Bad switch\n");
3246 /* Convert the input to sim_fpu internal format */
3250 sim_fpu_64to (&wop
, op
);
3253 sim_fpu_32to (&wop
, op
);
3256 sim_fpu_i32to (&wop
, op
, round
);
3259 sim_fpu_i64to (&wop
, op
, round
);
3262 fprintf (stderr
, "Bad switch\n");
3266 /* Convert sim_fpu format into the output */
3267 /* The value WOP is converted to the destination format, rounding
3268 using mode RM. When the destination is a fixed-point format, then
3269 a source value of Infinity, NaN or one which would round to an
3270 integer outside the fixed point range then an IEEE Invalid
3271 Operation condition is raised. */
3275 sim_fpu_round_32 (&wop
, round
, 0);
3276 sim_fpu_to32 (&result32
, &wop
);
3277 result64
= result32
;
3280 sim_fpu_round_64 (&wop
, round
, 0);
3281 sim_fpu_to64 (&result64
, &wop
);
3284 sim_fpu_to32i (&result32
, &wop
, round
);
3285 result64
= result32
;
3288 sim_fpu_to64i (&result64
, &wop
, round
);
3292 fprintf (stderr
, "Bad switch\n");
3297 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
3304 /*-- co-processor support routines ------------------------------------------*/
3307 CoProcPresent(coproc_number
)
3308 unsigned int coproc_number
;
3310 /* Return TRUE if simulator provides a model for the given co-processor number */
3315 cop_lw (SIM_DESC sd
,
3320 unsigned int memword
)
3325 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3328 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
3330 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
3331 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
3336 #if 0 /* this should be controlled by a configuration option */
3337 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
));
3346 cop_ld (SIM_DESC sd
,
3353 switch (coproc_num
) {
3355 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3357 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
3362 #if 0 /* this message should be controlled by a configuration option */
3363 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
));
3372 /* start-sanitize-sky */
3375 cop_lq (SIM_DESC sd
,
3380 unsigned128 memword
)
3389 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3390 coproc_num
,coproc_reg
,pr_addr(cia
));
3396 #endif /* TARGET_SKY */
3397 /* end-sanitize-sky */
3401 cop_sw (SIM_DESC sd
,
3407 unsigned int value
= 0;
3412 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3415 hold
= FPR_STATE
[coproc_reg
];
3416 FPR_STATE
[coproc_reg
] = fmt_word
;
3417 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3418 FPR_STATE
[coproc_reg
] = hold
;
3423 #if 0 /* should be controlled by configuration option */
3424 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3433 cop_sd (SIM_DESC sd
,
3443 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3445 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3450 #if 0 /* should be controlled by configuration option */
3451 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3460 /* start-sanitize-sky */
3463 cop_sq (SIM_DESC sd
,
3469 unsigned128 value
= U16_8(0, 0);
3477 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3478 coproc_num
,coproc_reg
,pr_addr(cia
));
3484 #endif /* TARGET_SKY */
3485 /* end-sanitize-sky */
3489 decode_coproc (SIM_DESC sd
,
3492 unsigned int instruction
)
3494 int coprocnum
= ((instruction
>> 26) & 3);
3498 case 0: /* standard CPU control and cache registers */
3500 int code
= ((instruction
>> 21) & 0x1F);
3501 /* R4000 Users Manual (second edition) lists the following CP0
3503 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3504 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3505 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3506 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3507 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3508 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3509 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3510 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3511 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3512 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3514 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0))
3516 int rt
= ((instruction
>> 16) & 0x1F);
3517 int rd
= ((instruction
>> 11) & 0x1F);
3519 switch (rd
) /* NOTEs: Standard CP0 registers */
3521 /* 0 = Index R4000 VR4100 VR4300 */
3522 /* 1 = Random R4000 VR4100 VR4300 */
3523 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3524 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3525 /* 4 = Context R4000 VR4100 VR4300 */
3526 /* 5 = PageMask R4000 VR4100 VR4300 */
3527 /* 6 = Wired R4000 VR4100 VR4300 */
3528 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3529 /* 9 = Count R4000 VR4100 VR4300 */
3530 /* 10 = EntryHi R4000 VR4100 VR4300 */
3531 /* 11 = Compare R4000 VR4100 VR4300 */
3532 /* 12 = SR R4000 VR4100 VR4300 */
3539 /* 13 = Cause R4000 VR4100 VR4300 */
3546 /* 14 = EPC R4000 VR4100 VR4300 */
3547 /* 15 = PRId R4000 VR4100 VR4300 */
3548 #ifdef SUBTARGET_R3900
3557 /* 16 = Config R4000 VR4100 VR4300 */
3560 GPR
[rt
] = C0_CONFIG
;
3562 C0_CONFIG
= GPR
[rt
];
3565 #ifdef SUBTARGET_R3900
3574 /* 17 = LLAddr R4000 VR4100 VR4300 */
3576 /* 18 = WatchLo R4000 VR4100 VR4300 */
3577 /* 19 = WatchHi R4000 VR4100 VR4300 */
3578 /* 20 = XContext R4000 VR4100 VR4300 */
3579 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3580 /* 27 = CacheErr R4000 VR4100 */
3581 /* 28 = TagLo R4000 VR4100 VR4300 */
3582 /* 29 = TagHi R4000 VR4100 VR4300 */
3583 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3584 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3585 /* CPR[0,rd] = GPR[rt]; */
3588 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3590 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3593 else if (code
== 0x10 && (instruction
& 0x3f) == 0x18)
3596 if (SR
& status_ERL
)
3598 /* Oops, not yet available */
3599 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3609 else if (code
== 0x10 && (instruction
& 0x3f) == 0x10)
3613 else if (code
== 0x10 && (instruction
& 0x3f) == 0x1F)
3621 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3622 /* TODO: When executing an ERET or RFE instruction we should
3623 clear LLBIT, to ensure that any out-standing atomic
3624 read/modify/write sequence fails. */
3628 case 2: /* undefined co-processor */
3632 /* start-sanitize-sky */
3634 /* On the R5900, this refers to a "VU" vector co-processor. */
3636 int i_25_21
= (instruction
>> 21) & 0x1f;
3637 int i_20_16
= (instruction
>> 16) & 0x1f;
3638 int i_15_11
= (instruction
>> 11) & 0x1f;
3639 int i_15_0
= instruction
& 0xffff;
3640 int i_10_1
= (instruction
>> 1) & 0x3ff;
3641 int i_5_0
= instruction
& 0x03f;
3642 int interlock
= instruction
& 0x01;
3643 int co
= (instruction
>> 25) & 0x01;
3644 /* setup for semantic.c-like actions below */
3645 typedef unsigned_4 instruction_word
;
3648 sim_cpu
* CPU_
= cpu
;
3652 /* test COP2 usability */
3653 if(! (SR
& status_CU2
))
3655 SignalException(CoProcessorUnusable
,instruction
);
3659 /* classify & execute basic COP2 instructions */
3660 if(i_25_21
== 0x08 && i_20_16
== 0x00) /* BC2F */
3662 address_word offset
= EXTEND16(i_15_0
) << 2;
3663 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3665 else if(i_25_21
== 0x08 && i_20_16
==0x02) /* BC2FL */
3667 address_word offset
= EXTEND16(i_15_0
) << 2;
3668 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3669 else NULLIFY_NEXT_INSTRUCTION();
3671 else if(i_25_21
== 0x08 && i_20_16
== 0x01) /* BC2T */
3673 address_word offset
= EXTEND16(i_15_0
) << 2;
3674 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3676 else if(i_25_21
== 0x08 && i_20_16
== 0x03) /* BC2TL */
3678 address_word offset
= EXTEND16(i_15_0
) << 2;
3679 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3680 else NULLIFY_NEXT_INSTRUCTION();
3682 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3683 (i_25_21
== 0x01)) /* QMFC2 */
3687 address_word vu_cr_addr
; /* VU control register address */
3690 /* interlock checking */
3691 if(vu0_busy_in_macro_mode()) /* busy in macro mode */
3693 /* interlock bit invalid here */
3695 ; /* XXX: warning */
3697 /* always check data hazard */
3698 while(vu0_macro_hazard_check(id
))
3701 else if(vu0_busy_in_micro_mode() && interlock
)
3703 while(vu0_busy_in_micro_mode())
3707 /* compute VU register address */
3708 if(i_25_21
== 0x01) /* QMFC2 */
3709 vu_cr_addr
= VU0_REGISTER_WINDOW_START
+ (id
* 16);
3711 vu_cr_addr
= VU0_MST
+ (id
* 16);
3713 /* read or write word */
3714 data
= sim_core_read_aligned_4(cpu
, cia
, read_map
, vu_cr_addr
);
3715 GPR
[rt
] = EXTEND64(data
);
3717 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3718 (i_25_21
== 0x05)) /* QMTC2 */
3722 address_word vu_cr_addr
; /* VU control register address */
3725 /* interlock checking */
3726 if(vu0_busy_in_macro_mode()) /* busy in macro mode */
3728 /* interlock bit invalid here */
3730 ; /* XXX: warning */
3732 /* always check data hazard */
3733 while(vu0_macro_hazard_check(id
))
3736 else if(vu0_busy_in_micro_mode())
3740 while(! vu0_micro_interlock_released())
3745 /* compute VU register address */
3746 if(i_25_21
== 0x05) /* QMTC2 */
3747 vu_cr_addr
= VU0_REGISTER_WINDOW_START
+ (id
* 16);
3749 vu_cr_addr
= VU0_MST
+ (id
* 16);
3752 sim_core_write_aligned_4(cpu
, cia
, write_map
, vu_cr_addr
, data
);
3754 else if( 0 /* XXX: ... upper ... */)
3756 unsigned_4 vu_upper
, vu_lower
;
3758 0x00000000 | /* bits 31 .. 25 */
3759 instruction
& 0x01ffffff; /* bits 24 .. 0 */
3760 vu_lower
= 0x8000033c; /* NOP */
3762 while(vu0_busy_in_micro_mode())
3765 vu0_macro_issue(vu_upper
, vu_lower
);
3767 else if( 0 /* XXX: ... lower ... */)
3769 unsigned_4 vu_upper
, vu_lower
;
3770 vu_upper
= 0x000002ff; /* NOP */
3772 0x10000000 | /* bits 31 .. 25 */
3773 instruction
& 0x01ffffff; /* bits 24 .. 0 */
3775 while(vu0_busy_in_micro_mode())
3778 vu0_macro_issue(vu_upper
, vu_lower
);
3781 /* ... other COP2 instructions ... */
3784 SignalException(ReservedInstruction
, instruction
);
3788 /* cleanup for semantic.c-like actions above */
3791 #endif /* TARGET_SKY */
3792 /* end-sanitize-sky */
3796 sim_io_eprintf(sd
,"COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3797 instruction
,pr_addr(cia
));
3802 case 1: /* should not occur (FPU co-processor) */
3803 case 3: /* should not occur (FPU co-processor) */
3804 SignalException(ReservedInstruction
,instruction
);
3812 /*-- instruction simulation -------------------------------------------------*/
3814 /* When the IGEN simulator is being built, the function below is be
3815 replaced by a generated version. However, WITH_IGEN == 2 indicates
3816 that the fubction below should be compiled but under a different
3817 name (to allow backward compatibility) */
3819 #if (WITH_IGEN != 1)
3821 void old_engine_run
PARAMS ((SIM_DESC sd
, int next_cpu_nr
, int siggnal
));
3823 old_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3826 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3829 int next_cpu_nr
; /* ignore */
3830 int nr_cpus
; /* ignore */
3831 int siggnal
; /* ignore */
3833 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* hardwire to cpu 0 */
3834 #if !defined(FASTSIM)
3835 unsigned int pipeline_count
= 1;
3839 if (STATE_MEMORY (sd
) == NULL
) {
3840 printf("DBG: simulate() entered with no memory\n");
3845 #if 0 /* Disabled to check that everything works OK */
3846 /* The VR4300 seems to sign-extend the PC on its first
3847 access. However, this may just be because it is currently
3848 configured in 32bit mode. However... */
3849 PC
= SIGNEXTEND(PC
,32);
3852 /* main controlling loop */
3854 /* vaddr is slowly being replaced with cia - current instruction
3856 address_word cia
= (uword64
)PC
;
3857 address_word vaddr
= cia
;
3860 unsigned int instruction
; /* uword64? what's this used for? FIXME! */
3864 printf("DBG: state = 0x%08X :",state
);
3865 if (state
& simHALTEX
) printf(" simHALTEX");
3866 if (state
& simHALTIN
) printf(" simHALTIN");
3871 DSSTATE
= (STATE
& simDELAYSLOT
);
3874 sim_io_printf(sd
,"DBG: DSPC = 0x%s\n",pr_addr(DSPC
));
3877 /* Fetch the next instruction from the simulator memory: */
3878 if (AddressTranslation(cia
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) {
3879 if ((vaddr
& 1) == 0) {
3880 /* Copy the action of the LW instruction */
3881 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3882 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3885 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3886 LoadMemory(&value
,NULL
,cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3887 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3888 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3890 /* Copy the action of the LH instruction */
3891 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 1) : 0);
3892 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 1) : 0);
3895 paddr
= (((paddr
& ~ (uword64
) 1) & ~LOADDRMASK
)
3896 | (((paddr
& ~ (uword64
) 1) & LOADDRMASK
) ^ (reverse
<< 1)));
3897 LoadMemory(&value
,NULL
,cca
, AccessLength_HALFWORD
,
3898 paddr
& ~ (uword64
) 1,
3899 vaddr
, isINSTRUCTION
, isREAL
);
3900 byte
= (((vaddr
&~ (uword64
) 1) & LOADDRMASK
) ^ (bigend
<< 1));
3901 instruction
= ((value
>> (8 * byte
)) & 0xFFFF);
3904 fprintf(stderr
,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC
));
3909 sim_io_printf(sd
,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction
,pr_addr(PC
));
3912 /* This is required by exception processing, to ensure that we can
3913 cope with exceptions in the delay slots of branches that may
3914 already have changed the PC. */
3915 if ((vaddr
& 1) == 0)
3916 PC
+= 4; /* increment ready for the next fetch */
3919 /* NOTE: If we perform a delay slot change to the PC, this
3920 increment is not requuired. However, it would make the
3921 simulator more complicated to try and avoid this small hit. */
3923 /* Currently this code provides a simple model. For more
3924 complicated models we could perform exception status checks at
3925 this point, and set the simSTOP state as required. This could
3926 also include processing any hardware interrupts raised by any
3927 I/O model attached to the simulator context.
3929 Support for "asynchronous" I/O events within the simulated world
3930 could be providing by managing a counter, and calling a I/O
3931 specific handler when a particular threshold is reached. On most
3932 architectures a decrement and check for zero operation is
3933 usually quicker than an increment and compare. However, the
3934 process of managing a known value decrement to zero, is higher
3935 than the cost of using an explicit value UINT_MAX into the
3936 future. Which system is used will depend on how complicated the
3937 I/O model is, and how much it is likely to affect the simulator
3940 If events need to be scheduled further in the future than
3941 UINT_MAX event ticks, then the I/O model should just provide its
3942 own counter, triggered from the event system. */
3944 /* MIPS pipeline ticks. To allow for future support where the
3945 pipeline hit of individual instructions is known, this control
3946 loop manages a "pipeline_count" variable. It is initialised to
3947 1 (one), and will only be changed by the simulator engine when
3948 executing an instruction. If the engine does not have access to
3949 pipeline cycle count information then all instructions will be
3950 treated as using a single cycle. NOTE: A standard system is not
3951 provided by the default simulator because different MIPS
3952 architectures have different cycle counts for the same
3955 [NOTE: pipeline_count has been replaced the event queue] */
3957 /* shuffle the floating point status pipeline state */
3958 ENGINE_ISSUE_PREFIX_HOOK();
3960 /* NOTE: For multi-context simulation environments the "instruction"
3961 variable should be local to this routine. */
3963 /* Shorthand accesses for engine. Note: If we wanted to use global
3964 variables (and a single-threaded simulator engine), then we can
3965 create the actual variables with these names. */
3967 if (!(STATE
& simSKIPNEXT
)) {
3968 /* Include the simulator engine */
3969 #include "oengine.c"
3970 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3971 #error "Mismatch between run-time simulator code and simulation engine"
3973 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3974 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3976 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3977 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3980 #if defined(WARN_LOHI)
3981 /* Decrement the HI/LO validity ticks */
3986 /* start-sanitize-r5900 */
3991 /* end-sanitize-r5900 */
3992 #endif /* WARN_LOHI */
3994 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3995 should check for it being changed. It is better doing it here,
3996 than within the simulator, since it will help keep the simulator
3999 #if defined(WARN_ZERO)
4000 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
));
4001 #endif /* WARN_ZERO */
4002 ZERO
= 0; /* reset back to zero before next instruction */
4004 } else /* simSKIPNEXT check */
4005 STATE
&= ~simSKIPNEXT
;
4007 /* If the delay slot was active before the instruction is
4008 executed, then update the PC to its new value: */
4011 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC
));
4020 #if !defined(FASTSIM)
4021 if (sim_events_tickn (sd
, pipeline_count
))
4023 /* cpu->cia = cia; */
4024 sim_events_process (sd
);
4027 if (sim_events_tick (sd
))
4029 /* cpu->cia = cia; */
4030 sim_events_process (sd
);
4032 #endif /* FASTSIM */
4038 /* This code copied from gdb's utils.c. Would like to share this code,
4039 but don't know of a common place where both could get to it. */
4041 /* Temporary storage using circular buffer */
4047 static char buf
[NUMCELLS
][CELLSIZE
];
4049 if (++cell
>=NUMCELLS
) cell
=0;
4053 /* Print routines to handle variable size regs, etc */
4055 /* Eliminate warning from compiler on 32-bit systems */
4056 static int thirty_two
= 32;
4062 char *paddr_str
=get_cell();
4063 switch (sizeof(addr
))
4066 sprintf(paddr_str
,"%08lx%08lx",
4067 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
4070 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
4073 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
4076 sprintf(paddr_str
,"%x",addr
);
4085 char *paddr_str
=get_cell();
4086 sprintf(paddr_str
,"%08lx%08lx",
4087 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
4093 pending_tick (SIM_DESC sd
,
4098 sim_io_printf (sd
, "PENDING_DRAIN - pending_in = %d, pending_out = %d, pending_total = %d\n", PENDING_IN
, PENDING_OUT
, PENDING_TOTAL
);
4099 if (PENDING_OUT
!= PENDING_IN
)
4102 int index
= PENDING_OUT
;
4103 int total
= PENDING_TOTAL
;
4104 if (PENDING_TOTAL
== 0)
4105 sim_engine_abort (SD
, CPU
, cia
, "PENDING_DRAIN - Mis-match on pending update pointers\n");
4106 for (loop
= 0; (loop
< total
); loop
++)
4108 if (PENDING_SLOT_DEST
[index
] != NULL
)
4110 PENDING_SLOT_DELAY
[index
] -= 1;
4111 if (PENDING_SLOT_DELAY
[index
] == 0)
4113 if (PENDING_SLOT_BIT
[index
] >= 0)
4114 switch (PENDING_SLOT_SIZE
[index
])
4117 if (PENDING_SLOT_VALUE
[index
])
4118 *(unsigned32
*)PENDING_SLOT_DEST
[index
] |=
4119 BIT32 (PENDING_SLOT_BIT
[index
]);
4121 *(unsigned32
*)PENDING_SLOT_DEST
[index
] &=
4122 BIT32 (PENDING_SLOT_BIT
[index
]);
4125 if (PENDING_SLOT_VALUE
[index
])
4126 *(unsigned64
*)PENDING_SLOT_DEST
[index
] |=
4127 BIT64 (PENDING_SLOT_BIT
[index
]);
4129 *(unsigned64
*)PENDING_SLOT_DEST
[index
] &=
4130 BIT64 (PENDING_SLOT_BIT
[index
]);
4135 switch (PENDING_SLOT_SIZE
[index
])
4138 *(unsigned32
*)PENDING_SLOT_DEST
[index
] =
4139 PENDING_SLOT_VALUE
[index
];
4142 *(unsigned64
*)PENDING_SLOT_DEST
[index
] =
4143 PENDING_SLOT_VALUE
[index
];
4147 if (PENDING_OUT
== index
)
4149 PENDING_SLOT_DEST
[index
] = NULL
;
4150 PENDING_OUT
= (PENDING_OUT
+ 1) % PSLOTS
;
4155 index
= (index
+ 1) % PSLOTS
;
4159 /*---------------------------------------------------------------------------*/
4160 /*> EOF interp.c <*/