Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: dart/runtime/vm/intermediate_language_arm.cc

Issue 59073003: Version 0.8.10.4 (Closed) Base URL: http://dart.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « dart/runtime/vm/intermediate_language.cc ('k') | dart/runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « dart/runtime/vm/intermediate_language.cc ('k') | dart/runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698