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