Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <math.h> // for isnan. | 5 #include <math.h> // for isnan. |
| 6 #include <setjmp.h> | 6 #include <setjmp.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
| 10 #if defined(TARGET_ARCH_MIPS) | 10 #if defined(TARGET_ARCH_MIPS) |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 | 85 |
| 86 void Stop(Instr* instr, const char* message); | 86 void Stop(Instr* instr, const char* message); |
| 87 void Debug(); | 87 void Debug(); |
| 88 char* ReadLine(const char* prompt); | 88 char* ReadLine(const char* prompt); |
| 89 | 89 |
| 90 private: | 90 private: |
| 91 Simulator* sim_; | 91 Simulator* sim_; |
| 92 | 92 |
| 93 bool GetValue(char* desc, uint32_t* value); | 93 bool GetValue(char* desc, uint32_t* value); |
| 94 bool GetFValue(char* desc, double* value); | 94 bool GetFValue(char* desc, double* value); |
| 95 bool GetDValue(char* desc, double* value); | |
| 95 | 96 |
| 96 // Set or delete a breakpoint. Returns true if successful. | 97 // Set or delete a breakpoint. Returns true if successful. |
| 97 bool SetBreakpoint(Instr* breakpc); | 98 bool SetBreakpoint(Instr* breakpc); |
| 98 bool DeleteBreakpoint(Instr* breakpc); | 99 bool DeleteBreakpoint(Instr* breakpc); |
| 99 | 100 |
| 100 // Undo and redo all breakpoints. This is needed to bracket disassembly and | 101 // Undo and redo all breakpoints. This is needed to bracket disassembly and |
| 101 // execution to skip past breakpoints when run from the debugger. | 102 // execution to skip past breakpoints when run from the debugger. |
| 102 void UndoBreakpoints(); | 103 void UndoBreakpoints(); |
| 103 void RedoBreakpoints(); | 104 void RedoBreakpoints(); |
| 104 }; | 105 }; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 return false; | 220 return false; |
| 220 } | 221 } |
| 221 *value = *(reinterpret_cast<float*>(addr)); | 222 *value = *(reinterpret_cast<float*>(addr)); |
| 222 return true; | 223 return true; |
| 223 } | 224 } |
| 224 } | 225 } |
| 225 return false; | 226 return false; |
| 226 } | 227 } |
| 227 | 228 |
| 228 | 229 |
| 230 bool SimulatorDebugger::GetDValue(char* desc, double* value) { | |
| 231 FRegister freg = LookupFRegisterByName(desc); | |
| 232 if (freg != kNoFRegister) { | |
| 233 *value = sim_->get_fregister_double(freg); | |
| 234 return true; | |
| 235 } | |
| 236 if (desc[0] == '*') { | |
| 237 uint32_t addr; | |
| 238 if (GetValue(desc + 1, &addr)) { | |
| 239 if (Simulator::IsIllegalAddress(addr)) { | |
| 240 return false; | |
| 241 } | |
| 242 *value = *(reinterpret_cast<double*>(addr)); | |
| 243 return true; | |
| 244 } | |
| 245 } | |
| 246 return false; | |
| 247 } | |
| 248 | |
| 249 | |
| 229 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) { | 250 bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) { |
| 230 // Check if a breakpoint can be set. If not return without any side-effects. | 251 // Check if a breakpoint can be set. If not return without any side-effects. |
| 231 if (sim_->break_pc_ != NULL) { | 252 if (sim_->break_pc_ != NULL) { |
| 232 return false; | 253 return false; |
| 233 } | 254 } |
| 234 | 255 |
| 235 // Set the breakpoint. | 256 // Set the breakpoint. |
| 236 sim_->break_pc_ = breakpc; | 257 sim_->break_pc_ = breakpc; |
| 237 sim_->break_instr_ = breakpc->InstructionBits(); | 258 sim_->break_instr_ = breakpc->InstructionBits(); |
| 238 // Not setting the breakpoint instruction in the code itself. It will be set | 259 // Not setting the breakpoint instruction in the code itself. It will be set |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 if (GetFValue(arg1, &dvalue)) { | 375 if (GetFValue(arg1, &dvalue)) { |
| 355 uint64_t long_value = bit_cast<uint64_t, double>(dvalue); | 376 uint64_t long_value = bit_cast<uint64_t, double>(dvalue); |
| 356 OS::Print("%s: %llu 0x%llx %.8g\n", | 377 OS::Print("%s: %llu 0x%llx %.8g\n", |
| 357 arg1, long_value, long_value, dvalue); | 378 arg1, long_value, long_value, dvalue); |
| 358 } else { | 379 } else { |
| 359 OS::Print("%s unrecognized\n", arg1); | 380 OS::Print("%s unrecognized\n", arg1); |
| 360 } | 381 } |
| 361 } else { | 382 } else { |
| 362 OS::Print("printfloat <dreg or *addr>\n"); | 383 OS::Print("printfloat <dreg or *addr>\n"); |
| 363 } | 384 } |
| 385 } else if ((strcmp(cmd, "pd") == 0) || | |
| 386 (strcmp(cmd, "printdouble") == 0)) { | |
| 387 if (args == 2) { | |
| 388 double dvalue; | |
| 389 if (GetDValue(arg1, &dvalue)) { | |
| 390 uint64_t long_value = bit_cast<uint64_t, double>(dvalue); | |
| 391 OS::Print("%s: %llu 0x%llx %.8g\n", | |
| 392 arg1, long_value, long_value, dvalue); | |
| 393 } else { | |
| 394 OS::Print("%s unrecognized\n", arg1); | |
| 395 } | |
| 396 } else { | |
| 397 OS::Print("printfloat <dreg or *addr>\n"); | |
| 398 } | |
| 364 } else if ((strcmp(cmd, "po") == 0) || | 399 } else if ((strcmp(cmd, "po") == 0) || |
| 365 (strcmp(cmd, "printobject") == 0)) { | 400 (strcmp(cmd, "printobject") == 0)) { |
| 366 if (args == 2) { | 401 if (args == 2) { |
| 367 uint32_t value; | 402 uint32_t value; |
| 368 // Make the dereferencing '*' optional. | 403 // Make the dereferencing '*' optional. |
| 369 if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) || | 404 if (((arg1[0] == '*') && GetValue(arg1 + 1, &value)) || |
| 370 GetValue(arg1, &value)) { | 405 GetValue(arg1, &value)) { |
| 371 if (Isolate::Current()->heap()->Contains(value)) { | 406 if (Isolate::Current()->heap()->Contains(value)) { |
| 372 OS::Print("%s: \n", arg1); | 407 OS::Print("%s: \n", arg1); |
| 373 #if defined(DEBUG) | 408 #if defined(DEBUG) |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 582 class Redirection { | 617 class Redirection { |
| 583 public: | 618 public: |
| 584 uword address_of_break_instruction() { | 619 uword address_of_break_instruction() { |
| 585 return reinterpret_cast<uword>(&break_instruction_); | 620 return reinterpret_cast<uword>(&break_instruction_); |
| 586 } | 621 } |
| 587 | 622 |
| 588 uword external_function() const { return external_function_; } | 623 uword external_function() const { return external_function_; } |
| 589 | 624 |
| 590 Simulator::CallKind call_kind() const { return call_kind_; } | 625 Simulator::CallKind call_kind() const { return call_kind_; } |
| 591 | 626 |
| 627 int argument_count() const { return argument_count_; } | |
| 628 | |
| 592 static Redirection* Get(uword external_function, | 629 static Redirection* Get(uword external_function, |
| 593 Simulator::CallKind call_kind) { | 630 Simulator::CallKind call_kind, |
| 631 int argument_count) { | |
| 594 Redirection* current; | 632 Redirection* current; |
| 595 for (current = list_; current != NULL; current = current->next_) { | 633 for (current = list_; current != NULL; current = current->next_) { |
| 596 if (current->external_function_ == external_function) return current; | 634 if (current->external_function_ == external_function) return current; |
| 597 } | 635 } |
| 598 return new Redirection(external_function, call_kind); | 636 return new Redirection(external_function, call_kind, argument_count); |
| 599 } | 637 } |
| 600 | 638 |
| 601 static Redirection* FromBreakInstruction(Instr* break_instruction) { | 639 static Redirection* FromBreakInstruction(Instr* break_instruction) { |
| 602 char* addr_of_break = reinterpret_cast<char*>(break_instruction); | 640 char* addr_of_break = reinterpret_cast<char*>(break_instruction); |
| 603 char* addr_of_redirection = | 641 char* addr_of_redirection = |
| 604 addr_of_break - OFFSET_OF(Redirection, break_instruction_); | 642 addr_of_break - OFFSET_OF(Redirection, break_instruction_); |
| 605 return reinterpret_cast<Redirection*>(addr_of_redirection); | 643 return reinterpret_cast<Redirection*>(addr_of_redirection); |
| 606 } | 644 } |
| 607 | 645 |
| 608 private: | 646 private: |
| 609 static const int32_t kRedirectInstruction = | 647 static const int32_t kRedirectInstruction = |
| 610 Instr::kBreakPointInstruction | (Instr::kRedirectCode << kBreakCodeShift); | 648 Instr::kBreakPointInstruction | (Instr::kRedirectCode << kBreakCodeShift); |
| 611 | 649 |
| 612 Redirection(uword external_function, Simulator::CallKind call_kind) | 650 Redirection(uword external_function, |
| 651 Simulator::CallKind call_kind, | |
| 652 int argument_count) | |
| 613 : external_function_(external_function), | 653 : external_function_(external_function), |
| 614 call_kind_(call_kind), | 654 call_kind_(call_kind), |
| 655 argument_count_(argument_count), | |
| 615 break_instruction_(kRedirectInstruction), | 656 break_instruction_(kRedirectInstruction), |
| 616 next_(list_) { | 657 next_(list_) { |
| 617 list_ = this; | 658 list_ = this; |
| 618 } | 659 } |
| 619 | 660 |
| 620 uword external_function_; | 661 uword external_function_; |
| 621 Simulator::CallKind call_kind_; | 662 Simulator::CallKind call_kind_; |
| 663 int argument_count_; | |
| 622 uint32_t break_instruction_; | 664 uint32_t break_instruction_; |
| 623 Redirection* next_; | 665 Redirection* next_; |
| 624 static Redirection* list_; | 666 static Redirection* list_; |
| 625 }; | 667 }; |
| 626 | 668 |
| 627 | 669 |
| 628 Redirection* Redirection::list_ = NULL; | 670 Redirection* Redirection::list_ = NULL; |
| 629 | 671 |
| 630 | 672 |
| 631 uword Simulator::RedirectExternalReference(uword function, CallKind call_kind) { | 673 uword Simulator::RedirectExternalReference(uword function, |
| 632 Redirection* redirection = Redirection::Get(function, call_kind); | 674 CallKind call_kind, |
| 675 int argument_count) { | |
| 676 Redirection* redirection = | |
| 677 Redirection::Get(function, call_kind, argument_count); | |
| 633 return redirection->address_of_break_instruction(); | 678 return redirection->address_of_break_instruction(); |
| 634 } | 679 } |
| 635 | 680 |
| 636 | 681 |
| 637 // Get the active Simulator for the current isolate. | 682 // Get the active Simulator for the current isolate. |
| 638 Simulator* Simulator::Current() { | 683 Simulator* Simulator::Current() { |
| 639 Simulator* simulator = Isolate::Current()->simulator(); | 684 Simulator* simulator = Isolate::Current()->simulator(); |
| 640 if (simulator == NULL) { | 685 if (simulator == NULL) { |
| 641 simulator = new Simulator(); | 686 simulator = new Simulator(); |
| 642 Isolate::Current()->set_simulator(simulator); | 687 Isolate::Current()->set_simulator(simulator); |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 } | 928 } |
| 884 | 929 |
| 885 | 930 |
| 886 // Calls into the Dart runtime are based on this interface. | 931 // Calls into the Dart runtime are based on this interface. |
| 887 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); | 932 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); |
| 888 | 933 |
| 889 // Calls to leaf Dart runtime functions are based on this interface. | 934 // Calls to leaf Dart runtime functions are based on this interface. |
| 890 typedef int32_t (*SimulatorLeafRuntimeCall)( | 935 typedef int32_t (*SimulatorLeafRuntimeCall)( |
| 891 int32_t r0, int32_t r1, int32_t r2, int32_t r3); | 936 int32_t r0, int32_t r1, int32_t r2, int32_t r3); |
| 892 | 937 |
| 938 // Calls to leaf float Dart runtime functions are based on this interface. | |
| 939 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1); | |
| 940 | |
| 893 // Calls to native Dart functions are based on this interface. | 941 // Calls to native Dart functions are based on this interface. |
| 894 typedef void (*SimulatorNativeCall)(NativeArguments* arguments); | 942 typedef void (*SimulatorNativeCall)(NativeArguments* arguments); |
| 895 | 943 |
| 896 | 944 |
| 897 void Simulator::DoBreak(Instr *instr) { | 945 void Simulator::DoBreak(Instr *instr) { |
| 898 ASSERT(instr->OpcodeField() == SPECIAL); | 946 ASSERT(instr->OpcodeField() == SPECIAL); |
| 899 ASSERT(instr->FunctionField() == BREAK); | 947 ASSERT(instr->FunctionField() == BREAK); |
| 900 if (instr->BreakCodeField() == Instr::kStopMessageCode) { | 948 if (instr->BreakCodeField() == Instr::kStopMessageCode) { |
| 901 SimulatorDebugger dbg(this); | 949 SimulatorDebugger dbg(this); |
| 902 const char* message = *reinterpret_cast<const char**>( | 950 const char* message = *reinterpret_cast<const char**>( |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 918 SimulatorSetjmpBuffer buffer(this); | 966 SimulatorSetjmpBuffer buffer(this); |
| 919 | 967 |
| 920 if (!setjmp(buffer.buffer_)) { | 968 if (!setjmp(buffer.buffer_)) { |
| 921 int32_t saved_ra = get_register(RA); | 969 int32_t saved_ra = get_register(RA); |
| 922 Redirection* redirection = Redirection::FromBreakInstruction(instr); | 970 Redirection* redirection = Redirection::FromBreakInstruction(instr); |
| 923 uword external = redirection->external_function(); | 971 uword external = redirection->external_function(); |
| 924 if (FLAG_trace_sim) { | 972 if (FLAG_trace_sim) { |
| 925 OS::Print("Call to host function at 0x%"Pd"\n", external); | 973 OS::Print("Call to host function at 0x%"Pd"\n", external); |
| 926 } | 974 } |
| 927 | 975 |
| 928 if (redirection->call_kind() != kLeafRuntimeCall) { | 976 if ((redirection->call_kind() == kRuntimeCall) || |
| 977 (redirection->call_kind() == kNativeCall)) { | |
| 929 // The top_exit_frame_info of the current isolate points to the top of | 978 // The top_exit_frame_info of the current isolate points to the top of |
| 930 // the simulator stack. | 979 // the simulator stack. |
| 931 ASSERT((StackTop() - Isolate::Current()->top_exit_frame_info()) < | 980 ASSERT((StackTop() - Isolate::Current()->top_exit_frame_info()) < |
| 932 Isolate::GetSpecifiedStackSize()); | 981 Isolate::GetSpecifiedStackSize()); |
| 933 // Set the top_exit_frame_info of this simulator to the native stack. | 982 // Set the top_exit_frame_info of this simulator to the native stack. |
| 934 set_top_exit_frame_info(reinterpret_cast<uword>(&buffer)); | 983 set_top_exit_frame_info(reinterpret_cast<uword>(&buffer)); |
| 935 } | 984 } |
| 936 if (redirection->call_kind() == kRuntimeCall) { | 985 if (redirection->call_kind() == kRuntimeCall) { |
| 937 NativeArguments arguments; | 986 NativeArguments arguments; |
| 938 ASSERT(sizeof(NativeArguments) == 4*kWordSize); | 987 ASSERT(sizeof(NativeArguments) == 4*kWordSize); |
| 939 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(A0)); | 988 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(A0)); |
| 940 arguments.argc_tag_ = get_register(A1); | 989 arguments.argc_tag_ = get_register(A1); |
| 941 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(A2)); | 990 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(A2)); |
| 942 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(A3)); | 991 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(A3)); |
| 943 SimulatorRuntimeCall target = | 992 SimulatorRuntimeCall target = |
| 944 reinterpret_cast<SimulatorRuntimeCall>(external); | 993 reinterpret_cast<SimulatorRuntimeCall>(external); |
| 945 target(arguments); | 994 target(arguments); |
| 946 set_register(V0, icount_); // Zap result register from void function. | 995 set_register(V0, icount_); // Zap result register from void function. |
| 947 } else if (redirection->call_kind() == kLeafRuntimeCall) { | 996 } else if (redirection->call_kind() == kLeafRuntimeCall) { |
| 948 int32_t a0 = get_register(A0); | 997 int32_t a0 = get_register(A0); |
| 949 int32_t a1 = get_register(A1); | 998 int32_t a1 = get_register(A1); |
| 950 int32_t a2 = get_register(A2); | 999 int32_t a2 = get_register(A2); |
| 951 int32_t a3 = get_register(A3); | 1000 int32_t a3 = get_register(A3); |
| 952 SimulatorLeafRuntimeCall target = | 1001 SimulatorLeafRuntimeCall target = |
| 953 reinterpret_cast<SimulatorLeafRuntimeCall>(external); | 1002 reinterpret_cast<SimulatorLeafRuntimeCall>(external); |
| 954 a0 = target(a0, a1, a2, a3); | 1003 a0 = target(a0, a1, a2, a3); |
| 955 set_register(V0, a0); // Set returned result from function. | 1004 set_register(V0, a0); // Set returned result from function. |
| 1005 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) { | |
| 1006 ASSERT((0 <= redirection->argument_count()) && | |
| 1007 (redirection->argument_count() <= 2)); | |
| 1008 // 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'.
| |
| 1009 SimulatorLeafFloatRuntimeCall target = | |
| 1010 reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external); | |
| 1011 double d0 = 0.0; | |
| 1012 double d6 = get_fregister_double(F12); | |
| 1013 double d7 = get_fregister_double(F14); | |
| 1014 d0 = target(d6, d7); | |
| 1015 set_fregister_double(F0, d0); | |
| 956 } else { | 1016 } else { |
| 957 ASSERT(redirection->call_kind() == kNativeCall); | 1017 ASSERT(redirection->call_kind() == kNativeCall); |
| 958 NativeArguments* arguments; | 1018 NativeArguments* arguments; |
| 959 arguments = reinterpret_cast<NativeArguments*>(get_register(A0)); | 1019 arguments = reinterpret_cast<NativeArguments*>(get_register(A0)); |
| 960 SimulatorNativeCall target = | 1020 SimulatorNativeCall target = |
| 961 reinterpret_cast<SimulatorNativeCall>(external); | 1021 reinterpret_cast<SimulatorNativeCall>(external); |
| 962 target(arguments); | 1022 target(arguments); |
| 963 set_register(V0, icount_); // Zap result register from void function. | 1023 set_register(V0, icount_); // Zap result register from void function. |
| 964 } | 1024 } |
| 965 set_top_exit_frame_info(0); | 1025 set_top_exit_frame_info(0); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 979 | 1039 |
| 980 set_register(A0, icount_); | 1040 set_register(A0, icount_); |
| 981 set_register(A1, icount_); | 1041 set_register(A1, icount_); |
| 982 set_register(A2, icount_); | 1042 set_register(A2, icount_); |
| 983 set_register(A3, icount_); | 1043 set_register(A3, icount_); |
| 984 set_register(TMP, icount_); | 1044 set_register(TMP, icount_); |
| 985 set_register(RA, icount_); | 1045 set_register(RA, icount_); |
| 986 | 1046 |
| 987 // Zap floating point registers. | 1047 // Zap floating point registers. |
| 988 int32_t zap_dvalue = icount_; | 1048 int32_t zap_dvalue = icount_; |
| 989 for (int i = F0; i <= F31; i++) { | 1049 for (int i = F4; i <= F18; i++) { |
| 990 set_fregister(static_cast<FRegister>(i), zap_dvalue); | 1050 set_fregister(static_cast<FRegister>(i), zap_dvalue); |
| 991 } | 1051 } |
| 992 | 1052 |
| 993 // Return. Subtract to account for pc_ increment after return. | 1053 // Return. Subtract to account for pc_ increment after return. |
| 994 set_pc(saved_ra - Instr::kInstrSize); | 1054 set_pc(saved_ra - Instr::kInstrSize); |
| 995 } else { | 1055 } else { |
| 996 // Coming via long jump from a throw. Continue to exception handler. | 1056 // Coming via long jump from a throw. Continue to exception handler. |
| 997 set_top_exit_frame_info(0); | 1057 set_top_exit_frame_info(0); |
| 998 // Adjust for extra pc increment. | 1058 // Adjust for extra pc increment. |
| 999 set_pc(get_pc() - Instr::kInstrSize); | 1059 set_pc(get_pc() - Instr::kInstrSize); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1102 break; | 1162 break; |
| 1103 } | 1163 } |
| 1104 case MFLO: { | 1164 case MFLO: { |
| 1105 ASSERT(instr->RsField() == 0); | 1165 ASSERT(instr->RsField() == 0); |
| 1106 ASSERT(instr->RtField() == 0); | 1166 ASSERT(instr->RtField() == 0); |
| 1107 ASSERT(instr->SaField() == 0); | 1167 ASSERT(instr->SaField() == 0); |
| 1108 // Format(instr, "mflo 'rd"); | 1168 // Format(instr, "mflo 'rd"); |
| 1109 set_register(instr->RdField(), get_lo_register()); | 1169 set_register(instr->RdField(), get_lo_register()); |
| 1110 break; | 1170 break; |
| 1111 } | 1171 } |
| 1172 case MOVCI: { | |
| 1173 ASSERT(instr->SaField() == 0); | |
| 1174 ASSERT(instr->Bit(17) == 0); | |
| 1175 int32_t rs_val = get_register(instr->RsField()); | |
| 1176 uint32_t cc, fcsr_cc, test, status; | |
| 1177 cc = instr->Bits(18, 3); | |
| 1178 fcsr_cc = get_fcsr_condition_bit(cc); | |
| 1179 test = instr->Bit(16); | |
| 1180 status = test_fcsr_bit(fcsr_cc); | |
| 1181 if (test == status) { | |
| 1182 set_register(instr->RdField(), rs_val); | |
| 1183 } | |
| 1184 break; | |
| 1185 } | |
| 1112 case MOVN: { | 1186 case MOVN: { |
| 1113 ASSERT(instr->SaField() == 0); | 1187 ASSERT(instr->SaField() == 0); |
| 1114 // Format(instr, "movn 'rd, 'rs, 'rt"); | 1188 // Format(instr, "movn 'rd, 'rs, 'rt"); |
| 1115 int32_t rt_val = get_register(instr->RtField()); | 1189 int32_t rt_val = get_register(instr->RtField()); |
| 1116 int32_t rs_val = get_register(instr->RsField()); | 1190 int32_t rs_val = get_register(instr->RsField()); |
| 1117 if (rt_val != 0) { | 1191 if (rt_val != 0) { |
| 1118 set_register(instr->RdField(), rs_val); | 1192 set_register(instr->RdField(), rs_val); |
| 1119 } | 1193 } |
| 1120 break; | 1194 break; |
| 1121 } | 1195 } |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1513 break; | 1587 break; |
| 1514 } | 1588 } |
| 1515 case COP1_CVT_D: { | 1589 case COP1_CVT_D: { |
| 1516 switch (instr->FormatField()) { | 1590 switch (instr->FormatField()) { |
| 1517 case FMT_W: { | 1591 case FMT_W: { |
| 1518 int32_t fs_int = get_fregister(instr->FsField()); | 1592 int32_t fs_int = get_fregister(instr->FsField()); |
| 1519 double fs_dbl = static_cast<double>(fs_int); | 1593 double fs_dbl = static_cast<double>(fs_int); |
| 1520 set_fregister_double(instr->FdField(), fs_dbl); | 1594 set_fregister_double(instr->FdField(), fs_dbl); |
| 1521 break; | 1595 break; |
| 1522 } | 1596 } |
| 1597 case FMT_S: { | |
| 1598 float fs_flt = get_fregister_float(instr->FsField()); | |
| 1599 double fs_dbl = static_cast<double>(fs_flt); | |
| 1600 set_fregister_double(instr->FdField(), fs_dbl); | |
| 1601 break; | |
| 1602 } | |
| 1523 case FMT_L: { | 1603 case FMT_L: { |
| 1524 int64_t fs_int = get_fregister_long(instr->FsField()); | 1604 int64_t fs_int = get_fregister_long(instr->FsField()); |
| 1525 double fs_dbl = static_cast<double>(fs_int); | 1605 double fs_dbl = static_cast<double>(fs_int); |
| 1526 set_fregister_double(instr->FdField(), fs_dbl); | 1606 set_fregister_double(instr->FdField(), fs_dbl); |
| 1527 break; | 1607 break; |
| 1528 } | 1608 } |
| 1529 default: { | 1609 default: { |
| 1530 OS::PrintErr("DecodeCop1: 0x%x\n", instr->InstructionBits()); | 1610 OS::PrintErr("DecodeCop1: 0x%x\n", instr->InstructionBits()); |
| 1531 UnimplementedInstruction(instr); | 1611 UnimplementedInstruction(instr); |
| 1532 break; | 1612 break; |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2052 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 2132 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 2053 } | 2133 } |
| 2054 buf->Longjmp(); | 2134 buf->Longjmp(); |
| 2055 } | 2135 } |
| 2056 | 2136 |
| 2057 } // namespace dart | 2137 } // namespace dart |
| 2058 | 2138 |
| 2059 #endif // !defined(HOST_ARCH_MIPS) | 2139 #endif // !defined(HOST_ARCH_MIPS) |
| 2060 | 2140 |
| 2061 #endif // defined TARGET_ARCH_MIPS | 2141 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |