| 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" // Needed here to get TARGET_ARCH_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 switch (class_id_) { | 701 switch (class_id_) { |
| 702 case kArrayCid: | 702 case kArrayCid: |
| 703 case kImmutableArrayCid: | 703 case kImmutableArrayCid: |
| 704 return CompileType::Dynamic(); | 704 return CompileType::Dynamic(); |
| 705 | 705 |
| 706 case kTypedDataFloat32ArrayCid: | 706 case kTypedDataFloat32ArrayCid: |
| 707 case kTypedDataFloat64ArrayCid: | 707 case kTypedDataFloat64ArrayCid: |
| 708 return CompileType::FromCid(kDoubleCid); | 708 return CompileType::FromCid(kDoubleCid); |
| 709 case kTypedDataFloat32x4ArrayCid: | 709 case kTypedDataFloat32x4ArrayCid: |
| 710 return CompileType::FromCid(kFloat32x4Cid); | 710 return CompileType::FromCid(kFloat32x4Cid); |
| 711 case kTypedDataUint32x4ArrayCid: | 711 case kTypedDataInt32x4ArrayCid: |
| 712 return CompileType::FromCid(kUint32x4Cid); | 712 return CompileType::FromCid(kInt32x4Cid); |
| 713 | 713 |
| 714 case kTypedDataInt8ArrayCid: | 714 case kTypedDataInt8ArrayCid: |
| 715 case kTypedDataUint8ArrayCid: | 715 case kTypedDataUint8ArrayCid: |
| 716 case kTypedDataUint8ClampedArrayCid: | 716 case kTypedDataUint8ClampedArrayCid: |
| 717 case kExternalTypedDataUint8ArrayCid: | 717 case kExternalTypedDataUint8ArrayCid: |
| 718 case kExternalTypedDataUint8ClampedArrayCid: | 718 case kExternalTypedDataUint8ClampedArrayCid: |
| 719 case kTypedDataInt16ArrayCid: | 719 case kTypedDataInt16ArrayCid: |
| 720 case kTypedDataUint16ArrayCid: | 720 case kTypedDataUint16ArrayCid: |
| 721 case kOneByteStringCid: | 721 case kOneByteStringCid: |
| 722 case kTwoByteStringCid: | 722 case kTwoByteStringCid: |
| (...skipping 29 matching lines...) Expand all Loading... |
| 752 case kTwoByteStringCid: | 752 case kTwoByteStringCid: |
| 753 return kTagged; | 753 return kTagged; |
| 754 case kTypedDataInt32ArrayCid: | 754 case kTypedDataInt32ArrayCid: |
| 755 case kTypedDataUint32ArrayCid: | 755 case kTypedDataUint32ArrayCid: |
| 756 // Instruction can deoptimize if we optimistically assumed that the result | 756 // Instruction can deoptimize if we optimistically assumed that the result |
| 757 // fits into Smi. | 757 // fits into Smi. |
| 758 return CanDeoptimize() ? kTagged : kUnboxedMint; | 758 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| 759 case kTypedDataFloat32ArrayCid: | 759 case kTypedDataFloat32ArrayCid: |
| 760 case kTypedDataFloat64ArrayCid: | 760 case kTypedDataFloat64ArrayCid: |
| 761 return kUnboxedDouble; | 761 return kUnboxedDouble; |
| 762 case kTypedDataUint32x4ArrayCid: | 762 case kTypedDataInt32x4ArrayCid: |
| 763 return kUnboxedUint32x4; | 763 return kUnboxedInt32x4; |
| 764 case kTypedDataFloat32x4ArrayCid: | 764 case kTypedDataFloat32x4ArrayCid: |
| 765 return kUnboxedFloat32x4; | 765 return kUnboxedFloat32x4; |
| 766 default: | 766 default: |
| 767 UNREACHABLE(); | 767 UNREACHABLE(); |
| 768 return kTagged; | 768 return kTagged; |
| 769 } | 769 } |
| 770 } | 770 } |
| 771 | 771 |
| 772 | 772 |
| 773 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 773 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 774 const intptr_t kNumInputs = 2; | 774 const intptr_t kNumInputs = 2; |
| 775 const intptr_t kNumTemps = 0; | 775 const intptr_t kNumTemps = 0; |
| 776 LocationSummary* locs = | 776 LocationSummary* locs = |
| 777 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 777 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 778 locs->set_in(0, Location::RequiresRegister()); | 778 locs->set_in(0, Location::RequiresRegister()); |
| 779 // The smi index is either untagged (element size == 1), or it is left smi | 779 // The smi index is either untagged (element size == 1), or it is left smi |
| 780 // tagged (for all element sizes > 1). | 780 // tagged (for all element sizes > 1). |
| 781 // TODO(regis): Revisit and see if the index can be immediate. | 781 // TODO(regis): Revisit and see if the index can be immediate. |
| 782 locs->set_in(1, Location::WritableRegister()); | 782 locs->set_in(1, Location::WritableRegister()); |
| 783 if ((representation() == kUnboxedDouble) || | 783 if ((representation() == kUnboxedDouble) || |
| 784 (representation() == kUnboxedFloat32x4) || | 784 (representation() == kUnboxedFloat32x4) || |
| 785 (representation() == kUnboxedUint32x4)) { | 785 (representation() == kUnboxedInt32x4)) { |
| 786 locs->set_out(Location::RequiresFpuRegister()); | 786 locs->set_out(Location::RequiresFpuRegister()); |
| 787 } else { | 787 } else { |
| 788 locs->set_out(Location::RequiresRegister()); | 788 locs->set_out(Location::RequiresRegister()); |
| 789 } | 789 } |
| 790 return locs; | 790 return locs; |
| 791 } | 791 } |
| 792 | 792 |
| 793 | 793 |
| 794 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 794 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 795 Register array = locs()->in(0).reg(); | 795 Register array = locs()->in(0).reg(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 if (!IsExternal()) { | 828 if (!IsExternal()) { |
| 829 ASSERT(this->array()->definition()->representation() == kTagged); | 829 ASSERT(this->array()->definition()->representation() == kTagged); |
| 830 __ AddImmediate(index.reg(), | 830 __ AddImmediate(index.reg(), |
| 831 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 831 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
| 832 } | 832 } |
| 833 element_address = Address(array, index.reg(), LSL, 0); | 833 element_address = Address(array, index.reg(), LSL, 0); |
| 834 | 834 |
| 835 if ((representation() == kUnboxedDouble) || | 835 if ((representation() == kUnboxedDouble) || |
| 836 (representation() == kUnboxedMint) || | 836 (representation() == kUnboxedMint) || |
| 837 (representation() == kUnboxedFloat32x4) || | 837 (representation() == kUnboxedFloat32x4) || |
| 838 (representation() == kUnboxedUint32x4)) { | 838 (representation() == kUnboxedInt32x4)) { |
| 839 QRegister result = locs()->out().fpu_reg(); | 839 QRegister result = locs()->out().fpu_reg(); |
| 840 DRegister dresult0 = EvenDRegisterOf(result); | 840 DRegister dresult0 = EvenDRegisterOf(result); |
| 841 DRegister dresult1 = OddDRegisterOf(result); | 841 DRegister dresult1 = OddDRegisterOf(result); |
| 842 switch (class_id()) { | 842 switch (class_id()) { |
| 843 case kTypedDataInt32ArrayCid: | 843 case kTypedDataInt32ArrayCid: |
| 844 UNIMPLEMENTED(); | 844 UNIMPLEMENTED(); |
| 845 break; | 845 break; |
| 846 case kTypedDataUint32ArrayCid: | 846 case kTypedDataUint32ArrayCid: |
| 847 UNIMPLEMENTED(); | 847 UNIMPLEMENTED(); |
| 848 break; | 848 break; |
| 849 case kTypedDataFloat32ArrayCid: | 849 case kTypedDataFloat32ArrayCid: |
| 850 // Load single precision float and promote to double. | 850 // Load single precision float and promote to double. |
| 851 // vldrs does not support indexed addressing. | 851 // vldrs does not support indexed addressing. |
| 852 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 852 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 853 element_address = Address(index.reg(), 0); | 853 element_address = Address(index.reg(), 0); |
| 854 __ vldrs(STMP, element_address); | 854 __ vldrs(STMP, element_address); |
| 855 __ vcvtds(dresult0, STMP); | 855 __ vcvtds(dresult0, STMP); |
| 856 break; | 856 break; |
| 857 case kTypedDataFloat64ArrayCid: | 857 case kTypedDataFloat64ArrayCid: |
| 858 // vldrd does not support indexed addressing. | 858 // vldrd does not support indexed addressing. |
| 859 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 859 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 860 element_address = Address(index.reg(), 0); | 860 element_address = Address(index.reg(), 0); |
| 861 __ vldrd(dresult0, element_address); | 861 __ vldrd(dresult0, element_address); |
| 862 break; | 862 break; |
| 863 case kTypedDataUint32x4ArrayCid: | 863 case kTypedDataInt32x4ArrayCid: |
| 864 case kTypedDataFloat32x4ArrayCid: | 864 case kTypedDataFloat32x4ArrayCid: |
| 865 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 865 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 866 __ LoadDFromOffset(dresult0, index.reg(), 0); | 866 __ LoadDFromOffset(dresult0, index.reg(), 0); |
| 867 __ LoadDFromOffset(dresult1, index.reg(), 2*kWordSize); | 867 __ LoadDFromOffset(dresult1, index.reg(), 2*kWordSize); |
| 868 break; | 868 break; |
| 869 } | 869 } |
| 870 return; | 870 return; |
| 871 } | 871 } |
| 872 | 872 |
| 873 Register result = locs()->out().reg(); | 873 Register result = locs()->out().reg(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 case kTypedDataUint16ArrayCid: | 939 case kTypedDataUint16ArrayCid: |
| 940 return kTagged; | 940 return kTagged; |
| 941 case kTypedDataInt32ArrayCid: | 941 case kTypedDataInt32ArrayCid: |
| 942 case kTypedDataUint32ArrayCid: | 942 case kTypedDataUint32ArrayCid: |
| 943 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 943 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| 944 case kTypedDataFloat32ArrayCid: | 944 case kTypedDataFloat32ArrayCid: |
| 945 case kTypedDataFloat64ArrayCid: | 945 case kTypedDataFloat64ArrayCid: |
| 946 return kUnboxedDouble; | 946 return kUnboxedDouble; |
| 947 case kTypedDataFloat32x4ArrayCid: | 947 case kTypedDataFloat32x4ArrayCid: |
| 948 return kUnboxedFloat32x4; | 948 return kUnboxedFloat32x4; |
| 949 case kTypedDataUint32x4ArrayCid: | 949 case kTypedDataInt32x4ArrayCid: |
| 950 return kUnboxedUint32x4; | 950 return kUnboxedInt32x4; |
| 951 default: | 951 default: |
| 952 UNREACHABLE(); | 952 UNREACHABLE(); |
| 953 return kTagged; | 953 return kTagged; |
| 954 } | 954 } |
| 955 } | 955 } |
| 956 | 956 |
| 957 | 957 |
| 958 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 958 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 959 const intptr_t kNumInputs = 3; | 959 const intptr_t kNumInputs = 3; |
| 960 const intptr_t kNumTemps = 0; | 960 const intptr_t kNumTemps = 0; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 978 case kTypedDataUint8ClampedArrayCid: | 978 case kTypedDataUint8ClampedArrayCid: |
| 979 case kOneByteStringCid: | 979 case kOneByteStringCid: |
| 980 case kTypedDataInt16ArrayCid: | 980 case kTypedDataInt16ArrayCid: |
| 981 case kTypedDataUint16ArrayCid: | 981 case kTypedDataUint16ArrayCid: |
| 982 case kTypedDataInt32ArrayCid: | 982 case kTypedDataInt32ArrayCid: |
| 983 case kTypedDataUint32ArrayCid: | 983 case kTypedDataUint32ArrayCid: |
| 984 locs->set_in(2, Location::WritableRegister()); | 984 locs->set_in(2, Location::WritableRegister()); |
| 985 break; | 985 break; |
| 986 case kTypedDataFloat32ArrayCid: | 986 case kTypedDataFloat32ArrayCid: |
| 987 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. | 987 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. |
| 988 case kTypedDataUint32x4ArrayCid: | 988 case kTypedDataInt32x4ArrayCid: |
| 989 case kTypedDataFloat32x4ArrayCid: | 989 case kTypedDataFloat32x4ArrayCid: |
| 990 locs->set_in(2, Location::RequiresFpuRegister()); | 990 locs->set_in(2, Location::RequiresFpuRegister()); |
| 991 break; | 991 break; |
| 992 default: | 992 default: |
| 993 UNREACHABLE(); | 993 UNREACHABLE(); |
| 994 return NULL; | 994 return NULL; |
| 995 } | 995 } |
| 996 return locs; | 996 return locs; |
| 997 } | 997 } |
| 998 | 998 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1119 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1120 __ StoreSToOffset(STMP, index.reg(), 0); | 1120 __ StoreSToOffset(STMP, index.reg(), 0); |
| 1121 break; | 1121 break; |
| 1122 } | 1122 } |
| 1123 case kTypedDataFloat64ArrayCid: { | 1123 case kTypedDataFloat64ArrayCid: { |
| 1124 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); | 1124 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); |
| 1125 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1125 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1126 __ StoreDToOffset(in2, index.reg(), 0); | 1126 __ StoreDToOffset(in2, index.reg(), 0); |
| 1127 break; | 1127 break; |
| 1128 } | 1128 } |
| 1129 case kTypedDataUint32x4ArrayCid: | 1129 case kTypedDataInt32x4ArrayCid: |
| 1130 case kTypedDataFloat32x4ArrayCid: { | 1130 case kTypedDataFloat32x4ArrayCid: { |
| 1131 QRegister in = locs()->in(2).fpu_reg(); | 1131 QRegister in = locs()->in(2).fpu_reg(); |
| 1132 DRegister din0 = EvenDRegisterOf(in); | 1132 DRegister din0 = EvenDRegisterOf(in); |
| 1133 DRegister din1 = OddDRegisterOf(in); | 1133 DRegister din1 = OddDRegisterOf(in); |
| 1134 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1134 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1135 __ StoreDToOffset(din0, index.reg(), 0); | 1135 __ StoreDToOffset(din0, index.reg(), 0); |
| 1136 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); | 1136 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); |
| 1137 break; | 1137 break; |
| 1138 } | 1138 } |
| 1139 default: | 1139 default: |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1245 Label check_array, length_compared, no_fixed_length; | 1245 Label check_array, length_compared, no_fixed_length; |
| 1246 // If length is negative the length guard is either disabled or | 1246 // If length is negative the length guard is either disabled or |
| 1247 // has not been initialized, either way it is safe to skip the | 1247 // has not been initialized, either way it is safe to skip the |
| 1248 // length check. | 1248 // length check. |
| 1249 __ ldr(IP, field_length_operand); | 1249 __ ldr(IP, field_length_operand); |
| 1250 __ CompareImmediate(IP, 0); | 1250 __ CompareImmediate(IP, 0); |
| 1251 __ b(&skip_length_check, LT); | 1251 __ b(&skip_length_check, LT); |
| 1252 __ CompareImmediate(value_cid_reg, kNullCid); | 1252 __ CompareImmediate(value_cid_reg, kNullCid); |
| 1253 __ b(&no_fixed_length, EQ); | 1253 __ b(&no_fixed_length, EQ); |
| 1254 // Check for typed data array. | 1254 // Check for typed data array. |
| 1255 __ CompareImmediate(value_cid_reg, kTypedDataUint32x4ArrayCid); | 1255 __ CompareImmediate(value_cid_reg, kTypedDataInt32x4ArrayCid); |
| 1256 __ b(&no_fixed_length, GT); | 1256 __ b(&no_fixed_length, GT); |
| 1257 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); | 1257 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); |
| 1258 // Could still be a regular array. | 1258 // Could still be a regular array. |
| 1259 __ b(&check_array, LT); | 1259 __ b(&check_array, LT); |
| 1260 __ ldr(temp_reg, | 1260 __ ldr(temp_reg, |
| 1261 FieldAddress(value_reg, TypedData::length_offset())); | 1261 FieldAddress(value_reg, TypedData::length_offset())); |
| 1262 __ ldr(IP, field_length_operand); | 1262 __ ldr(IP, field_length_operand); |
| 1263 __ cmp(temp_reg, ShifterOperand(IP)); | 1263 __ cmp(temp_reg, ShifterOperand(IP)); |
| 1264 __ b(&length_compared); | 1264 __ b(&length_compared); |
| 1265 // Check for regular array. | 1265 // Check for regular array. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 __ b(fail, NE); | 1325 __ b(fail, NE); |
| 1326 | 1326 |
| 1327 if (value_cid == kDynamicCid) { | 1327 if (value_cid == kDynamicCid) { |
| 1328 __ str(value_cid_reg, field_cid_operand); | 1328 __ str(value_cid_reg, field_cid_operand); |
| 1329 __ str(value_cid_reg, field_nullability_operand); | 1329 __ str(value_cid_reg, field_nullability_operand); |
| 1330 if (field_has_length) { | 1330 if (field_has_length) { |
| 1331 Label check_array, length_set, no_fixed_length; | 1331 Label check_array, length_set, no_fixed_length; |
| 1332 __ CompareImmediate(value_cid_reg, kNullCid); | 1332 __ CompareImmediate(value_cid_reg, kNullCid); |
| 1333 __ b(&no_fixed_length, EQ); | 1333 __ b(&no_fixed_length, EQ); |
| 1334 // Check for typed data array. | 1334 // Check for typed data array. |
| 1335 __ CompareImmediate(value_cid_reg, kTypedDataUint32x4ArrayCid); | 1335 __ CompareImmediate(value_cid_reg, kTypedDataInt32x4ArrayCid); |
| 1336 __ b(&no_fixed_length, GT); | 1336 __ b(&no_fixed_length, GT); |
| 1337 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); | 1337 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); |
| 1338 // Could still be a regular array. | 1338 // Could still be a regular array. |
| 1339 __ b(&check_array, LT); | 1339 __ b(&check_array, LT); |
| 1340 // Destroy value_cid_reg (safe because we are finished with it). | 1340 // Destroy value_cid_reg (safe because we are finished with it). |
| 1341 __ ldr(value_cid_reg, | 1341 __ ldr(value_cid_reg, |
| 1342 FieldAddress(value_reg, TypedData::length_offset())); | 1342 FieldAddress(value_reg, TypedData::length_offset())); |
| 1343 __ str(value_cid_reg, field_length_operand); | 1343 __ str(value_cid_reg, field_length_operand); |
| 1344 __ b(&length_set); // Updated field length typed data array. | 1344 __ b(&length_set); // Updated field length typed data array. |
| 1345 // Check for regular array. | 1345 // Check for regular array. |
| (...skipping 1262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2608 | 2608 |
| 2609 const DRegister result_even = EvenDRegisterOf(result); | 2609 const DRegister result_even = EvenDRegisterOf(result); |
| 2610 const DRegister result_odd = OddDRegisterOf(result); | 2610 const DRegister result_odd = OddDRegisterOf(result); |
| 2611 __ LoadDFromOffset(result_even, value, | 2611 __ LoadDFromOffset(result_even, value, |
| 2612 Float32x4::value_offset() - kHeapObjectTag); | 2612 Float32x4::value_offset() - kHeapObjectTag); |
| 2613 __ LoadDFromOffset(result_odd, value, | 2613 __ LoadDFromOffset(result_odd, value, |
| 2614 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2614 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
| 2615 } | 2615 } |
| 2616 | 2616 |
| 2617 | 2617 |
| 2618 LocationSummary* BoxUint32x4Instr::MakeLocationSummary() const { | 2618 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { |
| 2619 const intptr_t kNumInputs = 1; | 2619 const intptr_t kNumInputs = 1; |
| 2620 const intptr_t kNumTemps = 0; | 2620 const intptr_t kNumTemps = 0; |
| 2621 LocationSummary* summary = | 2621 LocationSummary* summary = |
| 2622 new LocationSummary(kNumInputs, | 2622 new LocationSummary(kNumInputs, |
| 2623 kNumTemps, | 2623 kNumTemps, |
| 2624 LocationSummary::kCallOnSlowPath); | 2624 LocationSummary::kCallOnSlowPath); |
| 2625 summary->set_in(0, Location::RequiresFpuRegister()); | 2625 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2626 summary->set_out(Location::RequiresRegister()); | 2626 summary->set_out(Location::RequiresRegister()); |
| 2627 return summary; | 2627 return summary; |
| 2628 } | 2628 } |
| 2629 | 2629 |
| 2630 | 2630 |
| 2631 class BoxUint32x4SlowPath : public SlowPathCode { | 2631 class BoxInt32x4SlowPath : public SlowPathCode { |
| 2632 public: | 2632 public: |
| 2633 explicit BoxUint32x4SlowPath(BoxUint32x4Instr* instruction) | 2633 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) |
| 2634 : instruction_(instruction) { } | 2634 : instruction_(instruction) { } |
| 2635 | 2635 |
| 2636 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2636 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2637 __ Comment("BoxUint32x4SlowPath"); | 2637 __ Comment("BoxInt32x4SlowPath"); |
| 2638 __ Bind(entry_label()); | 2638 __ Bind(entry_label()); |
| 2639 const Class& uint32x4_class = compiler->uint32x4_class(); | 2639 const Class& int32x4_class = compiler->int32x4_class(); |
| 2640 const Code& stub = | 2640 const Code& stub = |
| 2641 Code::Handle(StubCode::GetAllocationStubForClass(uint32x4_class)); | 2641 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); |
| 2642 const ExternalLabel label(uint32x4_class.ToCString(), stub.EntryPoint()); | 2642 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); |
| 2643 | 2643 |
| 2644 LocationSummary* locs = instruction_->locs(); | 2644 LocationSummary* locs = instruction_->locs(); |
| 2645 locs->live_registers()->Remove(locs->out()); | 2645 locs->live_registers()->Remove(locs->out()); |
| 2646 | 2646 |
| 2647 compiler->SaveLiveRegisters(locs); | 2647 compiler->SaveLiveRegisters(locs); |
| 2648 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | 2648 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 2649 &label, | 2649 &label, |
| 2650 PcDescriptors::kOther, | 2650 PcDescriptors::kOther, |
| 2651 locs); | 2651 locs); |
| 2652 __ mov(locs->out().reg(), ShifterOperand(R0)); | 2652 __ mov(locs->out().reg(), ShifterOperand(R0)); |
| 2653 compiler->RestoreLiveRegisters(locs); | 2653 compiler->RestoreLiveRegisters(locs); |
| 2654 | 2654 |
| 2655 __ b(exit_label()); | 2655 __ b(exit_label()); |
| 2656 } | 2656 } |
| 2657 | 2657 |
| 2658 private: | 2658 private: |
| 2659 BoxUint32x4Instr* instruction_; | 2659 BoxInt32x4Instr* instruction_; |
| 2660 }; | 2660 }; |
| 2661 | 2661 |
| 2662 | 2662 |
| 2663 void BoxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2663 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2664 BoxUint32x4SlowPath* slow_path = new BoxUint32x4SlowPath(this); | 2664 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); |
| 2665 compiler->AddSlowPathCode(slow_path); | 2665 compiler->AddSlowPathCode(slow_path); |
| 2666 | 2666 |
| 2667 Register out_reg = locs()->out().reg(); | 2667 Register out_reg = locs()->out().reg(); |
| 2668 QRegister value = locs()->in(0).fpu_reg(); | 2668 QRegister value = locs()->in(0).fpu_reg(); |
| 2669 DRegister value_even = EvenDRegisterOf(value); | 2669 DRegister value_even = EvenDRegisterOf(value); |
| 2670 DRegister value_odd = OddDRegisterOf(value); | 2670 DRegister value_odd = OddDRegisterOf(value); |
| 2671 | 2671 |
| 2672 __ TryAllocate(compiler->uint32x4_class(), | 2672 __ TryAllocate(compiler->int32x4_class(), |
| 2673 slow_path->entry_label(), | 2673 slow_path->entry_label(), |
| 2674 out_reg); | 2674 out_reg); |
| 2675 __ Bind(slow_path->exit_label()); | 2675 __ Bind(slow_path->exit_label()); |
| 2676 __ StoreDToOffset(value_even, out_reg, | 2676 __ StoreDToOffset(value_even, out_reg, |
| 2677 Uint32x4::value_offset() - kHeapObjectTag); | 2677 Int32x4::value_offset() - kHeapObjectTag); |
| 2678 __ StoreDToOffset(value_odd, out_reg, | 2678 __ StoreDToOffset(value_odd, out_reg, |
| 2679 Uint32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2679 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
| 2680 } | 2680 } |
| 2681 | 2681 |
| 2682 | 2682 |
| 2683 LocationSummary* UnboxUint32x4Instr::MakeLocationSummary() const { | 2683 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { |
| 2684 const intptr_t value_cid = value()->Type()->ToCid(); | 2684 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2685 const intptr_t kNumInputs = 1; | 2685 const intptr_t kNumInputs = 1; |
| 2686 const intptr_t kNumTemps = value_cid == kUint32x4Cid ? 0 : 1; | 2686 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
| 2687 LocationSummary* summary = | 2687 LocationSummary* summary = |
| 2688 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2688 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2689 summary->set_in(0, Location::RequiresRegister()); | 2689 summary->set_in(0, Location::RequiresRegister()); |
| 2690 if (kNumTemps > 0) { | 2690 if (kNumTemps > 0) { |
| 2691 ASSERT(kNumTemps == 1); | 2691 ASSERT(kNumTemps == 1); |
| 2692 summary->set_temp(0, Location::RequiresRegister()); | 2692 summary->set_temp(0, Location::RequiresRegister()); |
| 2693 } | 2693 } |
| 2694 summary->set_out(Location::RequiresFpuRegister()); | 2694 summary->set_out(Location::RequiresFpuRegister()); |
| 2695 return summary; | 2695 return summary; |
| 2696 } | 2696 } |
| 2697 | 2697 |
| 2698 | 2698 |
| 2699 void UnboxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2699 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2700 const intptr_t value_cid = value()->Type()->ToCid(); | 2700 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2701 const Register value = locs()->in(0).reg(); | 2701 const Register value = locs()->in(0).reg(); |
| 2702 const QRegister result = locs()->out().fpu_reg(); | 2702 const QRegister result = locs()->out().fpu_reg(); |
| 2703 | 2703 |
| 2704 if (value_cid != kUint32x4Cid) { | 2704 if (value_cid != kInt32x4Cid) { |
| 2705 const Register temp = locs()->temp(0).reg(); | 2705 const Register temp = locs()->temp(0).reg(); |
| 2706 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 2706 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 2707 __ tst(value, ShifterOperand(kSmiTagMask)); | 2707 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 2708 __ b(deopt, EQ); | 2708 __ b(deopt, EQ); |
| 2709 __ CompareClassId(value, kUint32x4Cid, temp); | 2709 __ CompareClassId(value, kInt32x4Cid, temp); |
| 2710 __ b(deopt, NE); | 2710 __ b(deopt, NE); |
| 2711 } | 2711 } |
| 2712 | 2712 |
| 2713 const DRegister result_even = EvenDRegisterOf(result); | 2713 const DRegister result_even = EvenDRegisterOf(result); |
| 2714 const DRegister result_odd = OddDRegisterOf(result); | 2714 const DRegister result_odd = OddDRegisterOf(result); |
| 2715 __ LoadDFromOffset(result_even, value, | 2715 __ LoadDFromOffset(result_even, value, |
| 2716 Uint32x4::value_offset() - kHeapObjectTag); | 2716 Int32x4::value_offset() - kHeapObjectTag); |
| 2717 __ LoadDFromOffset(result_odd, value, | 2717 __ LoadDFromOffset(result_odd, value, |
| 2718 Uint32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2718 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
| 2719 } | 2719 } |
| 2720 | 2720 |
| 2721 | 2721 |
| 2722 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2722 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
| 2723 const intptr_t kNumInputs = 2; | 2723 const intptr_t kNumInputs = 2; |
| 2724 const intptr_t kNumTemps = 0; | 2724 const intptr_t kNumTemps = 0; |
| 2725 LocationSummary* summary = | 2725 LocationSummary* summary = |
| 2726 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2726 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2727 summary->set_in(0, Location::RequiresFpuRegister()); | 2727 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2728 summary->set_in(1, Location::RequiresFpuRegister()); | 2728 summary->set_in(1, Location::RequiresFpuRegister()); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2813 __ vcvtds(dresult0, sresult0); | 2813 __ vcvtds(dresult0, sresult0); |
| 2814 break; | 2814 break; |
| 2815 case MethodRecognizer::kFloat32x4ShuffleZ: | 2815 case MethodRecognizer::kFloat32x4ShuffleZ: |
| 2816 __ vdup(kWord, result, dvalue1, 0); | 2816 __ vdup(kWord, result, dvalue1, 0); |
| 2817 __ vcvtds(dresult0, sresult0); | 2817 __ vcvtds(dresult0, sresult0); |
| 2818 break; | 2818 break; |
| 2819 case MethodRecognizer::kFloat32x4ShuffleW: | 2819 case MethodRecognizer::kFloat32x4ShuffleW: |
| 2820 __ vdup(kWord, result, dvalue1, 1); | 2820 __ vdup(kWord, result, dvalue1, 1); |
| 2821 __ vcvtds(dresult0, sresult0); | 2821 __ vcvtds(dresult0, sresult0); |
| 2822 break; | 2822 break; |
| 2823 case MethodRecognizer::kUint32x4Shuffle: | 2823 case MethodRecognizer::kInt32x4Shuffle: |
| 2824 case MethodRecognizer::kFloat32x4Shuffle: | 2824 case MethodRecognizer::kFloat32x4Shuffle: |
| 2825 if (mask_ == 0x00) { | 2825 if (mask_ == 0x00) { |
| 2826 __ vdup(kWord, result, dvalue0, 0); | 2826 __ vdup(kWord, result, dvalue0, 0); |
| 2827 } else if (mask_ == 0x55) { | 2827 } else if (mask_ == 0x55) { |
| 2828 __ vdup(kWord, result, dvalue0, 1); | 2828 __ vdup(kWord, result, dvalue0, 1); |
| 2829 } else if (mask_ == 0xAA) { | 2829 } else if (mask_ == 0xAA) { |
| 2830 __ vdup(kWord, result, dvalue1, 0); | 2830 __ vdup(kWord, result, dvalue1, 0); |
| 2831 } else if (mask_ == 0xFF) { | 2831 } else if (mask_ == 0xFF) { |
| 2832 __ vdup(kWord, result, dvalue1, 1); | 2832 __ vdup(kWord, result, dvalue1, 1); |
| 2833 } else { | 2833 } else { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2877 SRegister sresult2 = EvenSRegisterOf(dresult1); | 2877 SRegister sresult2 = EvenSRegisterOf(dresult1); |
| 2878 SRegister sresult3 = OddSRegisterOf(dresult1); | 2878 SRegister sresult3 = OddSRegisterOf(dresult1); |
| 2879 | 2879 |
| 2880 DRegister dleft0 = EvenDRegisterOf(left); | 2880 DRegister dleft0 = EvenDRegisterOf(left); |
| 2881 DRegister dleft1 = OddDRegisterOf(left); | 2881 DRegister dleft1 = OddDRegisterOf(left); |
| 2882 DRegister dright0 = EvenDRegisterOf(right); | 2882 DRegister dright0 = EvenDRegisterOf(right); |
| 2883 DRegister dright1 = OddDRegisterOf(right); | 2883 DRegister dright1 = OddDRegisterOf(right); |
| 2884 | 2884 |
| 2885 switch (op_kind()) { | 2885 switch (op_kind()) { |
| 2886 case MethodRecognizer::kFloat32x4ShuffleMix: | 2886 case MethodRecognizer::kFloat32x4ShuffleMix: |
| 2887 case MethodRecognizer::kUint32x4ShuffleMix: | 2887 case MethodRecognizer::kInt32x4ShuffleMix: |
| 2888 // TODO(zra): Investigate better instruction sequences for shuffle masks. | 2888 // TODO(zra): Investigate better instruction sequences for shuffle masks. |
| 2889 SRegister left_svalues[4]; | 2889 SRegister left_svalues[4]; |
| 2890 SRegister right_svalues[4]; | 2890 SRegister right_svalues[4]; |
| 2891 | 2891 |
| 2892 left_svalues[0] = EvenSRegisterOf(dleft0); | 2892 left_svalues[0] = EvenSRegisterOf(dleft0); |
| 2893 left_svalues[1] = OddSRegisterOf(dleft0); | 2893 left_svalues[1] = OddSRegisterOf(dleft0); |
| 2894 left_svalues[2] = EvenSRegisterOf(dleft1); | 2894 left_svalues[2] = EvenSRegisterOf(dleft1); |
| 2895 left_svalues[3] = OddSRegisterOf(dleft1); | 2895 left_svalues[3] = OddSRegisterOf(dleft1); |
| 2896 right_svalues[0] = EvenSRegisterOf(dright0); | 2896 right_svalues[0] = EvenSRegisterOf(dright0); |
| 2897 right_svalues[1] = OddSRegisterOf(dright0); | 2897 right_svalues[1] = OddSRegisterOf(dright0); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3246 __ vmovs(sresult2, STMP); | 3246 __ vmovs(sresult2, STMP); |
| 3247 break; | 3247 break; |
| 3248 case MethodRecognizer::kFloat32x4WithW: | 3248 case MethodRecognizer::kFloat32x4WithW: |
| 3249 __ vmovs(sresult3, STMP); | 3249 __ vmovs(sresult3, STMP); |
| 3250 break; | 3250 break; |
| 3251 default: UNREACHABLE(); | 3251 default: UNREACHABLE(); |
| 3252 } | 3252 } |
| 3253 } | 3253 } |
| 3254 | 3254 |
| 3255 | 3255 |
| 3256 LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const { | 3256 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { |
| 3257 const intptr_t kNumInputs = 1; | 3257 const intptr_t kNumInputs = 1; |
| 3258 const intptr_t kNumTemps = 0; | 3258 const intptr_t kNumTemps = 0; |
| 3259 LocationSummary* summary = | 3259 LocationSummary* summary = |
| 3260 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3260 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3261 summary->set_in(0, Location::RequiresFpuRegister()); | 3261 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3262 summary->set_out(Location::RequiresFpuRegister()); | 3262 summary->set_out(Location::RequiresFpuRegister()); |
| 3263 return summary; | 3263 return summary; |
| 3264 } | 3264 } |
| 3265 | 3265 |
| 3266 | 3266 |
| 3267 void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3267 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3268 QRegister value = locs()->in(0).fpu_reg(); | 3268 QRegister value = locs()->in(0).fpu_reg(); |
| 3269 QRegister result = locs()->out().fpu_reg(); | 3269 QRegister result = locs()->out().fpu_reg(); |
| 3270 | 3270 |
| 3271 if (value != result) { | 3271 if (value != result) { |
| 3272 __ vmovq(result, value); | 3272 __ vmovq(result, value); |
| 3273 } | 3273 } |
| 3274 } | 3274 } |
| 3275 | 3275 |
| 3276 | 3276 |
| 3277 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const { | 3277 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { |
| 3278 const intptr_t kNumInputs = 4; | 3278 const intptr_t kNumInputs = 4; |
| 3279 const intptr_t kNumTemps = 1; | 3279 const intptr_t kNumTemps = 1; |
| 3280 LocationSummary* summary = | 3280 LocationSummary* summary = |
| 3281 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3281 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3282 summary->set_in(0, Location::RequiresRegister()); | 3282 summary->set_in(0, Location::RequiresRegister()); |
| 3283 summary->set_in(1, Location::RequiresRegister()); | 3283 summary->set_in(1, Location::RequiresRegister()); |
| 3284 summary->set_in(2, Location::RequiresRegister()); | 3284 summary->set_in(2, Location::RequiresRegister()); |
| 3285 summary->set_in(3, Location::RequiresRegister()); | 3285 summary->set_in(3, Location::RequiresRegister()); |
| 3286 summary->set_temp(0, Location::RequiresRegister()); | 3286 summary->set_temp(0, Location::RequiresRegister()); |
| 3287 // Low (< 7) Q register needed for the vmovsr instruction. | 3287 // Low (< 7) Q register needed for the vmovsr instruction. |
| 3288 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3288 summary->set_out(Location::FpuRegisterLocation(Q6)); |
| 3289 return summary; | 3289 return summary; |
| 3290 } | 3290 } |
| 3291 | 3291 |
| 3292 | 3292 |
| 3293 void Uint32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3293 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3294 Register v0 = locs()->in(0).reg(); | 3294 Register v0 = locs()->in(0).reg(); |
| 3295 Register v1 = locs()->in(1).reg(); | 3295 Register v1 = locs()->in(1).reg(); |
| 3296 Register v2 = locs()->in(2).reg(); | 3296 Register v2 = locs()->in(2).reg(); |
| 3297 Register v3 = locs()->in(3).reg(); | 3297 Register v3 = locs()->in(3).reg(); |
| 3298 Register temp = locs()->temp(0).reg(); | 3298 Register temp = locs()->temp(0).reg(); |
| 3299 QRegister result = locs()->out().fpu_reg(); | 3299 QRegister result = locs()->out().fpu_reg(); |
| 3300 DRegister dresult0 = EvenDRegisterOf(result); | 3300 DRegister dresult0 = EvenDRegisterOf(result); |
| 3301 DRegister dresult1 = OddDRegisterOf(result); | 3301 DRegister dresult1 = OddDRegisterOf(result); |
| 3302 SRegister sresult0 = EvenSRegisterOf(dresult0); | 3302 SRegister sresult0 = EvenSRegisterOf(dresult0); |
| 3303 SRegister sresult1 = OddSRegisterOf(dresult0); | 3303 SRegister sresult1 = OddSRegisterOf(dresult0); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3314 __ vmovsr(sresult1, temp, EQ); | 3314 __ vmovsr(sresult1, temp, EQ); |
| 3315 | 3315 |
| 3316 __ CompareObject(v2, Bool::True()); | 3316 __ CompareObject(v2, Bool::True()); |
| 3317 __ vmovsr(sresult2, temp, EQ); | 3317 __ vmovsr(sresult2, temp, EQ); |
| 3318 | 3318 |
| 3319 __ CompareObject(v3, Bool::True()); | 3319 __ CompareObject(v3, Bool::True()); |
| 3320 __ vmovsr(sresult3, temp, EQ); | 3320 __ vmovsr(sresult3, temp, EQ); |
| 3321 } | 3321 } |
| 3322 | 3322 |
| 3323 | 3323 |
| 3324 LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const { | 3324 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { |
| 3325 const intptr_t kNumInputs = 1; | 3325 const intptr_t kNumInputs = 1; |
| 3326 const intptr_t kNumTemps = 0; | 3326 const intptr_t kNumTemps = 0; |
| 3327 LocationSummary* summary = | 3327 LocationSummary* summary = |
| 3328 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3328 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3329 // Low (< 7) Q registers are needed for the vmovrs instruction. | 3329 // Low (< 7) Q registers are needed for the vmovrs instruction. |
| 3330 summary->set_in(0, Location::FpuRegisterLocation(Q6)); | 3330 summary->set_in(0, Location::FpuRegisterLocation(Q6)); |
| 3331 summary->set_out(Location::RequiresRegister()); | 3331 summary->set_out(Location::RequiresRegister()); |
| 3332 return summary; | 3332 return summary; |
| 3333 } | 3333 } |
| 3334 | 3334 |
| 3335 | 3335 |
| 3336 void Uint32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3336 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3337 QRegister value = locs()->in(0).fpu_reg(); | 3337 QRegister value = locs()->in(0).fpu_reg(); |
| 3338 Register result = locs()->out().reg(); | 3338 Register result = locs()->out().reg(); |
| 3339 | 3339 |
| 3340 DRegister dvalue0 = EvenDRegisterOf(value); | 3340 DRegister dvalue0 = EvenDRegisterOf(value); |
| 3341 DRegister dvalue1 = OddDRegisterOf(value); | 3341 DRegister dvalue1 = OddDRegisterOf(value); |
| 3342 SRegister svalue0 = EvenSRegisterOf(dvalue0); | 3342 SRegister svalue0 = EvenSRegisterOf(dvalue0); |
| 3343 SRegister svalue1 = OddSRegisterOf(dvalue0); | 3343 SRegister svalue1 = OddSRegisterOf(dvalue0); |
| 3344 SRegister svalue2 = EvenSRegisterOf(dvalue1); | 3344 SRegister svalue2 = EvenSRegisterOf(dvalue1); |
| 3345 SRegister svalue3 = OddSRegisterOf(dvalue1); | 3345 SRegister svalue3 = OddSRegisterOf(dvalue1); |
| 3346 | 3346 |
| 3347 switch (op_kind()) { | 3347 switch (op_kind()) { |
| 3348 case MethodRecognizer::kUint32x4GetFlagX: | 3348 case MethodRecognizer::kInt32x4GetFlagX: |
| 3349 __ vmovrs(result, svalue0); | 3349 __ vmovrs(result, svalue0); |
| 3350 break; | 3350 break; |
| 3351 case MethodRecognizer::kUint32x4GetFlagY: | 3351 case MethodRecognizer::kInt32x4GetFlagY: |
| 3352 __ vmovrs(result, svalue1); | 3352 __ vmovrs(result, svalue1); |
| 3353 break; | 3353 break; |
| 3354 case MethodRecognizer::kUint32x4GetFlagZ: | 3354 case MethodRecognizer::kInt32x4GetFlagZ: |
| 3355 __ vmovrs(result, svalue2); | 3355 __ vmovrs(result, svalue2); |
| 3356 break; | 3356 break; |
| 3357 case MethodRecognizer::kUint32x4GetFlagW: | 3357 case MethodRecognizer::kInt32x4GetFlagW: |
| 3358 __ vmovrs(result, svalue3); | 3358 __ vmovrs(result, svalue3); |
| 3359 break; | 3359 break; |
| 3360 default: UNREACHABLE(); | 3360 default: UNREACHABLE(); |
| 3361 } | 3361 } |
| 3362 | 3362 |
| 3363 __ tst(result, ShifterOperand(result)); | 3363 __ tst(result, ShifterOperand(result)); |
| 3364 __ LoadObject(result, Bool::True(), NE); | 3364 __ LoadObject(result, Bool::True(), NE); |
| 3365 __ LoadObject(result, Bool::False(), EQ); | 3365 __ LoadObject(result, Bool::False(), EQ); |
| 3366 } | 3366 } |
| 3367 | 3367 |
| 3368 | 3368 |
| 3369 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const { | 3369 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { |
| 3370 const intptr_t kNumInputs = 3; | 3370 const intptr_t kNumInputs = 3; |
| 3371 const intptr_t kNumTemps = 1; | 3371 const intptr_t kNumTemps = 1; |
| 3372 LocationSummary* summary = | 3372 LocationSummary* summary = |
| 3373 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3373 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3374 summary->set_in(0, Location::RequiresFpuRegister()); | 3374 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3375 summary->set_in(1, Location::RequiresFpuRegister()); | 3375 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3376 summary->set_in(2, Location::RequiresFpuRegister()); | 3376 summary->set_in(2, Location::RequiresFpuRegister()); |
| 3377 summary->set_temp(0, Location::RequiresFpuRegister()); | 3377 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 3378 summary->set_out(Location::RequiresFpuRegister()); | 3378 summary->set_out(Location::RequiresFpuRegister()); |
| 3379 return summary; | 3379 return summary; |
| 3380 } | 3380 } |
| 3381 | 3381 |
| 3382 | 3382 |
| 3383 void Uint32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3383 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3384 QRegister mask = locs()->in(0).fpu_reg(); | 3384 QRegister mask = locs()->in(0).fpu_reg(); |
| 3385 QRegister trueValue = locs()->in(1).fpu_reg(); | 3385 QRegister trueValue = locs()->in(1).fpu_reg(); |
| 3386 QRegister falseValue = locs()->in(2).fpu_reg(); | 3386 QRegister falseValue = locs()->in(2).fpu_reg(); |
| 3387 QRegister out = locs()->out().fpu_reg(); | 3387 QRegister out = locs()->out().fpu_reg(); |
| 3388 QRegister temp = locs()->temp(0).fpu_reg(); | 3388 QRegister temp = locs()->temp(0).fpu_reg(); |
| 3389 | 3389 |
| 3390 // Copy mask. | 3390 // Copy mask. |
| 3391 __ vmovq(temp, mask); | 3391 __ vmovq(temp, mask); |
| 3392 // Invert it. | 3392 // Invert it. |
| 3393 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. | 3393 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. |
| 3394 __ vornq(temp, QTMP, temp); // temp <- ~temp. | 3394 __ vornq(temp, QTMP, temp); // temp <- ~temp. |
| 3395 // mask = mask & trueValue. | 3395 // mask = mask & trueValue. |
| 3396 __ vandq(mask, mask, trueValue); | 3396 __ vandq(mask, mask, trueValue); |
| 3397 // temp = temp & falseValue. | 3397 // temp = temp & falseValue. |
| 3398 __ vandq(temp, temp, falseValue); | 3398 __ vandq(temp, temp, falseValue); |
| 3399 // out = mask | temp. | 3399 // out = mask | temp. |
| 3400 __ vorrq(out, mask, temp); | 3400 __ vorrq(out, mask, temp); |
| 3401 } | 3401 } |
| 3402 | 3402 |
| 3403 | 3403 |
| 3404 LocationSummary* Uint32x4SetFlagInstr::MakeLocationSummary() const { | 3404 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { |
| 3405 const intptr_t kNumInputs = 2; | 3405 const intptr_t kNumInputs = 2; |
| 3406 const intptr_t kNumTemps = 0; | 3406 const intptr_t kNumTemps = 0; |
| 3407 LocationSummary* summary = | 3407 LocationSummary* summary = |
| 3408 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3408 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3409 summary->set_in(0, Location::RequiresFpuRegister()); | 3409 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3410 summary->set_in(1, Location::RequiresRegister()); | 3410 summary->set_in(1, Location::RequiresRegister()); |
| 3411 // Low (< 7) Q register needed for the vmovsr instruction. | 3411 // Low (< 7) Q register needed for the vmovsr instruction. |
| 3412 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3412 summary->set_out(Location::FpuRegisterLocation(Q6)); |
| 3413 return summary; | 3413 return summary; |
| 3414 } | 3414 } |
| 3415 | 3415 |
| 3416 | 3416 |
| 3417 void Uint32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3417 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3418 QRegister mask = locs()->in(0).fpu_reg(); | 3418 QRegister mask = locs()->in(0).fpu_reg(); |
| 3419 Register flag = locs()->in(1).reg(); | 3419 Register flag = locs()->in(1).reg(); |
| 3420 QRegister result = locs()->out().fpu_reg(); | 3420 QRegister result = locs()->out().fpu_reg(); |
| 3421 | 3421 |
| 3422 DRegister dresult0 = EvenDRegisterOf(result); | 3422 DRegister dresult0 = EvenDRegisterOf(result); |
| 3423 DRegister dresult1 = OddDRegisterOf(result); | 3423 DRegister dresult1 = OddDRegisterOf(result); |
| 3424 SRegister sresult0 = EvenSRegisterOf(dresult0); | 3424 SRegister sresult0 = EvenSRegisterOf(dresult0); |
| 3425 SRegister sresult1 = OddSRegisterOf(dresult0); | 3425 SRegister sresult1 = OddSRegisterOf(dresult0); |
| 3426 SRegister sresult2 = EvenSRegisterOf(dresult1); | 3426 SRegister sresult2 = EvenSRegisterOf(dresult1); |
| 3427 SRegister sresult3 = OddSRegisterOf(dresult1); | 3427 SRegister sresult3 = OddSRegisterOf(dresult1); |
| 3428 | 3428 |
| 3429 if (result != mask) { | 3429 if (result != mask) { |
| 3430 __ vmovq(result, mask); | 3430 __ vmovq(result, mask); |
| 3431 } | 3431 } |
| 3432 | 3432 |
| 3433 __ CompareObject(flag, Bool::True()); | 3433 __ CompareObject(flag, Bool::True()); |
| 3434 __ LoadImmediate(TMP, 0xffffffff, EQ); | 3434 __ LoadImmediate(TMP, 0xffffffff, EQ); |
| 3435 __ LoadImmediate(TMP, 0, NE); | 3435 __ LoadImmediate(TMP, 0, NE); |
| 3436 switch (op_kind()) { | 3436 switch (op_kind()) { |
| 3437 case MethodRecognizer::kUint32x4WithFlagX: | 3437 case MethodRecognizer::kInt32x4WithFlagX: |
| 3438 __ vmovsr(sresult0, TMP); | 3438 __ vmovsr(sresult0, TMP); |
| 3439 break; | 3439 break; |
| 3440 case MethodRecognizer::kUint32x4WithFlagY: | 3440 case MethodRecognizer::kInt32x4WithFlagY: |
| 3441 __ vmovsr(sresult1, TMP); | 3441 __ vmovsr(sresult1, TMP); |
| 3442 break; | 3442 break; |
| 3443 case MethodRecognizer::kUint32x4WithFlagZ: | 3443 case MethodRecognizer::kInt32x4WithFlagZ: |
| 3444 __ vmovsr(sresult2, TMP); | 3444 __ vmovsr(sresult2, TMP); |
| 3445 break; | 3445 break; |
| 3446 case MethodRecognizer::kUint32x4WithFlagW: | 3446 case MethodRecognizer::kInt32x4WithFlagW: |
| 3447 __ vmovsr(sresult3, TMP); | 3447 __ vmovsr(sresult3, TMP); |
| 3448 break; | 3448 break; |
| 3449 default: UNREACHABLE(); | 3449 default: UNREACHABLE(); |
| 3450 } | 3450 } |
| 3451 } | 3451 } |
| 3452 | 3452 |
| 3453 | 3453 |
| 3454 LocationSummary* Uint32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3454 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { |
| 3455 const intptr_t kNumInputs = 1; | 3455 const intptr_t kNumInputs = 1; |
| 3456 const intptr_t kNumTemps = 0; | 3456 const intptr_t kNumTemps = 0; |
| 3457 LocationSummary* summary = | 3457 LocationSummary* summary = |
| 3458 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3458 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3459 summary->set_in(0, Location::RequiresFpuRegister()); | 3459 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3460 summary->set_out(Location::RequiresFpuRegister()); | 3460 summary->set_out(Location::RequiresFpuRegister()); |
| 3461 return summary; | 3461 return summary; |
| 3462 } | 3462 } |
| 3463 | 3463 |
| 3464 | 3464 |
| 3465 void Uint32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3465 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3466 QRegister value = locs()->in(0).fpu_reg(); | 3466 QRegister value = locs()->in(0).fpu_reg(); |
| 3467 QRegister result = locs()->out().fpu_reg(); | 3467 QRegister result = locs()->out().fpu_reg(); |
| 3468 | 3468 |
| 3469 if (value != result) { | 3469 if (value != result) { |
| 3470 __ vmovq(result, value); | 3470 __ vmovq(result, value); |
| 3471 } | 3471 } |
| 3472 } | 3472 } |
| 3473 | 3473 |
| 3474 | 3474 |
| 3475 LocationSummary* BinaryUint32x4OpInstr::MakeLocationSummary() const { | 3475 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { |
| 3476 const intptr_t kNumInputs = 2; | 3476 const intptr_t kNumInputs = 2; |
| 3477 const intptr_t kNumTemps = 0; | 3477 const intptr_t kNumTemps = 0; |
| 3478 LocationSummary* summary = | 3478 LocationSummary* summary = |
| 3479 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3479 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3480 summary->set_in(0, Location::RequiresFpuRegister()); | 3480 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3481 summary->set_in(1, Location::RequiresFpuRegister()); | 3481 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3482 summary->set_out(Location::RequiresFpuRegister()); | 3482 summary->set_out(Location::RequiresFpuRegister()); |
| 3483 return summary; | 3483 return summary; |
| 3484 } | 3484 } |
| 3485 | 3485 |
| 3486 | 3486 |
| 3487 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3487 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3488 QRegister left = locs()->in(0).fpu_reg(); | 3488 QRegister left = locs()->in(0).fpu_reg(); |
| 3489 QRegister right = locs()->in(1).fpu_reg(); | 3489 QRegister right = locs()->in(1).fpu_reg(); |
| 3490 QRegister result = locs()->out().fpu_reg(); | 3490 QRegister result = locs()->out().fpu_reg(); |
| 3491 switch (op_kind()) { | 3491 switch (op_kind()) { |
| 3492 case Token::kBIT_AND: { | 3492 case Token::kBIT_AND: { |
| 3493 __ vandq(result, left, right); | 3493 __ vandq(result, left, right); |
| 3494 break; | 3494 break; |
| 3495 } | 3495 } |
| 3496 case Token::kBIT_OR: { | 3496 case Token::kBIT_OR: { |
| 3497 __ vorrq(result, left, right); | 3497 __ vorrq(result, left, right); |
| (...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4436 compiler->GenerateCall(token_pos(), | 4436 compiler->GenerateCall(token_pos(), |
| 4437 &label, | 4437 &label, |
| 4438 PcDescriptors::kOther, | 4438 PcDescriptors::kOther, |
| 4439 locs()); | 4439 locs()); |
| 4440 __ Drop(2); // Discard type arguments and receiver. | 4440 __ Drop(2); // Discard type arguments and receiver. |
| 4441 } | 4441 } |
| 4442 | 4442 |
| 4443 } // namespace dart | 4443 } // namespace dart |
| 4444 | 4444 |
| 4445 #endif // defined TARGET_ARCH_ARM | 4445 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |