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