| 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 |