2002-05-01 Chris Demetriou <cgd@broadcom.com>
[deliverable/binutils-gdb.git] / sim / mips / sim-main.h
index 9f15093a091c94e1d3841cc9968b114d247e5d0a..4373c008794cf1cb61cb0fdc40bbc6bf466d4592 100644 (file)
@@ -1,5 +1,5 @@
 /* MIPS Simulator definition.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
 This file is part of GDB, the GNU debugger.
@@ -32,18 +32,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define WITH_WATCHPOINTS 1
 #define WITH_MODULO_MEMORY 1
 
+
+#define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
+mips_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR))
+
 #include "sim-basics.h"
 
 typedef address_word sim_cia;
 
-#if (WITH_IGEN)
-/* Get the number of instructions.  FIXME: must be a more elegant way
-   of doing this.  */
-#include "itable.h"
-#define MAX_INSNS (nr_itable_entries)
-#define INSN_NAME(i) itable[(i)].name
-#endif
-
 #include "sim-base.h"
 
 
@@ -60,15 +56,6 @@ typedef unsigned64 uword64;
 #define WORD64(h,l)     ((word64)((SET64HI(h)|SET64LO(l))))
 #define UWORD64(h,l)     (SET64HI(h)|SET64LO(l))
 
-/* Sign-extend the given value (e) as a value (b) bits long. We cannot
-   assume the HI32bits of the operand are zero, so we must perform a
-   mask to ensure we can use the simple subtraction to sign-extend. */
-#define SIGNEXTEND(e,b) \
- ((unsigned_word) \
-  (((e) & ((uword64) 1 << ((b) - 1))) \
-   ? (((e) & (((uword64) 1 << (b)) - 1)) - ((uword64)1 << (b))) \
-   : ((e) & (((((uword64) 1 << ((b) - 1)) - 1) << 1) | 1))))
-
 /* Check if a value will fit within a halfword: */
 #define NOTHALFWORDVALUE(v) ((((((uword64)(v)>>16) == 0) && !((v) & ((unsigned)1 << 15))) || (((((uword64)(v)>>32) == 0xFFFFFFFF) && ((((uword64)(v)>>16) & 0xFFFF) == 0xFFFF)) && ((v) & ((unsigned)1 << 15)))) ? (1 == 0) : (1 == 1))
 
@@ -90,7 +77,7 @@ typedef enum {
  fmt_unknown       = 0x10000000,
  fmt_uninterpreted = 0x20000000,
  fmt_uninterpreted_32 = 0x40000000,
- fmt_uninterpreted_64 = 0x80000000,
+ fmt_uninterpreted_64 = 0x80000000U,
 } FP_formats;
 
 unsigned64 value_fpr PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int fpr, FP_formats));
@@ -111,6 +98,8 @@ unsigned64 Multiply PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
 unsigned64 Divide PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
 unsigned64 Recip PARAMS ((unsigned64 op, FP_formats fmt));
 unsigned64 SquareRoot PARAMS ((unsigned64 op, FP_formats fmt));
+unsigned64 Max PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Min PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
 unsigned64 convert PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int rm, unsigned64 op, FP_formats from, FP_formats to));
 #define Convert(rm,op,from,to) \
 convert (SD, CPU, cia, rm, op, from, to)
@@ -124,17 +113,19 @@ convert (SD, CPU, cia, rm, op, from, to)
   int bit = ((cc == 0) ? 23 : (24 + (cc)));\
   FCSR = ((FCSR & ~(1 << bit)) | ((v) << bit));\
 }
-#define GETFCC(cc) (((((cc) == 0) ? (FCSR & (1 << 23)) : (FCSR & (1 << (24 + (cc))))) != 0) ? 1 : 0)
+#define GETFCC(cc) (((((cc) == 0) ? (FCSR & (1 << 23)) : (FCSR & (1 << (24 + (cc))))) != 0) ? 1U : 0)
 
 /* This should be the COC1 value at the start of the preceding
    instruction: */
 #define PREVCOC1() ((STATE & simPCOC1) ? 1 : 0)
 
-#if 1
-#define SizeFGR() (WITH_TARGET_WORD_BITSIZE)
+#ifdef TARGET_ENABLE_FR
+/* FIXME: this should be enabled for all targets, but needs testing first. */
+#define SizeFGR() (((WITH_TARGET_FLOATING_POINT_BITSIZE) == 64) \
+   ? ((SR & status_FR) ? 64 : 32) \
+   : (WITH_TARGET_FLOATING_POINT_BITSIZE))
 #else
-/* They depend on the CPU being simulated */
-#define SizeFGR() ((WITH_TARGET_WORD_BITSIZE == 64 && ((SR & status_FR) == 1)) ? 64 : 32)
+#define SizeFGR() (WITH_TARGET_FLOATING_POINT_BITSIZE)
 #endif
 
 /* Standard FCRS bits: */
@@ -168,120 +159,49 @@ convert (SD, CPU, cia, rm, op, from, to)
 
 
 
-/* Integer ALU operations: */
 
-#include "sim-alu.h"
 
-#define ALU32_END(ANS) \
-  if (ALU32_HAD_OVERFLOW) \
-    SignalExceptionIntegerOverflow (); \
-  (ANS) = ALU32_OVERFLOW_RESULT
 
+/* HI/LO register accesses */
 
-#define ALU64_END(ANS) \
-  if (ALU64_HAD_OVERFLOW) \
-    SignalExceptionIntegerOverflow (); \
-  (ANS) = ALU64_OVERFLOW_RESULT;
+/* For some MIPS targets, the HI/LO registers have certain timing
+   restrictions in that, for instance, a read of a HI register must be
+   separated by at least three instructions from a preceeding read.
 
-/* start-sanitize-r5900 */
-
-#define BYTES_IN_MMI_REGS       (sizeof(signed_word) + sizeof(signed_word))
-#define HALFWORDS_IN_MMI_REGS   (BYTES_IN_MMI_REGS/2)
-#define WORDS_IN_MMI_REGS       (BYTES_IN_MMI_REGS/4)
-#define DOUBLEWORDS_IN_MMI_REGS (BYTES_IN_MMI_REGS/8)
-
-#define BYTES_IN_MIPS_REGS       (sizeof(signed_word))
-#define HALFWORDS_IN_MIPS_REGS   (BYTES_IN_MIPS_REGS/2)
-#define WORDS_IN_MIPS_REGS       (BYTES_IN_MIPS_REGS/4)
-#define DOUBLEWORDS_IN_MIPS_REGS (BYTES_IN_MIPS_REGS/8)
-
-/* SUB_REG_FETCH - return as lvalue some sub-part of a "register"
-   T  - type of the sub part
-   TC - # of T's in the mips part of the "register"
-   I  - index (from 0) of desired sub part
-   A  - low part of "register"
-   A1 - high part of register
-*/
-#define SUB_REG_FETCH(T,TC,A,A1,I) \
-(*(((I) < (TC) ? (T*)(A) : (T*)(A1)) \
-   + (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN \
-      ? ((TC) - 1 - (I) % (TC)) \
-      : ((I) % (TC)) \
-      ) \
-   ) \
- )
-
-/* 
-GPR_<type>(R,I) - return, as lvalue, the I'th <type> of general register R 
-            where <type> has two letters:
-                  1 is S=signed or U=unsigned
-                  2 is B=byte H=halfword W=word D=doubleword 
-*/
-
-#define SUB_REG_SB(A,A1,I) SUB_REG_FETCH(signed8,  BYTES_IN_MIPS_REGS,       A, A1, I)
-#define SUB_REG_SH(A,A1,I) SUB_REG_FETCH(signed16, HALFWORDS_IN_MIPS_REGS,   A, A1, I)
-#define SUB_REG_SW(A,A1,I) SUB_REG_FETCH(signed32, WORDS_IN_MIPS_REGS,       A, A1, I)
-#define SUB_REG_SD(A,A1,I) SUB_REG_FETCH(signed64, DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
-
-#define SUB_REG_UB(A,A1,I) SUB_REG_FETCH(unsigned8,  BYTES_IN_MIPS_REGS,       A, A1, I)
-#define SUB_REG_UH(A,A1,I) SUB_REG_FETCH(unsigned16, HALFWORDS_IN_MIPS_REGS,   A, A1, I)
-#define SUB_REG_UW(A,A1,I) SUB_REG_FETCH(unsigned32, WORDS_IN_MIPS_REGS,       A, A1, I)
-#define SUB_REG_UD(A,A1,I) SUB_REG_FETCH(unsigned64, DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
-  
-#define GPR_SB(R,I) SUB_REG_SB(&REGISTERS[R], &REGISTERS1[R], I)
-#define GPR_SH(R,I) SUB_REG_SH(&REGISTERS[R], &REGISTERS1[R], I)
-#define GPR_SW(R,I) SUB_REG_SW(&REGISTERS[R], &REGISTERS1[R], I)
-#define GPR_SD(R,I) SUB_REG_SD(&REGISTERS[R], &REGISTERS1[R], I)
+   The struct below is used to record the last access by each of A MT,
+   MF or other OP instruction to a HI/LO register.  See mips.igen for
+   more details. */
 
-#define GPR_UB(R,I) SUB_REG_UB(&REGISTERS[R], &REGISTERS1[R], I)
-#define GPR_UH(R,I) SUB_REG_UH(&REGISTERS[R], &REGISTERS1[R], I)
-#define GPR_UW(R,I) SUB_REG_UW(&REGISTERS[R], &REGISTERS1[R], I)
-#define GPR_UD(R,I) SUB_REG_UD(&REGISTERS[R], &REGISTERS1[R], I)
+typedef struct _hilo_access {
+  signed64 timestamp;
+  address_word cia;
+} hilo_access;
 
+typedef struct _hilo_history {
+  hilo_access mt;
+  hilo_access mf;
+  hilo_access op;
+} hilo_history;
 
-#define RS_SB(I) SUB_REG_SB(&rs_reg, &rs_reg1, I)
-#define RS_SH(I) SUB_REG_SH(&rs_reg, &rs_reg1, I)
-#define RS_SW(I) SUB_REG_SW(&rs_reg, &rs_reg1, I)
-#define RS_SD(I) SUB_REG_SD(&rs_reg, &rs_reg1, I)
 
-#define RS_UB(I) SUB_REG_UB(&rs_reg, &rs_reg1, I)
-#define RS_UH(I) SUB_REG_UH(&rs_reg, &rs_reg1, I)
-#define RS_UW(I) SUB_REG_UW(&rs_reg, &rs_reg1, I)
-#define RS_UD(I) SUB_REG_UD(&rs_reg, &rs_reg1, I)
 
-#define RT_SB(I) SUB_REG_SB(&rt_reg, &rt_reg1, I)
-#define RT_SH(I) SUB_REG_SH(&rt_reg, &rt_reg1, I)
-#define RT_SW(I) SUB_REG_SW(&rt_reg, &rt_reg1, I)
-#define RT_SD(I) SUB_REG_SD(&rt_reg, &rt_reg1, I)
-
-#define RT_UB(I) SUB_REG_UB(&rt_reg, &rt_reg1, I)
-#define RT_UH(I) SUB_REG_UH(&rt_reg, &rt_reg1, I)
-#define RT_UW(I) SUB_REG_UW(&rt_reg, &rt_reg1, I)
-#define RT_UD(I) SUB_REG_UD(&rt_reg, &rt_reg1, I)
 
+/* Integer ALU operations: */
 
+#include "sim-alu.h"
 
-#define LO_SB(I) SUB_REG_SB(&LO, &LO1, I)
-#define LO_SH(I) SUB_REG_SH(&LO, &LO1, I)
-#define LO_SW(I) SUB_REG_SW(&LO, &LO1, I)
-#define LO_SD(I) SUB_REG_SD(&LO, &LO1, I)
+#define ALU32_END(ANS) \
+  if (ALU32_HAD_OVERFLOW) \
+    SignalExceptionIntegerOverflow (); \
+  (ANS) = (signed32) ALU32_OVERFLOW_RESULT
 
-#define LO_UB(I) SUB_REG_UB(&LO, &LO1, I)
-#define LO_UH(I) SUB_REG_UH(&LO, &LO1, I)
-#define LO_UW(I) SUB_REG_UW(&LO, &LO1, I)
-#define LO_UD(I) SUB_REG_UD(&LO, &LO1, I)
 
-#define HI_SB(I) SUB_REG_SB(&HI, &HI1, I)
-#define HI_SH(I) SUB_REG_SH(&HI, &HI1, I)
-#define HI_SW(I) SUB_REG_SW(&HI, &HI1, I)
-#define HI_SD(I) SUB_REG_SD(&HI, &HI1, I)
+#define ALU64_END(ANS) \
+  if (ALU64_HAD_OVERFLOW) \
+    SignalExceptionIntegerOverflow (); \
+  (ANS) = ALU64_OVERFLOW_RESULT;
 
-#define HI_UB(I) SUB_REG_UB(&HI, &HI1, I)
-#define HI_UH(I) SUB_REG_UH(&HI, &HI1, I)
-#define HI_UW(I) SUB_REG_UW(&HI, &HI1, I)
-#define HI_UD(I) SUB_REG_UD(&HI, &HI1, I)
 
-/* end-sanitize-r5900 */
 
 
 
@@ -311,7 +231,7 @@ typedef struct _pending_write_queue {
 #define PENDING_OUT ((CPU)->pending.out)
 #define PENDING_TOTAL ((CPU)->pending.total)
 #define PENDING_SLOT_SIZE ((CPU)->pending.slot_size)
-#define PENDING_SLOT_BIT ((CPU)->pending.slot_size)
+#define PENDING_SLOT_BIT ((CPU)->pending.slot_bit)
 #define PENDING_SLOT_DELAY ((CPU)->pending.slot_delay)
 #define PENDING_SLOT_DEST ((CPU)->pending.slot_dest)
 #define PENDING_SLOT_VALUE ((CPU)->pending.slot_value)
@@ -334,12 +254,17 @@ memset (&(CPU)->pending, 0, sizeof ((CPU)->pending))
       sim_engine_abort (SD, CPU, cia,                                  \
                        "PENDING_SCHED - buffer overflow\n");           \
     if (PENDING_TRACE)                                                 \
-      sim_io_printf (SD, "PENDING_SCHED - dest 0x%lx, val 0x%lx, pending_in %d, pending_out %d, pending_total %d\n", (unsigned long) (DEST), (unsigned long) (VAL), PENDING_IN, PENDING_OUT, PENDING_TOTAL); \
+      sim_io_eprintf (SD, "PENDING_SCHED - 0x%lx - dest 0x%lx, val 0x%lx, bit %d, size %d, pending_in %d, pending_out %d, pending_total %d\n",                 \
+                     (unsigned long) cia, (unsigned long) &(DEST),     \
+                     (unsigned long) (VAL), (BIT), (int) sizeof (DEST),\
+                     PENDING_IN, PENDING_OUT, PENDING_TOTAL);          \
     PENDING_SLOT_DELAY[PENDING_IN] = (DELAY) + 1;                      \
     PENDING_SLOT_DEST[PENDING_IN] = &(DEST);                           \
     PENDING_SLOT_VALUE[PENDING_IN] = (VAL);                            \
     PENDING_SLOT_SIZE[PENDING_IN] = sizeof (DEST);                     \
     PENDING_SLOT_BIT[PENDING_IN] = (BIT);                              \
+    PENDING_IN = (PENDING_IN + 1) % PSLOTS;                             \
+    PENDING_TOTAL += 1;                                                        \
   } while (0)
 
 #define PENDING_WRITE(DEST,VAL,DELAY) PENDING_SCHED(DEST,VAL,DELAY,-1)
@@ -352,14 +277,24 @@ memset (&(CPU)->pending, 0, sizeof ((CPU)->pending))
 
 /* For backward compatibility */
 #define PENDING_FILL(R,VAL)                                            \
-{                                                                      \
+do {                                                                   \
   if ((R) >= FGRIDX && (R) < FGRIDX + NR_FGR)                          \
-    PENDING_SCHED(FGR[(R) - FGRIDX], VAL, 2, -1);                      \
+    {                                                                  \
+      PENDING_SCHED(FGR[(R) - FGRIDX], VAL, 1, -1);                    \
+      PENDING_SCHED(FPR_STATE[(R) - FGRIDX], fmt_uninterpreted, 1, -1);        \
+    }                                                                  \
   else                                                                 \
-    PENDING_SCHED(GPR[(R)], VAL, 2, -1);                               \
-}
+    PENDING_SCHED(GPR[(R)], VAL, 1, -1);                               \
+} while (0)
 
 
+enum float_operation
+  {
+    FLOP_ADD,    FLOP_SUB,    FLOP_MUL,    FLOP_MADD,
+    FLOP_MSUB,   FLOP_MAX=10, FLOP_MIN,    FLOP_ABS,
+    FLOP_ITOF0=14, FLOP_FTOI0=18, FLOP_NEG=23
+  };
+
 
 struct _sim_cpu {
 
@@ -370,27 +305,8 @@ struct _sim_cpu {
   address_word dspc;  /* delay-slot PC */
 #define DSPC ((CPU)->dspc)
 
-  /* Issue a delay slot instruction immediatly by re-calling
-     idecode_issue */
-#define DELAY_SLOT(TARGET) \
-  do { \
-    address_word target = (TARGET); \
-    instruction_word delay_insn; \
-    sim_events_slip (SD, 1); \
-    CIA = CIA + 4; \
-    STATE |= simDELAYSLOT; \
-    delay_insn = IMEM (CIA); \
-    idecode_issue (CPU_, delay_insn, (CIA)); \
-    STATE &= ~simDELAYSLOT; \
-    NIA = target; \
-  } while (0)
-#define NULLIFY_NEXT_INSTRUCTION() \
-  do { \
-    sim_events_slip (SD, 1); \
-    dotrace (SD, CPU, tracefh, 2, NIA, 4, "load instruction"); \
-    NIA = CIA + 8; \
-  } while (0)
-
+#define DELAY_SLOT(TARGET) NIA = delayslot32 (SD_, (TARGET))
+#define NULLIFY_NEXT_INSTRUCTION() NIA = nullify_next_insn32 (SD_)
 
 
   /* State of the simulator */
@@ -410,6 +326,7 @@ struct _sim_cpu {
 #define simSIGINT      (1 << 28)  /* 0 = do nothing; 1 = SIGINT has occured */
 #define simJALDELAYSLOT        (1 << 29) /* 1 = in jal delay slot */
 
+#ifndef ENGINE_ISSUE_PREFIX_HOOK
 #define ENGINE_ISSUE_PREFIX_HOOK() \
   { \
     /* Perform any pending writes */ \
@@ -425,6 +342,7 @@ struct _sim_cpu {
     else \
      STATE &= ~simPCOC0; \
   }
+#endif /* ENGINE_ISSUE_PREFIX_HOOK */
 
 
 /* This is nasty, since we have to rely on matching the register
@@ -437,25 +355,32 @@ struct _sim_cpu {
 #ifndef TM_MIPS_H
 #define LAST_EMBED_REGNUM (89)
 #define NUM_REGS (LAST_EMBED_REGNUM + 1)
-/* start-sanitize-r5900 */
-#undef NUM_REGS
-#define NUM_REGS (128)
-/* end-sanitize-r5900 */
+
+
 #endif
 
+
 /* To keep this default simulator simple, and fast, we use a direct
    vector of registers. The internal simulator engine then uses
    manifests to access the correct slot. */
 
   unsigned_word registers[LAST_EMBED_REGNUM + 1];
+
   int register_widths[NUM_REGS];
 #define REGISTERS       ((CPU)->registers)
 
 #define GPR     (&REGISTERS[0])
 #define GPR_SET(N,VAL) (REGISTERS[(N)] = (VAL))
+
+  /* While space is allocated for the floating point registers in the
+     main registers array, they are stored separatly.  This is because
+     their size may not necessarily match the size of either the
+     general-purpose or system specific registers */
 #define NR_FGR  (32)
 #define FGRIDX  (38)
-#define FGR     (&REGISTERS[FGRIDX])
+  fp_word fgr[NR_FGR];
+#define FGR     ((CPU)->fgr)
+
 #define LO      (REGISTERS[33])
 #define HI      (REGISTERS[34])
 #define PCIDX  37
@@ -471,7 +396,16 @@ struct _sim_cpu {
 #define Debug  (REGISTERS[86])
 #define DEPC   (REGISTERS[87])
 #define EPC    (REGISTERS[88])
-#define COCIDX  (LAST_EMBED_REGNUM + 2) /* special case : outside the normal range */
+
+  /* All internal state modified by signal_exception() that may need to be
+     rolled back for passing moment-of-exception image back to gdb. */
+  unsigned_word exc_trigger_registers[LAST_EMBED_REGNUM + 1];
+  unsigned_word exc_suspend_registers[LAST_EMBED_REGNUM + 1];
+  int exc_suspended;
+
+#define SIM_CPU_EXCEPTION_TRIGGER(SD,CPU,CIA) mips_cpu_exception_trigger(SD,CPU,CIA)
+#define SIM_CPU_EXCEPTION_SUSPEND(SD,CPU,EXC) mips_cpu_exception_suspend(SD,CPU,EXC)
+#define SIM_CPU_EXCEPTION_RESUME(SD,CPU,EXC) mips_cpu_exception_resume(SD,CPU,EXC)
 
   unsigned_word c0_config_reg;
 #define C0_CONFIG ((CPU)->c0_config_reg)
@@ -483,8 +417,21 @@ struct _sim_cpu {
 #define A1      (REGISTERS[5])
 #define A2      (REGISTERS[6])
 #define A3      (REGISTERS[7])
-#define SP      (REGISTERS[29])
-#define RA      (REGISTERS[31])
+#define T8IDX   24
+#define T8     (REGISTERS[T8IDX])
+#define SPIDX   29
+#define SP      (REGISTERS[SPIDX])
+#define RAIDX   31
+#define RA      (REGISTERS[RAIDX])
+
+  /* While space is allocated in the main registers arrray for some of
+     the COP0 registers, that space isn't sufficient.  Unknown COP0
+     registers overflow into the array below */
+
+#define NR_COP0_GPR    32
+  unsigned_word cop0_gpr[NR_COP0_GPR];
+#define COP0_GPR       ((CPU)->cop0_gpr)
+#define COP0_BADVADDR ((unsigned32)(COP0_GPR[8]))
 
   /* Keep the current format state for each register: */
   FP_formats fpr_state[32];
@@ -502,73 +449,19 @@ struct _sim_cpu {
 #define LLBIT ((CPU)->llbit)
 
 
-/* The HIACCESS and LOACCESS counts are used to ensure that
-   corruptions caused by using the HI or LO register to close to a
-   following operation are spotted. */
-
-  int hiaccess;
-  int loaccess;
-#define HIACCESS ((CPU)->hiaccess)
-#define LOACCESS ((CPU)->loaccess)
-  /* start-sanitize-r5900 */
-  int hi1access;
-  int lo1access;
-#define HI1ACCESS ((CPU)->hi1access)
-#define LO1ACCESS ((CPU)->lo1access)
-  /* end-sanitize-r5900 */
-#if 1
-  /* The 4300 and a few other processors have interlocks on hi/lo
-     register reads, and hence do not have this problem.  To avoid
-     spurious warnings, we just disable this always.  */
-#define CHECKHILO(s)
-#else
-  unsigned_word HLPC;
-  /* If either of the preceding two instructions have accessed the HI
-     or LO registers, then the values they see should be
-     undefined. However, to keep the simulator world simple, we just
-     let them use the value read and raise a warning to notify the
-     user: */
-#define CHECKHILO(s) {\
-  if ((HIACCESS != 0) || (LOACCESS != 0)) \
-    sim_io_eprintf(sd,"%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\
-}
-  /* start-sanitize-r5900 */
-#undef CHECKHILO
-#define CHECKHILO(s) {\
-  if ((HIACCESS != 0) || (LOACCESS != 0) || (HI1ACCESS != 0) || (LO1ACCESS != 0))\
-    sim_io_eprintf(sd,"%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\
-}
-  /* end-sanitize-r5900 */
-#endif
-
-
-  /* start-sanitize-r5900 */
-  /* The R5900 has 128 bit registers, but the hi 64 bits are only
-     touched by multimedia (MMI) instructions.  The normal mips
-     instructions just use the lower 64 bits.  To avoid changing the
-     older parts of the simulator to handle this weirdness, the high
-     64 bits of each register are kept in a separate array
-     (registers1).  The high 64 bits of any register are by convention
-     refered by adding a '1' to the end of the normal register's name.
-     So LO still refers to the low 64 bits of the LO register, LO1
-     refers to the high 64 bits of that same register.  */
+/* The HIHISTORY and LOHISTORY timestamps are used to ensure that
+   corruptions caused by using the HI or LO register too close to a
+   following operation is spotted. See mips.igen for more details. */
 
-  signed_word registers1[LAST_EMBED_REGNUM + 1];
-#define REGISTERS1 ((CPU)->registers1)
-#define GPR1     (&REGISTERS1[0])
-#define LO1      (REGISTERS1[32])
-#define HI1      (REGISTERS1[33])
-#define REGISTER_SA    (124)
+  hilo_history hi_history;
+#define HIHISTORY (&(CPU)->hi_history)
+  hilo_history lo_history;
+#define LOHISTORY (&(CPU)->lo_history)
 
-  unsigned_word sa;        /* the shift amount register */
-#define SA ((CPU)->sa)
+#define check_branch_bug() 
+#define mark_branch_bug(TARGET) 
 
-  /* end-sanitize-r5900 */
-  /* start-sanitize-vr5400 */
 
-  /* The MDMX ISA has a very very large accumulator */
-  unsigned8 acc[3 * 8];
-  /* end-sanitize-vr5400 */
 
   sim_cpu_base base;
 };
@@ -597,6 +490,7 @@ struct sim_state {
 #define STATE_CPU(sd,n) (&(sd)->cpu[0])
 #endif
 
+
   sim_state_base base;
 };
 
@@ -607,14 +501,17 @@ struct sim_state {
 /* TODO : these should be the bitmasks for these bits within the
    status register. At the moment the following are VR4300
    bit-positions: */
-#define status_KSU_mask  (0x3)          /* mask for KSU bits */
+#define status_KSU_mask  (0x18)         /* mask for KSU bits */
 #define status_KSU_shift (3)            /* shift for field */
 #define ksu_kernel       (0x0)
 #define ksu_supervisor   (0x1)
 #define ksu_user         (0x2)
 #define ksu_unknown      (0x3)
 
+#define SR_KSU          ((SR & status_KSU_mask) >> status_KSU_shift)
+
 #define status_IE       (1 <<  0)      /* Interrupt enable */
+#define status_EIE      (1 << 16)      /* Enable Interrupt Enable */
 #define status_EXL      (1 <<  1)      /* Exception level */
 #define status_RE        (1 << 25)      /* Reverse Endian in user mode */
 #define status_FR        (1 << 26)      /* enables MIPS III additional FP registers */
@@ -622,9 +519,55 @@ struct sim_state {
 #define status_BEV       (1 << 22)      /* Location of general exception vectors */
 #define status_TS        (1 << 21)      /* TLB shutdown has occurred */
 #define status_ERL       (1 <<  2)      /* Error level */
+#define status_IM7       (1 << 15)      /* Timer Interrupt Mask */
 #define status_RP        (1 << 27)      /* Reduced Power mode */
 
-#define cause_BD        ((unsigned)1 << 31)     /* Exception in branch delay slot */
+/* Specializations for TX39 family */
+#define status_IEc       (1 << 0)       /* Interrupt enable (current) */
+#define status_KUc       (1 << 1)       /* Kernel/User mode */
+#define status_IEp       (1 << 2)       /* Interrupt enable (previous) */
+#define status_KUp       (1 << 3)       /* Kernel/User mode */
+#define status_IEo       (1 << 4)       /* Interrupt enable (old) */
+#define status_KUo       (1 << 5)       /* Kernel/User mode */
+#define status_IM_mask   (0xff)         /* Interrupt mask */
+#define status_IM_shift  (8)
+#define status_NMI       (1 << 20)      /* NMI */
+#define status_NMI       (1 << 20)      /* NMI */
+
+/* Status bits used by MIPS32/MIPS64.  */
+#define status_UX        (1 <<  5)      /* 64-bit user addrs */
+#define status_SX        (1 <<  6)      /* 64-bit supervisor addrs */
+#define status_KX        (1 <<  7)      /* 64-bit kernel addrs */
+#define status_TS        (1 << 21)      /* TLB shutdown has occurred */
+#define status_PX        (1 << 23)      /* Enable 64 bit operations */
+#define status_MX        (1 << 24)      /* Enable MDMX resources */
+#define status_CU0       (1 << 28)      /* Coprocessor 0 usable */
+#define status_CU1       (1 << 29)      /* Coprocessor 1 usable */
+#define status_CU2       (1 << 30)      /* Coprocessor 2 usable */
+#define status_CU3       (1 << 31)      /* Coprocessor 3 usable */
+
+#define cause_BD ((unsigned)1 << 31)    /* L1 Exception in branch delay slot */
+#define cause_BD2         (1 << 30)     /* L2 Exception in branch delay slot */
+#define cause_CE_mask     0x30000000   /* Coprocessor exception */
+#define cause_CE_shift    28
+#define cause_EXC2_mask   0x00070000
+#define cause_EXC2_shift  16
+#define cause_IP7        (1 << 15)     /* Interrupt pending */
+#define cause_SIOP        (1 << 12)     /* SIO pending */
+#define cause_IP3        (1 << 11)     /* Int 0 pending */
+#define cause_IP2        (1 << 10)     /* Int 1 pending */
+
+#define cause_EXC_mask  (0x1c)          /* Exception code */
+#define cause_EXC_shift (2)
+
+#define cause_SW0       (1 << 8)        /* Software interrupt 0 */
+#define cause_SW1       (1 << 9)        /* Software interrupt 1 */
+#define cause_IP_mask   (0x3f)          /* Interrupt pending field */
+#define cause_IP_shift  (10)
+
+#define cause_set_EXC(x)  CAUSE = (CAUSE & ~cause_EXC_mask)  | ((x << cause_EXC_shift)  & cause_EXC_mask)
+#define cause_set_EXC2(x) CAUSE = (CAUSE & ~cause_EXC2_mask) | ((x << cause_EXC2_shift) & cause_EXC2_mask)
+
 
 /* NOTE: We keep the following status flags as bit values (1 for true,
    0 for false). This allows them to be used in binary boolean
@@ -632,7 +575,11 @@ struct sim_state {
    value is. */
 
 /* UserMode */
-#define UserMode        ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0)
+#ifdef SUBTARGET_R3900
+#define UserMode        ((SR & status_KUc) ? 1 : 0)
+#else
+#define UserMode       ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0)
+#endif /* SUBTARGET_R3900 */
 
 /* BigEndianMem */
 /* Hardware configuration. Affects endianness of LoadMemory and
@@ -660,43 +607,84 @@ struct sim_state {
 
 /* NOTE: These numbers depend on the processor architecture being
    simulated: */
-#define Interrupt               (0)
-#define TLBModification         (1)
-#define TLBLoad                 (2)
-#define TLBStore                (3)
-#define AddressLoad             (4)
-#define AddressStore            (5)
-#define InstructionFetch        (6)
-#define DataReference           (7)
-#define SystemCall              (8)
-#define BreakPoint              (9)
-#define ReservedInstruction     (10)
-#define CoProcessorUnusable     (11)
-#define IntegerOverflow         (12)    /* Arithmetic overflow (IDT monitor raises SIGFPE) */
-#define Trap                    (13)
-#define FPE                     (15)
-#define DebugBreakPoint         (16)
-#define Watch                   (23)
+enum ExceptionCause {
+  Interrupt               = 0,
+  TLBModification         = 1,
+  TLBLoad                 = 2,
+  TLBStore                = 3,
+  AddressLoad             = 4,
+  AddressStore            = 5,
+  InstructionFetch        = 6,
+  DataReference           = 7,
+  SystemCall              = 8,
+  BreakPoint              = 9,
+  ReservedInstruction     = 10,
+  CoProcessorUnusable     = 11,
+  IntegerOverflow         = 12,    /* Arithmetic overflow (IDT monitor raises SIGFPE) */
+  Trap                    = 13,
+  FPE                     = 15,
+  DebugBreakPoint         = 16,    /* Impl. dep. in MIPS32/MIPS64.  */
+  MDMX                    = 22,
+  Watch                   = 23,
+  MCheck                  = 24,
+  CacheErr                = 30,
+  NMIReset                = 31,    /* Reserved in MIPS32/MIPS64.  */
+
 
 /* The following exception code is actually private to the simulator
    world. It is *NOT* a processor feature, and is used to signal
    run-time errors in the simulator. */
-#define SimulatorFault      (0xFFFFFFFF)
+  SimulatorFault         = 0xFFFFFFFF
+};
+
+#define TLB_REFILL  (0)
+#define TLB_INVALID (1)
+
+
+/* The following break instructions are reserved for use by the
+   simulator.  The first is used to halt the simulation.  The second
+   is used by gdb for break-points.  NOTE: Care must be taken, since 
+   this value may be used in later revisions of the MIPS ISA. */
+#define HALT_INSTRUCTION_MASK   (0x03FFFFC0)
+
+#define HALT_INSTRUCTION        (0x03ff000d)
+#define HALT_INSTRUCTION2       (0x0000ffcd)
+
+
+#define BREAKPOINT_INSTRUCTION  (0x0005000d)
+#define BREAKPOINT_INSTRUCTION2 (0x0000014d)
+
+
+
+void interrupt_event (SIM_DESC sd, void *data);
 
 void signal_exception (SIM_DESC sd, sim_cpu *cpu, address_word cia, int exception, ...);
 #define SignalException(exc,instruction)     signal_exception (SD, CPU, cia, (exc), (instruction))
-#define SignalExceptionInterrupt()           signal_exception (SD, CPU, NULL_CIA, Interrupt)
+#define SignalExceptionInterrupt(level)      signal_exception (SD, CPU, cia, Interrupt, level)
 #define SignalExceptionInstructionFetch()    signal_exception (SD, CPU, cia, InstructionFetch)
 #define SignalExceptionAddressStore()        signal_exception (SD, CPU, cia, AddressStore)
 #define SignalExceptionAddressLoad()         signal_exception (SD, CPU, cia, AddressLoad)
+#define SignalExceptionDataReference()       signal_exception (SD, CPU, cia, DataReference)
 #define SignalExceptionSimulatorFault(buf)   signal_exception (SD, CPU, cia, SimulatorFault, buf)
 #define SignalExceptionFPE()                 signal_exception (SD, CPU, cia, FPE)
 #define SignalExceptionIntegerOverflow()     signal_exception (SD, CPU, cia, IntegerOverflow)
-#define SignalExceptionCoProcessorUnusable() signal_exception (SD, CPU, cia, CoProcessorUnusable)
-
+#define SignalExceptionCoProcessorUnusable(cop) signal_exception (SD, CPU, cia, CoProcessorUnusable)
+#define SignalExceptionNMIReset()            signal_exception (SD, CPU, cia, NMIReset)
+#define SignalExceptionTLBRefillStore()      signal_exception (SD, CPU, cia, TLBStore, TLB_REFILL)
+#define SignalExceptionTLBRefillLoad()       signal_exception (SD, CPU, cia, TLBLoad, TLB_REFILL)
+#define SignalExceptionTLBInvalidStore()     signal_exception (SD, CPU, cia, TLBStore, TLB_INVALID)
+#define SignalExceptionTLBInvalidLoad()      signal_exception (SD, CPU, cia, TLBLoad, TLB_INVALID)
+#define SignalExceptionTLBModification()     signal_exception (SD, CPU, cia, TLBModification)
+#define SignalExceptionMDMX()                signal_exception (SD, CPU, cia, MDMX)
+#define SignalExceptionWatch()               signal_exception (SD, CPU, cia, Watch)
+#define SignalExceptionMCheck()              signal_exception (SD, CPU, cia, MCheck)
+#define SignalExceptionCacheErr()            signal_exception (SD, CPU, cia, CacheErr)
 
 /* Co-processor accesses */
 
+/* XXX FIXME: For now, assume that FPU (cp1) is always usable.  */
+#define COP_Usable(coproc_num)         (coproc_num == 1)
+
 void cop_lw  PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg, unsigned int memword));
 void cop_ld  PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg, uword64 memword));
 unsigned int cop_sw PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg));
@@ -711,10 +699,13 @@ cop_sw (SD, CPU, cia, coproc_num, coproc_reg)
 #define COP_SD(coproc_num,coproc_reg) \
 cop_sd (SD, CPU, cia, coproc_num, coproc_reg)
 
+
 void decode_coproc PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int instruction));
 #define DecodeCoproc(instruction) \
 decode_coproc (SD, CPU, cia, (instruction))
 
+int sim_monitor (SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int arg);
+  
 
 
 /* Memory accesses */
@@ -750,36 +741,65 @@ decode_coproc (SD, CPU, cia, (instruction))
 #define AccessLength_DOUBLEWORD (7)
 #define AccessLength_QUADWORD   (15)
 
-int address_translation PARAMS ((SIM_DESC sd, sim_cpu *, address_word cia, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int raw));
+#define LOADDRMASK (WITH_TARGET_WORD_BITSIZE == 64 \
+                   ? AccessLength_DOUBLEWORD /*7*/ \
+                   : AccessLength_WORD /*3*/)
+#define PSIZE (WITH_TARGET_ADDRESS_BITSIZE)
+
+
+INLINE_SIM_MAIN (int) address_translation PARAMS ((SIM_DESC sd, sim_cpu *, address_word cia, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int raw));
 #define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \
 address_translation (SD, CPU, cia, vAddr, IorD, LorS, pAddr, CCA, raw)
 
-void load_memory PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, address_word pAddr, address_word vAddr, int IorD));
+INLINE_SIM_MAIN (void) load_memory PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, uword64* memvalp, uword64* memval1p, int CCA, unsigned int AccessLength, address_word pAddr, address_word vAddr, int IorD));
 #define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \
 load_memory (SD, CPU, cia, memvalp, memval1p, CCA, AccessLength, pAddr, vAddr, IorD)
 
-void store_memory PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr));
+INLINE_SIM_MAIN (void) store_memory PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, unsigned int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr));
 #define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \
 store_memory (SD, CPU, cia, CCA, AccessLength, MemElem, MemElem1, pAddr, vAddr)
 
-void cache_op PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int op, address_word pAddr, address_word vAddr, unsigned int instruction));
+INLINE_SIM_MAIN (void) cache_op PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int op, address_word pAddr, address_word vAddr, unsigned int instruction));
 #define CacheOp(op,pAddr,vAddr,instruction) \
 cache_op (SD, CPU, cia, op, pAddr, vAddr, instruction)
 
-void sync_operation PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int stype));
+INLINE_SIM_MAIN (void) sync_operation PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int stype));
 #define SyncOperation(stype) \
 sync_operation (SD, CPU, cia, (stype))
 
-void prefetch PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint));
+INLINE_SIM_MAIN (void) prefetch PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint));
 #define Prefetch(CCA,pAddr,vAddr,DATA,hint) \
 prefetch (SD, CPU, cia, CCA, pAddr, vAddr, DATA, hint)
 
-unsigned32 ifetch32 PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, address_word vaddr));
-#define IMEM(CIA) ifetch32 (SD, CPU, (CIA), (CIA))
+void unpredictable_action (sim_cpu *cpu, address_word cia);
+#define NotWordValue(val)      not_word_value (SD_, (val))
+#define Unpredictable()                unpredictable (SD_)
+
+INLINE_SIM_MAIN (unsigned32) ifetch32 PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, address_word vaddr));
+#define IMEM32(CIA) ifetch32 (SD, CPU, (CIA), (CIA))
+INLINE_SIM_MAIN (unsigned16) ifetch16 PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, address_word vaddr));
+#define IMEM16(CIA) ifetch16 (SD, CPU, (CIA), ((CIA) & ~1))
+#define IMEM16_IMMED(CIA,NR) ifetch16 (SD, CPU, (CIA), ((CIA) & ~1) + 2 * (NR))
 
 void dotrace PARAMS ((SIM_DESC sd, sim_cpu *cpu, FILE *tracefh, int type, SIM_ADDR address, int width, char *comment, ...));
-FILE *tracefh;
+extern FILE *tracefh;
+
+INLINE_SIM_MAIN (void) pending_tick PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia));
+extern SIM_CORE_SIGNAL_FN mips_core_signal;
+
+char* pr_addr PARAMS ((SIM_ADDR addr));
+char* pr_uword64 PARAMS ((uword64 addr));
+
 
-void pending_tick PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia));
+#define GPR_CLEAR(N) do { GPR_SET((N),0); } while (0)
+
+void mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word pc);
+void mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception);
+void mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception);
+
+
+#if H_REVEALS_MODULE_P (SIM_MAIN_INLINE)
+#include "sim-main.c"
+#endif
 
 #endif
This page took 0.033942 seconds and 4 git commands to generate.