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