OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [mips/] [interp.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.