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