Index: src/mips/simulator-mips.cc |
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc |
index 2e4921c71059eb799228c38bfa7bf5886b192d6b..c2ac415d5723921ee7bfcc1e2e04d24394cb8e9c 100644 |
--- a/src/mips/simulator-mips.cc |
+++ b/src/mips/simulator-mips.cc |
@@ -2329,13 +2329,61 @@ void Simulator::DecodeTypeRegisterSRsType(Instruction* instr, |
const int32_t& ft_reg, |
const int32_t& fs_reg, |
const int32_t& fd_reg) { |
- float f; |
- double ft = get_fpu_register_double(ft_reg); |
- int64_t ft_int = static_cast<int64_t>(ft); |
+ float fs, ft; |
+ fs = get_fpu_register_float(fs_reg); |
+ ft = get_fpu_register_float(ft_reg); |
+ int64_t ft_int = static_cast<int64_t>(get_fpu_register_double(ft_reg)); |
+ uint32_t cc, fcsr_cc; |
+ cc = instr->FCccValue(); |
+ fcsr_cc = get_fcsr_condition_bit(cc); |
switch (instr->FunctionFieldRaw()) { |
+ case ADD_D: |
+ set_fpu_register_float(fd_reg, fs + ft); |
+ break; |
+ case SUB_D: |
+ set_fpu_register_float(fd_reg, fs - ft); |
+ break; |
+ case MUL_D: |
+ set_fpu_register_float(fd_reg, fs * ft); |
+ break; |
+ case DIV_D: |
+ set_fpu_register_float(fd_reg, fs / ft); |
+ break; |
+ case ABS_D: |
+ set_fpu_register_float(fd_reg, fabs(fs)); |
+ break; |
+ case MOV_D: |
+ set_fpu_register_float(fd_reg, fs); |
+ break; |
+ case NEG_D: |
+ set_fpu_register_float(fd_reg, -fs); |
+ break; |
+ case SQRT_D: |
+ set_fpu_register_float(fd_reg, fast_sqrt(fs)); |
+ break; |
+ case C_UN_D: |
+ set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
+ break; |
+ case C_EQ_D: |
+ set_fcsr_bit(fcsr_cc, (fs == ft)); |
+ break; |
+ case C_UEQ_D: |
+ set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
+ break; |
+ case C_OLT_D: |
+ set_fcsr_bit(fcsr_cc, (fs < ft)); |
+ break; |
+ case C_ULT_D: |
+ set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); |
+ break; |
+ case C_OLE_D: |
+ set_fcsr_bit(fcsr_cc, (fs <= ft)); |
+ break; |
+ case C_ULE_D: |
+ set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
+ break; |
case CVT_D_S: |
- f = get_fpu_register_float(fs_reg); |
- set_fpu_register_double(fd_reg, static_cast<double>(f)); |
+ set_fpu_register_double(fd_reg, static_cast<double>(fs)); |
break; |
case SELEQZ_C: |
DCHECK(IsMipsArchVariant(kMips32r6)); |