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