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 floating point registers. |
| 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 |