* Support for sky hardware interrupts. The sky-dma cannot trigger
[deliverable/binutils-gdb.git] / sim / mips / interp.c
1 /*> interp.c <*/
2 /* Simulator for the MIPS architecture.
3
4 This file is part of the MIPS sim
5
6 THIS SOFTWARE IS NOT COPYRIGHTED
7
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.
11
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.
15
16 $Revision$
17 $Date$
18
19 NOTEs:
20
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
24 code on the hardware.
25
26 */
27
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 */
32 #define TRACE (1)
33 #endif
34
35 #include "bfd.h"
36 #include "sim-main.h"
37 #include "sim-utils.h"
38 #include "sim-options.h"
39 #include "sim-assert.h"
40 #include "sim-hw.h"
41
42 /* start-sanitize-sky */
43 #ifdef TARGET_SKY
44 #include "sky-vu.h"
45 #include "sky-vpe.h"
46 #include "sky-libvpe.h"
47 #include "sky-pke.h"
48 #include "idecode.h"
49 #include "support.h"
50 #include "sky-gdb.h"
51 #undef SD
52 #endif
53 /* end-sanitize-sky */
54
55 #include "config.h"
56
57 #include <stdio.h>
58 #include <stdarg.h>
59 #include <ansidecl.h>
60 #include <ctype.h>
61 #include <limits.h>
62 #include <math.h>
63 #ifdef HAVE_STDLIB_H
64 #include <stdlib.h>
65 #endif
66 #ifdef HAVE_STRING_H
67 #include <string.h>
68 #else
69 #ifdef HAVE_STRINGS_H
70 #include <strings.h>
71 #endif
72 #endif
73
74 #include "getopt.h"
75 #include "libiberty.h"
76 #include "bfd.h"
77 #include "callback.h" /* GDB simulator callback interface */
78 #include "remote-sim.h" /* GDB simulator interface */
79
80 #include "sysdep.h"
81
82 #ifndef PARAMS
83 #define PARAMS(x)
84 #endif
85
86 char* pr_addr PARAMS ((SIM_ADDR addr));
87 char* pr_uword64 PARAMS ((uword64 addr));
88
89
90 /* Get the simulator engine description, without including the code: */
91 #if !(WITH_IGEN)
92 #define SIM_MANIFESTS
93 #include "oengine.c"
94 #undef SIM_MANIFESTS
95 #endif
96
97 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
98 #define CPU cpu
99 #define SD sd
100
101
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. */
105
106 #define RSVD_INSTRUCTION (0x00000005)
107 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
108
109 #define RSVD_INSTRUCTION_ARG_SHIFT 6
110 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
111
112
113 /* Bits in the Debug register */
114 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
115 #define Debug_DM 0x40000000 /* Debug Mode */
116 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
117
118 /*---------------------------------------------------------------------------*/
119 /*-- GDB simulator interface ------------------------------------------------*/
120 /*---------------------------------------------------------------------------*/
121
122 static void ColdReset PARAMS((SIM_DESC sd));
123
124 /*---------------------------------------------------------------------------*/
125
126
127
128 #define DELAYSLOT() {\
129 if (STATE & simDELAYSLOT)\
130 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
131 STATE |= simDELAYSLOT;\
132 }
133
134 #define JALDELAYSLOT() {\
135 DELAYSLOT ();\
136 STATE |= simJALDELAYSLOT;\
137 }
138
139 #define NULLIFY() {\
140 STATE &= ~simDELAYSLOT;\
141 STATE |= simSKIPNEXT;\
142 }
143
144 #define CANCELDELAYSLOT() {\
145 DSSTATE = 0;\
146 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
147 }
148
149 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
150 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
151
152 #define K0BASE (0x80000000)
153 #define K0SIZE (0x20000000)
154 #define K1BASE (0xA0000000)
155 #define K1SIZE (0x20000000)
156 #define MONITOR_BASE (0xBFC00000)
157 #define MONITOR_SIZE (1 << 11)
158 #define MEM_SIZE (2 << 20)
159
160 /* start-sanitize-sky */
161 #ifdef TARGET_SKY
162 #undef MEM_SIZE
163 #define MEM_SIZE (16 << 20) /* 16 MB */
164 #endif
165 /* end-sanitize-sky */
166
167 #if defined(TRACE)
168 static char *tracefile = "trace.din"; /* default filename for trace log */
169 FILE *tracefh = NULL;
170 static void open_trace PARAMS((SIM_DESC sd));
171 #endif /* TRACE */
172
173 /* simulation target board. NULL=canonical */
174 static char* board = NULL;
175
176
177 static DECLARE_OPTION_HANDLER (mips_option_handler);
178
179 enum {
180 OPTION_DINERO_TRACE = OPTION_START,
181 OPTION_DINERO_FILE,
182 OPTION_BOARD
183 };
184
185
186 static SIM_RC
187 mips_option_handler (sd, cpu, opt, arg, is_command)
188 SIM_DESC sd;
189 sim_cpu *cpu;
190 int opt;
191 char *arg;
192 int is_command;
193 {
194 int cpu_nr;
195 switch (opt)
196 {
197 case OPTION_DINERO_TRACE: /* ??? */
198 #if defined(TRACE)
199 /* Eventually the simTRACE flag could be treated as a toggle, to
200 allow external control of the program points being traced
201 (i.e. only from main onwards, excluding the run-time setup,
202 etc.). */
203 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
204 {
205 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
206 if (arg == NULL)
207 STATE |= simTRACE;
208 else if (strcmp (arg, "yes") == 0)
209 STATE |= simTRACE;
210 else if (strcmp (arg, "no") == 0)
211 STATE &= ~simTRACE;
212 else if (strcmp (arg, "on") == 0)
213 STATE |= simTRACE;
214 else if (strcmp (arg, "off") == 0)
215 STATE &= ~simTRACE;
216 else
217 {
218 fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
219 return SIM_RC_FAIL;
220 }
221 }
222 return SIM_RC_OK;
223 #else /* !TRACE */
224 fprintf(stderr,"\
225 Simulator constructed without dinero tracing support (for performance).\n\
226 Re-compile simulator with \"-DTRACE\" to enable this option.\n");
227 return SIM_RC_FAIL;
228 #endif /* !TRACE */
229
230 case OPTION_DINERO_FILE:
231 #if defined(TRACE)
232 if (optarg != NULL) {
233 char *tmp;
234 tmp = (char *)malloc(strlen(optarg) + 1);
235 if (tmp == NULL)
236 {
237 sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
238 return SIM_RC_FAIL;
239 }
240 else {
241 strcpy(tmp,optarg);
242 tracefile = tmp;
243 sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
244 }
245 }
246 #endif /* TRACE */
247 return SIM_RC_OK;
248
249 case OPTION_BOARD:
250 {
251 if (arg)
252 {
253 board = zalloc(strlen(arg) + 1);
254 strcpy(board, arg);
255 }
256 return SIM_RC_OK;
257 }
258 }
259
260 return SIM_RC_OK;
261 }
262
263
264 static const OPTION mips_options[] =
265 {
266 { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
267 '\0', "on|off", "Enable dinero tracing",
268 mips_option_handler },
269 { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
270 '\0', "FILE", "Write dinero trace to FILE",
271 mips_option_handler },
272 { {"board", required_argument, NULL, OPTION_BOARD},
273 '\0', "none" /* rely on compile-time string concatenation for other options */
274
275 /* start-sanitize-tx3904 */
276 #define BOARD_JMR3904 "jmr3904"
277 "|" BOARD_JMR3904
278 #define BOARD_JMR3904_PAL "jmr3904pal"
279 "|" BOARD_JMR3904_PAL
280 #define BOARD_JMR3904_DEBUG "jmr3904debug"
281 "|" BOARD_JMR3904_DEBUG
282 /* end-sanitize-tx3904 */
283
284 , "Customize simulation for a particular board.", mips_option_handler },
285
286 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
287 };
288
289
290 int interrupt_pending;
291
292 void
293 interrupt_event (SIM_DESC sd, void *data)
294 {
295 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
296 address_word cia = CIA_GET (cpu);
297 if (SR & status_IE)
298 {
299 interrupt_pending = 0;
300 SignalExceptionInterrupt ();
301 }
302 else if (!interrupt_pending)
303 sim_events_schedule (sd, 1, interrupt_event, data);
304 }
305
306
307 /*---------------------------------------------------------------------------*/
308 /*-- Device registration hook -----------------------------------------------*/
309 /*---------------------------------------------------------------------------*/
310 static void device_init(SIM_DESC sd) {
311 #ifdef DEVICE_INIT
312 extern void register_devices(SIM_DESC);
313 register_devices(sd);
314 #endif
315 }
316
317 /*---------------------------------------------------------------------------*/
318 /*-- GDB simulator interface ------------------------------------------------*/
319 /*---------------------------------------------------------------------------*/
320
321 SIM_DESC
322 sim_open (kind, cb, abfd, argv)
323 SIM_OPEN_KIND kind;
324 host_callback *cb;
325 struct _bfd *abfd;
326 char **argv;
327 {
328 SIM_DESC sd = sim_state_alloc (kind, cb);
329 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
330
331 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
332
333
334 /* FIXME: watchpoints code shouldn't need this */
335 STATE_WATCHPOINTS (sd)->pc = &(PC);
336 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
337 STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
338
339 STATE = 0;
340
341 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
342 return 0;
343 sim_add_option_table (sd, NULL, mips_options);
344
345 /* start-sanitize-sky */
346 #ifdef TARGET_SKY
347 sky_command_options (sd);
348 #endif
349 /* end-sanitize-sky */
350
351 /* getopt will print the error message so we just have to exit if this fails.
352 FIXME: Hmmm... in the case of gdb we need getopt to call
353 print_filtered. */
354 if (sim_parse_args (sd, argv) != SIM_RC_OK)
355 {
356 /* Uninstall the modules to avoid memory leaks,
357 file descriptor leaks, etc. */
358 sim_module_uninstall (sd);
359 return 0;
360 }
361
362 /* handle board-specific memory maps */
363 if (board == NULL)
364 {
365 /* Allocate core managed memory */
366
367 /* start-sanitize-sky */
368 #ifndef TARGET_SKY
369 /* end-sanitize-sky */
370 /* the monitor */
371 sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE, MONITOR_SIZE);
372 /* For compatibility with the old code - under this (at level one)
373 are the kernel spaces K0 & K1. Both of these map to a single
374 smaller sub region */
375 sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
376 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
377 K1BASE, K0SIZE,
378 MEM_SIZE, /* actual size */
379 K0BASE);
380 /* start-sanitize-sky */
381 #else
382 /* the monitor */
383 sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE - K1BASE, MONITOR_SIZE);
384 sim_do_command (sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
385 /* 16M @ 0x0. Aliases at 0x80000000 and 0xA0000000 are handled by
386 address_translation() */
387 sim_do_commandf (sd, "memory size 0x%lx", MEM_SIZE);
388 #endif
389 /* end-sanitize-sky */
390
391 device_init(sd);
392 }
393
394 /* start-sanitize-tx3904 */
395 #if (WITH_HW)
396 if (board != NULL
397 && (strcmp(board, BOARD_JMR3904) == 0 ||
398 strcmp(board, BOARD_JMR3904_PAL) == 0 ||
399 strcmp(board, BOARD_JMR3904_DEBUG) == 0))
400 {
401 /* match VIRTUAL memory layout of JMR-TX3904 board */
402
403 /* --- memory --- */
404
405 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
406 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
407 0x9FC00000,
408 4 * 1024 * 1024, /* 4 MB */
409 0xBFC00000);
410
411 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
412 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
413 0x80000000,
414 4 * 1024 * 1024, /* 4 MB */
415 0xA0000000);
416
417 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
418 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
419 0x88000000,
420 32 * 1024 * 1024, /* 32 MB */
421 0xA8000000);
422
423 /* --- simulated devices --- */
424 sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
425 sim_hw_parse (sd, "/tx3904cpu");
426 sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
427 sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
428 sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
429
430 /* -- device connections --- */
431 sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
432 sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
433 sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
434 sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
435
436 /* add PAL timer & I/O module */
437 if(! strcmp(board, BOARD_JMR3904_PAL))
438 {
439 /* the device */
440 sim_hw_parse (sd, "/pal@0xffff0000");
441 sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
442
443 /* wire up interrupt ports to irc */
444 sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
445 sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
446 sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
447 }
448
449 if(! strcmp(board, BOARD_JMR3904_DEBUG))
450 {
451 /* -- DEBUG: glue interrupt generators --- */
452 sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
453 sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
454 sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
455 sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
456 sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
457 sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
458 sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
459 sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
460 sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
461 sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
462 sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
463 sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
464 sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
465 sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
466 sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
467 sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
468 sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
469 sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
470 sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
471 }
472
473 device_init(sd);
474 }
475 #endif
476 /* end-sanitize-tx3904 */
477
478
479 /* check for/establish the a reference program image */
480 if (sim_analyze_program (sd,
481 (STATE_PROG_ARGV (sd) != NULL
482 ? *STATE_PROG_ARGV (sd)
483 : NULL),
484 abfd) != SIM_RC_OK)
485 {
486 sim_module_uninstall (sd);
487 return 0;
488 }
489
490 /* Configure/verify the target byte order and other runtime
491 configuration options */
492 if (sim_config (sd) != SIM_RC_OK)
493 {
494 sim_module_uninstall (sd);
495 return 0;
496 }
497
498 if (sim_post_argv_init (sd) != SIM_RC_OK)
499 {
500 /* Uninstall the modules to avoid memory leaks,
501 file descriptor leaks, etc. */
502 sim_module_uninstall (sd);
503 return 0;
504 }
505
506 /* verify assumptions the simulator made about the host type system.
507 This macro does not return if there is a problem */
508 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
509 SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
510
511 /* This is NASTY, in that we are assuming the size of specific
512 registers: */
513 {
514 int rn;
515 for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
516 {
517 if (rn < 32)
518 cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
519 else if ((rn >= FGRIDX) && (rn < (FGRIDX + NR_FGR)))
520 cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
521 else if ((rn >= 33) && (rn <= 37))
522 cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
523 else if ((rn == SRIDX)
524 || (rn == FCR0IDX)
525 || (rn == FCR31IDX)
526 || ((rn >= 72) && (rn <= 89)))
527 cpu->register_widths[rn] = 32;
528 else
529 cpu->register_widths[rn] = 0;
530 }
531 /* start-sanitize-r5900 */
532
533 /* set the 5900 "upper" registers to 64 bits */
534 for( rn = LAST_EMBED_REGNUM+1; rn < NUM_REGS; rn++)
535 cpu->register_widths[rn] = 64;
536 /* end-sanitize-r5900 */
537
538 /* start-sanitize-sky */
539 #ifdef TARGET_SKY
540 /* Now the VU registers */
541 for( rn = 0; rn < NUM_VU_INTEGER_REGS; rn++ ) {
542 cpu->register_widths[rn + NUM_R5900_REGS] = 16;
543 cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 16;
544 }
545
546 for( rn = NUM_VU_INTEGER_REGS; rn < NUM_VU_REGS; rn++ ) {
547 cpu->register_widths[rn + NUM_R5900_REGS] = 32;
548 cpu->register_widths[rn + NUM_R5900_REGS + NUM_VU_REGS] = 32;
549 }
550
551 /* Finally the VIF registers */
552 for( rn = 2*NUM_VU_REGS; rn < 2*NUM_VU_REGS + 2*NUM_VIF_REGS; rn++ )
553 cpu->register_widths[rn + NUM_R5900_REGS] = 32;
554
555 cpu->cur_device = 0;
556 #endif
557 /* end-sanitize-sky */
558 }
559
560 #if defined(TRACE)
561 if (STATE & simTRACE)
562 open_trace(sd);
563 #endif /* TRACE */
564
565 /* Write an abort sequence into the TRAP (common) exception vector
566 addresses. This is to catch code executing a TRAP (et.al.)
567 instruction without installing a trap handler. */
568 {
569 unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
570 HALT_INSTRUCTION /* BREAK */ };
571 H2T (halt[0]);
572 H2T (halt[1]);
573 sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
574 sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
575 }
576
577
578 /* Write the monitor trap address handlers into the monitor (eeprom)
579 address space. This can only be done once the target endianness
580 has been determined. */
581 {
582 unsigned loop;
583 /* Entry into the IDT monitor is via fixed address vectors, and
584 not using machine instructions. To avoid clashing with use of
585 the MIPS TRAP system, we place our own (simulator specific)
586 "undefined" instructions into the relevant vector slots. */
587 for (loop = 0; (loop < MONITOR_SIZE); loop += 4)
588 {
589 address_word vaddr = (MONITOR_BASE + loop);
590 unsigned32 insn = (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT));
591 H2T (insn);
592 sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
593 }
594 /* The PMON monitor uses the same address space, but rather than
595 branching into it the address of a routine is loaded. We can
596 cheat for the moment, and direct the PMON routine to IDT style
597 instructions within the monitor space. This relies on the IDT
598 monitor not using the locations from 0xBFC00500 onwards as its
599 entry points.*/
600 for (loop = 0; (loop < 24); loop++)
601 {
602 address_word vaddr = (MONITOR_BASE + 0x500 + (loop * 4));
603 unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
604 switch (loop)
605 {
606 case 0: /* read */
607 value = 7;
608 break;
609 case 1: /* write */
610 value = 8;
611 break;
612 case 2: /* open */
613 value = 6;
614 break;
615 case 3: /* close */
616 value = 10;
617 break;
618 case 5: /* printf */
619 value = ((0x500 - 16) / 8); /* not an IDT reason code */
620 break;
621 case 8: /* cliexit */
622 value = 17;
623 break;
624 case 11: /* flush_cache */
625 value = 28;
626 break;
627 }
628 /* FIXME - should monitor_base be SIM_ADDR?? */
629 value = ((unsigned int)MONITOR_BASE + (value * 8));
630 H2T (value);
631 sim_write (sd, vaddr, (char *)&value, sizeof (value));
632
633 /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
634 vaddr -= 0x300;
635 sim_write (sd, vaddr, (char *)&value, sizeof (value));
636 }
637 }
638
639 return sd;
640 }
641
642 #if defined(TRACE)
643 static void
644 open_trace(sd)
645 SIM_DESC sd;
646 {
647 tracefh = fopen(tracefile,"wb+");
648 if (tracefh == NULL)
649 {
650 sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
651 tracefh = stderr;
652 }
653 }
654 #endif /* TRACE */
655
656 void
657 sim_close (sd, quitting)
658 SIM_DESC sd;
659 int quitting;
660 {
661 #ifdef DEBUG
662 printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
663 #endif
664
665 /* "quitting" is non-zero if we cannot hang on errors */
666
667 /* Ensure that any resources allocated through the callback
668 mechanism are released: */
669 sim_io_shutdown (sd);
670
671 #if defined(TRACE)
672 if (tracefh != NULL && tracefh != stderr)
673 fclose(tracefh);
674 tracefh = NULL;
675 #endif /* TRACE */
676
677 /* FIXME - free SD */
678
679 return;
680 }
681
682
683 int
684 sim_write (sd,addr,buffer,size)
685 SIM_DESC sd;
686 SIM_ADDR addr;
687 unsigned char *buffer;
688 int size;
689 {
690 int index;
691 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
692
693 /* Return the number of bytes written, or zero if error. */
694 #ifdef DEBUG
695 sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
696 #endif
697
698 /* We use raw read and write routines, since we do not want to count
699 the GDB memory accesses in our statistics gathering. */
700
701 for (index = 0; index < size; index++)
702 {
703 address_word vaddr = (address_word)addr + index;
704 address_word paddr;
705 int cca;
706 if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
707 break;
708 if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
709 break;
710 }
711
712 return(index);
713 }
714
715 int
716 sim_read (sd,addr,buffer,size)
717 SIM_DESC sd;
718 SIM_ADDR addr;
719 unsigned char *buffer;
720 int size;
721 {
722 int index;
723 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
724
725 /* Return the number of bytes read, or zero if error. */
726 #ifdef DEBUG
727 sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
728 #endif /* DEBUG */
729
730 for (index = 0; (index < size); index++)
731 {
732 address_word vaddr = (address_word)addr + index;
733 address_word paddr;
734 int cca;
735 if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
736 break;
737 if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
738 break;
739 }
740
741 return(index);
742 }
743
744 int
745 sim_store_register (sd,rn,memory,length)
746 SIM_DESC sd;
747 int rn;
748 unsigned char *memory;
749 int length;
750 {
751 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
752 /* NOTE: gdb (the client) stores registers in target byte order
753 while the simulator uses host byte order */
754 #ifdef DEBUG
755 sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
756 #endif /* DEBUG */
757
758 /* Unfortunately this suffers from the same problem as the register
759 numbering one. We need to know what the width of each logical
760 register number is for the architecture being simulated. */
761
762 if (cpu->register_widths[rn] == 0)
763 {
764 sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
765 return 0;
766 }
767
768 /* start-sanitize-r5900 */
769 if (rn >= 90 && rn < 90 + 32)
770 {
771 GPR1[rn - 90] = T2H_8 (*(unsigned64*)memory);
772 return 8;
773 }
774 switch (rn)
775 {
776 case REGISTER_SA:
777 SA = T2H_8(*(unsigned64*)memory);
778 return 8;
779 case 122: /* FIXME */
780 LO1 = T2H_8(*(unsigned64*)memory);
781 return 8;
782 case 123: /* FIXME */
783 HI1 = T2H_8(*(unsigned64*)memory);
784 return 8;
785 }
786 /* end-sanitize-r5900 */
787
788 /* start-sanitize-sky */
789 #ifdef TARGET_SKY
790 if (rn >= NUM_R5900_REGS)
791 {
792 rn = rn - NUM_R5900_REGS;
793
794 if( rn < NUM_VU_REGS )
795 {
796 if (rn < NUM_VU_INTEGER_REGS)
797 return write_vu_int_reg (&(vu0_device.regs), rn, memory);
798 else if (rn >= FIRST_VEC_REG)
799 {
800 rn -= FIRST_VEC_REG;
801 return write_vu_vec_reg (&(vu0_device.regs), rn>>2, rn&3,
802 memory);
803 }
804 else switch (rn - NUM_VU_INTEGER_REGS)
805 {
806 case 0:
807 return write_vu_special_reg (&vu0_device, VU_REG_CIA,
808 memory);
809 case 1:
810 return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MR,
811 memory);
812 case 2: /* VU0 has no P register */
813 return 4;
814 case 3:
815 return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MI,
816 memory);
817 case 4:
818 return write_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ,
819 memory);
820 default:
821 return write_vu_acc_reg (&(vu0_device.regs),
822 rn - (NUM_VU_INTEGER_REGS + 5),
823 memory);
824 }
825 }
826
827 rn = rn - NUM_VU_REGS;
828
829 if (rn < NUM_VU_REGS)
830 {
831 if (rn < NUM_VU_INTEGER_REGS)
832 return write_vu_int_reg (&(vu1_device.regs), rn, memory);
833 else if (rn >= FIRST_VEC_REG)
834 {
835 rn -= FIRST_VEC_REG;
836 return write_vu_vec_reg (&(vu1_device.regs),
837 rn >> 2, rn & 3, memory);
838 }
839 else switch (rn - NUM_VU_INTEGER_REGS)
840 {
841 case 0:
842 return write_vu_special_reg (&vu1_device, VU_REG_CIA,
843 memory);
844 case 1:
845 return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MR,
846 memory);
847 case 2:
848 return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MP,
849 memory);
850 case 3:
851 return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MI,
852 memory);
853 case 4:
854 return write_vu_misc_reg (&(vu1_device.regs), VU_REG_MQ,
855 memory);
856 default:
857 return write_vu_acc_reg (&(vu1_device.regs),
858 rn - (NUM_VU_INTEGER_REGS + 5),
859 memory);
860 }
861 }
862
863 rn -= NUM_VU_REGS; /* VIF0 registers are next */
864
865 if (rn < NUM_VIF_REGS)
866 {
867 if (rn < NUM_VIF_REGS-1)
868 return write_pke_reg (&pke0_device, rn, memory);
869 else
870 {
871 sim_io_eprintf( sd, "Can't write vif0_pc (store ignored)\n" );
872 return 0;
873 }
874 }
875
876 rn -= NUM_VIF_REGS; /* VIF1 registers are last */
877
878 if (rn < NUM_VIF_REGS)
879 {
880 if (rn < NUM_VIF_REGS-1)
881 return write_pke_reg (&pke1_device, rn, memory);
882 else
883 {
884 sim_io_eprintf( sd, "Can't write vif1_pc (store ignored)\n" );
885 return 0;
886 }
887 }
888
889 sim_io_eprintf( sd, "Invalid VU register (register store ignored)\n" );
890 return 0;
891 }
892 #endif
893 /* end-sanitize-sky */
894
895 if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
896 {
897 if (cpu->register_widths[rn] == 32)
898 {
899 cpu->fgr[rn - FGRIDX] = T2H_4 (*(unsigned32*)memory);
900 return 4;
901 }
902 else
903 {
904 cpu->fgr[rn - FGRIDX] = T2H_8 (*(unsigned64*)memory);
905 return 8;
906 }
907 }
908
909 if (cpu->register_widths[rn] == 32)
910 {
911 cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
912 return 4;
913 }
914 else
915 {
916 cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
917 return 8;
918 }
919
920 return 0;
921 }
922
923 int
924 sim_fetch_register (sd,rn,memory,length)
925 SIM_DESC sd;
926 int rn;
927 unsigned char *memory;
928 int length;
929 {
930 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
931 /* NOTE: gdb (the client) stores registers in target byte order
932 while the simulator uses host byte order */
933 #ifdef DEBUG
934 sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
935 #endif /* DEBUG */
936
937 if (cpu->register_widths[rn] == 0)
938 {
939 sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
940 return 0;
941 }
942
943 /* start-sanitize-r5900 */
944 if (rn >= 90 && rn < 90 + 32)
945 {
946 *((unsigned64*)memory) = H2T_8 (GPR1[rn - 90]);
947 return 8;
948 }
949 switch (rn)
950 {
951 case REGISTER_SA:
952 *((unsigned64*)memory) = H2T_8(SA);
953 return 8;
954 case 122: /* FIXME */
955 *((unsigned64*)memory) = H2T_8(LO1);
956 return 8;
957 case 123: /* FIXME */
958 *((unsigned64*)memory) = H2T_8(HI1);
959 return 8;
960 }
961 /* end-sanitize-r5900 */
962
963 /* start-sanitize-sky */
964 #ifdef TARGET_SKY
965 if (rn >= NUM_R5900_REGS)
966 {
967 rn = rn - NUM_R5900_REGS;
968
969 if (rn < NUM_VU_REGS)
970 {
971 if (rn < NUM_VU_INTEGER_REGS)
972 return read_vu_int_reg (&(vu0_device.regs), rn, memory);
973 else if (rn >= FIRST_VEC_REG)
974 {
975 rn -= FIRST_VEC_REG;
976 return read_vu_vec_reg (&(vu0_device.regs), rn>>2, rn & 3,
977 memory);
978 }
979 else switch (rn - NUM_VU_INTEGER_REGS)
980 {
981 case 0:
982 return read_vu_special_reg(&vu0_device, VU_REG_CIA, memory);
983 case 1:
984 return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MR,
985 memory);
986 case 2: /* VU0 has no P register */
987 *((int *) memory) = 0;
988 return 4;
989 case 3:
990 return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MI,
991 memory);
992 case 4:
993 return read_vu_misc_reg (&(vu0_device.regs), VU_REG_MQ,
994 memory);
995 default:
996 return read_vu_acc_reg (&(vu0_device.regs),
997 rn - (NUM_VU_INTEGER_REGS + 5),
998 memory);
999 }
1000 }
1001
1002 rn -= NUM_VU_REGS; /* VU1 registers are next */
1003
1004 if (rn < NUM_VU_REGS)
1005 {
1006 if (rn < NUM_VU_INTEGER_REGS)
1007 return read_vu_int_reg (&(vu1_device.regs), rn, memory);
1008 else if (rn >= FIRST_VEC_REG)
1009 {
1010 rn -= FIRST_VEC_REG;
1011 return read_vu_vec_reg (&(vu1_device.regs),
1012 rn >> 2, rn & 3, memory);
1013 }
1014 else switch (rn - NUM_VU_INTEGER_REGS)
1015 {
1016 case 0:
1017 return read_vu_special_reg(&vu1_device, VU_REG_CIA, memory);
1018 case 1:
1019 return read_vu_misc_reg (&(vu1_device.regs),
1020 VU_REG_MR, memory);
1021 case 2:
1022 return read_vu_misc_reg (&(vu1_device.regs),
1023 VU_REG_MP, memory);
1024 case 3:
1025 return read_vu_misc_reg (&(vu1_device.regs),
1026 VU_REG_MI, memory);
1027 case 4:
1028 return read_vu_misc_reg (&(vu1_device.regs),
1029 VU_REG_MQ, memory);
1030 default:
1031 return read_vu_acc_reg (&(vu1_device.regs),
1032 rn - (NUM_VU_INTEGER_REGS + 5),
1033 memory);
1034 }
1035 }
1036
1037 rn -= NUM_VU_REGS; /* VIF0 registers are next */
1038
1039 if (rn < NUM_VIF_REGS)
1040 {
1041 if (rn < NUM_VIF_REGS-1)
1042 return read_pke_reg (&pke0_device, rn, memory);
1043 else
1044 return read_pke_pc (&pke0_device, memory);
1045 }
1046
1047 rn -= NUM_VIF_REGS; /* VIF1 registers are last */
1048
1049 if (rn < NUM_VIF_REGS)
1050 {
1051 if (rn < NUM_VIF_REGS-1)
1052 return read_pke_reg (&pke1_device, rn, memory);
1053 else
1054 return read_pke_pc (&pke1_device, memory);
1055 }
1056
1057 sim_io_eprintf( sd, "Invalid VU register (register fetch ignored)\n" );
1058 }
1059 #endif
1060 /* end-sanitize-sky */
1061
1062 /* Any floating point register */
1063 if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
1064 {
1065 if (cpu->register_widths[rn] == 32)
1066 {
1067 *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGRIDX]);
1068 return 4;
1069 }
1070 else
1071 {
1072 *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGRIDX]);
1073 return 8;
1074 }
1075 }
1076
1077 if (cpu->register_widths[rn] == 32)
1078 {
1079 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
1080 return 4;
1081 }
1082 else
1083 {
1084 *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
1085 return 8;
1086 }
1087
1088 return 0;
1089 }
1090
1091
1092 SIM_RC
1093 sim_create_inferior (sd, abfd, argv,env)
1094 SIM_DESC sd;
1095 struct _bfd *abfd;
1096 char **argv;
1097 char **env;
1098 {
1099
1100 #ifdef DEBUG
1101 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1102 pr_addr(PC));
1103 #endif /* DEBUG */
1104
1105 ColdReset(sd);
1106
1107 if (abfd != NULL)
1108 {
1109 /* override PC value set by ColdReset () */
1110 int cpu_nr;
1111 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1112 {
1113 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1114 CIA_SET (cpu, (unsigned64) bfd_get_start_address (abfd));
1115 }
1116 }
1117
1118 #if 0 /* def DEBUG */
1119 if (argv || env)
1120 {
1121 /* We should really place the argv slot values into the argument
1122 registers, and onto the stack as required. However, this
1123 assumes that we have a stack defined, which is not
1124 necessarily true at the moment. */
1125 char **cptr;
1126 sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
1127 for (cptr = argv; (cptr && *cptr); cptr++)
1128 printf("DBG: arg \"%s\"\n",*cptr);
1129 }
1130 #endif /* DEBUG */
1131
1132 return SIM_RC_OK;
1133 }
1134
1135 void
1136 sim_do_command (sd,cmd)
1137 SIM_DESC sd;
1138 char *cmd;
1139 {
1140 if (sim_args_command (sd, cmd) != SIM_RC_OK)
1141 sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1142 cmd);
1143 }
1144
1145 /*---------------------------------------------------------------------------*/
1146 /*-- Private simulator support interface ------------------------------------*/
1147 /*---------------------------------------------------------------------------*/
1148
1149 /* Read a null terminated string from memory, return in a buffer */
1150 static char *
1151 fetch_str (sd, addr)
1152 SIM_DESC sd;
1153 address_word addr;
1154 {
1155 char *buf;
1156 int nr = 0;
1157 char null;
1158 while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
1159 nr++;
1160 buf = NZALLOC (char, nr + 1);
1161 sim_read (sd, addr, buf, nr);
1162 return buf;
1163 }
1164
1165 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1166 static void
1167 sim_monitor (SIM_DESC sd,
1168 sim_cpu *cpu,
1169 address_word cia,
1170 unsigned int reason)
1171 {
1172 #ifdef DEBUG
1173 printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1174 #endif /* DEBUG */
1175
1176 /* The IDT monitor actually allows two instructions per vector
1177 slot. However, the simulator currently causes a trap on each
1178 individual instruction. We cheat, and lose the bottom bit. */
1179 reason >>= 1;
1180
1181 /* The following callback functions are available, however the
1182 monitor we are simulating does not make use of them: get_errno,
1183 isatty, lseek, rename, system, time and unlink */
1184 switch (reason)
1185 {
1186
1187 case 6: /* int open(char *path,int flags) */
1188 {
1189 char *path = fetch_str (sd, A0);
1190 V0 = sim_io_open (sd, path, (int)A1);
1191 zfree (path);
1192 break;
1193 }
1194
1195 case 7: /* int read(int file,char *ptr,int len) */
1196 {
1197 int fd = A0;
1198 int nr = A2;
1199 char *buf = zalloc (nr);
1200 V0 = sim_io_read (sd, fd, buf, nr);
1201 sim_write (sd, A1, buf, nr);
1202 zfree (buf);
1203 }
1204 break;
1205
1206 case 8: /* int write(int file,char *ptr,int len) */
1207 {
1208 int fd = A0;
1209 int nr = A2;
1210 char *buf = zalloc (nr);
1211 sim_read (sd, A1, buf, nr);
1212 V0 = sim_io_write (sd, fd, buf, nr);
1213 zfree (buf);
1214 break;
1215 }
1216
1217 case 10: /* int close(int file) */
1218 {
1219 V0 = sim_io_close (sd, (int)A0);
1220 break;
1221 }
1222
1223 case 2: /* Densan monitor: char inbyte(int waitflag) */
1224 {
1225 if (A0 == 0) /* waitflag == NOWAIT */
1226 V0 = (unsigned_word)-1;
1227 }
1228 /* Drop through to case 11 */
1229
1230 case 11: /* char inbyte(void) */
1231 {
1232 char tmp;
1233 if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
1234 {
1235 sim_io_error(sd,"Invalid return from character read");
1236 V0 = (unsigned_word)-1;
1237 }
1238 else
1239 V0 = (unsigned_word)tmp;
1240 break;
1241 }
1242
1243 case 3: /* Densan monitor: void co(char chr) */
1244 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1245 {
1246 char tmp = (char)(A0 & 0xFF);
1247 sim_io_write_stdout (sd, &tmp, sizeof(char));
1248 break;
1249 }
1250
1251 case 17: /* void _exit() */
1252 {
1253 sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
1254 sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited,
1255 (unsigned int)(A0 & 0xFFFFFFFF));
1256 break;
1257 }
1258
1259 case 28 : /* PMON flush_cache */
1260 break;
1261
1262 case 55: /* void get_mem_info(unsigned int *ptr) */
1263 /* in: A0 = pointer to three word memory location */
1264 /* out: [A0 + 0] = size */
1265 /* [A0 + 4] = instruction cache size */
1266 /* [A0 + 8] = data cache size */
1267 {
1268 unsigned_4 value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
1269 unsigned_4 zero = 0;
1270 H2T (value);
1271 sim_write (sd, A0 + 0, (char *)&value, 4);
1272 sim_write (sd, A0 + 4, (char *)&zero, 4);
1273 sim_write (sd, A0 + 8, (char *)&zero, 4);
1274 /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
1275 break;
1276 }
1277
1278 case 158 : /* PMON printf */
1279 /* in: A0 = pointer to format string */
1280 /* A1 = optional argument 1 */
1281 /* A2 = optional argument 2 */
1282 /* A3 = optional argument 3 */
1283 /* out: void */
1284 /* The following is based on the PMON printf source */
1285 {
1286 address_word s = A0;
1287 char c;
1288 signed_word *ap = &A1; /* 1st argument */
1289 /* This isn't the quickest way, since we call the host print
1290 routine for every character almost. But it does avoid
1291 having to allocate and manage a temporary string buffer. */
1292 /* TODO: Include check that we only use three arguments (A1,
1293 A2 and A3) */
1294 while (sim_read (sd, s++, &c, 1) && c != '\0')
1295 {
1296 if (c == '%')
1297 {
1298 char tmp[40];
1299 enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
1300 int width = 0, trunc = 0, haddot = 0, longlong = 0;
1301 while (sim_read (sd, s++, &c, 1) && c != '\0')
1302 {
1303 if (strchr ("dobxXulscefg%", c))
1304 break;
1305 else if (c == '-')
1306 fmt = FMT_LJUST;
1307 else if (c == '0')
1308 fmt = FMT_RJUST0;
1309 else if (c == '~')
1310 fmt = FMT_CENTER;
1311 else if (c == '*')
1312 {
1313 if (haddot)
1314 trunc = (int)*ap++;
1315 else
1316 width = (int)*ap++;
1317 }
1318 else if (c >= '1' && c <= '9')
1319 {
1320 address_word t = s;
1321 unsigned int n;
1322 while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
1323 tmp[s - t] = c;
1324 tmp[s - t] = '\0';
1325 n = (unsigned int)strtol(tmp,NULL,10);
1326 if (haddot)
1327 trunc = n;
1328 else
1329 width = n;
1330 s--;
1331 }
1332 else if (c == '.')
1333 haddot = 1;
1334 }
1335 switch (c)
1336 {
1337 case '%':
1338 sim_io_printf (sd, "%%");
1339 break;
1340 case 's':
1341 if ((int)*ap != 0)
1342 {
1343 address_word p = *ap++;
1344 char ch;
1345 while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
1346 sim_io_printf(sd, "%c", ch);
1347 }
1348 else
1349 sim_io_printf(sd,"(null)");
1350 break;
1351 case 'c':
1352 sim_io_printf (sd, "%c", (int)*ap++);
1353 break;
1354 default:
1355 if (c == 'l')
1356 {
1357 sim_read (sd, s++, &c, 1);
1358 if (c == 'l')
1359 {
1360 longlong = 1;
1361 sim_read (sd, s++, &c, 1);
1362 }
1363 }
1364 if (strchr ("dobxXu", c))
1365 {
1366 word64 lv = (word64) *ap++;
1367 if (c == 'b')
1368 sim_io_printf(sd,"<binary not supported>");
1369 else
1370 {
1371 sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
1372 if (longlong)
1373 sim_io_printf(sd, tmp, lv);
1374 else
1375 sim_io_printf(sd, tmp, (int)lv);
1376 }
1377 }
1378 else if (strchr ("eEfgG", c))
1379 {
1380 double dbl = *(double*)(ap++);
1381 sprintf (tmp, "%%%d.%d%c", width, trunc, c);
1382 sim_io_printf (sd, tmp, dbl);
1383 trunc = 0;
1384 }
1385 }
1386 }
1387 else
1388 sim_io_printf(sd, "%c", c);
1389 }
1390 break;
1391 }
1392
1393 default:
1394 sim_io_error (sd, "TODO: sim_monitor(%d) : PC = 0x%s\n",
1395 reason, pr_addr(cia));
1396 break;
1397 }
1398 return;
1399 }
1400
1401 /* Store a word into memory. */
1402
1403 static void
1404 store_word (SIM_DESC sd,
1405 sim_cpu *cpu,
1406 address_word cia,
1407 uword64 vaddr,
1408 signed_word val)
1409 {
1410 address_word paddr;
1411 int uncached;
1412
1413 if ((vaddr & 3) != 0)
1414 SignalExceptionAddressStore ();
1415 else
1416 {
1417 if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1418 isTARGET, isREAL))
1419 {
1420 const uword64 mask = 7;
1421 uword64 memval;
1422 unsigned int byte;
1423
1424 paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1425 byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1426 memval = ((uword64) val) << (8 * byte);
1427 StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
1428 isREAL);
1429 }
1430 }
1431 }
1432
1433 /* Load a word from memory. */
1434
1435 static signed_word
1436 load_word (SIM_DESC sd,
1437 sim_cpu *cpu,
1438 address_word cia,
1439 uword64 vaddr)
1440 {
1441 if ((vaddr & 3) != 0)
1442 SignalExceptionAddressLoad ();
1443 else
1444 {
1445 address_word paddr;
1446 int uncached;
1447
1448 if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
1449 isTARGET, isREAL))
1450 {
1451 const uword64 mask = 0x7;
1452 const unsigned int reverse = ReverseEndian ? 1 : 0;
1453 const unsigned int bigend = BigEndianCPU ? 1 : 0;
1454 uword64 memval;
1455 unsigned int byte;
1456
1457 paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1458 LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
1459 isDATA, isREAL);
1460 byte = (vaddr & mask) ^ (bigend << 2);
1461 return SIGNEXTEND (((memval >> (8 * byte)) & 0xffffffff), 32);
1462 }
1463 }
1464
1465 return 0;
1466 }
1467
1468 /* Simulate the mips16 entry and exit pseudo-instructions. These
1469 would normally be handled by the reserved instruction exception
1470 code, but for ease of simulation we just handle them directly. */
1471
1472 static void
1473 mips16_entry (SIM_DESC sd,
1474 sim_cpu *cpu,
1475 address_word cia,
1476 unsigned int insn)
1477 {
1478 int aregs, sregs, rreg;
1479
1480 #ifdef DEBUG
1481 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1482 #endif /* DEBUG */
1483
1484 aregs = (insn & 0x700) >> 8;
1485 sregs = (insn & 0x0c0) >> 6;
1486 rreg = (insn & 0x020) >> 5;
1487
1488 /* This should be checked by the caller. */
1489 if (sregs == 3)
1490 abort ();
1491
1492 if (aregs < 5)
1493 {
1494 int i;
1495 signed_word tsp;
1496
1497 /* This is the entry pseudo-instruction. */
1498
1499 for (i = 0; i < aregs; i++)
1500 store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
1501
1502 tsp = SP;
1503 SP -= 32;
1504
1505 if (rreg)
1506 {
1507 tsp -= 4;
1508 store_word (SD, CPU, cia, (uword64) tsp, RA);
1509 }
1510
1511 for (i = 0; i < sregs; i++)
1512 {
1513 tsp -= 4;
1514 store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1515 }
1516 }
1517 else
1518 {
1519 int i;
1520 signed_word tsp;
1521
1522 /* This is the exit pseudo-instruction. */
1523
1524 tsp = SP + 32;
1525
1526 if (rreg)
1527 {
1528 tsp -= 4;
1529 RA = load_word (SD, CPU, cia, (uword64) tsp);
1530 }
1531
1532 for (i = 0; i < sregs; i++)
1533 {
1534 tsp -= 4;
1535 GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1536 }
1537
1538 SP += 32;
1539
1540 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1541 {
1542 if (aregs == 5)
1543 {
1544 FGR[0] = WORD64LO (GPR[4]);
1545 FPR_STATE[0] = fmt_uninterpreted;
1546 }
1547 else if (aregs == 6)
1548 {
1549 FGR[0] = WORD64LO (GPR[5]);
1550 FGR[1] = WORD64LO (GPR[4]);
1551 FPR_STATE[0] = fmt_uninterpreted;
1552 FPR_STATE[1] = fmt_uninterpreted;
1553 }
1554 }
1555
1556 PC = RA;
1557 }
1558
1559 }
1560
1561 /*-- trace support ----------------------------------------------------------*/
1562
1563 /* The TRACE support is provided (if required) in the memory accessing
1564 routines. Since we are also providing the architecture specific
1565 features, the architecture simulation code can also deal with
1566 notifying the TRACE world of cache flushes, etc. Similarly we do
1567 not need to provide profiling support in the simulator engine,
1568 since we can sample in the instruction fetch control loop. By
1569 defining the TRACE manifest, we add tracing as a run-time
1570 option. */
1571
1572 #if defined(TRACE)
1573 /* Tracing by default produces "din" format (as required by
1574 dineroIII). Each line of such a trace file *MUST* have a din label
1575 and address field. The rest of the line is ignored, so comments can
1576 be included if desired. The first field is the label which must be
1577 one of the following values:
1578
1579 0 read data
1580 1 write data
1581 2 instruction fetch
1582 3 escape record (treated as unknown access type)
1583 4 escape record (causes cache flush)
1584
1585 The address field is a 32bit (lower-case) hexadecimal address
1586 value. The address should *NOT* be preceded by "0x".
1587
1588 The size of the memory transfer is not important when dealing with
1589 cache lines (as long as no more than a cache line can be
1590 transferred in a single operation :-), however more information
1591 could be given following the dineroIII requirement to allow more
1592 complete memory and cache simulators to provide better
1593 results. i.e. the University of Pisa has a cache simulator that can
1594 also take bus size and speed as (variable) inputs to calculate
1595 complete system performance (a much more useful ability when trying
1596 to construct an end product, rather than a processor). They
1597 currently have an ARM version of their tool called ChARM. */
1598
1599
1600 void
1601 dotrace (SIM_DESC sd,
1602 sim_cpu *cpu,
1603 FILE *tracefh,
1604 int type,
1605 SIM_ADDR address,
1606 int width,
1607 char *comment,...)
1608 {
1609 if (STATE & simTRACE) {
1610 va_list ap;
1611 fprintf(tracefh,"%d %s ; width %d ; ",
1612 type,
1613 pr_addr(address),
1614 width);
1615 va_start(ap,comment);
1616 vfprintf(tracefh,comment,ap);
1617 va_end(ap);
1618 fprintf(tracefh,"\n");
1619 }
1620 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1621 we may be generating 64bit ones, we should put the hi-32bits of the
1622 address into the comment field. */
1623
1624 /* TODO: Provide a buffer for the trace lines. We can then avoid
1625 performing writes until the buffer is filled, or the file is
1626 being closed. */
1627
1628 /* NOTE: We could consider adding a comment field to the "din" file
1629 produced using type 3 markers (unknown access). This would then
1630 allow information about the program that the "din" is for, and
1631 the MIPs world that was being simulated, to be placed into the
1632 trace file. */
1633
1634 return;
1635 }
1636 #endif /* TRACE */
1637
1638 /*---------------------------------------------------------------------------*/
1639 /*-- simulator engine -------------------------------------------------------*/
1640 /*---------------------------------------------------------------------------*/
1641
1642 static void
1643 ColdReset (SIM_DESC sd)
1644 {
1645 int cpu_nr;
1646 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1647 {
1648 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1649 /* RESET: Fixed PC address: */
1650 PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
1651 /* The reset vector address is in the unmapped, uncached memory space. */
1652
1653 SR &= ~(status_SR | status_TS | status_RP);
1654 SR |= (status_ERL | status_BEV);
1655
1656 /* Cheat and allow access to the complete register set immediately */
1657 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
1658 && WITH_TARGET_WORD_BITSIZE == 64)
1659 SR |= status_FR; /* 64bit registers */
1660
1661 /* Ensure that any instructions with pending register updates are
1662 cleared: */
1663 PENDING_INVALIDATE();
1664
1665 /* Initialise the FPU registers to the unknown state */
1666 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1667 {
1668 int rn;
1669 for (rn = 0; (rn < 32); rn++)
1670 FPR_STATE[rn] = fmt_uninterpreted;
1671 }
1672
1673 }
1674 }
1675
1676 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1677 /* Signal an exception condition. This will result in an exception
1678 that aborts the instruction. The instruction operation pseudocode
1679 will never see a return from this function call. */
1680
1681 void
1682 signal_exception (SIM_DESC sd,
1683 sim_cpu *cpu,
1684 address_word cia,
1685 int exception,...)
1686 {
1687 /* int vector; */
1688
1689 #ifdef DEBUG
1690 sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1691 #endif /* DEBUG */
1692
1693 /* Ensure that any active atomic read/modify/write operation will fail: */
1694 LLBIT = 0;
1695
1696 switch (exception) {
1697
1698 case DebugBreakPoint :
1699 if (! (Debug & Debug_DM))
1700 {
1701 if (INDELAYSLOT())
1702 {
1703 CANCELDELAYSLOT();
1704
1705 Debug |= Debug_DBD; /* signaled from within in delay slot */
1706 DEPC = cia - 4; /* reference the branch instruction */
1707 }
1708 else
1709 {
1710 Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1711 DEPC = cia;
1712 }
1713
1714 Debug |= Debug_DM; /* in debugging mode */
1715 Debug |= Debug_DBp; /* raising a DBp exception */
1716 PC = 0xBFC00200;
1717 sim_engine_restart (SD, CPU, NULL, NULL_CIA);
1718 }
1719 break;
1720
1721 case ReservedInstruction :
1722 {
1723 va_list ap;
1724 unsigned int instruction;
1725 va_start(ap,exception);
1726 instruction = va_arg(ap,unsigned int);
1727 va_end(ap);
1728 /* Provide simple monitor support using ReservedInstruction
1729 exceptions. The following code simulates the fixed vector
1730 entry points into the IDT monitor by causing a simulator
1731 trap, performing the monitor operation, and returning to
1732 the address held in the $ra register (standard PCS return
1733 address). This means we only need to pre-load the vector
1734 space with suitable instruction values. For systems were
1735 actual trap instructions are used, we would not need to
1736 perform this magic. */
1737 if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
1738 {
1739 sim_monitor (SD, CPU, cia, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
1740 /* NOTE: This assumes that a branch-and-link style
1741 instruction was used to enter the vector (which is the
1742 case with the current IDT monitor). */
1743 sim_engine_restart (SD, CPU, NULL, RA);
1744 }
1745 /* Look for the mips16 entry and exit instructions, and
1746 simulate a handler for them. */
1747 else if ((cia & 1) != 0
1748 && (instruction & 0xf81f) == 0xe809
1749 && (instruction & 0x0c0) != 0x0c0)
1750 {
1751 mips16_entry (SD, CPU, cia, instruction);
1752 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
1753 }
1754 /* else fall through to normal exception processing */
1755 sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
1756 }
1757
1758 default:
1759 /* Store exception code into current exception id variable (used
1760 by exit code): */
1761
1762 /* TODO: If not simulating exceptions then stop the simulator
1763 execution. At the moment we always stop the simulation. */
1764
1765 #ifdef SUBTARGET_R3900
1766 /* update interrupt-related registers */
1767
1768 /* insert exception code in bits 6:2 */
1769 CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
1770 /* shift IE/KU history bits left */
1771 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
1772
1773 if (STATE & simDELAYSLOT)
1774 {
1775 STATE &= ~simDELAYSLOT;
1776 CAUSE |= cause_BD;
1777 EPC = (cia - 4); /* reference the branch instruction */
1778 }
1779 else
1780 EPC = cia;
1781
1782 if (SR & status_BEV)
1783 PC = (signed)0xBFC00000 + 0x180;
1784 else
1785 PC = (signed)0x80000000 + 0x080;
1786 #else
1787 /* See figure 5-17 for an outline of the code below */
1788 if (! (SR & status_EXL))
1789 {
1790 CAUSE = (exception << 2);
1791 if (STATE & simDELAYSLOT)
1792 {
1793 STATE &= ~simDELAYSLOT;
1794 CAUSE |= cause_BD;
1795 EPC = (cia - 4); /* reference the branch instruction */
1796 }
1797 else
1798 EPC = cia;
1799 /* FIXME: TLB et.al. */
1800 /* vector = 0x180; */
1801 }
1802 else
1803 {
1804 CAUSE = (exception << 2);
1805 /* vector = 0x180; */
1806 }
1807 SR |= status_EXL;
1808 /* Store exception code into current exception id variable (used
1809 by exit code): */
1810
1811 if (SR & status_BEV)
1812 PC = (signed)0xBFC00200 + 0x180;
1813 else
1814 PC = (signed)0x80000000 + 0x180;
1815 #endif
1816
1817 switch ((CAUSE >> 2) & 0x1F)
1818 {
1819 case Interrupt:
1820 /* Interrupts arrive during event processing, no need to
1821 restart */
1822 return;
1823
1824 case NMIReset:
1825 /* Ditto */
1826 #ifdef SUBTARGET_3900
1827 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1828 PC = (signed)0xBFC00000;
1829 #endif SUBTARGET_3900
1830 return;
1831
1832 case TLBModification:
1833 case TLBLoad:
1834 case TLBStore:
1835 case AddressLoad:
1836 case AddressStore:
1837 case InstructionFetch:
1838 case DataReference:
1839 /* The following is so that the simulator will continue from the
1840 exception address on breakpoint operations. */
1841 PC = EPC;
1842 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
1843 sim_stopped, SIM_SIGBUS);
1844
1845 case ReservedInstruction:
1846 case CoProcessorUnusable:
1847 PC = EPC;
1848 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
1849 sim_stopped, SIM_SIGILL);
1850
1851 case IntegerOverflow:
1852 case FPE:
1853 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
1854 sim_stopped, SIM_SIGFPE);
1855
1856 case BreakPoint:
1857 case SystemCall:
1858 case Trap:
1859 sim_engine_restart (SD, CPU, NULL, PC);
1860 break;
1861
1862 case Watch:
1863 PC = EPC;
1864 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
1865 sim_stopped, SIM_SIGTRAP);
1866
1867 default : /* Unknown internal exception */
1868 PC = EPC;
1869 sim_engine_halt (SD, CPU, NULL, NULL_CIA,
1870 sim_stopped, SIM_SIGABRT);
1871
1872 }
1873
1874 case SimulatorFault:
1875 {
1876 va_list ap;
1877 char *msg;
1878 va_start(ap,exception);
1879 msg = va_arg(ap,char *);
1880 va_end(ap);
1881 sim_engine_abort (SD, CPU, NULL_CIA,
1882 "FATAL: Simulator error \"%s\"\n",msg);
1883 }
1884 }
1885
1886 return;
1887 }
1888
1889 #if defined(WARN_RESULT)
1890 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1891 /* This function indicates that the result of the operation is
1892 undefined. However, this should not affect the instruction
1893 stream. All that is meant to happen is that the destination
1894 register is set to an undefined result. To keep the simulator
1895 simple, we just don't bother updating the destination register, so
1896 the overall result will be undefined. If desired we can stop the
1897 simulator by raising a pseudo-exception. */
1898 #define UndefinedResult() undefined_result (sd,cia)
1899 static void
1900 undefined_result(sd,cia)
1901 SIM_DESC sd;
1902 address_word cia;
1903 {
1904 sim_io_eprintf(sd,"UndefinedResult: PC = 0x%s\n",pr_addr(cia));
1905 #if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
1906 state |= simSTOP;
1907 #endif
1908 return;
1909 }
1910 #endif /* WARN_RESULT */
1911
1912 /*-- FPU support routines ---------------------------------------------------*/
1913
1914 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
1915 formats conform to ANSI/IEEE Std 754-1985. */
1916 /* SINGLE precision floating:
1917 * seeeeeeeefffffffffffffffffffffff
1918 * s = 1bit = sign
1919 * e = 8bits = exponent
1920 * f = 23bits = fraction
1921 */
1922 /* SINGLE precision fixed:
1923 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1924 * s = 1bit = sign
1925 * i = 31bits = integer
1926 */
1927 /* DOUBLE precision floating:
1928 * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
1929 * s = 1bit = sign
1930 * e = 11bits = exponent
1931 * f = 52bits = fraction
1932 */
1933 /* DOUBLE precision fixed:
1934 * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
1935 * s = 1bit = sign
1936 * i = 63bits = integer
1937 */
1938
1939 /* Extract sign-bit: */
1940 #define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
1941 #define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
1942 /* Extract biased exponent: */
1943 #define FP_S_be(v) (((v) >> 23) & 0xFF)
1944 #define FP_D_be(v) (((v) >> 52) & 0x7FF)
1945 /* Extract unbiased Exponent: */
1946 #define FP_S_e(v) (FP_S_be(v) - 0x7F)
1947 #define FP_D_e(v) (FP_D_be(v) - 0x3FF)
1948 /* Extract complete fraction field: */
1949 #define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
1950 #define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
1951 /* Extract numbered fraction bit: */
1952 #define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
1953 #define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
1954
1955 /* Explicit QNaN values used when value required: */
1956 #define FPQNaN_SINGLE (0x7FBFFFFF)
1957 #define FPQNaN_WORD (0x7FFFFFFF)
1958 #define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
1959 #define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
1960
1961 /* Explicit Infinity values used when required: */
1962 #define FPINF_SINGLE (0x7F800000)
1963 #define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
1964
1965 #if 1 /* def DEBUG */
1966 #define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
1967 #define DOFMT(v) (((v) == fmt_single) ? "single" : (((v) == fmt_double) ? "double" : (((v) == fmt_word) ? "word" : (((v) == fmt_long) ? "long" : (((v) == fmt_unknown) ? "<unknown>" : (((v) == fmt_uninterpreted) ? "<uninterpreted>" : "<format error>"))))))
1968 #endif /* DEBUG */
1969
1970 uword64
1971 value_fpr (SIM_DESC sd,
1972 sim_cpu *cpu,
1973 address_word cia,
1974 int fpr,
1975 FP_formats fmt)
1976 {
1977 uword64 value = 0;
1978 int err = 0;
1979
1980 /* Treat unused register values, as fixed-point 64bit values: */
1981 if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
1982 #if 1
1983 /* If request to read data as "uninterpreted", then use the current
1984 encoding: */
1985 fmt = FPR_STATE[fpr];
1986 #else
1987 fmt = fmt_long;
1988 #endif
1989
1990 /* For values not yet accessed, set to the desired format: */
1991 if (FPR_STATE[fpr] == fmt_uninterpreted) {
1992 FPR_STATE[fpr] = fmt;
1993 #ifdef DEBUG
1994 printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr,DOFMT(fmt));
1995 #endif /* DEBUG */
1996 }
1997 if (fmt != FPR_STATE[fpr]) {
1998 sim_io_eprintf(sd,"FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",fpr,DOFMT(FPR_STATE[fpr]),DOFMT(fmt),pr_addr(cia));
1999 FPR_STATE[fpr] = fmt_unknown;
2000 }
2001
2002 if (FPR_STATE[fpr] == fmt_unknown) {
2003 /* Set QNaN value: */
2004 switch (fmt) {
2005 case fmt_single:
2006 value = FPQNaN_SINGLE;
2007 break;
2008
2009 case fmt_double:
2010 value = FPQNaN_DOUBLE;
2011 break;
2012
2013 case fmt_word:
2014 value = FPQNaN_WORD;
2015 break;
2016
2017 case fmt_long:
2018 value = FPQNaN_LONG;
2019 break;
2020
2021 default:
2022 err = -1;
2023 break;
2024 }
2025 } else if (SizeFGR() == 64) {
2026 switch (fmt) {
2027 case fmt_single:
2028 case fmt_word:
2029 value = (FGR[fpr] & 0xFFFFFFFF);
2030 break;
2031
2032 case fmt_uninterpreted:
2033 case fmt_double:
2034 case fmt_long:
2035 value = FGR[fpr];
2036 break;
2037
2038 default :
2039 err = -1;
2040 break;
2041 }
2042 } else {
2043 switch (fmt) {
2044 case fmt_single:
2045 case fmt_word:
2046 value = (FGR[fpr] & 0xFFFFFFFF);
2047 break;
2048
2049 case fmt_uninterpreted:
2050 case fmt_double:
2051 case fmt_long:
2052 if ((fpr & 1) == 0) { /* even registers only */
2053 value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF));
2054 } else {
2055 SignalException(ReservedInstruction,0);
2056 }
2057 break;
2058
2059 default :
2060 err = -1;
2061 break;
2062 }
2063 }
2064
2065 if (err)
2066 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
2067
2068 #ifdef DEBUG
2069 printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_addr(value),pr_addr(cia),SizeFGR());
2070 #endif /* DEBUG */
2071
2072 return(value);
2073 }
2074
2075 void
2076 store_fpr (SIM_DESC sd,
2077 sim_cpu *cpu,
2078 address_word cia,
2079 int fpr,
2080 FP_formats fmt,
2081 uword64 value)
2082 {
2083 int err = 0;
2084
2085 #ifdef DEBUG
2086 printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_addr(value),pr_addr(cia),SizeFGR());
2087 #endif /* DEBUG */
2088
2089 if (SizeFGR() == 64) {
2090 switch (fmt) {
2091 case fmt_uninterpreted_32:
2092 fmt = fmt_uninterpreted;
2093 case fmt_single :
2094 case fmt_word :
2095 FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
2096 FPR_STATE[fpr] = fmt;
2097 break;
2098
2099 case fmt_uninterpreted_64:
2100 fmt = fmt_uninterpreted;
2101 case fmt_uninterpreted:
2102 case fmt_double :
2103 case fmt_long :
2104 FGR[fpr] = value;
2105 FPR_STATE[fpr] = fmt;
2106 break;
2107
2108 default :
2109 FPR_STATE[fpr] = fmt_unknown;
2110 err = -1;
2111 break;
2112 }
2113 } else {
2114 switch (fmt) {
2115 case fmt_uninterpreted_32:
2116 fmt = fmt_uninterpreted;
2117 case fmt_single :
2118 case fmt_word :
2119 FGR[fpr] = (value & 0xFFFFFFFF);
2120 FPR_STATE[fpr] = fmt;
2121 break;
2122
2123 case fmt_uninterpreted_64:
2124 fmt = fmt_uninterpreted;
2125 case fmt_uninterpreted:
2126 case fmt_double :
2127 case fmt_long :
2128 if ((fpr & 1) == 0) { /* even register number only */
2129 FGR[fpr+1] = (value >> 32);
2130 FGR[fpr] = (value & 0xFFFFFFFF);
2131 FPR_STATE[fpr + 1] = fmt;
2132 FPR_STATE[fpr] = fmt;
2133 } else {
2134 FPR_STATE[fpr] = fmt_unknown;
2135 FPR_STATE[fpr + 1] = fmt_unknown;
2136 SignalException(ReservedInstruction,0);
2137 }
2138 break;
2139
2140 default :
2141 FPR_STATE[fpr] = fmt_unknown;
2142 err = -1;
2143 break;
2144 }
2145 }
2146 #if defined(WARN_RESULT)
2147 else
2148 UndefinedResult();
2149 #endif /* WARN_RESULT */
2150
2151 if (err)
2152 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
2153
2154 #ifdef DEBUG
2155 printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_addr(FGR[fpr]),DOFMT(fmt));
2156 #endif /* DEBUG */
2157
2158 return;
2159 }
2160
2161 int
2162 NaN(op,fmt)
2163 uword64 op;
2164 FP_formats fmt;
2165 {
2166 int boolean = 0;
2167 switch (fmt) {
2168 case fmt_single:
2169 case fmt_word:
2170 {
2171 sim_fpu wop;
2172 sim_fpu_32to (&wop, op);
2173 boolean = sim_fpu_is_nan (&wop);
2174 break;
2175 }
2176 case fmt_double:
2177 case fmt_long:
2178 {
2179 sim_fpu wop;
2180 sim_fpu_64to (&wop, op);
2181 boolean = sim_fpu_is_nan (&wop);
2182 break;
2183 }
2184 default:
2185 fprintf (stderr, "Bad switch\n");
2186 abort ();
2187 }
2188
2189 #ifdef DEBUG
2190 printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
2191 #endif /* DEBUG */
2192
2193 return(boolean);
2194 }
2195
2196 int
2197 Infinity(op,fmt)
2198 uword64 op;
2199 FP_formats fmt;
2200 {
2201 int boolean = 0;
2202
2203 #ifdef DEBUG
2204 printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt),pr_addr(op));
2205 #endif /* DEBUG */
2206
2207 switch (fmt) {
2208 case fmt_single:
2209 {
2210 sim_fpu wop;
2211 sim_fpu_32to (&wop, op);
2212 boolean = sim_fpu_is_infinity (&wop);
2213 break;
2214 }
2215 case fmt_double:
2216 {
2217 sim_fpu wop;
2218 sim_fpu_64to (&wop, op);
2219 boolean = sim_fpu_is_infinity (&wop);
2220 break;
2221 }
2222 default:
2223 printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt));
2224 break;
2225 }
2226
2227 #ifdef DEBUG
2228 printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
2229 #endif /* DEBUG */
2230
2231 return(boolean);
2232 }
2233
2234 int
2235 Less(op1,op2,fmt)
2236 uword64 op1;
2237 uword64 op2;
2238 FP_formats fmt;
2239 {
2240 int boolean = 0;
2241
2242 /* Argument checking already performed by the FPCOMPARE code */
2243
2244 #ifdef DEBUG
2245 printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2246 #endif /* DEBUG */
2247
2248 /* The format type should already have been checked: */
2249 switch (fmt) {
2250 case fmt_single:
2251 {
2252 sim_fpu wop1;
2253 sim_fpu wop2;
2254 sim_fpu_32to (&wop1, op1);
2255 sim_fpu_32to (&wop2, op2);
2256 boolean = sim_fpu_is_lt (&wop1, &wop2);
2257 break;
2258 }
2259 case fmt_double:
2260 {
2261 sim_fpu wop1;
2262 sim_fpu wop2;
2263 sim_fpu_64to (&wop1, op1);
2264 sim_fpu_64to (&wop2, op2);
2265 boolean = sim_fpu_is_lt (&wop1, &wop2);
2266 break;
2267 }
2268 default:
2269 fprintf (stderr, "Bad switch\n");
2270 abort ();
2271 }
2272
2273 #ifdef DEBUG
2274 printf("DBG: Less: returning %d (format = %s)\n",boolean,DOFMT(fmt));
2275 #endif /* DEBUG */
2276
2277 return(boolean);
2278 }
2279
2280 int
2281 Equal(op1,op2,fmt)
2282 uword64 op1;
2283 uword64 op2;
2284 FP_formats fmt;
2285 {
2286 int boolean = 0;
2287
2288 /* Argument checking already performed by the FPCOMPARE code */
2289
2290 #ifdef DEBUG
2291 printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2292 #endif /* DEBUG */
2293
2294 /* The format type should already have been checked: */
2295 switch (fmt) {
2296 case fmt_single:
2297 {
2298 sim_fpu wop1;
2299 sim_fpu wop2;
2300 sim_fpu_32to (&wop1, op1);
2301 sim_fpu_32to (&wop2, op2);
2302 boolean = sim_fpu_is_eq (&wop1, &wop2);
2303 break;
2304 }
2305 case fmt_double:
2306 {
2307 sim_fpu wop1;
2308 sim_fpu wop2;
2309 sim_fpu_64to (&wop1, op1);
2310 sim_fpu_64to (&wop2, op2);
2311 boolean = sim_fpu_is_eq (&wop1, &wop2);
2312 break;
2313 }
2314 default:
2315 fprintf (stderr, "Bad switch\n");
2316 abort ();
2317 }
2318
2319 #ifdef DEBUG
2320 printf("DBG: Equal: returning %d (format = %s)\n",boolean,DOFMT(fmt));
2321 #endif /* DEBUG */
2322
2323 return(boolean);
2324 }
2325
2326 uword64
2327 AbsoluteValue(op,fmt)
2328 uword64 op;
2329 FP_formats fmt;
2330 {
2331 uword64 result = 0;
2332
2333 #ifdef DEBUG
2334 printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2335 #endif /* DEBUG */
2336
2337 /* The format type should already have been checked: */
2338 switch (fmt) {
2339 case fmt_single:
2340 {
2341 sim_fpu wop;
2342 unsigned32 ans;
2343 sim_fpu_32to (&wop, op);
2344 sim_fpu_abs (&wop, &wop);
2345 sim_fpu_to32 (&ans, &wop);
2346 result = ans;
2347 break;
2348 }
2349 case fmt_double:
2350 {
2351 sim_fpu wop;
2352 unsigned64 ans;
2353 sim_fpu_64to (&wop, op);
2354 sim_fpu_abs (&wop, &wop);
2355 sim_fpu_to64 (&ans, &wop);
2356 result = ans;
2357 break;
2358 }
2359 default:
2360 fprintf (stderr, "Bad switch\n");
2361 abort ();
2362 }
2363
2364 return(result);
2365 }
2366
2367 uword64
2368 Negate(op,fmt)
2369 uword64 op;
2370 FP_formats fmt;
2371 {
2372 uword64 result = 0;
2373
2374 #ifdef DEBUG
2375 printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2376 #endif /* DEBUG */
2377
2378 /* The format type should already have been checked: */
2379 switch (fmt) {
2380 case fmt_single:
2381 {
2382 sim_fpu wop;
2383 unsigned32 ans;
2384 sim_fpu_32to (&wop, op);
2385 sim_fpu_neg (&wop, &wop);
2386 sim_fpu_to32 (&ans, &wop);
2387 result = ans;
2388 break;
2389 }
2390 case fmt_double:
2391 {
2392 sim_fpu wop;
2393 unsigned64 ans;
2394 sim_fpu_64to (&wop, op);
2395 sim_fpu_neg (&wop, &wop);
2396 sim_fpu_to64 (&ans, &wop);
2397 result = ans;
2398 break;
2399 }
2400 default:
2401 fprintf (stderr, "Bad switch\n");
2402 abort ();
2403 }
2404
2405 return(result);
2406 }
2407
2408 uword64
2409 Add(op1,op2,fmt)
2410 uword64 op1;
2411 uword64 op2;
2412 FP_formats fmt;
2413 {
2414 uword64 result = 0;
2415
2416 #ifdef DEBUG
2417 printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2418 #endif /* DEBUG */
2419
2420 /* The registers must specify FPRs valid for operands of type
2421 "fmt". If they are not valid, the result is undefined. */
2422
2423 /* The format type should already have been checked: */
2424 switch (fmt) {
2425 case fmt_single:
2426 {
2427 sim_fpu wop1;
2428 sim_fpu wop2;
2429 sim_fpu ans;
2430 unsigned32 res;
2431 sim_fpu_32to (&wop1, op1);
2432 sim_fpu_32to (&wop2, op2);
2433 sim_fpu_add (&ans, &wop1, &wop2);
2434 sim_fpu_to32 (&res, &ans);
2435 result = res;
2436 break;
2437 }
2438 case fmt_double:
2439 {
2440 sim_fpu wop1;
2441 sim_fpu wop2;
2442 sim_fpu ans;
2443 unsigned64 res;
2444 sim_fpu_64to (&wop1, op1);
2445 sim_fpu_64to (&wop2, op2);
2446 sim_fpu_add (&ans, &wop1, &wop2);
2447 sim_fpu_to64 (&res, &ans);
2448 result = res;
2449 break;
2450 }
2451 default:
2452 fprintf (stderr, "Bad switch\n");
2453 abort ();
2454 }
2455
2456 #ifdef DEBUG
2457 printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2458 #endif /* DEBUG */
2459
2460 return(result);
2461 }
2462
2463 uword64
2464 Sub(op1,op2,fmt)
2465 uword64 op1;
2466 uword64 op2;
2467 FP_formats fmt;
2468 {
2469 uword64 result = 0;
2470
2471 #ifdef DEBUG
2472 printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2473 #endif /* DEBUG */
2474
2475 /* The registers must specify FPRs valid for operands of type
2476 "fmt". If they are not valid, the result is undefined. */
2477
2478 /* The format type should already have been checked: */
2479 switch (fmt) {
2480 case fmt_single:
2481 {
2482 sim_fpu wop1;
2483 sim_fpu wop2;
2484 sim_fpu ans;
2485 unsigned32 res;
2486 sim_fpu_32to (&wop1, op1);
2487 sim_fpu_32to (&wop2, op2);
2488 sim_fpu_sub (&ans, &wop1, &wop2);
2489 sim_fpu_to32 (&res, &ans);
2490 result = res;
2491 }
2492 break;
2493 case fmt_double:
2494 {
2495 sim_fpu wop1;
2496 sim_fpu wop2;
2497 sim_fpu ans;
2498 unsigned64 res;
2499 sim_fpu_64to (&wop1, op1);
2500 sim_fpu_64to (&wop2, op2);
2501 sim_fpu_sub (&ans, &wop1, &wop2);
2502 sim_fpu_to64 (&res, &ans);
2503 result = res;
2504 }
2505 break;
2506 default:
2507 fprintf (stderr, "Bad switch\n");
2508 abort ();
2509 }
2510
2511 #ifdef DEBUG
2512 printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2513 #endif /* DEBUG */
2514
2515 return(result);
2516 }
2517
2518 uword64
2519 Multiply(op1,op2,fmt)
2520 uword64 op1;
2521 uword64 op2;
2522 FP_formats fmt;
2523 {
2524 uword64 result = 0;
2525
2526 #ifdef DEBUG
2527 printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2528 #endif /* DEBUG */
2529
2530 /* The registers must specify FPRs valid for operands of type
2531 "fmt". If they are not valid, the result is undefined. */
2532
2533 /* The format type should already have been checked: */
2534 switch (fmt) {
2535 case fmt_single:
2536 {
2537 sim_fpu wop1;
2538 sim_fpu wop2;
2539 sim_fpu ans;
2540 unsigned32 res;
2541 sim_fpu_32to (&wop1, op1);
2542 sim_fpu_32to (&wop2, op2);
2543 sim_fpu_mul (&ans, &wop1, &wop2);
2544 sim_fpu_to32 (&res, &ans);
2545 result = res;
2546 break;
2547 }
2548 case fmt_double:
2549 {
2550 sim_fpu wop1;
2551 sim_fpu wop2;
2552 sim_fpu ans;
2553 unsigned64 res;
2554 sim_fpu_64to (&wop1, op1);
2555 sim_fpu_64to (&wop2, op2);
2556 sim_fpu_mul (&ans, &wop1, &wop2);
2557 sim_fpu_to64 (&res, &ans);
2558 result = res;
2559 break;
2560 }
2561 default:
2562 fprintf (stderr, "Bad switch\n");
2563 abort ();
2564 }
2565
2566 #ifdef DEBUG
2567 printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2568 #endif /* DEBUG */
2569
2570 return(result);
2571 }
2572
2573 uword64
2574 Divide(op1,op2,fmt)
2575 uword64 op1;
2576 uword64 op2;
2577 FP_formats fmt;
2578 {
2579 uword64 result = 0;
2580
2581 #ifdef DEBUG
2582 printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2583 #endif /* DEBUG */
2584
2585 /* The registers must specify FPRs valid for operands of type
2586 "fmt". If they are not valid, the result is undefined. */
2587
2588 /* The format type should already have been checked: */
2589 switch (fmt) {
2590 case fmt_single:
2591 {
2592 sim_fpu wop1;
2593 sim_fpu wop2;
2594 sim_fpu ans;
2595 unsigned32 res;
2596 sim_fpu_32to (&wop1, op1);
2597 sim_fpu_32to (&wop2, op2);
2598 sim_fpu_div (&ans, &wop1, &wop2);
2599 sim_fpu_to32 (&res, &ans);
2600 result = res;
2601 break;
2602 }
2603 case fmt_double:
2604 {
2605 sim_fpu wop1;
2606 sim_fpu wop2;
2607 sim_fpu ans;
2608 unsigned64 res;
2609 sim_fpu_64to (&wop1, op1);
2610 sim_fpu_64to (&wop2, op2);
2611 sim_fpu_div (&ans, &wop1, &wop2);
2612 sim_fpu_to64 (&res, &ans);
2613 result = res;
2614 break;
2615 }
2616 default:
2617 fprintf (stderr, "Bad switch\n");
2618 abort ();
2619 }
2620
2621 #ifdef DEBUG
2622 printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2623 #endif /* DEBUG */
2624
2625 return(result);
2626 }
2627
2628 uword64 UNUSED
2629 Recip(op,fmt)
2630 uword64 op;
2631 FP_formats fmt;
2632 {
2633 uword64 result = 0;
2634
2635 #ifdef DEBUG
2636 printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2637 #endif /* DEBUG */
2638
2639 /* The registers must specify FPRs valid for operands of type
2640 "fmt". If they are not valid, the result is undefined. */
2641
2642 /* The format type should already have been checked: */
2643 switch (fmt) {
2644 case fmt_single:
2645 {
2646 sim_fpu wop;
2647 sim_fpu ans;
2648 unsigned32 res;
2649 sim_fpu_32to (&wop, op);
2650 sim_fpu_inv (&ans, &wop);
2651 sim_fpu_to32 (&res, &ans);
2652 result = res;
2653 break;
2654 }
2655 case fmt_double:
2656 {
2657 sim_fpu wop;
2658 sim_fpu ans;
2659 unsigned64 res;
2660 sim_fpu_64to (&wop, op);
2661 sim_fpu_inv (&ans, &wop);
2662 sim_fpu_to64 (&res, &ans);
2663 result = res;
2664 break;
2665 }
2666 default:
2667 fprintf (stderr, "Bad switch\n");
2668 abort ();
2669 }
2670
2671 #ifdef DEBUG
2672 printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2673 #endif /* DEBUG */
2674
2675 return(result);
2676 }
2677
2678 uword64
2679 SquareRoot(op,fmt)
2680 uword64 op;
2681 FP_formats fmt;
2682 {
2683 uword64 result = 0;
2684
2685 #ifdef DEBUG
2686 printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
2687 #endif /* DEBUG */
2688
2689 /* The registers must specify FPRs valid for operands of type
2690 "fmt". If they are not valid, the result is undefined. */
2691
2692 /* The format type should already have been checked: */
2693 switch (fmt) {
2694 case fmt_single:
2695 {
2696 sim_fpu wop;
2697 sim_fpu ans;
2698 unsigned32 res;
2699 sim_fpu_32to (&wop, op);
2700 sim_fpu_sqrt (&ans, &wop);
2701 sim_fpu_to32 (&res, &ans);
2702 result = res;
2703 break;
2704 }
2705 case fmt_double:
2706 {
2707 sim_fpu wop;
2708 sim_fpu ans;
2709 unsigned64 res;
2710 sim_fpu_64to (&wop, op);
2711 sim_fpu_sqrt (&ans, &wop);
2712 sim_fpu_to64 (&res, &ans);
2713 result = res;
2714 break;
2715 }
2716 default:
2717 fprintf (stderr, "Bad switch\n");
2718 abort ();
2719 }
2720
2721 #ifdef DEBUG
2722 printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2723 #endif /* DEBUG */
2724
2725 return(result);
2726 }
2727
2728 #if 0
2729 uword64
2730 Max (uword64 op1,
2731 uword64 op2,
2732 FP_formats fmt)
2733 {
2734 int cmp;
2735 unsigned64 result;
2736
2737 #ifdef DEBUG
2738 printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2739 #endif /* DEBUG */
2740
2741 /* The registers must specify FPRs valid for operands of type
2742 "fmt". If they are not valid, the result is undefined. */
2743
2744 /* The format type should already have been checked: */
2745 switch (fmt)
2746 {
2747 case fmt_single:
2748 {
2749 sim_fpu wop1;
2750 sim_fpu wop2;
2751 sim_fpu_32to (&wop1, op1);
2752 sim_fpu_32to (&wop2, op2);
2753 cmp = sim_fpu_cmp (&wop1, &wop2);
2754 break;
2755 }
2756 case fmt_double:
2757 {
2758 sim_fpu wop1;
2759 sim_fpu wop2;
2760 sim_fpu_64to (&wop1, op1);
2761 sim_fpu_64to (&wop2, op2);
2762 cmp = sim_fpu_cmp (&wop1, &wop2);
2763 break;
2764 }
2765 default:
2766 fprintf (stderr, "Bad switch\n");
2767 abort ();
2768 }
2769
2770 switch (cmp)
2771 {
2772 case SIM_FPU_IS_SNAN:
2773 case SIM_FPU_IS_QNAN:
2774 result = op1;
2775 case SIM_FPU_IS_NINF:
2776 case SIM_FPU_IS_NNUMBER:
2777 case SIM_FPU_IS_NDENORM:
2778 case SIM_FPU_IS_NZERO:
2779 result = op2; /* op1 - op2 < 0 */
2780 case SIM_FPU_IS_PINF:
2781 case SIM_FPU_IS_PNUMBER:
2782 case SIM_FPU_IS_PDENORM:
2783 case SIM_FPU_IS_PZERO:
2784 result = op1; /* op1 - op2 > 0 */
2785 default:
2786 fprintf (stderr, "Bad switch\n");
2787 abort ();
2788 }
2789
2790 #ifdef DEBUG
2791 printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2792 #endif /* DEBUG */
2793
2794 return(result);
2795 }
2796 #endif
2797
2798 #if 0
2799 uword64
2800 Min (uword64 op1,
2801 uword64 op2,
2802 FP_formats fmt)
2803 {
2804 int cmp;
2805 unsigned64 result;
2806
2807 #ifdef DEBUG
2808 printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
2809 #endif /* DEBUG */
2810
2811 /* The registers must specify FPRs valid for operands of type
2812 "fmt". If they are not valid, the result is undefined. */
2813
2814 /* The format type should already have been checked: */
2815 switch (fmt)
2816 {
2817 case fmt_single:
2818 {
2819 sim_fpu wop1;
2820 sim_fpu wop2;
2821 sim_fpu_32to (&wop1, op1);
2822 sim_fpu_32to (&wop2, op2);
2823 cmp = sim_fpu_cmp (&wop1, &wop2);
2824 break;
2825 }
2826 case fmt_double:
2827 {
2828 sim_fpu wop1;
2829 sim_fpu wop2;
2830 sim_fpu_64to (&wop1, op1);
2831 sim_fpu_64to (&wop2, op2);
2832 cmp = sim_fpu_cmp (&wop1, &wop2);
2833 break;
2834 }
2835 default:
2836 fprintf (stderr, "Bad switch\n");
2837 abort ();
2838 }
2839
2840 switch (cmp)
2841 {
2842 case SIM_FPU_IS_SNAN:
2843 case SIM_FPU_IS_QNAN:
2844 result = op1;
2845 case SIM_FPU_IS_NINF:
2846 case SIM_FPU_IS_NNUMBER:
2847 case SIM_FPU_IS_NDENORM:
2848 case SIM_FPU_IS_NZERO:
2849 result = op1; /* op1 - op2 < 0 */
2850 case SIM_FPU_IS_PINF:
2851 case SIM_FPU_IS_PNUMBER:
2852 case SIM_FPU_IS_PDENORM:
2853 case SIM_FPU_IS_PZERO:
2854 result = op2; /* op1 - op2 > 0 */
2855 default:
2856 fprintf (stderr, "Bad switch\n");
2857 abort ();
2858 }
2859
2860 #ifdef DEBUG
2861 printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
2862 #endif /* DEBUG */
2863
2864 return(result);
2865 }
2866 #endif
2867
2868 uword64
2869 convert (SIM_DESC sd,
2870 sim_cpu *cpu,
2871 address_word cia,
2872 int rm,
2873 uword64 op,
2874 FP_formats from,
2875 FP_formats to)
2876 {
2877 sim_fpu wop;
2878 sim_fpu_round round;
2879 unsigned32 result32;
2880 unsigned64 result64;
2881
2882 #ifdef DEBUG
2883 printf("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",RMMODE(rm),pr_addr(op),DOFMT(from),DOFMT(to),pr_addr(IPC));
2884 #endif /* DEBUG */
2885
2886 switch (rm)
2887 {
2888 case FP_RM_NEAREST:
2889 /* Round result to nearest representable value. When two
2890 representable values are equally near, round to the value
2891 that has a least significant bit of zero (i.e. is even). */
2892 round = sim_fpu_round_near;
2893 break;
2894 case FP_RM_TOZERO:
2895 /* Round result to the value closest to, and not greater in
2896 magnitude than, the result. */
2897 round = sim_fpu_round_zero;
2898 break;
2899 case FP_RM_TOPINF:
2900 /* Round result to the value closest to, and not less than,
2901 the result. */
2902 round = sim_fpu_round_up;
2903 break;
2904
2905 case FP_RM_TOMINF:
2906 /* Round result to the value closest to, and not greater than,
2907 the result. */
2908 round = sim_fpu_round_down;
2909 break;
2910 default:
2911 round = 0;
2912 fprintf (stderr, "Bad switch\n");
2913 abort ();
2914 }
2915
2916 /* Convert the input to sim_fpu internal format */
2917 switch (from)
2918 {
2919 case fmt_double:
2920 sim_fpu_64to (&wop, op);
2921 break;
2922 case fmt_single:
2923 sim_fpu_32to (&wop, op);
2924 break;
2925 case fmt_word:
2926 sim_fpu_i32to (&wop, op, round);
2927 break;
2928 case fmt_long:
2929 sim_fpu_i64to (&wop, op, round);
2930 break;
2931 default:
2932 fprintf (stderr, "Bad switch\n");
2933 abort ();
2934 }
2935
2936 /* Convert sim_fpu format into the output */
2937 /* The value WOP is converted to the destination format, rounding
2938 using mode RM. When the destination is a fixed-point format, then
2939 a source value of Infinity, NaN or one which would round to an
2940 integer outside the fixed point range then an IEEE Invalid
2941 Operation condition is raised. */
2942 switch (to)
2943 {
2944 case fmt_single:
2945 sim_fpu_round_32 (&wop, round, 0);
2946 sim_fpu_to32 (&result32, &wop);
2947 result64 = result32;
2948 break;
2949 case fmt_double:
2950 sim_fpu_round_64 (&wop, round, 0);
2951 sim_fpu_to64 (&result64, &wop);
2952 break;
2953 case fmt_word:
2954 sim_fpu_to32i (&result32, &wop, round);
2955 result64 = result32;
2956 break;
2957 case fmt_long:
2958 sim_fpu_to64i (&result64, &wop, round);
2959 break;
2960 default:
2961 result64 = 0;
2962 fprintf (stderr, "Bad switch\n");
2963 abort ();
2964 }
2965
2966 #ifdef DEBUG
2967 printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64),DOFMT(to));
2968 #endif /* DEBUG */
2969
2970 return(result64);
2971 }
2972
2973
2974 /*-- co-processor support routines ------------------------------------------*/
2975
2976 static int UNUSED
2977 CoProcPresent(coproc_number)
2978 unsigned int coproc_number;
2979 {
2980 /* Return TRUE if simulator provides a model for the given co-processor number */
2981 return(0);
2982 }
2983
2984 void
2985 cop_lw (SIM_DESC sd,
2986 sim_cpu *cpu,
2987 address_word cia,
2988 int coproc_num,
2989 int coproc_reg,
2990 unsigned int memword)
2991 {
2992 switch (coproc_num)
2993 {
2994 case 1:
2995 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2996 {
2997 #ifdef DEBUG
2998 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
2999 #endif
3000 StoreFPR(coproc_reg,fmt_word,(uword64)memword);
3001 FPR_STATE[coproc_reg] = fmt_uninterpreted;
3002 break;
3003 }
3004
3005 default:
3006 #if 0 /* this should be controlled by a configuration option */
3007 sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(cia));
3008 #endif
3009 break;
3010 }
3011
3012 return;
3013 }
3014
3015 void
3016 cop_ld (SIM_DESC sd,
3017 sim_cpu *cpu,
3018 address_word cia,
3019 int coproc_num,
3020 int coproc_reg,
3021 uword64 memword)
3022 {
3023 switch (coproc_num) {
3024 case 1:
3025 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3026 {
3027 StoreFPR(coproc_reg,fmt_uninterpreted,memword);
3028 break;
3029 }
3030
3031 default:
3032 #if 0 /* this message should be controlled by a configuration option */
3033 sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(cia));
3034 #endif
3035 break;
3036 }
3037
3038 return;
3039 }
3040
3041
3042 /* start-sanitize-sky */
3043 #ifdef TARGET_SKY
3044 void
3045 cop_lq (SIM_DESC sd,
3046 sim_cpu *cpu,
3047 address_word cia,
3048 int coproc_num,
3049 int coproc_reg,
3050 unsigned128 memword)
3051 {
3052 switch (coproc_num)
3053 {
3054 case 2:
3055 {
3056 int i;
3057
3058 while(vu0_busy())
3059 vu0_issue(sd);
3060
3061 /* one word at a time, argh! */
3062 for(i=0; i<4; i++)
3063 {
3064 unsigned_4 value;
3065 value = H2T_4(*A4_16(& memword, 3-i));
3066 write_vu_vec_reg(&(vu0_device.regs), coproc_reg, i, & value);
3067 }
3068 }
3069 break;
3070
3071 default:
3072 sim_io_printf(sd,"COP_LQ(%d,%d,??) at PC = 0x%s : TODO (architecture specific)\n",
3073 coproc_num,coproc_reg,pr_addr(cia));
3074 break;
3075 }
3076
3077 return;
3078 }
3079 #endif /* TARGET_SKY */
3080 /* end-sanitize-sky */
3081
3082
3083 unsigned int
3084 cop_sw (SIM_DESC sd,
3085 sim_cpu *cpu,
3086 address_word cia,
3087 int coproc_num,
3088 int coproc_reg)
3089 {
3090 unsigned int value = 0;
3091
3092 switch (coproc_num)
3093 {
3094 case 1:
3095 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3096 {
3097 FP_formats hold;
3098 hold = FPR_STATE[coproc_reg];
3099 FPR_STATE[coproc_reg] = fmt_word;
3100 value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
3101 FPR_STATE[coproc_reg] = hold;
3102 break;
3103 }
3104
3105 default:
3106 #if 0 /* should be controlled by configuration option */
3107 sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
3108 #endif
3109 break;
3110 }
3111
3112 return(value);
3113 }
3114
3115 uword64
3116 cop_sd (SIM_DESC sd,
3117 sim_cpu *cpu,
3118 address_word cia,
3119 int coproc_num,
3120 int coproc_reg)
3121 {
3122 uword64 value = 0;
3123 switch (coproc_num)
3124 {
3125 case 1:
3126 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
3127 {
3128 value = ValueFPR(coproc_reg,fmt_uninterpreted);
3129 break;
3130 }
3131
3132 default:
3133 #if 0 /* should be controlled by configuration option */
3134 sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
3135 #endif
3136 break;
3137 }
3138
3139 return(value);
3140 }
3141
3142
3143 /* start-sanitize-sky */
3144 #ifdef TARGET_SKY
3145 unsigned128
3146 cop_sq (SIM_DESC sd,
3147 sim_cpu *cpu,
3148 address_word cia,
3149 int coproc_num,
3150 int coproc_reg)
3151 {
3152 unsigned128 value = U16_8(0, 0);
3153 switch (coproc_num)
3154 {
3155 case 2:
3156 {
3157 unsigned_16 xyzw;
3158 int i;
3159
3160 while(vu0_busy())
3161 vu0_issue(sd);
3162
3163 /* one word at a time, argh! */
3164 for(i=0; i<4; i++)
3165 {
3166 unsigned_4 value;
3167 read_vu_vec_reg(&(vu0_device.regs), coproc_reg, i, & value);
3168 *A4_16(& xyzw, 3-i) = T2H_4(value);
3169 }
3170 return xyzw;
3171 }
3172 break;
3173
3174 default:
3175 sim_io_printf(sd,"COP_SQ(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",
3176 coproc_num,coproc_reg,pr_addr(cia));
3177 break;
3178 }
3179
3180 return(value);
3181 }
3182 #endif /* TARGET_SKY */
3183 /* end-sanitize-sky */
3184
3185
3186 void
3187 decode_coproc (SIM_DESC sd,
3188 sim_cpu *cpu,
3189 address_word cia,
3190 unsigned int instruction)
3191 {
3192 int coprocnum = ((instruction >> 26) & 3);
3193
3194 switch (coprocnum)
3195 {
3196 case 0: /* standard CPU control and cache registers */
3197 {
3198 int code = ((instruction >> 21) & 0x1F);
3199 /* R4000 Users Manual (second edition) lists the following CP0
3200 instructions:
3201 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
3202 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
3203 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
3204 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
3205 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
3206 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
3207 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
3208 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
3209 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
3210 ERET Exception return (VR4100 = 01000010000000000000000000011000)
3211 */
3212 if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0))
3213 {
3214 int rt = ((instruction >> 16) & 0x1F);
3215 int rd = ((instruction >> 11) & 0x1F);
3216
3217 switch (rd) /* NOTEs: Standard CP0 registers */
3218 {
3219 /* 0 = Index R4000 VR4100 VR4300 */
3220 /* 1 = Random R4000 VR4100 VR4300 */
3221 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
3222 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
3223 /* 4 = Context R4000 VR4100 VR4300 */
3224 /* 5 = PageMask R4000 VR4100 VR4300 */
3225 /* 6 = Wired R4000 VR4100 VR4300 */
3226 /* 8 = BadVAddr R4000 VR4100 VR4300 */
3227 /* 9 = Count R4000 VR4100 VR4300 */
3228 /* 10 = EntryHi R4000 VR4100 VR4300 */
3229 /* 11 = Compare R4000 VR4100 VR4300 */
3230 /* 12 = SR R4000 VR4100 VR4300 */
3231 #ifdef SUBTARGET_R3900
3232 case 3:
3233 /* ignore */
3234 break;
3235 /* 3 = Config R3900 */
3236
3237 case 7:
3238 /* ignore */
3239 break;
3240 /* 3 = Cache R3900 */
3241
3242 #endif /* SUBTARGET_R3900 */
3243 case 12:
3244 if (code == 0x00)
3245 GPR[rt] = SR;
3246 else
3247 SR = GPR[rt];
3248 break;
3249 /* 13 = Cause R4000 VR4100 VR4300 */
3250 case 13:
3251 if (code == 0x00)
3252 GPR[rt] = CAUSE;
3253 else
3254 CAUSE = GPR[rt];
3255 break;
3256 /* 14 = EPC R4000 VR4100 VR4300 */
3257 case 14:
3258 if (code == 0x00)
3259 GPR[rt] = (signed_word) (signed_address) EPC;
3260 else
3261 EPC = GPR[rt];
3262 break;
3263 /* 15 = PRId R4000 VR4100 VR4300 */
3264 #ifdef SUBTARGET_R3900
3265 /* 16 = Debug */
3266 case 16:
3267 if (code == 0x00)
3268 GPR[rt] = Debug;
3269 else
3270 Debug = GPR[rt];
3271 break;
3272 #else
3273 /* 16 = Config R4000 VR4100 VR4300 */
3274 case 16:
3275 if (code == 0x00)
3276 GPR[rt] = C0_CONFIG;
3277 else
3278 C0_CONFIG = GPR[rt];
3279 break;
3280 #endif
3281 #ifdef SUBTARGET_R3900
3282 /* 17 = Debug */
3283 case 17:
3284 if (code == 0x00)
3285 GPR[rt] = DEPC;
3286 else
3287 DEPC = GPR[rt];
3288 break;
3289 #else
3290 /* 17 = LLAddr R4000 VR4100 VR4300 */
3291 #endif
3292 /* 18 = WatchLo R4000 VR4100 VR4300 */
3293 /* 19 = WatchHi R4000 VR4100 VR4300 */
3294 /* 20 = XContext R4000 VR4100 VR4300 */
3295 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
3296 /* 27 = CacheErr R4000 VR4100 */
3297 /* 28 = TagLo R4000 VR4100 VR4300 */
3298 /* 29 = TagHi R4000 VR4100 VR4300 */
3299 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
3300 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
3301 /* CPR[0,rd] = GPR[rt]; */
3302 default:
3303 if (code == 0x00)
3304 sim_io_printf(sd,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt,rd);
3305 else
3306 sim_io_printf(sd,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt,rd);
3307 }
3308 }
3309 else if (code == 0x10 && (instruction & 0x3f) == 0x18)
3310 {
3311 /* ERET */
3312 if (SR & status_ERL)
3313 {
3314 /* Oops, not yet available */
3315 sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
3316 PC = EPC;
3317 SR &= ~status_ERL;
3318 }
3319 else
3320 {
3321 PC = EPC;
3322 SR &= ~status_EXL;
3323 }
3324 }
3325 else if (code == 0x10 && (instruction & 0x3f) == 0x10)
3326 {
3327 /* RFE */
3328 #ifdef SUBTARGET_R3900
3329 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
3330
3331 /* shift IE/KU history bits right */
3332 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
3333
3334 /* TODO: CACHE register */
3335 #endif /* SUBTARGET_R3900 */
3336 }
3337 else if (code == 0x10 && (instruction & 0x3f) == 0x1F)
3338 {
3339 /* DERET */
3340 Debug &= ~Debug_DM;
3341 DELAYSLOT();
3342 DSPC = DEPC;
3343 }
3344 else
3345 sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
3346 /* TODO: When executing an ERET or RFE instruction we should
3347 clear LLBIT, to ensure that any out-standing atomic
3348 read/modify/write sequence fails. */
3349 }
3350 break;
3351
3352 case 2: /* co-processor 2 */
3353 {
3354 int handle = 0;
3355
3356 /* start-sanitize-sky */
3357 #ifdef TARGET_SKY
3358 /* On the R5900, this refers to a "VU" vector co-processor. */
3359
3360 int i_25_21 = (instruction >> 21) & 0x1f;
3361 int i_20_16 = (instruction >> 16) & 0x1f;
3362 int i_20_6 = (instruction >> 6) & 0x7fff;
3363 int i_15_11 = (instruction >> 11) & 0x1f;
3364 int i_15_0 = instruction & 0xffff;
3365 int i_10_1 = (instruction >> 1) & 0x3ff;
3366 int i_10_0 = instruction & 0x7ff;
3367 int i_10_6 = (instruction >> 6) & 0x1f;
3368 int i_5_0 = instruction & 0x03f;
3369 int interlock = instruction & 0x01;
3370 /* setup for semantic.c-like actions below */
3371 typedef unsigned_4 instruction_word;
3372 int CIA = cia;
3373 int NIA = cia + 4;
3374
3375 handle = 1;
3376
3377 /* test COP2 usability */
3378 if(! (SR & status_CU2))
3379 {
3380 SignalException(CoProcessorUnusable,instruction);
3381 /* NOTREACHED */
3382 }
3383
3384 #define MY_INDEX itable_COPz_NORMAL
3385 #define MY_PREFIX COPz_NORMAL
3386 #define MY_NAME "COPz_NORMAL"
3387
3388 /* classify & execute basic COP2 instructions */
3389 if(i_25_21 == 0x08 && i_20_16 == 0x00) /* BC2F */
3390 {
3391 address_word offset = EXTEND16(i_15_0) << 2;
3392 if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset);
3393 }
3394 else if(i_25_21 == 0x08 && i_20_16==0x02) /* BC2FL */
3395 {
3396 address_word offset = EXTEND16(i_15_0) << 2;
3397 if(! vu0_busy()) DELAY_SLOT(cia + 4 + offset);
3398 else NULLIFY_NEXT_INSTRUCTION();
3399 }
3400 else if(i_25_21 == 0x08 && i_20_16 == 0x01) /* BC2T */
3401 {
3402 address_word offset = EXTEND16(i_15_0) << 2;
3403 if(vu0_busy()) DELAY_SLOT(cia + 4 + offset);
3404 }
3405 else if(i_25_21 == 0x08 && i_20_16 == 0x03) /* BC2TL */
3406 {
3407 address_word offset = EXTEND16(i_15_0) << 2;
3408 if(vu0_busy()) DELAY_SLOT(cia + 4 + offset);
3409 else NULLIFY_NEXT_INSTRUCTION();
3410 }
3411 else if((i_25_21 == 0x02 && i_10_1 == 0x000) || /* CFC2 */
3412 (i_25_21 == 0x01)) /* QMFC2 */
3413 {
3414 int rt = i_20_16;
3415 int id = i_15_11;
3416
3417 /* interlock checking */
3418 /* POLICY: never busy in macro mode */
3419 while(vu0_busy() && interlock)
3420 vu0_issue(sd);
3421
3422 /* perform VU register address */
3423 if(i_25_21 == 0x01) /* QMFC2 */
3424 {
3425 unsigned_16 xyzw;
3426 /* one word at a time, argh! */
3427 read_vu_vec_reg(&(vu0_device.regs), id, 0, A4_16(& xyzw, 3));
3428 read_vu_vec_reg(&(vu0_device.regs), id, 1, A4_16(& xyzw, 2));
3429 read_vu_vec_reg(&(vu0_device.regs), id, 2, A4_16(& xyzw, 1));
3430 read_vu_vec_reg(&(vu0_device.regs), id, 3, A4_16(& xyzw, 0));
3431 GPR[rt] = T2H_8(* A8_16(& xyzw, 1));
3432 GPR1[rt] = T2H_8(* A8_16(& xyzw, 0));
3433 }
3434 else /* CFC2 */
3435 {
3436 unsigned_4 data;
3437 /* enum + int calculation, argh! */
3438 id = VU_REG_MST + 16 * id;
3439 if (id >= VU_REG_CMSAR0)
3440 read_vu_special_reg(&vu0_device, id, & data);
3441 else
3442 read_vu_misc_reg(&(vu0_device.regs), id, & data);
3443 GPR[rt] = EXTEND32(T2H_4(data));
3444 }
3445 }
3446 else if((i_25_21 == 0x06 && i_10_1 == 0x000) || /* CTC2 */
3447 (i_25_21 == 0x05)) /* QMTC2 */
3448 {
3449 int rt = i_20_16;
3450 int id = i_15_11;
3451
3452 /* interlock checking: wait until M or E bits set */
3453 /* POLICY: never busy in macro mode */
3454 while(vu0_busy() && interlock)
3455 {
3456 if(vu0_micro_interlock_released())
3457 {
3458 vu0_micro_interlock_clear();
3459 break;
3460 }
3461
3462 vu0_issue(sd);
3463 }
3464
3465 /* perform VU register address */
3466 if(i_25_21 == 0x05) /* QMTC2 */
3467 {
3468 unsigned_16 xyzw = U16_8(GPR1[rt], GPR[rt]);
3469
3470 xyzw = H2T_16(xyzw);
3471 /* one word at a time, argh! */
3472 write_vu_vec_reg(&(vu0_device.regs), id, 0, A4_16(& xyzw, 3));
3473 write_vu_vec_reg(&(vu0_device.regs), id, 1, A4_16(& xyzw, 2));
3474 write_vu_vec_reg(&(vu0_device.regs), id, 2, A4_16(& xyzw, 1));
3475 write_vu_vec_reg(&(vu0_device.regs), id, 3, A4_16(& xyzw, 0));
3476 }
3477 else /* CTC2 */
3478 {
3479 unsigned_4 data = H2T_4(GPR[rt]);
3480 /* enum + int calculation, argh! */
3481 id = VU_REG_VI + 16 * id;
3482 if (id >= VU_REG_CMSAR0)
3483 write_vu_special_reg(&vu0_device, id, & data);
3484 else
3485 write_vu_misc_reg(&(vu0_device.regs), id, & data);
3486 }
3487 }
3488 else if(i_10_0 == 0x3bf) /* VWAITQ */
3489 {
3490 while(vu0_q_busy())
3491 vu0_issue(sd);
3492 }
3493 else if(i_5_0 == 0x38) /* VCALLMS */
3494 {
3495 unsigned_4 data = H2T_2(i_20_6);
3496
3497 while(vu0_busy())
3498 vu0_issue(sd);
3499
3500 /* write to reserved CIA register to get VU0 moving */
3501 write_vu_special_reg(& vu0_device, VU_REG_CIA, & data);
3502
3503 ASSERT(vu0_busy());
3504 }
3505 else if(i_5_0 == 0x39) /* VCALLMSR */
3506 {
3507 unsigned_4 data;
3508
3509 while(vu0_busy())
3510 vu0_issue(sd);
3511
3512 read_vu_special_reg(& vu0_device, VU_REG_CMSAR0, & data);
3513 /* write to reserved CIA register to get VU0 moving */
3514 write_vu_special_reg(& vu0_device, VU_REG_CIA, & data);
3515
3516 ASSERT(vu0_busy());
3517 }
3518 /* handle all remaining UPPER VU instructions in one block */
3519 else if((i_5_0 < 0x30) || /* VADDx .. VMINI */
3520 (i_5_0 >= 0x3c && i_10_6 < 0x0c)) /* VADDAx .. VNOP */
3521 {
3522 unsigned_4 vu_upper, vu_lower;
3523 vu_upper =
3524 0x00000000 | /* bits 31 .. 25 */
3525 (instruction & 0x01ffffff); /* bits 24 .. 0 */
3526 vu_lower = 0x8000033c; /* NOP */
3527
3528 /* POLICY: never busy in macro mode */
3529 while(vu0_busy())
3530 vu0_issue(sd);
3531
3532 vu0_macro_issue(vu_upper, vu_lower);
3533
3534 /* POLICY: wait for completion of macro-instruction */
3535 while(vu0_busy())
3536 vu0_issue(sd);
3537 }
3538 /* handle all remaining LOWER VU instructions in one block */
3539 else if((i_5_0 >= 0x30 && i_5_0 <= 0x35) || /* VIADD .. VIOR */
3540 (i_5_0 >= 0x3c && i_10_6 >= 0x0c)) /* VMOVE .. VRXOR */
3541 { /* N.B.: VWAITQ already covered by prior case */
3542 unsigned_4 vu_upper, vu_lower;
3543 vu_upper = 0x000002ff; /* NOP/NOP */
3544 vu_lower =
3545 0x80000000 | /* bits 31 .. 25 */
3546 (instruction & 0x01ffffff); /* bits 24 .. 0 */
3547
3548 /* POLICY: never busy in macro mode */
3549 while(vu0_busy())
3550 vu0_issue(sd);
3551
3552 vu0_macro_issue(vu_upper, vu_lower);
3553
3554 /* POLICY: wait for completion of macro-instruction */
3555 while(vu0_busy())
3556 vu0_issue(sd);
3557 }
3558 /* ... no other COP2 instructions ... */
3559 else
3560 {
3561 SignalException(ReservedInstruction, instruction);
3562 /* NOTREACHED */
3563 }
3564
3565 /* cleanup for semantic.c-like actions above */
3566 PC = NIA;
3567
3568 #undef MY_INDEX
3569 #undef MY_PREFIX
3570 #undef MY_NAME
3571
3572 #endif /* TARGET_SKY */
3573 /* end-sanitize-sky */
3574
3575 if(! handle)
3576 {
3577 sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
3578 instruction,pr_addr(cia));
3579 }
3580 }
3581 break;
3582
3583 case 1: /* should not occur (FPU co-processor) */
3584 case 3: /* should not occur (FPU co-processor) */
3585 SignalException(ReservedInstruction,instruction);
3586 break;
3587 }
3588
3589 return;
3590 }
3591
3592
3593 /*-- instruction simulation -------------------------------------------------*/
3594
3595 /* When the IGEN simulator is being built, the function below is be
3596 replaced by a generated version. However, WITH_IGEN == 2 indicates
3597 that the fubction below should be compiled but under a different
3598 name (to allow backward compatibility) */
3599
3600 #if (WITH_IGEN != 1)
3601 #if (WITH_IGEN > 1)
3602 void old_engine_run PARAMS ((SIM_DESC sd, int next_cpu_nr, int siggnal));
3603 void
3604 old_engine_run (sd, next_cpu_nr, nr_cpus, siggnal)
3605 #else
3606 void
3607 sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal)
3608 #endif
3609 SIM_DESC sd;
3610 int next_cpu_nr; /* ignore */
3611 int nr_cpus; /* ignore */
3612 int siggnal; /* ignore */
3613 {
3614 sim_cpu *cpu = STATE_CPU (sd, 0); /* hardwire to cpu 0 */
3615 #if !defined(FASTSIM)
3616 unsigned int pipeline_count = 1;
3617 #endif
3618
3619 #ifdef DEBUG
3620 if (STATE_MEMORY (sd) == NULL) {
3621 printf("DBG: simulate() entered with no memory\n");
3622 exit(1);
3623 }
3624 #endif /* DEBUG */
3625
3626 #if 0 /* Disabled to check that everything works OK */
3627 /* The VR4300 seems to sign-extend the PC on its first
3628 access. However, this may just be because it is currently
3629 configured in 32bit mode. However... */
3630 PC = SIGNEXTEND(PC,32);
3631 #endif
3632
3633 /* main controlling loop */
3634 while (1) {
3635 /* vaddr is slowly being replaced with cia - current instruction
3636 address */
3637 address_word cia = (uword64)PC;
3638 address_word vaddr = cia;
3639 address_word paddr;
3640 int cca;
3641 unsigned int instruction; /* uword64? what's this used for? FIXME! */
3642
3643 #ifdef DEBUG
3644 {
3645 printf("DBG: state = 0x%08X :",state);
3646 if (state & simHALTEX) printf(" simHALTEX");
3647 if (state & simHALTIN) printf(" simHALTIN");
3648 printf("\n");
3649 }
3650 #endif /* DEBUG */
3651
3652 DSSTATE = (STATE & simDELAYSLOT);
3653 #ifdef DEBUG
3654 if (dsstate)
3655 sim_io_printf(sd,"DBG: DSPC = 0x%s\n",pr_addr(DSPC));
3656 #endif /* DEBUG */
3657
3658 /* Fetch the next instruction from the simulator memory: */
3659 if (AddressTranslation(cia,isINSTRUCTION,isLOAD,&paddr,&cca,isTARGET,isREAL)) {
3660 if ((vaddr & 1) == 0) {
3661 /* Copy the action of the LW instruction */
3662 unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
3663 unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
3664 uword64 value;
3665 unsigned int byte;
3666 paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
3667 LoadMemory(&value,NULL,cca,AccessLength_WORD,paddr,vaddr,isINSTRUCTION,isREAL);
3668 byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
3669 instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
3670 } else {
3671 /* Copy the action of the LH instruction */
3672 unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 1) : 0);
3673 unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 1) : 0);
3674 uword64 value;
3675 unsigned int byte;
3676 paddr = (((paddr & ~ (uword64) 1) & ~LOADDRMASK)
3677 | (((paddr & ~ (uword64) 1) & LOADDRMASK) ^ (reverse << 1)));
3678 LoadMemory(&value,NULL,cca, AccessLength_HALFWORD,
3679 paddr & ~ (uword64) 1,
3680 vaddr, isINSTRUCTION, isREAL);
3681 byte = (((vaddr &~ (uword64) 1) & LOADDRMASK) ^ (bigend << 1));
3682 instruction = ((value >> (8 * byte)) & 0xFFFF);
3683 }
3684 } else {
3685 fprintf(stderr,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC));
3686 exit(1);
3687 }
3688
3689 #ifdef DEBUG
3690 sim_io_printf(sd,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction,pr_addr(PC));
3691 #endif /* DEBUG */
3692
3693 /* This is required by exception processing, to ensure that we can
3694 cope with exceptions in the delay slots of branches that may
3695 already have changed the PC. */
3696 if ((vaddr & 1) == 0)
3697 PC += 4; /* increment ready for the next fetch */
3698 else
3699 PC += 2;
3700 /* NOTE: If we perform a delay slot change to the PC, this
3701 increment is not requuired. However, it would make the
3702 simulator more complicated to try and avoid this small hit. */
3703
3704 /* Currently this code provides a simple model. For more
3705 complicated models we could perform exception status checks at
3706 this point, and set the simSTOP state as required. This could
3707 also include processing any hardware interrupts raised by any
3708 I/O model attached to the simulator context.
3709
3710 Support for "asynchronous" I/O events within the simulated world
3711 could be providing by managing a counter, and calling a I/O
3712 specific handler when a particular threshold is reached. On most
3713 architectures a decrement and check for zero operation is
3714 usually quicker than an increment and compare. However, the
3715 process of managing a known value decrement to zero, is higher
3716 than the cost of using an explicit value UINT_MAX into the
3717 future. Which system is used will depend on how complicated the
3718 I/O model is, and how much it is likely to affect the simulator
3719 bandwidth.
3720
3721 If events need to be scheduled further in the future than
3722 UINT_MAX event ticks, then the I/O model should just provide its
3723 own counter, triggered from the event system. */
3724
3725 /* MIPS pipeline ticks. To allow for future support where the
3726 pipeline hit of individual instructions is known, this control
3727 loop manages a "pipeline_count" variable. It is initialised to
3728 1 (one), and will only be changed by the simulator engine when
3729 executing an instruction. If the engine does not have access to
3730 pipeline cycle count information then all instructions will be
3731 treated as using a single cycle. NOTE: A standard system is not
3732 provided by the default simulator because different MIPS
3733 architectures have different cycle counts for the same
3734 instructions.
3735
3736 [NOTE: pipeline_count has been replaced the event queue] */
3737
3738 /* shuffle the floating point status pipeline state */
3739 ENGINE_ISSUE_PREFIX_HOOK();
3740
3741 /* NOTE: For multi-context simulation environments the "instruction"
3742 variable should be local to this routine. */
3743
3744 /* Shorthand accesses for engine. Note: If we wanted to use global
3745 variables (and a single-threaded simulator engine), then we can
3746 create the actual variables with these names. */
3747
3748 if (!(STATE & simSKIPNEXT)) {
3749 /* Include the simulator engine */
3750 #include "oengine.c"
3751 #if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
3752 #error "Mismatch between run-time simulator code and simulation engine"
3753 #endif
3754 #if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
3755 #error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
3756 #endif
3757 #if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
3758 #error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
3759 #endif
3760
3761 /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
3762 should check for it being changed. It is better doing it here,
3763 than within the simulator, since it will help keep the simulator
3764 small. */
3765 if (ZERO != 0) {
3766 #if defined(WARN_ZERO)
3767 sim_io_eprintf(sd,"The ZERO register has been updated with 0x%s (PC = 0x%s) (reset back to zero)\n",pr_addr(ZERO),pr_addr(cia));
3768 #endif /* WARN_ZERO */
3769 ZERO = 0; /* reset back to zero before next instruction */
3770 }
3771 } else /* simSKIPNEXT check */
3772 STATE &= ~simSKIPNEXT;
3773
3774 /* If the delay slot was active before the instruction is
3775 executed, then update the PC to its new value: */
3776 if (DSSTATE) {
3777 #ifdef DEBUG
3778 printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC));
3779 #endif /* DEBUG */
3780 PC = DSPC;
3781 CANCELDELAYSLOT();
3782 }
3783
3784 if (MIPSISA < 4)
3785 PENDING_TICK();
3786
3787 #if !defined(FASTSIM)
3788 if (sim_events_tickn (sd, pipeline_count))
3789 {
3790 /* cpu->cia = cia; */
3791 sim_events_process (sd);
3792 }
3793 #else
3794 if (sim_events_tick (sd))
3795 {
3796 /* cpu->cia = cia; */
3797 sim_events_process (sd);
3798 }
3799 #endif /* FASTSIM */
3800 }
3801 }
3802 #endif
3803
3804
3805 /* This code copied from gdb's utils.c. Would like to share this code,
3806 but don't know of a common place where both could get to it. */
3807
3808 /* Temporary storage using circular buffer */
3809 #define NUMCELLS 16
3810 #define CELLSIZE 32
3811 static char*
3812 get_cell()
3813 {
3814 static char buf[NUMCELLS][CELLSIZE];
3815 static int cell=0;
3816 if (++cell>=NUMCELLS) cell=0;
3817 return buf[cell];
3818 }
3819
3820 /* Print routines to handle variable size regs, etc */
3821
3822 /* Eliminate warning from compiler on 32-bit systems */
3823 static int thirty_two = 32;
3824
3825 char*
3826 pr_addr(addr)
3827 SIM_ADDR addr;
3828 {
3829 char *paddr_str=get_cell();
3830 switch (sizeof(addr))
3831 {
3832 case 8:
3833 sprintf(paddr_str,"%08lx%08lx",
3834 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
3835 break;
3836 case 4:
3837 sprintf(paddr_str,"%08lx",(unsigned long)addr);
3838 break;
3839 case 2:
3840 sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
3841 break;
3842 default:
3843 sprintf(paddr_str,"%x",addr);
3844 }
3845 return paddr_str;
3846 }
3847
3848 char*
3849 pr_uword64(addr)
3850 uword64 addr;
3851 {
3852 char *paddr_str=get_cell();
3853 sprintf(paddr_str,"%08lx%08lx",
3854 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
3855 return paddr_str;
3856 }
3857
3858
3859
3860 /*---------------------------------------------------------------------------*/
3861 /*> EOF interp.c <*/
This page took 0.142246 seconds and 5 git commands to generate.