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