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 */
466 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
, MONITOR_SIZE
);
467 /* For compatibility with the old code - under this (at level one)
468 are the kernel spaces K0 & K1. Both of these map to a single
469 smaller sub region */
470 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
471 /* start-sanitize-sky */
473 /* end-sanitize-sky */
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 */
480 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x",
482 MEM_SIZE
, /* actual size */
484 0); /* add alias at 0x0000 */
486 /* end-sanitize-sky */
491 /* start-sanitize-tx3904 */
494 && (strcmp(board
, BOARD_JMR3904
) == 0 ||
495 strcmp(board
, BOARD_JMR3904_DEBUG
) == 0))
497 /* match VIRTUAL memory layout of JMR-TX3904 board */
501 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
502 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
504 4 * 1024 * 1024, /* 4 MB */
507 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
508 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
510 4 * 1024 * 1024, /* 4 MB */
513 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
514 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
516 32 * 1024 * 1024, /* 32 MB */
519 /* --- simulated devices --- */
520 sim_hw_parse (sd
, "/tx3904irc@0xffffc00/reg 0xffffc000 0x20");
521 sim_hw_parse (sd
, "/tx3904cpu");
523 /* -- device connections --- */
524 sim_hw_parse (sd
, "/tx3904irc > ip level /tx3904cpu");
526 if(! strcmp(board
, BOARD_JMR3904_DEBUG
))
528 /* -- DEBUG: glue interrupt generators --- */
529 sim_hw_parse (sd
, "/glue@0xffff0000/reg 0xffff0000 0x50");
530 sim_hw_parse (sd
, "/glue@0xffff0000 > int0 int0 /tx3904irc");
531 sim_hw_parse (sd
, "/glue@0xffff0000 > int1 int1 /tx3904irc");
532 sim_hw_parse (sd
, "/glue@0xffff0000 > int2 int2 /tx3904irc");
533 sim_hw_parse (sd
, "/glue@0xffff0000 > int3 int3 /tx3904irc");
534 sim_hw_parse (sd
, "/glue@0xffff0000 > int4 int4 /tx3904irc");
535 sim_hw_parse (sd
, "/glue@0xffff0000 > int5 int5 /tx3904irc");
536 sim_hw_parse (sd
, "/glue@0xffff0000 > int6 int6 /tx3904irc");
537 sim_hw_parse (sd
, "/glue@0xffff0000 > int7 int7 /tx3904irc");
538 sim_hw_parse (sd
, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
539 sim_hw_parse (sd
, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
540 sim_hw_parse (sd
, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
541 sim_hw_parse (sd
, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
542 sim_hw_parse (sd
, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
543 sim_hw_parse (sd
, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
544 sim_hw_parse (sd
, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
545 sim_hw_parse (sd
, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
546 sim_hw_parse (sd
, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
547 sim_hw_parse (sd
, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
553 /* end-sanitize-tx3904 */
556 /* check for/establish the a reference program image */
557 if (sim_analyze_program (sd
,
558 (STATE_PROG_ARGV (sd
) != NULL
559 ? *STATE_PROG_ARGV (sd
)
563 sim_module_uninstall (sd
);
567 /* Configure/verify the target byte order and other runtime
568 configuration options */
569 if (sim_config (sd
) != SIM_RC_OK
)
571 sim_module_uninstall (sd
);
575 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
577 /* Uninstall the modules to avoid memory leaks,
578 file descriptor leaks, etc. */
579 sim_module_uninstall (sd
);
583 /* verify assumptions the simulator made about the host type system.
584 This macro does not return if there is a problem */
585 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
586 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
588 /* This is NASTY, in that we are assuming the size of specific
592 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
595 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
596 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ NR_FGR
)))
597 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
598 else if ((rn
>= 33) && (rn
<= 37))
599 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
600 else if ((rn
== SRIDX
)
603 || ((rn
>= 72) && (rn
<= 89)))
604 cpu
->register_widths
[rn
] = 32;
606 cpu
->register_widths
[rn
] = 0;
608 /* start-sanitize-r5900 */
610 /* set the 5900 "upper" registers to 64 bits */
611 for( rn
= LAST_EMBED_REGNUM
+1; rn
< NUM_REGS
; rn
++)
612 cpu
->register_widths
[rn
] = 64;
613 /* end-sanitize-r5900 */
615 /* start-sanitize-sky */
617 /* Now the VU registers */
618 for( rn
= 0; rn
< NUM_VU_INTEGER_REGS
; rn
++ ) {
619 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 16;
620 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 16;
623 for( rn
= NUM_VU_INTEGER_REGS
; rn
< NUM_VU_REGS
; rn
++ ) {
624 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
625 cpu
->register_widths
[rn
+ NUM_R5900_REGS
+ NUM_VU_REGS
] = 32;
628 /* Finally the VIF registers */
629 for( rn
= 2*NUM_VU_REGS
; rn
< 2*NUM_VU_REGS
+ 2*NUM_VIF_REGS
; rn
++ )
630 cpu
->register_widths
[rn
+ NUM_R5900_REGS
] = 32;
634 /* end-sanitize-sky */
638 if (STATE
& simTRACE
)
642 /* Write an abort sequence into the TRAP (common) exception vector
643 addresses. This is to catch code executing a TRAP (et.al.)
644 instruction without installing a trap handler. */
646 unsigned32 halt
[2] = { 0x2404002f /* addiu r4, r0, 47 */,
647 HALT_INSTRUCTION
/* BREAK */ };
650 sim_write (sd
, 0x80000180, (char *) halt
, sizeof (halt
));
651 sim_write (sd
, 0xBFC00380, (char *) halt
, sizeof (halt
));
655 /* Write the monitor trap address handlers into the monitor (eeprom)
656 address space. This can only be done once the target endianness
657 has been determined. */
660 /* Entry into the IDT monitor is via fixed address vectors, and
661 not using machine instructions. To avoid clashing with use of
662 the MIPS TRAP system, we place our own (simulator specific)
663 "undefined" instructions into the relevant vector slots. */
664 for (loop
= 0; (loop
< MONITOR_SIZE
); loop
+= 4)
666 address_word vaddr
= (MONITOR_BASE
+ loop
);
667 unsigned32 insn
= (RSVD_INSTRUCTION
| (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
) << RSVD_INSTRUCTION_ARG_SHIFT
));
669 sim_write (sd
, vaddr
, (char *)&insn
, sizeof (insn
));
671 /* The PMON monitor uses the same address space, but rather than
672 branching into it the address of a routine is loaded. We can
673 cheat for the moment, and direct the PMON routine to IDT style
674 instructions within the monitor space. This relies on the IDT
675 monitor not using the locations from 0xBFC00500 onwards as its
677 for (loop
= 0; (loop
< 24); loop
++)
679 address_word vaddr
= (MONITOR_BASE
+ 0x500 + (loop
* 4));
680 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
696 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
698 case 8: /* cliexit */
701 case 11: /* flush_cache */
705 /* FIXME - should monitor_base be SIM_ADDR?? */
706 value
= ((unsigned int)MONITOR_BASE
+ (value
* 8));
708 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
710 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
712 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
724 tracefh
= fopen(tracefile
,"wb+");
727 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
734 sim_close (sd
, quitting
)
739 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
742 /* "quitting" is non-zero if we cannot hang on errors */
744 /* Ensure that any resources allocated through the callback
745 mechanism are released: */
746 sim_io_shutdown (sd
);
749 if (tracefh
!= NULL
&& tracefh
!= stderr
)
754 /* FIXME - free SD */
761 sim_write (sd
,addr
,buffer
,size
)
764 unsigned char *buffer
;
768 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
770 /* Return the number of bytes written, or zero if error. */
772 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
775 /* We use raw read and write routines, since we do not want to count
776 the GDB memory accesses in our statistics gathering. */
778 for (index
= 0; index
< size
; index
++)
780 address_word vaddr
= (address_word
)addr
+ index
;
783 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
785 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
793 sim_read (sd
,addr
,buffer
,size
)
796 unsigned char *buffer
;
800 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
802 /* Return the number of bytes read, or zero if error. */
804 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
807 for (index
= 0; (index
< size
); index
++)
809 address_word vaddr
= (address_word
)addr
+ index
;
812 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isLOAD
, &paddr
, &cca
, isRAW
))
814 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
822 sim_store_register (sd
,rn
,memory
,length
)
825 unsigned char *memory
;
828 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
829 /* NOTE: gdb (the client) stores registers in target byte order
830 while the simulator uses host byte order */
832 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
835 /* Unfortunately this suffers from the same problem as the register
836 numbering one. We need to know what the width of each logical
837 register number is for the architecture being simulated. */
839 if (cpu
->register_widths
[rn
] == 0)
841 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
845 /* start-sanitize-r5900 */
846 if (rn
>= 90 && rn
< 90 + 32)
848 GPR1
[rn
- 90] = T2H_8 (*(unsigned64
*)memory
);
854 SA
= T2H_8(*(unsigned64
*)memory
);
856 case 122: /* FIXME */
857 LO1
= T2H_8(*(unsigned64
*)memory
);
859 case 123: /* FIXME */
860 HI1
= T2H_8(*(unsigned64
*)memory
);
863 /* end-sanitize-r5900 */
865 /* start-sanitize-sky */
867 if (rn
>= NUM_R5900_REGS
)
869 rn
= rn
- NUM_R5900_REGS
;
871 if( rn
< NUM_VU_REGS
)
873 if (rn
< NUM_VU_INTEGER_REGS
)
874 return write_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
875 else if (rn
>= FIRST_VEC_REG
)
878 return write_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
&3,
881 else switch (rn
- NUM_VU_INTEGER_REGS
)
884 return write_vu_special_reg (&vu0_device
, VU_REG_CIA
,
887 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
889 case 2: /* VU0 has no P register */
892 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
895 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
898 return write_vu_acc_reg (&(vu0_device
.regs
),
899 rn
- (NUM_VU_INTEGER_REGS
+ 5),
904 rn
= rn
- NUM_VU_REGS
;
906 if (rn
< NUM_VU_REGS
)
908 if (rn
< NUM_VU_INTEGER_REGS
)
909 return write_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
910 else if (rn
>= FIRST_VEC_REG
)
913 return write_vu_vec_reg (&(vu1_device
.regs
),
914 rn
>> 2, rn
& 3, memory
);
916 else switch (rn
- NUM_VU_INTEGER_REGS
)
919 return write_vu_special_reg (&vu1_device
, VU_REG_CIA
,
922 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MR
,
925 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MP
,
928 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MI
,
931 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MQ
,
934 return write_vu_acc_reg (&(vu1_device
.regs
),
935 rn
- (NUM_VU_INTEGER_REGS
+ 5),
940 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
942 if (rn
< NUM_VIF_REGS
)
944 if (rn
< NUM_VIF_REGS
-1)
945 return write_pke_reg (&pke0_device
, rn
, memory
);
948 sim_io_eprintf( sd
, "Can't write vif0_pc (store ignored)\n" );
953 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
955 if (rn
< NUM_VIF_REGS
)
957 if (rn
< NUM_VIF_REGS
-1)
958 return write_pke_reg (&pke1_device
, rn
, memory
);
961 sim_io_eprintf( sd
, "Can't write vif1_pc (store ignored)\n" );
966 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
970 /* end-sanitize-sky */
972 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
974 if (cpu
->register_widths
[rn
] == 32)
976 cpu
->fgr
[rn
- FGRIDX
] = T2H_4 (*(unsigned32
*)memory
);
981 cpu
->fgr
[rn
- FGRIDX
] = T2H_8 (*(unsigned64
*)memory
);
986 if (cpu
->register_widths
[rn
] == 32)
988 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
993 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
1001 sim_fetch_register (sd
,rn
,memory
,length
)
1004 unsigned char *memory
;
1007 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
1008 /* NOTE: gdb (the client) stores registers in target byte order
1009 while the simulator uses host byte order */
1011 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
1014 if (cpu
->register_widths
[rn
] == 0)
1016 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
1020 /* start-sanitize-r5900 */
1021 if (rn
>= 90 && rn
< 90 + 32)
1023 *((unsigned64
*)memory
) = H2T_8 (GPR1
[rn
- 90]);
1029 *((unsigned64
*)memory
) = H2T_8(SA
);
1031 case 122: /* FIXME */
1032 *((unsigned64
*)memory
) = H2T_8(LO1
);
1034 case 123: /* FIXME */
1035 *((unsigned64
*)memory
) = H2T_8(HI1
);
1038 /* end-sanitize-r5900 */
1040 /* start-sanitize-sky */
1042 if (rn
>= NUM_R5900_REGS
)
1044 rn
= rn
- NUM_R5900_REGS
;
1046 if (rn
< NUM_VU_REGS
)
1048 if (rn
< NUM_VU_INTEGER_REGS
)
1049 return read_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
1050 else if (rn
>= FIRST_VEC_REG
)
1052 rn
-= FIRST_VEC_REG
;
1053 return read_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
& 3,
1056 else switch (rn
- NUM_VU_INTEGER_REGS
)
1059 return read_vu_special_reg(&vu0_device
, VU_REG_CIA
, memory
);
1061 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
,
1063 case 2: /* VU0 has no P register */
1064 *((int *) memory
) = 0;
1067 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
,
1070 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
,
1073 return read_vu_acc_reg (&(vu0_device
.regs
),
1074 rn
- (NUM_VU_INTEGER_REGS
+ 5),
1079 rn
-= NUM_VU_REGS
; /* VU1 registers are next */
1081 if (rn
< NUM_VU_REGS
)
1083 if (rn
< NUM_VU_INTEGER_REGS
)
1084 return read_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
1085 else if (rn
>= FIRST_VEC_REG
)
1087 rn
-= FIRST_VEC_REG
;
1088 return read_vu_vec_reg (&(vu1_device
.regs
),
1089 rn
>> 2, rn
& 3, memory
);
1091 else switch (rn
- NUM_VU_INTEGER_REGS
)
1094 return read_vu_special_reg(&vu1_device
, VU_REG_CIA
, memory
);
1096 return read_vu_misc_reg (&(vu1_device
.regs
),
1099 return read_vu_misc_reg (&(vu1_device
.regs
),
1102 return read_vu_misc_reg (&(vu1_device
.regs
),
1105 return read_vu_misc_reg (&(vu1_device
.regs
),
1108 return read_vu_acc_reg (&(vu1_device
.regs
),
1109 rn
- (NUM_VU_INTEGER_REGS
+ 5),
1114 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
1116 if (rn
< NUM_VIF_REGS
)
1118 if (rn
< NUM_VIF_REGS
-1)
1119 return read_pke_reg (&pke0_device
, rn
, memory
);
1121 return read_pke_pc (&pke0_device
, memory
);
1124 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
1126 if (rn
< NUM_VIF_REGS
)
1128 if (rn
< NUM_VIF_REGS
-1)
1129 return read_pke_reg (&pke1_device
, rn
, memory
);
1131 return read_pke_pc (&pke1_device
, memory
);
1134 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
1137 /* end-sanitize-sky */
1139 /* Any floating point register */
1140 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
1142 if (cpu
->register_widths
[rn
] == 32)
1144 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGRIDX
]);
1149 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGRIDX
]);
1154 if (cpu
->register_widths
[rn
] == 32)
1156 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
1161 *(unsigned64
*)memory
= H2T_8 ((unsigned64
)(cpu
->registers
[rn
]));
1170 sim_create_inferior (sd
, abfd
, argv
,env
)
1178 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1186 /* override PC value set by ColdReset () */
1188 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1190 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1191 CIA_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
1195 #if 0 /* def DEBUG */
1198 /* We should really place the argv slot values into the argument
1199 registers, and onto the stack as required. However, this
1200 assumes that we have a stack defined, which is not
1201 necessarily true at the moment. */
1203 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1204 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1205 printf("DBG: arg \"%s\"\n",*cptr
);
1213 sim_do_command (sd
,cmd
)
1217 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1218 sim_io_printf (sd
, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1222 /*---------------------------------------------------------------------------*/
1223 /*-- Private simulator support interface ------------------------------------*/
1224 /*---------------------------------------------------------------------------*/
1226 /* Read a null terminated string from memory, return in a buffer */
1228 fetch_str (sd
, addr
)
1235 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1237 buf
= NZALLOC (char, nr
+ 1);
1238 sim_read (sd
, addr
, buf
, nr
);
1242 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1244 sim_monitor (SIM_DESC sd
,
1247 unsigned int reason
)
1250 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1253 /* The IDT monitor actually allows two instructions per vector
1254 slot. However, the simulator currently causes a trap on each
1255 individual instruction. We cheat, and lose the bottom bit. */
1258 /* The following callback functions are available, however the
1259 monitor we are simulating does not make use of them: get_errno,
1260 isatty, lseek, rename, system, time and unlink */
1264 case 6: /* int open(char *path,int flags) */
1266 char *path
= fetch_str (sd
, A0
);
1267 V0
= sim_io_open (sd
, path
, (int)A1
);
1272 case 7: /* int read(int file,char *ptr,int len) */
1276 char *buf
= zalloc (nr
);
1277 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1278 sim_write (sd
, A1
, buf
, nr
);
1283 case 8: /* int write(int file,char *ptr,int len) */
1287 char *buf
= zalloc (nr
);
1288 sim_read (sd
, A1
, buf
, nr
);
1289 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1294 case 10: /* int close(int file) */
1296 V0
= sim_io_close (sd
, (int)A0
);
1300 case 2: /* Densan monitor: char inbyte(int waitflag) */
1302 if (A0
== 0) /* waitflag == NOWAIT */
1303 V0
= (unsigned_word
)-1;
1305 /* Drop through to case 11 */
1307 case 11: /* char inbyte(void) */
1310 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1312 sim_io_error(sd
,"Invalid return from character read");
1313 V0
= (unsigned_word
)-1;
1316 V0
= (unsigned_word
)tmp
;
1320 case 3: /* Densan monitor: void co(char chr) */
1321 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1323 char tmp
= (char)(A0
& 0xFF);
1324 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1328 case 17: /* void _exit() */
1330 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1331 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1332 (unsigned int)(A0
& 0xFFFFFFFF));
1336 case 28 : /* PMON flush_cache */
1339 case 55: /* void get_mem_info(unsigned int *ptr) */
1340 /* in: A0 = pointer to three word memory location */
1341 /* out: [A0 + 0] = size */
1342 /* [A0 + 4] = instruction cache size */
1343 /* [A0 + 8] = data cache size */
1345 unsigned_4 value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1346 unsigned_4 zero
= 0;
1348 sim_write (sd
, A0
+ 0, (char *)&value
, 4);
1349 sim_write (sd
, A0
+ 4, (char *)&zero
, 4);
1350 sim_write (sd
, A0
+ 8, (char *)&zero
, 4);
1351 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1355 case 158 : /* PMON printf */
1356 /* in: A0 = pointer to format string */
1357 /* A1 = optional argument 1 */
1358 /* A2 = optional argument 2 */
1359 /* A3 = optional argument 3 */
1361 /* The following is based on the PMON printf source */
1363 address_word s
= A0
;
1365 signed_word
*ap
= &A1
; /* 1st argument */
1366 /* This isn't the quickest way, since we call the host print
1367 routine for every character almost. But it does avoid
1368 having to allocate and manage a temporary string buffer. */
1369 /* TODO: Include check that we only use three arguments (A1,
1371 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1376 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1377 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1378 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1380 if (strchr ("dobxXulscefg%", c
))
1395 else if (c
>= '1' && c
<= '9')
1399 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1402 n
= (unsigned int)strtol(tmp
,NULL
,10);
1415 sim_io_printf (sd
, "%%");
1420 address_word p
= *ap
++;
1422 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1423 sim_io_printf(sd
, "%c", ch
);
1426 sim_io_printf(sd
,"(null)");
1429 sim_io_printf (sd
, "%c", (int)*ap
++);
1434 sim_read (sd
, s
++, &c
, 1);
1438 sim_read (sd
, s
++, &c
, 1);
1441 if (strchr ("dobxXu", c
))
1443 word64 lv
= (word64
) *ap
++;
1445 sim_io_printf(sd
,"<binary not supported>");
1448 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1450 sim_io_printf(sd
, tmp
, lv
);
1452 sim_io_printf(sd
, tmp
, (int)lv
);
1455 else if (strchr ("eEfgG", c
))
1457 double dbl
= *(double*)(ap
++);
1458 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1459 sim_io_printf (sd
, tmp
, dbl
);
1465 sim_io_printf(sd
, "%c", c
);
1471 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1472 reason
, pr_addr(cia
));
1478 /* Store a word into memory. */
1481 store_word (SIM_DESC sd
,
1490 if ((vaddr
& 3) != 0)
1491 SignalExceptionAddressStore ();
1494 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1497 const uword64 mask
= 7;
1501 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1502 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1503 memval
= ((uword64
) val
) << (8 * byte
);
1504 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1510 /* Load a word from memory. */
1513 load_word (SIM_DESC sd
,
1518 if ((vaddr
& 3) != 0)
1519 SignalExceptionAddressLoad ();
1525 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1528 const uword64 mask
= 0x7;
1529 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1530 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1534 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1535 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1537 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1538 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1545 /* Simulate the mips16 entry and exit pseudo-instructions. These
1546 would normally be handled by the reserved instruction exception
1547 code, but for ease of simulation we just handle them directly. */
1550 mips16_entry (SIM_DESC sd
,
1555 int aregs
, sregs
, rreg
;
1558 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1561 aregs
= (insn
& 0x700) >> 8;
1562 sregs
= (insn
& 0x0c0) >> 6;
1563 rreg
= (insn
& 0x020) >> 5;
1565 /* This should be checked by the caller. */
1574 /* This is the entry pseudo-instruction. */
1576 for (i
= 0; i
< aregs
; i
++)
1577 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1585 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1588 for (i
= 0; i
< sregs
; i
++)
1591 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1599 /* This is the exit pseudo-instruction. */
1606 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1609 for (i
= 0; i
< sregs
; i
++)
1612 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1617 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1621 FGR
[0] = WORD64LO (GPR
[4]);
1622 FPR_STATE
[0] = fmt_uninterpreted
;
1624 else if (aregs
== 6)
1626 FGR
[0] = WORD64LO (GPR
[5]);
1627 FGR
[1] = WORD64LO (GPR
[4]);
1628 FPR_STATE
[0] = fmt_uninterpreted
;
1629 FPR_STATE
[1] = fmt_uninterpreted
;
1638 /*-- trace support ----------------------------------------------------------*/
1640 /* The TRACE support is provided (if required) in the memory accessing
1641 routines. Since we are also providing the architecture specific
1642 features, the architecture simulation code can also deal with
1643 notifying the TRACE world of cache flushes, etc. Similarly we do
1644 not need to provide profiling support in the simulator engine,
1645 since we can sample in the instruction fetch control loop. By
1646 defining the TRACE manifest, we add tracing as a run-time
1650 /* Tracing by default produces "din" format (as required by
1651 dineroIII). Each line of such a trace file *MUST* have a din label
1652 and address field. The rest of the line is ignored, so comments can
1653 be included if desired. The first field is the label which must be
1654 one of the following values:
1659 3 escape record (treated as unknown access type)
1660 4 escape record (causes cache flush)
1662 The address field is a 32bit (lower-case) hexadecimal address
1663 value. The address should *NOT* be preceded by "0x".
1665 The size of the memory transfer is not important when dealing with
1666 cache lines (as long as no more than a cache line can be
1667 transferred in a single operation :-), however more information
1668 could be given following the dineroIII requirement to allow more
1669 complete memory and cache simulators to provide better
1670 results. i.e. the University of Pisa has a cache simulator that can
1671 also take bus size and speed as (variable) inputs to calculate
1672 complete system performance (a much more useful ability when trying
1673 to construct an end product, rather than a processor). They
1674 currently have an ARM version of their tool called ChARM. */
1678 dotrace (SIM_DESC sd
,
1686 if (STATE
& simTRACE
) {
1688 fprintf(tracefh
,"%d %s ; width %d ; ",
1692 va_start(ap
,comment
);
1693 vfprintf(tracefh
,comment
,ap
);
1695 fprintf(tracefh
,"\n");
1697 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1698 we may be generating 64bit ones, we should put the hi-32bits of the
1699 address into the comment field. */
1701 /* TODO: Provide a buffer for the trace lines. We can then avoid
1702 performing writes until the buffer is filled, or the file is
1705 /* NOTE: We could consider adding a comment field to the "din" file
1706 produced using type 3 markers (unknown access). This would then
1707 allow information about the program that the "din" is for, and
1708 the MIPs world that was being simulated, to be placed into the
1715 /*---------------------------------------------------------------------------*/
1716 /*-- simulator engine -------------------------------------------------------*/
1717 /*---------------------------------------------------------------------------*/
1720 ColdReset (SIM_DESC sd
)
1723 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1725 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1726 /* RESET: Fixed PC address: */
1727 PC
= (unsigned_word
) UNSIGNED64 (0xFFFFFFFFBFC00000);
1728 /* The reset vector address is in the unmapped, uncached memory space. */
1730 SR
&= ~(status_SR
| status_TS
| status_RP
);
1731 SR
|= (status_ERL
| status_BEV
);
1733 /* Cheat and allow access to the complete register set immediately */
1734 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1735 && WITH_TARGET_WORD_BITSIZE
== 64)
1736 SR
|= status_FR
; /* 64bit registers */
1738 /* Ensure that any instructions with pending register updates are
1740 PENDING_INVALIDATE();
1742 /* Initialise the FPU registers to the unknown state */
1743 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1746 for (rn
= 0; (rn
< 32); rn
++)
1747 FPR_STATE
[rn
] = fmt_uninterpreted
;
1753 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1754 /* Signal an exception condition. This will result in an exception
1755 that aborts the instruction. The instruction operation pseudocode
1756 will never see a return from this function call. */
1759 signal_exception (SIM_DESC sd
,
1767 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1770 /* Ensure that any active atomic read/modify/write operation will fail: */
1773 switch (exception
) {
1778 unsigned int instruction
;
1781 va_start(ap
,exception
);
1782 instruction
= va_arg(ap
,unsigned int);
1785 code
= (instruction
>> 6) & 0xFFFFF;
1787 sim_io_eprintf(sd
,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
1788 code
, pr_addr(cia
));
1792 case DebugBreakPoint
:
1793 if (! (Debug
& Debug_DM
))
1799 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1800 DEPC
= cia
- 4; /* reference the branch instruction */
1804 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1808 Debug
|= Debug_DM
; /* in debugging mode */
1809 Debug
|= Debug_DBp
; /* raising a DBp exception */
1811 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1815 case ReservedInstruction
:
1818 unsigned int instruction
;
1819 va_start(ap
,exception
);
1820 instruction
= va_arg(ap
,unsigned int);
1822 /* Provide simple monitor support using ReservedInstruction
1823 exceptions. The following code simulates the fixed vector
1824 entry points into the IDT monitor by causing a simulator
1825 trap, performing the monitor operation, and returning to
1826 the address held in the $ra register (standard PCS return
1827 address). This means we only need to pre-load the vector
1828 space with suitable instruction values. For systems were
1829 actual trap instructions are used, we would not need to
1830 perform this magic. */
1831 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1833 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
1834 /* NOTE: This assumes that a branch-and-link style
1835 instruction was used to enter the vector (which is the
1836 case with the current IDT monitor). */
1837 sim_engine_restart (SD
, CPU
, NULL
, RA
);
1839 /* Look for the mips16 entry and exit instructions, and
1840 simulate a handler for them. */
1841 else if ((cia
& 1) != 0
1842 && (instruction
& 0xf81f) == 0xe809
1843 && (instruction
& 0x0c0) != 0x0c0)
1845 mips16_entry (SD
, CPU
, cia
, instruction
);
1846 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1848 /* else fall through to normal exception processing */
1849 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
1854 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1856 /* Keep a copy of the current A0 in-case this is the program exit
1860 unsigned int instruction
;
1861 va_start(ap
, exception
);
1862 instruction
= va_arg(ap
,unsigned int);
1864 /* Check for our special terminating BREAK: */
1865 if ((instruction
& HALT_INSTRUCTION_MASK
) == (HALT_INSTRUCTION
& HALT_INSTRUCTION_MASK
) ||
1866 (instruction
& HALT_INSTRUCTION_MASK
) == (HALT_INSTRUCTION2
& HALT_INSTRUCTION_MASK
))
1868 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1869 sim_exited
, (unsigned int)(A0
& 0xFFFFFFFF));
1872 if (STATE
& simDELAYSLOT
)
1873 PC
= cia
- 4; /* reference the branch instruction */
1876 sim_engine_halt (SD
, CPU
, NULL
, cia
,
1877 sim_stopped
, SIM_SIGTRAP
);
1880 /* Store exception code into current exception id variable (used
1883 /* TODO: If not simulating exceptions then stop the simulator
1884 execution. At the moment we always stop the simulation. */
1886 #ifdef SUBTARGET_R3900
1887 /* update interrupt-related registers */
1889 /* insert exception code in bits 6:2 */
1890 CAUSE
= LSMASKED32(CAUSE
, 31, 7) | LSINSERTED32(exception
, 6, 2);
1891 /* shift IE/KU history bits left */
1892 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 3, 0), 5, 2);
1894 if (STATE
& simDELAYSLOT
)
1896 STATE
&= ~simDELAYSLOT
;
1898 EPC
= (cia
- 4); /* reference the branch instruction */
1903 if (SR
& status_BEV
)
1904 PC
= (signed)0xBFC00000 + 0x180;
1906 PC
= (signed)0x80000000 + 0x080;
1908 /* See figure 5-17 for an outline of the code below */
1909 if (! (SR
& status_EXL
))
1911 CAUSE
= (exception
<< 2);
1912 if (STATE
& simDELAYSLOT
)
1914 STATE
&= ~simDELAYSLOT
;
1916 EPC
= (cia
- 4); /* reference the branch instruction */
1920 /* FIXME: TLB et.al. */
1921 /* vector = 0x180; */
1925 CAUSE
= (exception
<< 2);
1926 /* vector = 0x180; */
1929 /* Store exception code into current exception id variable (used
1932 if (SR
& status_BEV
)
1933 PC
= (signed)0xBFC00200 + 0x180;
1935 PC
= (signed)0x80000000 + 0x180;
1938 switch ((CAUSE
>> 2) & 0x1F)
1941 /* Interrupts arrive during event processing, no need to
1947 #ifdef SUBTARGET_3900
1948 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1949 PC
= (signed)0xBFC00000;
1950 #endif SUBTARGET_3900
1953 case TLBModification
:
1958 case InstructionFetch
:
1960 /* The following is so that the simulator will continue from the
1961 exception address on breakpoint operations. */
1963 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1964 sim_stopped
, SIM_SIGBUS
);
1966 case ReservedInstruction
:
1967 case CoProcessorUnusable
:
1969 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1970 sim_stopped
, SIM_SIGILL
);
1972 case IntegerOverflow
:
1974 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1975 sim_stopped
, SIM_SIGFPE
);
1978 sim_engine_restart (SD
, CPU
, NULL
, PC
);
1984 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1985 sim_stopped
, SIM_SIGTRAP
);
1989 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1990 "FATAL: Should not encounter a breakpoint\n");
1992 default : /* Unknown internal exception */
1994 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
1995 sim_stopped
, SIM_SIGABRT
);
1999 case SimulatorFault
:
2003 va_start(ap
,exception
);
2004 msg
= va_arg(ap
,char *);
2006 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2007 "FATAL: Simulator error \"%s\"\n",msg
);
2014 #if defined(WARN_RESULT)
2015 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2016 /* This function indicates that the result of the operation is
2017 undefined. However, this should not affect the instruction
2018 stream. All that is meant to happen is that the destination
2019 register is set to an undefined result. To keep the simulator
2020 simple, we just don't bother updating the destination register, so
2021 the overall result will be undefined. If desired we can stop the
2022 simulator by raising a pseudo-exception. */
2023 #define UndefinedResult() undefined_result (sd,cia)
2025 undefined_result(sd
,cia
)
2029 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
2030 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2035 #endif /* WARN_RESULT */
2037 /*-- FPU support routines ---------------------------------------------------*/
2039 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
2040 formats conform to ANSI/IEEE Std 754-1985. */
2041 /* SINGLE precision floating:
2042 * seeeeeeeefffffffffffffffffffffff
2044 * e = 8bits = exponent
2045 * f = 23bits = fraction
2047 /* SINGLE precision fixed:
2048 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2050 * i = 31bits = integer
2052 /* DOUBLE precision floating:
2053 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
2055 * e = 11bits = exponent
2056 * f = 52bits = fraction
2058 /* DOUBLE precision fixed:
2059 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2061 * i = 63bits = integer
2064 /* Extract sign-bit: */
2065 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
2066 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
2067 /* Extract biased exponent: */
2068 #define FP_S_be(v) (((v) >> 23) & 0xFF)
2069 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
2070 /* Extract unbiased Exponent: */
2071 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
2072 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
2073 /* Extract complete fraction field: */
2074 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
2075 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
2076 /* Extract numbered fraction bit: */
2077 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
2078 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
2080 /* Explicit QNaN values used when value required: */
2081 #define FPQNaN_SINGLE (0x7FBFFFFF)
2082 #define FPQNaN_WORD (0x7FFFFFFF)
2083 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
2084 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
2086 /* Explicit Infinity values used when required: */
2087 #define FPINF_SINGLE (0x7F800000)
2088 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
2090 #if 1 /* def DEBUG */
2091 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
2092 #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>"))))))
2096 value_fpr (SIM_DESC sd
,
2105 /* Treat unused register values, as fixed-point 64bit values: */
2106 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
2108 /* If request to read data as "uninterpreted", then use the current
2110 fmt
= FPR_STATE
[fpr
];
2115 /* For values not yet accessed, set to the desired format: */
2116 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
2117 FPR_STATE
[fpr
] = fmt
;
2119 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
2122 if (fmt
!= FPR_STATE
[fpr
]) {
2123 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
));
2124 FPR_STATE
[fpr
] = fmt_unknown
;
2127 if (FPR_STATE
[fpr
] == fmt_unknown
) {
2128 /* Set QNaN value: */
2131 value
= FPQNaN_SINGLE
;
2135 value
= FPQNaN_DOUBLE
;
2139 value
= FPQNaN_WORD
;
2143 value
= FPQNaN_LONG
;
2150 } else if (SizeFGR() == 64) {
2154 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2157 case fmt_uninterpreted
:
2171 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2174 case fmt_uninterpreted
:
2177 if ((fpr
& 1) == 0) { /* even registers only */
2178 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
2180 SignalException(ReservedInstruction
,0);
2191 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2194 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());
2201 store_fpr (SIM_DESC sd
,
2211 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());
2214 if (SizeFGR() == 64) {
2216 case fmt_uninterpreted_32
:
2217 fmt
= fmt_uninterpreted
;
2220 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2221 FPR_STATE
[fpr
] = fmt
;
2224 case fmt_uninterpreted_64
:
2225 fmt
= fmt_uninterpreted
;
2226 case fmt_uninterpreted
:
2230 FPR_STATE
[fpr
] = fmt
;
2234 FPR_STATE
[fpr
] = fmt_unknown
;
2240 case fmt_uninterpreted_32
:
2241 fmt
= fmt_uninterpreted
;
2244 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2245 FPR_STATE
[fpr
] = fmt
;
2248 case fmt_uninterpreted_64
:
2249 fmt
= fmt_uninterpreted
;
2250 case fmt_uninterpreted
:
2253 if ((fpr
& 1) == 0) { /* even register number only */
2254 FGR
[fpr
+1] = (value
>> 32);
2255 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2256 FPR_STATE
[fpr
+ 1] = fmt
;
2257 FPR_STATE
[fpr
] = fmt
;
2259 FPR_STATE
[fpr
] = fmt_unknown
;
2260 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2261 SignalException(ReservedInstruction
,0);
2266 FPR_STATE
[fpr
] = fmt_unknown
;
2271 #if defined(WARN_RESULT)
2274 #endif /* WARN_RESULT */
2277 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2280 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_addr(FGR
[fpr
]),DOFMT(fmt
));
2297 sim_fpu_32to (&wop
, op
);
2298 boolean
= sim_fpu_is_nan (&wop
);
2305 sim_fpu_64to (&wop
, op
);
2306 boolean
= sim_fpu_is_nan (&wop
);
2310 fprintf (stderr
, "Bad switch\n");
2315 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2329 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2336 sim_fpu_32to (&wop
, op
);
2337 boolean
= sim_fpu_is_infinity (&wop
);
2343 sim_fpu_64to (&wop
, op
);
2344 boolean
= sim_fpu_is_infinity (&wop
);
2348 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2353 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2367 /* Argument checking already performed by the FPCOMPARE code */
2370 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2373 /* The format type should already have been checked: */
2379 sim_fpu_32to (&wop1
, op1
);
2380 sim_fpu_32to (&wop2
, op2
);
2381 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2388 sim_fpu_64to (&wop1
, op1
);
2389 sim_fpu_64to (&wop2
, op2
);
2390 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2394 fprintf (stderr
, "Bad switch\n");
2399 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2413 /* Argument checking already performed by the FPCOMPARE code */
2416 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2419 /* The format type should already have been checked: */
2425 sim_fpu_32to (&wop1
, op1
);
2426 sim_fpu_32to (&wop2
, op2
);
2427 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2434 sim_fpu_64to (&wop1
, op1
);
2435 sim_fpu_64to (&wop2
, op2
);
2436 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2440 fprintf (stderr
, "Bad switch\n");
2445 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2452 AbsoluteValue(op
,fmt
)
2459 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2462 /* The format type should already have been checked: */
2468 sim_fpu_32to (&wop
, op
);
2469 sim_fpu_abs (&wop
, &wop
);
2470 sim_fpu_to32 (&ans
, &wop
);
2478 sim_fpu_64to (&wop
, op
);
2479 sim_fpu_abs (&wop
, &wop
);
2480 sim_fpu_to64 (&ans
, &wop
);
2485 fprintf (stderr
, "Bad switch\n");
2500 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2503 /* The format type should already have been checked: */
2509 sim_fpu_32to (&wop
, op
);
2510 sim_fpu_neg (&wop
, &wop
);
2511 sim_fpu_to32 (&ans
, &wop
);
2519 sim_fpu_64to (&wop
, op
);
2520 sim_fpu_neg (&wop
, &wop
);
2521 sim_fpu_to64 (&ans
, &wop
);
2526 fprintf (stderr
, "Bad switch\n");
2542 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2545 /* The registers must specify FPRs valid for operands of type
2546 "fmt". If they are not valid, the result is undefined. */
2548 /* The format type should already have been checked: */
2556 sim_fpu_32to (&wop1
, op1
);
2557 sim_fpu_32to (&wop2
, op2
);
2558 sim_fpu_add (&ans
, &wop1
, &wop2
);
2559 sim_fpu_to32 (&res
, &ans
);
2569 sim_fpu_64to (&wop1
, op1
);
2570 sim_fpu_64to (&wop2
, op2
);
2571 sim_fpu_add (&ans
, &wop1
, &wop2
);
2572 sim_fpu_to64 (&res
, &ans
);
2577 fprintf (stderr
, "Bad switch\n");
2582 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2597 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2600 /* The registers must specify FPRs valid for operands of type
2601 "fmt". If they are not valid, the result is undefined. */
2603 /* The format type should already have been checked: */
2611 sim_fpu_32to (&wop1
, op1
);
2612 sim_fpu_32to (&wop2
, op2
);
2613 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2614 sim_fpu_to32 (&res
, &ans
);
2624 sim_fpu_64to (&wop1
, op1
);
2625 sim_fpu_64to (&wop2
, op2
);
2626 sim_fpu_sub (&ans
, &wop1
, &wop2
);
2627 sim_fpu_to64 (&res
, &ans
);
2632 fprintf (stderr
, "Bad switch\n");
2637 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2644 Multiply(op1
,op2
,fmt
)
2652 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2655 /* The registers must specify FPRs valid for operands of type
2656 "fmt". If they are not valid, the result is undefined. */
2658 /* The format type should already have been checked: */
2666 sim_fpu_32to (&wop1
, op1
);
2667 sim_fpu_32to (&wop2
, op2
);
2668 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2669 sim_fpu_to32 (&res
, &ans
);
2679 sim_fpu_64to (&wop1
, op1
);
2680 sim_fpu_64to (&wop2
, op2
);
2681 sim_fpu_mul (&ans
, &wop1
, &wop2
);
2682 sim_fpu_to64 (&res
, &ans
);
2687 fprintf (stderr
, "Bad switch\n");
2692 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2707 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2710 /* The registers must specify FPRs valid for operands of type
2711 "fmt". If they are not valid, the result is undefined. */
2713 /* The format type should already have been checked: */
2721 sim_fpu_32to (&wop1
, op1
);
2722 sim_fpu_32to (&wop2
, op2
);
2723 sim_fpu_div (&ans
, &wop1
, &wop2
);
2724 sim_fpu_to32 (&res
, &ans
);
2734 sim_fpu_64to (&wop1
, op1
);
2735 sim_fpu_64to (&wop2
, op2
);
2736 sim_fpu_div (&ans
, &wop1
, &wop2
);
2737 sim_fpu_to64 (&res
, &ans
);
2742 fprintf (stderr
, "Bad switch\n");
2747 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2761 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2764 /* The registers must specify FPRs valid for operands of type
2765 "fmt". If they are not valid, the result is undefined. */
2767 /* The format type should already have been checked: */
2774 sim_fpu_32to (&wop
, op
);
2775 sim_fpu_inv (&ans
, &wop
);
2776 sim_fpu_to32 (&res
, &ans
);
2785 sim_fpu_64to (&wop
, op
);
2786 sim_fpu_inv (&ans
, &wop
);
2787 sim_fpu_to64 (&res
, &ans
);
2792 fprintf (stderr
, "Bad switch\n");
2797 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2811 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2814 /* The registers must specify FPRs valid for operands of type
2815 "fmt". If they are not valid, the result is undefined. */
2817 /* The format type should already have been checked: */
2824 sim_fpu_32to (&wop
, op
);
2825 sim_fpu_sqrt (&ans
, &wop
);
2826 sim_fpu_to32 (&res
, &ans
);
2835 sim_fpu_64to (&wop
, op
);
2836 sim_fpu_sqrt (&ans
, &wop
);
2837 sim_fpu_to64 (&res
, &ans
);
2842 fprintf (stderr
, "Bad switch\n");
2847 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2863 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2866 /* The registers must specify FPRs valid for operands of type
2867 "fmt". If they are not valid, the result is undefined. */
2869 /* The format type should already have been checked: */
2876 sim_fpu_32to (&wop1
, op1
);
2877 sim_fpu_32to (&wop2
, op2
);
2878 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2885 sim_fpu_64to (&wop1
, op1
);
2886 sim_fpu_64to (&wop2
, op2
);
2887 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2891 fprintf (stderr
, "Bad switch\n");
2897 case SIM_FPU_IS_SNAN
:
2898 case SIM_FPU_IS_QNAN
:
2900 case SIM_FPU_IS_NINF
:
2901 case SIM_FPU_IS_NNUMBER
:
2902 case SIM_FPU_IS_NDENORM
:
2903 case SIM_FPU_IS_NZERO
:
2904 result
= op2
; /* op1 - op2 < 0 */
2905 case SIM_FPU_IS_PINF
:
2906 case SIM_FPU_IS_PNUMBER
:
2907 case SIM_FPU_IS_PDENORM
:
2908 case SIM_FPU_IS_PZERO
:
2909 result
= op1
; /* op1 - op2 > 0 */
2911 fprintf (stderr
, "Bad switch\n");
2916 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2933 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2936 /* The registers must specify FPRs valid for operands of type
2937 "fmt". If they are not valid, the result is undefined. */
2939 /* The format type should already have been checked: */
2946 sim_fpu_32to (&wop1
, op1
);
2947 sim_fpu_32to (&wop2
, op2
);
2948 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2955 sim_fpu_64to (&wop1
, op1
);
2956 sim_fpu_64to (&wop2
, op2
);
2957 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
2961 fprintf (stderr
, "Bad switch\n");
2967 case SIM_FPU_IS_SNAN
:
2968 case SIM_FPU_IS_QNAN
:
2970 case SIM_FPU_IS_NINF
:
2971 case SIM_FPU_IS_NNUMBER
:
2972 case SIM_FPU_IS_NDENORM
:
2973 case SIM_FPU_IS_NZERO
:
2974 result
= op1
; /* op1 - op2 < 0 */
2975 case SIM_FPU_IS_PINF
:
2976 case SIM_FPU_IS_PNUMBER
:
2977 case SIM_FPU_IS_PDENORM
:
2978 case SIM_FPU_IS_PZERO
:
2979 result
= op2
; /* op1 - op2 > 0 */
2981 fprintf (stderr
, "Bad switch\n");
2986 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2994 convert (SIM_DESC sd
,
3003 sim_fpu_round round
;
3004 unsigned32 result32
;
3005 unsigned64 result64
;
3008 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
));
3014 /* Round result to nearest representable value. When two
3015 representable values are equally near, round to the value
3016 that has a least significant bit of zero (i.e. is even). */
3017 round
= sim_fpu_round_near
;
3020 /* Round result to the value closest to, and not greater in
3021 magnitude than, the result. */
3022 round
= sim_fpu_round_zero
;
3025 /* Round result to the value closest to, and not less than,
3027 round
= sim_fpu_round_up
;
3031 /* Round result to the value closest to, and not greater than,
3033 round
= sim_fpu_round_down
;
3037 fprintf (stderr
, "Bad switch\n");
3041 /* Convert the input to sim_fpu internal format */
3045 sim_fpu_64to (&wop
, op
);
3048 sim_fpu_32to (&wop
, op
);
3051 sim_fpu_i32to (&wop
, op
, round
);
3054 sim_fpu_i64to (&wop
, op
, round
);
3057 fprintf (stderr
, "Bad switch\n");
3061 /* Convert sim_fpu format into the output */
3062 /* The value WOP is converted to the destination format, rounding
3063 using mode RM. When the destination is a fixed-point format, then
3064 a source value of Infinity, NaN or one which would round to an
3065 integer outside the fixed point range then an IEEE Invalid
3066 Operation condition is raised. */
3070 sim_fpu_round_32 (&wop
, round
, 0);
3071 sim_fpu_to32 (&result32
, &wop
);
3072 result64
= result32
;
3075 sim_fpu_round_64 (&wop
, round
, 0);
3076 sim_fpu_to64 (&result64
, &wop
);
3079 sim_fpu_to32i (&result32
, &wop
, round
);
3080 result64
= result32
;
3083 sim_fpu_to64i (&result64
, &wop
, round
);
3087 fprintf (stderr
, "Bad switch\n");
3092 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
3099 /*-- co-processor support routines ------------------------------------------*/
3102 CoProcPresent(coproc_number
)
3103 unsigned int coproc_number
;
3105 /* Return TRUE if simulator provides a model for the given co-processor number */
3110 cop_lw (SIM_DESC sd
,
3115 unsigned int memword
)
3120 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3123 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
3125 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
3126 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
3131 #if 0 /* this should be controlled by a configuration option */
3132 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
));
3141 cop_ld (SIM_DESC sd
,
3148 switch (coproc_num
) {
3150 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3152 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
3157 #if 0 /* this message should be controlled by a configuration option */
3158 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
));
3167 /* start-sanitize-sky */
3170 cop_lq (SIM_DESC sd
,
3175 unsigned128 memword
)
3186 /* one word at a time, argh! */
3190 value
= H2T_4(*A4_16(& memword
, 3-i
));
3191 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3197 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3198 coproc_num
,coproc_reg
,pr_addr(cia
));
3204 #endif /* TARGET_SKY */
3205 /* end-sanitize-sky */
3209 cop_sw (SIM_DESC sd
,
3215 unsigned int value
= 0;
3220 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3223 hold
= FPR_STATE
[coproc_reg
];
3224 FPR_STATE
[coproc_reg
] = fmt_word
;
3225 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3226 FPR_STATE
[coproc_reg
] = hold
;
3231 #if 0 /* should be controlled by configuration option */
3232 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3241 cop_sd (SIM_DESC sd
,
3251 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3253 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3258 #if 0 /* should be controlled by configuration option */
3259 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3268 /* start-sanitize-sky */
3271 cop_sq (SIM_DESC sd
,
3277 unsigned128 value
= U16_8(0, 0);
3288 /* one word at a time, argh! */
3292 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3293 *A4_16(& xyzw
, 3-i
) = T2H_4(value
);
3300 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3301 coproc_num
,coproc_reg
,pr_addr(cia
));
3307 #endif /* TARGET_SKY */
3308 /* end-sanitize-sky */
3312 decode_coproc (SIM_DESC sd
,
3315 unsigned int instruction
)
3317 int coprocnum
= ((instruction
>> 26) & 3);
3321 case 0: /* standard CPU control and cache registers */
3323 int code
= ((instruction
>> 21) & 0x1F);
3324 /* R4000 Users Manual (second edition) lists the following CP0
3326 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3327 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3328 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3329 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3330 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3331 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3332 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3333 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3334 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3335 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3337 if (((code
== 0x00) || (code
== 0x04)) && ((instruction
& 0x7FF) == 0))
3339 int rt
= ((instruction
>> 16) & 0x1F);
3340 int rd
= ((instruction
>> 11) & 0x1F);
3342 switch (rd
) /* NOTEs: Standard CP0 registers */
3344 /* 0 = Index R4000 VR4100 VR4300 */
3345 /* 1 = Random R4000 VR4100 VR4300 */
3346 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3347 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3348 /* 4 = Context R4000 VR4100 VR4300 */
3349 /* 5 = PageMask R4000 VR4100 VR4300 */
3350 /* 6 = Wired R4000 VR4100 VR4300 */
3351 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3352 /* 9 = Count R4000 VR4100 VR4300 */
3353 /* 10 = EntryHi R4000 VR4100 VR4300 */
3354 /* 11 = Compare R4000 VR4100 VR4300 */
3355 /* 12 = SR R4000 VR4100 VR4300 */
3356 #ifdef SUBTARGET_R3900
3360 /* 3 = Config R3900 */
3361 #endif /* SUBTARGET_R3900 */
3368 /* 13 = Cause R4000 VR4100 VR4300 */
3375 /* 14 = EPC R4000 VR4100 VR4300 */
3378 GPR
[rt
] = (signed_word
) (signed_address
) EPC
;
3382 /* 15 = PRId R4000 VR4100 VR4300 */
3383 #ifdef SUBTARGET_R3900
3392 /* 16 = Config R4000 VR4100 VR4300 */
3395 GPR
[rt
] = C0_CONFIG
;
3397 C0_CONFIG
= GPR
[rt
];
3400 #ifdef SUBTARGET_R3900
3409 /* 17 = LLAddr R4000 VR4100 VR4300 */
3411 /* 18 = WatchLo R4000 VR4100 VR4300 */
3412 /* 19 = WatchHi R4000 VR4100 VR4300 */
3413 /* 20 = XContext R4000 VR4100 VR4300 */
3414 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3415 /* 27 = CacheErr R4000 VR4100 */
3416 /* 28 = TagLo R4000 VR4100 VR4300 */
3417 /* 29 = TagHi R4000 VR4100 VR4300 */
3418 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3419 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3420 /* CPR[0,rd] = GPR[rt]; */
3423 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3425 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt
,rd
);
3428 else if (code
== 0x10 && (instruction
& 0x3f) == 0x18)
3431 if (SR
& status_ERL
)
3433 /* Oops, not yet available */
3434 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3444 else if (code
== 0x10 && (instruction
& 0x3f) == 0x10)
3447 #ifdef SUBTARGET_R3900
3448 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
3450 /* shift IE/KU history bits right */
3451 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 5, 2), 3, 0);
3453 /* TODO: CACHE register */
3454 #endif /* SUBTARGET_R3900 */
3456 else if (code
== 0x10 && (instruction
& 0x3f) == 0x1F)
3464 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3465 /* TODO: When executing an ERET or RFE instruction we should
3466 clear LLBIT, to ensure that any out-standing atomic
3467 read/modify/write sequence fails. */
3471 case 2: /* co-processor 2 */
3475 /* start-sanitize-sky */
3477 /* On the R5900, this refers to a "VU" vector co-processor. */
3479 int i_25_21
= (instruction
>> 21) & 0x1f;
3480 int i_20_16
= (instruction
>> 16) & 0x1f;
3481 int i_20_6
= (instruction
>> 6) & 0x7fff;
3482 int i_15_11
= (instruction
>> 11) & 0x1f;
3483 int i_15_0
= instruction
& 0xffff;
3484 int i_10_1
= (instruction
>> 1) & 0x3ff;
3485 int i_10_0
= instruction
& 0x7ff;
3486 int i_10_6
= (instruction
>> 6) & 0x1f;
3487 int i_5_0
= instruction
& 0x03f;
3488 int interlock
= instruction
& 0x01;
3489 /* setup for semantic.c-like actions below */
3490 typedef unsigned_4 instruction_word
;
3496 /* test COP2 usability */
3497 if(! (SR
& status_CU2
))
3499 SignalException(CoProcessorUnusable
,instruction
);
3503 #define MY_INDEX itable_COPz_NORMAL
3504 #define MY_PREFIX COPz_NORMAL
3505 #define MY_NAME "COPz_NORMAL"
3507 /* classify & execute basic COP2 instructions */
3508 if(i_25_21
== 0x08 && i_20_16
== 0x00) /* BC2F */
3510 address_word offset
= EXTEND16(i_15_0
) << 2;
3511 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3513 else if(i_25_21
== 0x08 && i_20_16
==0x02) /* BC2FL */
3515 address_word offset
= EXTEND16(i_15_0
) << 2;
3516 if(! vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3517 else NULLIFY_NEXT_INSTRUCTION();
3519 else if(i_25_21
== 0x08 && i_20_16
== 0x01) /* BC2T */
3521 address_word offset
= EXTEND16(i_15_0
) << 2;
3522 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3524 else if(i_25_21
== 0x08 && i_20_16
== 0x03) /* BC2TL */
3526 address_word offset
= EXTEND16(i_15_0
) << 2;
3527 if(vu0_busy()) DELAY_SLOT(cia
+ 4 + offset
);
3528 else NULLIFY_NEXT_INSTRUCTION();
3530 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3531 (i_25_21
== 0x01)) /* QMFC2 */
3536 /* interlock checking */
3537 /* POLICY: never busy in macro mode */
3538 while(vu0_busy() && interlock
)
3541 /* perform VU register address */
3542 if(i_25_21
== 0x01) /* QMFC2 */
3545 /* one word at a time, argh! */
3546 read_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3547 read_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3548 read_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3549 read_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3550 GPR
[rt
] = T2H_8(* A8_16(& xyzw
, 1));
3551 GPR1
[rt
] = T2H_8(* A8_16(& xyzw
, 0));
3556 /* enum + int calculation, argh! */
3557 id
= VU_REG_MST
+ 16 * id
;
3558 read_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3559 GPR
[rt
] = EXTEND32(T2H_4(data
));
3562 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3563 (i_25_21
== 0x05)) /* QMTC2 */
3568 /* interlock checking: wait until M or E bits set */
3569 /* POLICY: never busy in macro mode */
3570 while(vu0_busy() && interlock
)
3572 if(vu0_micro_interlock_released())
3574 vu0_micro_interlock_clear();
3581 /* perform VU register address */
3582 if(i_25_21
== 0x05) /* QMTC2 */
3584 unsigned_16 xyzw
= U16_8(GPR1
[rt
], GPR
[rt
]);
3586 xyzw
= H2T_16(xyzw
);
3587 /* one word at a time, argh! */
3588 write_vu_vec_reg(&(vu0_device
.regs
), id
, 0, A4_16(& xyzw
, 3));
3589 write_vu_vec_reg(&(vu0_device
.regs
), id
, 1, A4_16(& xyzw
, 2));
3590 write_vu_vec_reg(&(vu0_device
.regs
), id
, 2, A4_16(& xyzw
, 1));
3591 write_vu_vec_reg(&(vu0_device
.regs
), id
, 3, A4_16(& xyzw
, 0));
3595 unsigned_4 data
= H2T_4(GPR
[rt
]);
3596 /* enum + int calculation, argh! */
3597 id
= VU_REG_MST
+ 16 * id
;
3598 write_vu_misc_reg(&(vu0_device
.regs
), id
, & data
);
3601 else if(i_10_0
== 0x3bf) /* VWAITQ */
3606 else if(i_5_0
== 0x38) /* VCALLMS */
3608 unsigned_4 data
= H2T_2(i_20_6
);
3613 /* write to reserved CIA register to get VU0 moving */
3614 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3618 else if(i_5_0
== 0x39) /* VCALLMSR */
3625 read_vu_special_reg(& vu0_device
, VU_REG_CMSAR0
, & data
);
3626 /* write to reserved CIA register to get VU0 moving */
3627 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
3631 /* handle all remaining UPPER VU instructions in one block */
3632 else if((i_5_0
< 0x30) || /* VADDx .. VMINI */
3633 (i_5_0
>= 0x3c && i_10_6
< 0x0c)) /* VADDAx .. VNOP */
3635 unsigned_4 vu_upper
, vu_lower
;
3637 0x00000000 | /* bits 31 .. 25 */
3638 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3639 vu_lower
= 0x8000033c; /* NOP */
3641 /* POLICY: never busy in macro mode */
3645 vu0_macro_issue(vu_upper
, vu_lower
);
3647 /* POLICY: wait for completion of macro-instruction */
3651 /* handle all remaining LOWER VU instructions in one block */
3652 else if((i_5_0
>= 0x30 && i_5_0
<= 0x35) || /* VIADD .. VIOR */
3653 (i_5_0
>= 0x3c && i_10_6
>= 0x0c)) /* VMOVE .. VRXOR */
3654 { /* N.B.: VWAITQ already covered by prior case */
3655 unsigned_4 vu_upper
, vu_lower
;
3656 vu_upper
= 0x000002ff; /* NOP/NOP */
3658 0x80000000 | /* bits 31 .. 25 */
3659 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
3661 /* POLICY: never busy in macro mode */
3665 vu0_macro_issue(vu_upper
, vu_lower
);
3667 /* POLICY: wait for completion of macro-instruction */
3671 /* ... no other COP2 instructions ... */
3674 SignalException(ReservedInstruction
, instruction
);
3678 /* cleanup for semantic.c-like actions above */
3685 #endif /* TARGET_SKY */
3686 /* end-sanitize-sky */
3690 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3691 instruction
,pr_addr(cia
));
3696 case 1: /* should not occur (FPU co-processor) */
3697 case 3: /* should not occur (FPU co-processor) */
3698 SignalException(ReservedInstruction
,instruction
);
3706 /*-- instruction simulation -------------------------------------------------*/
3708 /* When the IGEN simulator is being built, the function below is be
3709 replaced by a generated version. However, WITH_IGEN == 2 indicates
3710 that the fubction below should be compiled but under a different
3711 name (to allow backward compatibility) */
3713 #if (WITH_IGEN != 1)
3715 void old_engine_run
PARAMS ((SIM_DESC sd
, int next_cpu_nr
, int siggnal
));
3717 old_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3720 sim_engine_run (sd
, next_cpu_nr
, nr_cpus
, siggnal
)
3723 int next_cpu_nr
; /* ignore */
3724 int nr_cpus
; /* ignore */
3725 int siggnal
; /* ignore */
3727 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* hardwire to cpu 0 */
3728 #if !defined(FASTSIM)
3729 unsigned int pipeline_count
= 1;
3733 if (STATE_MEMORY (sd
) == NULL
) {
3734 printf("DBG: simulate() entered with no memory\n");
3739 #if 0 /* Disabled to check that everything works OK */
3740 /* The VR4300 seems to sign-extend the PC on its first
3741 access. However, this may just be because it is currently
3742 configured in 32bit mode. However... */
3743 PC
= SIGNEXTEND(PC
,32);
3746 /* main controlling loop */
3748 /* vaddr is slowly being replaced with cia - current instruction
3750 address_word cia
= (uword64
)PC
;
3751 address_word vaddr
= cia
;
3754 unsigned int instruction
; /* uword64? what's this used for? FIXME! */
3758 printf("DBG: state = 0x%08X :",state
);
3759 if (state
& simHALTEX
) printf(" simHALTEX");
3760 if (state
& simHALTIN
) printf(" simHALTIN");
3765 DSSTATE
= (STATE
& simDELAYSLOT
);
3768 sim_io_printf(sd
,"DBG: DSPC = 0x%s\n",pr_addr(DSPC
));
3771 /* Fetch the next instruction from the simulator memory: */
3772 if (AddressTranslation(cia
,isINSTRUCTION
,isLOAD
,&paddr
,&cca
,isTARGET
,isREAL
)) {
3773 if ((vaddr
& 1) == 0) {
3774 /* Copy the action of the LW instruction */
3775 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 2) : 0);
3776 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 2) : 0);
3779 paddr
= ((paddr
& ~LOADDRMASK
) | ((paddr
& LOADDRMASK
) ^ (reverse
<< 2)));
3780 LoadMemory(&value
,NULL
,cca
,AccessLength_WORD
,paddr
,vaddr
,isINSTRUCTION
,isREAL
);
3781 byte
= ((vaddr
& LOADDRMASK
) ^ (bigend
<< 2));
3782 instruction
= ((value
>> (8 * byte
)) & 0xFFFFFFFF);
3784 /* Copy the action of the LH instruction */
3785 unsigned int reverse
= (ReverseEndian
? (LOADDRMASK
>> 1) : 0);
3786 unsigned int bigend
= (BigEndianCPU
? (LOADDRMASK
>> 1) : 0);
3789 paddr
= (((paddr
& ~ (uword64
) 1) & ~LOADDRMASK
)
3790 | (((paddr
& ~ (uword64
) 1) & LOADDRMASK
) ^ (reverse
<< 1)));
3791 LoadMemory(&value
,NULL
,cca
, AccessLength_HALFWORD
,
3792 paddr
& ~ (uword64
) 1,
3793 vaddr
, isINSTRUCTION
, isREAL
);
3794 byte
= (((vaddr
&~ (uword64
) 1) & LOADDRMASK
) ^ (bigend
<< 1));
3795 instruction
= ((value
>> (8 * byte
)) & 0xFFFF);
3798 fprintf(stderr
,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC
));
3803 sim_io_printf(sd
,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction
,pr_addr(PC
));
3806 /* This is required by exception processing, to ensure that we can
3807 cope with exceptions in the delay slots of branches that may
3808 already have changed the PC. */
3809 if ((vaddr
& 1) == 0)
3810 PC
+= 4; /* increment ready for the next fetch */
3813 /* NOTE: If we perform a delay slot change to the PC, this
3814 increment is not requuired. However, it would make the
3815 simulator more complicated to try and avoid this small hit. */
3817 /* Currently this code provides a simple model. For more
3818 complicated models we could perform exception status checks at
3819 this point, and set the simSTOP state as required. This could
3820 also include processing any hardware interrupts raised by any
3821 I/O model attached to the simulator context.
3823 Support for "asynchronous" I/O events within the simulated world
3824 could be providing by managing a counter, and calling a I/O
3825 specific handler when a particular threshold is reached. On most
3826 architectures a decrement and check for zero operation is
3827 usually quicker than an increment and compare. However, the
3828 process of managing a known value decrement to zero, is higher
3829 than the cost of using an explicit value UINT_MAX into the
3830 future. Which system is used will depend on how complicated the
3831 I/O model is, and how much it is likely to affect the simulator
3834 If events need to be scheduled further in the future than
3835 UINT_MAX event ticks, then the I/O model should just provide its
3836 own counter, triggered from the event system. */
3838 /* MIPS pipeline ticks. To allow for future support where the
3839 pipeline hit of individual instructions is known, this control
3840 loop manages a "pipeline_count" variable. It is initialised to
3841 1 (one), and will only be changed by the simulator engine when
3842 executing an instruction. If the engine does not have access to
3843 pipeline cycle count information then all instructions will be
3844 treated as using a single cycle. NOTE: A standard system is not
3845 provided by the default simulator because different MIPS
3846 architectures have different cycle counts for the same
3849 [NOTE: pipeline_count has been replaced the event queue] */
3851 /* shuffle the floating point status pipeline state */
3852 ENGINE_ISSUE_PREFIX_HOOK();
3854 /* NOTE: For multi-context simulation environments the "instruction"
3855 variable should be local to this routine. */
3857 /* Shorthand accesses for engine. Note: If we wanted to use global
3858 variables (and a single-threaded simulator engine), then we can
3859 create the actual variables with these names. */
3861 if (!(STATE
& simSKIPNEXT
)) {
3862 /* Include the simulator engine */
3863 #include "oengine.c"
3864 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3865 #error "Mismatch between run-time simulator code and simulation engine"
3867 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3868 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3870 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3871 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3874 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3875 should check for it being changed. It is better doing it here,
3876 than within the simulator, since it will help keep the simulator
3879 #if defined(WARN_ZERO)
3880 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
));
3881 #endif /* WARN_ZERO */
3882 ZERO
= 0; /* reset back to zero before next instruction */
3884 } else /* simSKIPNEXT check */
3885 STATE
&= ~simSKIPNEXT
;
3887 /* If the delay slot was active before the instruction is
3888 executed, then update the PC to its new value: */
3891 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC
));
3900 #if !defined(FASTSIM)
3901 if (sim_events_tickn (sd
, pipeline_count
))
3903 /* cpu->cia = cia; */
3904 sim_events_process (sd
);
3907 if (sim_events_tick (sd
))
3909 /* cpu->cia = cia; */
3910 sim_events_process (sd
);
3912 #endif /* FASTSIM */
3918 /* This code copied from gdb's utils.c. Would like to share this code,
3919 but don't know of a common place where both could get to it. */
3921 /* Temporary storage using circular buffer */
3927 static char buf
[NUMCELLS
][CELLSIZE
];
3929 if (++cell
>=NUMCELLS
) cell
=0;
3933 /* Print routines to handle variable size regs, etc */
3935 /* Eliminate warning from compiler on 32-bit systems */
3936 static int thirty_two
= 32;
3942 char *paddr_str
=get_cell();
3943 switch (sizeof(addr
))
3946 sprintf(paddr_str
,"%08lx%08lx",
3947 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3950 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
3953 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
3956 sprintf(paddr_str
,"%x",addr
);
3965 char *paddr_str
=get_cell();
3966 sprintf(paddr_str
,"%08lx%08lx",
3967 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
3973 /*---------------------------------------------------------------------------*/
3974 /*> EOF interp.c <*/