| Index: runtime/vm/simulator_mips.cc
|
| ===================================================================
|
| --- runtime/vm/simulator_mips.cc (revision 24149)
|
| +++ runtime/vm/simulator_mips.cc (working copy)
|
| @@ -727,6 +727,23 @@
|
| }
|
|
|
|
|
| +void Simulator::set_dregister_bits(DRegister reg, int64_t value) {
|
| + ASSERT(reg >= 0);
|
| + ASSERT(reg < kNumberOfDRegisters);
|
| + FRegister lo = static_cast<FRegister>(reg * 2);
|
| + FRegister hi = static_cast<FRegister>((reg * 2) + 1);
|
| + set_fregister(lo, Utils::Low32Bits(value));
|
| + set_fregister(hi, Utils::High32Bits(value));
|
| +}
|
| +
|
| +
|
| +void Simulator::set_dregister(DRegister reg, double value) {
|
| + ASSERT(reg >= 0);
|
| + ASSERT(reg < kNumberOfDRegisters);
|
| + set_dregister_bits(reg, bit_cast<int64_t, double>(value));
|
| +}
|
| +
|
| +
|
| // Get the register from the architecture state.
|
| int32_t Simulator::get_register(Register reg) const {
|
| if (reg == R0) {
|
| @@ -769,6 +786,23 @@
|
| }
|
|
|
|
|
| +int64_t Simulator::get_dregister_bits(DRegister reg) const {
|
| + ASSERT(reg >= 0);
|
| + ASSERT(reg < kNumberOfDRegisters);
|
| + FRegister lo = static_cast<FRegister>(reg * 2);
|
| + FRegister hi = static_cast<FRegister>((reg * 2) + 1);
|
| + return Utils::LowHighTo64Bits(get_fregister(lo), get_fregister(hi));
|
| +}
|
| +
|
| +
|
| +double Simulator::get_dregister(DRegister reg) const {
|
| + ASSERT(reg >= 0);
|
| + ASSERT(reg < kNumberOfDRegisters);
|
| + const int64_t value = get_dregister_bits(reg);
|
| + return bit_cast<double, int64_t>(value);
|
| +}
|
| +
|
| +
|
| void Simulator::UnimplementedInstruction(Instr* instr) {
|
| char buffer[64];
|
| snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr);
|
| @@ -1097,10 +1131,9 @@
|
| int32_t rs_val = get_register(instr->RsField());
|
| int32_t rt_val = get_register(instr->RtField());
|
| if (rt_val == 0) {
|
| - // Results are unpredictable.
|
| - set_hi_register(0);
|
| - set_lo_register(0);
|
| - // TODO(zra): Drop into the debugger here.
|
| + // Results are unpredictable, but there is no arithmetic exception.
|
| + set_hi_register(icount_);
|
| + set_lo_register(icount_);
|
| break;
|
| }
|
|
|
| @@ -1121,10 +1154,9 @@
|
| uint32_t rs_val = get_register(instr->RsField());
|
| uint32_t rt_val = get_register(instr->RtField());
|
| if (rt_val == 0) {
|
| - // Results are unpredictable.
|
| - set_hi_register(0);
|
| - set_lo_register(0);
|
| - // TODO(zra): Drop into the debugger here.
|
| + // Results are unpredictable, but there is no arithmetic exception.
|
| + set_hi_register(icount_);
|
| + set_lo_register(icount_);
|
| break;
|
| }
|
| set_lo_register(rs_val / rt_val);
|
| @@ -2021,7 +2053,8 @@
|
| int32_t parameter0,
|
| int32_t parameter1,
|
| int32_t parameter2,
|
| - int32_t parameter3) {
|
| + int32_t parameter3,
|
| + bool fp_return) {
|
| // Save the SP register before the call so we can restore it.
|
| int32_t sp_before_call = get_register(SP);
|
|
|
| @@ -2058,6 +2091,13 @@
|
| int32_t r22_val = get_register(R22);
|
| int32_t r23_val = get_register(R23);
|
|
|
| + double d10_val = get_dregister(D10);
|
| + double d11_val = get_dregister(D11);
|
| + double d12_val = get_dregister(D12);
|
| + double d13_val = get_dregister(D13);
|
| + double d14_val = get_dregister(D14);
|
| + double d15_val = get_dregister(D15);
|
| +
|
| // Setup the callee-saved registers with a known value. To be able to check
|
| // that they are preserved properly across dart execution.
|
| int32_t callee_saved_value = icount_;
|
| @@ -2070,6 +2110,13 @@
|
| set_register(R22, callee_saved_value);
|
| set_register(R23, callee_saved_value);
|
|
|
| + set_dregister_bits(D10, callee_saved_value);
|
| + set_dregister_bits(D11, callee_saved_value);
|
| + set_dregister_bits(D12, callee_saved_value);
|
| + set_dregister_bits(D13, callee_saved_value);
|
| + set_dregister_bits(D14, callee_saved_value);
|
| + set_dregister_bits(D15, callee_saved_value);
|
| +
|
| // Start the simulation
|
| Execute();
|
|
|
| @@ -2083,6 +2130,13 @@
|
| ASSERT(callee_saved_value == get_register(R22));
|
| ASSERT(callee_saved_value == get_register(R23));
|
|
|
| + ASSERT(callee_saved_value == get_dregister_bits(D10));
|
| + ASSERT(callee_saved_value == get_dregister_bits(D11));
|
| + ASSERT(callee_saved_value == get_dregister_bits(D12));
|
| + ASSERT(callee_saved_value == get_dregister_bits(D13));
|
| + ASSERT(callee_saved_value == get_dregister_bits(D14));
|
| + ASSERT(callee_saved_value == get_dregister_bits(D15));
|
| +
|
| // Restore callee-saved registers with the original value.
|
| set_register(R16, r16_val);
|
| set_register(R17, r17_val);
|
| @@ -2093,9 +2147,22 @@
|
| set_register(R22, r22_val);
|
| set_register(R23, r23_val);
|
|
|
| + set_dregister(D10, d10_val);
|
| + set_dregister(D11, d11_val);
|
| + set_dregister(D12, d12_val);
|
| + set_dregister(D13, d13_val);
|
| + set_dregister(D14, d14_val);
|
| + set_dregister(D15, d15_val);
|
| +
|
| // Restore the SP register and return V1:V0.
|
| set_register(SP, sp_before_call);
|
| - return Utils::LowHighTo64Bits(get_register(V0), get_register(V1));
|
| + int64_t return_value;
|
| + if (fp_return) {
|
| + return_value = Utils::LowHighTo64Bits(get_fregister(F0), get_fregister(F1));
|
| + } else {
|
| + return_value = Utils::LowHighTo64Bits(get_register(V0), get_register(V1));
|
| + }
|
| + return return_value;
|
| }
|
|
|
|
|
|
|