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@0xffffc000/reg 0xffffc000 0x20");
522 sim_hw_parse (sd
, "/tx3904cpu");
523 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
524 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
525 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
527 /* -- device connections --- */
528 sim_hw_parse (sd
, "/tx3904irc > ip level /tx3904cpu");
529 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
530 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
531 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
533 if(! strcmp(board
, BOARD_JMR3904_DEBUG
))
535 /* -- DEBUG: glue interrupt generators --- */
536 sim_hw_parse (sd
, "/glue@0xffff0000/reg 0xffff0000 0x50");
537 sim_hw_parse (sd
, "/glue@0xffff0000 > int0 int0 /tx3904irc");
538 sim_hw_parse (sd
, "/glue@0xffff0000 > int1 int1 /tx3904irc");
539 sim_hw_parse (sd
, "/glue@0xffff0000 > int2 int2 /tx3904irc");
540 sim_hw_parse (sd
, "/glue@0xffff0000 > int3 int3 /tx3904irc");
541 sim_hw_parse (sd
, "/glue@0xffff0000 > int4 int4 /tx3904irc");
542 sim_hw_parse (sd
, "/glue@0xffff0000 > int5 int5 /tx3904irc");
543 sim_hw_parse (sd
, "/glue@0xffff0000 > int6 int6 /tx3904irc");
544 sim_hw_parse (sd
, "/glue@0xffff0000 > int7 int7 /tx3904irc");
545 sim_hw_parse (sd
, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
546 sim_hw_parse (sd
, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
547 sim_hw_parse (sd
, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
548 sim_hw_parse (sd
, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
549 sim_hw_parse (sd
, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
550 sim_hw_parse (sd
, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
551 sim_hw_parse (sd
, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
552 sim_hw_parse (sd
, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
553 sim_hw_parse (sd
, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
554 sim_hw_parse (sd
, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
560 /* end-sanitize-tx3904 */
563 /* check for/establish the a reference program image */
564 if (sim_analyze_program (sd
,
565 (STATE_PROG_ARGV (sd
) != NULL
566 ? *STATE_PROG_ARGV (sd
)
570 sim_module_uninstall (sd
);
574 /* Configure/verify the target byte order and other runtime
575 configuration options */
576 if (sim_config (sd
) != SIM_RC_OK
)
578 sim_module_uninstall (sd
);
582 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
584 /* Uninstall the modules to avoid memory leaks,
585 file descriptor leaks, etc. */
586 sim_module_uninstall (sd
);
590 /* verify assumptions the simulator made about the host type system.
591 This macro does not return if there is a problem */
592 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
593 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
595 /* This is NASTY, in that we are assuming the size of specific
599 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
602 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
603 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ NR_FGR
)))
604 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
605 else if ((rn
>= 33) && (rn
<= 37))
606 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
607 else if ((rn
== SRIDX
)
610 || ((rn
>= 72) && (rn
<= 89)))
611 cpu
->register_widths
[rn
] = 32;
613 cpu
->register_widths
[rn
] = 0;
615 /* start-sanitize-r5900 */
617 /* set the 5900 "upper" registers to 64 bits */
618 for( rn
= LAST_EMBED_REGNUM
+1; rn
< NUM_REGS
; rn
++)
619 cpu
->register_widths
[rn
] = 64;
620 /* end-sanitize-r5900 */
622 /* start-sanitize-sky */
624 /* Now the VU registers */
625 for( rn
= 0; rn
< NUM_VU_INTEGER_REGS
; rn
++ ) {
626 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 16;
627 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 16;
630 for( rn
= NUM_VU_INTEGER_REGS
; rn
< NUM_VU_REGS
; rn
++ ) {
631 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
632 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 32;
635 /* Finally the VIF registers */
636 for( rn
= 2*NUM_VU_REGS
; rn
< 2*NUM_VU_REGS
+ 2*NUM_VIF_REGS
; rn
++ )
637 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
641 /* end-sanitize-sky */
645 if (STATE
& simTRACE
)
649 /* Write an abort sequence into the TRAP (common) exception vector
650 addresses. This is to catch code executing a TRAP (et.al.)
651 instruction without installing a trap handler. */
653 unsigned32 halt
[2] = { 0x2404002f /* addiu r4, r0, 47 */,
654 HALT_INSTRUCTION
/* BREAK */ };
657 sim_write (sd
, 0x80000180, (char *) halt
, sizeof (halt
));
658 sim_write (sd
, 0xBFC00380, (char *) halt
, sizeof (halt
));
662 /* Write the monitor trap address handlers into the monitor (eeprom)
663 address space. This can only be done once the target endianness
664 has been determined. */
667 /* Entry into the IDT monitor is via fixed address vectors, and
668 not using machine instructions. To avoid clashing with use of
669 the MIPS TRAP system, we place our own (simulator specific)
670 "undefined" instructions into the relevant vector slots. */
671 for (loop
= 0; (loop
< MONITOR_SIZE
); loop
+= 4)
673 address_word vaddr
= (MONITOR_BASE
+ loop
);
674 unsigned32 insn
= (RSVD_INSTRUCTION
| (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
) << RSVD_INSTRUCTION_ARG_SHIFT
));
676 sim_write (sd
, vaddr
, (char *)&insn
, sizeof (insn
));
678 /* The PMON monitor uses the same address space, but rather than
679 branching into it the address of a routine is loaded. We can
680 cheat for the moment, and direct the PMON routine to IDT style
681 instructions within the monitor space. This relies on the IDT
682 monitor not using the locations from 0xBFC00500 onwards as its
684 for (loop
= 0; (loop
< 24); loop
++)
686 address_word vaddr
= (MONITOR_BASE
+ 0x500 + (loop
* 4));
687 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
703 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
705 case 8: /* cliexit */
708 case 11: /* flush_cache */
712 /* FIXME - should monitor_base be SIM_ADDR?? */
713 value
= ((unsigned int)MONITOR_BASE
+ (value
* 8));
715 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
717 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
719 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
731 tracefh
= fopen(tracefile
,"wb+");
734 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
741 sim_close (sd
, quitting
)
746 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
749 /* "quitting" is non-zero if we cannot hang on errors */
751 /* Ensure that any resources allocated through the callback
752 mechanism are released: */
753 sim_io_shutdown (sd
);
756 if (tracefh
!= NULL
&& tracefh
!= stderr
)
761 /* FIXME - free SD */
768 sim_write (sd
,addr
,buffer
,size
)
771 unsigned char *buffer
;
775 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
777 /* Return the number of bytes written, or zero if error. */
779 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
782 /* We use raw read and write routines, since we do not want to count
783 the GDB memory accesses in our statistics gathering. */
785 for (index
= 0; index
< size
; index
++)
787 address_word vaddr
= (address_word
)addr
+ index
;
790 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
792 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
800 sim_read (sd
,addr
,buffer
,size
)
803 unsigned char *buffer
;
807 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
809 /* Return the number of bytes read, or zero if error. */
811 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
814 for (index
= 0; (index
< size
); index
++)
816 address_word vaddr
= (address_word
)addr
+ index
;
819 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isLOAD
, &paddr
, &cca
, isRAW
))
821 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
829 sim_store_register (sd
,rn
,memory
,length
)
832 unsigned char *memory
;
835 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
836 /* NOTE: gdb (the client) stores registers in target byte order
837 while the simulator uses host byte order */
839 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
842 /* Unfortunately this suffers from the same problem as the register
843 numbering one. We need to know what the width of each logical
844 register number is for the architecture being simulated. */
846 if (cpu
->register_widths
[rn
] == 0)
848 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
852 /* start-sanitize-r5900 */
853 if (rn
>= 90 && rn
< 90 + 32)
855 GPR1
[rn
- 90] = T2H_8 (*(unsigned64
*)memory
);
861 SA
= T2H_8(*(unsigned64
*)memory
);
863 case 122: /* FIXME */
864 LO1
= T2H_8(*(unsigned64
*)memory
);
866 case 123: /* FIXME */
867 HI1
= T2H_8(*(unsigned64
*)memory
);
870 /* end-sanitize-r5900 */
872 /* start-sanitize-sky */
874 if (rn
>= NUM_R5900_REGS
)
876 rn
= rn
- NUM_R5900_REGS
;
878 if( rn
< NUM_VU_REGS
)
880 if (rn
< NUM_VU_INTEGER_REGS
)
881 return write_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
882 else if (rn
>= FIRST_VEC_REG
)
885 return write_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
&3,
888 else switch (rn
- NUM_VU_INTEGER_REGS
)
891 return write_vu_special_reg (&vu0_device
, VU_REG_CIA
,
894 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
896 case 2: /* VU0 has no P register */
899 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
902 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
905 return write_vu_acc_reg (&(vu0_device
.regs
),
906 rn
- (NUM_VU_INTEGER_REGS
+ 5),
911 rn
= rn
- NUM_VU_REGS
;
913 if (rn
< NUM_VU_REGS
)
915 if (rn
< NUM_VU_INTEGER_REGS
)
916 return write_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
917 else if (rn
>= FIRST_VEC_REG
)
920 return write_vu_vec_reg (&(vu1_device
.regs
),
921 rn
>> 2, rn
& 3, memory
);
923 else switch (rn
- NUM_VU_INTEGER_REGS
)
926 return write_vu_special_reg (&vu1_device
, VU_REG_CIA
,
929 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MR
,
932 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MP
,
935 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MI
,
938 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MQ
,
941 return write_vu_acc_reg (&(vu1_device
.regs
),
942 rn
- (NUM_VU_INTEGER_REGS
+ 5),
947 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
949 if (rn
< NUM_VIF_REGS
)
951 if (rn
< NUM_VIF_REGS
-1)
952 return write_pke_reg (&pke0_device
, rn
, memory
);
955 sim_io_eprintf( sd
, "Can't write vif0_pc (store ignored)\n" );
960 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
962 if (rn
< NUM_VIF_REGS
)
964 if (rn
< NUM_VIF_REGS
-1)
965 return write_pke_reg (&pke1_device
, rn
, memory
);
968 sim_io_eprintf( sd
, "Can't write vif1_pc (store ignored)\n" );
973 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
977 /* end-sanitize-sky */
979 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
981 if (cpu
->register_widths
[rn
] == 32)
983 cpu
->fgr
[rn
- FGRIDX
] = T2H_4 (*(unsigned32
*)memory
);
988 cpu
->fgr
[rn
- FGRIDX
] = T2H_8 (*(unsigned64
*)memory
);
993 if (cpu
->register_widths
[rn
] == 32)
995 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
1000 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
1008 sim_fetch_register (sd
,rn
,memory
,length
)
1011 unsigned char *memory
;
1014 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
1015 /* NOTE: gdb (the client) stores registers in target byte order
1016 while the simulator uses host byte order */
1018 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
1021 if (cpu
->register_widths
[rn
] == 0)
1023 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
1027 /* start-sanitize-r5900 */
1028 if (rn
>= 90 && rn
< 90 + 32)
1030 *((unsigned64
*)memory
) = H2T_8 (GPR1
[rn
- 90]);
1036 *((unsigned64
*)memory
) = H2T_8(SA
);
1038 case 122: /* FIXME */
1039 *((unsigned64
*)memory
) = H2T_8(LO1
);
1041 case 123: /* FIXME */
1042 *((unsigned64
*)memory
) = H2T_8(HI1
);
1045 /* end-sanitize-r5900 */
1047 /* start-sanitize-sky */
1049 if (rn
>= NUM_R5900_REGS
)
1051 rn
= rn
- NUM_R5900_REGS
;
1053 if (rn
< NUM_VU_REGS
)
1055 if (rn
< NUM_VU_INTEGER_REGS
)
1056 return read_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
1057 else if (rn
>= FIRST_VEC_REG
)
1059 rn
-= FIRST_VEC_REG
;
1060 return read_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
& 3,
1063 else switch (rn
- NUM_VU_INTEGER_REGS
)
1066 return read_vu_special_reg(&vu0_device
, VU_REG_CIA
, memory
);
1068 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
1070 case 2: /* VU0 has no P register */
1071 *((int *) memory
) = 0;
1074 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
1077 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
1080 return read_vu_acc_reg (&(vu0_device
.regs
),
1081 rn
- (NUM_VU_INTEGER_REGS
+ 5),
1086 rn
-= NUM_VU_REGS
; /* VU1 registers are next */
1088 if (rn
< NUM_VU_REGS
)
1090 if (rn
< NUM_VU_INTEGER_REGS
)
1091 return read_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
1092 else if (rn
>= FIRST_VEC_REG
)
1094 rn
-= FIRST_VEC_REG
;
1095 return read_vu_vec_reg (&(vu1_device
.regs
),
1096 rn
>> 2, rn
& 3, memory
);
1098 else switch (rn
- NUM_VU_INTEGER_REGS
)
1101 return read_vu_special_reg(&vu1_device
, VU_REG_CIA
, memory
);
1103 return read_vu_misc_reg (&(vu1_device
.regs
),
1106 return read_vu_misc_reg (&(vu1_device
.regs
),
1109 return read_vu_misc_reg (&(vu1_device
.regs
),
1112 return read_vu_misc_reg (&(vu1_device
.regs
),
1115 return read_vu_acc_reg (&(vu1_device
.regs
),
1116 rn
- (NUM_VU_INTEGER_REGS
+ 5),
1121 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
1123 if (rn
< NUM_VIF_REGS
)
1125 if (rn
< NUM_VIF_REGS
-1)
1126 return read_pke_reg (&pke0_device
, rn
, memory
);
1128 return read_pke_pc (&pke0_device
, memory
);
1131 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
1133 if (rn
< NUM_VIF_REGS
)
1135 if (rn
< NUM_VIF_REGS
-1)
1136 return read_pke_reg (&pke1_device
, rn
, memory
);
1138 return read_pke_pc (&pke1_device
, memory
);
1141 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
1144 /* end-sanitize-sky */
1146 /* Any floating point register */
1147 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
1149 if (cpu
->register_widths
[rn
] == 32)
1151 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGRIDX
]);
1156 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGRIDX
]);
1161 if (cpu
->register_widths
[rn
] == 32)
1163 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
1168 *(unsigned64
*)memory
= H2T_8 ((unsigned64
)(cpu
->registers
[rn
]));
1177 sim_create_inferior (sd
, abfd
, argv
,env
)
1185 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1193 /* override PC value set by ColdReset () */
1195 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1197 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1198 CIA_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
1202 #if 0 /* def DEBUG */
1205 /* We should really place the argv slot values into the argument
1206 registers, and onto the stack as required. However, this
1207 assumes that we have a stack defined, which is not
1208 necessarily true at the moment. */
1210 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1211 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1212 printf("DBG: arg \"%s\"\n",*cptr
);
1220 sim_do_command (sd
,cmd
)
1224 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1225 sim_io_printf (sd
, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1229 /*---------------------------------------------------------------------------*/
1230 /*-- Private simulator support interface ------------------------------------*/
1231 /*---------------------------------------------------------------------------*/
1233 /* Read a null terminated string from memory, return in a buffer */
1235 fetch_str (sd
, addr
)
1242 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1244 buf
= NZALLOC (char, nr
+ 1);
1245 sim_read (sd
, addr
, buf
, nr
);
1249 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1251 sim_monitor (SIM_DESC sd
,
1254 unsigned int reason
)
1257 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1260 /* The IDT monitor actually allows two instructions per vector
1261 slot. However, the simulator currently causes a trap on each
1262 individual instruction. We cheat, and lose the bottom bit. */
1265 /* The following callback functions are available, however the
1266 monitor we are simulating does not make use of them: get_errno,
1267 isatty, lseek, rename, system, time and unlink */
1271 case 6: /* int open(char *path,int flags) */
1273 char *path
= fetch_str (sd
, A0
);
1274 V0
= sim_io_open (sd
, path
, (int)A1
);
1279 case 7: /* int read(int file,char *ptr,int len) */
1283 char *buf
= zalloc (nr
);
1284 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1285 sim_write (sd
, A1
, buf
, nr
);
1290 case 8: /* int write(int file,char *ptr,int len) */
1294 char *buf
= zalloc (nr
);
1295 sim_read (sd
, A1
, buf
, nr
);
1296 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1301 case 10: /* int close(int file) */
1303 V0
= sim_io_close (sd
, (int)A0
);
1307 case 2: /* Densan monitor: char inbyte(int waitflag) */
1309 if (A0
== 0) /* waitflag == NOWAIT */
1310 V0
= (unsigned_word
)-1;
1312 /* Drop through to case 11 */
1314 case 11: /* char inbyte(void) */
1317 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1319 sim_io_error(sd
,"Invalid return from character read");
1320 V0
= (unsigned_word
)-1;
1323 V0
= (unsigned_word
)tmp
;
1327 case 3: /* Densan monitor: void co(char chr) */
1328 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1330 char tmp
= (char)(A0
& 0xFF);
1331 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1335 case 17: /* void _exit() */
1337 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1338 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1339 (unsigned int)(A0
& 0xFFFFFFFF));
1343 case 28 : /* PMON flush_cache */
1346 case 55: /* void get_mem_info(unsigned int *ptr) */
1347 /* in: A0 = pointer to three word memory location */
1348 /* out: [A0 + 0] = size */
1349 /* [A0 + 4] = instruction cache size */
1350 /* [A0 + 8] = data cache size */
1352 unsigned_4 value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1353 unsigned_4 zero
= 0;
1355 sim_write (sd
, A0
+ 0, (char *)&value
, 4);
1356 sim_write (sd
, A0
+ 4, (char *)&zero
, 4);
1357 sim_write (sd
, A0
+ 8, (char *)&zero
, 4);
1358 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1362 case 158 : /* PMON printf */
1363 /* in: A0 = pointer to format string */
1364 /* A1 = optional argument 1 */
1365 /* A2 = optional argument 2 */
1366 /* A3 = optional argument 3 */
1368 /* The following is based on the PMON printf source */
1370 address_word s
= A0
;
1372 signed_word
*ap
= &A1
; /* 1st argument */
1373 /* This isn't the quickest way, since we call the host print
1374 routine for every character almost. But it does avoid
1375 having to allocate and manage a temporary string buffer. */
1376 /* TODO: Include check that we only use three arguments (A1,
1378 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1383 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1384 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1385 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1387 if (strchr ("dobxXulscefg%", c
))
1402 else if (c
>= '1' && c
<= '9')
1406 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1409 n
= (unsigned int)strtol(tmp
,NULL
,10);
1422 sim_io_printf (sd
, "%%");
1427 address_word p
= *ap
++;
1429 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1430 sim_io_printf(sd
, "%c", ch
);
1433 sim_io_printf(sd
,"(null)");
1436 sim_io_printf (sd
, "%c", (int)*ap
++);
1441 sim_read (sd
, s
++, &c
, 1);
1445 sim_read (sd
, s
++, &c
, 1);
1448 if (strchr ("dobxXu", c
))
1450 word64 lv
= (word64
) *ap
++;
1452 sim_io_printf(sd
,"<binary not supported>");
1455 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1457 sim_io_printf(sd
, tmp
, lv
);
1459 sim_io_printf(sd
, tmp
, (int)lv
);
1462 else if (strchr ("eEfgG", c
))
1464 double dbl
= *(double*)(ap
++);
1465 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1466 sim_io_printf (sd
, tmp
, dbl
);
1472 sim_io_printf(sd
, "%c", c
);
1478 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1479 reason
, pr_addr(cia
));
1485 /* Store a word into memory. */
1488 store_word (SIM_DESC sd
,
1497 if ((vaddr
& 3) != 0)
1498 SignalExceptionAddressStore ();
1501 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1504 const uword64 mask
= 7;
1508 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1509 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1510 memval
= ((uword64
) val
) << (8 * byte
);
1511 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1517 /* Load a word from memory. */
1520 load_word (SIM_DESC sd
,
1525 if ((vaddr
& 3) != 0)
1526 SignalExceptionAddressLoad ();
1532 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1535 const uword64 mask
= 0x7;
1536 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1537 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1541 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1542 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1544 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1545 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1552 /* Simulate the mips16 entry and exit pseudo-instructions. These
1553 would normally be handled by the reserved instruction exception
1554 code, but for ease of simulation we just handle them directly. */
1557 mips16_entry (SIM_DESC sd
,
1562 int aregs
, sregs
, rreg
;
1565 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1568 aregs
= (insn
& 0x700) >> 8;
1569 sregs
= (insn
& 0x0c0) >> 6;
1570 rreg
= (insn
& 0x020) >> 5;
1572 /* This should be checked by the caller. */
1581 /* This is the entry pseudo-instruction. */
1583 for (i
= 0; i
< aregs
; i
++)
1584 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1592 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1595 for (i
= 0; i
< sregs
; i
++)
1598 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1606 /* This is the exit pseudo-instruction. */
1613 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1616 for (i
= 0; i
< sregs
; i
++)
1619 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1624 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1628 FGR
[0] = WORD64LO (GPR
[4]);
1629 FPR_STATE
[0] = fmt_uninterpreted
;
1631 else if (aregs
== 6)
1633 FGR
[0] = WORD64LO (GPR
[5]);
1634 FGR
[1] = WORD64LO (GPR
[4]);
1635 FPR_STATE
[0] = fmt_uninterpreted
;
1636 FPR_STATE
[1] = fmt_uninterpreted
;
1645 /*-- trace support ----------------------------------------------------------*/
1647 /* The TRACE support is provided (if required) in the memory accessing
1648 routines. Since we are also providing the architecture specific
1649 features, the architecture simulation code can also deal with
1650 notifying the TRACE world of cache flushes, etc. Similarly we do
1651 not need to provide profiling support in the simulator engine,
1652 since we can sample in the instruction fetch control loop. By
1653 defining the TRACE manifest, we add tracing as a run-time
1657 /* Tracing by default produces "din" format (as required by
1658 dineroIII). Each line of such a trace file *MUST* have a din label
1659 and address field. The rest of the line is ignored, so comments can
1660 be included if desired. The first field is the label which must be
1661 one of the following values:
1666 3 escape record (treated as unknown access type)
1667 4 escape record (causes cache flush)
1669 The address field is a 32bit (lower-case) hexadecimal address
1670 value. The address should *NOT* be preceded by "0x".
1672 The size of the memory transfer is not important when dealing with
1673 cache lines (as long as no more than a cache line can be
1674 transferred in a single operation :-), however more information
1675 could be given following the dineroIII requirement to allow more
1676 complete memory and cache simulators to provide better
1677 results. i.e. the University of Pisa has a cache simulator that can
1678 also take bus size and speed as (variable) inputs to calculate
1679 complete system performance (a much more useful ability when trying
1680 to construct an end product, rather than a processor). They
1681 currently have an ARM version of their tool called ChARM. */
1685 dotrace (SIM_DESC sd
,
1693 if (STATE
& simTRACE
) {
1695 fprintf(tracefh
,"%d %s ; width %d ; ",
1699 va_start(ap
,comment
);
1700 vfprintf(tracefh
,comment
,ap
);
1702 fprintf(tracefh
,"\n");
1704 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1705 we may be generating 64bit ones, we should put the hi-32bits of the
1706 address into the comment field. */
1708 /* TODO: Provide a buffer for the trace lines. We can then avoid
1709 performing writes until the buffer is filled, or the file is
1712 /* NOTE: We could consider adding a comment field to the "din" file
1713 produced using type 3 markers (unknown access). This would then
1714 allow information about the program that the "din" is for, and
1715 the MIPs world that was being simulated, to be placed into the
1722 /*---------------------------------------------------------------------------*/
1723 /*-- simulator engine -------------------------------------------------------*/
1724 /*---------------------------------------------------------------------------*/
1727 ColdReset (SIM_DESC sd
)
1730 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1732 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1733 /* RESET: Fixed PC address: */
1734 PC
= (unsigned_word
) UNSIGNED64 (0xFFFFFFFFBFC00000);
1735 /* The reset vector address is in the unmapped, uncached memory space. */
1737 SR
&= ~(status_SR
| status_TS
| status_RP
);
1738 SR
|= (status_ERL
| status_BEV
);
1740 /* Cheat and allow access to the complete register set immediately */
1741 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1742 && WITH_TARGET_WORD_BITSIZE
== 64)
1743 SR
|= status_FR
; /* 64bit registers */
1745 /* Ensure that any instructions with pending register updates are
1747 PENDING_INVALIDATE();
1749 /* Initialise the FPU registers to the unknown state */
1750 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1753 for (rn
= 0; (rn
< 32); rn
++)
1754 FPR_STATE
[rn
] = fmt_uninterpreted
;
1760 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1761 /* Signal an exception condition. This will result in an exception
1762 that aborts the instruction. The instruction operation pseudocode
1763 will never see a return from this function call. */
1766 signal_exception (SIM_DESC sd
,
1774 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1777 /* Ensure that any active atomic read/modify/write operation will fail: */
1780 switch (exception
) {
1782 case DebugBreakPoint
:
1783 if (! (Debug
& Debug_DM
))
1789 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1790 DEPC
= cia
- 4; /* reference the branch instruction */
1794 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1798 Debug
|= Debug_DM
; /* in debugging mode */
1799 Debug
|= Debug_DBp
; /* raising a DBp exception */
1801 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1805 case ReservedInstruction
:
1808 unsigned int instruction
;
1809 va_start(ap
,exception
);
1810 instruction
= va_arg(ap
,unsigned int);
1812 /* Provide simple monitor support using ReservedInstruction
1813 exceptions. The following code simulates the fixed vector
1814 entry points into the IDT monitor by causing a simulator
1815 trap, performing the monitor operation, and returning to
1816 the address held in the $ra register (standard PCS return
1817 address). This means we only need to pre-load the vector
1818 space with suitable instruction values. For systems were
1819 actual trap instructions are used, we would not need to
1820 perform this magic. */
1821 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1823 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
1824 /* NOTE: This assumes that a branch-and-link style
1825 instruction was used to enter the vector (which is the
1826 case with the current IDT monitor). */
1827 sim_engine_restart (SD
, CPU
, NULL
, RA
);
1829 /* Look for the mips16 entry and exit instructions, and
1830 simulate a handler for them. */
1831 else if ((cia
& 1) != 0
1832 && (instruction
& 0xf81f) == 0xe809
1833 && (instruction
& 0x0c0) != 0x0c0)
1835 mips16_entry (SD
, CPU
, cia
, instruction
);
1836 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1838 /* else fall through to normal exception processing */
1839 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
1844 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1846 /* Keep a copy of the current A0 in-case this is the program exit
1850 unsigned int instruction
;
1851 va_start(ap
, exception
);
1852 instruction
= va_arg(ap
,unsigned int);
1854 /* Check for our special terminating BREAK: */
1855 if ((instruction
& HALT_INSTRUCTION_MASK
) == (HALT_INSTRUCTION
& HALT_INSTRUCTION_MASK
) ||
1856 (instruction
& HALT_INSTRUCTION_MASK
) == (HALT_INSTRUCTION2
& HALT_INSTRUCTION_MASK
))
1858 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1859 sim_exited
, (unsigned int)(A0
& 0xFFFFFFFF));
1862 if (STATE
& simDELAYSLOT
)
1863 PC
= cia
- 4; /* reference the branch instruction */
1866 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1867 sim_stopped
, SIM_SIGTRAP
);
1870 /* Store exception code into current exception id variable (used
1873 /* TODO: If not simulating exceptions then stop the simulator
1874 execution. At the moment we always stop the simulation. */
1876 #ifdef SUBTARGET_R3900
1877 /* update interrupt-related registers */
1879 /* insert exception code in bits 6:2 */
1880 CAUSE
= LSMASKED32(CAUSE
, 31, 7) | LSINSERTED32(exception
, 6, 2);
1881 /* shift IE/KU history bits left */
1882 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 3, 0), 5, 2);
1884 if (STATE
& simDELAYSLOT
)
1886 STATE
&= ~simDELAYSLOT
;
1888 EPC
= (cia
- 4); /* reference the branch instruction */
1893 if (SR
& status_BEV
)
1894 PC
= (signed)0xBFC00000 + 0x180;
1896 PC
= (signed)0x80000000 + 0x080;
1898 /* See figure 5-17 for an outline of the code below */
1899 if (! (SR
& status_EXL
))
1901 CAUSE
= (exception
<< 2);
1902 if (STATE
& simDELAYSLOT
)
1904 STATE
&= ~simDELAYSLOT
;
1906 EPC
= (cia
- 4); /* reference the branch instruction */
1910 /* FIXME: TLB et.al. */
1911 /* vector = 0x180; */
1915 CAUSE
= (exception
<< 2);
1916 /* vector = 0x180; */
1919 /* Store exception code into current exception id variable (used
1922 if (SR
& status_BEV
)
1923 PC
= (signed)0xBFC00200 + 0x180;
1925 PC
= (signed)0x80000000 + 0x180;
1928 switch ((CAUSE
>> 2) & 0x1F)
1931 /* Interrupts arrive during event processing, no need to
1937 #ifdef SUBTARGET_3900
1938 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1939 PC
= (signed)0xBFC00000;
1940 #endif SUBTARGET_3900
1943 case TLBModification
:
1948 case InstructionFetch
:
1950 /* The following is so that the simulator will continue from the
1951 exception address on breakpoint operations. */
1953 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1954 sim_stopped
, SIM_SIGBUS
);
1956 case ReservedInstruction
:
1957 case CoProcessorUnusable
:
1959 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1960 sim_stopped
, SIM_SIGILL
);
1962 case IntegerOverflow
:
1964 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1965 sim_stopped
, SIM_SIGFPE
);
1969 sim_engine_restart (SD
, CPU
, NULL
, PC
);
1974 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1975 sim_stopped
, SIM_SIGTRAP
);
1979 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1980 "FATAL: Should not encounter a breakpoint\n");
1982 default : /* Unknown internal exception */
1984 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1985 sim_stopped
, SIM_SIGABRT
);
1989 case SimulatorFault
:
1993 va_start(ap
,exception
);
1994 msg
= va_arg(ap
,char *);
1996 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1997 "FATAL: Simulator error \"%s\"\n",msg
);
2004 #if defined(WARN_RESULT)
2005 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2006 /* This function indicates that the result of the operation is
2007 undefined. However, this should not affect the instruction
2008 stream. All that is meant to happen is that the destination
2009 register is set to an undefined result. To keep the simulator
2010 simple, we just don't bother updating the destination register, so
2011 the overall result will be undefined. If desired we can stop the
2012 simulator by raising a pseudo-exception. */
2013 #define UndefinedResult() undefined_result (sd,cia)
2015 undefined_result(sd
,cia
)
2019 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
2020 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2025 #endif /* WARN_RESULT */
2027 /*-- FPU support routines ---------------------------------------------------*/
2029 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
2030 formats conform to ANSI/IEEE Std 754-1985. */
2031 /* SINGLE precision floating:
2032 * seeeeeeeefffffffffffffffffffffff
2034 * e = 8bits = exponent
2035 * f = 23bits = fraction
2037 /* SINGLE precision fixed:
2038 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2040 * i = 31bits = integer
2042 /* DOUBLE precision floating:
2043 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
2045 * e = 11bits = exponent
2046 * f = 52bits = fraction
2048 /* DOUBLE precision fixed:
2049 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2051 * i = 63bits = integer
2054 /* Extract sign-bit: */
2055 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
2056 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
2057 /* Extract biased exponent: */
2058 #define FP_S_be(v) (((v) >> 23) & 0xFF)
2059 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
2060 /* Extract unbiased Exponent: */
2061 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
2062 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
2063 /* Extract complete fraction field: */
2064 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
2065 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
2066 /* Extract numbered fraction bit: */
2067 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
2068 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
2070 /* Explicit QNaN values used when value required: */
2071 #define FPQNaN_SINGLE (0x7FBFFFFF)
2072 #define FPQNaN_WORD (0x7FFFFFFF)
2073 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
2074 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
2076 /* Explicit Infinity values used when required: */
2077 #define FPINF_SINGLE (0x7F800000)
2078 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
2080 #if 1 /* def DEBUG */
2081 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
2082 #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>"))))))
2086 value_fpr (SIM_DESC sd
,
2095 /* Treat unused register values, as fixed-point 64bit values: */
2096 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
2098 /* If request to read data as "uninterpreted", then use the current
2100 fmt
= FPR_STATE
[fpr
];
2105 /* For values not yet accessed, set to the desired format: */
2106 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
2107 FPR_STATE
[fpr
] = fmt
;
2109 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
2112 if (fmt
!= FPR_STATE
[fpr
]) {
2113 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
));
2114 FPR_STATE
[fpr
] = fmt_unknown
;
2117 if (FPR_STATE
[fpr
] == fmt_unknown
) {
2118 /* Set QNaN value: */
2121 value
= FPQNaN_SINGLE
;
2125 value
= FPQNaN_DOUBLE
;
2129 value
= FPQNaN_WORD
;
2133 value
= FPQNaN_LONG
;
2140 } else if (SizeFGR() == 64) {
2144 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2147 case fmt_uninterpreted
:
2161 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2164 case fmt_uninterpreted
:
2167 if ((fpr
& 1) == 0) { /* even registers only */
2168 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
2170 SignalException(ReservedInstruction
,0);
2181 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2184 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());
2191 store_fpr (SIM_DESC sd
,
2201 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());
2204 if (SizeFGR() == 64) {
2206 case fmt_uninterpreted_32
:
2207 fmt
= fmt_uninterpreted
;
2210 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2211 FPR_STATE
[fpr
] = fmt
;
2214 case fmt_uninterpreted_64
:
2215 fmt
= fmt_uninterpreted
;
2216 case fmt_uninterpreted
:
2220 FPR_STATE
[fpr
] = fmt
;
2224 FPR_STATE
[fpr
] = fmt_unknown
;
2230 case fmt_uninterpreted_32
:
2231 fmt
= fmt_uninterpreted
;
2234 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2235 FPR_STATE
[fpr
] = fmt
;
2238 case fmt_uninterpreted_64
:
2239 fmt
= fmt_uninterpreted
;
2240 case fmt_uninterpreted
:
2243 if ((fpr
& 1) == 0) { /* even register number only */
2244 FGR
[fpr
+1] = (value
>> 32);
2245 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2246 FPR_STATE
[fpr
+ 1] = fmt
;
2247 FPR_STATE
[fpr
] = fmt
;
2249 FPR_STATE
[fpr
] = fmt_unknown
;
2250 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2251 SignalException(ReservedInstruction
,0);
2256 FPR_STATE
[fpr
] = fmt_unknown
;
2261 #if defined(WARN_RESULT)
2264 #endif /* WARN_RESULT */
2267 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2270 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_addr(FGR
[fpr
]),DOFMT(fmt
));
2287 sim_fpu_32to (&wop
, op
);
2288 boolean
= sim_fpu_is_nan (&wop
);
2295 sim_fpu_64to (&wop
, op
);
2296 boolean
= sim_fpu_is_nan (&wop
);
2300 fprintf (stderr
, "Bad switch\n");
2305 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2319 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2326 sim_fpu_32to (&wop
, op
);
2327 boolean
= sim_fpu_is_infinity (&wop
);
2333 sim_fpu_64to (&wop
, op
);
2334 boolean
= sim_fpu_is_infinity (&wop
);
2338 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2343 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2357 /* Argument checking already performed by the FPCOMPARE code */
2360 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2363 /* The format type should already have been checked: */
2369 sim_fpu_32to (&wop1
, op1
);
2370 sim_fpu_32to (&wop2
, op2
);
2371 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2378 sim_fpu_64to (&wop1
, op1
);
2379 sim_fpu_64to (&wop2
, op2
);
2380 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2384 fprintf (stderr
, "Bad switch\n");
2389 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2403 /* Argument checking already performed by the FPCOMPARE code */
2406 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2409 /* The format type should already have been checked: */
2415 sim_fpu_32to (&wop1
, op1
);
2416 sim_fpu_32to (&wop2
, op2
);
2417 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2424 sim_fpu_64to (&wop1
, op1
);
2425 sim_fpu_64to (&wop2
, op2
);
2426 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2430 fprintf (stderr
, "Bad switch\n");
2435 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2442 AbsoluteValue(op
,fmt
)
2449 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2452 /* The format type should already have been checked: */
2458 sim_fpu_32to (&wop
, op
);
2459 sim_fpu_abs (&wop
, &wop
);
2460 sim_fpu_to32 (&ans
, &wop
);
2468 sim_fpu_64to (&wop
, op
);
2469 sim_fpu_abs (&wop
, &wop
);
2470 sim_fpu_to64 (&ans
, &wop
);
2475 fprintf (stderr
, "Bad switch\n");
2490 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2493 /* The format type should already have been checked: */
2499 sim_fpu_32to (&wop
, op
);
2500 sim_fpu_neg (&wop
, &wop
);
2501 sim_fpu_to32 (&ans
, &wop
);
2509 sim_fpu_64to (&wop
, op
);
2510 sim_fpu_neg (&wop
, &wop
);
2511 sim_fpu_to64 (&ans
, &wop
);
2516 fprintf (stderr
, "Bad switch\n");
2532 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2535 /* The registers must specify FPRs valid for operands of type
2536 "fmt". If they are not valid, the result is undefined. */
2538 /* The format type should already have been checked: */
2546 sim_fpu_32to (&wop1
, op1
);
2547 sim_fpu_32to (&wop2
, op2
);
2548 sim_fpu_add (&ans
, &wop1
, &wop2
);
2549 sim_fpu_to32 (&res
, &ans
);
2559 sim_fpu_64to (&wop1
, op1
);
2560 sim_fpu_64to (&wop2
, op2
);
2561 sim_fpu_add (&ans
, &wop1
, &wop2
);
2562 sim_fpu_to64 (&res
, &ans
);
2567 fprintf (stderr
, "Bad switch\n");
2572 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2587 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2590 /* The registers must specify FPRs valid for operands of type
2591 "fmt". If they are not valid, the result is undefined. */
2593 /* The format type should already have been checked: */
2601 sim_fpu_32to (&wop1
, op1
);
2602 sim_fpu_32to (&wop2
, op2
);
2603 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2604 sim_fpu_to32 (&res
, &ans
);
2614 sim_fpu_64to (&wop1
, op1
);
2615 sim_fpu_64to (&wop2
, op2
);
2616 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2617 sim_fpu_to64 (&res
, &ans
);
2622 fprintf (stderr
, "Bad switch\n");
2627 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2634 Multiply(op1
,op2
,fmt
)
2642 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2645 /* The registers must specify FPRs valid for operands of type
2646 "fmt". If they are not valid, the result is undefined. */
2648 /* The format type should already have been checked: */
2656 sim_fpu_32to (&wop1
, op1
);
2657 sim_fpu_32to (&wop2
, op2
);
2658 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2659 sim_fpu_to32 (&res
, &ans
);
2669 sim_fpu_64to (&wop1
, op1
);
2670 sim_fpu_64to (&wop2
, op2
);
2671 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2672 sim_fpu_to64 (&res
, &ans
);
2677 fprintf (stderr
, "Bad switch\n");
2682 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2697 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2700 /* The registers must specify FPRs valid for operands of type
2701 "fmt". If they are not valid, the result is undefined. */
2703 /* The format type should already have been checked: */
2711 sim_fpu_32to (&wop1
, op1
);
2712 sim_fpu_32to (&wop2
, op2
);
2713 sim_fpu_div (&ans
, &wop1
, &wop2
);
2714 sim_fpu_to32 (&res
, &ans
);
2724 sim_fpu_64to (&wop1
, op1
);
2725 sim_fpu_64to (&wop2
, op2
);
2726 sim_fpu_div (&ans
, &wop1
, &wop2
);
2727 sim_fpu_to64 (&res
, &ans
);
2732 fprintf (stderr
, "Bad switch\n");
2737 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2751 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2754 /* The registers must specify FPRs valid for operands of type
2755 "fmt". If they are not valid, the result is undefined. */
2757 /* The format type should already have been checked: */
2764 sim_fpu_32to (&wop
, op
);
2765 sim_fpu_inv (&ans
, &wop
);
2766 sim_fpu_to32 (&res
, &ans
);
2775 sim_fpu_64to (&wop
, op
);
2776 sim_fpu_inv (&ans
, &wop
);
2777 sim_fpu_to64 (&res
, &ans
);
2782 fprintf (stderr
, "Bad switch\n");
2787 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2801 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2804 /* The registers must specify FPRs valid for operands of type
2805 "fmt". If they are not valid, the result is undefined. */
2807 /* The format type should already have been checked: */
2814 sim_fpu_32to (&wop
, op
);
2815 sim_fpu_sqrt (&ans
, &wop
);
2816 sim_fpu_to32 (&res
, &ans
);
2825 sim_fpu_64to (&wop
, op
);
2826 sim_fpu_sqrt (&ans
, &wop
);
2827 sim_fpu_to64 (&res
, &ans
);
2832 fprintf (stderr
, "Bad switch\n");
2837 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2853 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2856 /* The registers must specify FPRs valid for operands of type
2857 "fmt". If they are not valid, the result is undefined. */
2859 /* The format type should already have been checked: */
2866 sim_fpu_32to (&wop1
, op1
);
2867 sim_fpu_32to (&wop2
, op2
);
2868 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2875 sim_fpu_64to (&wop1
, op1
);
2876 sim_fpu_64to (&wop2
, op2
);
2877 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2881 fprintf (stderr
, "Bad switch\n");
2887 case SIM_FPU_IS_SNAN
:
2888 case SIM_FPU_IS_QNAN
:
2890 case SIM_FPU_IS_NINF
:
2891 case SIM_FPU_IS_NNUMBER
:
2892 case SIM_FPU_IS_NDENORM
:
2893 case SIM_FPU_IS_NZERO
:
2894 result
= op2
; /* op1 - op2 < 0 */
2895 case SIM_FPU_IS_PINF
:
2896 case SIM_FPU_IS_PNUMBER
:
2897 case SIM_FPU_IS_PDENORM
:
2898 case SIM_FPU_IS_PZERO
:
2899 result
= op1
; /* op1 - op2 > 0 */
2901 fprintf (stderr
, "Bad switch\n");
2906 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2923 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2926 /* The registers must specify FPRs valid for operands of type
2927 "fmt". If they are not valid, the result is undefined. */
2929 /* The format type should already have been checked: */
2936 sim_fpu_32to (&wop1
, op1
);
2937 sim_fpu_32to (&wop2
, op2
);
2938 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2945 sim_fpu_64to (&wop1
, op1
);
2946 sim_fpu_64to (&wop2
, op2
);
2947 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2951 fprintf (stderr
, "Bad switch\n");
2957 case SIM_FPU_IS_SNAN
:
2958 case SIM_FPU_IS_QNAN
:
2960 case SIM_FPU_IS_NINF
:
2961 case SIM_FPU_IS_NNUMBER
:
2962 case SIM_FPU_IS_NDENORM
:
2963 case SIM_FPU_IS_NZERO
:
2964 result
= op1
; /* op1 - op2 < 0 */
2965 case SIM_FPU_IS_PINF
:
2966 case SIM_FPU_IS_PNUMBER
:
2967 case SIM_FPU_IS_PDENORM
:
2968 case SIM_FPU_IS_PZERO
:
2969 result
= op2
; /* op1 - op2 > 0 */
2971 fprintf (stderr
, "Bad switch\n");
2976 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2984 convert (SIM_DESC sd
,
2993 sim_fpu_round round
;
2994 unsigned32 result32
;
2995 unsigned64 result64
;
2998 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
));
3004 /* Round result to nearest representable value. When two
3005 representable values are equally near, round to the value
3006 that has a least significant bit of zero (i.e. is even). */
3007 round
= sim_fpu_round_near
;
3010 /* Round result to the value closest to, and not greater in
3011 magnitude than, the result. */
3012 round
= sim_fpu_round_zero
;
3015 /* Round result to the value closest to, and not less than,
3017 round
= sim_fpu_round_up
;
3021 /* Round result to the value closest to, and not greater than,
3023 round
= sim_fpu_round_down
;
3027 fprintf (stderr
, "Bad switch\n");
3031 /* Convert the input to sim_fpu internal format */
3035 sim_fpu_64to (&wop
, op
);
3038 sim_fpu_32to (&wop
, op
);
3041 sim_fpu_i32to (&wop
, op
, round
);
3044 sim_fpu_i64to (&wop
, op
, round
);
3047 fprintf (stderr
, "Bad switch\n");
3051 /* Convert sim_fpu format into the output */
3052 /* The value WOP is converted to the destination format, rounding
3053 using mode RM. When the destination is a fixed-point format, then
3054 a source value of Infinity, NaN or one which would round to an
3055 integer outside the fixed point range then an IEEE Invalid
3056 Operation condition is raised. */
3060 sim_fpu_round_32 (&wop
, round
, 0);
3061 sim_fpu_to32 (&result32
, &wop
);
3062 result64
= result32
;
3065 sim_fpu_round_64 (&wop
, round
, 0);
3066 sim_fpu_to64 (&result64
, &wop
);
3069 sim_fpu_to32i (&result32
, &wop
, round
);
3070 result64
= result32
;
3073 sim_fpu_to64i (&result64
, &wop
, round
);
3077 fprintf (stderr
, "Bad switch\n");
3082 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
3089 /*-- co-processor support routines ------------------------------------------*/
3092 CoProcPresent(coproc_number
)
3093 unsigned int coproc_number
;
3095 /* Return TRUE if simulator provides a model for the given co-processor number */
3100 cop_lw (SIM_DESC sd
,
3105 unsigned int memword
)
3110 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3113 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
3115 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
3116 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
3121 #if 0 /* this should be controlled by a configuration option */
3122 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
));
3131 cop_ld (SIM_DESC sd
,
3138 switch (coproc_num
) {
3140 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3142 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
3147 #if 0 /* this message should be controlled by a configuration option */
3148 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
));
3157 /* start-sanitize-sky */
3160 cop_lq (SIM_DESC sd
,
3165 unsigned128 memword
)
3176 /* one word at a time, argh! */
3180 value
= H2T_4(*A4_16(& memword
, 3-i
));
3181 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3187 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3188 coproc_num
,coproc_reg
,pr_addr(cia
));
3194 #endif /* TARGET_SKY */
3195 /* end-sanitize-sky */
3199 cop_sw (SIM_DESC sd
,
3205 unsigned int value
= 0;
3210 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3213 hold
= FPR_STATE
[coproc_reg
];
3214 FPR_STATE
[coproc_reg
] = fmt_word
;
3215 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3216 FPR_STATE
[coproc_reg
] = hold
;
3221 #if 0 /* should be controlled by configuration option */
3222 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3231 cop_sd (SIM_DESC sd
,
3241 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3243 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3248 #if 0 /* should be controlled by configuration option */
3249 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3258 /* start-sanitize-sky */
3261 cop_sq (SIM_DESC sd
,
3267 unsigned128 value
= U16_8(0, 0);
3278 /* one word at a time, argh! */
3282 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3283 *A4_16(& xyzw
, 3-i
) = T2H_4(value
);
3290 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3291 coproc_num
,coproc_reg
,pr_addr(cia
));
3297 #endif /* TARGET_SKY */
3298 /* end-sanitize-sky */
3302 decode_coproc (SIM_DESC sd
,
3305 unsigned int instruction
)
3307 int coprocnum
= ((instruction
>> 26) & 3);
3311 case 0: /* standard CPU control and cache registers */
3313 int code
= ((instruction
>> 21) & 0x1F);
3314 /* R4000 Users Manual (second edition) lists the following CP0
3316 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3317 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3318 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3319 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3320 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3321 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3322 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3323 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3324 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3325 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3327 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0))
3329 int rt
= ((instruction
>> 16) & 0x1F);
3330 int rd
= ((instruction
>> 11) & 0x1F);
3332 switch (rd
) /* NOTEs: Standard CP0 registers */
3334 /* 0 = Index R4000 VR4100 VR4300 */
3335 /* 1 = Random R4000 VR4100 VR4300 */
3336 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3337 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3338 /* 4 = Context R4000 VR4100 VR4300 */
3339 /* 5 = PageMask R4000 VR4100 VR4300 */
3340 /* 6 = Wired R4000 VR4100 VR4300 */
3341 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3342 /* 9 = Count R4000 VR4100 VR4300 */
3343 /* 10 = EntryHi R4000 VR4100 VR4300 */
3344 /* 11 = Compare R4000 VR4100 VR4300 */
3345 /* 12 = SR R4000 VR4100 VR4300 */
3346 #ifdef SUBTARGET_R3900
3350 /* 3 = Config R3900 */
3351 #endif /* SUBTARGET_R3900 */
3358 /* 13 = Cause R4000 VR4100 VR4300 */
3365 /* 14 = EPC R4000 VR4100 VR4300 */
3368 GPR
[rt
] = (signed_word
) (signed_address
) EPC
;
3372 /* 15 = PRId R4000 VR4100 VR4300 */
3373 #ifdef SUBTARGET_R3900
3382 /* 16 = Config R4000 VR4100 VR4300 */
3385 GPR
[rt
] = C0_CONFIG
;
3387 C0_CONFIG
= GPR
[rt
];
3390 #ifdef SUBTARGET_R3900
3399 /* 17 = LLAddr R4000 VR4100 VR4300 */
3401 /* 18 = WatchLo R4000 VR4100 VR4300 */
3402 /* 19 = WatchHi R4000 VR4100 VR4300 */
3403 /* 20 = XContext R4000 VR4100 VR4300 */
3404 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3405 /* 27 = CacheErr R4000 VR4100 */
3406 /* 28 = TagLo R4000 VR4100 VR4300 */
3407 /* 29 = TagHi R4000 VR4100 VR4300 */
3408 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3409 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3410 /* CPR[0,rd] = GPR[rt]; */
3413 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3415 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3418 else if (code
== 0x10 && (instruction
& 0x3f) == 0x18)
3421 if (SR
& status_ERL
)
3423 /* Oops, not yet available */
3424 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3434 else if (code
== 0x10 && (instruction
& 0x3f) == 0x10)
3437 #ifdef SUBTARGET_R3900
3438 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
3440 /* shift IE/KU history bits right */
3441 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 5, 2), 3, 0);
3443 /* TODO: CACHE register */
3444 #endif /* SUBTARGET_R3900 */
3446 else if (code
== 0x10 && (instruction
& 0x3f) == 0x1F)
3454 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3455 /* TODO: When executing an ERET or RFE instruction we should
3456 clear LLBIT, to ensure that any out-standing atomic
3457 read/modify/write sequence fails. */
3461 case 2: /* co-processor 2 */
3465 /* start-sanitize-sky */
3467 /* On the R5900, this refers to a "VU" vector co-processor. */
3469 int i_25_21
= (instruction
>> 21) & 0x1f;
3470 int i_20_16
= (instruction
>> 16) & 0x1f;
3471 int i_20_6
= (instruction
>> 6) & 0x7fff;
3472 int i_15_11
= (instruction
>> 11) & 0x1f;
3473 int i_15_0
= instruction
& 0xffff;
3474 int i_10_1
= (instruction
>> 1) & 0x3ff;
3475 int i_10_0
= instruction
& 0x7ff;
3476 int i_10_6
= (instruction
>> 6) & 0x1f;
3477 int i_5_0
= instruction
& 0x03f;
3478 int interlock
= instruction
& 0x01;
3479 /* setup for semantic.c-like actions below */
3480 typedef unsigned_4 instruction_word
;
3486 /* test COP2 usability */
3487 if(! (SR
& status_CU2
))
3489 SignalException(CoProcessorUnusable
,instruction
);
3493 #define MY_INDEX itable_COPz_NORMAL
3494 #define MY_PREFIX COPz_NORMAL
3495 #define MY_NAME "COPz_NORMAL"
3497 /* classify & execute basic COP2 instructions */
3498 if(i_25_21
== 0x08 && i_20_16
== 0x00) /* BC2F */
3500 address_word offset
= EXTEND16(i_15_0
) << 2;
3501 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3503 else if(i_25_21
== 0x08 && i_20_16
==0x02) /* BC2FL */
3505 address_word offset
= EXTEND16(i_15_0
) << 2;
3506 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3507 else NULLIFY_NEXT_INSTRUCTION();
3509 else if(i_25_21
== 0x08 && i_20_16
== 0x01) /* BC2T */
3511 address_word offset
= EXTEND16(i_15_0
) << 2;
3512 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3514 else if(i_25_21
== 0x08 && i_20_16
== 0x03) /* BC2TL */
3516 address_word offset
= EXTEND16(i_15_0
) << 2;
3517 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3518 else NULLIFY_NEXT_INSTRUCTION();
3520 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3521 (i_25_21
== 0x01)) /* QMFC2 */
3526 /* interlock checking */
3527 /* POLICY: never busy in macro mode */
3528 while(vu0_busy() && interlock
)
3531 /* perform VU register address */
3532 if(i_25_21
== 0x01) /* QMFC2 */
3535 /* one word at a time, argh! */
3536 read_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3537 read_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3538 read_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3539 read_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3540 GPR
[rt
] = T2H_8(* A8_16(& xyzw
, 1));
3541 GPR1
[rt
] = T2H_8(* A8_16(& xyzw
, 0));
3546 /* enum + int calculation, argh! */
3547 id
= VU_REG_MST
+ 16 * id
;
3548 if (id
>= VU_REG_CMSAR0
)
3549 read_vu_special_reg(&vu0_device
, id
, & data
);
3551 read_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3552 GPR
[rt
] = EXTEND32(T2H_4(data
));
3555 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3556 (i_25_21
== 0x05)) /* QMTC2 */
3561 /* interlock checking: wait until M or E bits set */
3562 /* POLICY: never busy in macro mode */
3563 while(vu0_busy() && interlock
)
3565 if(vu0_micro_interlock_released())
3567 vu0_micro_interlock_clear();
3574 /* perform VU register address */
3575 if(i_25_21
== 0x05) /* QMTC2 */
3577 unsigned_16 xyzw
= U16_8(GPR1
[rt
], GPR
[rt
]);
3579 xyzw
= H2T_16(xyzw
);
3580 /* one word at a time, argh! */
3581 write_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3582 write_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3583 write_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3584 write_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3588 unsigned_4 data
= H2T_4(GPR
[rt
]);
3589 /* enum + int calculation, argh! */
3590 id
= VU_REG_VI
+ 16 * id
;
3591 if (id
>= VU_REG_CMSAR0
)
3592 write_vu_special_reg(&vu0_device
, id
, & data
);
3594 write_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3597 else if(i_10_0
== 0x3bf) /* VWAITQ */
3602 else if(i_5_0
== 0x38) /* VCALLMS */
3604 unsigned_4 data
= H2T_2(i_20_6
);
3609 /* write to reserved CIA register to get VU0 moving */
3610 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3614 else if(i_5_0
== 0x39) /* VCALLMSR */
3621 read_vu_special_reg(& vu0_device
, VU_REG_CMSAR0
, & data
);
3622 /* write to reserved CIA register to get VU0 moving */
3623 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3627 /* handle all remaining UPPER VU instructions in one block */
3628 else if((i_5_0
< 0x30) || /* VADDx .. VMINI */
3629 (i_5_0
>= 0x3c && i_10_6
< 0x0c)) /* VADDAx .. VNOP */
3631 unsigned_4 vu_upper
, vu_lower
;
3633 0x00000000 | /* bits 31 .. 25 */
3634 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3635 vu_lower
= 0x8000033c; /* NOP */
3637 /* POLICY: never busy in macro mode */
3641 vu0_macro_issue(vu_upper
, vu_lower
);
3643 /* POLICY: wait for completion of macro-instruction */
3647 /* handle all remaining LOWER VU instructions in one block */
3648 else if((i_5_0
>= 0x30 && i_5_0
<= 0x35) || /* VIADD .. VIOR */
3649 (i_5_0
>= 0x3c && i_10_6
>= 0x0c)) /* VMOVE .. VRXOR */
3650 { /* N.B.: VWAITQ already covered by prior case */
3651 unsigned_4 vu_upper
, vu_lower
;
3652 vu_upper
= 0x000002ff; /* NOP/NOP */
3654 0x80000000 | /* bits 31 .. 25 */
3655 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3657 /* POLICY: never busy in macro mode */
3661 vu0_macro_issue(vu_upper
, vu_lower
);
3663 /* POLICY: wait for completion of macro-instruction */
3667 /* ... no other COP2 instructions ... */
3670 SignalException(ReservedInstruction
, instruction
);
3674 /* cleanup for semantic.c-like actions above */
3681 #endif /* TARGET_SKY */
3682 /* end-sanitize-sky */
3686 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3687 instruction
,pr_addr(cia
));
3692 case 1: /* should not occur (FPU co-processor) */
3693 case 3: /* should not occur (FPU co-processor) */
3694 SignalException(ReservedInstruction
,instruction
);
3702 /*-- instruction simulation -------------------------------------------------*/
3704 /* When the IGEN simulator is being built, the function below is be
3705 replaced by a generated version. However, WITH_IGEN == 2 indicates
3706 that the fubction below should be compiled but under a different
3707 name (to allow backward compatibility) */
3709 #if (WITH_IGEN != 1)
3711 void old_engine_run
PARAMS ((SIM_DESC sd
, int next_cpu_nr
, int siggnal
));
3713 old_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3716 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3719 int next_cpu_nr
; /* ignore */
3720 int nr_cpus
; /* ignore */
3721 int siggnal
; /* ignore */
3723 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* hardwire to cpu 0 */
3724 #if !defined(FASTSIM)
3725 unsigned int pipeline_count
= 1;
3729 if (STATE_MEMORY (sd
) == NULL
) {
3730 printf("DBG: simulate() entered with no memory\n");
3735 #if 0 /* Disabled to check that everything works OK */
3736 /* The VR4300 seems to sign-extend the PC on its first
3737 access. However, this may just be because it is currently
3738 configured in 32bit mode. However... */
3739 PC
= SIGNEXTEND(PC
,32);
3742 /* main controlling loop */
3744 /* vaddr is slowly being replaced with cia - current instruction
3746 address_word cia
= (uword64
)PC
;
3747 address_word vaddr
= cia
;
3750 unsigned int instruction
; /* uword64? what's this used for? FIXME! */
3754 printf("DBG: state = 0x%08X :",state
);
3755 if (state
& simHALTEX
) printf(" simHALTEX");
3756 if (state
& simHALTIN
) printf(" simHALTIN");
3761 DSSTATE
= (STATE
& simDELAYSLOT
);
3764 sim_io_printf(sd
,"DBG: DSPC = 0x%s\n",pr_addr(DSPC
));
3767 /* Fetch the next instruction from the simulator memory: */
3768 if (AddressTranslation(cia
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) {
3769 if ((vaddr
& 1) == 0) {
3770 /* Copy the action of the LW instruction */
3771 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3772 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3775 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3776 LoadMemory(&value
,NULL
,cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3777 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3778 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3780 /* Copy the action of the LH instruction */
3781 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 1) : 0);
3782 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 1) : 0);
3785 paddr
= (((paddr
& ~ (uword64
) 1) & ~LOADDRMASK
)
3786 | (((paddr
& ~ (uword64
) 1) & LOADDRMASK
) ^ (reverse
<< 1)));
3787 LoadMemory(&value
,NULL
,cca
, AccessLength_HALFWORD
,
3788 paddr
& ~ (uword64
) 1,
3789 vaddr
, isINSTRUCTION
, isREAL
);
3790 byte
= (((vaddr
&~ (uword64
) 1) & LOADDRMASK
) ^ (bigend
<< 1));
3791 instruction
= ((value
>> (8 * byte
)) & 0xFFFF);
3794 fprintf(stderr
,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC
));
3799 sim_io_printf(sd
,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction
,pr_addr(PC
));
3802 /* This is required by exception processing, to ensure that we can
3803 cope with exceptions in the delay slots of branches that may
3804 already have changed the PC. */
3805 if ((vaddr
& 1) == 0)
3806 PC
+= 4; /* increment ready for the next fetch */
3809 /* NOTE: If we perform a delay slot change to the PC, this
3810 increment is not requuired. However, it would make the
3811 simulator more complicated to try and avoid this small hit. */
3813 /* Currently this code provides a simple model. For more
3814 complicated models we could perform exception status checks at
3815 this point, and set the simSTOP state as required. This could
3816 also include processing any hardware interrupts raised by any
3817 I/O model attached to the simulator context.
3819 Support for "asynchronous" I/O events within the simulated world
3820 could be providing by managing a counter, and calling a I/O
3821 specific handler when a particular threshold is reached. On most
3822 architectures a decrement and check for zero operation is
3823 usually quicker than an increment and compare. However, the
3824 process of managing a known value decrement to zero, is higher
3825 than the cost of using an explicit value UINT_MAX into the
3826 future. Which system is used will depend on how complicated the
3827 I/O model is, and how much it is likely to affect the simulator
3830 If events need to be scheduled further in the future than
3831 UINT_MAX event ticks, then the I/O model should just provide its
3832 own counter, triggered from the event system. */
3834 /* MIPS pipeline ticks. To allow for future support where the
3835 pipeline hit of individual instructions is known, this control
3836 loop manages a "pipeline_count" variable. It is initialised to
3837 1 (one), and will only be changed by the simulator engine when
3838 executing an instruction. If the engine does not have access to
3839 pipeline cycle count information then all instructions will be
3840 treated as using a single cycle. NOTE: A standard system is not
3841 provided by the default simulator because different MIPS
3842 architectures have different cycle counts for the same
3845 [NOTE: pipeline_count has been replaced the event queue] */
3847 /* shuffle the floating point status pipeline state */
3848 ENGINE_ISSUE_PREFIX_HOOK();
3850 /* NOTE: For multi-context simulation environments the "instruction"
3851 variable should be local to this routine. */
3853 /* Shorthand accesses for engine. Note: If we wanted to use global
3854 variables (and a single-threaded simulator engine), then we can
3855 create the actual variables with these names. */
3857 if (!(STATE
& simSKIPNEXT
)) {
3858 /* Include the simulator engine */
3859 #include "oengine.c"
3860 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3861 #error "Mismatch between run-time simulator code and simulation engine"
3863 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3864 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3866 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3867 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3870 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3871 should check for it being changed. It is better doing it here,
3872 than within the simulator, since it will help keep the simulator
3875 #if defined(WARN_ZERO)
3876 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
));
3877 #endif /* WARN_ZERO */
3878 ZERO
= 0; /* reset back to zero before next instruction */
3880 } else /* simSKIPNEXT check */
3881 STATE
&= ~simSKIPNEXT
;
3883 /* If the delay slot was active before the instruction is
3884 executed, then update the PC to its new value: */
3887 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC
));
3896 #if !defined(FASTSIM)
3897 if (sim_events_tickn (sd
, pipeline_count
))
3899 /* cpu->cia = cia; */
3900 sim_events_process (sd
);
3903 if (sim_events_tick (sd
))
3905 /* cpu->cia = cia; */
3906 sim_events_process (sd
);
3908 #endif /* FASTSIM */
3914 /* This code copied from gdb's utils.c. Would like to share this code,
3915 but don't know of a common place where both could get to it. */
3917 /* Temporary storage using circular buffer */
3923 static char buf
[NUMCELLS
][CELLSIZE
];
3925 if (++cell
>=NUMCELLS
) cell
=0;
3929 /* Print routines to handle variable size regs, etc */
3931 /* Eliminate warning from compiler on 32-bit systems */
3932 static int thirty_two
= 32;
3938 char *paddr_str
=get_cell();
3939 switch (sizeof(addr
))
3942 sprintf(paddr_str
,"%08lx%08lx",
3943 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3946 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
3949 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
3952 sprintf(paddr_str
,"%x",addr
);
3961 char *paddr_str
=get_cell();
3962 sprintf(paddr_str
,"%08lx%08lx",
3963 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3969 /*---------------------------------------------------------------------------*/
3970 /*> EOF interp.c <*/