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