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 intptr_t (*Semaphore)() DART_UNUSED; | 583 typedef int (*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 intptr_t (*FailedSemaphore)() DART_UNUSED; | 605 typedef int (*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 | |
672 // Logical register operations. | 610 // Logical register operations. |
673 ASSEMBLER_TEST_GENERATE(AndRegs, assembler) { | 611 ASSEMBLER_TEST_GENERATE(AndRegs, assembler) { |
674 __ movz(R1, Immediate(43), 0); | 612 __ movz(R1, Immediate(43), 0); |
675 __ movz(R2, Immediate(42), 0); | 613 __ movz(R2, Immediate(42), 0); |
676 __ and_(R0, R1, Operand(R2)); | 614 __ and_(R0, R1, Operand(R2)); |
677 __ ret(); | 615 __ ret(); |
678 } | 616 } |
679 | 617 |
680 | 618 |
681 ASSEMBLER_TEST_RUN(AndRegs, test) { | 619 ASSEMBLER_TEST_RUN(AndRegs, test) { |
(...skipping 3204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3886 __ Pop(LR); | 3824 __ Pop(LR); |
3887 __ Pop(THR); | 3825 __ Pop(THR); |
3888 __ Pop(CODE_REG); | 3826 __ Pop(CODE_REG); |
3889 __ RestoreCSP(); | 3827 __ RestoreCSP(); |
3890 __ ret(); | 3828 __ ret(); |
3891 } | 3829 } |
3892 | 3830 |
3893 } // namespace dart | 3831 } // namespace dart |
3894 | 3832 |
3895 #endif // defined(TARGET_ARCH_ARM64) | 3833 #endif // defined(TARGET_ARCH_ARM64) |
OLD | NEW |