| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 case kImmutableArrayCid: | 961 case kImmutableArrayCid: |
| 962 case kTypedDataInt8ArrayCid: | 962 case kTypedDataInt8ArrayCid: |
| 963 case kTypedDataUint8ArrayCid: | 963 case kTypedDataUint8ArrayCid: |
| 964 case kTypedDataUint8ClampedArrayCid: | 964 case kTypedDataUint8ClampedArrayCid: |
| 965 case kExternalTypedDataUint8ArrayCid: | 965 case kExternalTypedDataUint8ArrayCid: |
| 966 case kExternalTypedDataUint8ClampedArrayCid: | 966 case kExternalTypedDataUint8ClampedArrayCid: |
| 967 case kTypedDataInt16ArrayCid: | 967 case kTypedDataInt16ArrayCid: |
| 968 case kTypedDataUint16ArrayCid: | 968 case kTypedDataUint16ArrayCid: |
| 969 case kOneByteStringCid: | 969 case kOneByteStringCid: |
| 970 case kTwoByteStringCid: | 970 case kTwoByteStringCid: |
| 971 return kTagged; |
| 971 case kTypedDataInt32ArrayCid: | 972 case kTypedDataInt32ArrayCid: |
| 973 return kUnboxedInt32; |
| 972 case kTypedDataUint32ArrayCid: | 974 case kTypedDataUint32ArrayCid: |
| 973 return kTagged; | 975 return kUnboxedUint32; |
| 974 case kTypedDataFloat32ArrayCid: | 976 case kTypedDataFloat32ArrayCid: |
| 975 case kTypedDataFloat64ArrayCid: | 977 case kTypedDataFloat64ArrayCid: |
| 976 return kUnboxedDouble; | 978 return kUnboxedDouble; |
| 977 case kTypedDataInt32x4ArrayCid: | 979 case kTypedDataInt32x4ArrayCid: |
| 978 return kUnboxedInt32x4; | 980 return kUnboxedInt32x4; |
| 979 case kTypedDataFloat32x4ArrayCid: | 981 case kTypedDataFloat32x4ArrayCid: |
| 980 return kUnboxedFloat32x4; | 982 return kUnboxedFloat32x4; |
| 981 case kTypedDataFloat64x2ArrayCid: | 983 case kTypedDataFloat64x2ArrayCid: |
| 982 return kUnboxedFloat64x2; | 984 return kUnboxedFloat64x2; |
| 983 default: | 985 default: |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 __ movsd(result, element_address); | 1047 __ movsd(result, element_address); |
| 1046 } else { | 1048 } else { |
| 1047 ASSERT((class_id() == kTypedDataInt32x4ArrayCid) || | 1049 ASSERT((class_id() == kTypedDataInt32x4ArrayCid) || |
| 1048 (class_id() == kTypedDataFloat32x4ArrayCid) || | 1050 (class_id() == kTypedDataFloat32x4ArrayCid) || |
| 1049 (class_id() == kTypedDataFloat64x2ArrayCid)); | 1051 (class_id() == kTypedDataFloat64x2ArrayCid)); |
| 1050 __ movups(result, element_address); | 1052 __ movups(result, element_address); |
| 1051 } | 1053 } |
| 1052 return; | 1054 return; |
| 1053 } | 1055 } |
| 1054 | 1056 |
| 1057 if ((representation() == kUnboxedUint32) || |
| 1058 (representation() == kUnboxedInt32)) { |
| 1059 if ((index_scale() == 1) && index.IsRegister()) { |
| 1060 __ SmiUntag(index.reg()); |
| 1061 } |
| 1062 Register result = locs()->out(0).reg(); |
| 1063 switch (class_id()) { |
| 1064 case kTypedDataInt32ArrayCid: |
| 1065 ASSERT(representation() == kUnboxedInt32); |
| 1066 __ movsxd(result, element_address); |
| 1067 break; |
| 1068 case kTypedDataUint32ArrayCid: |
| 1069 ASSERT(representation() == kUnboxedUint32); |
| 1070 __ movl(result, element_address); |
| 1071 break; |
| 1072 default: |
| 1073 UNREACHABLE(); |
| 1074 } |
| 1075 return; |
| 1076 } |
| 1077 |
| 1078 ASSERT(representation() == kTagged); |
| 1079 |
| 1055 if ((index_scale() == 1) && index.IsRegister()) { | 1080 if ((index_scale() == 1) && index.IsRegister()) { |
| 1056 __ SmiUntag(index.reg()); | 1081 __ SmiUntag(index.reg()); |
| 1057 } | 1082 } |
| 1058 Register result = locs()->out(0).reg(); | 1083 Register result = locs()->out(0).reg(); |
| 1059 switch (class_id()) { | 1084 switch (class_id()) { |
| 1060 case kTypedDataInt8ArrayCid: | 1085 case kTypedDataInt8ArrayCid: |
| 1061 __ movsxb(result, element_address); | 1086 __ movsxb(result, element_address); |
| 1062 __ SmiTag(result); | 1087 __ SmiTag(result); |
| 1063 break; | 1088 break; |
| 1064 case kTypedDataUint8ArrayCid: | 1089 case kTypedDataUint8ArrayCid: |
| 1065 case kTypedDataUint8ClampedArrayCid: | 1090 case kTypedDataUint8ClampedArrayCid: |
| 1066 case kExternalTypedDataUint8ArrayCid: | 1091 case kExternalTypedDataUint8ArrayCid: |
| 1067 case kExternalTypedDataUint8ClampedArrayCid: | 1092 case kExternalTypedDataUint8ClampedArrayCid: |
| 1068 case kOneByteStringCid: | 1093 case kOneByteStringCid: |
| 1069 __ movzxb(result, element_address); | 1094 __ movzxb(result, element_address); |
| 1070 __ SmiTag(result); | 1095 __ SmiTag(result); |
| 1071 break; | 1096 break; |
| 1072 case kTypedDataInt16ArrayCid: | 1097 case kTypedDataInt16ArrayCid: |
| 1073 __ movsxw(result, element_address); | 1098 __ movsxw(result, element_address); |
| 1074 __ SmiTag(result); | 1099 __ SmiTag(result); |
| 1075 break; | 1100 break; |
| 1076 case kTypedDataUint16ArrayCid: | 1101 case kTypedDataUint16ArrayCid: |
| 1077 case kTwoByteStringCid: | 1102 case kTwoByteStringCid: |
| 1078 __ movzxw(result, element_address); | 1103 __ movzxw(result, element_address); |
| 1079 __ SmiTag(result); | 1104 __ SmiTag(result); |
| 1080 break; | 1105 break; |
| 1081 case kTypedDataInt32ArrayCid: | |
| 1082 __ movsxd(result, element_address); | |
| 1083 __ SmiTag(result); | |
| 1084 break; | |
| 1085 case kTypedDataUint32ArrayCid: | |
| 1086 __ movl(result, element_address); | |
| 1087 __ SmiTag(result); | |
| 1088 break; | |
| 1089 default: | 1106 default: |
| 1090 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1107 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1091 __ movq(result, element_address); | 1108 __ movq(result, element_address); |
| 1092 break; | 1109 break; |
| 1093 } | 1110 } |
| 1094 } | 1111 } |
| 1095 | 1112 |
| 1096 | 1113 |
| 1097 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1114 Representation StoreIndexedInstr::RequiredInputRepresentation( |
| 1098 intptr_t idx) const { | 1115 intptr_t idx) const { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1265 case kTypedDataUint16ArrayCid: { | 1282 case kTypedDataUint16ArrayCid: { |
| 1266 Register value = locs()->in(2).reg(); | 1283 Register value = locs()->in(2).reg(); |
| 1267 __ SmiUntag(value); | 1284 __ SmiUntag(value); |
| 1268 __ movw(element_address, value); | 1285 __ movw(element_address, value); |
| 1269 break; | 1286 break; |
| 1270 } | 1287 } |
| 1271 case kTypedDataInt32ArrayCid: | 1288 case kTypedDataInt32ArrayCid: |
| 1272 case kTypedDataUint32ArrayCid: { | 1289 case kTypedDataUint32ArrayCid: { |
| 1273 Register value = locs()->in(2).reg(); | 1290 Register value = locs()->in(2).reg(); |
| 1274 __ movl(element_address, value); | 1291 __ movl(element_address, value); |
| 1275 break; | 1292 break; |
| 1276 } | 1293 } |
| 1277 case kTypedDataFloat32ArrayCid: | 1294 case kTypedDataFloat32ArrayCid: |
| 1278 __ movss(element_address, locs()->in(2).fpu_reg()); | 1295 __ movss(element_address, locs()->in(2).fpu_reg()); |
| 1279 break; | 1296 break; |
| 1280 case kTypedDataFloat64ArrayCid: | 1297 case kTypedDataFloat64ArrayCid: |
| 1281 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1298 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1282 break; | 1299 break; |
| 1283 case kTypedDataInt32x4ArrayCid: | 1300 case kTypedDataInt32x4ArrayCid: |
| 1284 case kTypedDataFloat64x2ArrayCid: | 1301 case kTypedDataFloat64x2ArrayCid: |
| 1285 case kTypedDataFloat32x4ArrayCid: | 1302 case kTypedDataFloat32x4ArrayCid: |
| (...skipping 1895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3181 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3198 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3182 CompileType* value_type = value()->Type(); | 3199 CompileType* value_type = value()->Type(); |
| 3183 const intptr_t value_cid = value_type->ToCid(); | 3200 const intptr_t value_cid = value_type->ToCid(); |
| 3184 const Register value = locs()->in(0).reg(); | 3201 const Register value = locs()->in(0).reg(); |
| 3185 const XmmRegister result = locs()->out(0).fpu_reg(); | 3202 const XmmRegister result = locs()->out(0).fpu_reg(); |
| 3186 | 3203 |
| 3187 if (value_cid == kDoubleCid) { | 3204 if (value_cid == kDoubleCid) { |
| 3188 __ movsd(result, FieldAddress(value, Double::value_offset())); | 3205 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 3189 } else if (value_cid == kSmiCid) { | 3206 } else if (value_cid == kSmiCid) { |
| 3190 __ SmiUntag(value); // Untag input before conversion. | 3207 __ SmiUntag(value); // Untag input before conversion. |
| 3191 __ cvtsi2sd(result, value); | 3208 __ cvtsi2sdq(result, value); |
| 3192 } else { | 3209 } else { |
| 3193 Label* deopt = compiler->AddDeoptStub(deopt_id_, | 3210 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
| 3194 ICData::kDeoptBinaryDoubleOp); | 3211 ICData::kDeoptBinaryDoubleOp); |
| 3195 if (value_type->is_nullable() && | 3212 if (value_type->is_nullable() && |
| 3196 (value_type->ToNullableCid() == kDoubleCid)) { | 3213 (value_type->ToNullableCid() == kDoubleCid)) { |
| 3197 const Immediate& raw_null = | 3214 const Immediate& raw_null = |
| 3198 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 3215 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 3199 __ cmpq(value, raw_null); | 3216 __ cmpq(value, raw_null); |
| 3200 __ j(EQUAL, deopt); | 3217 __ j(EQUAL, deopt); |
| 3201 // It must be double now. | 3218 // It must be double now. |
| 3202 __ movsd(result, FieldAddress(value, Double::value_offset())); | 3219 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 3203 } else { | 3220 } else { |
| 3204 Label is_smi, done; | 3221 Label is_smi, done; |
| 3205 __ testq(value, Immediate(kSmiTagMask)); | 3222 __ testq(value, Immediate(kSmiTagMask)); |
| 3206 __ j(ZERO, &is_smi); | 3223 __ j(ZERO, &is_smi); |
| 3207 __ CompareClassId(value, kDoubleCid); | 3224 __ CompareClassId(value, kDoubleCid); |
| 3208 __ j(NOT_EQUAL, deopt); | 3225 __ j(NOT_EQUAL, deopt); |
| 3209 __ movsd(result, FieldAddress(value, Double::value_offset())); | 3226 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 3210 __ jmp(&done); | 3227 __ jmp(&done); |
| 3211 __ Bind(&is_smi); | 3228 __ Bind(&is_smi); |
| 3212 __ SmiUntag(value); | 3229 __ SmiUntag(value); |
| 3213 __ cvtsi2sd(result, value); | 3230 __ cvtsi2sdq(result, value); |
| 3214 __ Bind(&done); | 3231 __ Bind(&done); |
| 3215 } | 3232 } |
| 3216 } | 3233 } |
| 3217 } | 3234 } |
| 3218 | 3235 |
| 3219 | 3236 |
| 3220 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 3237 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, |
| 3221 bool opt) const { | 3238 bool opt) const { |
| 3222 const intptr_t kNumInputs = 1; | 3239 const intptr_t kNumInputs = 1; |
| 3223 const intptr_t kNumTemps = 0; | 3240 const intptr_t kNumTemps = 0; |
| (...skipping 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4622 __ cmpq(left, right); | 4639 __ cmpq(left, right); |
| 4623 ASSERT(result == left); | 4640 ASSERT(result == left); |
| 4624 if (is_min) { | 4641 if (is_min) { |
| 4625 __ cmovgeq(result, right); | 4642 __ cmovgeq(result, right); |
| 4626 } else { | 4643 } else { |
| 4627 __ cmovlessq(result, right); | 4644 __ cmovlessq(result, right); |
| 4628 } | 4645 } |
| 4629 } | 4646 } |
| 4630 | 4647 |
| 4631 | 4648 |
| 4632 DEFINE_UNIMPLEMENTED_INSTRUCTION(Int32ToDoubleInstr) | 4649 LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Isolate* isolate, |
| 4650 bool opt) const { |
| 4651 const intptr_t kNumInputs = 1; |
| 4652 const intptr_t kNumTemps = 0; |
| 4653 LocationSummary* result = new(isolate) LocationSummary( |
| 4654 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4655 result->set_in(0, Location::RequiresRegister()); |
| 4656 result->set_out(0, Location::RequiresFpuRegister()); |
| 4657 return result; |
| 4658 } |
| 4659 |
| 4660 |
| 4661 void Int32ToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4662 Register value = locs()->in(0).reg(); |
| 4663 FpuRegister result = locs()->out(0).fpu_reg(); |
| 4664 __ cvtsi2sdl(result, value); |
| 4665 } |
| 4633 | 4666 |
| 4634 | 4667 |
| 4635 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate, | 4668 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate, |
| 4636 bool opt) const { | 4669 bool opt) const { |
| 4637 const intptr_t kNumInputs = 1; | 4670 const intptr_t kNumInputs = 1; |
| 4638 const intptr_t kNumTemps = 0; | 4671 const intptr_t kNumTemps = 0; |
| 4639 LocationSummary* result = new(isolate) LocationSummary( | 4672 LocationSummary* result = new(isolate) LocationSummary( |
| 4640 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4673 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4641 result->set_in(0, Location::WritableRegister()); | 4674 result->set_in(0, Location::WritableRegister()); |
| 4642 result->set_out(0, Location::RequiresFpuRegister()); | 4675 result->set_out(0, Location::RequiresFpuRegister()); |
| 4643 return result; | 4676 return result; |
| 4644 } | 4677 } |
| 4645 | 4678 |
| 4646 | 4679 |
| 4647 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4680 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4648 Register value = locs()->in(0).reg(); | 4681 Register value = locs()->in(0).reg(); |
| 4649 FpuRegister result = locs()->out(0).fpu_reg(); | 4682 FpuRegister result = locs()->out(0).fpu_reg(); |
| 4650 __ SmiUntag(value); | 4683 __ SmiUntag(value); |
| 4651 __ cvtsi2sd(result, value); | 4684 __ cvtsi2sdq(result, value); |
| 4652 } | 4685 } |
| 4653 | 4686 |
| 4654 | 4687 |
| 4655 LocationSummary* MintToDoubleInstr::MakeLocationSummary(Isolate* isolate, | 4688 LocationSummary* MintToDoubleInstr::MakeLocationSummary(Isolate* isolate, |
| 4656 bool opt) const { | 4689 bool opt) const { |
| 4657 UNIMPLEMENTED(); | 4690 UNIMPLEMENTED(); |
| 4658 return NULL; | 4691 return NULL; |
| 4659 } | 4692 } |
| 4660 | 4693 |
| 4661 | 4694 |
| (...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5929 __ movq(R10, Immediate(kInvalidObjectPointer)); | 5962 __ movq(R10, Immediate(kInvalidObjectPointer)); |
| 5930 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 5963 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
| 5931 #endif | 5964 #endif |
| 5932 } | 5965 } |
| 5933 | 5966 |
| 5934 } // namespace dart | 5967 } // namespace dart |
| 5935 | 5968 |
| 5936 #undef __ | 5969 #undef __ |
| 5937 | 5970 |
| 5938 #endif // defined TARGET_ARCH_X64 | 5971 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |