OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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/longjump.h" | 10 #include "vm/longjump.h" |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 int64_t imm = bit_cast<int64_t, double>(immd); | 677 int64_t imm = bit_cast<int64_t, double>(immd); |
678 LoadImmediate(TMP, imm, pp); | 678 LoadImmediate(TMP, imm, pp); |
679 fmovdr(vd, TMP); | 679 fmovdr(vd, TMP); |
680 } | 680 } |
681 } | 681 } |
682 | 682 |
683 | 683 |
684 void Assembler::AddImmediate( | 684 void Assembler::AddImmediate( |
685 Register dest, Register rn, int64_t imm, Register pp) { | 685 Register dest, Register rn, int64_t imm, Register pp) { |
686 Operand op; | 686 Operand op; |
| 687 if (imm == 0) { |
| 688 if (dest != rn) { |
| 689 mov(dest, rn); |
| 690 } |
| 691 return; |
| 692 } |
687 if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) { | 693 if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) { |
688 add(dest, rn, op); | 694 add(dest, rn, op); |
689 } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) == | 695 } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) == |
690 Operand::Immediate) { | 696 Operand::Immediate) { |
691 sub(dest, rn, op); | 697 sub(dest, rn, op); |
692 } else { | 698 } else { |
693 // TODO(zra): Try adding top 12 bits, then bottom 12 bits. | 699 // TODO(zra): Try adding top 12 bits, then bottom 12 bits. |
694 ASSERT(rn != TMP2); | 700 ASSERT(rn != TMP2); |
695 LoadImmediate(TMP2, imm, pp); | 701 LoadImmediate(TMP2, imm, pp); |
696 add(dest, rn, Operand(TMP2)); | 702 add(dest, rn, Operand(TMP2)); |
697 } | 703 } |
698 } | 704 } |
699 | 705 |
700 | 706 |
701 void Assembler::AddImmediateSetFlags( | 707 void Assembler::AddImmediateSetFlags( |
702 Register dest, Register rn, int64_t imm, Register pp) { | 708 Register dest, Register rn, int64_t imm, Register pp) { |
703 Operand op; | 709 Operand op; |
704 if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) { | 710 if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) { |
| 711 // Handles imm == kMinInt64. |
705 adds(dest, rn, op); | 712 adds(dest, rn, op); |
706 } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) == | 713 } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) == |
707 Operand::Immediate) { | 714 Operand::Immediate) { |
| 715 ASSERT(imm != kMinInt64); // Would cause erroneous overflow detection. |
708 subs(dest, rn, op); | 716 subs(dest, rn, op); |
709 } else { | 717 } else { |
710 // TODO(zra): Try adding top 12 bits, then bottom 12 bits. | 718 // TODO(zra): Try adding top 12 bits, then bottom 12 bits. |
711 ASSERT(rn != TMP2); | 719 ASSERT(rn != TMP2); |
712 LoadImmediate(TMP2, imm, pp); | 720 LoadImmediate(TMP2, imm, pp); |
713 adds(dest, rn, Operand(TMP2)); | 721 adds(dest, rn, Operand(TMP2)); |
714 } | 722 } |
715 } | 723 } |
716 | 724 |
717 | 725 |
| 726 void Assembler::SubImmediateSetFlags( |
| 727 Register dest, Register rn, int64_t imm, Register pp) { |
| 728 Operand op; |
| 729 if (Operand::CanHold(imm, kXRegSizeInBits, &op) == Operand::Immediate) { |
| 730 // Handles imm == kMinInt64. |
| 731 subs(dest, rn, op); |
| 732 } else if (Operand::CanHold(-imm, kXRegSizeInBits, &op) == |
| 733 Operand::Immediate) { |
| 734 ASSERT(imm != kMinInt64); // Would cause erroneous overflow detection. |
| 735 adds(dest, rn, op); |
| 736 } else { |
| 737 // TODO(zra): Try subtracting top 12 bits, then bottom 12 bits. |
| 738 ASSERT(rn != TMP2); |
| 739 LoadImmediate(TMP2, imm, pp); |
| 740 subs(dest, rn, Operand(TMP2)); |
| 741 } |
| 742 } |
| 743 |
| 744 |
718 void Assembler::AndImmediate( | 745 void Assembler::AndImmediate( |
719 Register rd, Register rn, int64_t imm, Register pp) { | 746 Register rd, Register rn, int64_t imm, Register pp) { |
720 Operand imm_op; | 747 Operand imm_op; |
721 if (Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op)) { | 748 if (Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op)) { |
722 andi(rd, rn, imm); | 749 andi(rd, rn, imm); |
723 } else { | 750 } else { |
724 LoadImmediate(TMP, imm, pp); | 751 LoadImmediate(TMP, imm, pp); |
725 and_(rd, rn, Operand(TMP)); | 752 and_(rd, rn, Operand(TMP)); |
726 } | 753 } |
727 } | 754 } |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 LoadImmediate(TMP, tags, pp); | 1351 LoadImmediate(TMP, tags, pp); |
1325 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset(), pp); | 1352 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset(), pp); |
1326 } else { | 1353 } else { |
1327 b(failure); | 1354 b(failure); |
1328 } | 1355 } |
1329 } | 1356 } |
1330 | 1357 |
1331 } // namespace dart | 1358 } // namespace dart |
1332 | 1359 |
1333 #endif // defined TARGET_ARCH_ARM64 | 1360 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |