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"
42 /* start-sanitize-sky */
46 #include "sky-libvpe.h"
53 /* end-sanitize-sky */
75 #include "libiberty.h"
77 #include "callback.h" /* GDB simulator callback interface */
78 #include "remote-sim.h" /* GDB simulator interface */
86 char* pr_addr
PARAMS ((SIM_ADDR addr
));
87 char* pr_uword64
PARAMS ((uword64 addr
));
90 /* Get the simulator engine description, without including the code: */
97 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
102 /* The following reserved instruction value is used when a simulator
103 trap is required. NOTE: Care must be taken, since this value may be
104 used in later revisions of the MIPS ISA. */
106 #define RSVD_INSTRUCTION (0x00000005)
107 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
109 #define RSVD_INSTRUCTION_ARG_SHIFT 6
110 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
113 /* Bits in the Debug register */
114 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
115 #define Debug_DM 0x40000000 /* Debug Mode */
116 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
118 /*---------------------------------------------------------------------------*/
119 /*-- GDB simulator interface ------------------------------------------------*/
120 /*---------------------------------------------------------------------------*/
122 static void ColdReset
PARAMS((SIM_DESC sd
));
124 /*---------------------------------------------------------------------------*/
128 #define DELAYSLOT() {\
129 if (STATE & simDELAYSLOT)\
130 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
131 STATE |= simDELAYSLOT;\
134 #define JALDELAYSLOT() {\
136 STATE |= simJALDELAYSLOT;\
140 STATE &= ~simDELAYSLOT;\
141 STATE |= simSKIPNEXT;\
144 #define CANCELDELAYSLOT() {\
146 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
149 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
150 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
152 #define K0BASE (0x80000000)
153 #define K0SIZE (0x20000000)
154 #define K1BASE (0xA0000000)
155 #define K1SIZE (0x20000000)
156 #define MONITOR_BASE (0xBFC00000)
157 #define MONITOR_SIZE (1 << 11)
158 #define MEM_SIZE (2 << 20)
160 /* start-sanitize-sky */
163 #define MEM_SIZE (16 << 20) /* 16 MB */
165 /* end-sanitize-sky */
168 static char *tracefile
= "trace.din"; /* default filename for trace log */
169 FILE *tracefh
= NULL
;
170 static void open_trace
PARAMS((SIM_DESC sd
));
173 /* simulation target board. NULL=canonical */
174 static char* board
= NULL
;
177 static DECLARE_OPTION_HANDLER (mips_option_handler
);
180 OPTION_DINERO_TRACE
= OPTION_START
,
187 mips_option_handler (sd
, cpu
, opt
, arg
, is_command
)
197 case OPTION_DINERO_TRACE
: /* ??? */
199 /* Eventually the simTRACE flag could be treated as a toggle, to
200 allow external control of the program points being traced
201 (i.e. only from main onwards, excluding the run-time setup,
203 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
205 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
208 else if (strcmp (arg
, "yes") == 0)
210 else if (strcmp (arg
, "no") == 0)
212 else if (strcmp (arg
, "on") == 0)
214 else if (strcmp (arg
, "off") == 0)
218 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
225 Simulator constructed without dinero tracing support (for performance).\n\
226 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
230 case OPTION_DINERO_FILE
:
232 if (optarg
!= NULL
) {
234 tmp
= (char *)malloc(strlen(optarg
) + 1);
237 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
243 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
253 board
= zalloc(strlen(arg
) + 1);
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 { {"board", required_argument
, NULL
, OPTION_BOARD
},
273 '\0', "none" /* rely on compile-time string concatenation for other options */
275 /* start-sanitize-tx3904 */
276 #define BOARD_JMR3904 "jmr3904"
278 #define BOARD_JMR3904_PAL "jmr3904pal"
279 "|" BOARD_JMR3904_PAL
280 #define BOARD_JMR3904_DEBUG "jmr3904debug"
281 "|" BOARD_JMR3904_DEBUG
282 /* end-sanitize-tx3904 */
284 , "Customize simulation for a particular board.", mips_option_handler
},
286 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
290 int interrupt_pending
;
293 interrupt_event (SIM_DESC sd
, void *data
)
295 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
296 address_word cia
= CIA_GET (cpu
);
299 interrupt_pending
= 0;
300 SignalExceptionInterrupt ();
302 else if (!interrupt_pending
)
303 sim_events_schedule (sd
, 1, interrupt_event
, data
);
307 /*---------------------------------------------------------------------------*/
308 /*-- Device registration hook -----------------------------------------------*/
309 /*---------------------------------------------------------------------------*/
310 static void device_init(SIM_DESC sd
) {
312 extern void register_devices(SIM_DESC
);
313 register_devices(sd
);
317 /*---------------------------------------------------------------------------*/
318 /*-- GDB simulator interface ------------------------------------------------*/
319 /*---------------------------------------------------------------------------*/
322 sim_open (kind
, cb
, abfd
, argv
)
328 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
329 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
331 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
334 /* FIXME: watchpoints code shouldn't need this */
335 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
336 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
337 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
341 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
343 sim_add_option_table (sd
, NULL
, mips_options
);
345 /* start-sanitize-sky */
347 sky_command_options (sd
);
349 /* end-sanitize-sky */
351 /* getopt will print the error message so we just have to exit if this fails.
352 FIXME: Hmmm... in the case of gdb we need getopt to call
354 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
356 /* Uninstall the modules to avoid memory leaks,
357 file descriptor leaks, etc. */
358 sim_module_uninstall (sd
);
362 /* handle board-specific memory maps */
365 /* Allocate core managed memory */
367 /* start-sanitize-sky */
369 /* end-sanitize-sky */
371 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
, MONITOR_SIZE
);
372 /* For compatibility with the old code - under this (at level one)
373 are the kernel spaces K0 & K1. Both of these map to a single
374 smaller sub region */
375 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
376 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
378 MEM_SIZE
, /* actual size */
380 /* start-sanitize-sky */
383 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
- K1BASE
, MONITOR_SIZE
);
384 sim_do_command (sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
385 /* 16M @ 0x0. Aliases at 0x80000000 and 0xA0000000 are handled by
386 address_translation() */
387 sim_do_commandf (sd
, "memory size 0x%lx", MEM_SIZE
);
389 /* end-sanitize-sky */
394 /* start-sanitize-tx3904 */
397 && (strcmp(board
, BOARD_JMR3904
) == 0 ||
398 strcmp(board
, BOARD_JMR3904_PAL
) == 0 ||
399 strcmp(board
, BOARD_JMR3904_DEBUG
) == 0))
401 /* match VIRTUAL memory layout of JMR-TX3904 board */
405 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
406 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
408 4 * 1024 * 1024, /* 4 MB */
411 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
412 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
414 4 * 1024 * 1024, /* 4 MB */
417 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
418 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
420 32 * 1024 * 1024, /* 32 MB */
423 /* --- simulated devices --- */
424 sim_hw_parse (sd
, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
425 sim_hw_parse (sd
, "/tx3904cpu");
426 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
427 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
428 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
430 /* -- device connections --- */
431 sim_hw_parse (sd
, "/tx3904irc > ip level /tx3904cpu");
432 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
433 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
434 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
436 /* add PAL timer & I/O module */
437 if(! strcmp(board
, BOARD_JMR3904_PAL
))
440 sim_hw_parse (sd
, "/pal@0xffff0000");
441 sim_hw_parse (sd
, "/pal@0xffff0000/reg 0xffff0000 64");
443 /* wire up interrupt ports to irc */
444 sim_hw_parse (sd
, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
445 sim_hw_parse (sd
, "/pal@0x31000000 > timer tmr1 /tx3904irc");
446 sim_hw_parse (sd
, "/pal@0x31000000 > int int0 /tx3904irc");
449 if(! strcmp(board
, BOARD_JMR3904_DEBUG
))
451 /* -- DEBUG: glue interrupt generators --- */
452 sim_hw_parse (sd
, "/glue@0xffff0000/reg 0xffff0000 0x50");
453 sim_hw_parse (sd
, "/glue@0xffff0000 > int0 int0 /tx3904irc");
454 sim_hw_parse (sd
, "/glue@0xffff0000 > int1 int1 /tx3904irc");
455 sim_hw_parse (sd
, "/glue@0xffff0000 > int2 int2 /tx3904irc");
456 sim_hw_parse (sd
, "/glue@0xffff0000 > int3 int3 /tx3904irc");
457 sim_hw_parse (sd
, "/glue@0xffff0000 > int4 int4 /tx3904irc");
458 sim_hw_parse (sd
, "/glue@0xffff0000 > int5 int5 /tx3904irc");
459 sim_hw_parse (sd
, "/glue@0xffff0000 > int6 int6 /tx3904irc");
460 sim_hw_parse (sd
, "/glue@0xffff0000 > int7 int7 /tx3904irc");
461 sim_hw_parse (sd
, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
462 sim_hw_parse (sd
, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
463 sim_hw_parse (sd
, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
464 sim_hw_parse (sd
, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
465 sim_hw_parse (sd
, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
466 sim_hw_parse (sd
, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
467 sim_hw_parse (sd
, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
468 sim_hw_parse (sd
, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
469 sim_hw_parse (sd
, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
470 sim_hw_parse (sd
, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
476 /* end-sanitize-tx3904 */
479 /* check for/establish the a reference program image */
480 if (sim_analyze_program (sd
,
481 (STATE_PROG_ARGV (sd
) != NULL
482 ? *STATE_PROG_ARGV (sd
)
486 sim_module_uninstall (sd
);
490 /* Configure/verify the target byte order and other runtime
491 configuration options */
492 if (sim_config (sd
) != SIM_RC_OK
)
494 sim_module_uninstall (sd
);
498 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
500 /* Uninstall the modules to avoid memory leaks,
501 file descriptor leaks, etc. */
502 sim_module_uninstall (sd
);
506 /* verify assumptions the simulator made about the host type system.
507 This macro does not return if there is a problem */
508 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
509 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
511 /* This is NASTY, in that we are assuming the size of specific
515 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
518 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
519 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ NR_FGR
)))
520 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
521 else if ((rn
>= 33) && (rn
<= 37))
522 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
523 else if ((rn
== SRIDX
)
526 || ((rn
>= 72) && (rn
<= 89)))
527 cpu
->register_widths
[rn
] = 32;
529 cpu
->register_widths
[rn
] = 0;
531 /* start-sanitize-r5900 */
533 /* set the 5900 "upper" registers to 64 bits */
534 for( rn
= LAST_EMBED_REGNUM
+1; rn
< NUM_REGS
; rn
++)
535 cpu
->register_widths
[rn
] = 64;
536 /* end-sanitize-r5900 */
538 /* start-sanitize-sky */
540 /* Now the VU registers */
541 for( rn
= 0; rn
< NUM_VU_INTEGER_REGS
; rn
++ ) {
542 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 16;
543 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 16;
546 for( rn
= NUM_VU_INTEGER_REGS
; rn
< NUM_VU_REGS
; rn
++ ) {
547 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
548 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 32;
551 /* Finally the VIF registers */
552 for( rn
= 2*NUM_VU_REGS
; rn
< 2*NUM_VU_REGS
+ 2*NUM_VIF_REGS
; rn
++ )
553 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
557 /* end-sanitize-sky */
561 if (STATE
& simTRACE
)
565 /* Write an abort sequence into the TRAP (common) exception vector
566 addresses. This is to catch code executing a TRAP (et.al.)
567 instruction without installing a trap handler. */
569 unsigned32 halt
[2] = { 0x2404002f /* addiu r4, r0, 47 */,
570 HALT_INSTRUCTION
/* BREAK */ };
573 sim_write (sd
, 0x80000180, (char *) halt
, sizeof (halt
));
574 sim_write (sd
, 0xBFC00380, (char *) halt
, sizeof (halt
));
578 /* Write the monitor trap address handlers into the monitor (eeprom)
579 address space. This can only be done once the target endianness
580 has been determined. */
583 /* Entry into the IDT monitor is via fixed address vectors, and
584 not using machine instructions. To avoid clashing with use of
585 the MIPS TRAP system, we place our own (simulator specific)
586 "undefined" instructions into the relevant vector slots. */
587 for (loop
= 0; (loop
< MONITOR_SIZE
); loop
+= 4)
589 address_word vaddr
= (MONITOR_BASE
+ loop
);
590 unsigned32 insn
= (RSVD_INSTRUCTION
| (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
) << RSVD_INSTRUCTION_ARG_SHIFT
));
592 sim_write (sd
, vaddr
, (char *)&insn
, sizeof (insn
));
594 /* The PMON monitor uses the same address space, but rather than
595 branching into it the address of a routine is loaded. We can
596 cheat for the moment, and direct the PMON routine to IDT style
597 instructions within the monitor space. This relies on the IDT
598 monitor not using the locations from 0xBFC00500 onwards as its
600 for (loop
= 0; (loop
< 24); loop
++)
602 address_word vaddr
= (MONITOR_BASE
+ 0x500 + (loop
* 4));
603 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
619 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
621 case 8: /* cliexit */
624 case 11: /* flush_cache */
628 /* FIXME - should monitor_base be SIM_ADDR?? */
629 value
= ((unsigned int)MONITOR_BASE
+ (value
* 8));
631 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
633 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
635 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
647 tracefh
= fopen(tracefile
,"wb+");
650 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
657 sim_close (sd
, quitting
)
662 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
665 /* "quitting" is non-zero if we cannot hang on errors */
667 /* Ensure that any resources allocated through the callback
668 mechanism are released: */
669 sim_io_shutdown (sd
);
672 if (tracefh
!= NULL
&& tracefh
!= stderr
)
677 /* FIXME - free SD */
684 sim_write (sd
,addr
,buffer
,size
)
687 unsigned char *buffer
;
691 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
693 /* Return the number of bytes written, or zero if error. */
695 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
698 /* We use raw read and write routines, since we do not want to count
699 the GDB memory accesses in our statistics gathering. */
701 for (index
= 0; index
< size
; index
++)
703 address_word vaddr
= (address_word
)addr
+ index
;
706 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
708 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
716 sim_read (sd
,addr
,buffer
,size
)
719 unsigned char *buffer
;
723 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
725 /* Return the number of bytes read, or zero if error. */
727 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
730 for (index
= 0; (index
< size
); index
++)
732 address_word vaddr
= (address_word
)addr
+ index
;
735 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isLOAD
, &paddr
, &cca
, isRAW
))
737 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
745 sim_store_register (sd
,rn
,memory
,length
)
748 unsigned char *memory
;
751 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
752 /* NOTE: gdb (the client) stores registers in target byte order
753 while the simulator uses host byte order */
755 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
758 /* Unfortunately this suffers from the same problem as the register
759 numbering one. We need to know what the width of each logical
760 register number is for the architecture being simulated. */
762 if (cpu
->register_widths
[rn
] == 0)
764 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
768 /* start-sanitize-r5900 */
769 if (rn
>= 90 && rn
< 90 + 32)
771 GPR1
[rn
- 90] = T2H_8 (*(unsigned64
*)memory
);
777 SA
= T2H_8(*(unsigned64
*)memory
);
779 case 122: /* FIXME */
780 LO1
= T2H_8(*(unsigned64
*)memory
);
782 case 123: /* FIXME */
783 HI1
= T2H_8(*(unsigned64
*)memory
);
786 /* end-sanitize-r5900 */
788 /* start-sanitize-sky */
790 if (rn
>= NUM_R5900_REGS
)
792 rn
= rn
- NUM_R5900_REGS
;
794 if( rn
< NUM_VU_REGS
)
796 if (rn
< NUM_VU_INTEGER_REGS
)
797 return write_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
798 else if (rn
>= FIRST_VEC_REG
)
801 return write_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
&3,
804 else switch (rn
- NUM_VU_INTEGER_REGS
)
807 return write_vu_special_reg (&vu0_device
, VU_REG_CIA
,
810 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
812 case 2: /* VU0 has no P register */
815 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
818 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
821 return write_vu_acc_reg (&(vu0_device
.regs
),
822 rn
- (NUM_VU_INTEGER_REGS
+ 5),
827 rn
= rn
- NUM_VU_REGS
;
829 if (rn
< NUM_VU_REGS
)
831 if (rn
< NUM_VU_INTEGER_REGS
)
832 return write_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
833 else if (rn
>= FIRST_VEC_REG
)
836 return write_vu_vec_reg (&(vu1_device
.regs
),
837 rn
>> 2, rn
& 3, memory
);
839 else switch (rn
- NUM_VU_INTEGER_REGS
)
842 return write_vu_special_reg (&vu1_device
, VU_REG_CIA
,
845 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MR
,
848 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MP
,
851 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MI
,
854 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MQ
,
857 return write_vu_acc_reg (&(vu1_device
.regs
),
858 rn
- (NUM_VU_INTEGER_REGS
+ 5),
863 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
865 if (rn
< NUM_VIF_REGS
)
867 if (rn
< NUM_VIF_REGS
-1)
868 return write_pke_reg (&pke0_device
, rn
, memory
);
871 sim_io_eprintf( sd
, "Can't write vif0_pc (store ignored)\n" );
876 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
878 if (rn
< NUM_VIF_REGS
)
880 if (rn
< NUM_VIF_REGS
-1)
881 return write_pke_reg (&pke1_device
, rn
, memory
);
884 sim_io_eprintf( sd
, "Can't write vif1_pc (store ignored)\n" );
889 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
893 /* end-sanitize-sky */
895 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
897 if (cpu
->register_widths
[rn
] == 32)
899 cpu
->fgr
[rn
- FGRIDX
] = T2H_4 (*(unsigned32
*)memory
);
904 cpu
->fgr
[rn
- FGRIDX
] = T2H_8 (*(unsigned64
*)memory
);
909 if (cpu
->register_widths
[rn
] == 32)
911 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
916 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
924 sim_fetch_register (sd
,rn
,memory
,length
)
927 unsigned char *memory
;
930 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
931 /* NOTE: gdb (the client) stores registers in target byte order
932 while the simulator uses host byte order */
934 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
937 if (cpu
->register_widths
[rn
] == 0)
939 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
943 /* start-sanitize-r5900 */
944 if (rn
>= 90 && rn
< 90 + 32)
946 *((unsigned64
*)memory
) = H2T_8 (GPR1
[rn
- 90]);
952 *((unsigned64
*)memory
) = H2T_8(SA
);
954 case 122: /* FIXME */
955 *((unsigned64
*)memory
) = H2T_8(LO1
);
957 case 123: /* FIXME */
958 *((unsigned64
*)memory
) = H2T_8(HI1
);
961 /* end-sanitize-r5900 */
963 /* start-sanitize-sky */
965 if (rn
>= NUM_R5900_REGS
)
967 rn
= rn
- NUM_R5900_REGS
;
969 if (rn
< NUM_VU_REGS
)
971 if (rn
< NUM_VU_INTEGER_REGS
)
972 return read_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
973 else if (rn
>= FIRST_VEC_REG
)
976 return read_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
& 3,
979 else switch (rn
- NUM_VU_INTEGER_REGS
)
982 return read_vu_special_reg(&vu0_device
, VU_REG_CIA
, memory
);
984 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
986 case 2: /* VU0 has no P register */
987 *((int *) memory
) = 0;
990 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
993 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
996 return read_vu_acc_reg (&(vu0_device
.regs
),
997 rn
- (NUM_VU_INTEGER_REGS
+ 5),
1002 rn
-= NUM_VU_REGS
; /* VU1 registers are next */
1004 if (rn
< NUM_VU_REGS
)
1006 if (rn
< NUM_VU_INTEGER_REGS
)
1007 return read_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
1008 else if (rn
>= FIRST_VEC_REG
)
1010 rn
-= FIRST_VEC_REG
;
1011 return read_vu_vec_reg (&(vu1_device
.regs
),
1012 rn
>> 2, rn
& 3, memory
);
1014 else switch (rn
- NUM_VU_INTEGER_REGS
)
1017 return read_vu_special_reg(&vu1_device
, VU_REG_CIA
, memory
);
1019 return read_vu_misc_reg (&(vu1_device
.regs
),
1022 return read_vu_misc_reg (&(vu1_device
.regs
),
1025 return read_vu_misc_reg (&(vu1_device
.regs
),
1028 return read_vu_misc_reg (&(vu1_device
.regs
),
1031 return read_vu_acc_reg (&(vu1_device
.regs
),
1032 rn
- (NUM_VU_INTEGER_REGS
+ 5),
1037 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
1039 if (rn
< NUM_VIF_REGS
)
1041 if (rn
< NUM_VIF_REGS
-1)
1042 return read_pke_reg (&pke0_device
, rn
, memory
);
1044 return read_pke_pc (&pke0_device
, memory
);
1047 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
1049 if (rn
< NUM_VIF_REGS
)
1051 if (rn
< NUM_VIF_REGS
-1)
1052 return read_pke_reg (&pke1_device
, rn
, memory
);
1054 return read_pke_pc (&pke1_device
, memory
);
1057 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
1060 /* end-sanitize-sky */
1062 /* Any floating point register */
1063 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
1065 if (cpu
->register_widths
[rn
] == 32)
1067 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGRIDX
]);
1072 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGRIDX
]);
1077 if (cpu
->register_widths
[rn
] == 32)
1079 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
1084 *(unsigned64
*)memory
= H2T_8 ((unsigned64
)(cpu
->registers
[rn
]));
1093 sim_create_inferior (sd
, abfd
, argv
,env
)
1101 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1109 /* override PC value set by ColdReset () */
1111 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1113 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1114 CIA_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
1118 #if 0 /* def DEBUG */
1121 /* We should really place the argv slot values into the argument
1122 registers, and onto the stack as required. However, this
1123 assumes that we have a stack defined, which is not
1124 necessarily true at the moment. */
1126 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1127 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1128 printf("DBG: arg \"%s\"\n",*cptr
);
1136 sim_do_command (sd
,cmd
)
1140 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1141 sim_io_printf (sd
, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1145 /*---------------------------------------------------------------------------*/
1146 /*-- Private simulator support interface ------------------------------------*/
1147 /*---------------------------------------------------------------------------*/
1149 /* Read a null terminated string from memory, return in a buffer */
1151 fetch_str (sd
, addr
)
1158 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1160 buf
= NZALLOC (char, nr
+ 1);
1161 sim_read (sd
, addr
, buf
, nr
);
1165 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1167 sim_monitor (SIM_DESC sd
,
1170 unsigned int reason
)
1173 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1176 /* The IDT monitor actually allows two instructions per vector
1177 slot. However, the simulator currently causes a trap on each
1178 individual instruction. We cheat, and lose the bottom bit. */
1181 /* The following callback functions are available, however the
1182 monitor we are simulating does not make use of them: get_errno,
1183 isatty, lseek, rename, system, time and unlink */
1187 case 6: /* int open(char *path,int flags) */
1189 char *path
= fetch_str (sd
, A0
);
1190 V0
= sim_io_open (sd
, path
, (int)A1
);
1195 case 7: /* int read(int file,char *ptr,int len) */
1199 char *buf
= zalloc (nr
);
1200 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1201 sim_write (sd
, A1
, buf
, nr
);
1206 case 8: /* int write(int file,char *ptr,int len) */
1210 char *buf
= zalloc (nr
);
1211 sim_read (sd
, A1
, buf
, nr
);
1212 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1217 case 10: /* int close(int file) */
1219 V0
= sim_io_close (sd
, (int)A0
);
1223 case 2: /* Densan monitor: char inbyte(int waitflag) */
1225 if (A0
== 0) /* waitflag == NOWAIT */
1226 V0
= (unsigned_word
)-1;
1228 /* Drop through to case 11 */
1230 case 11: /* char inbyte(void) */
1233 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1235 sim_io_error(sd
,"Invalid return from character read");
1236 V0
= (unsigned_word
)-1;
1239 V0
= (unsigned_word
)tmp
;
1243 case 3: /* Densan monitor: void co(char chr) */
1244 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1246 char tmp
= (char)(A0
& 0xFF);
1247 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1251 case 17: /* void _exit() */
1253 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1254 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1255 (unsigned int)(A0
& 0xFFFFFFFF));
1259 case 28 : /* PMON flush_cache */
1262 case 55: /* void get_mem_info(unsigned int *ptr) */
1263 /* in: A0 = pointer to three word memory location */
1264 /* out: [A0 + 0] = size */
1265 /* [A0 + 4] = instruction cache size */
1266 /* [A0 + 8] = data cache size */
1268 unsigned_4 value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1269 unsigned_4 zero
= 0;
1271 sim_write (sd
, A0
+ 0, (char *)&value
, 4);
1272 sim_write (sd
, A0
+ 4, (char *)&zero
, 4);
1273 sim_write (sd
, A0
+ 8, (char *)&zero
, 4);
1274 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1278 case 158 : /* PMON printf */
1279 /* in: A0 = pointer to format string */
1280 /* A1 = optional argument 1 */
1281 /* A2 = optional argument 2 */
1282 /* A3 = optional argument 3 */
1284 /* The following is based on the PMON printf source */
1286 address_word s
= A0
;
1288 signed_word
*ap
= &A1
; /* 1st argument */
1289 /* This isn't the quickest way, since we call the host print
1290 routine for every character almost. But it does avoid
1291 having to allocate and manage a temporary string buffer. */
1292 /* TODO: Include check that we only use three arguments (A1,
1294 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1299 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1300 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1301 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1303 if (strchr ("dobxXulscefg%", c
))
1318 else if (c
>= '1' && c
<= '9')
1322 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1325 n
= (unsigned int)strtol(tmp
,NULL
,10);
1338 sim_io_printf (sd
, "%%");
1343 address_word p
= *ap
++;
1345 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1346 sim_io_printf(sd
, "%c", ch
);
1349 sim_io_printf(sd
,"(null)");
1352 sim_io_printf (sd
, "%c", (int)*ap
++);
1357 sim_read (sd
, s
++, &c
, 1);
1361 sim_read (sd
, s
++, &c
, 1);
1364 if (strchr ("dobxXu", c
))
1366 word64 lv
= (word64
) *ap
++;
1368 sim_io_printf(sd
,"<binary not supported>");
1371 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1373 sim_io_printf(sd
, tmp
, lv
);
1375 sim_io_printf(sd
, tmp
, (int)lv
);
1378 else if (strchr ("eEfgG", c
))
1380 double dbl
= *(double*)(ap
++);
1381 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1382 sim_io_printf (sd
, tmp
, dbl
);
1388 sim_io_printf(sd
, "%c", c
);
1394 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1395 reason
, pr_addr(cia
));
1401 /* Store a word into memory. */
1404 store_word (SIM_DESC sd
,
1413 if ((vaddr
& 3) != 0)
1414 SignalExceptionAddressStore ();
1417 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1420 const uword64 mask
= 7;
1424 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1425 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1426 memval
= ((uword64
) val
) << (8 * byte
);
1427 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1433 /* Load a word from memory. */
1436 load_word (SIM_DESC sd
,
1441 if ((vaddr
& 3) != 0)
1442 SignalExceptionAddressLoad ();
1448 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1451 const uword64 mask
= 0x7;
1452 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1453 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1457 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1458 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1460 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1461 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1468 /* Simulate the mips16 entry and exit pseudo-instructions. These
1469 would normally be handled by the reserved instruction exception
1470 code, but for ease of simulation we just handle them directly. */
1473 mips16_entry (SIM_DESC sd
,
1478 int aregs
, sregs
, rreg
;
1481 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1484 aregs
= (insn
& 0x700) >> 8;
1485 sregs
= (insn
& 0x0c0) >> 6;
1486 rreg
= (insn
& 0x020) >> 5;
1488 /* This should be checked by the caller. */
1497 /* This is the entry pseudo-instruction. */
1499 for (i
= 0; i
< aregs
; i
++)
1500 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1508 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1511 for (i
= 0; i
< sregs
; i
++)
1514 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1522 /* This is the exit pseudo-instruction. */
1529 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1532 for (i
= 0; i
< sregs
; i
++)
1535 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1540 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1544 FGR
[0] = WORD64LO (GPR
[4]);
1545 FPR_STATE
[0] = fmt_uninterpreted
;
1547 else if (aregs
== 6)
1549 FGR
[0] = WORD64LO (GPR
[5]);
1550 FGR
[1] = WORD64LO (GPR
[4]);
1551 FPR_STATE
[0] = fmt_uninterpreted
;
1552 FPR_STATE
[1] = fmt_uninterpreted
;
1561 /*-- trace support ----------------------------------------------------------*/
1563 /* The TRACE support is provided (if required) in the memory accessing
1564 routines. Since we are also providing the architecture specific
1565 features, the architecture simulation code can also deal with
1566 notifying the TRACE world of cache flushes, etc. Similarly we do
1567 not need to provide profiling support in the simulator engine,
1568 since we can sample in the instruction fetch control loop. By
1569 defining the TRACE manifest, we add tracing as a run-time
1573 /* Tracing by default produces "din" format (as required by
1574 dineroIII). Each line of such a trace file *MUST* have a din label
1575 and address field. The rest of the line is ignored, so comments can
1576 be included if desired. The first field is the label which must be
1577 one of the following values:
1582 3 escape record (treated as unknown access type)
1583 4 escape record (causes cache flush)
1585 The address field is a 32bit (lower-case) hexadecimal address
1586 value. The address should *NOT* be preceded by "0x".
1588 The size of the memory transfer is not important when dealing with
1589 cache lines (as long as no more than a cache line can be
1590 transferred in a single operation :-), however more information
1591 could be given following the dineroIII requirement to allow more
1592 complete memory and cache simulators to provide better
1593 results. i.e. the University of Pisa has a cache simulator that can
1594 also take bus size and speed as (variable) inputs to calculate
1595 complete system performance (a much more useful ability when trying
1596 to construct an end product, rather than a processor). They
1597 currently have an ARM version of their tool called ChARM. */
1601 dotrace (SIM_DESC sd
,
1609 if (STATE
& simTRACE
) {
1611 fprintf(tracefh
,"%d %s ; width %d ; ",
1615 va_start(ap
,comment
);
1616 vfprintf(tracefh
,comment
,ap
);
1618 fprintf(tracefh
,"\n");
1620 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1621 we may be generating 64bit ones, we should put the hi-32bits of the
1622 address into the comment field. */
1624 /* TODO: Provide a buffer for the trace lines. We can then avoid
1625 performing writes until the buffer is filled, or the file is
1628 /* NOTE: We could consider adding a comment field to the "din" file
1629 produced using type 3 markers (unknown access). This would then
1630 allow information about the program that the "din" is for, and
1631 the MIPs world that was being simulated, to be placed into the
1638 /*---------------------------------------------------------------------------*/
1639 /*-- simulator engine -------------------------------------------------------*/
1640 /*---------------------------------------------------------------------------*/
1643 ColdReset (SIM_DESC sd
)
1646 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1648 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1649 /* RESET: Fixed PC address: */
1650 PC
= (unsigned_word
) UNSIGNED64 (0xFFFFFFFFBFC00000);
1651 /* The reset vector address is in the unmapped, uncached memory space. */
1653 SR
&= ~(status_SR
| status_TS
| status_RP
);
1654 SR
|= (status_ERL
| status_BEV
);
1656 /* Cheat and allow access to the complete register set immediately */
1657 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1658 && WITH_TARGET_WORD_BITSIZE
== 64)
1659 SR
|= status_FR
; /* 64bit registers */
1661 /* Ensure that any instructions with pending register updates are
1663 PENDING_INVALIDATE();
1665 /* Initialise the FPU registers to the unknown state */
1666 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1669 for (rn
= 0; (rn
< 32); rn
++)
1670 FPR_STATE
[rn
] = fmt_uninterpreted
;
1676 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1677 /* Signal an exception condition. This will result in an exception
1678 that aborts the instruction. The instruction operation pseudocode
1679 will never see a return from this function call. */
1682 signal_exception (SIM_DESC sd
,
1690 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1693 /* Ensure that any active atomic read/modify/write operation will fail: */
1696 switch (exception
) {
1698 case DebugBreakPoint
:
1699 if (! (Debug
& Debug_DM
))
1705 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1706 DEPC
= cia
- 4; /* reference the branch instruction */
1710 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1714 Debug
|= Debug_DM
; /* in debugging mode */
1715 Debug
|= Debug_DBp
; /* raising a DBp exception */
1717 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1721 case ReservedInstruction
:
1724 unsigned int instruction
;
1725 va_start(ap
,exception
);
1726 instruction
= va_arg(ap
,unsigned int);
1728 /* Provide simple monitor support using ReservedInstruction
1729 exceptions. The following code simulates the fixed vector
1730 entry points into the IDT monitor by causing a simulator
1731 trap, performing the monitor operation, and returning to
1732 the address held in the $ra register (standard PCS return
1733 address). This means we only need to pre-load the vector
1734 space with suitable instruction values. For systems were
1735 actual trap instructions are used, we would not need to
1736 perform this magic. */
1737 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1739 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
1740 /* NOTE: This assumes that a branch-and-link style
1741 instruction was used to enter the vector (which is the
1742 case with the current IDT monitor). */
1743 sim_engine_restart (SD
, CPU
, NULL
, RA
);
1745 /* Look for the mips16 entry and exit instructions, and
1746 simulate a handler for them. */
1747 else if ((cia
& 1) != 0
1748 && (instruction
& 0xf81f) == 0xe809
1749 && (instruction
& 0x0c0) != 0x0c0)
1751 mips16_entry (SD
, CPU
, cia
, instruction
);
1752 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1754 /* else fall through to normal exception processing */
1755 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
1759 /* Store exception code into current exception id variable (used
1762 /* TODO: If not simulating exceptions then stop the simulator
1763 execution. At the moment we always stop the simulation. */
1765 #ifdef SUBTARGET_R3900
1766 /* update interrupt-related registers */
1768 /* insert exception code in bits 6:2 */
1769 CAUSE
= LSMASKED32(CAUSE
, 31, 7) | LSINSERTED32(exception
, 6, 2);
1770 /* shift IE/KU history bits left */
1771 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 3, 0), 5, 2);
1773 if (STATE
& simDELAYSLOT
)
1775 STATE
&= ~simDELAYSLOT
;
1777 EPC
= (cia
- 4); /* reference the branch instruction */
1782 if (SR
& status_BEV
)
1783 PC
= (signed)0xBFC00000 + 0x180;
1785 PC
= (signed)0x80000000 + 0x080;
1787 /* See figure 5-17 for an outline of the code below */
1788 if (! (SR
& status_EXL
))
1790 CAUSE
= (exception
<< 2);
1791 if (STATE
& simDELAYSLOT
)
1793 STATE
&= ~simDELAYSLOT
;
1795 EPC
= (cia
- 4); /* reference the branch instruction */
1799 /* FIXME: TLB et.al. */
1800 /* vector = 0x180; */
1804 CAUSE
= (exception
<< 2);
1805 /* vector = 0x180; */
1808 /* Store exception code into current exception id variable (used
1811 if (SR
& status_BEV
)
1812 PC
= (signed)0xBFC00200 + 0x180;
1814 PC
= (signed)0x80000000 + 0x180;
1817 switch ((CAUSE
>> 2) & 0x1F)
1820 /* Interrupts arrive during event processing, no need to
1826 #ifdef SUBTARGET_3900
1827 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1828 PC
= (signed)0xBFC00000;
1829 #endif SUBTARGET_3900
1832 case TLBModification
:
1837 case InstructionFetch
:
1839 /* The following is so that the simulator will continue from the
1840 exception address on breakpoint operations. */
1842 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1843 sim_stopped
, SIM_SIGBUS
);
1845 case ReservedInstruction
:
1846 case CoProcessorUnusable
:
1848 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1849 sim_stopped
, SIM_SIGILL
);
1851 case IntegerOverflow
:
1853 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1854 sim_stopped
, SIM_SIGFPE
);
1859 sim_engine_restart (SD
, CPU
, NULL
, PC
);
1864 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1865 sim_stopped
, SIM_SIGTRAP
);
1867 default : /* Unknown internal exception */
1869 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1870 sim_stopped
, SIM_SIGABRT
);
1874 case SimulatorFault
:
1878 va_start(ap
,exception
);
1879 msg
= va_arg(ap
,char *);
1881 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1882 "FATAL: Simulator error \"%s\"\n",msg
);
1889 #if defined(WARN_RESULT)
1890 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1891 /* This function indicates that the result of the operation is
1892 undefined. However, this should not affect the instruction
1893 stream. All that is meant to happen is that the destination
1894 register is set to an undefined result. To keep the simulator
1895 simple, we just don't bother updating the destination register, so
1896 the overall result will be undefined. If desired we can stop the
1897 simulator by raising a pseudo-exception. */
1898 #define UndefinedResult() undefined_result (sd,cia)
1900 undefined_result(sd
,cia
)
1904 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
1905 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
1910 #endif /* WARN_RESULT */
1912 /*-- FPU support routines ---------------------------------------------------*/
1914 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
1915 formats conform to ANSI/IEEE Std 754-1985. */
1916 /* SINGLE precision floating:
1917 * seeeeeeeefffffffffffffffffffffff
1919 * e = 8bits = exponent
1920 * f = 23bits = fraction
1922 /* SINGLE precision fixed:
1923 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1925 * i = 31bits = integer
1927 /* DOUBLE precision floating:
1928 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
1930 * e = 11bits = exponent
1931 * f = 52bits = fraction
1933 /* DOUBLE precision fixed:
1934 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1936 * i = 63bits = integer
1939 /* Extract sign-bit: */
1940 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
1941 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
1942 /* Extract biased exponent: */
1943 #define FP_S_be(v) (((v) >> 23) & 0xFF)
1944 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
1945 /* Extract unbiased Exponent: */
1946 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
1947 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
1948 /* Extract complete fraction field: */
1949 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
1950 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
1951 /* Extract numbered fraction bit: */
1952 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
1953 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
1955 /* Explicit QNaN values used when value required: */
1956 #define FPQNaN_SINGLE (0x7FBFFFFF)
1957 #define FPQNaN_WORD (0x7FFFFFFF)
1958 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
1959 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
1961 /* Explicit Infinity values used when required: */
1962 #define FPINF_SINGLE (0x7F800000)
1963 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
1965 #if 1 /* def DEBUG */
1966 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
1967 #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>"))))))
1971 value_fpr (SIM_DESC sd
,
1980 /* Treat unused register values, as fixed-point 64bit values: */
1981 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
1983 /* If request to read data as "uninterpreted", then use the current
1985 fmt
= FPR_STATE
[fpr
];
1990 /* For values not yet accessed, set to the desired format: */
1991 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
1992 FPR_STATE
[fpr
] = fmt
;
1994 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
1997 if (fmt
!= FPR_STATE
[fpr
]) {
1998 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
));
1999 FPR_STATE
[fpr
] = fmt_unknown
;
2002 if (FPR_STATE
[fpr
] == fmt_unknown
) {
2003 /* Set QNaN value: */
2006 value
= FPQNaN_SINGLE
;
2010 value
= FPQNaN_DOUBLE
;
2014 value
= FPQNaN_WORD
;
2018 value
= FPQNaN_LONG
;
2025 } else if (SizeFGR() == 64) {
2029 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2032 case fmt_uninterpreted
:
2046 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2049 case fmt_uninterpreted
:
2052 if ((fpr
& 1) == 0) { /* even registers only */
2053 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
2055 SignalException(ReservedInstruction
,0);
2066 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2069 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());
2076 store_fpr (SIM_DESC sd
,
2086 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());
2089 if (SizeFGR() == 64) {
2091 case fmt_uninterpreted_32
:
2092 fmt
= fmt_uninterpreted
;
2095 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2096 FPR_STATE
[fpr
] = fmt
;
2099 case fmt_uninterpreted_64
:
2100 fmt
= fmt_uninterpreted
;
2101 case fmt_uninterpreted
:
2105 FPR_STATE
[fpr
] = fmt
;
2109 FPR_STATE
[fpr
] = fmt_unknown
;
2115 case fmt_uninterpreted_32
:
2116 fmt
= fmt_uninterpreted
;
2119 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2120 FPR_STATE
[fpr
] = fmt
;
2123 case fmt_uninterpreted_64
:
2124 fmt
= fmt_uninterpreted
;
2125 case fmt_uninterpreted
:
2128 if ((fpr
& 1) == 0) { /* even register number only */
2129 FGR
[fpr
+1] = (value
>> 32);
2130 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2131 FPR_STATE
[fpr
+ 1] = fmt
;
2132 FPR_STATE
[fpr
] = fmt
;
2134 FPR_STATE
[fpr
] = fmt_unknown
;
2135 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2136 SignalException(ReservedInstruction
,0);
2141 FPR_STATE
[fpr
] = fmt_unknown
;
2146 #if defined(WARN_RESULT)
2149 #endif /* WARN_RESULT */
2152 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2155 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_addr(FGR
[fpr
]),DOFMT(fmt
));
2172 sim_fpu_32to (&wop
, op
);
2173 boolean
= sim_fpu_is_nan (&wop
);
2180 sim_fpu_64to (&wop
, op
);
2181 boolean
= sim_fpu_is_nan (&wop
);
2185 fprintf (stderr
, "Bad switch\n");
2190 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2204 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2211 sim_fpu_32to (&wop
, op
);
2212 boolean
= sim_fpu_is_infinity (&wop
);
2218 sim_fpu_64to (&wop
, op
);
2219 boolean
= sim_fpu_is_infinity (&wop
);
2223 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2228 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2242 /* Argument checking already performed by the FPCOMPARE code */
2245 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2248 /* The format type should already have been checked: */
2254 sim_fpu_32to (&wop1
, op1
);
2255 sim_fpu_32to (&wop2
, op2
);
2256 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2263 sim_fpu_64to (&wop1
, op1
);
2264 sim_fpu_64to (&wop2
, op2
);
2265 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2269 fprintf (stderr
, "Bad switch\n");
2274 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2288 /* Argument checking already performed by the FPCOMPARE code */
2291 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2294 /* The format type should already have been checked: */
2300 sim_fpu_32to (&wop1
, op1
);
2301 sim_fpu_32to (&wop2
, op2
);
2302 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2309 sim_fpu_64to (&wop1
, op1
);
2310 sim_fpu_64to (&wop2
, op2
);
2311 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2315 fprintf (stderr
, "Bad switch\n");
2320 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2327 AbsoluteValue(op
,fmt
)
2334 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2337 /* The format type should already have been checked: */
2343 sim_fpu_32to (&wop
, op
);
2344 sim_fpu_abs (&wop
, &wop
);
2345 sim_fpu_to32 (&ans
, &wop
);
2353 sim_fpu_64to (&wop
, op
);
2354 sim_fpu_abs (&wop
, &wop
);
2355 sim_fpu_to64 (&ans
, &wop
);
2360 fprintf (stderr
, "Bad switch\n");
2375 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2378 /* The format type should already have been checked: */
2384 sim_fpu_32to (&wop
, op
);
2385 sim_fpu_neg (&wop
, &wop
);
2386 sim_fpu_to32 (&ans
, &wop
);
2394 sim_fpu_64to (&wop
, op
);
2395 sim_fpu_neg (&wop
, &wop
);
2396 sim_fpu_to64 (&ans
, &wop
);
2401 fprintf (stderr
, "Bad switch\n");
2417 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2420 /* The registers must specify FPRs valid for operands of type
2421 "fmt". If they are not valid, the result is undefined. */
2423 /* The format type should already have been checked: */
2431 sim_fpu_32to (&wop1
, op1
);
2432 sim_fpu_32to (&wop2
, op2
);
2433 sim_fpu_add (&ans
, &wop1
, &wop2
);
2434 sim_fpu_to32 (&res
, &ans
);
2444 sim_fpu_64to (&wop1
, op1
);
2445 sim_fpu_64to (&wop2
, op2
);
2446 sim_fpu_add (&ans
, &wop1
, &wop2
);
2447 sim_fpu_to64 (&res
, &ans
);
2452 fprintf (stderr
, "Bad switch\n");
2457 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2472 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2475 /* The registers must specify FPRs valid for operands of type
2476 "fmt". If they are not valid, the result is undefined. */
2478 /* The format type should already have been checked: */
2486 sim_fpu_32to (&wop1
, op1
);
2487 sim_fpu_32to (&wop2
, op2
);
2488 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2489 sim_fpu_to32 (&res
, &ans
);
2499 sim_fpu_64to (&wop1
, op1
);
2500 sim_fpu_64to (&wop2
, op2
);
2501 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2502 sim_fpu_to64 (&res
, &ans
);
2507 fprintf (stderr
, "Bad switch\n");
2512 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2519 Multiply(op1
,op2
,fmt
)
2527 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2530 /* The registers must specify FPRs valid for operands of type
2531 "fmt". If they are not valid, the result is undefined. */
2533 /* The format type should already have been checked: */
2541 sim_fpu_32to (&wop1
, op1
);
2542 sim_fpu_32to (&wop2
, op2
);
2543 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2544 sim_fpu_to32 (&res
, &ans
);
2554 sim_fpu_64to (&wop1
, op1
);
2555 sim_fpu_64to (&wop2
, op2
);
2556 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2557 sim_fpu_to64 (&res
, &ans
);
2562 fprintf (stderr
, "Bad switch\n");
2567 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2582 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2585 /* The registers must specify FPRs valid for operands of type
2586 "fmt". If they are not valid, the result is undefined. */
2588 /* The format type should already have been checked: */
2596 sim_fpu_32to (&wop1
, op1
);
2597 sim_fpu_32to (&wop2
, op2
);
2598 sim_fpu_div (&ans
, &wop1
, &wop2
);
2599 sim_fpu_to32 (&res
, &ans
);
2609 sim_fpu_64to (&wop1
, op1
);
2610 sim_fpu_64to (&wop2
, op2
);
2611 sim_fpu_div (&ans
, &wop1
, &wop2
);
2612 sim_fpu_to64 (&res
, &ans
);
2617 fprintf (stderr
, "Bad switch\n");
2622 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2636 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2639 /* The registers must specify FPRs valid for operands of type
2640 "fmt". If they are not valid, the result is undefined. */
2642 /* The format type should already have been checked: */
2649 sim_fpu_32to (&wop
, op
);
2650 sim_fpu_inv (&ans
, &wop
);
2651 sim_fpu_to32 (&res
, &ans
);
2660 sim_fpu_64to (&wop
, op
);
2661 sim_fpu_inv (&ans
, &wop
);
2662 sim_fpu_to64 (&res
, &ans
);
2667 fprintf (stderr
, "Bad switch\n");
2672 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2686 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2689 /* The registers must specify FPRs valid for operands of type
2690 "fmt". If they are not valid, the result is undefined. */
2692 /* The format type should already have been checked: */
2699 sim_fpu_32to (&wop
, op
);
2700 sim_fpu_sqrt (&ans
, &wop
);
2701 sim_fpu_to32 (&res
, &ans
);
2710 sim_fpu_64to (&wop
, op
);
2711 sim_fpu_sqrt (&ans
, &wop
);
2712 sim_fpu_to64 (&res
, &ans
);
2717 fprintf (stderr
, "Bad switch\n");
2722 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2738 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2741 /* The registers must specify FPRs valid for operands of type
2742 "fmt". If they are not valid, the result is undefined. */
2744 /* The format type should already have been checked: */
2751 sim_fpu_32to (&wop1
, op1
);
2752 sim_fpu_32to (&wop2
, op2
);
2753 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2760 sim_fpu_64to (&wop1
, op1
);
2761 sim_fpu_64to (&wop2
, op2
);
2762 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2766 fprintf (stderr
, "Bad switch\n");
2772 case SIM_FPU_IS_SNAN
:
2773 case SIM_FPU_IS_QNAN
:
2775 case SIM_FPU_IS_NINF
:
2776 case SIM_FPU_IS_NNUMBER
:
2777 case SIM_FPU_IS_NDENORM
:
2778 case SIM_FPU_IS_NZERO
:
2779 result
= op2
; /* op1 - op2 < 0 */
2780 case SIM_FPU_IS_PINF
:
2781 case SIM_FPU_IS_PNUMBER
:
2782 case SIM_FPU_IS_PDENORM
:
2783 case SIM_FPU_IS_PZERO
:
2784 result
= op1
; /* op1 - op2 > 0 */
2786 fprintf (stderr
, "Bad switch\n");
2791 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2808 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2811 /* The registers must specify FPRs valid for operands of type
2812 "fmt". If they are not valid, the result is undefined. */
2814 /* The format type should already have been checked: */
2821 sim_fpu_32to (&wop1
, op1
);
2822 sim_fpu_32to (&wop2
, op2
);
2823 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2830 sim_fpu_64to (&wop1
, op1
);
2831 sim_fpu_64to (&wop2
, op2
);
2832 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2836 fprintf (stderr
, "Bad switch\n");
2842 case SIM_FPU_IS_SNAN
:
2843 case SIM_FPU_IS_QNAN
:
2845 case SIM_FPU_IS_NINF
:
2846 case SIM_FPU_IS_NNUMBER
:
2847 case SIM_FPU_IS_NDENORM
:
2848 case SIM_FPU_IS_NZERO
:
2849 result
= op1
; /* op1 - op2 < 0 */
2850 case SIM_FPU_IS_PINF
:
2851 case SIM_FPU_IS_PNUMBER
:
2852 case SIM_FPU_IS_PDENORM
:
2853 case SIM_FPU_IS_PZERO
:
2854 result
= op2
; /* op1 - op2 > 0 */
2856 fprintf (stderr
, "Bad switch\n");
2861 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2869 convert (SIM_DESC sd
,
2878 sim_fpu_round round
;
2879 unsigned32 result32
;
2880 unsigned64 result64
;
2883 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
));
2889 /* Round result to nearest representable value. When two
2890 representable values are equally near, round to the value
2891 that has a least significant bit of zero (i.e. is even). */
2892 round
= sim_fpu_round_near
;
2895 /* Round result to the value closest to, and not greater in
2896 magnitude than, the result. */
2897 round
= sim_fpu_round_zero
;
2900 /* Round result to the value closest to, and not less than,
2902 round
= sim_fpu_round_up
;
2906 /* Round result to the value closest to, and not greater than,
2908 round
= sim_fpu_round_down
;
2912 fprintf (stderr
, "Bad switch\n");
2916 /* Convert the input to sim_fpu internal format */
2920 sim_fpu_64to (&wop
, op
);
2923 sim_fpu_32to (&wop
, op
);
2926 sim_fpu_i32to (&wop
, op
, round
);
2929 sim_fpu_i64to (&wop
, op
, round
);
2932 fprintf (stderr
, "Bad switch\n");
2936 /* Convert sim_fpu format into the output */
2937 /* The value WOP is converted to the destination format, rounding
2938 using mode RM. When the destination is a fixed-point format, then
2939 a source value of Infinity, NaN or one which would round to an
2940 integer outside the fixed point range then an IEEE Invalid
2941 Operation condition is raised. */
2945 sim_fpu_round_32 (&wop
, round
, 0);
2946 sim_fpu_to32 (&result32
, &wop
);
2947 result64
= result32
;
2950 sim_fpu_round_64 (&wop
, round
, 0);
2951 sim_fpu_to64 (&result64
, &wop
);
2954 sim_fpu_to32i (&result32
, &wop
, round
);
2955 result64
= result32
;
2958 sim_fpu_to64i (&result64
, &wop
, round
);
2962 fprintf (stderr
, "Bad switch\n");
2967 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
2974 /*-- co-processor support routines ------------------------------------------*/
2977 CoProcPresent(coproc_number
)
2978 unsigned int coproc_number
;
2980 /* Return TRUE if simulator provides a model for the given co-processor number */
2985 cop_lw (SIM_DESC sd
,
2990 unsigned int memword
)
2995 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2998 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
3000 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
3001 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
3006 #if 0 /* this should be controlled by a configuration option */
3007 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
));
3016 cop_ld (SIM_DESC sd
,
3023 switch (coproc_num
) {
3025 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3027 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
3032 #if 0 /* this message should be controlled by a configuration option */
3033 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
));
3042 /* start-sanitize-sky */
3045 cop_lq (SIM_DESC sd
,
3050 unsigned128 memword
)
3061 /* one word at a time, argh! */
3065 value
= H2T_4(*A4_16(& memword
, 3-i
));
3066 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3072 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3073 coproc_num
,coproc_reg
,pr_addr(cia
));
3079 #endif /* TARGET_SKY */
3080 /* end-sanitize-sky */
3084 cop_sw (SIM_DESC sd
,
3090 unsigned int value
= 0;
3095 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3098 hold
= FPR_STATE
[coproc_reg
];
3099 FPR_STATE
[coproc_reg
] = fmt_word
;
3100 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3101 FPR_STATE
[coproc_reg
] = hold
;
3106 #if 0 /* should be controlled by configuration option */
3107 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3116 cop_sd (SIM_DESC sd
,
3126 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3128 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3133 #if 0 /* should be controlled by configuration option */
3134 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3143 /* start-sanitize-sky */
3146 cop_sq (SIM_DESC sd
,
3152 unsigned128 value
= U16_8(0, 0);
3163 /* one word at a time, argh! */
3167 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3168 *A4_16(& xyzw
, 3-i
) = T2H_4(value
);
3175 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3176 coproc_num
,coproc_reg
,pr_addr(cia
));
3182 #endif /* TARGET_SKY */
3183 /* end-sanitize-sky */
3187 decode_coproc (SIM_DESC sd
,
3190 unsigned int instruction
)
3192 int coprocnum
= ((instruction
>> 26) & 3);
3196 case 0: /* standard CPU control and cache registers */
3198 int code
= ((instruction
>> 21) & 0x1F);
3199 /* R4000 Users Manual (second edition) lists the following CP0
3201 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3202 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3203 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3204 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3205 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3206 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3207 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3208 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3209 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3210 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3212 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0))
3214 int rt
= ((instruction
>> 16) & 0x1F);
3215 int rd
= ((instruction
>> 11) & 0x1F);
3217 switch (rd
) /* NOTEs: Standard CP0 registers */
3219 /* 0 = Index R4000 VR4100 VR4300 */
3220 /* 1 = Random R4000 VR4100 VR4300 */
3221 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3222 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3223 /* 4 = Context R4000 VR4100 VR4300 */
3224 /* 5 = PageMask R4000 VR4100 VR4300 */
3225 /* 6 = Wired R4000 VR4100 VR4300 */
3226 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3227 /* 9 = Count R4000 VR4100 VR4300 */
3228 /* 10 = EntryHi R4000 VR4100 VR4300 */
3229 /* 11 = Compare R4000 VR4100 VR4300 */
3230 /* 12 = SR R4000 VR4100 VR4300 */
3231 #ifdef SUBTARGET_R3900
3235 /* 3 = Config R3900 */
3240 /* 3 = Cache R3900 */
3242 #endif /* SUBTARGET_R3900 */
3249 /* 13 = Cause R4000 VR4100 VR4300 */
3256 /* 14 = EPC R4000 VR4100 VR4300 */
3259 GPR
[rt
] = (signed_word
) (signed_address
) EPC
;
3263 /* 15 = PRId R4000 VR4100 VR4300 */
3264 #ifdef SUBTARGET_R3900
3273 /* 16 = Config R4000 VR4100 VR4300 */
3276 GPR
[rt
] = C0_CONFIG
;
3278 C0_CONFIG
= GPR
[rt
];
3281 #ifdef SUBTARGET_R3900
3290 /* 17 = LLAddr R4000 VR4100 VR4300 */
3292 /* 18 = WatchLo R4000 VR4100 VR4300 */
3293 /* 19 = WatchHi R4000 VR4100 VR4300 */
3294 /* 20 = XContext R4000 VR4100 VR4300 */
3295 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3296 /* 27 = CacheErr R4000 VR4100 */
3297 /* 28 = TagLo R4000 VR4100 VR4300 */
3298 /* 29 = TagHi R4000 VR4100 VR4300 */
3299 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3300 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3301 /* CPR[0,rd] = GPR[rt]; */
3304 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3306 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3309 else if (code
== 0x10 && (instruction
& 0x3f) == 0x18)
3312 if (SR
& status_ERL
)
3314 /* Oops, not yet available */
3315 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3325 else if (code
== 0x10 && (instruction
& 0x3f) == 0x10)
3328 #ifdef SUBTARGET_R3900
3329 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
3331 /* shift IE/KU history bits right */
3332 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 5, 2), 3, 0);
3334 /* TODO: CACHE register */
3335 #endif /* SUBTARGET_R3900 */
3337 else if (code
== 0x10 && (instruction
& 0x3f) == 0x1F)
3345 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3346 /* TODO: When executing an ERET or RFE instruction we should
3347 clear LLBIT, to ensure that any out-standing atomic
3348 read/modify/write sequence fails. */
3352 case 2: /* co-processor 2 */
3356 /* start-sanitize-sky */
3358 /* On the R5900, this refers to a "VU" vector co-processor. */
3360 int i_25_21
= (instruction
>> 21) & 0x1f;
3361 int i_20_16
= (instruction
>> 16) & 0x1f;
3362 int i_20_6
= (instruction
>> 6) & 0x7fff;
3363 int i_15_11
= (instruction
>> 11) & 0x1f;
3364 int i_15_0
= instruction
& 0xffff;
3365 int i_10_1
= (instruction
>> 1) & 0x3ff;
3366 int i_10_0
= instruction
& 0x7ff;
3367 int i_10_6
= (instruction
>> 6) & 0x1f;
3368 int i_5_0
= instruction
& 0x03f;
3369 int interlock
= instruction
& 0x01;
3370 /* setup for semantic.c-like actions below */
3371 typedef unsigned_4 instruction_word
;
3377 /* test COP2 usability */
3378 if(! (SR
& status_CU2
))
3380 SignalException(CoProcessorUnusable
,instruction
);
3384 #define MY_INDEX itable_COPz_NORMAL
3385 #define MY_PREFIX COPz_NORMAL
3386 #define MY_NAME "COPz_NORMAL"
3388 /* classify & execute basic COP2 instructions */
3389 if(i_25_21
== 0x08 && i_20_16
== 0x00) /* BC2F */
3391 address_word offset
= EXTEND16(i_15_0
) << 2;
3392 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3394 else if(i_25_21
== 0x08 && i_20_16
==0x02) /* BC2FL */
3396 address_word offset
= EXTEND16(i_15_0
) << 2;
3397 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3398 else NULLIFY_NEXT_INSTRUCTION();
3400 else if(i_25_21
== 0x08 && i_20_16
== 0x01) /* BC2T */
3402 address_word offset
= EXTEND16(i_15_0
) << 2;
3403 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3405 else if(i_25_21
== 0x08 && i_20_16
== 0x03) /* BC2TL */
3407 address_word offset
= EXTEND16(i_15_0
) << 2;
3408 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3409 else NULLIFY_NEXT_INSTRUCTION();
3411 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3412 (i_25_21
== 0x01)) /* QMFC2 */
3417 /* interlock checking */
3418 /* POLICY: never busy in macro mode */
3419 while(vu0_busy() && interlock
)
3422 /* perform VU register address */
3423 if(i_25_21
== 0x01) /* QMFC2 */
3426 /* one word at a time, argh! */
3427 read_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3428 read_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3429 read_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3430 read_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3431 GPR
[rt
] = T2H_8(* A8_16(& xyzw
, 1));
3432 GPR1
[rt
] = T2H_8(* A8_16(& xyzw
, 0));
3437 /* enum + int calculation, argh! */
3438 id
= VU_REG_MST
+ 16 * id
;
3439 if (id
>= VU_REG_CMSAR0
)
3440 read_vu_special_reg(&vu0_device
, id
, & data
);
3442 read_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3443 GPR
[rt
] = EXTEND32(T2H_4(data
));
3446 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3447 (i_25_21
== 0x05)) /* QMTC2 */
3452 /* interlock checking: wait until M or E bits set */
3453 /* POLICY: never busy in macro mode */
3454 while(vu0_busy() && interlock
)
3456 if(vu0_micro_interlock_released())
3458 vu0_micro_interlock_clear();
3465 /* perform VU register address */
3466 if(i_25_21
== 0x05) /* QMTC2 */
3468 unsigned_16 xyzw
= U16_8(GPR1
[rt
], GPR
[rt
]);
3470 xyzw
= H2T_16(xyzw
);
3471 /* one word at a time, argh! */
3472 write_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3473 write_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3474 write_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3475 write_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3479 unsigned_4 data
= H2T_4(GPR
[rt
]);
3480 /* enum + int calculation, argh! */
3481 id
= VU_REG_VI
+ 16 * id
;
3482 if (id
>= VU_REG_CMSAR0
)
3483 write_vu_special_reg(&vu0_device
, id
, & data
);
3485 write_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3488 else if(i_10_0
== 0x3bf) /* VWAITQ */
3493 else if(i_5_0
== 0x38) /* VCALLMS */
3495 unsigned_4 data
= H2T_2(i_20_6
);
3500 /* write to reserved CIA register to get VU0 moving */
3501 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3505 else if(i_5_0
== 0x39) /* VCALLMSR */
3512 read_vu_special_reg(& vu0_device
, VU_REG_CMSAR0
, & data
);
3513 /* write to reserved CIA register to get VU0 moving */
3514 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3518 /* handle all remaining UPPER VU instructions in one block */
3519 else if((i_5_0
< 0x30) || /* VADDx .. VMINI */
3520 (i_5_0
>= 0x3c && i_10_6
< 0x0c)) /* VADDAx .. VNOP */
3522 unsigned_4 vu_upper
, vu_lower
;
3524 0x00000000 | /* bits 31 .. 25 */
3525 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3526 vu_lower
= 0x8000033c; /* NOP */
3528 /* POLICY: never busy in macro mode */
3532 vu0_macro_issue(vu_upper
, vu_lower
);
3534 /* POLICY: wait for completion of macro-instruction */
3538 /* handle all remaining LOWER VU instructions in one block */
3539 else if((i_5_0
>= 0x30 && i_5_0
<= 0x35) || /* VIADD .. VIOR */
3540 (i_5_0
>= 0x3c && i_10_6
>= 0x0c)) /* VMOVE .. VRXOR */
3541 { /* N.B.: VWAITQ already covered by prior case */
3542 unsigned_4 vu_upper
, vu_lower
;
3543 vu_upper
= 0x000002ff; /* NOP/NOP */
3545 0x80000000 | /* bits 31 .. 25 */
3546 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3548 /* POLICY: never busy in macro mode */
3552 vu0_macro_issue(vu_upper
, vu_lower
);
3554 /* POLICY: wait for completion of macro-instruction */
3558 /* ... no other COP2 instructions ... */
3561 SignalException(ReservedInstruction
, instruction
);
3565 /* cleanup for semantic.c-like actions above */
3572 #endif /* TARGET_SKY */
3573 /* end-sanitize-sky */
3577 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3578 instruction
,pr_addr(cia
));
3583 case 1: /* should not occur (FPU co-processor) */
3584 case 3: /* should not occur (FPU co-processor) */
3585 SignalException(ReservedInstruction
,instruction
);
3593 /*-- instruction simulation -------------------------------------------------*/
3595 /* When the IGEN simulator is being built, the function below is be
3596 replaced by a generated version. However, WITH_IGEN == 2 indicates
3597 that the fubction below should be compiled but under a different
3598 name (to allow backward compatibility) */
3600 #if (WITH_IGEN != 1)
3602 void old_engine_run
PARAMS ((SIM_DESC sd
, int next_cpu_nr
, int siggnal
));
3604 old_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3607 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3610 int next_cpu_nr
; /* ignore */
3611 int nr_cpus
; /* ignore */
3612 int siggnal
; /* ignore */
3614 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* hardwire to cpu 0 */
3615 #if !defined(FASTSIM)
3616 unsigned int pipeline_count
= 1;
3620 if (STATE_MEMORY (sd
) == NULL
) {
3621 printf("DBG: simulate() entered with no memory\n");
3626 #if 0 /* Disabled to check that everything works OK */
3627 /* The VR4300 seems to sign-extend the PC on its first
3628 access. However, this may just be because it is currently
3629 configured in 32bit mode. However... */
3630 PC
= SIGNEXTEND(PC
,32);
3633 /* main controlling loop */
3635 /* vaddr is slowly being replaced with cia - current instruction
3637 address_word cia
= (uword64
)PC
;
3638 address_word vaddr
= cia
;
3641 unsigned int instruction
; /* uword64? what's this used for? FIXME! */
3645 printf("DBG: state = 0x%08X :",state
);
3646 if (state
& simHALTEX
) printf(" simHALTEX");
3647 if (state
& simHALTIN
) printf(" simHALTIN");
3652 DSSTATE
= (STATE
& simDELAYSLOT
);
3655 sim_io_printf(sd
,"DBG: DSPC = 0x%s\n",pr_addr(DSPC
));
3658 /* Fetch the next instruction from the simulator memory: */
3659 if (AddressTranslation(cia
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) {
3660 if ((vaddr
& 1) == 0) {
3661 /* Copy the action of the LW instruction */
3662 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3663 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3666 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3667 LoadMemory(&value
,NULL
,cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3668 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3669 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3671 /* Copy the action of the LH instruction */
3672 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 1) : 0);
3673 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 1) : 0);
3676 paddr
= (((paddr
& ~ (uword64
) 1) & ~LOADDRMASK
)
3677 | (((paddr
& ~ (uword64
) 1) & LOADDRMASK
) ^ (reverse
<< 1)));
3678 LoadMemory(&value
,NULL
,cca
, AccessLength_HALFWORD
,
3679 paddr
& ~ (uword64
) 1,
3680 vaddr
, isINSTRUCTION
, isREAL
);
3681 byte
= (((vaddr
&~ (uword64
) 1) & LOADDRMASK
) ^ (bigend
<< 1));
3682 instruction
= ((value
>> (8 * byte
)) & 0xFFFF);
3685 fprintf(stderr
,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC
));
3690 sim_io_printf(sd
,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction
,pr_addr(PC
));
3693 /* This is required by exception processing, to ensure that we can
3694 cope with exceptions in the delay slots of branches that may
3695 already have changed the PC. */
3696 if ((vaddr
& 1) == 0)
3697 PC
+= 4; /* increment ready for the next fetch */
3700 /* NOTE: If we perform a delay slot change to the PC, this
3701 increment is not requuired. However, it would make the
3702 simulator more complicated to try and avoid this small hit. */
3704 /* Currently this code provides a simple model. For more
3705 complicated models we could perform exception status checks at
3706 this point, and set the simSTOP state as required. This could
3707 also include processing any hardware interrupts raised by any
3708 I/O model attached to the simulator context.
3710 Support for "asynchronous" I/O events within the simulated world
3711 could be providing by managing a counter, and calling a I/O
3712 specific handler when a particular threshold is reached. On most
3713 architectures a decrement and check for zero operation is
3714 usually quicker than an increment and compare. However, the
3715 process of managing a known value decrement to zero, is higher
3716 than the cost of using an explicit value UINT_MAX into the
3717 future. Which system is used will depend on how complicated the
3718 I/O model is, and how much it is likely to affect the simulator
3721 If events need to be scheduled further in the future than
3722 UINT_MAX event ticks, then the I/O model should just provide its
3723 own counter, triggered from the event system. */
3725 /* MIPS pipeline ticks. To allow for future support where the
3726 pipeline hit of individual instructions is known, this control
3727 loop manages a "pipeline_count" variable. It is initialised to
3728 1 (one), and will only be changed by the simulator engine when
3729 executing an instruction. If the engine does not have access to
3730 pipeline cycle count information then all instructions will be
3731 treated as using a single cycle. NOTE: A standard system is not
3732 provided by the default simulator because different MIPS
3733 architectures have different cycle counts for the same
3736 [NOTE: pipeline_count has been replaced the event queue] */
3738 /* shuffle the floating point status pipeline state */
3739 ENGINE_ISSUE_PREFIX_HOOK();
3741 /* NOTE: For multi-context simulation environments the "instruction"
3742 variable should be local to this routine. */
3744 /* Shorthand accesses for engine. Note: If we wanted to use global
3745 variables (and a single-threaded simulator engine), then we can
3746 create the actual variables with these names. */
3748 if (!(STATE
& simSKIPNEXT
)) {
3749 /* Include the simulator engine */
3750 #include "oengine.c"
3751 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3752 #error "Mismatch between run-time simulator code and simulation engine"
3754 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3755 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3757 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3758 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3761 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3762 should check for it being changed. It is better doing it here,
3763 than within the simulator, since it will help keep the simulator
3766 #if defined(WARN_ZERO)
3767 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
));
3768 #endif /* WARN_ZERO */
3769 ZERO
= 0; /* reset back to zero before next instruction */
3771 } else /* simSKIPNEXT check */
3772 STATE
&= ~simSKIPNEXT
;
3774 /* If the delay slot was active before the instruction is
3775 executed, then update the PC to its new value: */
3778 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC
));
3787 #if !defined(FASTSIM)
3788 if (sim_events_tickn (sd
, pipeline_count
))
3790 /* cpu->cia = cia; */
3791 sim_events_process (sd
);
3794 if (sim_events_tick (sd
))
3796 /* cpu->cia = cia; */
3797 sim_events_process (sd
);
3799 #endif /* FASTSIM */
3805 /* This code copied from gdb's utils.c. Would like to share this code,
3806 but don't know of a common place where both could get to it. */
3808 /* Temporary storage using circular buffer */
3814 static char buf
[NUMCELLS
][CELLSIZE
];
3816 if (++cell
>=NUMCELLS
) cell
=0;
3820 /* Print routines to handle variable size regs, etc */
3822 /* Eliminate warning from compiler on 32-bit systems */
3823 static int thirty_two
= 32;
3829 char *paddr_str
=get_cell();
3830 switch (sizeof(addr
))
3833 sprintf(paddr_str
,"%08lx%08lx",
3834 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3837 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
3840 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
3843 sprintf(paddr_str
,"%x",addr
);
3852 char *paddr_str
=get_cell();
3853 sprintf(paddr_str
,"%08lx%08lx",
3854 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3860 /*---------------------------------------------------------------------------*/
3861 /*> EOF interp.c <*/