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