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