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"
44 /* start-sanitize-sky */
48 #include "sky-libvpe.h"
53 /* end-sanitize-sky */
75 #include "libiberty.h"
77 #include "callback.h" /* GDB simulator callback interface */
78 #include "remote-sim.h" /* GDB simulator interface */
86 char* pr_addr
PARAMS ((SIM_ADDR addr
));
87 char* pr_uword64
PARAMS ((uword64 addr
));
90 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
95 /* The following reserved instruction value is used when a simulator
96 trap is required. NOTE: Care must be taken, since this value may be
97 used in later revisions of the MIPS ISA. */
99 #define RSVD_INSTRUCTION (0x00000005)
100 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
102 #define RSVD_INSTRUCTION_ARG_SHIFT 6
103 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
106 /* Bits in the Debug register */
107 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
108 #define Debug_DM 0x40000000 /* Debug Mode */
109 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
111 /*---------------------------------------------------------------------------*/
112 /*-- GDB simulator interface ------------------------------------------------*/
113 /*---------------------------------------------------------------------------*/
115 static void ColdReset
PARAMS((SIM_DESC sd
));
117 /*---------------------------------------------------------------------------*/
121 #define DELAYSLOT() {\
122 if (STATE & simDELAYSLOT)\
123 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
124 STATE |= simDELAYSLOT;\
127 #define JALDELAYSLOT() {\
129 STATE |= simJALDELAYSLOT;\
133 STATE &= ~simDELAYSLOT;\
134 STATE |= simSKIPNEXT;\
137 #define CANCELDELAYSLOT() {\
139 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
142 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
143 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
145 #define K0BASE (0x80000000)
146 #define K0SIZE (0x20000000)
147 #define K1BASE (0xA0000000)
148 #define K1SIZE (0x20000000)
149 #define MONITOR_BASE (0xBFC00000)
150 #define MONITOR_SIZE (1 << 11)
151 #define MEM_SIZE (2 << 20)
153 /* start-sanitize-sky */
156 #define MEM_SIZE (16 << 20) /* 16 MB */
158 #define MONITOR_SIZE 0x100000 /* 1MB */
160 /* end-sanitize-sky */
163 static char *tracefile
= "trace.din"; /* default filename for trace log */
164 FILE *tracefh
= NULL
;
165 static void open_trace
PARAMS((SIM_DESC sd
));
168 static const char * get_insn_name (sim_cpu
*, int);
170 /* simulation target board. NULL=canonical */
171 static char* board
= NULL
;
174 static DECLARE_OPTION_HANDLER (mips_option_handler
);
177 OPTION_DINERO_TRACE
= OPTION_START
,
179 /* start-stanitize-branchbug4011 */
180 OPTION_BRANCH_BUG_4011
,
181 /* end-stanitize-branchbug4011 */
187 mips_option_handler (sd
, cpu
, opt
, arg
, is_command
)
197 /* start-sanitize-branchbug4011 */
198 case OPTION_BRANCH_BUG_4011
:
200 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
202 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
204 BRANCHBUG4011_OPTION
= 1;
205 else if (strcmp (arg
, "yes") == 0)
206 BRANCHBUG4011_OPTION
= 1;
207 else if (strcmp (arg
, "no") == 0)
208 BRANCHBUG4011_OPTION
= 0;
209 else if (strcmp (arg
, "on") == 0)
210 BRANCHBUG4011_OPTION
= 1;
211 else if (strcmp (arg
, "off") == 0)
212 BRANCHBUG4011_OPTION
= 0;
215 fprintf (stderr
, "Unrecognized check-4011-branch-bug option `%s'\n", arg
);
222 /* end-sanitize-branchbug4011 */
223 case OPTION_DINERO_TRACE
: /* ??? */
225 /* Eventually the simTRACE flag could be treated as a toggle, to
226 allow external control of the program points being traced
227 (i.e. only from main onwards, excluding the run-time setup,
229 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
231 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
234 else if (strcmp (arg
, "yes") == 0)
236 else if (strcmp (arg
, "no") == 0)
238 else if (strcmp (arg
, "on") == 0)
240 else if (strcmp (arg
, "off") == 0)
244 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
251 Simulator constructed without dinero tracing support (for performance).\n\
252 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
256 case OPTION_DINERO_FILE
:
258 if (optarg
!= NULL
) {
260 tmp
= (char *)malloc(strlen(optarg
) + 1);
263 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
269 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
279 board
= zalloc(strlen(arg
) + 1);
290 static const OPTION mips_options
[] =
292 { {"dinero-trace", optional_argument
, NULL
, OPTION_DINERO_TRACE
},
293 '\0', "on|off", "Enable dinero tracing",
294 mips_option_handler
},
295 /* start-sanitize-branchbug4011 */
296 { {"check-4011-branch-bug", optional_argument
, NULL
, OPTION_BRANCH_BUG_4011
},
297 '\0', "on|off", "Enable checking for 4011 branch bug",
298 mips_option_handler
},
299 /* end-sanitize-branchbug4011 */
300 { {"dinero-file", required_argument
, NULL
, OPTION_DINERO_FILE
},
301 '\0', "FILE", "Write dinero trace to FILE",
302 mips_option_handler
},
303 { {"board", required_argument
, NULL
, OPTION_BOARD
},
304 '\0', "none" /* rely on compile-time string concatenation for other options */
306 #define BOARD_JMR3904 "jmr3904"
308 #define BOARD_JMR3904_PAL "jmr3904pal"
309 "|" BOARD_JMR3904_PAL
310 #define BOARD_JMR3904_DEBUG "jmr3904debug"
311 "|" BOARD_JMR3904_DEBUG
313 , "Customize simulation for a particular board.", mips_option_handler
},
315 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
319 int interrupt_pending
;
322 interrupt_event (SIM_DESC sd
, void *data
)
324 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
325 address_word cia
= CIA_GET (cpu
);
328 interrupt_pending
= 0;
329 SignalExceptionInterrupt (1); /* interrupt "1" */
331 else if (!interrupt_pending
)
332 sim_events_schedule (sd
, 1, interrupt_event
, data
);
336 /*---------------------------------------------------------------------------*/
337 /*-- Device registration hook -----------------------------------------------*/
338 /*---------------------------------------------------------------------------*/
339 static void device_init(SIM_DESC sd
) {
341 extern void register_devices(SIM_DESC
);
342 register_devices(sd
);
346 /*---------------------------------------------------------------------------*/
347 /*-- GDB simulator interface ------------------------------------------------*/
348 /*---------------------------------------------------------------------------*/
351 sim_open (kind
, cb
, abfd
, argv
)
357 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
358 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
360 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
362 /* FIXME: watchpoints code shouldn't need this */
363 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
364 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
365 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
367 /* Initialize the mechanism for doing insn profiling. */
368 CPU_INSN_NAME (cpu
) = get_insn_name
;
369 CPU_MAX_INSNS (cpu
) = nr_itable_entries
;
373 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
375 sim_add_option_table (sd
, NULL
, mips_options
);
377 /* start-sanitize-sky */
379 sky_command_options_open (sd
);
381 /* end-sanitize-sky */
383 /* getopt will print the error message so we just have to exit if this fails.
384 FIXME: Hmmm... in the case of gdb we need getopt to call
386 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
388 /* Uninstall the modules to avoid memory leaks,
389 file descriptor leaks, etc. */
390 sim_module_uninstall (sd
);
394 /* handle board-specific memory maps */
397 /* Allocate core managed memory */
399 /* start-sanitize-sky */
401 /* end-sanitize-sky */
403 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
, MONITOR_SIZE
);
404 /* For compatibility with the old code - under this (at level one)
405 are the kernel spaces K0 & K1. Both of these map to a single
406 smaller sub region */
407 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
408 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
410 MEM_SIZE
, /* actual size */
412 /* start-sanitize-sky */
415 sim_do_commandf (sd
, "memory region 0x%lx,0x%lx", MONITOR_BASE
- K1BASE
, MONITOR_SIZE
);
416 sim_do_command (sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
417 /* 16M @ 0x0. Aliases at 0x80000000 and 0xA0000000 are handled by
418 address_translation() */
419 sim_do_commandf (sd
, "memory size 0x%lx", MEM_SIZE
);
421 /* end-sanitize-sky */
428 && (strcmp(board
, BOARD_JMR3904
) == 0 ||
429 strcmp(board
, BOARD_JMR3904_PAL
) == 0 ||
430 strcmp(board
, BOARD_JMR3904_DEBUG
) == 0))
432 /* match VIRTUAL memory layout of JMR-TX3904 board */
435 /* --- environment --- */
437 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
441 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
442 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
444 4 * 1024 * 1024, /* 4 MB */
447 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
448 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
450 4 * 1024 * 1024, /* 4 MB */
453 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
454 for (i
=0; i
<8; i
++) /* 32 MB total */
456 unsigned size
= 4 * 1024 * 1024; /* 4 MB */
457 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
458 0x88000000 + (i
* size
),
460 0xA8000000 + (i
* size
));
463 /* Dummy memory regions for unsimulated devices */
465 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFFE010, 0x00c); /* EBIF */
466 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
467 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
469 /* --- simulated devices --- */
470 sim_hw_parse (sd
, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
471 sim_hw_parse (sd
, "/tx3904cpu");
472 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
473 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
474 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
475 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
477 /* FIXME: poking at dv-sockser internals, use tcp backend if
478 --sockser_addr option was given.*/
479 extern char* sockser_addr
;
480 if(sockser_addr
== NULL
)
481 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/backend stdio");
483 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/backend tcp");
485 sim_hw_parse (sd
, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
486 sim_hw_parse (sd
, "/tx3904sio@0xfffff400/backend stdio");
488 /* -- device connections --- */
489 sim_hw_parse (sd
, "/tx3904irc > ip level /tx3904cpu");
490 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
491 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
492 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
493 sim_hw_parse (sd
, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
494 sim_hw_parse (sd
, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
496 /* add PAL timer & I/O module */
497 if(! strcmp(board
, BOARD_JMR3904_PAL
))
500 sim_hw_parse (sd
, "/pal@0xffff0000");
501 sim_hw_parse (sd
, "/pal@0xffff0000/reg 0xffff0000 64");
503 /* wire up interrupt ports to irc */
504 sim_hw_parse (sd
, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
505 sim_hw_parse (sd
, "/pal@0x31000000 > timer tmr1 /tx3904irc");
506 sim_hw_parse (sd
, "/pal@0x31000000 > int int0 /tx3904irc");
509 if(! strcmp(board
, BOARD_JMR3904_DEBUG
))
511 /* -- DEBUG: glue interrupt generators --- */
512 sim_hw_parse (sd
, "/glue@0xffff0000/reg 0xffff0000 0x50");
513 sim_hw_parse (sd
, "/glue@0xffff0000 > int0 int0 /tx3904irc");
514 sim_hw_parse (sd
, "/glue@0xffff0000 > int1 int1 /tx3904irc");
515 sim_hw_parse (sd
, "/glue@0xffff0000 > int2 int2 /tx3904irc");
516 sim_hw_parse (sd
, "/glue@0xffff0000 > int3 int3 /tx3904irc");
517 sim_hw_parse (sd
, "/glue@0xffff0000 > int4 int4 /tx3904irc");
518 sim_hw_parse (sd
, "/glue@0xffff0000 > int5 int5 /tx3904irc");
519 sim_hw_parse (sd
, "/glue@0xffff0000 > int6 int6 /tx3904irc");
520 sim_hw_parse (sd
, "/glue@0xffff0000 > int7 int7 /tx3904irc");
521 sim_hw_parse (sd
, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
522 sim_hw_parse (sd
, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
523 sim_hw_parse (sd
, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
524 sim_hw_parse (sd
, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
525 sim_hw_parse (sd
, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
526 sim_hw_parse (sd
, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
527 sim_hw_parse (sd
, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
528 sim_hw_parse (sd
, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
529 sim_hw_parse (sd
, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
530 sim_hw_parse (sd
, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
538 /* check for/establish the a reference program image */
539 if (sim_analyze_program (sd
,
540 (STATE_PROG_ARGV (sd
) != NULL
541 ? *STATE_PROG_ARGV (sd
)
545 sim_module_uninstall (sd
);
549 /* Configure/verify the target byte order and other runtime
550 configuration options */
551 if (sim_config (sd
) != SIM_RC_OK
)
553 sim_module_uninstall (sd
);
557 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
559 /* Uninstall the modules to avoid memory leaks,
560 file descriptor leaks, etc. */
561 sim_module_uninstall (sd
);
565 /* verify assumptions the simulator made about the host type system.
566 This macro does not return if there is a problem */
567 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
568 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
570 /* This is NASTY, in that we are assuming the size of specific
574 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
577 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
578 else if ((rn
>= FGRIDX
) && (rn
< (FGRIDX
+ NR_FGR
)))
579 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
580 else if ((rn
>= 33) && (rn
<= 37))
581 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
582 else if ((rn
== SRIDX
)
585 || ((rn
>= 72) && (rn
<= 89)))
586 cpu
->register_widths
[rn
] = 32;
588 cpu
->register_widths
[rn
] = 0;
591 /* start-sanitize-r5900 */
592 /* set the 5900 "upper" registers to 64 bits */
593 for( rn
= LAST_EMBED_REGNUM
+1; rn
< FIRST_COP0_REG
; rn
++)
594 cpu
->register_widths
[rn
] = 64;
596 for( rn
= FIRST_COP0_REG
; rn
< NUM_REGS
; rn
++)
597 cpu
->register_widths
[rn
] = 32;
598 /* end-sanitize-r5900 */
600 /* start-sanitize-sky */
602 /* Now the VU registers */
603 for( rn
= 0; rn
< NUM_VU_INTEGER_REGS
; rn
++ ) {
604 cpu
->register_widths
[rn
+ NUM_CORE_REGS
] = 16;
605 cpu
->register_widths
[rn
+ NUM_CORE_REGS
+ NUM_VU_REGS
] = 16;
608 for( rn
= NUM_VU_INTEGER_REGS
; rn
< NUM_VU_REGS
; rn
++ ) {
609 cpu
->register_widths
[rn
+ NUM_CORE_REGS
] = 32;
610 cpu
->register_widths
[rn
+ NUM_CORE_REGS
+ NUM_VU_REGS
] = 32;
613 /* Finally the VIF registers */
614 for( rn
= 2*NUM_VU_REGS
; rn
< 2*NUM_VU_REGS
+ 2*NUM_VIF_REGS
; rn
++ )
615 cpu
->register_widths
[rn
+ NUM_CORE_REGS
] = 32;
619 /* end-sanitize-sky */
623 if (STATE
& simTRACE
)
627 /* Write an abort sequence into the TRAP (common) exception vector
628 addresses. This is to catch code executing a TRAP (et.al.)
629 instruction without installing a trap handler. */
631 unsigned32 halt
[2] = { 0x2404002f /* addiu r4, r0, 47 */,
632 HALT_INSTRUCTION
/* BREAK */ };
635 sim_write (sd
, 0x80000000, (char *) halt
, sizeof (halt
));
636 sim_write (sd
, 0x80000180, (char *) halt
, sizeof (halt
));
637 sim_write (sd
, 0x80000200, (char *) halt
, sizeof (halt
));
638 sim_write (sd
, 0xBFC00200, (char *) halt
, sizeof (halt
));
639 sim_write (sd
, 0xBFC00380, (char *) halt
, sizeof (halt
));
640 sim_write (sd
, 0xBFC00400, (char *) halt
, sizeof (halt
));
644 /* Write the monitor trap address handlers into the monitor (eeprom)
645 address space. This can only be done once the target endianness
646 has been determined. */
649 /* Entry into the IDT monitor is via fixed address vectors, and
650 not using machine instructions. To avoid clashing with use of
651 the MIPS TRAP system, we place our own (simulator specific)
652 "undefined" instructions into the relevant vector slots. */
653 for (loop
= 0; (loop
< MONITOR_SIZE
); loop
+= 4)
655 address_word vaddr
= (MONITOR_BASE
+ loop
);
656 unsigned32 insn
= (RSVD_INSTRUCTION
| (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
) << RSVD_INSTRUCTION_ARG_SHIFT
));
658 sim_write (sd
, vaddr
, (char *)&insn
, sizeof (insn
));
660 /* The PMON monitor uses the same address space, but rather than
661 branching into it the address of a routine is loaded. We can
662 cheat for the moment, and direct the PMON routine to IDT style
663 instructions within the monitor space. This relies on the IDT
664 monitor not using the locations from 0xBFC00500 onwards as its
666 for (loop
= 0; (loop
< 24); loop
++)
668 address_word vaddr
= (MONITOR_BASE
+ 0x500 + (loop
* 4));
669 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
685 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
687 case 8: /* cliexit */
690 case 11: /* flush_cache */
694 /* FIXME - should monitor_base be SIM_ADDR?? */
695 value
= ((unsigned int)MONITOR_BASE
+ (value
* 8));
697 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
699 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
701 sim_write (sd
, vaddr
, (char *)&value
, sizeof (value
));
706 /* start-sanitize-sky */
708 /* Default TLB initialization... */
710 #define KPAGEMASK 0x001fe000
711 #define PAGE_MASK_4K 0x00000000
712 #define PAGE_MASK_16K 0x00006000
713 #define PAGE_MASK_64K 0x0001e000
714 #define PAGE_MASK_256K 0x0007e000
715 #define PAGE_MASK_1M 0x001fe000
716 #define PAGE_MASK_4M 0x007fe000
717 #define PAGE_MASK_16M 0x01ffe000
719 #define SET_TLB(index, page_mask, entry_hi, entry_lo0, entry_lo1) \
720 TLB[index].mask = page_mask; \
721 TLB[index].hi = entry_hi; \
722 TLB[index].lo0 = entry_lo0; \
723 TLB[index].lo1 = entry_lo1
725 SET_TLB(0, PAGE_MASK_16M
, 0x00000000, 0x0000001e, 0x0004001e);/*0-32M*/
727 #endif /* TARGET_SKY */
728 /* end-sanitize-sky */
738 tracefh
= fopen(tracefile
,"wb+");
741 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
747 /* Return name of an insn, used by insn profiling. */
749 get_insn_name (sim_cpu
*cpu
, int i
)
751 return itable
[i
].name
;
755 sim_close (sd
, quitting
)
760 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
763 /* start-sanitize-sky */
765 sky_command_options_close (sd
);
767 /* end-sanitize-sky */
769 /* "quitting" is non-zero if we cannot hang on errors */
771 /* shut down modules */
772 sim_module_uninstall (sd
);
774 /* Ensure that any resources allocated through the callback
775 mechanism are released: */
776 sim_io_shutdown (sd
);
779 if (tracefh
!= NULL
&& tracefh
!= stderr
)
784 /* FIXME - free SD */
791 sim_write (sd
,addr
,buffer
,size
)
794 unsigned char *buffer
;
798 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
800 /* Return the number of bytes written, or zero if error. */
802 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
805 /* We use raw read and write routines, since we do not want to count
806 the GDB memory accesses in our statistics gathering. */
808 for (index
= 0; index
< size
; index
++)
810 address_word vaddr
= (address_word
)addr
+ index
;
813 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
815 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
823 sim_read (sd
,addr
,buffer
,size
)
826 unsigned char *buffer
;
830 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
832 /* Return the number of bytes read, or zero if error. */
834 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
837 for (index
= 0; (index
< size
); index
++)
839 address_word vaddr
= (address_word
)addr
+ index
;
842 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isLOAD
, &paddr
, &cca
, isRAW
))
844 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
852 sim_store_register (sd
,rn
,memory
,length
)
855 unsigned char *memory
;
858 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
859 /* NOTE: gdb (the client) stores registers in target byte order
860 while the simulator uses host byte order */
862 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
865 /* Unfortunately this suffers from the same problem as the register
866 numbering one. We need to know what the width of each logical
867 register number is for the architecture being simulated. */
869 if (cpu
->register_widths
[rn
] == 0)
871 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
875 /* start-sanitize-r5900 */
876 if (rn
>= 90 && rn
< 90 + 32)
878 GPR1
[rn
- 90] = T2H_8 (*(unsigned64
*)memory
);
884 SA
= T2H_8(*(unsigned64
*)memory
);
886 case 122: /* FIXME */
887 LO1
= T2H_8(*(unsigned64
*)memory
);
889 case 123: /* FIXME */
890 HI1
= T2H_8(*(unsigned64
*)memory
);
894 if (rn
>= FIRST_COP0_REG
&& rn
< (FIRST_COP0_REG
+NUM_COP0_REGS
))
896 switch (rn
- FIRST_COP0_REG
)
898 case 12: /* Status */
900 return -1; /* Already done in regular register set */
902 EPC
= T2H_4(*((unsigned32
*) memory
));
905 C0_CONFIG
= T2H_4(*((unsigned32
*) memory
));
908 Debug
= T2H_4(*((unsigned32
*) memory
));
911 COP0_GPR
[rn
- FIRST_COP0_REG
+ 7] = T2H_4(*((unsigned32
*) memory
));
915 case 21: /* ErrorEPC */
916 COP0_GPR
[rn
- FIRST_COP0_REG
+ 9] = T2H_4(*((unsigned32
*) memory
));
919 COP0_GPR
[rn
- FIRST_COP0_REG
] = T2H_4(*((unsigned32
*) memory
));
925 /* end-sanitize-r5900 */
927 /* start-sanitize-sky */
929 if (rn
>= NUM_CORE_REGS
)
931 rn
= rn
- NUM_CORE_REGS
;
933 if( rn
< NUM_VU_REGS
)
936 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
939 if (rn
< NUM_VU_INTEGER_REGS
)
940 return write_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
941 else if (rn
>= FIRST_VEC_REG
)
944 return write_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
&3,
947 else switch (rn
- NUM_VU_INTEGER_REGS
)
950 return write_vu_special_reg (&vu0_device
, VU_REG_CIA
, memory
);
952 case 1: /* Can't write TPC register */
953 case 2: /* or VPU_STAT */
955 case 9: /* VU0 has no P register */
959 return write_vu_misc_reg(&(vu0_device
.regs
), VU_REG_MST
, memory
);
961 return write_vu_misc_reg(&(vu0_device
.regs
), VU_REG_MCP
, memory
);
963 return write_vu_special_reg (&vu0_device
, VU_REG_CMSAR0
, memory
);
965 return write_vu_special_reg (&vu0_device
, VU_REG_FBRST
, memory
);
967 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
, memory
);
969 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
, memory
);
971 return write_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
, memory
);
973 return write_vu_acc_reg (&(vu0_device
.regs
),
974 rn
- (NUM_VU_INTEGER_REGS
+ 12),
977 #endif /* ! TARGET_SKY_B */
980 rn
= rn
- NUM_VU_REGS
;
982 if (rn
< NUM_VU_REGS
)
984 if (rn
< NUM_VU_INTEGER_REGS
)
985 return write_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
986 else if (rn
>= FIRST_VEC_REG
)
989 return write_vu_vec_reg (&(vu1_device
.regs
),
990 rn
>> 2, rn
& 3, memory
);
992 else switch (rn
- NUM_VU_INTEGER_REGS
)
995 return write_vu_special_reg (&vu1_device
, VU_REG_CIA
, memory
);
997 case 1: /* Can't write TPC register */
998 case 2: /* or VPU_STAT */
1000 case 7: /* VU1 has no FBRST register */
1004 return write_vu_misc_reg(&(vu1_device
.regs
), VU_REG_MST
, memory
);
1006 return write_vu_misc_reg(&(vu1_device
.regs
), VU_REG_MCP
, memory
);
1007 case 6: /* CMSAR1 is actually part of VU0 */
1011 return write_vu_special_reg (&vu0_device
, VU_REG_CMSAR1
, memory
);
1012 #endif /* ! TARGET_SKY_B */
1014 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MR
, memory
);
1016 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MP
, memory
);
1018 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MI
, memory
);
1020 return write_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MQ
, memory
);
1022 return write_vu_acc_reg (&(vu1_device
.regs
),
1023 rn
- (NUM_VU_INTEGER_REGS
+ 12),
1028 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
1030 if (rn
< NUM_VIF_REGS
)
1033 sim_io_eprintf( sd
, "Invalid VIF register (register store ignored)\n" );
1036 if (rn
< NUM_VIF_REGS
-1)
1037 return write_vif_reg (&vif0_device
, rn
, memory
);
1040 sim_io_eprintf( sd
, "Can't write vif0_pc (store ignored)\n" );
1043 #endif /* ! TARGET_SKY_B */
1046 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
1048 if (rn
< NUM_VIF_REGS
)
1050 if (rn
< NUM_VIF_REGS
-1)
1051 return write_vif_reg (&vif1_device
, rn
, memory
);
1054 sim_io_eprintf( sd
, "Can't write vif1_pc (store ignored)\n" );
1059 sim_io_eprintf( sd
, "Invalid VU register (register store ignored)\n" );
1063 /* end-sanitize-sky */
1065 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
1067 if (cpu
->register_widths
[rn
] == 32)
1069 cpu
->fgr
[rn
- FGRIDX
] = T2H_4 (*(unsigned32
*)memory
);
1074 cpu
->fgr
[rn
- FGRIDX
] = T2H_8 (*(unsigned64
*)memory
);
1079 if (cpu
->register_widths
[rn
] == 32)
1081 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
1086 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
1094 sim_fetch_register (sd
,rn
,memory
,length
)
1097 unsigned char *memory
;
1100 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
1101 /* NOTE: gdb (the client) stores registers in target byte order
1102 while the simulator uses host byte order */
1104 #if 0 /* FIXME: doesn't compile */
1105 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
1109 if (cpu
->register_widths
[rn
] == 0)
1111 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
1115 /* start-sanitize-r5900 */
1116 if (rn
>= 90 && rn
< 90 + 32)
1118 *((unsigned64
*)memory
) = H2T_8 (GPR1
[rn
- 90]);
1124 *((unsigned64
*)memory
) = H2T_8(SA
);
1126 case 122: /* FIXME */
1127 *((unsigned64
*)memory
) = H2T_8(LO1
);
1129 case 123: /* FIXME */
1130 *((unsigned64
*)memory
) = H2T_8(HI1
);
1134 if (rn
>= FIRST_COP0_REG
&& rn
< (FIRST_COP0_REG
+NUM_COP0_REGS
))
1136 switch (rn
- FIRST_COP0_REG
)
1138 case 12: /* Status */
1139 case 13: /* Cause */
1140 return -1; /* Already done in regular register set */
1142 *((unsigned32
*) memory
) = H2T_4(EPC
);
1145 *((unsigned32
*) memory
) = H2T_4(C0_CONFIG
);
1147 case 17: /* Debug */
1148 *((unsigned32
*) memory
) = H2T_4(Debug
);
1151 *((unsigned32
*) memory
) = H2T_4(COP0_GPR
[rn
- FIRST_COP0_REG
+ 7]);
1153 case 19: /* TagLo */
1154 case 20: /* TagHi */
1155 case 21: /* ErrorEPC */
1156 *((unsigned32
*) memory
) = H2T_4(COP0_GPR
[rn
- FIRST_COP0_REG
+ 9]);
1159 *((unsigned32
*) memory
) = H2T_4(COP0_GPR
[rn
- FIRST_COP0_REG
]);
1165 /* end-sanitize-r5900 */
1167 /* start-sanitize-sky */
1169 if (rn
>= NUM_CORE_REGS
)
1171 rn
= rn
- NUM_CORE_REGS
;
1173 if (rn
< NUM_VU_REGS
)
1176 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
1179 if (rn
< NUM_VU_INTEGER_REGS
)
1180 return read_vu_int_reg (&(vu0_device
.regs
), rn
, memory
);
1181 else if (rn
>= FIRST_VEC_REG
)
1183 rn
-= FIRST_VEC_REG
;
1184 return read_vu_vec_reg (&(vu0_device
.regs
), rn
>>2, rn
& 3,
1187 else switch (rn
- NUM_VU_INTEGER_REGS
)
1190 return read_vu_special_reg (&vu0_device
, VU_REG_CIA
, memory
);
1192 return read_vu_misc_reg(&(vu0_device
.regs
), VU_REG_MTPC
, memory
);
1194 return read_vu_special_reg (&vu0_device
, VU_REG_STAT
, memory
);
1196 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MST
, memory
);
1198 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MMC
, memory
);
1200 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MCP
, memory
);
1202 return read_vu_special_reg (&vu0_device
, VU_REG_CMSAR0
, memory
);
1204 return read_vu_special_reg (&vu0_device
, VU_REG_FBRST
, memory
);
1206 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MR
, memory
);
1207 case 9: /* VU0 has no P register */
1208 *((int *) memory
) = 0;
1211 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MI
, memory
);
1213 return read_vu_misc_reg (&(vu0_device
.regs
), VU_REG_MQ
, memory
);
1215 return read_vu_acc_reg (&(vu0_device
.regs
),
1216 rn
- (NUM_VU_INTEGER_REGS
+ 12),
1219 #endif /* ! TARGET_SKY_B */
1222 rn
-= NUM_VU_REGS
; /* VU1 registers are next */
1224 if (rn
< NUM_VU_REGS
)
1226 if (rn
< NUM_VU_INTEGER_REGS
)
1227 return read_vu_int_reg (&(vu1_device
.regs
), rn
, memory
);
1228 else if (rn
>= FIRST_VEC_REG
)
1230 rn
-= FIRST_VEC_REG
;
1231 return read_vu_vec_reg (&(vu1_device
.regs
),
1232 rn
>> 2, rn
& 3, memory
);
1234 else switch (rn
- NUM_VU_INTEGER_REGS
)
1237 return read_vu_special_reg (&vu1_device
, VU_REG_CIA
, memory
);
1239 return read_vu_misc_reg(&(vu1_device
.regs
), VU_REG_MTPC
, memory
);
1241 return read_vu_special_reg (&vu1_device
, VU_REG_STAT
, memory
);
1243 return read_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MST
, memory
);
1245 return read_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MMC
, memory
);
1247 return read_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MCP
, memory
);
1248 case 6: /* CMSAR1 is actually from VU0 */
1252 return read_vu_special_reg (&vu0_device
, VU_REG_CMSAR1
, memory
);
1253 #endif /* ! TARGET_SKY_B */
1254 case 7: /* VU1 has no FBRST register */
1255 *((int *) memory
) = 0;
1258 return read_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MR
, memory
);
1260 return read_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MP
, memory
);
1262 return read_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MI
, memory
);
1264 return read_vu_misc_reg (&(vu1_device
.regs
), VU_REG_MQ
, memory
);
1266 return read_vu_acc_reg (&(vu1_device
.regs
),
1267 rn
- (NUM_VU_INTEGER_REGS
+ 12),
1272 rn
-= NUM_VU_REGS
; /* VIF0 registers are next */
1274 if (rn
< NUM_VIF_REGS
)
1277 sim_io_eprintf( sd
, "Invalid VIF register (register fetch ignored)\n" );
1280 if (rn
< NUM_VIF_REGS
-2)
1281 return read_vif_reg (&vif0_device
, rn
, memory
);
1282 else if (rn
== NUM_VIF_REGS
-2)
1283 return read_vif_pc (&vif0_device
, memory
);
1285 return read_vif_pcx (&vif0_device
, memory
);
1286 #endif /* ! TARGET_SKY_B */
1289 rn
-= NUM_VIF_REGS
; /* VIF1 registers are last */
1291 if (rn
< NUM_VIF_REGS
)
1293 if (rn
< NUM_VIF_REGS
-2)
1294 return read_vif_reg (&vif1_device
, rn
, memory
);
1295 else if (rn
== NUM_VIF_REGS
-2)
1296 return read_vif_pc (&vif1_device
, memory
);
1298 return read_vif_pcx (&vif1_device
, memory
);
1301 sim_io_eprintf( sd
, "Invalid VU register (register fetch ignored)\n" );
1304 /* end-sanitize-sky */
1306 /* Any floating point register */
1307 if (rn
>= FGRIDX
&& rn
< FGRIDX
+ NR_FGR
)
1309 if (cpu
->register_widths
[rn
] == 32)
1311 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGRIDX
]);
1316 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGRIDX
]);
1321 if (cpu
->register_widths
[rn
] == 32)
1323 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
1328 *(unsigned64
*)memory
= H2T_8 ((unsigned64
)(cpu
->registers
[rn
]));
1337 sim_create_inferior (sd
, abfd
, argv
,env
)
1345 #if 0 /* FIXME: doesn't compile */
1346 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1355 /* override PC value set by ColdReset () */
1357 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1359 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1360 CIA_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
1364 #if 0 /* def DEBUG */
1367 /* We should really place the argv slot values into the argument
1368 registers, and onto the stack as required. However, this
1369 assumes that we have a stack defined, which is not
1370 necessarily true at the moment. */
1372 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1373 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1374 printf("DBG: arg \"%s\"\n",*cptr
);
1382 sim_do_command (sd
,cmd
)
1386 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1387 sim_io_printf (sd
, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1391 /*---------------------------------------------------------------------------*/
1392 /*-- Private simulator support interface ------------------------------------*/
1393 /*---------------------------------------------------------------------------*/
1395 /* Read a null terminated string from memory, return in a buffer */
1397 fetch_str (SIM_DESC sd
,
1403 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1405 buf
= NZALLOC (char, nr
+ 1);
1406 sim_read (sd
, addr
, buf
, nr
);
1410 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1412 sim_monitor (SIM_DESC sd
,
1415 unsigned int reason
)
1418 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1421 /* The IDT monitor actually allows two instructions per vector
1422 slot. However, the simulator currently causes a trap on each
1423 individual instruction. We cheat, and lose the bottom bit. */
1426 /* The following callback functions are available, however the
1427 monitor we are simulating does not make use of them: get_errno,
1428 isatty, lseek, rename, system, time and unlink */
1432 case 6: /* int open(char *path,int flags) */
1434 char *path
= fetch_str (sd
, A0
);
1435 V0
= sim_io_open (sd
, path
, (int)A1
);
1440 case 7: /* int read(int file,char *ptr,int len) */
1444 char *buf
= zalloc (nr
);
1445 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1446 sim_write (sd
, A1
, buf
, nr
);
1451 case 8: /* int write(int file,char *ptr,int len) */
1455 char *buf
= zalloc (nr
);
1456 sim_read (sd
, A1
, buf
, nr
);
1457 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1462 case 10: /* int close(int file) */
1464 V0
= sim_io_close (sd
, (int)A0
);
1468 case 2: /* Densan monitor: char inbyte(int waitflag) */
1470 if (A0
== 0) /* waitflag == NOWAIT */
1471 V0
= (unsigned_word
)-1;
1473 /* Drop through to case 11 */
1475 case 11: /* char inbyte(void) */
1478 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1480 sim_io_error(sd
,"Invalid return from character read");
1481 V0
= (unsigned_word
)-1;
1484 V0
= (unsigned_word
)tmp
;
1488 case 3: /* Densan monitor: void co(char chr) */
1489 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1491 char tmp
= (char)(A0
& 0xFF);
1492 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1496 case 17: /* void _exit() */
1498 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1499 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1500 (unsigned int)(A0
& 0xFFFFFFFF));
1504 case 28 : /* PMON flush_cache */
1507 case 55: /* void get_mem_info(unsigned int *ptr) */
1508 /* in: A0 = pointer to three word memory location */
1509 /* out: [A0 + 0] = size */
1510 /* [A0 + 4] = instruction cache size */
1511 /* [A0 + 8] = data cache size */
1513 unsigned_4 value
= MEM_SIZE
/* FIXME STATE_MEM_SIZE (sd) */;
1514 unsigned_4 zero
= 0;
1516 sim_write (sd
, A0
+ 0, (char *)&value
, 4);
1517 sim_write (sd
, A0
+ 4, (char *)&zero
, 4);
1518 sim_write (sd
, A0
+ 8, (char *)&zero
, 4);
1519 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1523 case 158 : /* PMON printf */
1524 /* in: A0 = pointer to format string */
1525 /* A1 = optional argument 1 */
1526 /* A2 = optional argument 2 */
1527 /* A3 = optional argument 3 */
1529 /* The following is based on the PMON printf source */
1531 address_word s
= A0
;
1533 signed_word
*ap
= &A1
; /* 1st argument */
1534 /* This isn't the quickest way, since we call the host print
1535 routine for every character almost. But it does avoid
1536 having to allocate and manage a temporary string buffer. */
1537 /* TODO: Include check that we only use three arguments (A1,
1539 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1544 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1545 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1546 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1548 if (strchr ("dobxXulscefg%", c
))
1563 else if (c
>= '1' && c
<= '9')
1567 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1570 n
= (unsigned int)strtol(tmp
,NULL
,10);
1583 sim_io_printf (sd
, "%%");
1588 address_word p
= *ap
++;
1590 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1591 sim_io_printf(sd
, "%c", ch
);
1594 sim_io_printf(sd
,"(null)");
1597 sim_io_printf (sd
, "%c", (int)*ap
++);
1602 sim_read (sd
, s
++, &c
, 1);
1606 sim_read (sd
, s
++, &c
, 1);
1609 if (strchr ("dobxXu", c
))
1611 word64 lv
= (word64
) *ap
++;
1613 sim_io_printf(sd
,"<binary not supported>");
1616 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1618 sim_io_printf(sd
, tmp
, lv
);
1620 sim_io_printf(sd
, tmp
, (int)lv
);
1623 else if (strchr ("eEfgG", c
))
1625 double dbl
= *(double*)(ap
++);
1626 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1627 sim_io_printf (sd
, tmp
, dbl
);
1633 sim_io_printf(sd
, "%c", c
);
1639 sim_io_error (sd
, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1640 reason
, pr_addr(cia
));
1646 /* Store a word into memory. */
1649 store_word (SIM_DESC sd
,
1658 if ((vaddr
& 3) != 0)
1659 SignalExceptionAddressStore ();
1662 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1665 const uword64 mask
= 7;
1669 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1670 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1671 memval
= ((uword64
) val
) << (8 * byte
);
1672 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1678 /* Load a word from memory. */
1681 load_word (SIM_DESC sd
,
1686 if ((vaddr
& 3) != 0)
1688 SIM_CORE_SIGNAL (SD
, cpu
, cia
, read_map
, AccessLength_WORD
+1, vaddr
, read_transfer
, sim_core_unaligned_signal
);
1695 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1698 const uword64 mask
= 0x7;
1699 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1700 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1704 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1705 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1707 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1708 return SIGNEXTEND (((memval
>> (8 * byte
)) & 0xffffffff), 32);
1715 /* Simulate the mips16 entry and exit pseudo-instructions. These
1716 would normally be handled by the reserved instruction exception
1717 code, but for ease of simulation we just handle them directly. */
1720 mips16_entry (SIM_DESC sd
,
1725 int aregs
, sregs
, rreg
;
1728 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1731 aregs
= (insn
& 0x700) >> 8;
1732 sregs
= (insn
& 0x0c0) >> 6;
1733 rreg
= (insn
& 0x020) >> 5;
1735 /* This should be checked by the caller. */
1744 /* This is the entry pseudo-instruction. */
1746 for (i
= 0; i
< aregs
; i
++)
1747 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1755 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1758 for (i
= 0; i
< sregs
; i
++)
1761 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1769 /* This is the exit pseudo-instruction. */
1776 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1779 for (i
= 0; i
< sregs
; i
++)
1782 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1787 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1791 FGR
[0] = WORD64LO (GPR
[4]);
1792 FPR_STATE
[0] = fmt_uninterpreted
;
1794 else if (aregs
== 6)
1796 FGR
[0] = WORD64LO (GPR
[5]);
1797 FGR
[1] = WORD64LO (GPR
[4]);
1798 FPR_STATE
[0] = fmt_uninterpreted
;
1799 FPR_STATE
[1] = fmt_uninterpreted
;
1808 /*-- trace support ----------------------------------------------------------*/
1810 /* The TRACE support is provided (if required) in the memory accessing
1811 routines. Since we are also providing the architecture specific
1812 features, the architecture simulation code can also deal with
1813 notifying the TRACE world of cache flushes, etc. Similarly we do
1814 not need to provide profiling support in the simulator engine,
1815 since we can sample in the instruction fetch control loop. By
1816 defining the TRACE manifest, we add tracing as a run-time
1820 /* Tracing by default produces "din" format (as required by
1821 dineroIII). Each line of such a trace file *MUST* have a din label
1822 and address field. The rest of the line is ignored, so comments can
1823 be included if desired. The first field is the label which must be
1824 one of the following values:
1829 3 escape record (treated as unknown access type)
1830 4 escape record (causes cache flush)
1832 The address field is a 32bit (lower-case) hexadecimal address
1833 value. The address should *NOT* be preceded by "0x".
1835 The size of the memory transfer is not important when dealing with
1836 cache lines (as long as no more than a cache line can be
1837 transferred in a single operation :-), however more information
1838 could be given following the dineroIII requirement to allow more
1839 complete memory and cache simulators to provide better
1840 results. i.e. the University of Pisa has a cache simulator that can
1841 also take bus size and speed as (variable) inputs to calculate
1842 complete system performance (a much more useful ability when trying
1843 to construct an end product, rather than a processor). They
1844 currently have an ARM version of their tool called ChARM. */
1848 dotrace (SIM_DESC sd
,
1856 if (STATE
& simTRACE
) {
1858 fprintf(tracefh
,"%d %s ; width %d ; ",
1862 va_start(ap
,comment
);
1863 vfprintf(tracefh
,comment
,ap
);
1865 fprintf(tracefh
,"\n");
1867 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1868 we may be generating 64bit ones, we should put the hi-32bits of the
1869 address into the comment field. */
1871 /* TODO: Provide a buffer for the trace lines. We can then avoid
1872 performing writes until the buffer is filled, or the file is
1875 /* NOTE: We could consider adding a comment field to the "din" file
1876 produced using type 3 markers (unknown access). This would then
1877 allow information about the program that the "din" is for, and
1878 the MIPs world that was being simulated, to be placed into the
1885 /*---------------------------------------------------------------------------*/
1886 /*-- simulator engine -------------------------------------------------------*/
1887 /*---------------------------------------------------------------------------*/
1890 ColdReset (SIM_DESC sd
)
1893 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1895 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1896 /* RESET: Fixed PC address: */
1897 PC
= (unsigned_word
) UNSIGNED64 (0xFFFFFFFFBFC00000);
1898 /* The reset vector address is in the unmapped, uncached memory space. */
1900 SR
&= ~(status_SR
| status_TS
| status_RP
);
1901 SR
|= (status_ERL
| status_BEV
);
1903 /* Cheat and allow access to the complete register set immediately */
1904 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1905 && WITH_TARGET_WORD_BITSIZE
== 64)
1906 SR
|= status_FR
; /* 64bit registers */
1908 /* Ensure that any instructions with pending register updates are
1910 PENDING_INVALIDATE();
1912 /* Initialise the FPU registers to the unknown state */
1913 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1916 for (rn
= 0; (rn
< 32); rn
++)
1917 FPR_STATE
[rn
] = fmt_uninterpreted
;
1925 /* start-sanitize-sky */
1928 /* See ch. 5 of the 5900 Users' Guide. */
1930 signal_exception (SIM_DESC sd
,
1938 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",cause
,pr_addr(cia
));
1941 /* Ensure that any active atomic read/modify/write operation will fail: */
1944 /* Save registers before interrupt dispatching */
1945 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1946 SIM_CPU_EXCEPTION_TRIGGER(sd
, cpu
, cia
);
1949 /* First, handle any simulator specific magic exceptions. These are not "real" exceptions, but
1950 are exceptions which the simulator uses to implement different features. */
1954 case SimulatorFault
:
1959 msg
= va_arg(ap
,char *);
1961 sim_engine_abort (SD
, CPU
, NULL_CIA
,
1962 "FATAL: Simulator error \"%s\"\n",msg
);
1965 case DebugBreakPoint
:
1966 if (! (Debug
& Debug_DM
))
1972 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1973 DEPC
= cia
- 4; /* reference the branch instruction */
1977 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1981 Debug
|= Debug_DM
; /* in debugging mode */
1982 Debug
|= Debug_DBp
; /* raising a DBp exception */
1984 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1988 case ReservedInstruction
:
1991 unsigned int instruction
;
1993 instruction
= va_arg(ap
,unsigned int);
1995 /* Provide simple monitor support using ReservedInstruction
1996 exceptions. The following code simulates the fixed vector
1997 entry points into the IDT monitor by causing a simulator
1998 trap, performing the monitor operation, and returning to
1999 the address held in the $ra register (standard PCS return
2000 address). This means we only need to pre-load the vector
2001 space with suitable instruction values. For systems were
2002 actual trap instructions are used, we would not need to
2003 perform this magic. */
2004 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
2006 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
2007 /* NOTE: This assumes that a branch-and-link style
2008 instruction was used to enter the vector (which is the
2009 case with the current IDT monitor). */
2010 sim_engine_restart (SD
, CPU
, NULL
, RA
);
2012 /* Look for the mips16 entry and exit instructions, and
2013 simulate a handler for them. */
2014 else if ((cia
& 1) != 0
2015 && (instruction
& 0xf81f) == 0xe809
2016 && (instruction
& 0x0c0) != 0x0c0)
2018 mips16_entry (SD
, CPU
, cia
, instruction
);
2019 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
2021 /* else fall through to normal exception processing */
2022 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
2026 /* Now we have the code for processing "real" exceptions. */
2028 if (is5900Level2Exception(cause
)) {
2034 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2035 "FATAL: Unexpected level 2 exception %d\n", cause
);
2037 if (STATE
& simDELAYSLOT
)
2039 STATE
&= ~simDELAYSLOT
;
2040 COP0_ERROREPC
= (cia
- 4); /* reference the branch instruction */
2045 COP0_ERROREPC
= cia
;
2046 CAUSE
&= ~cause_BD2
;
2051 if (cause
== NMIReset
)
2055 ASSERT(0); /* At the moment, COUNTER, DEBUG never generated. */
2057 sim_engine_restart (SD
, CPU
, NULL
, PC
);
2059 /* A level 1 exception. */
2060 int refill
, vector_offset
;
2062 cause_set_EXC(cause
);
2063 if (SR
& status_EXL
)
2064 vector_offset
= 0x180;
2067 if (cause
== TLBLoad
|| cause
== TLBStore
) {
2069 va_start(ap
, cause
);
2070 refill
= va_arg(ap
,int);
2074 if (STATE
& simDELAYSLOT
)
2076 STATE
&= ~simDELAYSLOT
;
2078 COP0_EPC
= (cia
- 4); /* reference the branch instruction */
2088 if ((cause
== TLBLoad
|| cause
== TLBStore
) && refill
== TLB_REFILL
)
2089 vector_offset
= 0x000;
2090 else if (cause
== Interrupt
)
2091 vector_offset
= 0x200;
2093 vector_offset
= 0x180;
2095 if (SR
& status_BEV
)
2096 PC
= (signed)0xBFC00200 + vector_offset
;
2098 PC
= (signed)0x80000000 + vector_offset
;
2101 /* Now, handle the exception. */
2108 va_start(ap
, cause
);
2109 level
= va_arg(ap
,unsigned int);
2111 /* Interrupts arrive during event processing, no need to restart.
2112 Hardware interrupts on sky target are INT1 and INT2. */
2114 CAUSE
|= cause_IP3
; /* bit 11 */
2115 else if ( level
== 2 )
2116 CAUSE
|= cause_IP7
; /* bit 15 */
2118 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2119 "FATAL: Unexpected interrupt level %d\n", level
);
2124 ASSERT(0); /* NMIReset is a level 0 exception. */
2129 case InstructionFetch
:
2131 /* The following is so that the simulator will continue from the
2132 exception address on breakpoint operations. */
2134 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2135 sim_stopped
, SIM_SIGBUS
);
2138 case ReservedInstruction
:
2139 case CoProcessorUnusable
:
2141 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2142 sim_stopped
, SIM_SIGILL
);
2145 case IntegerOverflow
:
2148 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2149 sim_stopped
, SIM_SIGFPE
);
2153 sim_engine_halt (SD
, CPU
, NULL
, PC
, sim_stopped
, SIM_SIGTRAP
);
2156 case TLBModification
:
2161 sim_engine_restart (SD
, CPU
, NULL
, PC
);
2166 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2167 sim_stopped
, SIM_SIGTRAP
);
2170 default : /* Unknown internal exception */
2172 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
,
2173 sim_stopped
, SIM_SIGABRT
);
2181 #else /* TARGET_SKY */
2182 /* end-sanitize-sky */
2184 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2185 /* Signal an exception condition. This will result in an exception
2186 that aborts the instruction. The instruction operation pseudocode
2187 will never see a return from this function call. */
2190 signal_exception (SIM_DESC sd
,
2198 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
2201 /* Ensure that any active atomic read/modify/write operation will fail: */
2204 /* Save registers before interrupt dispatching */
2205 #ifdef SIM_CPU_EXCEPTION_TRIGGER
2206 SIM_CPU_EXCEPTION_TRIGGER(sd
, cpu
, cia
);
2209 switch (exception
) {
2211 case DebugBreakPoint
:
2212 if (! (Debug
& Debug_DM
))
2218 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
2219 DEPC
= cia
- 4; /* reference the branch instruction */
2223 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
2227 Debug
|= Debug_DM
; /* in debugging mode */
2228 Debug
|= Debug_DBp
; /* raising a DBp exception */
2230 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
2234 case ReservedInstruction
:
2237 unsigned int instruction
;
2238 va_start(ap
,exception
);
2239 instruction
= va_arg(ap
,unsigned int);
2241 /* Provide simple monitor support using ReservedInstruction
2242 exceptions. The following code simulates the fixed vector
2243 entry points into the IDT monitor by causing a simulator
2244 trap, performing the monitor operation, and returning to
2245 the address held in the $ra register (standard PCS return
2246 address). This means we only need to pre-load the vector
2247 space with suitable instruction values. For systems were
2248 actual trap instructions are used, we would not need to
2249 perform this magic. */
2250 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
2252 sim_monitor (SD
, CPU
, cia
, ((instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
) );
2253 /* NOTE: This assumes that a branch-and-link style
2254 instruction was used to enter the vector (which is the
2255 case with the current IDT monitor). */
2256 sim_engine_restart (SD
, CPU
, NULL
, RA
);
2258 /* Look for the mips16 entry and exit instructions, and
2259 simulate a handler for them. */
2260 else if ((cia
& 1) != 0
2261 && (instruction
& 0xf81f) == 0xe809
2262 && (instruction
& 0x0c0) != 0x0c0)
2264 mips16_entry (SD
, CPU
, cia
, instruction
);
2265 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
2267 /* else fall through to normal exception processing */
2268 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
2272 /* Store exception code into current exception id variable (used
2275 /* TODO: If not simulating exceptions then stop the simulator
2276 execution. At the moment we always stop the simulation. */
2278 #ifdef SUBTARGET_R3900
2279 /* update interrupt-related registers */
2281 /* insert exception code in bits 6:2 */
2282 CAUSE
= LSMASKED32(CAUSE
, 31, 7) | LSINSERTED32(exception
, 6, 2);
2283 /* shift IE/KU history bits left */
2284 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 3, 0), 5, 2);
2286 if (STATE
& simDELAYSLOT
)
2288 STATE
&= ~simDELAYSLOT
;
2290 EPC
= (cia
- 4); /* reference the branch instruction */
2295 if (SR
& status_BEV
)
2296 PC
= (signed)0xBFC00000 + 0x180;
2298 PC
= (signed)0x80000000 + 0x080;
2300 /* See figure 5-17 for an outline of the code below */
2301 if (! (SR
& status_EXL
))
2303 CAUSE
= (exception
<< 2);
2304 if (STATE
& simDELAYSLOT
)
2306 STATE
&= ~simDELAYSLOT
;
2308 EPC
= (cia
- 4); /* reference the branch instruction */
2312 /* FIXME: TLB et.al. */
2313 /* vector = 0x180; */
2317 CAUSE
= (exception
<< 2);
2318 /* vector = 0x180; */
2321 /* Store exception code into current exception id variable (used
2324 if (SR
& status_BEV
)
2325 PC
= (signed)0xBFC00200 + 0x180;
2327 PC
= (signed)0x80000000 + 0x180;
2330 switch ((CAUSE
>> 2) & 0x1F)
2333 /* Interrupts arrive during event processing, no need to
2339 #ifdef SUBTARGET_3900
2340 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
2341 PC
= (signed)0xBFC00000;
2342 #endif SUBTARGET_3900
2345 case TLBModification
:
2350 case InstructionFetch
:
2352 /* The following is so that the simulator will continue from the
2353 exception handler address. */
2354 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2355 sim_stopped
, SIM_SIGBUS
);
2357 case ReservedInstruction
:
2358 case CoProcessorUnusable
:
2360 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2361 sim_stopped
, SIM_SIGILL
);
2363 case IntegerOverflow
:
2365 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2366 sim_stopped
, SIM_SIGFPE
);
2369 sim_engine_halt (SD
, CPU
, NULL
, PC
, sim_stopped
, SIM_SIGTRAP
);
2374 sim_engine_restart (SD
, CPU
, NULL
, PC
);
2379 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2380 sim_stopped
, SIM_SIGTRAP
);
2382 default : /* Unknown internal exception */
2384 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2385 sim_stopped
, SIM_SIGABRT
);
2389 case SimulatorFault
:
2393 va_start(ap
,exception
);
2394 msg
= va_arg(ap
,char *);
2396 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2397 "FATAL: Simulator error \"%s\"\n",msg
);
2404 /* start-sanitize-sky */
2405 #endif /* ! TARGET_SKY */
2406 /* end-sanitize-sky */
2409 #if defined(WARN_RESULT)
2410 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
2411 /* This function indicates that the result of the operation is
2412 undefined. However, this should not affect the instruction
2413 stream. All that is meant to happen is that the destination
2414 register is set to an undefined result. To keep the simulator
2415 simple, we just don't bother updating the destination register, so
2416 the overall result will be undefined. If desired we can stop the
2417 simulator by raising a pseudo-exception. */
2418 #define UndefinedResult() undefined_result (sd,cia)
2420 undefined_result(sd
,cia
)
2424 sim_io_eprintf(sd
,"UndefinedResult: PC = 0x%s\n",pr_addr(cia
));
2425 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
2430 #endif /* WARN_RESULT */
2432 /*-- FPU support routines ---------------------------------------------------*/
2434 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
2435 formats conform to ANSI/IEEE Std 754-1985. */
2436 /* SINGLE precision floating:
2437 * seeeeeeeefffffffffffffffffffffff
2439 * e = 8bits = exponent
2440 * f = 23bits = fraction
2442 /* SINGLE precision fixed:
2443 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2445 * i = 31bits = integer
2447 /* DOUBLE precision floating:
2448 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
2450 * e = 11bits = exponent
2451 * f = 52bits = fraction
2453 /* DOUBLE precision fixed:
2454 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
2456 * i = 63bits = integer
2459 /* Extract sign-bit: */
2460 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
2461 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
2462 /* Extract biased exponent: */
2463 #define FP_S_be(v) (((v) >> 23) & 0xFF)
2464 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
2465 /* Extract unbiased Exponent: */
2466 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
2467 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
2468 /* Extract complete fraction field: */
2469 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
2470 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
2471 /* Extract numbered fraction bit: */
2472 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
2473 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
2475 /* Explicit QNaN values used when value required: */
2476 #define FPQNaN_SINGLE (0x7FBFFFFF)
2477 #define FPQNaN_WORD (0x7FFFFFFF)
2478 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
2479 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
2481 /* Explicit Infinity values used when required: */
2482 #define FPINF_SINGLE (0x7F800000)
2483 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
2485 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
2486 #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>" : (((v) == fmt_uninterpreted_32) ? "<uninterpreted_32>" : (((v) == fmt_uninterpreted_64) ? "<uninterpreted_64>" : "<format error>"))))))))
2489 value_fpr (SIM_DESC sd
,
2498 /* Treat unused register values, as fixed-point 64bit values: */
2499 if ((fmt
== fmt_uninterpreted
) || (fmt
== fmt_unknown
))
2501 /* If request to read data as "uninterpreted", then use the current
2503 fmt
= FPR_STATE
[fpr
];
2508 /* For values not yet accessed, set to the desired format: */
2509 if (FPR_STATE
[fpr
] == fmt_uninterpreted
) {
2510 FPR_STATE
[fpr
] = fmt
;
2512 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr
,DOFMT(fmt
));
2515 if (fmt
!= FPR_STATE
[fpr
]) {
2516 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
));
2517 FPR_STATE
[fpr
] = fmt_unknown
;
2520 if (FPR_STATE
[fpr
] == fmt_unknown
) {
2521 /* Set QNaN value: */
2524 value
= FPQNaN_SINGLE
;
2528 value
= FPQNaN_DOUBLE
;
2532 value
= FPQNaN_WORD
;
2536 value
= FPQNaN_LONG
;
2543 } else if (SizeFGR() == 64) {
2547 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2550 case fmt_uninterpreted
:
2564 value
= (FGR
[fpr
] & 0xFFFFFFFF);
2567 case fmt_uninterpreted
:
2570 if ((fpr
& 1) == 0) { /* even registers only */
2572 printf("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
2573 fpr
+1, pr_uword64( (uword64
) FGR
[fpr
+1] ),
2574 fpr
, pr_uword64( (uword64
) FGR
[fpr
] ));
2576 value
= ((((uword64
)FGR
[fpr
+1]) << 32) | (FGR
[fpr
] & 0xFFFFFFFF));
2578 SignalException(ReservedInstruction
,0);
2589 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2592 printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr
,DOFMT(fmt
),pr_uword64(value
),pr_addr(cia
),SizeFGR());
2599 store_fpr (SIM_DESC sd
,
2609 printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d,\n",fpr
,DOFMT(fmt
),pr_uword64(value
),pr_addr(cia
),SizeFGR());
2612 if (SizeFGR() == 64) {
2614 case fmt_uninterpreted_32
:
2615 fmt
= fmt_uninterpreted
;
2618 FGR
[fpr
] = (((uword64
)0xDEADC0DE << 32) | (value
& 0xFFFFFFFF));
2619 FPR_STATE
[fpr
] = fmt
;
2622 case fmt_uninterpreted_64
:
2623 fmt
= fmt_uninterpreted
;
2624 case fmt_uninterpreted
:
2628 FPR_STATE
[fpr
] = fmt
;
2632 FPR_STATE
[fpr
] = fmt_unknown
;
2638 case fmt_uninterpreted_32
:
2639 fmt
= fmt_uninterpreted
;
2642 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2643 FPR_STATE
[fpr
] = fmt
;
2646 case fmt_uninterpreted_64
:
2647 fmt
= fmt_uninterpreted
;
2648 case fmt_uninterpreted
:
2651 if ((fpr
& 1) == 0) { /* even register number only */
2652 FGR
[fpr
+1] = (value
>> 32);
2653 FGR
[fpr
] = (value
& 0xFFFFFFFF);
2654 FPR_STATE
[fpr
+ 1] = fmt
;
2655 FPR_STATE
[fpr
] = fmt
;
2657 FPR_STATE
[fpr
] = fmt_unknown
;
2658 FPR_STATE
[fpr
+ 1] = fmt_unknown
;
2659 SignalException(ReservedInstruction
,0);
2664 FPR_STATE
[fpr
] = fmt_unknown
;
2669 #if defined(WARN_RESULT)
2672 #endif /* WARN_RESULT */
2675 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2678 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr
,pr_uword64(FGR
[fpr
]),DOFMT(fmt
));
2695 sim_fpu_32to (&wop
, op
);
2696 boolean
= sim_fpu_is_nan (&wop
);
2703 sim_fpu_64to (&wop
, op
);
2704 boolean
= sim_fpu_is_nan (&wop
);
2708 fprintf (stderr
, "Bad switch\n");
2713 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2727 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2734 sim_fpu_32to (&wop
, op
);
2735 boolean
= sim_fpu_is_infinity (&wop
);
2741 sim_fpu_64to (&wop
, op
);
2742 boolean
= sim_fpu_is_infinity (&wop
);
2746 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt
));
2751 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean
,pr_addr(op
),DOFMT(fmt
));
2765 /* Argument checking already performed by the FPCOMPARE code */
2768 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2771 /* The format type should already have been checked: */
2777 sim_fpu_32to (&wop1
, op1
);
2778 sim_fpu_32to (&wop2
, op2
);
2779 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2786 sim_fpu_64to (&wop1
, op1
);
2787 sim_fpu_64to (&wop2
, op2
);
2788 boolean
= sim_fpu_is_lt (&wop1
, &wop2
);
2792 fprintf (stderr
, "Bad switch\n");
2797 printf("DBG: Less: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2811 /* Argument checking already performed by the FPCOMPARE code */
2814 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2817 /* The format type should already have been checked: */
2823 sim_fpu_32to (&wop1
, op1
);
2824 sim_fpu_32to (&wop2
, op2
);
2825 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2832 sim_fpu_64to (&wop1
, op1
);
2833 sim_fpu_64to (&wop2
, op2
);
2834 boolean
= sim_fpu_is_eq (&wop1
, &wop2
);
2838 fprintf (stderr
, "Bad switch\n");
2843 printf("DBG: Equal: returning %d (format = %s)\n",boolean
,DOFMT(fmt
));
2850 AbsoluteValue(op
,fmt
)
2857 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2860 /* The format type should already have been checked: */
2866 sim_fpu_32to (&wop
, op
);
2867 sim_fpu_abs (&wop
, &wop
);
2868 sim_fpu_to32 (&ans
, &wop
);
2876 sim_fpu_64to (&wop
, op
);
2877 sim_fpu_abs (&wop
, &wop
);
2878 sim_fpu_to64 (&ans
, &wop
);
2883 fprintf (stderr
, "Bad switch\n");
2898 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
2901 /* The format type should already have been checked: */
2907 sim_fpu_32to (&wop
, op
);
2908 sim_fpu_neg (&wop
, &wop
);
2909 sim_fpu_to32 (&ans
, &wop
);
2917 sim_fpu_64to (&wop
, op
);
2918 sim_fpu_neg (&wop
, &wop
);
2919 sim_fpu_to64 (&ans
, &wop
);
2924 fprintf (stderr
, "Bad switch\n");
2940 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2943 /* The registers must specify FPRs valid for operands of type
2944 "fmt". If they are not valid, the result is undefined. */
2946 /* The format type should already have been checked: */
2954 sim_fpu_32to (&wop1
, op1
);
2955 sim_fpu_32to (&wop2
, op2
);
2956 sim_fpu_add (&ans
, &wop1
, &wop2
);
2957 sim_fpu_to32 (&res
, &ans
);
2967 sim_fpu_64to (&wop1
, op1
);
2968 sim_fpu_64to (&wop2
, op2
);
2969 sim_fpu_add (&ans
, &wop1
, &wop2
);
2970 sim_fpu_to64 (&res
, &ans
);
2975 fprintf (stderr
, "Bad switch\n");
2980 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
2995 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
2998 /* The registers must specify FPRs valid for operands of type
2999 "fmt". If they are not valid, the result is undefined. */
3001 /* The format type should already have been checked: */
3009 sim_fpu_32to (&wop1
, op1
);
3010 sim_fpu_32to (&wop2
, op2
);
3011 sim_fpu_sub (&ans
, &wop1
, &wop2
);
3012 sim_fpu_to32 (&res
, &ans
);
3022 sim_fpu_64to (&wop1
, op1
);
3023 sim_fpu_64to (&wop2
, op2
);
3024 sim_fpu_sub (&ans
, &wop1
, &wop2
);
3025 sim_fpu_to64 (&res
, &ans
);
3030 fprintf (stderr
, "Bad switch\n");
3035 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3042 Multiply(op1
,op2
,fmt
)
3050 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3053 /* The registers must specify FPRs valid for operands of type
3054 "fmt". If they are not valid, the result is undefined. */
3056 /* The format type should already have been checked: */
3064 sim_fpu_32to (&wop1
, op1
);
3065 sim_fpu_32to (&wop2
, op2
);
3066 sim_fpu_mul (&ans
, &wop1
, &wop2
);
3067 sim_fpu_to32 (&res
, &ans
);
3077 sim_fpu_64to (&wop1
, op1
);
3078 sim_fpu_64to (&wop2
, op2
);
3079 sim_fpu_mul (&ans
, &wop1
, &wop2
);
3080 sim_fpu_to64 (&res
, &ans
);
3085 fprintf (stderr
, "Bad switch\n");
3090 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3105 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3108 /* The registers must specify FPRs valid for operands of type
3109 "fmt". If they are not valid, the result is undefined. */
3111 /* The format type should already have been checked: */
3119 sim_fpu_32to (&wop1
, op1
);
3120 sim_fpu_32to (&wop2
, op2
);
3121 sim_fpu_div (&ans
, &wop1
, &wop2
);
3122 sim_fpu_to32 (&res
, &ans
);
3132 sim_fpu_64to (&wop1
, op1
);
3133 sim_fpu_64to (&wop2
, op2
);
3134 sim_fpu_div (&ans
, &wop1
, &wop2
);
3135 sim_fpu_to64 (&res
, &ans
);
3140 fprintf (stderr
, "Bad switch\n");
3145 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3159 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
3162 /* The registers must specify FPRs valid for operands of type
3163 "fmt". If they are not valid, the result is undefined. */
3165 /* The format type should already have been checked: */
3172 sim_fpu_32to (&wop
, op
);
3173 sim_fpu_inv (&ans
, &wop
);
3174 sim_fpu_to32 (&res
, &ans
);
3183 sim_fpu_64to (&wop
, op
);
3184 sim_fpu_inv (&ans
, &wop
);
3185 sim_fpu_to64 (&res
, &ans
);
3190 fprintf (stderr
, "Bad switch\n");
3195 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3209 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt
),pr_addr(op
));
3212 /* The registers must specify FPRs valid for operands of type
3213 "fmt". If they are not valid, the result is undefined. */
3215 /* The format type should already have been checked: */
3222 sim_fpu_32to (&wop
, op
);
3223 sim_fpu_sqrt (&ans
, &wop
);
3224 sim_fpu_to32 (&res
, &ans
);
3233 sim_fpu_64to (&wop
, op
);
3234 sim_fpu_sqrt (&ans
, &wop
);
3235 sim_fpu_to64 (&res
, &ans
);
3240 fprintf (stderr
, "Bad switch\n");
3245 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3261 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3264 /* The registers must specify FPRs valid for operands of type
3265 "fmt". If they are not valid, the result is undefined. */
3267 /* The format type should already have been checked: */
3274 sim_fpu_32to (&wop1
, op1
);
3275 sim_fpu_32to (&wop2
, op2
);
3276 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3283 sim_fpu_64to (&wop1
, op1
);
3284 sim_fpu_64to (&wop2
, op2
);
3285 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3289 fprintf (stderr
, "Bad switch\n");
3295 case SIM_FPU_IS_SNAN
:
3296 case SIM_FPU_IS_QNAN
:
3298 case SIM_FPU_IS_NINF
:
3299 case SIM_FPU_IS_NNUMBER
:
3300 case SIM_FPU_IS_NDENORM
:
3301 case SIM_FPU_IS_NZERO
:
3302 result
= op2
; /* op1 - op2 < 0 */
3303 case SIM_FPU_IS_PINF
:
3304 case SIM_FPU_IS_PNUMBER
:
3305 case SIM_FPU_IS_PDENORM
:
3306 case SIM_FPU_IS_PZERO
:
3307 result
= op1
; /* op1 - op2 > 0 */
3309 fprintf (stderr
, "Bad switch\n");
3314 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3331 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt
),pr_addr(op1
),pr_addr(op2
));
3334 /* The registers must specify FPRs valid for operands of type
3335 "fmt". If they are not valid, the result is undefined. */
3337 /* The format type should already have been checked: */
3344 sim_fpu_32to (&wop1
, op1
);
3345 sim_fpu_32to (&wop2
, op2
);
3346 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3353 sim_fpu_64to (&wop1
, op1
);
3354 sim_fpu_64to (&wop2
, op2
);
3355 cmp
= sim_fpu_cmp (&wop1
, &wop2
);
3359 fprintf (stderr
, "Bad switch\n");
3365 case SIM_FPU_IS_SNAN
:
3366 case SIM_FPU_IS_QNAN
:
3368 case SIM_FPU_IS_NINF
:
3369 case SIM_FPU_IS_NNUMBER
:
3370 case SIM_FPU_IS_NDENORM
:
3371 case SIM_FPU_IS_NZERO
:
3372 result
= op1
; /* op1 - op2 < 0 */
3373 case SIM_FPU_IS_PINF
:
3374 case SIM_FPU_IS_PNUMBER
:
3375 case SIM_FPU_IS_PDENORM
:
3376 case SIM_FPU_IS_PZERO
:
3377 result
= op2
; /* op1 - op2 > 0 */
3379 fprintf (stderr
, "Bad switch\n");
3384 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result
),DOFMT(fmt
));
3392 convert (SIM_DESC sd
,
3401 sim_fpu_round round
;
3402 unsigned32 result32
;
3403 unsigned64 result64
;
3406 #if 0 /* FIXME: doesn't compile */
3407 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
));
3414 /* Round result to nearest representable value. When two
3415 representable values are equally near, round to the value
3416 that has a least significant bit of zero (i.e. is even). */
3417 round
= sim_fpu_round_near
;
3420 /* Round result to the value closest to, and not greater in
3421 magnitude than, the result. */
3422 round
= sim_fpu_round_zero
;
3425 /* Round result to the value closest to, and not less than,
3427 round
= sim_fpu_round_up
;
3431 /* Round result to the value closest to, and not greater than,
3433 round
= sim_fpu_round_down
;
3437 fprintf (stderr
, "Bad switch\n");
3441 /* Convert the input to sim_fpu internal format */
3445 sim_fpu_64to (&wop
, op
);
3448 sim_fpu_32to (&wop
, op
);
3451 sim_fpu_i32to (&wop
, op
, round
);
3454 sim_fpu_i64to (&wop
, op
, round
);
3457 fprintf (stderr
, "Bad switch\n");
3461 /* Convert sim_fpu format into the output */
3462 /* The value WOP is converted to the destination format, rounding
3463 using mode RM. When the destination is a fixed-point format, then
3464 a source value of Infinity, NaN or one which would round to an
3465 integer outside the fixed point range then an IEEE Invalid
3466 Operation condition is raised. */
3470 sim_fpu_round_32 (&wop
, round
, 0);
3471 sim_fpu_to32 (&result32
, &wop
);
3472 result64
= result32
;
3475 sim_fpu_round_64 (&wop
, round
, 0);
3476 sim_fpu_to64 (&result64
, &wop
);
3479 sim_fpu_to32i (&result32
, &wop
, round
);
3480 result64
= result32
;
3483 sim_fpu_to64i (&result64
, &wop
, round
);
3487 fprintf (stderr
, "Bad switch\n");
3492 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64
),DOFMT(to
));
3499 /*-- co-processor support routines ------------------------------------------*/
3502 CoProcPresent(unsigned int coproc_number
)
3504 /* Return TRUE if simulator provides a model for the given co-processor number */
3509 cop_lw (SIM_DESC sd
,
3514 unsigned int memword
)
3519 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3522 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
3524 StoreFPR(coproc_reg
,fmt_word
,(uword64
)memword
);
3525 FPR_STATE
[coproc_reg
] = fmt_uninterpreted
;
3530 #if 0 /* this should be controlled by a configuration option */
3531 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
));
3540 cop_ld (SIM_DESC sd
,
3549 printf("DBG: COP_LD: coproc_num = %d, coproc_reg = %d, value = 0x%s : PC = 0x%s\n", coproc_num
, coproc_reg
, pr_uword64(memword
), pr_addr(cia
) );
3552 switch (coproc_num
) {
3554 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3556 StoreFPR(coproc_reg
,fmt_uninterpreted
,memword
);
3561 #if 0 /* this message should be controlled by a configuration option */
3562 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
));
3571 /* start-sanitize-sky */
3572 #if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
3574 cop_lq (SIM_DESC sd
,
3579 unsigned128 memword
)
3590 /* one word at a time, argh! */
3594 value
= H2T_4(*A4_16(& memword
, 3-i
));
3595 write_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3601 sim_io_printf(sd
,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3602 coproc_num
,coproc_reg
,pr_addr(cia
));
3608 #endif /* TARGET_SKY */
3609 /* end-sanitize-sky */
3613 cop_sw (SIM_DESC sd
,
3619 unsigned int value
= 0;
3624 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3627 hold
= FPR_STATE
[coproc_reg
];
3628 FPR_STATE
[coproc_reg
] = fmt_word
;
3629 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted
);
3630 FPR_STATE
[coproc_reg
] = hold
;
3635 #if 0 /* should be controlled by configuration option */
3636 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3645 cop_sd (SIM_DESC sd
,
3655 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
3657 value
= ValueFPR(coproc_reg
,fmt_uninterpreted
);
3662 #if 0 /* should be controlled by configuration option */
3663 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
3672 /* start-sanitize-sky */
3673 #if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
3675 cop_sq (SIM_DESC sd
,
3681 unsigned128 value
= U16_8(0, 0);
3692 /* one word at a time, argh! */
3696 read_vu_vec_reg(&(vu0_device
.regs
), coproc_reg
, i
, & value
);
3697 *A4_16(& xyzw
, 3-i
) = T2H_4(value
);
3704 sim_io_printf(sd
,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3705 coproc_num
,coproc_reg
,pr_addr(cia
));
3711 #endif /* TARGET_SKY */
3712 /* end-sanitize-sky */
3716 decode_coproc (SIM_DESC sd
,
3719 unsigned int instruction
)
3721 int coprocnum
= ((instruction
>> 26) & 3);
3725 case 0: /* standard CPU control and cache registers */
3727 int code
= ((instruction
>> 21) & 0x1F);
3728 int rt
= ((instruction
>> 16) & 0x1F);
3729 int rd
= ((instruction
>> 11) & 0x1F);
3730 int tail
= instruction
& 0x3ff;
3731 /* R4000 Users Manual (second edition) lists the following CP0
3733 CODE><-RT><RD-><--TAIL--->
3734 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3735 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3736 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3737 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3738 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3739 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3740 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3741 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3742 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3743 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3745 if (((code
== 0x00) || (code
== 0x04)) && tail
== 0)
3747 /* M[TF]C0 - 32 bit word */
3749 switch (rd
) /* NOTEs: Standard CP0 registers */
3751 /* 0 = Index R4000 VR4100 VR4300 */
3752 /* 1 = Random R4000 VR4100 VR4300 */
3753 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3754 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3755 /* 4 = Context R4000 VR4100 VR4300 */
3756 /* 5 = PageMask R4000 VR4100 VR4300 */
3757 /* 6 = Wired R4000 VR4100 VR4300 */
3758 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3759 /* 9 = Count R4000 VR4100 VR4300 */
3760 /* 10 = EntryHi R4000 VR4100 VR4300 */
3761 /* 11 = Compare R4000 VR4100 VR4300 */
3762 /* 12 = SR R4000 VR4100 VR4300 */
3763 #ifdef SUBTARGET_R3900
3765 /* 3 = Config R3900 */
3767 /* 7 = Cache R3900 */
3769 /* 15 = PRID R3900 */
3775 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3777 GPR
[rt
] = COP0_BADVADDR
;
3779 COP0_BADVADDR
= GPR
[rt
];
3782 #endif /* SUBTARGET_R3900 */
3789 /* 13 = Cause R4000 VR4100 VR4300 */
3796 /* 14 = EPC R4000 VR4100 VR4300 */
3799 GPR
[rt
] = (signed_word
) (signed_address
) EPC
;
3803 /* 15 = PRId R4000 VR4100 VR4300 */
3804 #ifdef SUBTARGET_R3900
3813 /* 16 = Config R4000 VR4100 VR4300 */
3816 GPR
[rt
] = C0_CONFIG
;
3818 C0_CONFIG
= GPR
[rt
];
3821 #ifdef SUBTARGET_R3900
3830 /* 17 = LLAddr R4000 VR4100 VR4300 */
3832 /* 18 = WatchLo R4000 VR4100 VR4300 */
3833 /* 19 = WatchHi R4000 VR4100 VR4300 */
3834 /* 20 = XContext R4000 VR4100 VR4300 */
3835 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3836 /* 27 = CacheErr R4000 VR4100 */
3837 /* 28 = TagLo R4000 VR4100 VR4300 */
3838 /* 29 = TagHi R4000 VR4100 VR4300 */
3839 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3840 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
3841 /* CPR[0,rd] = GPR[rt]; */
3844 GPR
[rt
] = (signed_word
) (signed32
) COP0_GPR
[rd
];
3846 COP0_GPR
[rd
] = GPR
[rt
];
3849 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt
,rd
, (unsigned)cia
);
3851 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt
,rd
, (unsigned)cia
);
3855 /* start-sanitize-r5900 */
3856 else if (((code
== 0x00) || (code
== 0x04)) && rd
== 0x18 && tail
> 0 && tail
< NR_COP0_BP
)
3857 /* Break-point registers */
3860 GPR
[rt
] = (signed_word
) (signed32
) COP0_BP
[tail
];
3862 COP0_BP
[tail
] = GPR
[rt
];
3864 else if (((code
== 0x00) || (code
== 0x04)) && rd
== 0x19 && tail
> 0 && tail
< NR_COP0_P
)
3865 /* Performance registers */
3868 GPR
[rt
] = (signed_word
) (signed32
) COP0_P
[tail
];
3870 COP0_P
[tail
] = GPR
[rt
];
3872 /* end-sanitize-r5900 */
3873 else if (code
== 0x10 && (tail
& 0x3f) == 0x18)
3876 if (SR
& status_ERL
)
3878 /* Oops, not yet available */
3879 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
3889 else if (code
== 0x10 && (tail
& 0x3f) == 0x10)
3892 #ifdef SUBTARGET_R3900
3893 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
3895 /* shift IE/KU history bits right */
3896 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 5, 2), 3, 0);
3898 /* TODO: CACHE register */
3899 #endif /* SUBTARGET_R3900 */
3901 else if (code
== 0x10 && (tail
& 0x3f) == 0x1F)
3909 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
3910 /* TODO: When executing an ERET or RFE instruction we should
3911 clear LLBIT, to ensure that any out-standing atomic
3912 read/modify/write sequence fails. */
3916 case 2: /* co-processor 2 */
3920 /* start-sanitize-sky */
3921 #if defined(TARGET_SKY) && !defined(TARGET_SKY_B)
3922 /* On the R5900, this refers to a "VU" vector co-processor. */
3924 int i_25_21
= (instruction
>> 21) & 0x1f;
3925 int i_20_16
= (instruction
>> 16) & 0x1f;
3926 int i_20_6
= (instruction
>> 6) & 0x7fff;
3927 int i_15_11
= (instruction
>> 11) & 0x1f;
3928 int i_15_0
= instruction
& 0xffff;
3929 int i_10_1
= (instruction
>> 1) & 0x3ff;
3930 int i_10_0
= instruction
& 0x7ff;
3931 int i_10_6
= (instruction
>> 6) & 0x1f;
3932 int i_5_0
= instruction
& 0x03f;
3933 int interlock
= instruction
& 0x01;
3937 /* test COP2 usability */
3938 if(! (SR
& status_CU2
))
3940 SignalException(CoProcessorUnusable
,instruction
);
3944 /* BC2T/BC2F/BC2TL/BC2FL handled in r5900.igen */
3946 else if((i_25_21
== 0x02 && i_10_1
== 0x000) || /* CFC2 */
3947 (i_25_21
== 0x01)) /* QMFC2 */
3952 /* interlock checking */
3953 /* POLICY: never busy in macro mode */
3954 while(vu0_busy() && interlock
)
3957 /* perform VU register access */
3958 if(i_25_21
== 0x01) /* QMFC2 */
3962 /* one word at a time, argh! */
3963 read_vu_vec_reg(&(vu0_device
.regs
), id
, 3, &w
);
3964 read_vu_vec_reg(&(vu0_device
.regs
), id
, 2, &z
);
3965 read_vu_vec_reg(&(vu0_device
.regs
), id
, 1, &y
);
3966 read_vu_vec_reg(&(vu0_device
.regs
), id
, 0, &x
);
3968 GPR
[rt
] = U8_4(T2H_4(y
), T2H_4(x
));
3969 GPR1
[rt
] = U8_4(T2H_4(w
), T2H_4(z
));
3973 GPR
[rt
] = vu0_read_cop2_register(id
);
3976 else if((i_25_21
== 0x06 && i_10_1
== 0x000) || /* CTC2 */
3977 (i_25_21
== 0x05)) /* QMTC2 */
3982 /* interlock checking: wait until M or E bits set */
3983 /* POLICY: never busy in macro mode */
3984 while(vu0_busy() && interlock
)
3986 if(vu0_micro_interlock_released())
3988 vu0_micro_interlock_clear();
3995 /* perform VU register access */
3996 if(i_25_21
== 0x05) /* QMTC2 */
4000 x
= H2T_4(V4_8(GPR
[rt
], 1));
4001 y
= H2T_4(V4_8(GPR
[rt
], 0));
4002 z
= H2T_4(V4_8(GPR1
[rt
], 1));
4003 w
= H2T_4(V4_8(GPR1
[rt
], 0));
4005 /* one word at a time, argh! */
4006 write_vu_vec_reg(&(vu0_device
.regs
), id
, 3, & w
);
4007 write_vu_vec_reg(&(vu0_device
.regs
), id
, 2, & z
);
4008 write_vu_vec_reg(&(vu0_device
.regs
), id
, 1, & y
);
4009 write_vu_vec_reg(&(vu0_device
.regs
), id
, 0, & x
);
4013 vu0_write_cop2_register(id
, GPR
[rt
]);
4016 else if(i_10_0
== 0x3bf) /* VWAITQ */
4021 else if(i_5_0
== 0x38) /* VCALLMS */
4023 unsigned_4 data
= H2T_2(i_20_6
);
4028 /* write to reserved CIA register to get VU0 moving */
4029 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
4033 else if(i_5_0
== 0x39) /* VCALLMSR */
4040 read_vu_special_reg(& vu0_device
, VU_REG_CMSAR0
, & data
);
4041 /* write to reserved CIA register to get VU0 moving */
4042 write_vu_special_reg(& vu0_device
, VU_REG_CIA
, & data
);
4046 /* handle all remaining UPPER VU instructions in one block */
4047 else if((i_5_0
< 0x30) || /* VADDx .. VMINI */
4048 (i_5_0
>= 0x3c && i_10_6
< 0x0c)) /* VADDAx .. VNOP */
4050 unsigned_4 vu_upper
, vu_lower
;
4052 0x00000000 | /* bits 31 .. 25 */
4053 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
4054 vu_lower
= 0x8000033c; /* NOP */
4056 /* POLICY: never busy in macro mode */
4060 vu0_macro_issue(vu_upper
, vu_lower
);
4062 /* POLICY: wait for completion of macro-instruction */
4066 /* handle all remaining LOWER VU instructions in one block */
4067 else if((i_5_0
>= 0x30 && i_5_0
<= 0x35) || /* VIADD .. VIOR */
4068 (i_5_0
>= 0x3c && i_10_6
>= 0x0c)) /* VMOVE .. VRXOR */
4069 { /* N.B.: VWAITQ already covered by prior case */
4070 unsigned_4 vu_upper
, vu_lower
;
4071 vu_upper
= 0x000002ff; /* NOP/NOP */
4073 0x80000000 | /* bits 31 .. 25 */
4074 (instruction
& 0x01ffffff); /* bits 24 .. 0 */
4076 /* POLICY: never busy in macro mode */
4080 vu0_macro_issue(vu_upper
, vu_lower
);
4082 /* POLICY: wait for completion of macro-instruction */
4086 /* ... no other COP2 instructions ... */
4089 SignalException(ReservedInstruction
, instruction
);
4093 #endif /* TARGET_SKY */
4094 /* end-sanitize-sky */
4098 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
4099 instruction
,pr_addr(cia
));
4104 case 1: /* should not occur (FPU co-processor) */
4105 case 3: /* should not occur (FPU co-processor) */
4106 SignalException(ReservedInstruction
,instruction
);
4114 /* This code copied from gdb's utils.c. Would like to share this code,
4115 but don't know of a common place where both could get to it. */
4117 /* Temporary storage using circular buffer */
4123 static char buf
[NUMCELLS
][CELLSIZE
];
4125 if (++cell
>=NUMCELLS
) cell
=0;
4129 /* Print routines to handle variable size regs, etc */
4131 /* Eliminate warning from compiler on 32-bit systems */
4132 static int thirty_two
= 32;
4138 char *paddr_str
=get_cell();
4139 switch (sizeof(addr
))
4142 sprintf(paddr_str
,"%08lx%08lx",
4143 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
4146 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
4149 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
4152 sprintf(paddr_str
,"%x",addr
);
4161 char *paddr_str
=get_cell();
4162 sprintf(paddr_str
,"%08lx%08lx",
4163 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
4169 mips_core_signal (SIM_DESC sd
,
4175 transfer_type transfer
,
4176 sim_core_signals sig
)
4178 const char *copy
= (transfer
== read_transfer
? "read" : "write");
4179 address_word ip
= CIA_ADDR (cia
);
4183 case sim_core_unmapped_signal
:
4184 sim_io_eprintf (sd
, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
4186 (unsigned long) addr
, (unsigned long) ip
);
4187 COP0_BADVADDR
= addr
;
4188 SignalExceptionDataReference();
4191 case sim_core_unaligned_signal
:
4192 sim_io_eprintf (sd
, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
4194 (unsigned long) addr
, (unsigned long) ip
);
4195 COP0_BADVADDR
= addr
;
4196 if(transfer
== read_transfer
)
4197 SignalExceptionAddressLoad();
4199 SignalExceptionAddressStore();
4203 sim_engine_abort (sd
, cpu
, cia
,
4204 "mips_core_signal - internal error - bad switch");
4210 mips_cpu_exception_trigger(SIM_DESC sd
, sim_cpu
* cpu
, address_word cia
)
4212 ASSERT(cpu
!= NULL
);
4214 if(cpu
->exc_suspended
> 0)
4215 sim_io_eprintf(sd
, "Warning, nested exception triggered (%d)\n", cpu
->exc_suspended
);
4218 memcpy(cpu
->exc_trigger_registers
, cpu
->registers
, sizeof(cpu
->exc_trigger_registers
));
4219 cpu
->exc_suspended
= 0;
4223 mips_cpu_exception_suspend(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
4225 ASSERT(cpu
!= NULL
);
4227 if(cpu
->exc_suspended
> 0)
4228 sim_io_eprintf(sd
, "Warning, nested exception signal (%d then %d)\n",
4229 cpu
->exc_suspended
, exception
);
4231 memcpy(cpu
->exc_suspend_registers
, cpu
->registers
, sizeof(cpu
->exc_suspend_registers
));
4232 memcpy(cpu
->registers
, cpu
->exc_trigger_registers
, sizeof(cpu
->registers
));
4233 cpu
->exc_suspended
= exception
;
4237 mips_cpu_exception_resume(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
4239 ASSERT(cpu
!= NULL
);
4241 if(exception
== 0 && cpu
->exc_suspended
> 0)
4243 /* warn not for breakpoints */
4244 if(cpu
->exc_suspended
!= sim_signal_to_host(sd
, SIM_SIGTRAP
))
4245 sim_io_eprintf(sd
, "Warning, resuming but ignoring pending exception signal (%d)\n",
4246 cpu
->exc_suspended
);
4248 else if(exception
!= 0 && cpu
->exc_suspended
> 0)
4250 if(exception
!= cpu
->exc_suspended
)
4251 sim_io_eprintf(sd
, "Warning, resuming with unmatching exception signal (%d vs %d)\n",
4252 cpu
->exc_suspended
, exception
);
4254 memcpy(cpu
->registers
, cpu
->exc_suspend_registers
, sizeof(cpu
->registers
));
4256 else if(exception
!= 0 && cpu
->exc_suspended
== 0)
4258 sim_io_eprintf(sd
, "Warning, ignoring spontanous exception signal (%d)\n", exception
);
4260 cpu
->exc_suspended
= 0;
4264 /*---------------------------------------------------------------------------*/
4265 /*> EOF interp.c <*/