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