2002-06-02 Chris Demetriou <cgd@broadcom.com>
[deliverable/binutils-gdb.git] / sim / mips / sim-main.h
index 6b6a6f9e17358983afc95d225a2b5ce97cbb278c..08d2e608b4e7d707aea75ffb7e6edbc6092e316c 100644 (file)
@@ -43,7 +43,7 @@ typedef address_word sim_cia;
 #include "sim-base.h"
 
 
-/* Depreciated macros and types for manipulating 64bit values.  Use
+/* Deprecated macros and types for manipulating 64bit values.  Use
    ../common/sim-bits.h and ../common/sim-endian.h macros instead. */
 
 typedef signed64 word64;
@@ -56,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))
 
@@ -297,6 +288,31 @@ do {                                                                       \
 } 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
+  };
+
+
+/* The internal representation of an MDMX accumulator. 
+   Note that 24 and 48 bit accumulator elements are represented in
+   32 or 64 bits.  Since the accumulators are 2's complement with
+   overflow suppressed, high-order bits can be ignored in most contexts.  */
+
+typedef signed32 signed24;
+typedef signed64 signed48;
+
+typedef union { 
+  signed24  ob[8];
+  signed48  qh[4]; 
+} MDMX_accumulator;
+
+
+/* Conventional system arguments.  */ 
+#define SIM_STATE  sim_cpu *cpu, address_word cia
+#define SIM_ARGS   CPU, cia
 
 struct _sim_cpu {
 
@@ -328,6 +344,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 */ \
@@ -343,6 +360,7 @@ struct _sim_cpu {
     else \
      STATE &= ~simPCOC0; \
   }
+#endif /* ENGINE_ISSUE_PREFIX_HOOK */
 
 
 /* This is nasty, since we have to rely on matching the register
@@ -360,13 +378,6 @@ struct _sim_cpu {
 #endif
 
 
-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
-  };
-
 /* 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. */
@@ -403,7 +414,6 @@ enum float_operation
 #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. */
@@ -447,6 +457,10 @@ enum float_operation
 
   pending_write_queue pending;
 
+  /* The MDMX accumulator (used only for MDMX ASE).  */
+  MDMX_accumulator acc; 
+#define ACC             ((CPU)->acc)
+
   /* LLBIT = Load-Linked bit. A bit of "virtual" state used by atomic
      read-write instructions. It is set when a linked load occurs. It
      is tested and cleared by the conditional store. It is cleared
@@ -542,6 +556,18 @@ struct sim_state {
 #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 */
@@ -619,9 +645,12 @@ enum ExceptionCause {
   IntegerOverflow         = 12,    /* Arithmetic overflow (IDT monitor raises SIGFPE) */
   Trap                    = 13,
   FPE                     = 15,
-  DebugBreakPoint         = 16,
+  DebugBreakPoint         = 16,    /* Impl. dep. in MIPS32/MIPS64.  */
+  MDMX                    = 22,
   Watch                   = 23,
-  NMIReset                = 31,
+  MCheck                  = 24,
+  CacheErr                = 30,
+  NMIReset                = 31,    /* Reserved in MIPS32/MIPS64.  */
 
 
 /* The following exception code is actually private to the simulator
@@ -661,16 +690,23 @@ void signal_exception (SIM_DESC sd, sim_cpu *cpu, address_word cia, int exceptio
 #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));
@@ -690,9 +726,110 @@ void decode_coproc PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigne
 #define DecodeCoproc(instruction) \
 decode_coproc (SD, CPU, cia, (instruction))
 
-void sim_monitor (SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int arg);
+int sim_monitor (SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int arg);
   
 
+/* MDMX access.  */
+
+typedef unsigned int MX_fmtsel;   /* MDMX format select field (5 bits).  */
+#define ob_fmtsel(sel) (((sel)<<1)|0x0)
+#define qh_fmtsel(sel) (((sel)<<2)|0x1)
+
+#define fmt_mdmx fmt_uninterpreted
+
+#define MX_VECT_AND  (0)
+#define MX_VECT_NOR  (1)
+#define MX_VECT_OR   (2)
+#define MX_VECT_XOR  (3)
+#define MX_VECT_SLL  (4)
+#define MX_VECT_SRL  (5)
+
+#define MX_VECT_ADD  (6)
+#define MX_VECT_SUB  (7)
+#define MX_VECT_MIN  (8)
+#define MX_VECT_MAX  (9)
+#define MX_VECT_MUL  (10)
+#define MX_VECT_MSGN (11)
+#define MX_VECT_SRA  (12)
+
+unsigned64 mdmx_cpr_op (SIM_STATE, int op, unsigned64 op1, int vt, MX_fmtsel fmtsel);
+#define MX_Add(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_ADD, op1, vt, fmtsel)
+#define MX_And(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_AND, op1, vt, fmtsel)
+#define MX_Max(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_MAX, op1, vt, fmtsel)
+#define MX_Min(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_MIN, op1, vt, fmtsel)
+#define MX_Msgn(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_MSGN, op1, vt, fmtsel)
+#define MX_Mul(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_MUL, op1, vt, fmtsel)
+#define MX_Nor(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_NOR, op1, vt, fmtsel)
+#define MX_Or(op1,vt,fmtsel)  mdmx_cpr_op(SIM_ARGS, MX_VECT_OR,  op1, vt, fmtsel)
+#define MX_ShiftLeftLogical(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_SLL, op1, vt, fmtsel)
+#define MX_ShiftRightArith(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_SRA, op1, vt, fmtsel)
+#define MX_ShiftRightLogical(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_SRL, op1, vt, fmtsel)
+#define MX_Sub(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_SUB, op1, vt, fmtsel)
+#define MX_Xor(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_XOR, op1, vt, fmtsel)
+
+#define MX_C_EQ  0x1
+#define MX_C_LT  0x4
+
+void mdmx_cc_op (SIM_STATE, int cond, unsigned64 op1, int vt, MX_fmtsel fmtsel);
+#define MX_Comp(op1,cond,vt,fmtsel) mdmx_cc_op(SIM_ARGS, cond, op1, vt, fmtsel)
+
+unsigned64 mdmx_pick_op (SIM_STATE, int tf, unsigned64 op1, int vt, MX_fmtsel fmtsel);
+#define MX_Pick(tf,op1,vt,fmtsel) mdmx_pick_op(SIM_ARGS, tf, op1, vt, fmtsel)
+
+#define MX_VECT_ADDA  (0)
+#define MX_VECT_ADDL  (1)
+#define MX_VECT_MULA  (2)
+#define MX_VECT_MULL  (3)
+#define MX_VECT_MULS  (4)
+#define MX_VECT_MULSL (5)
+#define MX_VECT_SUBA  (6)
+#define MX_VECT_SUBL  (7)
+
+void mdmx_acc_op (SIM_STATE, int op, unsigned64 op1, int vt, MX_fmtsel fmtsel);
+#define MX_AddA(op1,vt,fmtsel) mdmx_acc_op(SIM_ARGS, MX_VECT_ADDA, op1, vt, fmtsel)
+#define MX_AddL(op1,vt,fmtsel) mdmx_acc_op(SIM_ARGS, MX_VECT_ADDL, op1, vt, fmtsel)
+#define MX_MulA(op1,vt,fmtsel) mdmx_acc_op(SIM_ARGS, MX_VECT_MULA, op1, vt, fmtsel)
+#define MX_MulL(op1,vt,fmtsel) mdmx_acc_op(SIM_ARGS, MX_VECT_MULL, op1, vt, fmtsel)
+#define MX_MulS(op1,vt,fmtsel) mdmx_acc_op(SIM_ARGS, MX_VECT_MULS, op1, vt, fmtsel)
+#define MX_MulSL(op1,vt,fmtsel) mdmx_acc_op(SIM_ARGS, MX_VECT_MULSL, op1, vt, fmtsel)
+#define MX_SubA(op1,vt,fmtsel) mdmx_acc_op(SIM_ARGS, MX_VECT_SUBA, op1, vt, fmtsel)
+#define MX_SubL(op1,vt,fmtsel) mdmx_acc_op(SIM_ARGS, MX_VECT_SUBL, op1, vt, fmtsel)
+
+#define MX_FMT_OB   (0)
+#define MX_FMT_QH   (1)
+
+/* The following codes chosen to indicate the units of shift.  */
+#define MX_RAC_L    (0)
+#define MX_RAC_M    (1)
+#define MX_RAC_H    (2)
+
+unsigned64 mdmx_rac_op (SIM_STATE, int, int);
+#define MX_RAC(op,fmt) mdmx_rac_op(SIM_ARGS, op, fmt)
+
+void mdmx_wacl (SIM_STATE, int, unsigned64, unsigned64);
+#define MX_WACL(fmt,vs,vt) mdmx_wacl(SIM_ARGS, fmt, vs, vt)
+void mdmx_wach (SIM_STATE, int, unsigned64);
+#define MX_WACH(fmt,vs) mdmx_wach(SIM_ARGS, fmt, vs)
+
+#define MX_RND_AS   (0)
+#define MX_RND_AU   (1)
+#define MX_RND_ES   (2)
+#define MX_RND_EU   (3)
+#define MX_RND_ZS   (4)
+#define MX_RND_ZU   (5)
+
+unsigned64 mdmx_round_op (SIM_STATE, int, int, MX_fmtsel);
+#define MX_RNAS(vt,fmt) mdmx_round_op(SIM_ARGS, MX_RND_AS, vt, fmt)
+#define MX_RNAU(vt,fmt) mdmx_round_op(SIM_ARGS, MX_RND_AU, vt, fmt)
+#define MX_RNES(vt,fmt) mdmx_round_op(SIM_ARGS, MX_RND_ES, vt, fmt)
+#define MX_RNEU(vt,fmt) mdmx_round_op(SIM_ARGS, MX_RND_EU, vt, fmt)
+#define MX_RZS(vt,fmt)  mdmx_round_op(SIM_ARGS, MX_RND_ZS, vt, fmt)
+#define MX_RZU(vt,fmt)  mdmx_round_op(SIM_ARGS, MX_RND_ZU, vt, fmt)
+
+unsigned64 mdmx_shuffle (SIM_STATE, int, unsigned64, unsigned64);
+#define MX_SHFL(shop,op1,op2) mdmx_shuffle(SIM_ARGS, shop, op1, op2)
+
+
 
 /* Memory accesses */
 
@@ -757,6 +894,11 @@ 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_)
+#define UnpredictableResult()  /* For now, do nothing.  */
+
 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));
@@ -773,6 +915,8 @@ 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);
This page took 0.034179 seconds and 4 git commands to generate.