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