/* Floating-point operations: */
#include "sim-fpu.h"
+#include "cp1.h"
/* FPU registers must be one of the following types. All other values
are reserved (and undefined). */
fmt_double = 1,
fmt_word = 4,
fmt_long = 5,
+ fmt_ps = 6,
/* The following are well outside the normal acceptable format
range, and are used in the register status vector. */
fmt_unknown = 0x10000000,
fmt_uninterpreted_64 = 0x80000000U,
} FP_formats;
-unsigned64 value_fpr PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int fpr, FP_formats));
-#define ValueFPR(FPR,FMT) value_fpr (SD, CPU, cia, (FPR), (FMT))
-
-void store_fpr PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int fpr, FP_formats fmt, unsigned64 value));
-#define StoreFPR(FPR,FMT,VALUE) store_fpr (SD, CPU, cia, (FPR), (FMT), (VALUE))
-
-int NaN PARAMS ((unsigned64 op, FP_formats fmt));
-int Infinity PARAMS ((unsigned64 op, FP_formats fmt));
-int Less PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
-int Equal PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
-unsigned64 AbsoluteValue PARAMS ((unsigned64 op, FP_formats fmt));
-unsigned64 Negate PARAMS ((unsigned64 op, FP_formats fmt));
-unsigned64 Add PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
-unsigned64 Sub PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
-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)
-
-/* Macro to update FPSR condition-code field. This is complicated by
- the fact that there is a hole in the index range of the bits within
- the FCSR register. Also, the number of bits visible depends on the
- MIPS ISA version being supported. */
-
-#define SETFCC(cc,v) {\
- 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) ? 1U : 0)
+/* For paired word (pw) operations, the opcode representation is fmt_word,
+ but register transfers (StoreFPR, ValueFPR, etc.) are done as fmt_long. */
+#define fmt_pw fmt_long
/* This should be the COC1 value at the start of the preceding
instruction: */
#define SizeFGR() (WITH_TARGET_FLOATING_POINT_BITSIZE)
#endif
-/* Standard FCRS bits: */
-#define IR (0) /* Inexact Result */
-#define UF (1) /* UnderFlow */
-#define OF (2) /* OverFlow */
-#define DZ (3) /* Division by Zero */
-#define IO (4) /* Invalid Operation */
-#define UO (5) /* Unimplemented Operation */
-
-/* Get masks for individual flags: */
-#if 1 /* SAFE version */
-#define FP_FLAGS(b) (((unsigned)(b) < 5) ? (1 << ((b) + 2)) : 0)
-#define FP_ENABLE(b) (((unsigned)(b) < 5) ? (1 << ((b) + 7)) : 0)
-#define FP_CAUSE(b) (((unsigned)(b) < 6) ? (1 << ((b) + 12)) : 0)
-#else
-#define FP_FLAGS(b) (1 << ((b) + 2))
-#define FP_ENABLE(b) (1 << ((b) + 7))
-#define FP_CAUSE(b) (1 << ((b) + 12))
-#endif
-
-#define FP_FS (1 << 24) /* MIPS III onwards : Flush to Zero */
-
-#define FP_MASK_RM (0x3)
-#define FP_SH_RM (0)
-#define FP_RM_NEAREST (0) /* Round to nearest (Round) */
-#define FP_RM_TOZERO (1) /* Round to zero (Trunc) */
-#define FP_RM_TOPINF (2) /* Round to Plus infinity (Ceil) */
-#define FP_RM_TOMINF (3) /* Round to Minus infinity (Floor) */
-#define GETRM() (int)((FCSR >> FP_SH_RM) & FP_MASK_RM)
-
-
/* For backward compatibility */
#define PENDING_FILL(R,VAL) \
do { \
- if ((R) >= FGRIDX && (R) < FGRIDX + NR_FGR) \
+ if ((R) >= FGR_BASE && (R) < FGR_BASE + NR_FGR) \
{ \
- PENDING_SCHED(FGR[(R) - FGRIDX], VAL, 1, -1); \
- PENDING_SCHED(FPR_STATE[(R) - FGRIDX], fmt_uninterpreted, 1, -1); \
+ PENDING_SCHED(FGR[(R) - FGR_BASE], VAL, 1, -1); \
+ PENDING_SCHED(FPR_STATE[(R) - FGR_BASE], fmt_uninterpreted, 1, -1); \
} \
else \
PENDING_SCHED(GPR[(R)], VAL, 1, -1); \
#define LAST_EMBED_REGNUM (89)
#define NUM_REGS (LAST_EMBED_REGNUM + 1)
-
+#define FP0_REGNUM 38 /* Floating point register 0 (single float) */
+#define FCRCS_REGNUM 70 /* FP control/status */
+#define FCRIR_REGNUM 71 /* FP implementation/revision */
#endif
#define GPR (®ISTERS[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)
- fp_word fgr[NR_FGR];
-#define FGR ((CPU)->fgr)
-
#define LO (REGISTERS[33])
#define HI (REGISTERS[34])
#define PCIDX 37
#define COP0_GPR ((CPU)->cop0_gpr)
#define COP0_BADVADDR ((unsigned32)(COP0_GPR[8]))
+ /* 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 FGR_BASE FP0_REGNUM
+ fp_word fgr[NR_FGR];
+#define FGR ((CPU)->fgr)
+
/* Keep the current format state for each register: */
FP_formats fpr_state[32];
#define FPR_STATE ((CPU)->fpr_state)
#define status_CU1 (1 << 29) /* Coprocessor 1 usable */
#define status_CU2 (1 << 30) /* Coprocessor 2 usable */
#define status_CU3 (1 << 31) /* Coprocessor 3 usable */
+/* Bits reserved for implementations: */
+#define status_SBX (1 << 16) /* Enable SiByte SB-1 extensions. */
#define cause_BD ((unsigned)1 << 31) /* L1 Exception in branch delay slot */
#define cause_BD2 (1 << 30) /* L2 Exception in branch delay slot */
int sim_monitor (SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int arg);
+/* FPR access. */
+unsigned64 value_fpr (SIM_STATE, int fpr, FP_formats);
+#define ValueFPR(FPR,FMT) value_fpr (SIM_ARGS, (FPR), (FMT))
+void store_fpr (SIM_STATE, int fpr, FP_formats fmt, unsigned64 value);
+#define StoreFPR(FPR,FMT,VALUE) store_fpr (SIM_ARGS, (FPR), (FMT), (VALUE))
+unsigned64 ps_lower (SIM_STATE, unsigned64 op);
+#define PSLower(op) ps_lower (SIM_ARGS, op)
+unsigned64 ps_upper (SIM_STATE, unsigned64 op);
+#define PSUpper(op) ps_upper (SIM_ARGS, op)
+unsigned64 pack_ps (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats from);
+#define PackPS(op1,op2) pack_ps (SIM_ARGS, op1, op2, fmt_single)
+
+
+/* FCR access. */
+unsigned_word value_fcr (SIM_STATE, int fcr);
+#define ValueFCR(FCR) value_fcr (SIM_ARGS, (FCR))
+void store_fcr (SIM_STATE, int fcr, unsigned_word value);
+#define StoreFCR(FCR,VALUE) store_fcr (SIM_ARGS, (FCR), (VALUE))
+void test_fcsr (SIM_STATE);
+#define TestFCSR() test_fcsr (SIM_ARGS)
+
+
+/* FPU operations. */
+void fp_cmp (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt, int abs, int cond, int cc);
+#define Compare(op1,op2,fmt,cond,cc) fp_cmp(SIM_ARGS, op1, op2, fmt, 0, cond, cc)
+unsigned64 fp_abs (SIM_STATE, unsigned64 op, FP_formats fmt);
+#define AbsoluteValue(op,fmt) fp_abs(SIM_ARGS, op, fmt)
+unsigned64 fp_neg (SIM_STATE, unsigned64 op, FP_formats fmt);
+#define Negate(op,fmt) fp_neg(SIM_ARGS, op, fmt)
+unsigned64 fp_add (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt);
+#define Add(op1,op2,fmt) fp_add(SIM_ARGS, op1, op2, fmt)
+unsigned64 fp_sub (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt);
+#define Sub(op1,op2,fmt) fp_sub(SIM_ARGS, op1, op2, fmt)
+unsigned64 fp_mul (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt);
+#define Multiply(op1,op2,fmt) fp_mul(SIM_ARGS, op1, op2, fmt)
+unsigned64 fp_div (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt);
+#define Divide(op1,op2,fmt) fp_div(SIM_ARGS, op1, op2, fmt)
+unsigned64 fp_recip (SIM_STATE, unsigned64 op, FP_formats fmt);
+#define Recip(op,fmt) fp_recip(SIM_ARGS, op, fmt)
+unsigned64 fp_sqrt (SIM_STATE, unsigned64 op, FP_formats fmt);
+#define SquareRoot(op,fmt) fp_sqrt(SIM_ARGS, op, fmt)
+unsigned64 fp_rsqrt (SIM_STATE, unsigned64 op, FP_formats fmt);
+#define RSquareRoot(op,fmt) fp_rsqrt(SIM_ARGS, op, fmt)
+unsigned64 fp_madd (SIM_STATE, unsigned64 op1, unsigned64 op2,
+ unsigned64 op3, FP_formats fmt);
+#define MultiplyAdd(op1,op2,op3,fmt) fp_madd(SIM_ARGS, op1, op2, op3, fmt)
+unsigned64 fp_msub (SIM_STATE, unsigned64 op1, unsigned64 op2,
+ unsigned64 op3, FP_formats fmt);
+#define MultiplySub(op1,op2,op3,fmt) fp_msub(SIM_ARGS, op1, op2, op3, fmt)
+unsigned64 fp_nmadd (SIM_STATE, unsigned64 op1, unsigned64 op2,
+ unsigned64 op3, FP_formats fmt);
+#define NegMultiplyAdd(op1,op2,op3,fmt) fp_nmadd(SIM_ARGS, op1, op2, op3, fmt)
+unsigned64 fp_nmsub (SIM_STATE, unsigned64 op1, unsigned64 op2,
+ unsigned64 op3, FP_formats fmt);
+#define NegMultiplySub(op1,op2,op3,fmt) fp_nmsub(SIM_ARGS, op1, op2, op3, fmt)
+unsigned64 convert (SIM_STATE, int rm, unsigned64 op, FP_formats from, FP_formats to);
+#define Convert(rm,op,from,to) convert (SIM_ARGS, rm, op, from, to)
+unsigned64 convert_ps (SIM_STATE, int rm, unsigned64 op, FP_formats from,
+ FP_formats to);
+#define ConvertPS(rm,op,from,to) convert_ps (SIM_ARGS, rm, op, from, to)
+
+
+/* MIPS-3D ASE operations. */
+#define CompareAbs(op1,op2,fmt,cond,cc) \
+fp_cmp(SIM_ARGS, op1, op2, fmt, 1, cond, cc)
+unsigned64 fp_add_r (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt);
+#define AddR(op1,op2,fmt) fp_add_r(SIM_ARGS, op1, op2, fmt)
+unsigned64 fp_mul_r (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt);
+#define MultiplyR(op1,op2,fmt) fp_mul_r(SIM_ARGS, op1, op2, fmt)
+unsigned64 fp_recip1 (SIM_STATE, unsigned64 op, FP_formats fmt);
+#define Recip1(op,fmt) fp_recip1(SIM_ARGS, op, fmt)
+unsigned64 fp_recip2 (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt);
+#define Recip2(op1,op2,fmt) fp_recip2(SIM_ARGS, op1, op2, fmt)
+unsigned64 fp_rsqrt1 (SIM_STATE, unsigned64 op, FP_formats fmt);
+#define RSquareRoot1(op,fmt) fp_rsqrt1(SIM_ARGS, op, fmt)
+unsigned64 fp_rsqrt2 (SIM_STATE, unsigned64 op1, unsigned64 op2, FP_formats fmt);
+#define RSquareRoot2(op1,op2,fmt) fp_rsqrt2(SIM_ARGS, op1, op2, fmt)
+
+
/* MDMX access. */
typedef unsigned int MX_fmtsel; /* MDMX format select field (5 bits). */
#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_MUL (10)
#define MX_VECT_MSGN (11)
#define MX_VECT_SRA (12)
+#define MX_VECT_ABSD (13) /* SB-1 only. */
+#define MX_VECT_AVG (14) /* SB-1 only. */
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_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_AbsDiff(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_ABSD, op1, vt, fmtsel)
+#define MX_Avg(op1,vt,fmtsel) mdmx_cpr_op(SIM_ARGS, MX_VECT_AVG, op1, vt, fmtsel)
#define MX_C_EQ 0x1
#define MX_C_LT 0x4
#define MX_VECT_MULSL (5)
#define MX_VECT_SUBA (6)
#define MX_VECT_SUBL (7)
+#define MX_VECT_ABSDA (8) /* SB-1 only. */
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_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_AbsDiffC(op1,vt,fmtsel) mdmx_acc_op(SIM_ARGS, MX_VECT_ABSDA, op1, vt, fmtsel)
#define MX_FMT_OB (0)
#define MX_FMT_QH (1)