}
+// Helper:
+//
+// Check that the 64-bit instruction can currently be used, and signal
+// an ReservedInstruction exception if not.
+//
+
+:function:::void:check_u64:instruction_word insn
+*mipsIII:
+*mipsIV:
+*mipsV:
+*vr4100:
+*vr5000:
+{
+ // On mips64, if UserMode check SR:PX & SR:UX bits.
+ // The check should be similar to mips64 for any with PX/UX bit equivalents.
+}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
{
ALU64_BEGIN (GPR[RS]);
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
{
ALU64_BEGIN (GPR[RS]);
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_daddiu (SD_, RS, RT, IMMEDIATE);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_daddu (SD_, RS, RT, RD);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_ddiv (SD_, RS, RT);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_ddivu (SD_, RS, RT);
}
*mipsV:
*vr4100:
{
+ check_u64 (SD_, instruction_0);
do_dmult (SD_, RS, RT, 0);
}
"dmult r<RD>, r<RS>, r<RT>"
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_dmult (SD_, RS, RT, RD);
}
*mipsV:
*vr4100:
{
+ check_u64 (SD_, instruction_0);
do_dmultu (SD_, RS, RT, 0);
}
"dmultu r<RS>, r<RT>"
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_dmultu (SD_, RS, RT, RD);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_dsll (SD_, RT, RD, SHIFT);
}
*vr5000:
{
int s = 32 + SHIFT;
+ check_u64 (SD_, instruction_0);
GPR[RD] = GPR[RT] << s;
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_dsllv (SD_, RS, RT, RD);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_dsra (SD_, RT, RD, SHIFT);
}
*vr5000:
{
int s = 32 + SHIFT;
+ check_u64 (SD_, instruction_0);
GPR[RD] = ((signed64) GPR[RT]) >> s;
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_dsrav (SD_, RS, RT, RD);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_dsrl (SD_, RT, RD, SHIFT);
}
*vr5000:
{
int s = 32 + SHIFT;
+ check_u64 (SD_, instruction_0);
GPR[RD] = (unsigned64) GPR[RT] >> s;
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_dsrlv (SD_, RS, RT, RD);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
{
ALU64_BEGIN (GPR[RS]);
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_dsubu (SD_, RS, RT, RD);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
}
signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
int destreg = ((instruction >> 16) & 0x0000001F);
signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ check_u64 (SD_, instruction_0);
{
address_word vaddr = ((unsigned64)op1 + offset);
address_word paddr;
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
GPR[RT] = do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET));
}
signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ check_u64 (SD_, instruction_0);
{
address_word vaddr = ((unsigned64)op1 + offset);
address_word paddr;
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
}
*vr4100:
*vr5000:
{
+ check_u64 (SD_, instruction_0);
do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
}
}
}
+// Helper:
+//
+// Check that the FPU is currently usable, and signal a CoProcessorUnusable
+// exception if not.
+//
+
+:function:::void:check_fpu:
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+#if 0 /* XXX FIXME: For now, never treat the FPU as disabled. */
+ if (! COP_Usable (1))
+ SignalExceptionCoProcessorUnusable (1);
+#endif
+}
+
010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
"abs.%s<FMT> f<FD>, f<FS>"
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction, instruction);
*mipsII:
*mipsIII:
{
+ check_fpu(SD_);
check_branch_bug ();
TRACE_BRANCH_INPUT (PREVCOC1());
if (PREVCOC1() == TF)
*vr5000:
*r3900:
{
+ check_fpu(SD_);
check_branch_bug ();
if (GETFCC(CC) == TF)
{
*mipsII:
*mipsIII:
{
+ check_fpu(SD_);
do_c_cond_fmt (SD_, FMT, FT, FS, 0, COND, instruction_0);
}
*vr5000:
*r3900:
{
+ check_fpu(SD_);
do_c_cond_fmt (SD_, FMT, FT, FS, CC, COND, instruction_0);
}
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
*mipsII:
*mipsIII:
{
+ check_fpu(SD_);
if (X)
{
if (FS == 0)
*vr5000:
*r3900:
{
+ check_fpu(SD_);
if (X)
{
/* control to */
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format == fmt_double) | 0)
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format == fmt_long) | ((format == fmt_long) || (format == fmt_word)))
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format == fmt_single) | 0)
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format == fmt_word) | ((format == fmt_long) || (format == fmt_word)))
SignalException(ReservedInstruction,instruction);
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
"dm%s<X>c1 r<RT>, f<FS>"
*mipsIII:
{
+ check_fpu(SD_);
+ check_u64 (SD_, instruction_0);
if (X)
{
if (SizeFGR() == 64)
*vr5000:
*r3900:
{
+ check_fpu(SD_);
+ check_u64 (SD_, instruction_0);
if (X)
{
if (SizeFGR() == 64)
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
*vr5000:
*r3900:
{
+ check_fpu(SD_);
COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
}
*mipsV:
*vr5000:
{
+ check_fpu(SD_);
+ check_u64 (SD_, instruction_0);
COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
}
*vr5000:
*r3900:
{
+ check_fpu(SD_);
COP_LW (1, FT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
}
*mipsV:
*vr5000:
{
+ check_fpu(SD_);
+ check_u64 (SD_, instruction_0);
COP_LW (1, FD, do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
}
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int fr = ((instruction >> 21) & 0x0000001F);
+ check_fpu(SD_);
{
StoreFPR(destreg,fmt_double,Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
}
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int fr = ((instruction >> 21) & 0x0000001F);
+ check_fpu(SD_);
{
StoreFPR(destreg,fmt_single,Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
}
*mipsII:
*mipsIII:
{
+ check_fpu(SD_);
if (X)
{ /*MTC1*/
if (SizeFGR() == 64)
*r3900:
{
int fs = FS;
+ check_fpu(SD_);
if (X)
/*MTC1*/
StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
StoreFPR(destreg,format,ValueFPR(fs,format));
}
*mipsV:
*vr5000:
{
+ check_fpu(SD_);
if (GETFCC(CC) == TF)
GPR[RD] = GPR[RS];
}
{
unsigned32 instruction = instruction_0;
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if (GETFCC(CC) == TF)
StoreFPR (FD, format, ValueFPR (FS, format));
*mipsV:
*vr5000:
{
+ check_fpu(SD_);
if (GPR[RT] != 0)
StoreFPR (FD, FMT, ValueFPR (FS, FMT));
else
*mipsV:
*vr5000:
{
+ check_fpu(SD_);
if (GPR[RT] == 0)
StoreFPR (FD, FMT, ValueFPR (FS, FMT));
else
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int fr = ((instruction >> 21) & 0x0000001F);
+ check_fpu(SD_);
{
StoreFPR(destreg,fmt_double,Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
}
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int fr = ((instruction >> 21) & 0x0000001F);
+ check_fpu(SD_);
{
StoreFPR(destreg,fmt_single,Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
}
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int fr = ((instruction >> 21) & 0x0000001F);
+ check_fpu(SD_);
{
StoreFPR(destreg,fmt_double,Negate(Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double));
}
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int fr = ((instruction >> 21) & 0x0000001F);
+ check_fpu(SD_);
{
StoreFPR(destreg,fmt_single,Negate(Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single));
}
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int fr = ((instruction >> 21) & 0x0000001F);
+ check_fpu(SD_);
{
StoreFPR(destreg,fmt_double,Negate(Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double));
}
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int fr = ((instruction >> 21) & 0x0000001F);
+ check_fpu(SD_);
{
StoreFPR(destreg,fmt_single,Negate(Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single));
}
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
*vr5000:
*r3900:
{
+ check_fpu(SD_);
do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
}
*mipsV:
*vr5000:
{
+ check_fpu(SD_);
+ check_u64 (SD_, instruction_0);
do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
}
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int fs = ((instruction >> 11) & 0x0000001F);
int ft = ((instruction >> 16) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
signed_word offset = EXTEND16 (OFFSET);
int destreg UNUSED = ((instruction >> 16) & 0x0000001F);
signed_word op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)];
+ check_fpu(SD_);
{
address_word vaddr = ((uword64)op1 + offset);
address_word paddr;
int fs = ((instruction >> 11) & 0x0000001F);
signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ check_fpu(SD_);
+ check_u64 (SD_, instruction_0);
{
address_word vaddr = ((unsigned64)op1 + op2);
address_word paddr;
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
int destreg = ((instruction >> 6) & 0x0000001F);
int fs = ((instruction >> 11) & 0x0000001F);
int format = ((instruction >> 21) & 0x00000007);
+ check_fpu(SD_);
{
if ((format != fmt_single) && (format != fmt_double))
SignalException(ReservedInstruction,instruction);
*mipsIV:
*mipsV:
{
+ check_u64 (SD_, instruction_0);
DecodeCoproc (instruction_0);
}
*mipsIV:
*mipsV:
{
+ check_u64 (SD_, instruction_0);
DecodeCoproc (instruction_0);
}