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