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 |
11 #include "src/arm64/decoder-arm64-inl.h" | 11 #include "src/arm64/decoder-arm64-inl.h" |
12 #include "src/arm64/simulator-arm64.h" | 12 #include "src/arm64/simulator-arm64.h" |
13 #include "src/assembler.h" | 13 #include "src/assembler.h" |
14 #include "src/codegen.h" | 14 #include "src/codegen.h" |
15 #include "src/disasm.h" | 15 #include "src/disasm.h" |
16 #include "src/macro-assembler.h" | 16 #include "src/macro-assembler.h" |
17 #include "src/ostreams.h" | 17 #include "src/ostreams.h" |
| 18 #include "src/runtime/runtime-utils.h" |
18 | 19 |
19 namespace v8 { | 20 namespace v8 { |
20 namespace internal { | 21 namespace internal { |
21 | 22 |
22 #if defined(USE_SIMULATOR) | 23 #if defined(USE_SIMULATOR) |
23 | 24 |
24 | 25 |
25 // This macro provides a platform independent use of sscanf. The reason for | 26 // This macro provides a platform independent use of sscanf. The reason for |
26 // SScanF not being implemented in a platform independent way through | 27 // SScanF not being implemented in a platform independent way through |
27 // ::v8::internal::OS in the same way as SNPrintF is that the | 28 // ::v8::internal::OS in the same way as SNPrintF is that the |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 void Simulator::TearDown(HashMap* i_cache, Redirection* first) { | 527 void Simulator::TearDown(HashMap* i_cache, Redirection* first) { |
527 Redirection::DeleteChain(first); | 528 Redirection::DeleteChain(first); |
528 } | 529 } |
529 | 530 |
530 | 531 |
531 // Calls into the V8 runtime are based on this very simple interface. | 532 // Calls into the V8 runtime are based on this very simple interface. |
532 // Note: To be able to return two values from some calls the code in runtime.cc | 533 // Note: To be able to return two values from some calls the code in runtime.cc |
533 // uses the ObjectPair structure. | 534 // uses the ObjectPair structure. |
534 // The simulator assumes all runtime calls return two 64-bits values. If they | 535 // The simulator assumes all runtime calls return two 64-bits values. If they |
535 // don't, register x1 is clobbered. This is fine because x1 is caller-saved. | 536 // don't, register x1 is clobbered. This is fine because x1 is caller-saved. |
536 struct ObjectPair { | |
537 int64_t res0; | |
538 int64_t res1; | |
539 }; | |
540 | |
541 | |
542 typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0, | 537 typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0, |
543 int64_t arg1, | 538 int64_t arg1, |
544 int64_t arg2, | 539 int64_t arg2, |
545 int64_t arg3, | 540 int64_t arg3, |
546 int64_t arg4, | 541 int64_t arg4, |
547 int64_t arg5, | 542 int64_t arg5, |
548 int64_t arg6, | 543 int64_t arg6, |
549 int64_t arg7); | 544 int64_t arg7); |
550 | 545 |
| 546 typedef ObjectTriple (*SimulatorRuntimeTripleCall)(int64_t arg0, int64_t arg1, |
| 547 int64_t arg2, int64_t arg3, |
| 548 int64_t arg4, int64_t arg5, |
| 549 int64_t arg6, int64_t arg7); |
| 550 |
551 typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2); | 551 typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2); |
552 typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2); | 552 typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2); |
553 typedef double (*SimulatorRuntimeFPCall)(double arg1); | 553 typedef double (*SimulatorRuntimeFPCall)(double arg1); |
554 typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2); | 554 typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2); |
555 | 555 |
556 // This signature supports direct call in to API function native callback | 556 // This signature supports direct call in to API function native callback |
557 // (refer to InvocationCallback in v8.h). | 557 // (refer to InvocationCallback in v8.h). |
558 typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0); | 558 typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0); |
559 typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1); | 559 typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1); |
560 | 560 |
(...skipping 22 matching lines...) Expand all Loading... |
583 FATAL("ALIGNMENT EXCEPTION"); | 583 FATAL("ALIGNMENT EXCEPTION"); |
584 } | 584 } |
585 | 585 |
586 switch (redirection->type()) { | 586 switch (redirection->type()) { |
587 default: | 587 default: |
588 TraceSim("Type: Unknown.\n"); | 588 TraceSim("Type: Unknown.\n"); |
589 UNREACHABLE(); | 589 UNREACHABLE(); |
590 break; | 590 break; |
591 | 591 |
592 case ExternalReference::BUILTIN_CALL: { | 592 case ExternalReference::BUILTIN_CALL: { |
593 // Object* f(v8::internal::Arguments). | 593 // Object* f(v8::internal::Arguments) or |
| 594 // ObjectPair f(v8::internal::Arguments). |
594 TraceSim("Type: BUILTIN_CALL\n"); | 595 TraceSim("Type: BUILTIN_CALL\n"); |
595 SimulatorRuntimeCall target = | 596 SimulatorRuntimeCall target = |
596 reinterpret_cast<SimulatorRuntimeCall>(external); | 597 reinterpret_cast<SimulatorRuntimeCall>(external); |
597 | 598 |
598 // We don't know how many arguments are being passed, but we can | 599 // We don't know how many arguments are being passed, but we can |
599 // pass 8 without touching the stack. They will be ignored by the | 600 // pass 8 without touching the stack. They will be ignored by the |
600 // host function if they aren't used. | 601 // host function if they aren't used. |
601 TraceSim("Arguments: " | 602 TraceSim("Arguments: " |
602 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | 603 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " |
603 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | 604 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " |
604 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " | 605 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " |
605 "0x%016" PRIx64 ", 0x%016" PRIx64, | 606 "0x%016" PRIx64 ", 0x%016" PRIx64, |
606 xreg(0), xreg(1), xreg(2), xreg(3), | 607 xreg(0), xreg(1), xreg(2), xreg(3), |
607 xreg(4), xreg(5), xreg(6), xreg(7)); | 608 xreg(4), xreg(5), xreg(6), xreg(7)); |
608 ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3), | 609 ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3), |
609 xreg(4), xreg(5), xreg(6), xreg(7)); | 610 xreg(4), xreg(5), xreg(6), xreg(7)); |
610 TraceSim("Returned: {0x%" PRIx64 ", 0x%" PRIx64 "}\n", | 611 TraceSim("Returned: {%p, %p}\n", result.x, result.y); |
611 result.res0, result.res1); | |
612 #ifdef DEBUG | 612 #ifdef DEBUG |
613 CorruptAllCallerSavedCPURegisters(); | 613 CorruptAllCallerSavedCPURegisters(); |
614 #endif | 614 #endif |
615 set_xreg(0, result.res0); | 615 set_xreg(0, reinterpret_cast<int64_t>(result.x)); |
616 set_xreg(1, result.res1); | 616 set_xreg(1, reinterpret_cast<int64_t>(result.y)); |
617 break; | 617 break; |
618 } | 618 } |
619 | 619 |
| 620 case ExternalReference::BUILTIN_CALL_TRIPLE: { |
| 621 // ObjectTriple f(v8::internal::Arguments). |
| 622 TraceSim("Type: BUILTIN_CALL TRIPLE\n"); |
| 623 SimulatorRuntimeTripleCall target = |
| 624 reinterpret_cast<SimulatorRuntimeTripleCall>(external); |
| 625 |
| 626 // We don't know how many arguments are being passed, but we can |
| 627 // pass 8 without touching the stack. They will be ignored by the |
| 628 // host function if they aren't used. |
| 629 TraceSim( |
| 630 "Arguments: " |
| 631 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " |
| 632 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " |
| 633 "0x%016" PRIx64 ", 0x%016" PRIx64 ", " |
| 634 "0x%016" PRIx64 ", 0x%016" PRIx64, |
| 635 xreg(0), xreg(1), xreg(2), xreg(3), xreg(4), xreg(5), xreg(6), |
| 636 xreg(7)); |
| 637 // Return location passed in x8. |
| 638 ObjectTriple* sim_result = reinterpret_cast<ObjectTriple*>(xreg(8)); |
| 639 ObjectTriple result = target(xreg(0), xreg(1), xreg(2), xreg(3), xreg(4), |
| 640 xreg(5), xreg(6), xreg(7)); |
| 641 TraceSim("Returned: {%p, %p, %p}\n", result.x, result.y, result.z); |
| 642 #ifdef DEBUG |
| 643 CorruptAllCallerSavedCPURegisters(); |
| 644 #endif |
| 645 *sim_result = result; |
| 646 break; |
| 647 } |
| 648 |
620 case ExternalReference::DIRECT_API_CALL: { | 649 case ExternalReference::DIRECT_API_CALL: { |
621 // void f(v8::FunctionCallbackInfo&) | 650 // void f(v8::FunctionCallbackInfo&) |
622 TraceSim("Type: DIRECT_API_CALL\n"); | 651 TraceSim("Type: DIRECT_API_CALL\n"); |
623 SimulatorRuntimeDirectApiCall target = | 652 SimulatorRuntimeDirectApiCall target = |
624 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); | 653 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); |
625 TraceSim("Arguments: 0x%016" PRIx64 "\n", xreg(0)); | 654 TraceSim("Arguments: 0x%016" PRIx64 "\n", xreg(0)); |
626 target(xreg(0)); | 655 target(xreg(0)); |
627 TraceSim("No return value."); | 656 TraceSim("No return value."); |
628 #ifdef DEBUG | 657 #ifdef DEBUG |
629 CorruptAllCallerSavedCPURegisters(); | 658 CorruptAllCallerSavedCPURegisters(); |
(...skipping 3207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3837 delete[] format; | 3866 delete[] format; |
3838 } | 3867 } |
3839 | 3868 |
3840 | 3869 |
3841 #endif // USE_SIMULATOR | 3870 #endif // USE_SIMULATOR |
3842 | 3871 |
3843 } // namespace internal | 3872 } // namespace internal |
3844 } // namespace v8 | 3873 } // namespace v8 |
3845 | 3874 |
3846 #endif // V8_TARGET_ARCH_ARM64 | 3875 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |