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