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