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"
48 #include "sky-gpuif.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 /* The following reserved instruction value is used when a simulator
114 halt is required. NOTE: Care must be taken, since this value may
115 be used in later revisions of the MIPS ISA. */
116 #define HALT_INSTRUCTION (0x03ff000d)
117 #define HALT_INSTRUCTION2 (0x0000ffcd)
118 #define HALT_INSTRUCTION_MASK (0x03FFFFC0)
121 /* Bits in the Debug register */
122 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
123 #define Debug_DM 0x40000000 /* Debug Mode */
124 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
130 /*---------------------------------------------------------------------------*/
131 /*-- GDB simulator interface ------------------------------------------------*/
132 /*---------------------------------------------------------------------------*/
134 static void ColdReset
PARAMS((SIM_DESC sd
));
136 /*---------------------------------------------------------------------------*/
140 #define DELAYSLOT() {\
141 if (STATE & simDELAYSLOT)\
142 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
143 STATE |= simDELAYSLOT;\
146 #define JALDELAYSLOT() {\
148 STATE |= simJALDELAYSLOT;\
152 STATE &= ~simDELAYSLOT;\
153 STATE |= simSKIPNEXT;\
156 #define CANCELDELAYSLOT() {\
158 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
161 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
162 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
164 #define K0BASE (0x80000000)
165 #define K0SIZE (0x20000000)
166 #define K1BASE (0xA0000000)
167 #define K1SIZE (0x20000000)
168 #define MONITOR_BASE (0xBFC00000)
169 #define MONITOR_SIZE (1 << 11)
170 #define MEM_SIZE (2 << 20)
172 /* start-sanitize-sky */
175 #define MEM_SIZE (16 << 20) /* 16 MB */
177 /* end-sanitize-sky */
180 static char *tracefile
= "trace.din"; /* default filename for trace log */
181 FILE *tracefh
= NULL
;
182 static void open_trace
PARAMS((SIM_DESC sd
));
185 /* simulation target board. NULL=canonical */
186 static char* board
= NULL
;
189 static DECLARE_OPTION_HANDLER (mips_option_handler
);
192 OPTION_DINERO_TRACE
= OPTION_START
,
194 /* start-sanitize-sky */
203 /* end-sanitize-sky */
209 mips_option_handler (sd
, cpu
, opt
, arg
, is_command
)
219 case OPTION_DINERO_TRACE
: /* ??? */
221 /* Eventually the simTRACE flag could be treated as a toggle, to
222 allow external control of the program points being traced
223 (i.e. only from main onwards, excluding the run-time setup,
225 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
227 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
230 else if (strcmp (arg
, "yes") == 0)
232 else if (strcmp (arg
, "no") == 0)
234 else if (strcmp (arg
, "on") == 0)
236 else if (strcmp (arg
, "off") == 0)
240 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
247 Simulator constructed without dinero tracing support (for performance).\n\
248 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
252 case OPTION_DINERO_FILE
:
254 if (optarg
!= NULL
) {
256 tmp
= (char *)malloc(strlen(optarg
) + 1);
259 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
265 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
271 /* start-sanitize-sky */
274 case OPTION_FLOAT_TYPE
:
275 /* Use host (fast) or target (accurate) floating point implementation. */
276 if (arg
&& strcmp (arg
, "fast") == 0)
277 STATE_FP_TYPE_OPT (sd
) &= ~STATE_FP_TYPE_OPT_ACCURATE
;
278 else if (arg
&& strcmp (arg
, "accurate") == 0)
279 STATE_FP_TYPE_OPT (sd
) |= STATE_FP_TYPE_OPT_ACCURATE
;
282 fprintf (stderr
, "Unrecognized float-type option `%s'\n", arg
);
285 /*printf ("float-type=0x%08x\n", STATE_FP_TYPE_OPT (sd));*/
289 case OPTION_GS_ENABLE
:
290 /* Enable GS libraries. */
291 if ( arg
&& strcmp (arg
, "on") == 0 )
292 gif_options (&GIF_full
,GIF_OPT_GS_ENABLE
,1,0,0);
293 else if ( arg
&& strcmp (arg
, "off") == 0 )
294 gif_options (&GIF_full
,GIF_OPT_GS_ENABLE
,0,0,0);
297 fprintf (stderr
, "Unrecognized enable-gs option `%s'\n", arg
);
302 case OPTION_GS_REFRESH1
:
303 case OPTION_GS_REFRESH2
:
305 /* The GS has defineable register and register values. */
306 unsigned_4 address
[2];
310 if ( arg
&& strlen (arg
) == 59 && arg
[10] == '=' &&
311 arg
[29] == ':' && arg
[40] == '=' &&
312 ( sscanf (arg
,"%lx%c%Lx%c%lx%c%Lx", &address
[0],&c
[0],&value
[0],
313 &c
[1],&address
[1],&c
[2],&value
[1]) == 7 ))
315 gif_options (&GIF_full
, ( opt
== OPTION_GS_REFRESH1
) ?
316 GIF_OPT_GS_REFRESH1
:GIF_OPT_GS_REFRESH2
,
317 0,&address
[0],&value
[0]);
321 fprintf (stderr
, "Unrecognized gs-refresh option `%s'\n", arg
);
328 /* end-sanitize-sky */
334 board
= zalloc(strlen(arg
) + 1);
345 static const OPTION mips_options
[] =
347 { {"dinero-trace", optional_argument
, NULL
, OPTION_DINERO_TRACE
},
348 '\0', "on|off", "Enable dinero tracing",
349 mips_option_handler
},
350 { {"dinero-file", required_argument
, NULL
, OPTION_DINERO_FILE
},
351 '\0', "FILE", "Write dinero trace to FILE",
352 mips_option_handler
},
353 /* start-sanitize-sky */
356 { {"float-type", required_argument
, NULL
, OPTION_FLOAT_TYPE
},
357 '\0', "fast|accurate", "Use fast (host) or accurate (target) floating point",
358 mips_option_handler
},
360 { {"enable-gs", required_argument
, NULL
, OPTION_GS_ENABLE
},
361 '\0', "on|off", "Enable GS library routines",
362 mips_option_handler
},
363 { {"gs-refresh1", required_argument
, NULL
, OPTION_GS_REFRESH1
},
364 '\0', "0xaddress0=0xvalue0:0xaddress1=0xvalue1", "GS refresh buffer 1 addresses and values",
365 mips_option_handler
},
366 { {"gs-refresh2", required_argument
, NULL
, OPTION_GS_REFRESH2
},
367 '\0', "0xaddress0=0xvalue0:0xaddress1=0xvalue1", "GS refresh buffer 2 addresses and values",
368 mips_option_handler
},
370 /* end-sanitize-sky */
372 { {"board", required_argument
, NULL
, OPTION_BOARD
},
373 '\0', "none" /* rely on compile-time string concatenation for other options */
375 /* start-sanitize-tx3904 */
376 #define BOARD_JMR3904 "jmr3904"
378 #define BOARD_JMR3904_DEBUG "jmr3904debug"
379 "|" BOARD_JMR3904_DEBUG
380 /* end-sanitize-tx3904 */
382 , "Customize simulation for a particular board.", mips_option_handler
},
384 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
388 int interrupt_pending
;
391 interrupt_event (SIM_DESC sd
, void *data
)
393 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
394 address_word cia
= CIA_GET (cpu
);
397 interrupt_pending
= 0;
398 SignalExceptionInterrupt ();
400 else if (!interrupt_pending
)
401 sim_events_schedule (sd
, 1, interrupt_event
, data
);
405 /*---------------------------------------------------------------------------*/
406 /*-- Device registration hook -----------------------------------------------*/
407 /*---------------------------------------------------------------------------*/
408 static void device_init(SIM_DESC sd
) {
410 extern void register_devices(SIM_DESC
);
411 register_devices(sd
);
415 /*---------------------------------------------------------------------------*/
416 /*-- GDB simulator interface ------------------------------------------------*/
417 /*---------------------------------------------------------------------------*/
420 sim_open (kind
, cb
, abfd
, argv
)
426 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
427 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
429 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
430 /* start-sanitize-sky */
432 #if defined(TARGET_SKY) && defined(SKY_FUNIT)
433 /* Set "--float-type fast" as the default. */
434 STATE_FP_TYPE_OPT (sd
) &= ~STATE_FP_TYPE_OPT_ACCURATE
;
436 /* end-sanitize-sky */
438 /* FIXME: watchpoints code shouldn't need this */
439 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
440 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
441 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
445 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
447 sim_add_option_table (sd
, NULL
, mips_options
);
449 /* getopt will print the error message so we just have to exit if this fails.
450 FIXME: Hmmm... in the case of gdb we need getopt to call
452 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
454 /* Uninstall the modules to avoid memory leaks,
455 file descriptor leaks, etc. */
456 sim_module_uninstall (sd
);
460 /* handle board-specific memory maps */
463 /* Allocate core managed memory */
465 /* start-sanitize-sky */
467 /* end-sanitize-sky */
469 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
, MONITOR_SIZE
);
470 /* For compatibility with the old code - under this (at level one)
471 are the kernel spaces K0 & K1. Both of these map to a single
472 smaller sub region */
473 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
474 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
476 MEM_SIZE
, /* actual size */
478 /* start-sanitize-sky */
481 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
- K1BASE
, MONITOR_SIZE
);
482 sim_do_command (sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
483 /* 16M @ 0x0. Aliases at 0x80000000 and 0xA0000000 are handled by
484 address_translation() */
485 sim_do_commandf (sd
, "memory size 0x%lx", MEM_SIZE
);
487 /* end-sanitize-sky */
492 /* start-sanitize-tx3904 */
495 && (strcmp(board
, BOARD_JMR3904
) == 0 ||
496 strcmp(board
, BOARD_JMR3904_DEBUG
) == 0))
498 /* match VIRTUAL memory layout of JMR-TX3904 board */
502 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
503 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
505 4 * 1024 * 1024, /* 4 MB */
508 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
509 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
511 4 * 1024 * 1024, /* 4 MB */
514 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
515 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
517 32 * 1024 * 1024, /* 32 MB */
520 /* --- simulated devices --- */
521 sim_hw_parse (sd
, "/tx3904irc@0xffffc00/reg 0xffffc000 0x20");
522 sim_hw_parse (sd
, "/tx3904cpu");
524 /* -- device connections --- */
525 sim_hw_parse (sd
, "/tx3904irc > ip level /tx3904cpu");
527 if(! strcmp(board
, BOARD_JMR3904_DEBUG
))
529 /* -- DEBUG: glue interrupt generators --- */
530 sim_hw_parse (sd
, "/glue@0xffff0000/reg 0xffff0000 0x50");
531 sim_hw_parse (sd
, "/glue@0xffff0000 > int0 int0 /tx3904irc");
532 sim_hw_parse (sd
, "/glue@0xffff0000 > int1 int1 /tx3904irc");
533 sim_hw_parse (sd
, "/glue@0xffff0000 > int2 int2 /tx3904irc");
534 sim_hw_parse (sd
, "/glue@0xffff0000 > int3 int3 /tx3904irc");
535 sim_hw_parse (sd
, "/glue@0xffff0000 > int4 int4 /tx3904irc");
536 sim_hw_parse (sd
, "/glue@0xffff0000 > int5 int5 /tx3904irc");
537 sim_hw_parse (sd
, "/glue@0xffff0000 > int6 int6 /tx3904irc");
538 sim_hw_parse (sd
, "/glue@0xffff0000 > int7 int7 /tx3904irc");
539 sim_hw_parse (sd
, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
540 sim_hw_parse (sd
, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
541 sim_hw_parse (sd
, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
542 sim_hw_parse (sd
, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
543 sim_hw_parse (sd
, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
544 sim_hw_parse (sd
, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
545 sim_hw_parse (sd
, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
546 sim_hw_parse (sd
, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
547 sim_hw_parse (sd
, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
548 sim_hw_parse (sd
, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
554 /* end-sanitize-tx3904 */
557 /* check for/establish the a reference program image */
558 if (sim_analyze_program (sd
,
559 (STATE_PROG_ARGV (sd
) != NULL
560 ? *STATE_PROG_ARGV (sd
)
564 sim_module_uninstall (sd
);
568 /* Configure/verify the target byte order and other runtime
569 configuration options */
570 if (sim_config (sd
) != SIM_RC_OK
)
572 sim_module_uninstall (sd
);
576 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
578 /* Uninstall the modules to avoid memory leaks,
579 file descriptor leaks, etc. */
580 sim_module_uninstall (sd
);
584 /* verify assumptions the simulator made about the host type system.
585 This macro does not return if there is a problem */
586 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
587 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
589 /* This is NASTY, in that we are assuming the size of specific
593 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
596 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
597 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ NR_FGR
)))
598 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
599 else if ((rn
>= 33) && (rn
<= 37))
600 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
601 else if ((rn
== SRIDX
)
604 || ((rn
>= 72) && (rn
<= 89)))
605 cpu
->register_widths
[rn
] = 32;
607 cpu
->register_widths
[rn
] = 0;
609 /* start-sanitize-r5900 */
611 /* set the 5900 "upper" registers to 64 bits */
612 for( rn
= LAST_EMBED_REGNUM
+1; rn
< NUM_REGS
; rn
++)
613 cpu
->register_widths
[rn
] = 64;
614 /* end-sanitize-r5900 */
616 /* start-sanitize-sky */
618 /* Now the VU registers */
619 for( rn
= 0; rn
< NUM_VU_INTEGER_REGS
; rn
++ ) {
620 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 16;
621 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 16;
624 for( rn
= NUM_VU_INTEGER_REGS
; rn
< NUM_VU_REGS
; rn
++ ) {
625 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
626 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 32;
629 /* Finally the VIF registers */
630 for( rn
= 2*NUM_VU_REGS
; rn
< 2*NUM_VU_REGS
+ 2*NUM_VIF_REGS
; rn
++ )
631 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
635 /* end-sanitize-sky */
639 if (STATE
& simTRACE
)
643 /* Write an abort sequence into the TRAP (common) exception vector
644 addresses. This is to catch code executing a TRAP (et.al.)
645 instruction without installing a trap handler. */
647 unsigned32 halt
[2] = { 0x2404002f /* addiu r4, r0, 47 */,
648 HALT_INSTRUCTION
/* BREAK */ };
651 sim_write (sd
, 0x80000180, (char *) halt
, sizeof (halt
));
652 sim_write (sd
, 0xBFC00380, (char *) halt
, sizeof (halt
));
656 /* Write the monitor trap address handlers into the monitor (eeprom)
657 address space. This can only be done once the target endianness
658 has been determined. */
661 /* Entry into the IDT monitor is via fixed address vectors, and
662 not using machine instructions. To avoid clashing with use of
663 the MIPS TRAP system, we place our own (simulator specific)
664 "undefined" instructions into the relevant vector slots. */
665 for (loop
= 0; (loop
< MONITOR_SIZE
); loop
+= 4)
667 address_word vaddr
= (MONITOR_BASE
+ loop
);
668 unsigned32 insn
= (RSVD_INSTRUCTION
| (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
) << RSVD_INSTRUCTION_ARG_SHIFT
));
670 sim_write (sd
, vaddr
, (char *)&insn
, sizeof (insn
));
672 /* The PMON monitor uses the same address space, but rather than
673 branching into it the address of a routine is loaded. We can
674 cheat for the moment, and direct the PMON routine to IDT style
675 instructions within the monitor space. This relies on the IDT
676 monitor not using the locations from 0xBFC00500 onwards as its
678 for (loop
= 0; (loop
< 24); loop
++)
680 address_word vaddr
= (MONITOR_BASE
+ 0x500 + (loop
* 4));
681 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
697 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
699 case 8: /* cliexit */
702 case 11: /* flush_cache */
706 /* FIXME - should monitor_base be SIM_ADDR?? */
707 value
= ((unsigned int)MONITOR_BASE
+ (value
* 8));
709 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
711 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
713 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
725 tracefh
= fopen(tracefile
,"wb+");
728 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
735 sim_close (sd
, quitting
)
740 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
743 /* "quitting" is non-zero if we cannot hang on errors */
745 /* Ensure that any resources allocated through the callback
746 mechanism are released: */
747 sim_io_shutdown (sd
);
750 if (tracefh
!= NULL
&& tracefh
!= stderr
)
755 /* FIXME - free SD */
762 sim_write (sd
,addr
,buffer
,size
)
765 unsigned char *buffer
;
769 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
771 /* Return the number of bytes written, or zero if error. */
773 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
776 /* We use raw read and write routines, since we do not want to count
777 the GDB memory accesses in our statistics gathering. */
779 for (index
= 0; index
< size
; index
++)
781 address_word vaddr
= (address_word
)addr
+ index
;
784 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
786 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
794 sim_read (sd
,addr
,buffer
,size
)
797 unsigned char *buffer
;
801 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
803 /* Return the number of bytes read, or zero if error. */
805 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
808 for (index
= 0; (index
< size
); index
++)
810 address_word vaddr
= (address_word
)addr
+ index
;
813 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isLOAD
, &paddr
, &cca
, isRAW
))
815 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
823 sim_store_register (sd
,rn
,memory
,length
)
826 unsigned char *memory
;
829 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
830 /* NOTE: gdb (the client) stores registers in target byte order
831 while the simulator uses host byte order */
833 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
836 /* Unfortunately this suffers from the same problem as the register
837 numbering one. We need to know what the width of each logical
838 register number is for the architecture being simulated. */
840 if (cpu
->register_widths
[rn
] == 0)
842 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
846 /* start-sanitize-r5900 */
847 if (rn
>= 90 && rn
< 90 + 32)
849 GPR1
[rn
- 90] = T2H_8 (*(unsigned64
*)memory
);
855 SA
= T2H_8(*(unsigned64
*)memory
);
857 case 122: /* FIXME */
858 LO1
= T2H_8(*(unsigned64
*)memory
);
860 case 123: /* FIXME */
861 HI1
= T2H_8(*(unsigned64
*)memory
);
864 /* end-sanitize-r5900 */
866 /* start-sanitize-sky */
868 if (rn
>= NUM_R5900_REGS
)
870 rn
= rn
- NUM_R5900_REGS
;
872 if( rn
< NUM_VU_REGS
)
874 if (rn
< NUM_VU_INTEGER_REGS
)
875 return write_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
876 else if (rn
>= FIRST_VEC_REG
)
879 return write_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
&3,
882 else switch (rn
- NUM_VU_INTEGER_REGS
)
885 return write_vu_special_reg (&vu0_device
, VU_REG_CIA
,
888 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
890 case 2: /* VU0 has no P register */
893 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
896 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
899 return write_vu_acc_reg (&(vu0_device
.regs
),
900 rn
- (NUM_VU_INTEGER_REGS
+ 5),
905 rn
= rn
- NUM_VU_REGS
;
907 if (rn
< NUM_VU_REGS
)
909 if (rn
< NUM_VU_INTEGER_REGS
)
910 return write_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
911 else if (rn
>= FIRST_VEC_REG
)
914 return write_vu_vec_reg (&(vu1_device
.regs
),
915 rn
>> 2, rn
& 3, memory
);
917 else switch (rn
- NUM_VU_INTEGER_REGS
)
920 return write_vu_special_reg (&vu1_device
, VU_REG_CIA
,
923 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MR
,
926 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MP
,
929 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MI
,
932 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MQ
,
935 return write_vu_acc_reg (&(vu1_device
.regs
),
936 rn
- (NUM_VU_INTEGER_REGS
+ 5),
941 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
943 if (rn
< NUM_VIF_REGS
)
945 if (rn
< NUM_VIF_REGS
-1)
946 return write_pke_reg (&pke0_device
, rn
, memory
);
949 sim_io_eprintf( sd
, "Can't write vif0_pc (store ignored)\n" );
954 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
956 if (rn
< NUM_VIF_REGS
)
958 if (rn
< NUM_VIF_REGS
-1)
959 return write_pke_reg (&pke1_device
, rn
, memory
);
962 sim_io_eprintf( sd
, "Can't write vif1_pc (store ignored)\n" );
967 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
971 /* end-sanitize-sky */
973 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
975 if (cpu
->register_widths
[rn
] == 32)
977 cpu
->fgr
[rn
- FGRIDX
] = T2H_4 (*(unsigned32
*)memory
);
982 cpu
->fgr
[rn
- FGRIDX
] = T2H_8 (*(unsigned64
*)memory
);
987 if (cpu
->register_widths
[rn
] == 32)
989 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
994 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
1002 sim_fetch_register (sd
,rn
,memory
,length
)
1005 unsigned char *memory
;
1008 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
1009 /* NOTE: gdb (the client) stores registers in target byte order
1010 while the simulator uses host byte order */
1012 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
1015 if (cpu
->register_widths
[rn
] == 0)
1017 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
1021 /* start-sanitize-r5900 */
1022 if (rn
>= 90 && rn
< 90 + 32)
1024 *((unsigned64
*)memory
) = H2T_8 (GPR1
[rn
- 90]);
1030 *((unsigned64
*)memory
) = H2T_8(SA
);
1032 case 122: /* FIXME */
1033 *((unsigned64
*)memory
) = H2T_8(LO1
);
1035 case 123: /* FIXME */
1036 *((unsigned64
*)memory
) = H2T_8(HI1
);
1039 /* end-sanitize-r5900 */
1041 /* start-sanitize-sky */
1043 if (rn
>= NUM_R5900_REGS
)
1045 rn
= rn
- NUM_R5900_REGS
;
1047 if (rn
< NUM_VU_REGS
)
1049 if (rn
< NUM_VU_INTEGER_REGS
)
1050 return read_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
1051 else if (rn
>= FIRST_VEC_REG
)
1053 rn
-= FIRST_VEC_REG
;
1054 return read_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
& 3,
1057 else switch (rn
- NUM_VU_INTEGER_REGS
)
1060 return read_vu_special_reg(&vu0_device
, VU_REG_CIA
, memory
);
1062 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
1064 case 2: /* VU0 has no P register */
1065 *((int *) memory
) = 0;
1068 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
1071 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
1074 return read_vu_acc_reg (&(vu0_device
.regs
),
1075 rn
- (NUM_VU_INTEGER_REGS
+ 5),
1080 rn
-= NUM_VU_REGS
; /* VU1 registers are next */
1082 if (rn
< NUM_VU_REGS
)
1084 if (rn
< NUM_VU_INTEGER_REGS
)
1085 return read_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
1086 else if (rn
>= FIRST_VEC_REG
)
1088 rn
-= FIRST_VEC_REG
;
1089 return read_vu_vec_reg (&(vu1_device
.regs
),
1090 rn
>> 2, rn
& 3, memory
);
1092 else switch (rn
- NUM_VU_INTEGER_REGS
)
1095 return read_vu_special_reg(&vu1_device
, VU_REG_CIA
, memory
);
1097 return read_vu_misc_reg (&(vu1_device
.regs
),
1100 return read_vu_misc_reg (&(vu1_device
.regs
),
1103 return read_vu_misc_reg (&(vu1_device
.regs
),
1106 return read_vu_misc_reg (&(vu1_device
.regs
),
1109 return read_vu_acc_reg (&(vu1_device
.regs
),
1110 rn
- (NUM_VU_INTEGER_REGS
+ 5),
1115 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
1117 if (rn
< NUM_VIF_REGS
)
1119 if (rn
< NUM_VIF_REGS
-1)
1120 return read_pke_reg (&pke0_device
, rn
, memory
);
1122 return read_pke_pc (&pke0_device
, memory
);
1125 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
1127 if (rn
< NUM_VIF_REGS
)
1129 if (rn
< NUM_VIF_REGS
-1)
1130 return read_pke_reg (&pke1_device
, rn
, memory
);
1132 return read_pke_pc (&pke1_device
, memory
);
1135 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
1138 /* end-sanitize-sky */
1140 /* Any floating point register */
1141 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
1143 if (cpu
->register_widths
[rn
] == 32)
1145 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGRIDX
]);
1150 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGRIDX
]);
1155 if (cpu
->register_widths
[rn
] == 32)
1157 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
1162 *(unsigned64
*)memory
= H2T_8 ((unsigned64
)(cpu
->registers
[rn
]));
1171 sim_create_inferior (sd
, abfd
, argv
,env
)
1179 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1187 /* override PC value set by ColdReset () */
1189 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1191 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1192 CIA_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
1196 #if 0 /* def DEBUG */
1199 /* We should really place the argv slot values into the argument
1200 registers, and onto the stack as required. However, this
1201 assumes that we have a stack defined, which is not
1202 necessarily true at the moment. */
1204 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1205 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1206 printf("DBG: arg \"%s\"\n",*cptr
);
1214 sim_do_command (sd
,cmd
)
1218 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1219 sim_io_printf (sd
, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1223 /*---------------------------------------------------------------------------*/
1224 /*-- Private simulator support interface ------------------------------------*/
1225 /*---------------------------------------------------------------------------*/
1227 /* Read a null terminated string from memory, return in a buffer */
1229 fetch_str (sd
, addr
)
1236 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1238 buf
= NZALLOC (char, nr
+ 1);
1239 sim_read (sd
, addr
, buf
, nr
);
1243 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1245 sim_monitor (SIM_DESC sd
,
1248 unsigned int reason
)
1251 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1254 /* The IDT monitor actually allows two instructions per vector
1255 slot. However, the simulator currently causes a trap on each
1256 individual instruction. We cheat, and lose the bottom bit. */
1259 /* The following callback functions are available, however the
1260 monitor we are simulating does not make use of them: get_errno,
1261 isatty, lseek, rename, system, time and unlink */
1265 case 6: /* int open(char *path,int flags) */
1267 char *path
= fetch_str (sd
, A0
);
1268 V0
= sim_io_open (sd
, path
, (int)A1
);
1273 case 7: /* int read(int file,char *ptr,int len) */
1277 char *buf
= zalloc (nr
);
1278 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1279 sim_write (sd
, A1
, buf
, nr
);
1284 case 8: /* int write(int file,char *ptr,int len) */
1288 char *buf
= zalloc (nr
);
1289 sim_read (sd
, A1
, buf
, nr
);
1290 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1295 case 10: /* int close(int file) */
1297 V0
= sim_io_close (sd
, (int)A0
);
1301 case 2: /* Densan monitor: char inbyte(int waitflag) */
1303 if (A0
== 0) /* waitflag == NOWAIT */
1304 V0
= (unsigned_word
)-1;
1306 /* Drop through to case 11 */
1308 case 11: /* char inbyte(void) */
1311 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1313 sim_io_error(sd
,"Invalid return from character read");
1314 V0
= (unsigned_word
)-1;
1317 V0
= (unsigned_word
)tmp
;
1321 case 3: /* Densan monitor: void co(char chr) */
1322 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1324 char tmp
= (char)(A0
& 0xFF);
1325 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1329 case 17: /* void _exit() */
1331 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1332 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1333 (unsigned int)(A0
& 0xFFFFFFFF));
1337 case 28 : /* PMON flush_cache */
1340 case 55: /* void get_mem_info(unsigned int *ptr) */
1341 /* in: A0 = pointer to three word memory location */
1342 /* out: [A0 + 0] = size */
1343 /* [A0 + 4] = instruction cache size */
1344 /* [A0 + 8] = data cache size */
1346 unsigned_4 value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1347 unsigned_4 zero
= 0;
1349 sim_write (sd
, A0
+ 0, (char *)&value
, 4);
1350 sim_write (sd
, A0
+ 4, (char *)&zero
, 4);
1351 sim_write (sd
, A0
+ 8, (char *)&zero
, 4);
1352 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1356 case 158 : /* PMON printf */
1357 /* in: A0 = pointer to format string */
1358 /* A1 = optional argument 1 */
1359 /* A2 = optional argument 2 */
1360 /* A3 = optional argument 3 */
1362 /* The following is based on the PMON printf source */
1364 address_word s
= A0
;
1366 signed_word
*ap
= &A1
; /* 1st argument */
1367 /* This isn't the quickest way, since we call the host print
1368 routine for every character almost. But it does avoid
1369 having to allocate and manage a temporary string buffer. */
1370 /* TODO: Include check that we only use three arguments (A1,
1372 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1377 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1378 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1379 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1381 if (strchr ("dobxXulscefg%", c
))
1396 else if (c
>= '1' && c
<= '9')
1400 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1403 n
= (unsigned int)strtol(tmp
,NULL
,10);
1416 sim_io_printf (sd
, "%%");
1421 address_word p
= *ap
++;
1423 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1424 sim_io_printf(sd
, "%c", ch
);
1427 sim_io_printf(sd
,"(null)");
1430 sim_io_printf (sd
, "%c", (int)*ap
++);
1435 sim_read (sd
, s
++, &c
, 1);
1439 sim_read (sd
, s
++, &c
, 1);
1442 if (strchr ("dobxXu", c
))
1444 word64 lv
= (word64
) *ap
++;
1446 sim_io_printf(sd
,"<binary not supported>");
1449 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1451 sim_io_printf(sd
, tmp
, lv
);
1453 sim_io_printf(sd
, tmp
, (int)lv
);
1456 else if (strchr ("eEfgG", c
))
1458 double dbl
= *(double*)(ap
++);
1459 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1460 sim_io_printf (sd
, tmp
, dbl
);
1466 sim_io_printf(sd
, "%c", c
);
1472 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1473 reason
, pr_addr(cia
));
1479 /* Store a word into memory. */
1482 store_word (SIM_DESC sd
,
1491 if ((vaddr
& 3) != 0)
1492 SignalExceptionAddressStore ();
1495 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1498 const uword64 mask
= 7;
1502 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1503 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1504 memval
= ((uword64
) val
) << (8 * byte
);
1505 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1511 /* Load a word from memory. */
1514 load_word (SIM_DESC sd
,
1519 if ((vaddr
& 3) != 0)
1520 SignalExceptionAddressLoad ();
1526 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1529 const uword64 mask
= 0x7;
1530 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1531 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1535 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1536 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1538 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1539 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1546 /* Simulate the mips16 entry and exit pseudo-instructions. These
1547 would normally be handled by the reserved instruction exception
1548 code, but for ease of simulation we just handle them directly. */
1551 mips16_entry (SIM_DESC sd
,
1556 int aregs
, sregs
, rreg
;
1559 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1562 aregs
= (insn
& 0x700) >> 8;
1563 sregs
= (insn
& 0x0c0) >> 6;
1564 rreg
= (insn
& 0x020) >> 5;
1566 /* This should be checked by the caller. */
1575 /* This is the entry pseudo-instruction. */
1577 for (i
= 0; i
< aregs
; i
++)
1578 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1586 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1589 for (i
= 0; i
< sregs
; i
++)
1592 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1600 /* This is the exit pseudo-instruction. */
1607 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1610 for (i
= 0; i
< sregs
; i
++)
1613 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1618 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1622 FGR
[0] = WORD64LO (GPR
[4]);
1623 FPR_STATE
[0] = fmt_uninterpreted
;
1625 else if (aregs
== 6)
1627 FGR
[0] = WORD64LO (GPR
[5]);
1628 FGR
[1] = WORD64LO (GPR
[4]);
1629 FPR_STATE
[0] = fmt_uninterpreted
;
1630 FPR_STATE
[1] = fmt_uninterpreted
;
1639 /*-- trace support ----------------------------------------------------------*/
1641 /* The TRACE support is provided (if required) in the memory accessing
1642 routines. Since we are also providing the architecture specific
1643 features, the architecture simulation code can also deal with
1644 notifying the TRACE world of cache flushes, etc. Similarly we do
1645 not need to provide profiling support in the simulator engine,
1646 since we can sample in the instruction fetch control loop. By
1647 defining the TRACE manifest, we add tracing as a run-time
1651 /* Tracing by default produces "din" format (as required by
1652 dineroIII). Each line of such a trace file *MUST* have a din label
1653 and address field. The rest of the line is ignored, so comments can
1654 be included if desired. The first field is the label which must be
1655 one of the following values:
1660 3 escape record (treated as unknown access type)
1661 4 escape record (causes cache flush)
1663 The address field is a 32bit (lower-case) hexadecimal address
1664 value. The address should *NOT* be preceded by "0x".
1666 The size of the memory transfer is not important when dealing with
1667 cache lines (as long as no more than a cache line can be
1668 transferred in a single operation :-), however more information
1669 could be given following the dineroIII requirement to allow more
1670 complete memory and cache simulators to provide better
1671 results. i.e. the University of Pisa has a cache simulator that can
1672 also take bus size and speed as (variable) inputs to calculate
1673 complete system performance (a much more useful ability when trying
1674 to construct an end product, rather than a processor). They
1675 currently have an ARM version of their tool called ChARM. */
1679 dotrace (SIM_DESC sd
,
1687 if (STATE
& simTRACE
) {
1689 fprintf(tracefh
,"%d %s ; width %d ; ",
1693 va_start(ap
,comment
);
1694 vfprintf(tracefh
,comment
,ap
);
1696 fprintf(tracefh
,"\n");
1698 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1699 we may be generating 64bit ones, we should put the hi-32bits of the
1700 address into the comment field. */
1702 /* TODO: Provide a buffer for the trace lines. We can then avoid
1703 performing writes until the buffer is filled, or the file is
1706 /* NOTE: We could consider adding a comment field to the "din" file
1707 produced using type 3 markers (unknown access). This would then
1708 allow information about the program that the "din" is for, and
1709 the MIPs world that was being simulated, to be placed into the
1716 /*---------------------------------------------------------------------------*/
1717 /*-- simulator engine -------------------------------------------------------*/
1718 /*---------------------------------------------------------------------------*/
1721 ColdReset (SIM_DESC sd
)
1724 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1726 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1727 /* RESET: Fixed PC address: */
1728 PC
= (unsigned_word
) UNSIGNED64 (0xFFFFFFFFBFC00000);
1729 /* The reset vector address is in the unmapped, uncached memory space. */
1731 SR
&= ~(status_SR
| status_TS
| status_RP
);
1732 SR
|= (status_ERL
| status_BEV
);
1734 /* Cheat and allow access to the complete register set immediately */
1735 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1736 && WITH_TARGET_WORD_BITSIZE
== 64)
1737 SR
|= status_FR
; /* 64bit registers */
1739 /* Ensure that any instructions with pending register updates are
1741 PENDING_INVALIDATE();
1743 /* Initialise the FPU registers to the unknown state */
1744 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1747 for (rn
= 0; (rn
< 32); rn
++)
1748 FPR_STATE
[rn
] = fmt_uninterpreted
;
1754 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1755 /* Signal an exception condition. This will result in an exception
1756 that aborts the instruction. The instruction operation pseudocode
1757 will never see a return from this function call. */
1760 signal_exception (SIM_DESC sd
,
1768 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1771 /* Ensure that any active atomic read/modify/write operation will fail: */
1774 switch (exception
) {
1776 case DebugBreakPoint
:
1777 if (! (Debug
& Debug_DM
))
1783 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1784 DEPC
= cia
- 4; /* reference the branch instruction */
1788 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1792 Debug
|= Debug_DM
; /* in debugging mode */
1793 Debug
|= Debug_DBp
; /* raising a DBp exception */
1795 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1799 case ReservedInstruction
:
1802 unsigned int instruction
;
1803 va_start(ap
,exception
);
1804 instruction
= va_arg(ap
,unsigned int);
1806 /* Provide simple monitor support using ReservedInstruction
1807 exceptions. The following code simulates the fixed vector
1808 entry points into the IDT monitor by causing a simulator
1809 trap, performing the monitor operation, and returning to
1810 the address held in the $ra register (standard PCS return
1811 address). This means we only need to pre-load the vector
1812 space with suitable instruction values. For systems were
1813 actual trap instructions are used, we would not need to
1814 perform this magic. */
1815 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1817 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
1818 /* NOTE: This assumes that a branch-and-link style
1819 instruction was used to enter the vector (which is the
1820 case with the current IDT monitor). */
1821 sim_engine_restart (SD
, CPU
, NULL
, RA
);
1823 /* Look for the mips16 entry and exit instructions, and
1824 simulate a handler for them. */
1825 else if ((cia
& 1) != 0
1826 && (instruction
& 0xf81f) == 0xe809
1827 && (instruction
& 0x0c0) != 0x0c0)
1829 mips16_entry (SD
, CPU
, cia
, instruction
);
1830 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1832 /* else fall through to normal exception processing */
1833 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
1838 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1840 /* Keep a copy of the current A0 in-case this is the program exit
1844 unsigned int instruction
;
1845 va_start(ap
, exception
);
1846 instruction
= va_arg(ap
,unsigned int);
1848 /* Check for our special terminating BREAK: */
1849 if ((instruction
& HALT_INSTRUCTION_MASK
) == (HALT_INSTRUCTION
& HALT_INSTRUCTION_MASK
) ||
1850 (instruction
& HALT_INSTRUCTION_MASK
) == (HALT_INSTRUCTION2
& HALT_INSTRUCTION_MASK
))
1852 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1853 sim_exited
, (unsigned int)(A0
& 0xFFFFFFFF));
1856 if (STATE
& simDELAYSLOT
)
1857 PC
= cia
- 4; /* reference the branch instruction */
1860 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1861 sim_stopped
, SIM_SIGTRAP
);
1864 /* Store exception code into current exception id variable (used
1867 /* TODO: If not simulating exceptions then stop the simulator
1868 execution. At the moment we always stop the simulation. */
1870 #ifdef SUBTARGET_R3900
1871 /* update interrupt-related registers */
1873 /* insert exception code in bits 6:2 */
1874 CAUSE
= LSMASKED32(CAUSE
, 31, 7) | LSINSERTED32(exception
, 6, 2);
1875 /* shift IE/KU history bits left */
1876 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 3, 0), 5, 2);
1878 if (STATE
& simDELAYSLOT
)
1880 STATE
&= ~simDELAYSLOT
;
1882 EPC
= (cia
- 4); /* reference the branch instruction */
1887 if (SR
& status_BEV
)
1888 PC
= (signed)0xBFC00000 + 0x180;
1890 PC
= (signed)0x80000000 + 0x080;
1892 /* See figure 5-17 for an outline of the code below */
1893 if (! (SR
& status_EXL
))
1895 CAUSE
= (exception
<< 2);
1896 if (STATE
& simDELAYSLOT
)
1898 STATE
&= ~simDELAYSLOT
;
1900 EPC
= (cia
- 4); /* reference the branch instruction */
1904 /* FIXME: TLB et.al. */
1905 /* vector = 0x180; */
1909 CAUSE
= (exception
<< 2);
1910 /* vector = 0x180; */
1913 /* Store exception code into current exception id variable (used
1916 if (SR
& status_BEV
)
1917 PC
= (signed)0xBFC00200 + 0x180;
1919 PC
= (signed)0x80000000 + 0x180;
1922 switch ((CAUSE
>> 2) & 0x1F)
1925 /* Interrupts arrive during event processing, no need to
1931 #ifdef SUBTARGET_3900
1932 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1933 PC
= (signed)0xBFC00000;
1934 #endif SUBTARGET_3900
1937 case TLBModification
:
1942 case InstructionFetch
:
1944 /* The following is so that the simulator will continue from the
1945 exception address on breakpoint operations. */
1947 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1948 sim_stopped
, SIM_SIGBUS
);
1950 case ReservedInstruction
:
1951 case CoProcessorUnusable
:
1953 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1954 sim_stopped
, SIM_SIGILL
);
1956 case IntegerOverflow
:
1958 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1959 sim_stopped
, SIM_SIGFPE
);
1963 sim_engine_restart (SD
, CPU
, NULL
, PC
);
1968 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1969 sim_stopped
, SIM_SIGTRAP
);
1973 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1974 "FATAL: Should not encounter a breakpoint\n");
1976 default : /* Unknown internal exception */
1978 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1979 sim_stopped
, SIM_SIGABRT
);
1983 case SimulatorFault
:
1987 va_start(ap
,exception
);
1988 msg
= va_arg(ap
,char *);
1990 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1991 "FATAL: Simulator error \"%s\"\n",msg
);
1998 #if defined(WARN_RESULT)
1999 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2000 /* This function indicates that the result of the operation is
2001 undefined. However, this should not affect the instruction
2002 stream. All that is meant to happen is that the destination
2003 register is set to an undefined result. To keep the simulator
2004 simple, we just don't bother updating the destination register, so
2005 the overall result will be undefined. If desired we can stop the
2006 simulator by raising a pseudo-exception. */
2007 #define UndefinedResult() undefined_result (sd,cia)
2009 undefined_result(sd
,cia
)
2013 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
2014 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2019 #endif /* WARN_RESULT */
2021 /*-- FPU support routines ---------------------------------------------------*/
2023 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
2024 formats conform to ANSI/IEEE Std 754-1985. */
2025 /* SINGLE precision floating:
2026 * seeeeeeeefffffffffffffffffffffff
2028 * e = 8bits = exponent
2029 * f = 23bits = fraction
2031 /* SINGLE precision fixed:
2032 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2034 * i = 31bits = integer
2036 /* DOUBLE precision floating:
2037 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
2039 * e = 11bits = exponent
2040 * f = 52bits = fraction
2042 /* DOUBLE precision fixed:
2043 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2045 * i = 63bits = integer
2048 /* Extract sign-bit: */
2049 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
2050 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
2051 /* Extract biased exponent: */
2052 #define FP_S_be(v) (((v) >> 23) & 0xFF)
2053 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
2054 /* Extract unbiased Exponent: */
2055 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
2056 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
2057 /* Extract complete fraction field: */
2058 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
2059 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
2060 /* Extract numbered fraction bit: */
2061 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
2062 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
2064 /* Explicit QNaN values used when value required: */
2065 #define FPQNaN_SINGLE (0x7FBFFFFF)
2066 #define FPQNaN_WORD (0x7FFFFFFF)
2067 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
2068 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
2070 /* Explicit Infinity values used when required: */
2071 #define FPINF_SINGLE (0x7F800000)
2072 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
2074 #if 1 /* def DEBUG */
2075 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
2076 #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>"))))))
2080 value_fpr (SIM_DESC sd
,
2089 /* Treat unused register values, as fixed-point 64bit values: */
2090 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
2092 /* If request to read data as "uninterpreted", then use the current
2094 fmt
= FPR_STATE
[fpr
];
2099 /* For values not yet accessed, set to the desired format: */
2100 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
2101 FPR_STATE
[fpr
] = fmt
;
2103 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
2106 if (fmt
!= FPR_STATE
[fpr
]) {
2107 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
));
2108 FPR_STATE
[fpr
] = fmt_unknown
;
2111 if (FPR_STATE
[fpr
] == fmt_unknown
) {
2112 /* Set QNaN value: */
2115 value
= FPQNaN_SINGLE
;
2119 value
= FPQNaN_DOUBLE
;
2123 value
= FPQNaN_WORD
;
2127 value
= FPQNaN_LONG
;
2134 } else if (SizeFGR() == 64) {
2138 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2141 case fmt_uninterpreted
:
2155 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2158 case fmt_uninterpreted
:
2161 if ((fpr
& 1) == 0) { /* even registers only */
2162 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
2164 SignalException(ReservedInstruction
,0);
2175 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2178 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());
2185 store_fpr (SIM_DESC sd
,
2195 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());
2198 if (SizeFGR() == 64) {
2200 case fmt_uninterpreted_32
:
2201 fmt
= fmt_uninterpreted
;
2204 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2205 FPR_STATE
[fpr
] = fmt
;
2208 case fmt_uninterpreted_64
:
2209 fmt
= fmt_uninterpreted
;
2210 case fmt_uninterpreted
:
2214 FPR_STATE
[fpr
] = fmt
;
2218 FPR_STATE
[fpr
] = fmt_unknown
;
2224 case fmt_uninterpreted_32
:
2225 fmt
= fmt_uninterpreted
;
2228 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2229 FPR_STATE
[fpr
] = fmt
;
2232 case fmt_uninterpreted_64
:
2233 fmt
= fmt_uninterpreted
;
2234 case fmt_uninterpreted
:
2237 if ((fpr
& 1) == 0) { /* even register number only */
2238 FGR
[fpr
+1] = (value
>> 32);
2239 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2240 FPR_STATE
[fpr
+ 1] = fmt
;
2241 FPR_STATE
[fpr
] = fmt
;
2243 FPR_STATE
[fpr
] = fmt_unknown
;
2244 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2245 SignalException(ReservedInstruction
,0);
2250 FPR_STATE
[fpr
] = fmt_unknown
;
2255 #if defined(WARN_RESULT)
2258 #endif /* WARN_RESULT */
2261 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2264 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_addr(FGR
[fpr
]),DOFMT(fmt
));
2281 sim_fpu_32to (&wop
, op
);
2282 boolean
= sim_fpu_is_nan (&wop
);
2289 sim_fpu_64to (&wop
, op
);
2290 boolean
= sim_fpu_is_nan (&wop
);
2294 fprintf (stderr
, "Bad switch\n");
2299 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2313 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2320 sim_fpu_32to (&wop
, op
);
2321 boolean
= sim_fpu_is_infinity (&wop
);
2327 sim_fpu_64to (&wop
, op
);
2328 boolean
= sim_fpu_is_infinity (&wop
);
2332 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2337 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2351 /* Argument checking already performed by the FPCOMPARE code */
2354 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2357 /* The format type should already have been checked: */
2363 sim_fpu_32to (&wop1
, op1
);
2364 sim_fpu_32to (&wop2
, op2
);
2365 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2372 sim_fpu_64to (&wop1
, op1
);
2373 sim_fpu_64to (&wop2
, op2
);
2374 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2378 fprintf (stderr
, "Bad switch\n");
2383 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2397 /* Argument checking already performed by the FPCOMPARE code */
2400 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2403 /* The format type should already have been checked: */
2409 sim_fpu_32to (&wop1
, op1
);
2410 sim_fpu_32to (&wop2
, op2
);
2411 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2418 sim_fpu_64to (&wop1
, op1
);
2419 sim_fpu_64to (&wop2
, op2
);
2420 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2424 fprintf (stderr
, "Bad switch\n");
2429 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2436 AbsoluteValue(op
,fmt
)
2443 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2446 /* The format type should already have been checked: */
2452 sim_fpu_32to (&wop
, op
);
2453 sim_fpu_abs (&wop
, &wop
);
2454 sim_fpu_to32 (&ans
, &wop
);
2462 sim_fpu_64to (&wop
, op
);
2463 sim_fpu_abs (&wop
, &wop
);
2464 sim_fpu_to64 (&ans
, &wop
);
2469 fprintf (stderr
, "Bad switch\n");
2484 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2487 /* The format type should already have been checked: */
2493 sim_fpu_32to (&wop
, op
);
2494 sim_fpu_neg (&wop
, &wop
);
2495 sim_fpu_to32 (&ans
, &wop
);
2503 sim_fpu_64to (&wop
, op
);
2504 sim_fpu_neg (&wop
, &wop
);
2505 sim_fpu_to64 (&ans
, &wop
);
2510 fprintf (stderr
, "Bad switch\n");
2526 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2529 /* The registers must specify FPRs valid for operands of type
2530 "fmt". If they are not valid, the result is undefined. */
2532 /* The format type should already have been checked: */
2540 sim_fpu_32to (&wop1
, op1
);
2541 sim_fpu_32to (&wop2
, op2
);
2542 sim_fpu_add (&ans
, &wop1
, &wop2
);
2543 sim_fpu_to32 (&res
, &ans
);
2553 sim_fpu_64to (&wop1
, op1
);
2554 sim_fpu_64to (&wop2
, op2
);
2555 sim_fpu_add (&ans
, &wop1
, &wop2
);
2556 sim_fpu_to64 (&res
, &ans
);
2561 fprintf (stderr
, "Bad switch\n");
2566 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2581 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2584 /* The registers must specify FPRs valid for operands of type
2585 "fmt". If they are not valid, the result is undefined. */
2587 /* The format type should already have been checked: */
2595 sim_fpu_32to (&wop1
, op1
);
2596 sim_fpu_32to (&wop2
, op2
);
2597 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2598 sim_fpu_to32 (&res
, &ans
);
2608 sim_fpu_64to (&wop1
, op1
);
2609 sim_fpu_64to (&wop2
, op2
);
2610 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2611 sim_fpu_to64 (&res
, &ans
);
2616 fprintf (stderr
, "Bad switch\n");
2621 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2628 Multiply(op1
,op2
,fmt
)
2636 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
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: */
2650 sim_fpu_32to (&wop1
, op1
);
2651 sim_fpu_32to (&wop2
, op2
);
2652 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2653 sim_fpu_to32 (&res
, &ans
);
2663 sim_fpu_64to (&wop1
, op1
);
2664 sim_fpu_64to (&wop2
, op2
);
2665 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2666 sim_fpu_to64 (&res
, &ans
);
2671 fprintf (stderr
, "Bad switch\n");
2676 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2691 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2694 /* The registers must specify FPRs valid for operands of type
2695 "fmt". If they are not valid, the result is undefined. */
2697 /* The format type should already have been checked: */
2705 sim_fpu_32to (&wop1
, op1
);
2706 sim_fpu_32to (&wop2
, op2
);
2707 sim_fpu_div (&ans
, &wop1
, &wop2
);
2708 sim_fpu_to32 (&res
, &ans
);
2718 sim_fpu_64to (&wop1
, op1
);
2719 sim_fpu_64to (&wop2
, op2
);
2720 sim_fpu_div (&ans
, &wop1
, &wop2
);
2721 sim_fpu_to64 (&res
, &ans
);
2726 fprintf (stderr
, "Bad switch\n");
2731 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2745 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2748 /* The registers must specify FPRs valid for operands of type
2749 "fmt". If they are not valid, the result is undefined. */
2751 /* The format type should already have been checked: */
2758 sim_fpu_32to (&wop
, op
);
2759 sim_fpu_inv (&ans
, &wop
);
2760 sim_fpu_to32 (&res
, &ans
);
2769 sim_fpu_64to (&wop
, op
);
2770 sim_fpu_inv (&ans
, &wop
);
2771 sim_fpu_to64 (&res
, &ans
);
2776 fprintf (stderr
, "Bad switch\n");
2781 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2795 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2798 /* The registers must specify FPRs valid for operands of type
2799 "fmt". If they are not valid, the result is undefined. */
2801 /* The format type should already have been checked: */
2808 sim_fpu_32to (&wop
, op
);
2809 sim_fpu_sqrt (&ans
, &wop
);
2810 sim_fpu_to32 (&res
, &ans
);
2819 sim_fpu_64to (&wop
, op
);
2820 sim_fpu_sqrt (&ans
, &wop
);
2821 sim_fpu_to64 (&res
, &ans
);
2826 fprintf (stderr
, "Bad switch\n");
2831 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2847 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2850 /* The registers must specify FPRs valid for operands of type
2851 "fmt". If they are not valid, the result is undefined. */
2853 /* The format type should already have been checked: */
2860 sim_fpu_32to (&wop1
, op1
);
2861 sim_fpu_32to (&wop2
, op2
);
2862 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2869 sim_fpu_64to (&wop1
, op1
);
2870 sim_fpu_64to (&wop2
, op2
);
2871 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2875 fprintf (stderr
, "Bad switch\n");
2881 case SIM_FPU_IS_SNAN
:
2882 case SIM_FPU_IS_QNAN
:
2884 case SIM_FPU_IS_NINF
:
2885 case SIM_FPU_IS_NNUMBER
:
2886 case SIM_FPU_IS_NDENORM
:
2887 case SIM_FPU_IS_NZERO
:
2888 result
= op2
; /* op1 - op2 < 0 */
2889 case SIM_FPU_IS_PINF
:
2890 case SIM_FPU_IS_PNUMBER
:
2891 case SIM_FPU_IS_PDENORM
:
2892 case SIM_FPU_IS_PZERO
:
2893 result
= op1
; /* op1 - op2 > 0 */
2895 fprintf (stderr
, "Bad switch\n");
2900 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2917 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2920 /* The registers must specify FPRs valid for operands of type
2921 "fmt". If they are not valid, the result is undefined. */
2923 /* The format type should already have been checked: */
2930 sim_fpu_32to (&wop1
, op1
);
2931 sim_fpu_32to (&wop2
, op2
);
2932 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2939 sim_fpu_64to (&wop1
, op1
);
2940 sim_fpu_64to (&wop2
, op2
);
2941 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2945 fprintf (stderr
, "Bad switch\n");
2951 case SIM_FPU_IS_SNAN
:
2952 case SIM_FPU_IS_QNAN
:
2954 case SIM_FPU_IS_NINF
:
2955 case SIM_FPU_IS_NNUMBER
:
2956 case SIM_FPU_IS_NDENORM
:
2957 case SIM_FPU_IS_NZERO
:
2958 result
= op1
; /* op1 - op2 < 0 */
2959 case SIM_FPU_IS_PINF
:
2960 case SIM_FPU_IS_PNUMBER
:
2961 case SIM_FPU_IS_PDENORM
:
2962 case SIM_FPU_IS_PZERO
:
2963 result
= op2
; /* op1 - op2 > 0 */
2965 fprintf (stderr
, "Bad switch\n");
2970 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2978 convert (SIM_DESC sd
,
2987 sim_fpu_round round
;
2988 unsigned32 result32
;
2989 unsigned64 result64
;
2992 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
));
2998 /* Round result to nearest representable value. When two
2999 representable values are equally near, round to the value
3000 that has a least significant bit of zero (i.e. is even). */
3001 round
= sim_fpu_round_near
;
3004 /* Round result to the value closest to, and not greater in
3005 magnitude than, the result. */
3006 round
= sim_fpu_round_zero
;
3009 /* Round result to the value closest to, and not less than,
3011 round
= sim_fpu_round_up
;
3015 /* Round result to the value closest to, and not greater than,
3017 round
= sim_fpu_round_down
;
3021 fprintf (stderr
, "Bad switch\n");
3025 /* Convert the input to sim_fpu internal format */
3029 sim_fpu_64to (&wop
, op
);
3032 sim_fpu_32to (&wop
, op
);
3035 sim_fpu_i32to (&wop
, op
, round
);
3038 sim_fpu_i64to (&wop
, op
, round
);
3041 fprintf (stderr
, "Bad switch\n");
3045 /* Convert sim_fpu format into the output */
3046 /* The value WOP is converted to the destination format, rounding
3047 using mode RM. When the destination is a fixed-point format, then
3048 a source value of Infinity, NaN or one which would round to an
3049 integer outside the fixed point range then an IEEE Invalid
3050 Operation condition is raised. */
3054 sim_fpu_round_32 (&wop
, round
, 0);
3055 sim_fpu_to32 (&result32
, &wop
);
3056 result64
= result32
;
3059 sim_fpu_round_64 (&wop
, round
, 0);
3060 sim_fpu_to64 (&result64
, &wop
);
3063 sim_fpu_to32i (&result32
, &wop
, round
);
3064 result64
= result32
;
3067 sim_fpu_to64i (&result64
, &wop
, round
);
3071 fprintf (stderr
, "Bad switch\n");
3076 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
3083 /*-- co-processor support routines ------------------------------------------*/
3086 CoProcPresent(coproc_number
)
3087 unsigned int coproc_number
;
3089 /* Return TRUE if simulator provides a model for the given co-processor number */
3094 cop_lw (SIM_DESC sd
,
3099 unsigned int memword
)
3104 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3107 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
3109 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
3110 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
3115 #if 0 /* this should be controlled by a configuration option */
3116 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
));
3125 cop_ld (SIM_DESC sd
,
3132 switch (coproc_num
) {
3134 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3136 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
3141 #if 0 /* this message should be controlled by a configuration option */
3142 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
));
3151 /* start-sanitize-sky */
3154 cop_lq (SIM_DESC sd
,
3159 unsigned128 memword
)
3170 /* one word at a time, argh! */
3174 value
= H2T_4(*A4_16(& memword
, 3-i
));
3175 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3181 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3182 coproc_num
,coproc_reg
,pr_addr(cia
));
3188 #endif /* TARGET_SKY */
3189 /* end-sanitize-sky */
3193 cop_sw (SIM_DESC sd
,
3199 unsigned int value
= 0;
3204 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3207 hold
= FPR_STATE
[coproc_reg
];
3208 FPR_STATE
[coproc_reg
] = fmt_word
;
3209 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3210 FPR_STATE
[coproc_reg
] = hold
;
3215 #if 0 /* should be controlled by configuration option */
3216 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3225 cop_sd (SIM_DESC sd
,
3235 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3237 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3242 #if 0 /* should be controlled by configuration option */
3243 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3252 /* start-sanitize-sky */
3255 cop_sq (SIM_DESC sd
,
3261 unsigned128 value
= U16_8(0, 0);
3272 /* one word at a time, argh! */
3276 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3277 *A4_16(& xyzw
, 3-i
) = T2H_4(value
);
3284 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3285 coproc_num
,coproc_reg
,pr_addr(cia
));
3291 #endif /* TARGET_SKY */
3292 /* end-sanitize-sky */
3296 decode_coproc (SIM_DESC sd
,
3299 unsigned int instruction
)
3301 int coprocnum
= ((instruction
>> 26) & 3);
3305 case 0: /* standard CPU control and cache registers */
3307 int code
= ((instruction
>> 21) & 0x1F);
3308 /* R4000 Users Manual (second edition) lists the following CP0
3310 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3311 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3312 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3313 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3314 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3315 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3316 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3317 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3318 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3319 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3321 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0))
3323 int rt
= ((instruction
>> 16) & 0x1F);
3324 int rd
= ((instruction
>> 11) & 0x1F);
3326 switch (rd
) /* NOTEs: Standard CP0 registers */
3328 /* 0 = Index R4000 VR4100 VR4300 */
3329 /* 1 = Random R4000 VR4100 VR4300 */
3330 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3331 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3332 /* 4 = Context R4000 VR4100 VR4300 */
3333 /* 5 = PageMask R4000 VR4100 VR4300 */
3334 /* 6 = Wired R4000 VR4100 VR4300 */
3335 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3336 /* 9 = Count R4000 VR4100 VR4300 */
3337 /* 10 = EntryHi R4000 VR4100 VR4300 */
3338 /* 11 = Compare R4000 VR4100 VR4300 */
3339 /* 12 = SR R4000 VR4100 VR4300 */
3340 #ifdef SUBTARGET_R3900
3344 /* 3 = Config R3900 */
3345 #endif /* SUBTARGET_R3900 */
3352 /* 13 = Cause R4000 VR4100 VR4300 */
3359 /* 14 = EPC R4000 VR4100 VR4300 */
3362 GPR
[rt
] = (signed_word
) (signed_address
) EPC
;
3366 /* 15 = PRId R4000 VR4100 VR4300 */
3367 #ifdef SUBTARGET_R3900
3376 /* 16 = Config R4000 VR4100 VR4300 */
3379 GPR
[rt
] = C0_CONFIG
;
3381 C0_CONFIG
= GPR
[rt
];
3384 #ifdef SUBTARGET_R3900
3393 /* 17 = LLAddr R4000 VR4100 VR4300 */
3395 /* 18 = WatchLo R4000 VR4100 VR4300 */
3396 /* 19 = WatchHi R4000 VR4100 VR4300 */
3397 /* 20 = XContext R4000 VR4100 VR4300 */
3398 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3399 /* 27 = CacheErr R4000 VR4100 */
3400 /* 28 = TagLo R4000 VR4100 VR4300 */
3401 /* 29 = TagHi R4000 VR4100 VR4300 */
3402 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3403 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3404 /* CPR[0,rd] = GPR[rt]; */
3407 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3409 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3412 else if (code
== 0x10 && (instruction
& 0x3f) == 0x18)
3415 if (SR
& status_ERL
)
3417 /* Oops, not yet available */
3418 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3428 else if (code
== 0x10 && (instruction
& 0x3f) == 0x10)
3431 #ifdef SUBTARGET_R3900
3432 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
3434 /* shift IE/KU history bits right */
3435 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 5, 2), 3, 0);
3437 /* TODO: CACHE register */
3438 #endif /* SUBTARGET_R3900 */
3440 else if (code
== 0x10 && (instruction
& 0x3f) == 0x1F)
3448 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3449 /* TODO: When executing an ERET or RFE instruction we should
3450 clear LLBIT, to ensure that any out-standing atomic
3451 read/modify/write sequence fails. */
3455 case 2: /* co-processor 2 */
3459 /* start-sanitize-sky */
3461 /* On the R5900, this refers to a "VU" vector co-processor. */
3463 int i_25_21
= (instruction
>> 21) & 0x1f;
3464 int i_20_16
= (instruction
>> 16) & 0x1f;
3465 int i_20_6
= (instruction
>> 6) & 0x7fff;
3466 int i_15_11
= (instruction
>> 11) & 0x1f;
3467 int i_15_0
= instruction
& 0xffff;
3468 int i_10_1
= (instruction
>> 1) & 0x3ff;
3469 int i_10_0
= instruction
& 0x7ff;
3470 int i_10_6
= (instruction
>> 6) & 0x1f;
3471 int i_5_0
= instruction
& 0x03f;
3472 int interlock
= instruction
& 0x01;
3473 /* setup for semantic.c-like actions below */
3474 typedef unsigned_4 instruction_word
;
3480 /* test COP2 usability */
3481 if(! (SR
& status_CU2
))
3483 SignalException(CoProcessorUnusable
,instruction
);
3487 #define MY_INDEX itable_COPz_NORMAL
3488 #define MY_PREFIX COPz_NORMAL
3489 #define MY_NAME "COPz_NORMAL"
3491 /* classify & execute basic COP2 instructions */
3492 if(i_25_21
== 0x08 && i_20_16
== 0x00) /* BC2F */
3494 address_word offset
= EXTEND16(i_15_0
) << 2;
3495 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3497 else if(i_25_21
== 0x08 && i_20_16
==0x02) /* BC2FL */
3499 address_word offset
= EXTEND16(i_15_0
) << 2;
3500 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3501 else NULLIFY_NEXT_INSTRUCTION();
3503 else if(i_25_21
== 0x08 && i_20_16
== 0x01) /* BC2T */
3505 address_word offset
= EXTEND16(i_15_0
) << 2;
3506 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3508 else if(i_25_21
== 0x08 && i_20_16
== 0x03) /* BC2TL */
3510 address_word offset
= EXTEND16(i_15_0
) << 2;
3511 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3512 else NULLIFY_NEXT_INSTRUCTION();
3514 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3515 (i_25_21
== 0x01)) /* QMFC2 */
3520 /* interlock checking */
3521 /* POLICY: never busy in macro mode */
3522 while(vu0_busy() && interlock
)
3525 /* perform VU register address */
3526 if(i_25_21
== 0x01) /* QMFC2 */
3529 /* one word at a time, argh! */
3530 read_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3531 read_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3532 read_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3533 read_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3534 GPR
[rt
] = T2H_8(* A8_16(& xyzw
, 1));
3535 GPR1
[rt
] = T2H_8(* A8_16(& xyzw
, 0));
3540 /* enum + int calculation, argh! */
3541 id
= VU_REG_MST
+ 16 * id
;
3542 read_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3543 GPR
[rt
] = EXTEND32(T2H_4(data
));
3546 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3547 (i_25_21
== 0x05)) /* QMTC2 */
3552 /* interlock checking: wait until M or E bits set */
3553 /* POLICY: never busy in macro mode */
3554 while(vu0_busy() && interlock
)
3556 if(vu0_micro_interlock_released())
3558 vu0_micro_interlock_clear();
3565 /* perform VU register address */
3566 if(i_25_21
== 0x05) /* QMTC2 */
3568 unsigned_16 xyzw
= U16_8(GPR1
[rt
], GPR
[rt
]);
3570 xyzw
= H2T_16(xyzw
);
3571 /* one word at a time, argh! */
3572 write_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3573 write_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3574 write_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3575 write_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3579 unsigned_4 data
= H2T_4(GPR
[rt
]);
3580 /* enum + int calculation, argh! */
3581 id
= VU_REG_MST
+ 16 * id
;
3582 write_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3585 else if(i_10_0
== 0x3bf) /* VWAITQ */
3590 else if(i_5_0
== 0x38) /* VCALLMS */
3592 unsigned_4 data
= H2T_2(i_20_6
);
3597 /* write to reserved CIA register to get VU0 moving */
3598 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3602 else if(i_5_0
== 0x39) /* VCALLMSR */
3609 read_vu_special_reg(& vu0_device
, VU_REG_CMSAR0
, & data
);
3610 /* write to reserved CIA register to get VU0 moving */
3611 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3615 /* handle all remaining UPPER VU instructions in one block */
3616 else if((i_5_0
< 0x30) || /* VADDx .. VMINI */
3617 (i_5_0
>= 0x3c && i_10_6
< 0x0c)) /* VADDAx .. VNOP */
3619 unsigned_4 vu_upper
, vu_lower
;
3621 0x00000000 | /* bits 31 .. 25 */
3622 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3623 vu_lower
= 0x8000033c; /* NOP */
3625 /* POLICY: never busy in macro mode */
3629 vu0_macro_issue(vu_upper
, vu_lower
);
3631 /* POLICY: wait for completion of macro-instruction */
3635 /* handle all remaining LOWER VU instructions in one block */
3636 else if((i_5_0
>= 0x30 && i_5_0
<= 0x35) || /* VIADD .. VIOR */
3637 (i_5_0
>= 0x3c && i_10_6
>= 0x0c)) /* VMOVE .. VRXOR */
3638 { /* N.B.: VWAITQ already covered by prior case */
3639 unsigned_4 vu_upper
, vu_lower
;
3640 vu_upper
= 0x000002ff; /* NOP/NOP */
3642 0x80000000 | /* bits 31 .. 25 */
3643 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3645 /* POLICY: never busy in macro mode */
3649 vu0_macro_issue(vu_upper
, vu_lower
);
3651 /* POLICY: wait for completion of macro-instruction */
3655 /* ... no other COP2 instructions ... */
3658 SignalException(ReservedInstruction
, instruction
);
3662 /* cleanup for semantic.c-like actions above */
3669 #endif /* TARGET_SKY */
3670 /* end-sanitize-sky */
3674 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3675 instruction
,pr_addr(cia
));
3680 case 1: /* should not occur (FPU co-processor) */
3681 case 3: /* should not occur (FPU co-processor) */
3682 SignalException(ReservedInstruction
,instruction
);
3690 /*-- instruction simulation -------------------------------------------------*/
3692 /* When the IGEN simulator is being built, the function below is be
3693 replaced by a generated version. However, WITH_IGEN == 2 indicates
3694 that the fubction below should be compiled but under a different
3695 name (to allow backward compatibility) */
3697 #if (WITH_IGEN != 1)
3699 void old_engine_run
PARAMS ((SIM_DESC sd
, int next_cpu_nr
, int siggnal
));
3701 old_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3704 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3707 int next_cpu_nr
; /* ignore */
3708 int nr_cpus
; /* ignore */
3709 int siggnal
; /* ignore */
3711 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* hardwire to cpu 0 */
3712 #if !defined(FASTSIM)
3713 unsigned int pipeline_count
= 1;
3717 if (STATE_MEMORY (sd
) == NULL
) {
3718 printf("DBG: simulate() entered with no memory\n");
3723 #if 0 /* Disabled to check that everything works OK */
3724 /* The VR4300 seems to sign-extend the PC on its first
3725 access. However, this may just be because it is currently
3726 configured in 32bit mode. However... */
3727 PC
= SIGNEXTEND(PC
,32);
3730 /* main controlling loop */
3732 /* vaddr is slowly being replaced with cia - current instruction
3734 address_word cia
= (uword64
)PC
;
3735 address_word vaddr
= cia
;
3738 unsigned int instruction
; /* uword64? what's this used for? FIXME! */
3742 printf("DBG: state = 0x%08X :",state
);
3743 if (state
& simHALTEX
) printf(" simHALTEX");
3744 if (state
& simHALTIN
) printf(" simHALTIN");
3749 DSSTATE
= (STATE
& simDELAYSLOT
);
3752 sim_io_printf(sd
,"DBG: DSPC = 0x%s\n",pr_addr(DSPC
));
3755 /* Fetch the next instruction from the simulator memory: */
3756 if (AddressTranslation(cia
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) {
3757 if ((vaddr
& 1) == 0) {
3758 /* Copy the action of the LW instruction */
3759 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3760 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3763 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3764 LoadMemory(&value
,NULL
,cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3765 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3766 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3768 /* Copy the action of the LH instruction */
3769 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 1) : 0);
3770 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 1) : 0);
3773 paddr
= (((paddr
& ~ (uword64
) 1) & ~LOADDRMASK
)
3774 | (((paddr
& ~ (uword64
) 1) & LOADDRMASK
) ^ (reverse
<< 1)));
3775 LoadMemory(&value
,NULL
,cca
, AccessLength_HALFWORD
,
3776 paddr
& ~ (uword64
) 1,
3777 vaddr
, isINSTRUCTION
, isREAL
);
3778 byte
= (((vaddr
&~ (uword64
) 1) & LOADDRMASK
) ^ (bigend
<< 1));
3779 instruction
= ((value
>> (8 * byte
)) & 0xFFFF);
3782 fprintf(stderr
,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC
));
3787 sim_io_printf(sd
,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction
,pr_addr(PC
));
3790 /* This is required by exception processing, to ensure that we can
3791 cope with exceptions in the delay slots of branches that may
3792 already have changed the PC. */
3793 if ((vaddr
& 1) == 0)
3794 PC
+= 4; /* increment ready for the next fetch */
3797 /* NOTE: If we perform a delay slot change to the PC, this
3798 increment is not requuired. However, it would make the
3799 simulator more complicated to try and avoid this small hit. */
3801 /* Currently this code provides a simple model. For more
3802 complicated models we could perform exception status checks at
3803 this point, and set the simSTOP state as required. This could
3804 also include processing any hardware interrupts raised by any
3805 I/O model attached to the simulator context.
3807 Support for "asynchronous" I/O events within the simulated world
3808 could be providing by managing a counter, and calling a I/O
3809 specific handler when a particular threshold is reached. On most
3810 architectures a decrement and check for zero operation is
3811 usually quicker than an increment and compare. However, the
3812 process of managing a known value decrement to zero, is higher
3813 than the cost of using an explicit value UINT_MAX into the
3814 future. Which system is used will depend on how complicated the
3815 I/O model is, and how much it is likely to affect the simulator
3818 If events need to be scheduled further in the future than
3819 UINT_MAX event ticks, then the I/O model should just provide its
3820 own counter, triggered from the event system. */
3822 /* MIPS pipeline ticks. To allow for future support where the
3823 pipeline hit of individual instructions is known, this control
3824 loop manages a "pipeline_count" variable. It is initialised to
3825 1 (one), and will only be changed by the simulator engine when
3826 executing an instruction. If the engine does not have access to
3827 pipeline cycle count information then all instructions will be
3828 treated as using a single cycle. NOTE: A standard system is not
3829 provided by the default simulator because different MIPS
3830 architectures have different cycle counts for the same
3833 [NOTE: pipeline_count has been replaced the event queue] */
3835 /* shuffle the floating point status pipeline state */
3836 ENGINE_ISSUE_PREFIX_HOOK();
3838 /* NOTE: For multi-context simulation environments the "instruction"
3839 variable should be local to this routine. */
3841 /* Shorthand accesses for engine. Note: If we wanted to use global
3842 variables (and a single-threaded simulator engine), then we can
3843 create the actual variables with these names. */
3845 if (!(STATE
& simSKIPNEXT
)) {
3846 /* Include the simulator engine */
3847 #include "oengine.c"
3848 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3849 #error "Mismatch between run-time simulator code and simulation engine"
3851 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3852 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3854 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3855 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3858 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3859 should check for it being changed. It is better doing it here,
3860 than within the simulator, since it will help keep the simulator
3863 #if defined(WARN_ZERO)
3864 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
));
3865 #endif /* WARN_ZERO */
3866 ZERO
= 0; /* reset back to zero before next instruction */
3868 } else /* simSKIPNEXT check */
3869 STATE
&= ~simSKIPNEXT
;
3871 /* If the delay slot was active before the instruction is
3872 executed, then update the PC to its new value: */
3875 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC
));
3884 #if !defined(FASTSIM)
3885 if (sim_events_tickn (sd
, pipeline_count
))
3887 /* cpu->cia = cia; */
3888 sim_events_process (sd
);
3891 if (sim_events_tick (sd
))
3893 /* cpu->cia = cia; */
3894 sim_events_process (sd
);
3896 #endif /* FASTSIM */
3902 /* This code copied from gdb's utils.c. Would like to share this code,
3903 but don't know of a common place where both could get to it. */
3905 /* Temporary storage using circular buffer */
3911 static char buf
[NUMCELLS
][CELLSIZE
];
3913 if (++cell
>=NUMCELLS
) cell
=0;
3917 /* Print routines to handle variable size regs, etc */
3919 /* Eliminate warning from compiler on 32-bit systems */
3920 static int thirty_two
= 32;
3926 char *paddr_str
=get_cell();
3927 switch (sizeof(addr
))
3930 sprintf(paddr_str
,"%08lx%08lx",
3931 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3934 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
3937 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
3940 sprintf(paddr_str
,"%x",addr
);
3949 char *paddr_str
=get_cell();
3950 sprintf(paddr_str
,"%08lx%08lx",
3951 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3957 /*---------------------------------------------------------------------------*/
3958 /*> EOF interp.c <*/