Chromium Code Reviews| Index: runtime/vm/simulator_mips.cc |
| =================================================================== |
| --- runtime/vm/simulator_mips.cc (revision 24063) |
| +++ runtime/vm/simulator_mips.cc (working copy) |
| @@ -92,6 +92,7 @@ |
| bool GetValue(char* desc, uint32_t* value); |
| bool GetFValue(char* desc, double* value); |
| + bool GetDValue(char* desc, double* value); |
| // Set or delete a breakpoint. Returns true if successful. |
| bool SetBreakpoint(Instr* breakpc); |
| @@ -226,6 +227,26 @@ |
| } |
| +bool SimulatorDebugger::GetDValue(char* desc, double* value) { |
| + FRegister freg = LookupFRegisterByName(desc); |
| + if (freg != kNoFRegister) { |
| + *value = sim_->get_fregister_double(freg); |
| + return true; |
| + } |
| + if (desc[0] == '*') { |
| + uint32_t addr; |
| + if (GetValue(desc + 1, &addr)) { |
| + if (Simulator::IsIllegalAddress(addr)) { |
| + return false; |
| + } |
| + *value = *(reinterpret_cast<double*>(addr)); |
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| + |
| bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) { |
| // Check if a breakpoint can be set. If not return without any side-effects. |
| if (sim_->break_pc_ != NULL) { |
| @@ -361,6 +382,20 @@ |
| } else { |
| OS::Print("printfloat <dreg or *addr>\n"); |
| } |
| + } else if ((strcmp(cmd, "pd") == 0) || |
| + (strcmp(cmd, "printdouble") == 0)) { |
| + if (args == 2) { |
| + double dvalue; |
| + if (GetDValue(arg1, &dvalue)) { |
| + uint64_t long_value = bit_cast<uint64_t, double>(dvalue); |
| + OS::Print("%s: %llu 0x%llx %.8g\n", |
| + arg1, long_value, long_value, dvalue); |
| + } else { |
| + OS::Print("%s unrecognized\n", arg1); |
| + } |
| + } else { |
| + OS::Print("printfloat <dreg or *addr>\n"); |
| + } |
| } else if ((strcmp(cmd, "po") == 0) || |
| (strcmp(cmd, "printobject") == 0)) { |
| if (args == 2) { |
| @@ -589,13 +624,16 @@ |
| Simulator::CallKind call_kind() const { return call_kind_; } |
| + int argument_count() const { return argument_count_; } |
| + |
| static Redirection* Get(uword external_function, |
| - Simulator::CallKind call_kind) { |
| + Simulator::CallKind call_kind, |
| + int argument_count) { |
| Redirection* current; |
| for (current = list_; current != NULL; current = current->next_) { |
| if (current->external_function_ == external_function) return current; |
| } |
| - return new Redirection(external_function, call_kind); |
| + return new Redirection(external_function, call_kind, argument_count); |
| } |
| static Redirection* FromBreakInstruction(Instr* break_instruction) { |
| @@ -609,9 +647,12 @@ |
| static const int32_t kRedirectInstruction = |
| Instr::kBreakPointInstruction | (Instr::kRedirectCode << kBreakCodeShift); |
| - Redirection(uword external_function, Simulator::CallKind call_kind) |
| + Redirection(uword external_function, |
| + Simulator::CallKind call_kind, |
| + int argument_count) |
| : external_function_(external_function), |
| call_kind_(call_kind), |
| + argument_count_(argument_count), |
| break_instruction_(kRedirectInstruction), |
| next_(list_) { |
| list_ = this; |
| @@ -619,6 +660,7 @@ |
| uword external_function_; |
| Simulator::CallKind call_kind_; |
| + int argument_count_; |
| uint32_t break_instruction_; |
| Redirection* next_; |
| static Redirection* list_; |
| @@ -628,8 +670,11 @@ |
| Redirection* Redirection::list_ = NULL; |
| -uword Simulator::RedirectExternalReference(uword function, CallKind call_kind) { |
| - Redirection* redirection = Redirection::Get(function, call_kind); |
| +uword Simulator::RedirectExternalReference(uword function, |
| + CallKind call_kind, |
| + int argument_count) { |
| + Redirection* redirection = |
| + Redirection::Get(function, call_kind, argument_count); |
| return redirection->address_of_break_instruction(); |
| } |
| @@ -890,6 +935,9 @@ |
| typedef int32_t (*SimulatorLeafRuntimeCall)( |
| int32_t r0, int32_t r1, int32_t r2, int32_t r3); |
| +// Calls to leaf float Dart runtime functions are based on this interface. |
| +typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1); |
| + |
| // Calls to native Dart functions are based on this interface. |
| typedef void (*SimulatorNativeCall)(NativeArguments* arguments); |
| @@ -925,7 +973,8 @@ |
| OS::Print("Call to host function at 0x%"Pd"\n", external); |
| } |
| - if (redirection->call_kind() != kLeafRuntimeCall) { |
| + if ((redirection->call_kind() == kRuntimeCall) || |
| + (redirection->call_kind() == kNativeCall)) { |
| // The top_exit_frame_info of the current isolate points to the top of |
| // the simulator stack. |
| ASSERT((StackTop() - Isolate::Current()->top_exit_frame_info()) < |
| @@ -953,6 +1002,17 @@ |
| reinterpret_cast<SimulatorLeafRuntimeCall>(external); |
| a0 = target(a0, a1, a2, a3); |
| set_register(V0, a0); // Set returned result from function. |
| + } else if (redirection->call_kind() == kLeafFloatRuntimeCall) { |
| + ASSERT((0 <= redirection->argument_count()) && |
| + (redirection->argument_count() <= 2)); |
| + // double values are passed and returned in vfp registers. |
|
regis
2013/06/15 09:52:48
Is "vfp" a meaningful term for MIPS?
zra
2013/06/17 15:58:15
Changed to 'floating point'.
|
| + SimulatorLeafFloatRuntimeCall target = |
| + reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external); |
| + double d0 = 0.0; |
| + double d6 = get_fregister_double(F12); |
| + double d7 = get_fregister_double(F14); |
| + d0 = target(d6, d7); |
| + set_fregister_double(F0, d0); |
| } else { |
| ASSERT(redirection->call_kind() == kNativeCall); |
| NativeArguments* arguments; |
| @@ -986,7 +1046,7 @@ |
| // Zap floating point registers. |
| int32_t zap_dvalue = icount_; |
| - for (int i = F0; i <= F31; i++) { |
| + for (int i = F4; i <= F18; i++) { |
| set_fregister(static_cast<FRegister>(i), zap_dvalue); |
| } |
| @@ -1109,6 +1169,20 @@ |
| set_register(instr->RdField(), get_lo_register()); |
| break; |
| } |
| + case MOVCI: { |
| + ASSERT(instr->SaField() == 0); |
| + ASSERT(instr->Bit(17) == 0); |
| + int32_t rs_val = get_register(instr->RsField()); |
| + uint32_t cc, fcsr_cc, test, status; |
| + cc = instr->Bits(18, 3); |
| + fcsr_cc = get_fcsr_condition_bit(cc); |
| + test = instr->Bit(16); |
| + status = test_fcsr_bit(fcsr_cc); |
| + if (test == status) { |
| + set_register(instr->RdField(), rs_val); |
| + } |
| + break; |
| + } |
| case MOVN: { |
| ASSERT(instr->SaField() == 0); |
| // Format(instr, "movn 'rd, 'rs, 'rt"); |
| @@ -1520,6 +1594,12 @@ |
| set_fregister_double(instr->FdField(), fs_dbl); |
| break; |
| } |
| + case FMT_S: { |
| + float fs_flt = get_fregister_float(instr->FsField()); |
| + double fs_dbl = static_cast<double>(fs_flt); |
| + set_fregister_double(instr->FdField(), fs_dbl); |
| + break; |
| + } |
| case FMT_L: { |
| int64_t fs_int = get_fregister_long(instr->FsField()); |
| double fs_dbl = static_cast<double>(fs_int); |