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 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 switch (class_id_) { | 972 switch (class_id_) { |
973 case kArrayCid: | 973 case kArrayCid: |
974 case kImmutableArrayCid: | 974 case kImmutableArrayCid: |
975 return CompileType::Dynamic(); | 975 return CompileType::Dynamic(); |
976 | 976 |
977 case kTypedDataFloat32ArrayCid: | 977 case kTypedDataFloat32ArrayCid: |
978 case kTypedDataFloat64ArrayCid: | 978 case kTypedDataFloat64ArrayCid: |
979 return CompileType::FromCid(kDoubleCid); | 979 return CompileType::FromCid(kDoubleCid); |
980 case kTypedDataFloat32x4ArrayCid: | 980 case kTypedDataFloat32x4ArrayCid: |
981 return CompileType::FromCid(kFloat32x4Cid); | 981 return CompileType::FromCid(kFloat32x4Cid); |
982 case kTypedDataUint32x4ArrayCid: | 982 case kTypedDataInt32x4ArrayCid: |
983 return CompileType::FromCid(kUint32x4Cid); | 983 return CompileType::FromCid(kInt32x4Cid); |
984 | 984 |
985 case kTypedDataInt8ArrayCid: | 985 case kTypedDataInt8ArrayCid: |
986 case kTypedDataUint8ArrayCid: | 986 case kTypedDataUint8ArrayCid: |
987 case kTypedDataUint8ClampedArrayCid: | 987 case kTypedDataUint8ClampedArrayCid: |
988 case kExternalTypedDataUint8ArrayCid: | 988 case kExternalTypedDataUint8ArrayCid: |
989 case kExternalTypedDataUint8ClampedArrayCid: | 989 case kExternalTypedDataUint8ClampedArrayCid: |
990 case kTypedDataInt16ArrayCid: | 990 case kTypedDataInt16ArrayCid: |
991 case kTypedDataUint16ArrayCid: | 991 case kTypedDataUint16ArrayCid: |
992 case kOneByteStringCid: | 992 case kOneByteStringCid: |
993 case kTwoByteStringCid: | 993 case kTwoByteStringCid: |
(...skipping 29 matching lines...) Expand all Loading... |
1023 case kTwoByteStringCid: | 1023 case kTwoByteStringCid: |
1024 return kTagged; | 1024 return kTagged; |
1025 case kTypedDataInt32ArrayCid: | 1025 case kTypedDataInt32ArrayCid: |
1026 case kTypedDataUint32ArrayCid: | 1026 case kTypedDataUint32ArrayCid: |
1027 // Instruction can deoptimize if we optimistically assumed that the result | 1027 // Instruction can deoptimize if we optimistically assumed that the result |
1028 // fits into Smi. | 1028 // fits into Smi. |
1029 return CanDeoptimize() ? kTagged : kUnboxedMint; | 1029 return CanDeoptimize() ? kTagged : kUnboxedMint; |
1030 case kTypedDataFloat32ArrayCid: | 1030 case kTypedDataFloat32ArrayCid: |
1031 case kTypedDataFloat64ArrayCid: | 1031 case kTypedDataFloat64ArrayCid: |
1032 return kUnboxedDouble; | 1032 return kUnboxedDouble; |
1033 case kTypedDataUint32x4ArrayCid: | 1033 case kTypedDataInt32x4ArrayCid: |
1034 return kUnboxedUint32x4; | 1034 return kUnboxedInt32x4; |
1035 case kTypedDataFloat32x4ArrayCid: | 1035 case kTypedDataFloat32x4ArrayCid: |
1036 return kUnboxedFloat32x4; | 1036 return kUnboxedFloat32x4; |
1037 default: | 1037 default: |
1038 UNREACHABLE(); | 1038 UNREACHABLE(); |
1039 return kTagged; | 1039 return kTagged; |
1040 } | 1040 } |
1041 } | 1041 } |
1042 | 1042 |
1043 | 1043 |
1044 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1044 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
1045 const intptr_t kNumInputs = 2; | 1045 const intptr_t kNumInputs = 2; |
1046 const intptr_t kNumTemps = 0; | 1046 const intptr_t kNumTemps = 0; |
1047 LocationSummary* locs = | 1047 LocationSummary* locs = |
1048 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1048 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1049 locs->set_in(0, Location::RequiresRegister()); | 1049 locs->set_in(0, Location::RequiresRegister()); |
1050 // The smi index is either untagged (element size == 1), or it is left smi | 1050 // The smi index is either untagged (element size == 1), or it is left smi |
1051 // tagged (for all element sizes > 1). | 1051 // tagged (for all element sizes > 1). |
1052 // TODO(regis): Revisit and see if the index can be immediate. | 1052 // TODO(regis): Revisit and see if the index can be immediate. |
1053 locs->set_in(1, Location::WritableRegister()); | 1053 locs->set_in(1, Location::WritableRegister()); |
1054 if ((representation() == kUnboxedDouble) || | 1054 if ((representation() == kUnboxedDouble) || |
1055 (representation() == kUnboxedFloat32x4) || | 1055 (representation() == kUnboxedFloat32x4) || |
1056 (representation() == kUnboxedUint32x4)) { | 1056 (representation() == kUnboxedInt32x4)) { |
1057 locs->set_out(Location::RequiresFpuRegister()); | 1057 locs->set_out(Location::RequiresFpuRegister()); |
1058 } else { | 1058 } else { |
1059 locs->set_out(Location::RequiresRegister()); | 1059 locs->set_out(Location::RequiresRegister()); |
1060 } | 1060 } |
1061 return locs; | 1061 return locs; |
1062 } | 1062 } |
1063 | 1063 |
1064 | 1064 |
1065 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1065 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1066 Register array = locs()->in(0).reg(); | 1066 Register array = locs()->in(0).reg(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 if (!IsExternal()) { | 1099 if (!IsExternal()) { |
1100 ASSERT(this->array()->definition()->representation() == kTagged); | 1100 ASSERT(this->array()->definition()->representation() == kTagged); |
1101 __ AddImmediate(index.reg(), | 1101 __ AddImmediate(index.reg(), |
1102 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 1102 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
1103 } | 1103 } |
1104 element_address = Address(array, index.reg(), LSL, 0); | 1104 element_address = Address(array, index.reg(), LSL, 0); |
1105 | 1105 |
1106 if ((representation() == kUnboxedDouble) || | 1106 if ((representation() == kUnboxedDouble) || |
1107 (representation() == kUnboxedMint) || | 1107 (representation() == kUnboxedMint) || |
1108 (representation() == kUnboxedFloat32x4) || | 1108 (representation() == kUnboxedFloat32x4) || |
1109 (representation() == kUnboxedUint32x4)) { | 1109 (representation() == kUnboxedInt32x4)) { |
1110 QRegister result = locs()->out().fpu_reg(); | 1110 QRegister result = locs()->out().fpu_reg(); |
1111 DRegister dresult0 = EvenDRegisterOf(result); | 1111 DRegister dresult0 = EvenDRegisterOf(result); |
1112 DRegister dresult1 = OddDRegisterOf(result); | 1112 DRegister dresult1 = OddDRegisterOf(result); |
1113 switch (class_id()) { | 1113 switch (class_id()) { |
1114 case kTypedDataInt32ArrayCid: | 1114 case kTypedDataInt32ArrayCid: |
1115 UNIMPLEMENTED(); | 1115 UNIMPLEMENTED(); |
1116 break; | 1116 break; |
1117 case kTypedDataUint32ArrayCid: | 1117 case kTypedDataUint32ArrayCid: |
1118 UNIMPLEMENTED(); | 1118 UNIMPLEMENTED(); |
1119 break; | 1119 break; |
1120 case kTypedDataFloat32ArrayCid: | 1120 case kTypedDataFloat32ArrayCid: |
1121 // Load single precision float and promote to double. | 1121 // Load single precision float and promote to double. |
1122 // vldrs does not support indexed addressing. | 1122 // vldrs does not support indexed addressing. |
1123 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1123 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
1124 element_address = Address(index.reg(), 0); | 1124 element_address = Address(index.reg(), 0); |
1125 __ vldrs(STMP, element_address); | 1125 __ vldrs(STMP, element_address); |
1126 __ vcvtds(dresult0, STMP); | 1126 __ vcvtds(dresult0, STMP); |
1127 break; | 1127 break; |
1128 case kTypedDataFloat64ArrayCid: | 1128 case kTypedDataFloat64ArrayCid: |
1129 // vldrd does not support indexed addressing. | 1129 // vldrd does not support indexed addressing. |
1130 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1130 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
1131 element_address = Address(index.reg(), 0); | 1131 element_address = Address(index.reg(), 0); |
1132 __ vldrd(dresult0, element_address); | 1132 __ vldrd(dresult0, element_address); |
1133 break; | 1133 break; |
1134 case kTypedDataUint32x4ArrayCid: | 1134 case kTypedDataInt32x4ArrayCid: |
1135 case kTypedDataFloat32x4ArrayCid: | 1135 case kTypedDataFloat32x4ArrayCid: |
1136 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1136 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
1137 __ LoadDFromOffset(dresult0, index.reg(), 0); | 1137 __ LoadDFromOffset(dresult0, index.reg(), 0); |
1138 __ LoadDFromOffset(dresult1, index.reg(), 2*kWordSize); | 1138 __ LoadDFromOffset(dresult1, index.reg(), 2*kWordSize); |
1139 break; | 1139 break; |
1140 } | 1140 } |
1141 return; | 1141 return; |
1142 } | 1142 } |
1143 | 1143 |
1144 Register result = locs()->out().reg(); | 1144 Register result = locs()->out().reg(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 case kTypedDataUint16ArrayCid: | 1210 case kTypedDataUint16ArrayCid: |
1211 return kTagged; | 1211 return kTagged; |
1212 case kTypedDataInt32ArrayCid: | 1212 case kTypedDataInt32ArrayCid: |
1213 case kTypedDataUint32ArrayCid: | 1213 case kTypedDataUint32ArrayCid: |
1214 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1214 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
1215 case kTypedDataFloat32ArrayCid: | 1215 case kTypedDataFloat32ArrayCid: |
1216 case kTypedDataFloat64ArrayCid: | 1216 case kTypedDataFloat64ArrayCid: |
1217 return kUnboxedDouble; | 1217 return kUnboxedDouble; |
1218 case kTypedDataFloat32x4ArrayCid: | 1218 case kTypedDataFloat32x4ArrayCid: |
1219 return kUnboxedFloat32x4; | 1219 return kUnboxedFloat32x4; |
1220 case kTypedDataUint32x4ArrayCid: | 1220 case kTypedDataInt32x4ArrayCid: |
1221 return kUnboxedUint32x4; | 1221 return kUnboxedInt32x4; |
1222 default: | 1222 default: |
1223 UNREACHABLE(); | 1223 UNREACHABLE(); |
1224 return kTagged; | 1224 return kTagged; |
1225 } | 1225 } |
1226 } | 1226 } |
1227 | 1227 |
1228 | 1228 |
1229 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1229 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
1230 const intptr_t kNumInputs = 3; | 1230 const intptr_t kNumInputs = 3; |
1231 const intptr_t kNumTemps = 0; | 1231 const intptr_t kNumTemps = 0; |
(...skipping 17 matching lines...) Expand all Loading... |
1249 case kTypedDataUint8ClampedArrayCid: | 1249 case kTypedDataUint8ClampedArrayCid: |
1250 case kOneByteStringCid: | 1250 case kOneByteStringCid: |
1251 case kTypedDataInt16ArrayCid: | 1251 case kTypedDataInt16ArrayCid: |
1252 case kTypedDataUint16ArrayCid: | 1252 case kTypedDataUint16ArrayCid: |
1253 case kTypedDataInt32ArrayCid: | 1253 case kTypedDataInt32ArrayCid: |
1254 case kTypedDataUint32ArrayCid: | 1254 case kTypedDataUint32ArrayCid: |
1255 locs->set_in(2, Location::WritableRegister()); | 1255 locs->set_in(2, Location::WritableRegister()); |
1256 break; | 1256 break; |
1257 case kTypedDataFloat32ArrayCid: | 1257 case kTypedDataFloat32ArrayCid: |
1258 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. | 1258 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. |
1259 case kTypedDataUint32x4ArrayCid: | 1259 case kTypedDataInt32x4ArrayCid: |
1260 case kTypedDataFloat32x4ArrayCid: | 1260 case kTypedDataFloat32x4ArrayCid: |
1261 locs->set_in(2, Location::RequiresFpuRegister()); | 1261 locs->set_in(2, Location::RequiresFpuRegister()); |
1262 break; | 1262 break; |
1263 default: | 1263 default: |
1264 UNREACHABLE(); | 1264 UNREACHABLE(); |
1265 return NULL; | 1265 return NULL; |
1266 } | 1266 } |
1267 return locs; | 1267 return locs; |
1268 } | 1268 } |
1269 | 1269 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1390 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
1391 __ StoreSToOffset(STMP, index.reg(), 0); | 1391 __ StoreSToOffset(STMP, index.reg(), 0); |
1392 break; | 1392 break; |
1393 } | 1393 } |
1394 case kTypedDataFloat64ArrayCid: { | 1394 case kTypedDataFloat64ArrayCid: { |
1395 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); | 1395 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); |
1396 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1396 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
1397 __ StoreDToOffset(in2, index.reg(), 0); | 1397 __ StoreDToOffset(in2, index.reg(), 0); |
1398 break; | 1398 break; |
1399 } | 1399 } |
1400 case kTypedDataUint32x4ArrayCid: | 1400 case kTypedDataInt32x4ArrayCid: |
1401 case kTypedDataFloat32x4ArrayCid: { | 1401 case kTypedDataFloat32x4ArrayCid: { |
1402 QRegister in = locs()->in(2).fpu_reg(); | 1402 QRegister in = locs()->in(2).fpu_reg(); |
1403 DRegister din0 = EvenDRegisterOf(in); | 1403 DRegister din0 = EvenDRegisterOf(in); |
1404 DRegister din1 = OddDRegisterOf(in); | 1404 DRegister din1 = OddDRegisterOf(in); |
1405 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1405 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
1406 __ StoreDToOffset(din0, index.reg(), 0); | 1406 __ StoreDToOffset(din0, index.reg(), 0); |
1407 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); | 1407 __ StoreDToOffset(din1, index.reg(), 2*kWordSize); |
1408 break; | 1408 break; |
1409 } | 1409 } |
1410 default: | 1410 default: |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1516 Label check_array, length_compared, no_fixed_length; | 1516 Label check_array, length_compared, no_fixed_length; |
1517 // If length is negative the length guard is either disabled or | 1517 // If length is negative the length guard is either disabled or |
1518 // has not been initialized, either way it is safe to skip the | 1518 // has not been initialized, either way it is safe to skip the |
1519 // length check. | 1519 // length check. |
1520 __ ldr(IP, field_length_operand); | 1520 __ ldr(IP, field_length_operand); |
1521 __ CompareImmediate(IP, 0); | 1521 __ CompareImmediate(IP, 0); |
1522 __ b(&skip_length_check, LT); | 1522 __ b(&skip_length_check, LT); |
1523 __ CompareImmediate(value_cid_reg, kNullCid); | 1523 __ CompareImmediate(value_cid_reg, kNullCid); |
1524 __ b(&no_fixed_length, EQ); | 1524 __ b(&no_fixed_length, EQ); |
1525 // Check for typed data array. | 1525 // Check for typed data array. |
1526 __ CompareImmediate(value_cid_reg, kTypedDataUint32x4ArrayCid); | 1526 __ CompareImmediate(value_cid_reg, kTypedDataInt32x4ArrayCid); |
1527 __ b(&no_fixed_length, GT); | 1527 __ b(&no_fixed_length, GT); |
1528 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); | 1528 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); |
1529 // Could still be a regular array. | 1529 // Could still be a regular array. |
1530 __ b(&check_array, LT); | 1530 __ b(&check_array, LT); |
1531 __ ldr(temp_reg, | 1531 __ ldr(temp_reg, |
1532 FieldAddress(value_reg, TypedData::length_offset())); | 1532 FieldAddress(value_reg, TypedData::length_offset())); |
1533 __ ldr(IP, field_length_operand); | 1533 __ ldr(IP, field_length_operand); |
1534 __ cmp(temp_reg, ShifterOperand(IP)); | 1534 __ cmp(temp_reg, ShifterOperand(IP)); |
1535 __ b(&length_compared); | 1535 __ b(&length_compared); |
1536 // Check for regular array. | 1536 // Check for regular array. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 __ b(fail, NE); | 1596 __ b(fail, NE); |
1597 | 1597 |
1598 if (value_cid == kDynamicCid) { | 1598 if (value_cid == kDynamicCid) { |
1599 __ str(value_cid_reg, field_cid_operand); | 1599 __ str(value_cid_reg, field_cid_operand); |
1600 __ str(value_cid_reg, field_nullability_operand); | 1600 __ str(value_cid_reg, field_nullability_operand); |
1601 if (field_has_length) { | 1601 if (field_has_length) { |
1602 Label check_array, length_set, no_fixed_length; | 1602 Label check_array, length_set, no_fixed_length; |
1603 __ CompareImmediate(value_cid_reg, kNullCid); | 1603 __ CompareImmediate(value_cid_reg, kNullCid); |
1604 __ b(&no_fixed_length, EQ); | 1604 __ b(&no_fixed_length, EQ); |
1605 // Check for typed data array. | 1605 // Check for typed data array. |
1606 __ CompareImmediate(value_cid_reg, kTypedDataUint32x4ArrayCid); | 1606 __ CompareImmediate(value_cid_reg, kTypedDataInt32x4ArrayCid); |
1607 __ b(&no_fixed_length, GT); | 1607 __ b(&no_fixed_length, GT); |
1608 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); | 1608 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); |
1609 // Could still be a regular array. | 1609 // Could still be a regular array. |
1610 __ b(&check_array, LT); | 1610 __ b(&check_array, LT); |
1611 // Destroy value_cid_reg (safe because we are finished with it). | 1611 // Destroy value_cid_reg (safe because we are finished with it). |
1612 __ ldr(value_cid_reg, | 1612 __ ldr(value_cid_reg, |
1613 FieldAddress(value_reg, TypedData::length_offset())); | 1613 FieldAddress(value_reg, TypedData::length_offset())); |
1614 __ str(value_cid_reg, field_length_operand); | 1614 __ str(value_cid_reg, field_length_operand); |
1615 __ b(&length_set); // Updated field length typed data array. | 1615 __ b(&length_set); // Updated field length typed data array. |
1616 // Check for regular array. | 1616 // Check for regular array. |
(...skipping 1262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2879 | 2879 |
2880 const DRegister result_even = EvenDRegisterOf(result); | 2880 const DRegister result_even = EvenDRegisterOf(result); |
2881 const DRegister result_odd = OddDRegisterOf(result); | 2881 const DRegister result_odd = OddDRegisterOf(result); |
2882 __ LoadDFromOffset(result_even, value, | 2882 __ LoadDFromOffset(result_even, value, |
2883 Float32x4::value_offset() - kHeapObjectTag); | 2883 Float32x4::value_offset() - kHeapObjectTag); |
2884 __ LoadDFromOffset(result_odd, value, | 2884 __ LoadDFromOffset(result_odd, value, |
2885 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2885 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
2886 } | 2886 } |
2887 | 2887 |
2888 | 2888 |
2889 LocationSummary* BoxUint32x4Instr::MakeLocationSummary() const { | 2889 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { |
2890 const intptr_t kNumInputs = 1; | 2890 const intptr_t kNumInputs = 1; |
2891 const intptr_t kNumTemps = 0; | 2891 const intptr_t kNumTemps = 0; |
2892 LocationSummary* summary = | 2892 LocationSummary* summary = |
2893 new LocationSummary(kNumInputs, | 2893 new LocationSummary(kNumInputs, |
2894 kNumTemps, | 2894 kNumTemps, |
2895 LocationSummary::kCallOnSlowPath); | 2895 LocationSummary::kCallOnSlowPath); |
2896 summary->set_in(0, Location::RequiresFpuRegister()); | 2896 summary->set_in(0, Location::RequiresFpuRegister()); |
2897 summary->set_out(Location::RequiresRegister()); | 2897 summary->set_out(Location::RequiresRegister()); |
2898 return summary; | 2898 return summary; |
2899 } | 2899 } |
2900 | 2900 |
2901 | 2901 |
2902 class BoxUint32x4SlowPath : public SlowPathCode { | 2902 class BoxInt32x4SlowPath : public SlowPathCode { |
2903 public: | 2903 public: |
2904 explicit BoxUint32x4SlowPath(BoxUint32x4Instr* instruction) | 2904 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) |
2905 : instruction_(instruction) { } | 2905 : instruction_(instruction) { } |
2906 | 2906 |
2907 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2907 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
2908 __ Comment("BoxUint32x4SlowPath"); | 2908 __ Comment("BoxInt32x4SlowPath"); |
2909 __ Bind(entry_label()); | 2909 __ Bind(entry_label()); |
2910 const Class& uint32x4_class = compiler->uint32x4_class(); | 2910 const Class& int32x4_class = compiler->int32x4_class(); |
2911 const Code& stub = | 2911 const Code& stub = |
2912 Code::Handle(StubCode::GetAllocationStubForClass(uint32x4_class)); | 2912 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); |
2913 const ExternalLabel label(uint32x4_class.ToCString(), stub.EntryPoint()); | 2913 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); |
2914 | 2914 |
2915 LocationSummary* locs = instruction_->locs(); | 2915 LocationSummary* locs = instruction_->locs(); |
2916 locs->live_registers()->Remove(locs->out()); | 2916 locs->live_registers()->Remove(locs->out()); |
2917 | 2917 |
2918 compiler->SaveLiveRegisters(locs); | 2918 compiler->SaveLiveRegisters(locs); |
2919 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | 2919 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
2920 &label, | 2920 &label, |
2921 PcDescriptors::kOther, | 2921 PcDescriptors::kOther, |
2922 locs); | 2922 locs); |
2923 __ mov(locs->out().reg(), ShifterOperand(R0)); | 2923 __ mov(locs->out().reg(), ShifterOperand(R0)); |
2924 compiler->RestoreLiveRegisters(locs); | 2924 compiler->RestoreLiveRegisters(locs); |
2925 | 2925 |
2926 __ b(exit_label()); | 2926 __ b(exit_label()); |
2927 } | 2927 } |
2928 | 2928 |
2929 private: | 2929 private: |
2930 BoxUint32x4Instr* instruction_; | 2930 BoxInt32x4Instr* instruction_; |
2931 }; | 2931 }; |
2932 | 2932 |
2933 | 2933 |
2934 void BoxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2934 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2935 BoxUint32x4SlowPath* slow_path = new BoxUint32x4SlowPath(this); | 2935 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); |
2936 compiler->AddSlowPathCode(slow_path); | 2936 compiler->AddSlowPathCode(slow_path); |
2937 | 2937 |
2938 Register out_reg = locs()->out().reg(); | 2938 Register out_reg = locs()->out().reg(); |
2939 QRegister value = locs()->in(0).fpu_reg(); | 2939 QRegister value = locs()->in(0).fpu_reg(); |
2940 DRegister value_even = EvenDRegisterOf(value); | 2940 DRegister value_even = EvenDRegisterOf(value); |
2941 DRegister value_odd = OddDRegisterOf(value); | 2941 DRegister value_odd = OddDRegisterOf(value); |
2942 | 2942 |
2943 __ TryAllocate(compiler->uint32x4_class(), | 2943 __ TryAllocate(compiler->int32x4_class(), |
2944 slow_path->entry_label(), | 2944 slow_path->entry_label(), |
2945 out_reg); | 2945 out_reg); |
2946 __ Bind(slow_path->exit_label()); | 2946 __ Bind(slow_path->exit_label()); |
2947 __ StoreDToOffset(value_even, out_reg, | 2947 __ StoreDToOffset(value_even, out_reg, |
2948 Uint32x4::value_offset() - kHeapObjectTag); | 2948 Int32x4::value_offset() - kHeapObjectTag); |
2949 __ StoreDToOffset(value_odd, out_reg, | 2949 __ StoreDToOffset(value_odd, out_reg, |
2950 Uint32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2950 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
2951 } | 2951 } |
2952 | 2952 |
2953 | 2953 |
2954 LocationSummary* UnboxUint32x4Instr::MakeLocationSummary() const { | 2954 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { |
2955 const intptr_t value_cid = value()->Type()->ToCid(); | 2955 const intptr_t value_cid = value()->Type()->ToCid(); |
2956 const intptr_t kNumInputs = 1; | 2956 const intptr_t kNumInputs = 1; |
2957 const intptr_t kNumTemps = value_cid == kUint32x4Cid ? 0 : 1; | 2957 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
2958 LocationSummary* summary = | 2958 LocationSummary* summary = |
2959 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2959 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2960 summary->set_in(0, Location::RequiresRegister()); | 2960 summary->set_in(0, Location::RequiresRegister()); |
2961 if (kNumTemps > 0) { | 2961 if (kNumTemps > 0) { |
2962 ASSERT(kNumTemps == 1); | 2962 ASSERT(kNumTemps == 1); |
2963 summary->set_temp(0, Location::RequiresRegister()); | 2963 summary->set_temp(0, Location::RequiresRegister()); |
2964 } | 2964 } |
2965 summary->set_out(Location::RequiresFpuRegister()); | 2965 summary->set_out(Location::RequiresFpuRegister()); |
2966 return summary; | 2966 return summary; |
2967 } | 2967 } |
2968 | 2968 |
2969 | 2969 |
2970 void UnboxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2970 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2971 const intptr_t value_cid = value()->Type()->ToCid(); | 2971 const intptr_t value_cid = value()->Type()->ToCid(); |
2972 const Register value = locs()->in(0).reg(); | 2972 const Register value = locs()->in(0).reg(); |
2973 const QRegister result = locs()->out().fpu_reg(); | 2973 const QRegister result = locs()->out().fpu_reg(); |
2974 | 2974 |
2975 if (value_cid != kUint32x4Cid) { | 2975 if (value_cid != kInt32x4Cid) { |
2976 const Register temp = locs()->temp(0).reg(); | 2976 const Register temp = locs()->temp(0).reg(); |
2977 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 2977 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
2978 __ tst(value, ShifterOperand(kSmiTagMask)); | 2978 __ tst(value, ShifterOperand(kSmiTagMask)); |
2979 __ b(deopt, EQ); | 2979 __ b(deopt, EQ); |
2980 __ CompareClassId(value, kUint32x4Cid, temp); | 2980 __ CompareClassId(value, kInt32x4Cid, temp); |
2981 __ b(deopt, NE); | 2981 __ b(deopt, NE); |
2982 } | 2982 } |
2983 | 2983 |
2984 const DRegister result_even = EvenDRegisterOf(result); | 2984 const DRegister result_even = EvenDRegisterOf(result); |
2985 const DRegister result_odd = OddDRegisterOf(result); | 2985 const DRegister result_odd = OddDRegisterOf(result); |
2986 __ LoadDFromOffset(result_even, value, | 2986 __ LoadDFromOffset(result_even, value, |
2987 Uint32x4::value_offset() - kHeapObjectTag); | 2987 Int32x4::value_offset() - kHeapObjectTag); |
2988 __ LoadDFromOffset(result_odd, value, | 2988 __ LoadDFromOffset(result_odd, value, |
2989 Uint32x4::value_offset() + 2*kWordSize - kHeapObjectTag); | 2989 Int32x4::value_offset() + 2*kWordSize - kHeapObjectTag); |
2990 } | 2990 } |
2991 | 2991 |
2992 | 2992 |
2993 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2993 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
2994 const intptr_t kNumInputs = 2; | 2994 const intptr_t kNumInputs = 2; |
2995 const intptr_t kNumTemps = 0; | 2995 const intptr_t kNumTemps = 0; |
2996 LocationSummary* summary = | 2996 LocationSummary* summary = |
2997 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2997 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2998 summary->set_in(0, Location::RequiresFpuRegister()); | 2998 summary->set_in(0, Location::RequiresFpuRegister()); |
2999 summary->set_in(1, Location::RequiresFpuRegister()); | 2999 summary->set_in(1, Location::RequiresFpuRegister()); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3084 __ vcvtds(dresult0, sresult0); | 3084 __ vcvtds(dresult0, sresult0); |
3085 break; | 3085 break; |
3086 case MethodRecognizer::kFloat32x4ShuffleZ: | 3086 case MethodRecognizer::kFloat32x4ShuffleZ: |
3087 __ vdup(kWord, result, dvalue1, 0); | 3087 __ vdup(kWord, result, dvalue1, 0); |
3088 __ vcvtds(dresult0, sresult0); | 3088 __ vcvtds(dresult0, sresult0); |
3089 break; | 3089 break; |
3090 case MethodRecognizer::kFloat32x4ShuffleW: | 3090 case MethodRecognizer::kFloat32x4ShuffleW: |
3091 __ vdup(kWord, result, dvalue1, 1); | 3091 __ vdup(kWord, result, dvalue1, 1); |
3092 __ vcvtds(dresult0, sresult0); | 3092 __ vcvtds(dresult0, sresult0); |
3093 break; | 3093 break; |
3094 case MethodRecognizer::kUint32x4Shuffle: | 3094 case MethodRecognizer::kInt32x4Shuffle: |
3095 case MethodRecognizer::kFloat32x4Shuffle: | 3095 case MethodRecognizer::kFloat32x4Shuffle: |
3096 if (mask_ == 0x00) { | 3096 if (mask_ == 0x00) { |
3097 __ vdup(kWord, result, dvalue0, 0); | 3097 __ vdup(kWord, result, dvalue0, 0); |
3098 } else if (mask_ == 0x55) { | 3098 } else if (mask_ == 0x55) { |
3099 __ vdup(kWord, result, dvalue0, 1); | 3099 __ vdup(kWord, result, dvalue0, 1); |
3100 } else if (mask_ == 0xAA) { | 3100 } else if (mask_ == 0xAA) { |
3101 __ vdup(kWord, result, dvalue1, 0); | 3101 __ vdup(kWord, result, dvalue1, 0); |
3102 } else if (mask_ == 0xFF) { | 3102 } else if (mask_ == 0xFF) { |
3103 __ vdup(kWord, result, dvalue1, 1); | 3103 __ vdup(kWord, result, dvalue1, 1); |
3104 } else { | 3104 } else { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3148 SRegister sresult2 = EvenSRegisterOf(dresult1); | 3148 SRegister sresult2 = EvenSRegisterOf(dresult1); |
3149 SRegister sresult3 = OddSRegisterOf(dresult1); | 3149 SRegister sresult3 = OddSRegisterOf(dresult1); |
3150 | 3150 |
3151 DRegister dleft0 = EvenDRegisterOf(left); | 3151 DRegister dleft0 = EvenDRegisterOf(left); |
3152 DRegister dleft1 = OddDRegisterOf(left); | 3152 DRegister dleft1 = OddDRegisterOf(left); |
3153 DRegister dright0 = EvenDRegisterOf(right); | 3153 DRegister dright0 = EvenDRegisterOf(right); |
3154 DRegister dright1 = OddDRegisterOf(right); | 3154 DRegister dright1 = OddDRegisterOf(right); |
3155 | 3155 |
3156 switch (op_kind()) { | 3156 switch (op_kind()) { |
3157 case MethodRecognizer::kFloat32x4ShuffleMix: | 3157 case MethodRecognizer::kFloat32x4ShuffleMix: |
3158 case MethodRecognizer::kUint32x4ShuffleMix: | 3158 case MethodRecognizer::kInt32x4ShuffleMix: |
3159 // TODO(zra): Investigate better instruction sequences for shuffle masks. | 3159 // TODO(zra): Investigate better instruction sequences for shuffle masks. |
3160 SRegister left_svalues[4]; | 3160 SRegister left_svalues[4]; |
3161 SRegister right_svalues[4]; | 3161 SRegister right_svalues[4]; |
3162 | 3162 |
3163 left_svalues[0] = EvenSRegisterOf(dleft0); | 3163 left_svalues[0] = EvenSRegisterOf(dleft0); |
3164 left_svalues[1] = OddSRegisterOf(dleft0); | 3164 left_svalues[1] = OddSRegisterOf(dleft0); |
3165 left_svalues[2] = EvenSRegisterOf(dleft1); | 3165 left_svalues[2] = EvenSRegisterOf(dleft1); |
3166 left_svalues[3] = OddSRegisterOf(dleft1); | 3166 left_svalues[3] = OddSRegisterOf(dleft1); |
3167 right_svalues[0] = EvenSRegisterOf(dright0); | 3167 right_svalues[0] = EvenSRegisterOf(dright0); |
3168 right_svalues[1] = OddSRegisterOf(dright0); | 3168 right_svalues[1] = OddSRegisterOf(dright0); |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3517 __ vmovs(sresult2, STMP); | 3517 __ vmovs(sresult2, STMP); |
3518 break; | 3518 break; |
3519 case MethodRecognizer::kFloat32x4WithW: | 3519 case MethodRecognizer::kFloat32x4WithW: |
3520 __ vmovs(sresult3, STMP); | 3520 __ vmovs(sresult3, STMP); |
3521 break; | 3521 break; |
3522 default: UNREACHABLE(); | 3522 default: UNREACHABLE(); |
3523 } | 3523 } |
3524 } | 3524 } |
3525 | 3525 |
3526 | 3526 |
3527 LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const { | 3527 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { |
3528 const intptr_t kNumInputs = 1; | 3528 const intptr_t kNumInputs = 1; |
3529 const intptr_t kNumTemps = 0; | 3529 const intptr_t kNumTemps = 0; |
3530 LocationSummary* summary = | 3530 LocationSummary* summary = |
3531 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3531 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3532 summary->set_in(0, Location::RequiresFpuRegister()); | 3532 summary->set_in(0, Location::RequiresFpuRegister()); |
3533 summary->set_out(Location::RequiresFpuRegister()); | 3533 summary->set_out(Location::RequiresFpuRegister()); |
3534 return summary; | 3534 return summary; |
3535 } | 3535 } |
3536 | 3536 |
3537 | 3537 |
3538 void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3538 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3539 QRegister value = locs()->in(0).fpu_reg(); | 3539 QRegister value = locs()->in(0).fpu_reg(); |
3540 QRegister result = locs()->out().fpu_reg(); | 3540 QRegister result = locs()->out().fpu_reg(); |
3541 | 3541 |
3542 if (value != result) { | 3542 if (value != result) { |
3543 __ vmovq(result, value); | 3543 __ vmovq(result, value); |
3544 } | 3544 } |
3545 } | 3545 } |
3546 | 3546 |
3547 | 3547 |
3548 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const { | 3548 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { |
3549 const intptr_t kNumInputs = 4; | 3549 const intptr_t kNumInputs = 4; |
3550 const intptr_t kNumTemps = 1; | 3550 const intptr_t kNumTemps = 1; |
3551 LocationSummary* summary = | 3551 LocationSummary* summary = |
3552 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3552 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3553 summary->set_in(0, Location::RequiresRegister()); | 3553 summary->set_in(0, Location::RequiresRegister()); |
3554 summary->set_in(1, Location::RequiresRegister()); | 3554 summary->set_in(1, Location::RequiresRegister()); |
3555 summary->set_in(2, Location::RequiresRegister()); | 3555 summary->set_in(2, Location::RequiresRegister()); |
3556 summary->set_in(3, Location::RequiresRegister()); | 3556 summary->set_in(3, Location::RequiresRegister()); |
3557 summary->set_temp(0, Location::RequiresRegister()); | 3557 summary->set_temp(0, Location::RequiresRegister()); |
3558 // Low (< 7) Q register needed for the vmovsr instruction. | 3558 // Low (< 7) Q register needed for the vmovsr instruction. |
3559 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3559 summary->set_out(Location::FpuRegisterLocation(Q6)); |
3560 return summary; | 3560 return summary; |
3561 } | 3561 } |
3562 | 3562 |
3563 | 3563 |
3564 void Uint32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3564 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3565 Register v0 = locs()->in(0).reg(); | 3565 Register v0 = locs()->in(0).reg(); |
3566 Register v1 = locs()->in(1).reg(); | 3566 Register v1 = locs()->in(1).reg(); |
3567 Register v2 = locs()->in(2).reg(); | 3567 Register v2 = locs()->in(2).reg(); |
3568 Register v3 = locs()->in(3).reg(); | 3568 Register v3 = locs()->in(3).reg(); |
3569 Register temp = locs()->temp(0).reg(); | 3569 Register temp = locs()->temp(0).reg(); |
3570 QRegister result = locs()->out().fpu_reg(); | 3570 QRegister result = locs()->out().fpu_reg(); |
3571 DRegister dresult0 = EvenDRegisterOf(result); | 3571 DRegister dresult0 = EvenDRegisterOf(result); |
3572 DRegister dresult1 = OddDRegisterOf(result); | 3572 DRegister dresult1 = OddDRegisterOf(result); |
3573 SRegister sresult0 = EvenSRegisterOf(dresult0); | 3573 SRegister sresult0 = EvenSRegisterOf(dresult0); |
3574 SRegister sresult1 = OddSRegisterOf(dresult0); | 3574 SRegister sresult1 = OddSRegisterOf(dresult0); |
(...skipping 10 matching lines...) Expand all Loading... |
3585 __ vmovsr(sresult1, temp, EQ); | 3585 __ vmovsr(sresult1, temp, EQ); |
3586 | 3586 |
3587 __ CompareObject(v2, Bool::True()); | 3587 __ CompareObject(v2, Bool::True()); |
3588 __ vmovsr(sresult2, temp, EQ); | 3588 __ vmovsr(sresult2, temp, EQ); |
3589 | 3589 |
3590 __ CompareObject(v3, Bool::True()); | 3590 __ CompareObject(v3, Bool::True()); |
3591 __ vmovsr(sresult3, temp, EQ); | 3591 __ vmovsr(sresult3, temp, EQ); |
3592 } | 3592 } |
3593 | 3593 |
3594 | 3594 |
3595 LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const { | 3595 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { |
3596 const intptr_t kNumInputs = 1; | 3596 const intptr_t kNumInputs = 1; |
3597 const intptr_t kNumTemps = 0; | 3597 const intptr_t kNumTemps = 0; |
3598 LocationSummary* summary = | 3598 LocationSummary* summary = |
3599 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3599 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3600 // Low (< 7) Q registers are needed for the vmovrs instruction. | 3600 // Low (< 7) Q registers are needed for the vmovrs instruction. |
3601 summary->set_in(0, Location::FpuRegisterLocation(Q6)); | 3601 summary->set_in(0, Location::FpuRegisterLocation(Q6)); |
3602 summary->set_out(Location::RequiresRegister()); | 3602 summary->set_out(Location::RequiresRegister()); |
3603 return summary; | 3603 return summary; |
3604 } | 3604 } |
3605 | 3605 |
3606 | 3606 |
3607 void Uint32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3607 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3608 QRegister value = locs()->in(0).fpu_reg(); | 3608 QRegister value = locs()->in(0).fpu_reg(); |
3609 Register result = locs()->out().reg(); | 3609 Register result = locs()->out().reg(); |
3610 | 3610 |
3611 DRegister dvalue0 = EvenDRegisterOf(value); | 3611 DRegister dvalue0 = EvenDRegisterOf(value); |
3612 DRegister dvalue1 = OddDRegisterOf(value); | 3612 DRegister dvalue1 = OddDRegisterOf(value); |
3613 SRegister svalue0 = EvenSRegisterOf(dvalue0); | 3613 SRegister svalue0 = EvenSRegisterOf(dvalue0); |
3614 SRegister svalue1 = OddSRegisterOf(dvalue0); | 3614 SRegister svalue1 = OddSRegisterOf(dvalue0); |
3615 SRegister svalue2 = EvenSRegisterOf(dvalue1); | 3615 SRegister svalue2 = EvenSRegisterOf(dvalue1); |
3616 SRegister svalue3 = OddSRegisterOf(dvalue1); | 3616 SRegister svalue3 = OddSRegisterOf(dvalue1); |
3617 | 3617 |
3618 switch (op_kind()) { | 3618 switch (op_kind()) { |
3619 case MethodRecognizer::kUint32x4GetFlagX: | 3619 case MethodRecognizer::kInt32x4GetFlagX: |
3620 __ vmovrs(result, svalue0); | 3620 __ vmovrs(result, svalue0); |
3621 break; | 3621 break; |
3622 case MethodRecognizer::kUint32x4GetFlagY: | 3622 case MethodRecognizer::kInt32x4GetFlagY: |
3623 __ vmovrs(result, svalue1); | 3623 __ vmovrs(result, svalue1); |
3624 break; | 3624 break; |
3625 case MethodRecognizer::kUint32x4GetFlagZ: | 3625 case MethodRecognizer::kInt32x4GetFlagZ: |
3626 __ vmovrs(result, svalue2); | 3626 __ vmovrs(result, svalue2); |
3627 break; | 3627 break; |
3628 case MethodRecognizer::kUint32x4GetFlagW: | 3628 case MethodRecognizer::kInt32x4GetFlagW: |
3629 __ vmovrs(result, svalue3); | 3629 __ vmovrs(result, svalue3); |
3630 break; | 3630 break; |
3631 default: UNREACHABLE(); | 3631 default: UNREACHABLE(); |
3632 } | 3632 } |
3633 | 3633 |
3634 __ tst(result, ShifterOperand(result)); | 3634 __ tst(result, ShifterOperand(result)); |
3635 __ LoadObject(result, Bool::True(), NE); | 3635 __ LoadObject(result, Bool::True(), NE); |
3636 __ LoadObject(result, Bool::False(), EQ); | 3636 __ LoadObject(result, Bool::False(), EQ); |
3637 } | 3637 } |
3638 | 3638 |
3639 | 3639 |
3640 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const { | 3640 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { |
3641 const intptr_t kNumInputs = 3; | 3641 const intptr_t kNumInputs = 3; |
3642 const intptr_t kNumTemps = 1; | 3642 const intptr_t kNumTemps = 1; |
3643 LocationSummary* summary = | 3643 LocationSummary* summary = |
3644 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3644 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3645 summary->set_in(0, Location::RequiresFpuRegister()); | 3645 summary->set_in(0, Location::RequiresFpuRegister()); |
3646 summary->set_in(1, Location::RequiresFpuRegister()); | 3646 summary->set_in(1, Location::RequiresFpuRegister()); |
3647 summary->set_in(2, Location::RequiresFpuRegister()); | 3647 summary->set_in(2, Location::RequiresFpuRegister()); |
3648 summary->set_temp(0, Location::RequiresFpuRegister()); | 3648 summary->set_temp(0, Location::RequiresFpuRegister()); |
3649 summary->set_out(Location::RequiresFpuRegister()); | 3649 summary->set_out(Location::RequiresFpuRegister()); |
3650 return summary; | 3650 return summary; |
3651 } | 3651 } |
3652 | 3652 |
3653 | 3653 |
3654 void Uint32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3654 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3655 QRegister mask = locs()->in(0).fpu_reg(); | 3655 QRegister mask = locs()->in(0).fpu_reg(); |
3656 QRegister trueValue = locs()->in(1).fpu_reg(); | 3656 QRegister trueValue = locs()->in(1).fpu_reg(); |
3657 QRegister falseValue = locs()->in(2).fpu_reg(); | 3657 QRegister falseValue = locs()->in(2).fpu_reg(); |
3658 QRegister out = locs()->out().fpu_reg(); | 3658 QRegister out = locs()->out().fpu_reg(); |
3659 QRegister temp = locs()->temp(0).fpu_reg(); | 3659 QRegister temp = locs()->temp(0).fpu_reg(); |
3660 | 3660 |
3661 // Copy mask. | 3661 // Copy mask. |
3662 __ vmovq(temp, mask); | 3662 __ vmovq(temp, mask); |
3663 // Invert it. | 3663 // Invert it. |
3664 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. | 3664 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. |
3665 __ vornq(temp, QTMP, temp); // temp <- ~temp. | 3665 __ vornq(temp, QTMP, temp); // temp <- ~temp. |
3666 // mask = mask & trueValue. | 3666 // mask = mask & trueValue. |
3667 __ vandq(mask, mask, trueValue); | 3667 __ vandq(mask, mask, trueValue); |
3668 // temp = temp & falseValue. | 3668 // temp = temp & falseValue. |
3669 __ vandq(temp, temp, falseValue); | 3669 __ vandq(temp, temp, falseValue); |
3670 // out = mask | temp. | 3670 // out = mask | temp. |
3671 __ vorrq(out, mask, temp); | 3671 __ vorrq(out, mask, temp); |
3672 } | 3672 } |
3673 | 3673 |
3674 | 3674 |
3675 LocationSummary* Uint32x4SetFlagInstr::MakeLocationSummary() const { | 3675 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { |
3676 const intptr_t kNumInputs = 2; | 3676 const intptr_t kNumInputs = 2; |
3677 const intptr_t kNumTemps = 0; | 3677 const intptr_t kNumTemps = 0; |
3678 LocationSummary* summary = | 3678 LocationSummary* summary = |
3679 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3679 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3680 summary->set_in(0, Location::RequiresFpuRegister()); | 3680 summary->set_in(0, Location::RequiresFpuRegister()); |
3681 summary->set_in(1, Location::RequiresRegister()); | 3681 summary->set_in(1, Location::RequiresRegister()); |
3682 // Low (< 7) Q register needed for the vmovsr instruction. | 3682 // Low (< 7) Q register needed for the vmovsr instruction. |
3683 summary->set_out(Location::FpuRegisterLocation(Q6)); | 3683 summary->set_out(Location::FpuRegisterLocation(Q6)); |
3684 return summary; | 3684 return summary; |
3685 } | 3685 } |
3686 | 3686 |
3687 | 3687 |
3688 void Uint32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3688 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3689 QRegister mask = locs()->in(0).fpu_reg(); | 3689 QRegister mask = locs()->in(0).fpu_reg(); |
3690 Register flag = locs()->in(1).reg(); | 3690 Register flag = locs()->in(1).reg(); |
3691 QRegister result = locs()->out().fpu_reg(); | 3691 QRegister result = locs()->out().fpu_reg(); |
3692 | 3692 |
3693 DRegister dresult0 = EvenDRegisterOf(result); | 3693 DRegister dresult0 = EvenDRegisterOf(result); |
3694 DRegister dresult1 = OddDRegisterOf(result); | 3694 DRegister dresult1 = OddDRegisterOf(result); |
3695 SRegister sresult0 = EvenSRegisterOf(dresult0); | 3695 SRegister sresult0 = EvenSRegisterOf(dresult0); |
3696 SRegister sresult1 = OddSRegisterOf(dresult0); | 3696 SRegister sresult1 = OddSRegisterOf(dresult0); |
3697 SRegister sresult2 = EvenSRegisterOf(dresult1); | 3697 SRegister sresult2 = EvenSRegisterOf(dresult1); |
3698 SRegister sresult3 = OddSRegisterOf(dresult1); | 3698 SRegister sresult3 = OddSRegisterOf(dresult1); |
3699 | 3699 |
3700 if (result != mask) { | 3700 if (result != mask) { |
3701 __ vmovq(result, mask); | 3701 __ vmovq(result, mask); |
3702 } | 3702 } |
3703 | 3703 |
3704 __ CompareObject(flag, Bool::True()); | 3704 __ CompareObject(flag, Bool::True()); |
3705 __ LoadImmediate(TMP, 0xffffffff, EQ); | 3705 __ LoadImmediate(TMP, 0xffffffff, EQ); |
3706 __ LoadImmediate(TMP, 0, NE); | 3706 __ LoadImmediate(TMP, 0, NE); |
3707 switch (op_kind()) { | 3707 switch (op_kind()) { |
3708 case MethodRecognizer::kUint32x4WithFlagX: | 3708 case MethodRecognizer::kInt32x4WithFlagX: |
3709 __ vmovsr(sresult0, TMP); | 3709 __ vmovsr(sresult0, TMP); |
3710 break; | 3710 break; |
3711 case MethodRecognizer::kUint32x4WithFlagY: | 3711 case MethodRecognizer::kInt32x4WithFlagY: |
3712 __ vmovsr(sresult1, TMP); | 3712 __ vmovsr(sresult1, TMP); |
3713 break; | 3713 break; |
3714 case MethodRecognizer::kUint32x4WithFlagZ: | 3714 case MethodRecognizer::kInt32x4WithFlagZ: |
3715 __ vmovsr(sresult2, TMP); | 3715 __ vmovsr(sresult2, TMP); |
3716 break; | 3716 break; |
3717 case MethodRecognizer::kUint32x4WithFlagW: | 3717 case MethodRecognizer::kInt32x4WithFlagW: |
3718 __ vmovsr(sresult3, TMP); | 3718 __ vmovsr(sresult3, TMP); |
3719 break; | 3719 break; |
3720 default: UNREACHABLE(); | 3720 default: UNREACHABLE(); |
3721 } | 3721 } |
3722 } | 3722 } |
3723 | 3723 |
3724 | 3724 |
3725 LocationSummary* Uint32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3725 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { |
3726 const intptr_t kNumInputs = 1; | 3726 const intptr_t kNumInputs = 1; |
3727 const intptr_t kNumTemps = 0; | 3727 const intptr_t kNumTemps = 0; |
3728 LocationSummary* summary = | 3728 LocationSummary* summary = |
3729 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3729 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3730 summary->set_in(0, Location::RequiresFpuRegister()); | 3730 summary->set_in(0, Location::RequiresFpuRegister()); |
3731 summary->set_out(Location::RequiresFpuRegister()); | 3731 summary->set_out(Location::RequiresFpuRegister()); |
3732 return summary; | 3732 return summary; |
3733 } | 3733 } |
3734 | 3734 |
3735 | 3735 |
3736 void Uint32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3736 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3737 QRegister value = locs()->in(0).fpu_reg(); | 3737 QRegister value = locs()->in(0).fpu_reg(); |
3738 QRegister result = locs()->out().fpu_reg(); | 3738 QRegister result = locs()->out().fpu_reg(); |
3739 | 3739 |
3740 if (value != result) { | 3740 if (value != result) { |
3741 __ vmovq(result, value); | 3741 __ vmovq(result, value); |
3742 } | 3742 } |
3743 } | 3743 } |
3744 | 3744 |
3745 | 3745 |
3746 LocationSummary* BinaryUint32x4OpInstr::MakeLocationSummary() const { | 3746 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { |
3747 const intptr_t kNumInputs = 2; | 3747 const intptr_t kNumInputs = 2; |
3748 const intptr_t kNumTemps = 0; | 3748 const intptr_t kNumTemps = 0; |
3749 LocationSummary* summary = | 3749 LocationSummary* summary = |
3750 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3750 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3751 summary->set_in(0, Location::RequiresFpuRegister()); | 3751 summary->set_in(0, Location::RequiresFpuRegister()); |
3752 summary->set_in(1, Location::RequiresFpuRegister()); | 3752 summary->set_in(1, Location::RequiresFpuRegister()); |
3753 summary->set_out(Location::RequiresFpuRegister()); | 3753 summary->set_out(Location::RequiresFpuRegister()); |
3754 return summary; | 3754 return summary; |
3755 } | 3755 } |
3756 | 3756 |
3757 | 3757 |
3758 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3758 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3759 QRegister left = locs()->in(0).fpu_reg(); | 3759 QRegister left = locs()->in(0).fpu_reg(); |
3760 QRegister right = locs()->in(1).fpu_reg(); | 3760 QRegister right = locs()->in(1).fpu_reg(); |
3761 QRegister result = locs()->out().fpu_reg(); | 3761 QRegister result = locs()->out().fpu_reg(); |
3762 switch (op_kind()) { | 3762 switch (op_kind()) { |
3763 case Token::kBIT_AND: { | 3763 case Token::kBIT_AND: { |
3764 __ vandq(result, left, right); | 3764 __ vandq(result, left, right); |
3765 break; | 3765 break; |
3766 } | 3766 } |
3767 case Token::kBIT_OR: { | 3767 case Token::kBIT_OR: { |
3768 __ vorrq(result, left, right); | 3768 __ vorrq(result, left, right); |
(...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4707 compiler->GenerateCall(token_pos(), | 4707 compiler->GenerateCall(token_pos(), |
4708 &label, | 4708 &label, |
4709 PcDescriptors::kOther, | 4709 PcDescriptors::kOther, |
4710 locs()); | 4710 locs()); |
4711 __ Drop(2); // Discard type arguments and receiver. | 4711 __ Drop(2); // Discard type arguments and receiver. |
4712 } | 4712 } |
4713 | 4713 |
4714 } // namespace dart | 4714 } // namespace dart |
4715 | 4715 |
4716 #endif // defined TARGET_ARCH_ARM | 4716 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |