2002-05-01 Chris Demetriou <cgd@broadcom.com>
[deliverable/binutils-gdb.git] / sim / mips / sim-main.h
index 594a9f789ad073fde10af80207f2d3963c867a31..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));
@@ -132,11 +119,13 @@ convert (SD, CPU, cia, rm, op, from, to)
    instruction: */
 #define PREVCOC1() ((STATE & simPCOC1) ? 1 : 0)
 
-#if 1
-#define SizeFGR() (WITH_TARGET_FLOATING_POINT_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: */
@@ -170,183 +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
-
-
-#define ALU64_END(ANS) \
-  if (ALU64_HAD_OVERFLOW) \
-    SignalExceptionIntegerOverflow (); \
-  (ANS) = ALU64_OVERFLOW_RESULT;
 
 
-/* start-sanitize-r5900 */
-
-/* Figure 10-5 FPU Control/Status Register.
-   Note: some of these bits are different to what is found in a
-   standard MIPS manual. */
-enum {
-  R5900_FCSR_C = BIT (23), /* OK */
-  R5900_FCSR_I = BIT (17),
-  R5900_FCSR_D = BIT (16),
-  R5900_FCSR_O = BIT (15),
-  R5900_FCSR_U = BIT (14),
-  R5900_FCSR_CAUSE = MASK (16,14),
-  R5900_FCSR_SI = BIT (6),
-  R5900_FCSR_SD = BIT (5),
-  R5900_FCSR_SO = BIT (4),
-  R5900_FCSR_SU = BIT (3),
-};
 
-typedef struct _sim_r5900_cpu {
-
-  /* The R5900 has 32 x 128bit general purpose registers.
-     Fortunatly, the high 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.  */
-  signed_word gpr1[32];
-#define GPR1     ((CPU)->r5900.gpr1)
-  signed_word lo1;
-  signed_word hi1;
-#define LO1      ((CPU)->r5900.lo1)
-#define HI1      ((CPU)->r5900.hi1)
-
-  /* The R5900 defines a shift amount register, that controls the
-     amount of certain shift instructions */
-  unsigned_word sa;        /* the shift amount register */
-#define REGISTER_SA    (124) /* GET RID IF THIS! */
-#define SA ((CPU)->r5900.sa)
-
-  /* The R5900, in addition to the (almost) standard floating point
-     registers, defines a 32 bit accumulator.  This is used in
-     multiply/accumulate style instructions */
-  fp_word acc; /* floating-point accumulator */
-#define ACC ((CPU)->r5900.acc)
-
-  /* See comments below about needing to count cycles between updating
-     and setting HI/LO registers */
-  int hi1access;
-  int lo1access;
-#define HI1ACCESS ((CPU)->r5900.hi1access)
-#define LO1ACCESS ((CPU)->r5900.lo1access)
-#if 0
-#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));\
-}
-#endif
+/* HI/LO register accesses */
 
-} sim_r5900_cpu;
-
-#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(&GPR[R], &GPR1[R], I)
-#define GPR_SH(R,I) SUB_REG_SH(&GPR[R], &GPR1[R], I)
-#define GPR_SW(R,I) SUB_REG_SW(&GPR[R], &GPR1[R], I)
-#define GPR_SD(R,I) SUB_REG_SD(&GPR[R], &GPR1[R], I)
+/* 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.
 
-#define GPR_UB(R,I) SUB_REG_UB(&GPR[R], &GPR1[R], I)
-#define GPR_UH(R,I) SUB_REG_UH(&GPR[R], &GPR1[R], I)
-#define GPR_UW(R,I) SUB_REG_UW(&GPR[R], &GPR1[R], I)
-#define GPR_UD(R,I) SUB_REG_UD(&GPR[R], &GPR1[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. */
 
+typedef struct _hilo_access {
+  signed64 timestamp;
+  address_word cia;
+} hilo_access;
 
-#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)
+typedef struct _hilo_history {
+  hilo_access mt;
+  hilo_access mf;
+  hilo_access op;
+} hilo_history;
 
-#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 */
 
 
 
@@ -376,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)
@@ -399,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)
@@ -417,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 {
 
@@ -435,31 +305,8 @@ struct _sim_cpu {
   address_word dspc;  /* delay-slot PC */
 #define DSPC ((CPU)->dspc)
 
-#if !WITH_IGEN
-  /* 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; /* NOTE not mips16 */ \
-    STATE |= simDELAYSLOT; \
-    delay_insn = IMEM32 (CIA); /* NOTE not mips16 */ \
-    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)
-#else
 #define DELAY_SLOT(TARGET) NIA = delayslot32 (SD_, (TARGET))
 #define NULLIFY_NEXT_INSTRUCTION() NIA = nullify_next_insn32 (SD_)
-#endif
 
 
   /* State of the simulator */
@@ -479,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 */ \
@@ -494,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
@@ -506,36 +355,17 @@ 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
-
-/* start-sanitize-sky */
-#ifdef TARGET_SKY
-#ifndef TM_TXVU_H
-
-/* Number of machine registers */
-#define NUM_VU_REGS    153
-#define NUM_VU_INTEGER_REGS 16
-
-#define NUM_VIF_REGS   25
 
-#define FIRST_VEC_REG  25
-#define NUM_R5900_REGS 128
 
-#undef NUM_REGS
-#define NUM_REGS (NUM_R5900_REGS + 2*(NUM_VU_REGS) + 2*(NUM_VIF_REGS))
-#endif /* no tm-txvu.h */
 #endif
-/* end-sanitize-sky */
+
 
 /* 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)
 
@@ -566,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)
@@ -585,6 +424,15 @@ struct _sim_cpu {
 #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];
 #define FPR_STATE ((CPU)->fpr_state)
@@ -601,44 +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)
-
-#if 0
-  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));\
-}
-#endif
+/* 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. */
 
-#if !defined CHECKHILO
-  /* 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)
-#endif
+  hilo_history hi_history;
+#define HIHISTORY (&(CPU)->hi_history)
+  hilo_history lo_history;
+#define LOHISTORY (&(CPU)->lo_history)
 
-  /* start-sanitize-r5900 */
-  sim_r5900_cpu r5900;
+#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;
 };
@@ -667,6 +490,7 @@ struct sim_state {
 #define STATE_CPU(sd,n) (&(sd)->cpu[0])
 #endif
 
+
   sim_state_base base;
 };
 
@@ -677,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 */
@@ -692,14 +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 */
-/* begin-sanitize-r5900 */
-#define status_CU0       (1 << 28)      /* COP0 usable */
-#define status_CU1       (1 << 29)      /* COP1 usable */
-#define status_CU2       (1 << 30)      /* COP2 usable */
-/* begin-sanitize-r5900 */
 
-#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
@@ -707,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
@@ -735,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));
@@ -786,23 +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)
 
-/* start-sanitize-sky */
-#ifdef TARGET_SKY
-void cop_lq  PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia,
-                     int coproc_num, int coproc_reg, unsigned128 memword));
-unsigned128 cop_sq PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia,
-                           int coproc_num, int coproc_reg));
-#define COP_LQ(coproc_num,coproc_reg,memword) \
-cop_lq (SD, CPU, cia, coproc_num, coproc_reg, memword)
-#define COP_SQ(coproc_num,coproc_reg) \
-cop_sq (SD, CPU, cia, coproc_num, coproc_reg)
-#endif /* TARGET_SKY */
-/* end-sanitize-sky */
 
 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 */
@@ -838,12 +741,10 @@ decode_coproc (SD, CPU, cia, (instruction))
 #define AccessLength_DOUBLEWORD (7)
 #define AccessLength_QUADWORD   (15)
 
-#if (WITH_IGEN)
 #define LOADDRMASK (WITH_TARGET_WORD_BITSIZE == 64 \
                    ? AccessLength_DOUBLEWORD /*7*/ \
                    : AccessLength_WORD /*3*/)
 #define PSIZE (WITH_TARGET_ADDRESS_BITSIZE)
-#endif
 
 
 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));
@@ -870,6 +771,10 @@ INLINE_SIM_MAIN (void) prefetch PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word
 #define Prefetch(CCA,pAddr,vAddr,DATA,hint) \
 prefetch (SD, CPU, cia, CCA, pAddr, vAddr, DATA, hint)
 
+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));
@@ -877,14 +782,22 @@ INLINE_SIM_MAIN (unsigned16) ifetch16 PARAMS ((SIM_DESC sd, sim_cpu *cpu, addres
 #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));
 
 
+#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
This page took 0.05374 seconds and 4 git commands to generate.