OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <cmath> | 6 #include <cmath> |
7 #include <cstdarg> | 7 #include <cstdarg> |
8 | 8 |
9 #if V8_TARGET_ARCH_ARM64 | 9 #if V8_TARGET_ARCH_ARM64 |
10 | 10 |
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 Redirection* first) { | 531 Redirection* first) { |
532 Redirection::DeleteChain(first); | 532 Redirection::DeleteChain(first); |
533 } | 533 } |
534 | 534 |
535 | 535 |
536 // Calls into the V8 runtime are based on this very simple interface. | 536 // Calls into the V8 runtime are based on this very simple interface. |
537 // Note: To be able to return two values from some calls the code in runtime.cc | 537 // Note: To be able to return two values from some calls the code in runtime.cc |
538 // uses the ObjectPair structure. | 538 // uses the ObjectPair structure. |
539 // The simulator assumes all runtime calls return two 64-bits values. If they | 539 // The simulator assumes all runtime calls return two 64-bits values. If they |
540 // don't, register x1 is clobbered. This is fine because x1 is caller-saved. | 540 // don't, register x1 is clobbered. This is fine because x1 is caller-saved. |
541 typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0, | 541 typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0, int64_t arg1, |
542 int64_t arg1, | 542 int64_t arg2, int64_t arg3, |
543 int64_t arg2, | 543 int64_t arg4, int64_t arg5, |
544 int64_t arg3, | 544 int64_t arg6, int64_t arg7, |
545 int64_t arg4, | 545 int64_t arg8); |
546 int64_t arg5, | |
547 int64_t arg6, | |
548 int64_t arg7); | |
549 | 546 |
550 typedef ObjectTriple (*SimulatorRuntimeTripleCall)(int64_t arg0, int64_t arg1, | 547 typedef ObjectTriple (*SimulatorRuntimeTripleCall)(int64_t arg0, int64_t arg1, |
551 int64_t arg2, int64_t arg3, | 548 int64_t arg2, int64_t arg3, |
552 int64_t arg4, int64_t arg5, | 549 int64_t arg4, int64_t arg5, |
553 int64_t arg6, int64_t arg7); | 550 int64_t arg6, int64_t arg7); |
554 | 551 |
555 typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2); | 552 typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2); |
556 typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2); | 553 typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2); |
557 typedef double (*SimulatorRuntimeFPCall)(double arg1); | 554 typedef double (*SimulatorRuntimeFPCall)(double arg1); |
558 typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2); | 555 typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2); |
(...skipping 21 matching lines...) Expand all Loading... |
580 TraceSim("Call to host function at %p\n", | 577 TraceSim("Call to host function at %p\n", |
581 redirection->external_function<void*>()); | 578 redirection->external_function<void*>()); |
582 | 579 |
583 // SP must be 16-byte-aligned at the call interface. | 580 // SP must be 16-byte-aligned at the call interface. |
584 bool stack_alignment_exception = ((sp() & 0xf) != 0); | 581 bool stack_alignment_exception = ((sp() & 0xf) != 0); |
585 if (stack_alignment_exception) { | 582 if (stack_alignment_exception) { |
586 TraceSim(" with unaligned stack 0x%016" PRIx64 ".\n", sp()); | 583 TraceSim(" with unaligned stack 0x%016" PRIx64 ".\n", sp()); |
587 FATAL("ALIGNMENT EXCEPTION"); | 584 FATAL("ALIGNMENT EXCEPTION"); |
588 } | 585 } |
589 | 586 |
| 587 int64_t* stack_pointer = reinterpret_cast<int64_t*>(sp()); |
| 588 |
| 589 const int64_t arg0 = xreg(0); |
| 590 const int64_t arg1 = xreg(1); |
| 591 const int64_t arg2 = xreg(2); |
| 592 const int64_t arg3 = xreg(3); |
| 593 const int64_t arg4 = xreg(4); |
| 594 const int64_t arg5 = xreg(5); |
| 595 const int64_t arg6 = xreg(6); |
| 596 const int64_t arg7 = xreg(7); |
| 597 const int64_t arg8 = stack_pointer[0]; |
| 598 STATIC_ASSERT(kMaxCParameters == 9); |
| 599 |
590 switch (redirection->type()) { | 600 switch (redirection->type()) { |
591 default: | 601 default: |
592 TraceSim("Type: Unknown.\n"); | 602 TraceSim("Type: Unknown.\n"); |
593 UNREACHABLE(); | 603 UNREACHABLE(); |
594 break; | 604 break; |
595 | 605 |
596 case ExternalReference::BUILTIN_CALL: | 606 case ExternalReference::BUILTIN_CALL: |
597 case ExternalReference::BUILTIN_CALL_PAIR: { | 607 case ExternalReference::BUILTIN_CALL_PAIR: { |
598 // Object* f(v8::internal::Arguments) or | 608 // Object* f(v8::internal::Arguments) or |
599 // ObjectPair f(v8::internal::Arguments). | 609 // ObjectPair f(v8::internal::Arguments). |
600 TraceSim("Type: BUILTIN_CALL\n"); | 610 TraceSim("Type: BUILTIN_CALL\n"); |
601 SimulatorRuntimeCall target = | 611 SimulatorRuntimeCall target = |
602 reinterpret_cast<SimulatorRuntimeCall>(external); | 612 reinterpret_cast<SimulatorRuntimeCall>(external); |
603 | 613 |
604 // We don't know how many arguments are being passed, but we can | 614 // We don't know how many arguments are being passed, but we can |
605 // pass 8 without touching the stack. They will be ignored by the | 615 // pass 8 without touching the stack. They will be ignored by the |
606 // host function if they aren't used. | 616 // host function if they aren't used. |
607 TraceSim("Arguments: " | 617 TraceSim( |
608 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | 618 "Arguments: " |
609 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | 619 "0x%016" PRIx64 ", 0x%016" PRIx64 |
610 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | 620 ", " |
611 "0x%016" PRIx64 ", 0x%016" PRIx64, | 621 "0x%016" PRIx64 ", 0x%016" PRIx64 |
612 xreg(0), xreg(1), xreg(2), xreg(3), | 622 ", " |
613 xreg(4), xreg(5), xreg(6), xreg(7)); | 623 "0x%016" PRIx64 ", 0x%016" PRIx64 |
614 ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3), | 624 ", " |
615 xreg(4), xreg(5), xreg(6), xreg(7)); | 625 "0x%016" PRIx64 ", 0x%016" PRIx64 |
| 626 ", " |
| 627 "0x%016" PRIx64, |
| 628 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); |
| 629 ObjectPair result = |
| 630 target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); |
616 TraceSim("Returned: {%p, %p}\n", static_cast<void*>(result.x), | 631 TraceSim("Returned: {%p, %p}\n", static_cast<void*>(result.x), |
617 static_cast<void*>(result.y)); | 632 static_cast<void*>(result.y)); |
618 #ifdef DEBUG | 633 #ifdef DEBUG |
619 CorruptAllCallerSavedCPURegisters(); | 634 CorruptAllCallerSavedCPURegisters(); |
620 #endif | 635 #endif |
621 set_xreg(0, reinterpret_cast<int64_t>(result.x)); | 636 set_xreg(0, reinterpret_cast<int64_t>(result.x)); |
622 set_xreg(1, reinterpret_cast<int64_t>(result.y)); | 637 set_xreg(1, reinterpret_cast<int64_t>(result.y)); |
623 break; | 638 break; |
624 } | 639 } |
625 | 640 |
626 case ExternalReference::BUILTIN_CALL_TRIPLE: { | 641 case ExternalReference::BUILTIN_CALL_TRIPLE: { |
627 // ObjectTriple f(v8::internal::Arguments). | 642 // ObjectTriple f(v8::internal::Arguments). |
628 TraceSim("Type: BUILTIN_CALL TRIPLE\n"); | 643 TraceSim("Type: BUILTIN_CALL TRIPLE\n"); |
629 SimulatorRuntimeTripleCall target = | 644 SimulatorRuntimeTripleCall target = |
630 reinterpret_cast<SimulatorRuntimeTripleCall>(external); | 645 reinterpret_cast<SimulatorRuntimeTripleCall>(external); |
631 | 646 |
632 // We don't know how many arguments are being passed, but we can | 647 // We don't know how many arguments are being passed, but we can |
633 // pass 8 without touching the stack. They will be ignored by the | 648 // pass 8 without touching the stack. They will be ignored by the |
634 // host function if they aren't used. | 649 // host function if they aren't used. |
635 TraceSim( | 650 TraceSim( |
636 "Arguments: " | 651 "Arguments: " |
637 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | 652 "0x%016" PRIx64 ", 0x%016" PRIx64 |
638 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | 653 ", " |
639 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | 654 "0x%016" PRIx64 ", 0x%016" PRIx64 |
| 655 ", " |
| 656 "0x%016" PRIx64 ", 0x%016" PRIx64 |
| 657 ", " |
640 "0x%016" PRIx64 ", 0x%016" PRIx64, | 658 "0x%016" PRIx64 ", 0x%016" PRIx64, |
641 xreg(0), xreg(1), xreg(2), xreg(3), xreg(4), xreg(5), xreg(6), | 659 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); |
642 xreg(7)); | |
643 // Return location passed in x8. | 660 // Return location passed in x8. |
644 ObjectTriple* sim_result = reinterpret_cast<ObjectTriple*>(xreg(8)); | 661 ObjectTriple* sim_result = reinterpret_cast<ObjectTriple*>(xreg(8)); |
645 ObjectTriple result = target(xreg(0), xreg(1), xreg(2), xreg(3), xreg(4), | 662 ObjectTriple result = |
646 xreg(5), xreg(6), xreg(7)); | 663 target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); |
647 TraceSim("Returned: {%p, %p, %p}\n", static_cast<void*>(result.x), | 664 TraceSim("Returned: {%p, %p, %p}\n", static_cast<void*>(result.x), |
648 static_cast<void*>(result.y), static_cast<void*>(result.z)); | 665 static_cast<void*>(result.y), static_cast<void*>(result.z)); |
649 #ifdef DEBUG | 666 #ifdef DEBUG |
650 CorruptAllCallerSavedCPURegisters(); | 667 CorruptAllCallerSavedCPURegisters(); |
651 #endif | 668 #endif |
652 *sim_result = result; | 669 *sim_result = result; |
653 break; | 670 break; |
654 } | 671 } |
655 | 672 |
656 case ExternalReference::DIRECT_API_CALL: { | 673 case ExternalReference::DIRECT_API_CALL: { |
(...skipping 3528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4185 processor->prev_ = nullptr; | 4202 processor->prev_ = nullptr; |
4186 processor->next_ = nullptr; | 4203 processor->next_ = nullptr; |
4187 } | 4204 } |
4188 | 4205 |
4189 #endif // USE_SIMULATOR | 4206 #endif // USE_SIMULATOR |
4190 | 4207 |
4191 } // namespace internal | 4208 } // namespace internal |
4192 } // namespace v8 | 4209 } // namespace v8 |
4193 | 4210 |
4194 #endif // V8_TARGET_ARCH_ARM64 | 4211 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |