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