Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: runtime/vm/simulator_arm.cc

Issue 16638012: Switch code generation on ARM from softfp ABI to hardfp ABI. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/simulator_arm.h ('k') | runtime/vm/store_buffer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_ARM) 10 #if defined(TARGET_ARCH_ARM)
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 class Redirection { 794 class Redirection {
795 public: 795 public:
796 uword address_of_svc_instruction() { 796 uword address_of_svc_instruction() {
797 return reinterpret_cast<uword>(&svc_instruction_); 797 return reinterpret_cast<uword>(&svc_instruction_);
798 } 798 }
799 799
800 uword external_function() const { return external_function_; } 800 uword external_function() const { return external_function_; }
801 801
802 Simulator::CallKind call_kind() const { return call_kind_; } 802 Simulator::CallKind call_kind() const { return call_kind_; }
803 803
804 int argument_count() const { return argument_count_; }
805
804 static Redirection* Get(uword external_function, 806 static Redirection* Get(uword external_function,
805 Simulator::CallKind call_kind) { 807 Simulator::CallKind call_kind,
808 int argument_count) {
806 Redirection* current; 809 Redirection* current;
807 for (current = list_; current != NULL; current = current->next_) { 810 for (current = list_; current != NULL; current = current->next_) {
808 if (current->external_function_ == external_function) return current; 811 if (current->external_function_ == external_function) return current;
809 } 812 }
810 return new Redirection(external_function, call_kind); 813 return new Redirection(external_function, call_kind, argument_count);
811 } 814 }
812 815
813 static Redirection* FromSvcInstruction(Instr* svc_instruction) { 816 static Redirection* FromSvcInstruction(Instr* svc_instruction) {
814 char* addr_of_svc = reinterpret_cast<char*>(svc_instruction); 817 char* addr_of_svc = reinterpret_cast<char*>(svc_instruction);
815 char* addr_of_redirection = 818 char* addr_of_redirection =
816 addr_of_svc - OFFSET_OF(Redirection, svc_instruction_); 819 addr_of_svc - OFFSET_OF(Redirection, svc_instruction_);
817 return reinterpret_cast<Redirection*>(addr_of_redirection); 820 return reinterpret_cast<Redirection*>(addr_of_redirection);
818 } 821 }
819 822
820 private: 823 private:
821 static const int32_t kRedirectSvcInstruction = 824 static const int32_t kRedirectSvcInstruction =
822 ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode); 825 ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode);
823 Redirection(uword external_function, Simulator::CallKind call_kind) 826 Redirection(uword external_function,
827 Simulator::CallKind call_kind,
828 int argument_count)
824 : external_function_(external_function), 829 : external_function_(external_function),
825 call_kind_(call_kind), 830 call_kind_(call_kind),
831 argument_count_(argument_count),
826 svc_instruction_(kRedirectSvcInstruction), 832 svc_instruction_(kRedirectSvcInstruction),
827 next_(list_) { 833 next_(list_) {
828 list_ = this; 834 list_ = this;
829 } 835 }
830 836
831 uword external_function_; 837 uword external_function_;
832 Simulator::CallKind call_kind_; 838 Simulator::CallKind call_kind_;
839 int argument_count_;
833 uint32_t svc_instruction_; 840 uint32_t svc_instruction_;
834 Redirection* next_; 841 Redirection* next_;
835 static Redirection* list_; 842 static Redirection* list_;
836 }; 843 };
837 844
838 845
839 Redirection* Redirection::list_ = NULL; 846 Redirection* Redirection::list_ = NULL;
840 847
841 848
842 uword Simulator::RedirectExternalReference(uword function, CallKind call_kind) { 849 uword Simulator::RedirectExternalReference(uword function,
843 Redirection* redirection = Redirection::Get(function, call_kind); 850 CallKind call_kind,
851 int argument_count) {
852 Redirection* redirection =
853 Redirection::Get(function, call_kind, argument_count);
844 return redirection->address_of_svc_instruction(); 854 return redirection->address_of_svc_instruction();
845 } 855 }
846 856
847 857
848 // Get the active Simulator for the current isolate. 858 // Get the active Simulator for the current isolate.
849 Simulator* Simulator::Current() { 859 Simulator* Simulator::Current() {
850 Simulator* simulator = Isolate::Current()->simulator(); 860 Simulator* simulator = Isolate::Current()->simulator();
851 if (simulator == NULL) { 861 if (simulator == NULL) {
852 simulator = new Simulator(); 862 simulator = new Simulator();
853 Isolate::Current()->set_simulator(simulator); 863 Isolate::Current()->set_simulator(simulator);
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 } 1433 }
1424 1434
1425 1435
1426 // Calls into the Dart runtime are based on this interface. 1436 // Calls into the Dart runtime are based on this interface.
1427 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); 1437 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
1428 1438
1429 // Calls to leaf Dart runtime functions are based on this interface. 1439 // Calls to leaf Dart runtime functions are based on this interface.
1430 typedef int32_t (*SimulatorLeafRuntimeCall)( 1440 typedef int32_t (*SimulatorLeafRuntimeCall)(
1431 int32_t r0, int32_t r1, int32_t r2, int32_t r3); 1441 int32_t r0, int32_t r1, int32_t r2, int32_t r3);
1432 1442
1443 // Calls to leaf float Dart runtime functions are based on this interface.
1444 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1);
1445
1433 // Calls to native Dart functions are based on this interface. 1446 // Calls to native Dart functions are based on this interface.
1434 typedef void (*SimulatorNativeCall)(NativeArguments* arguments); 1447 typedef void (*SimulatorNativeCall)(NativeArguments* arguments);
1435 1448
1436 1449
1437 void Simulator::SupervisorCall(Instr* instr) { 1450 void Simulator::SupervisorCall(Instr* instr) {
1438 int svc = instr->SvcField(); 1451 int svc = instr->SvcField();
1439 switch (svc) { 1452 switch (svc) {
1440 case kRedirectionSvcCode: { 1453 case kRedirectionSvcCode: {
1441 SimulatorSetjmpBuffer buffer(this); 1454 SimulatorSetjmpBuffer buffer(this);
1442 1455
1443 if (!setjmp(buffer.buffer_)) { 1456 if (!setjmp(buffer.buffer_)) {
1444 int32_t saved_lr = get_register(LR); 1457 int32_t saved_lr = get_register(LR);
1445 Redirection* redirection = Redirection::FromSvcInstruction(instr); 1458 Redirection* redirection = Redirection::FromSvcInstruction(instr);
1446 uword external = redirection->external_function(); 1459 uword external = redirection->external_function();
1447 if (FLAG_trace_sim) { 1460 if (FLAG_trace_sim) {
1448 OS::Print("Call to host function at 0x%"Pd"\n", external); 1461 OS::Print("Call to host function at 0x%"Pd"\n", external);
1449 } 1462 }
1450 1463
1451 if (redirection->call_kind() != kLeafRuntimeCall) { 1464 if ((redirection->call_kind() == kRuntimeCall) ||
1465 (redirection->call_kind() == kNativeCall)) {
1452 // The top_exit_frame_info of the current isolate points to the top of 1466 // The top_exit_frame_info of the current isolate points to the top of
1453 // the simulator stack. 1467 // the simulator stack.
1454 ASSERT((StackTop() - Isolate::Current()->top_exit_frame_info()) < 1468 ASSERT((StackTop() - Isolate::Current()->top_exit_frame_info()) <
1455 Isolate::GetSpecifiedStackSize()); 1469 Isolate::GetSpecifiedStackSize());
1456 // Set the top_exit_frame_info of this simulator to the native stack. 1470 // Set the top_exit_frame_info of this simulator to the native stack.
1457 set_top_exit_frame_info(reinterpret_cast<uword>(&buffer)); 1471 set_top_exit_frame_info(reinterpret_cast<uword>(&buffer));
1458 } 1472 }
1459 if (redirection->call_kind() == kRuntimeCall) { 1473 if (redirection->call_kind() == kRuntimeCall) {
1460 NativeArguments arguments; 1474 NativeArguments arguments;
1461 ASSERT(sizeof(NativeArguments) == 4*kWordSize); 1475 ASSERT(sizeof(NativeArguments) == 4*kWordSize);
1462 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0)); 1476 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0));
1463 arguments.argc_tag_ = get_register(R1); 1477 arguments.argc_tag_ = get_register(R1);
1464 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2)); 1478 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2));
1465 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3)); 1479 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
1466 SimulatorRuntimeCall target = 1480 SimulatorRuntimeCall target =
1467 reinterpret_cast<SimulatorRuntimeCall>(external); 1481 reinterpret_cast<SimulatorRuntimeCall>(external);
1468 target(arguments); 1482 target(arguments);
1469 set_register(R0, icount_); // Zap result register from void function. 1483 set_register(R0, icount_); // Zap result register from void function.
1470 } else if (redirection->call_kind() == kLeafRuntimeCall) { 1484 } else if (redirection->call_kind() == kLeafRuntimeCall) {
1485 ASSERT((0 <= redirection->argument_count()) &&
1486 (redirection->argument_count() <= 4));
1471 int32_t r0 = get_register(R0); 1487 int32_t r0 = get_register(R0);
1472 int32_t r1 = get_register(R1); 1488 int32_t r1 = get_register(R1);
1473 int32_t r2 = get_register(R2); 1489 int32_t r2 = get_register(R2);
1474 int32_t r3 = get_register(R3); 1490 int32_t r3 = get_register(R3);
1475 SimulatorLeafRuntimeCall target = 1491 SimulatorLeafRuntimeCall target =
1476 reinterpret_cast<SimulatorLeafRuntimeCall>(external); 1492 reinterpret_cast<SimulatorLeafRuntimeCall>(external);
1477 r0 = target(r0, r1, r2, r3); 1493 r0 = target(r0, r1, r2, r3);
1478 set_register(R0, r0); // Set returned result from function. 1494 set_register(R0, r0); // Set returned result from function.
1495 } else if (redirection->call_kind() == kLeafFloatRuntimeCall) {
1496 ASSERT((0 <= redirection->argument_count()) &&
1497 (redirection->argument_count() <= 2));
1498 // We currently use 'hardfp' ('gnueabihf') rather than 'softfp'
1499 // ('gnueabi') float ABI for leaf runtime calls, i.e. double values
1500 // are passed and returned in vfp registers rather than in integer
1501 // register pairs.
1502 SimulatorLeafFloatRuntimeCall target =
1503 reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external);
1504 double d0 = get_dregister(D0);
1505 double d1 = get_dregister(D1);
1506 d0 = target(d0, d1);
1507 set_dregister(D0, d0);
1479 } else { 1508 } else {
1480 ASSERT(redirection->call_kind() == kNativeCall); 1509 ASSERT(redirection->call_kind() == kNativeCall);
1481 NativeArguments* arguments; 1510 NativeArguments* arguments;
1482 arguments = reinterpret_cast<NativeArguments*>(get_register(R0)); 1511 arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
1483 SimulatorNativeCall target = 1512 SimulatorNativeCall target =
1484 reinterpret_cast<SimulatorNativeCall>(external); 1513 reinterpret_cast<SimulatorNativeCall>(external);
1485 target(arguments); 1514 target(arguments);
1486 set_register(R0, icount_); // Zap result register from void function. 1515 set_register(R0, icount_); // Zap result register from void function.
1487 } 1516 }
1488 set_top_exit_frame_info(0); 1517 set_top_exit_frame_info(0);
1489 1518
1490 // Zap caller-saved registers, since the actual runtime call could have 1519 // Zap caller-saved registers, since the actual runtime call could have
1491 // used them. 1520 // used them.
1492 set_register(R1, icount_); 1521 set_register(R1, icount_);
1493 set_register(R2, icount_); 1522 set_register(R2, icount_);
1494 set_register(R3, icount_); 1523 set_register(R3, icount_);
1495 set_register(IP, icount_); 1524 set_register(IP, icount_);
1496 set_register(LR, icount_); 1525 set_register(LR, icount_);
1497 double zap_dvalue = static_cast<double>(icount_); 1526 double zap_dvalue = static_cast<double>(icount_);
1498 for (int i = D0; i <= D7; i++) { 1527 // Do not zap D0, as it may contain a float result.
1528 for (int i = D1; i <= D7; i++) {
1499 set_dregister(static_cast<DRegister>(i), zap_dvalue); 1529 set_dregister(static_cast<DRegister>(i), zap_dvalue);
1500 } 1530 }
1501 // The above loop also zaps overlapping registers S0-S15. 1531 // The above loop also zaps overlapping registers S2-S15.
1502 // Registers D8-D15 (overlapping with S16-S31) are preserved. 1532 // Registers D8-D15 (overlapping with S16-S31) are preserved.
1503 #ifdef VFPv3_D32 1533 #ifdef VFPv3_D32
1504 for (int i = D16; i <= D31; i++) { 1534 for (int i = D16; i <= D31; i++) {
1505 set_dregister(static_cast<DRegister>(i), zap_dvalue); 1535 set_dregister(static_cast<DRegister>(i), zap_dvalue);
1506 } 1536 }
1507 #endif // VFPv3_D32 1537 #endif // VFPv3_D32
1508 1538
1509 // Return. 1539 // Return.
1510 set_pc(saved_lr); 1540 set_pc(saved_lr);
1511 } else { 1541 } else {
(...skipping 1537 matching lines...) Expand 10 before | Expand all | Expand 10 after
3049 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); 3079 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
3050 } 3080 }
3051 buf->Longjmp(); 3081 buf->Longjmp();
3052 } 3082 }
3053 3083
3054 } // namespace dart 3084 } // namespace dart
3055 3085
3056 #endif // !defined(HOST_ARCH_ARM) 3086 #endif // !defined(HOST_ARCH_ARM)
3057 3087
3058 #endif // defined TARGET_ARCH_ARM 3088 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm.h ('k') | runtime/vm/store_buffer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698