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