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 "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/os.h" | 10 #include "vm/os.h" |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 __ cmp(TMP, Operand(0)); | 573 __ cmp(TMP, Operand(0)); |
574 __ b(&retry, NE); // NE if context switch occurred between ldrex and strex. | 574 __ b(&retry, NE); // NE if context switch occurred between ldrex and strex. |
575 __ Pop(R0); // 42 | 575 __ Pop(R0); // 42 |
576 __ RestoreCSP(); | 576 __ RestoreCSP(); |
577 __ ret(); | 577 __ ret(); |
578 } | 578 } |
579 | 579 |
580 | 580 |
581 ASSEMBLER_TEST_RUN(Semaphore, test) { | 581 ASSEMBLER_TEST_RUN(Semaphore, test) { |
582 EXPECT(test != NULL); | 582 EXPECT(test != NULL); |
583 typedef int (*Semaphore)() DART_UNUSED; | 583 typedef intptr_t (*Semaphore)() DART_UNUSED; |
584 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Semaphore, test->entry())); | 584 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Semaphore, test->entry())); |
585 } | 585 } |
586 | 586 |
587 | 587 |
588 ASSEMBLER_TEST_GENERATE(FailedSemaphore, assembler) { | 588 ASSEMBLER_TEST_GENERATE(FailedSemaphore, assembler) { |
589 __ SetupDartSP(); | 589 __ SetupDartSP(); |
590 __ movz(R0, Immediate(40), 0); | 590 __ movz(R0, Immediate(40), 0); |
591 __ movz(R1, Immediate(42), 0); | 591 __ movz(R1, Immediate(42), 0); |
592 __ Push(R0); | 592 __ Push(R0); |
593 __ ldxr(R0, SP); | 593 __ ldxr(R0, SP); |
594 __ clrex(); // Simulate a context switch. | 594 __ clrex(); // Simulate a context switch. |
595 __ stxr(TMP, R1, SP); // IP == 1, failure | 595 __ stxr(TMP, R1, SP); // IP == 1, failure |
596 __ Pop(R0); // 40 | 596 __ Pop(R0); // 40 |
597 __ add(R0, R0, Operand(TMP)); | 597 __ add(R0, R0, Operand(TMP)); |
598 __ RestoreCSP(); | 598 __ RestoreCSP(); |
599 __ ret(); | 599 __ ret(); |
600 } | 600 } |
601 | 601 |
602 | 602 |
603 ASSEMBLER_TEST_RUN(FailedSemaphore, test) { | 603 ASSEMBLER_TEST_RUN(FailedSemaphore, test) { |
604 EXPECT(test != NULL); | 604 EXPECT(test != NULL); |
605 typedef int (*FailedSemaphore)() DART_UNUSED; | 605 typedef intptr_t (*FailedSemaphore)() DART_UNUSED; |
606 EXPECT_EQ(41, EXECUTE_TEST_CODE_INT64(FailedSemaphore, test->entry())); | 606 EXPECT_EQ(41, EXECUTE_TEST_CODE_INT64(FailedSemaphore, test->entry())); |
607 } | 607 } |
608 | 608 |
609 | 609 |
| 610 ASSEMBLER_TEST_GENERATE(Semaphore32, assembler) { |
| 611 __ SetupDartSP(); |
| 612 __ movz(R0, Immediate(40), 0); |
| 613 __ add(R0, R0, Operand(R0, LSL, 32)); |
| 614 __ Push(R0); |
| 615 |
| 616 __ movz(R0, Immediate(40), 0); |
| 617 __ movz(R1, Immediate(42), 0); |
| 618 |
| 619 Label retry; |
| 620 __ Bind(&retry); |
| 621 __ ldxr(R0, SP, kWord); |
| 622 // 32 bit operation should ignore the high word of R0 that was pushed on the |
| 623 // stack. |
| 624 __ stxr(TMP, R1, SP, kWord); // IP == 0, success |
| 625 __ cmp(TMP, Operand(0)); |
| 626 __ b(&retry, NE); // NE if context switch occurred between ldrex and strex. |
| 627 __ Pop(R0); // 42 + 42 * 2**32 |
| 628 __ RestoreCSP(); |
| 629 __ ret(); |
| 630 } |
| 631 |
| 632 |
| 633 ASSEMBLER_TEST_RUN(Semaphore32, test) { |
| 634 EXPECT(test != NULL); |
| 635 typedef intptr_t (*Semaphore32)() DART_UNUSED; |
| 636 // Lower word has been atomically switched from 40 to 42k, whereas upper word |
| 637 // is unchanged at 40. |
| 638 EXPECT_EQ(42 + (40l << 32), |
| 639 EXECUTE_TEST_CODE_INT64(Semaphore32, test->entry())); |
| 640 } |
| 641 |
| 642 |
| 643 ASSEMBLER_TEST_GENERATE(FailedSemaphore32, assembler) { |
| 644 __ SetupDartSP(); |
| 645 __ movz(R0, Immediate(40), 0); |
| 646 __ add(R0, R0, Operand(R0, LSL, 32)); |
| 647 __ Push(R0); |
| 648 |
| 649 __ movz(R0, Immediate(40), 0); |
| 650 __ movz(R1, Immediate(42), 0); |
| 651 |
| 652 __ ldxr(R0, SP, kWord); |
| 653 __ clrex(); // Simulate a context switch. |
| 654 __ stxr(TMP, R1, SP, kWord); // IP == 1, failure |
| 655 __ Pop(R0); // 40 |
| 656 __ add(R0, R0, Operand(TMP)); |
| 657 __ RestoreCSP(); |
| 658 __ ret(); |
| 659 } |
| 660 |
| 661 |
| 662 ASSEMBLER_TEST_RUN(FailedSemaphore32, test) { |
| 663 EXPECT(test != NULL); |
| 664 typedef intptr_t (*FailedSemaphore32)() DART_UNUSED; |
| 665 // Lower word has had the failure code (1) added to it. Upper word is |
| 666 // unchanged at 40. |
| 667 EXPECT_EQ(41 + (40l << 32), |
| 668 EXECUTE_TEST_CODE_INT64(FailedSemaphore32, test->entry())); |
| 669 } |
| 670 |
| 671 |
610 // Logical register operations. | 672 // Logical register operations. |
611 ASSEMBLER_TEST_GENERATE(AndRegs, assembler) { | 673 ASSEMBLER_TEST_GENERATE(AndRegs, assembler) { |
612 __ movz(R1, Immediate(43), 0); | 674 __ movz(R1, Immediate(43), 0); |
613 __ movz(R2, Immediate(42), 0); | 675 __ movz(R2, Immediate(42), 0); |
614 __ and_(R0, R1, Operand(R2)); | 676 __ and_(R0, R1, Operand(R2)); |
615 __ ret(); | 677 __ ret(); |
616 } | 678 } |
617 | 679 |
618 | 680 |
619 ASSEMBLER_TEST_RUN(AndRegs, test) { | 681 ASSEMBLER_TEST_RUN(AndRegs, test) { |
(...skipping 3204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3824 __ Pop(LR); | 3886 __ Pop(LR); |
3825 __ Pop(THR); | 3887 __ Pop(THR); |
3826 __ Pop(CODE_REG); | 3888 __ Pop(CODE_REG); |
3827 __ RestoreCSP(); | 3889 __ RestoreCSP(); |
3828 __ ret(); | 3890 __ ret(); |
3829 } | 3891 } |
3830 | 3892 |
3831 } // namespace dart | 3893 } // namespace dart |
3832 | 3894 |
3833 #endif // defined(TARGET_ARCH_ARM64) | 3895 #endif // defined(TARGET_ARCH_ARM64) |
OLD | NEW |