| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 switch (class_id_) { | 759 switch (class_id_) { |
| 760 case kArrayCid: | 760 case kArrayCid: |
| 761 case kImmutableArrayCid: | 761 case kImmutableArrayCid: |
| 762 return CompileType::Dynamic(); | 762 return CompileType::Dynamic(); |
| 763 | 763 |
| 764 case kTypedDataFloat32ArrayCid: | 764 case kTypedDataFloat32ArrayCid: |
| 765 case kTypedDataFloat64ArrayCid: | 765 case kTypedDataFloat64ArrayCid: |
| 766 return CompileType::FromCid(kDoubleCid); | 766 return CompileType::FromCid(kDoubleCid); |
| 767 case kTypedDataFloat32x4ArrayCid: | 767 case kTypedDataFloat32x4ArrayCid: |
| 768 return CompileType::FromCid(kFloat32x4Cid); | 768 return CompileType::FromCid(kFloat32x4Cid); |
| 769 case kTypedDataUint32x4ArrayCid: | 769 case kTypedDataInt32x4ArrayCid: |
| 770 return CompileType::FromCid(kUint32x4Cid); | 770 return CompileType::FromCid(kInt32x4Cid); |
| 771 | 771 |
| 772 case kTypedDataInt8ArrayCid: | 772 case kTypedDataInt8ArrayCid: |
| 773 case kTypedDataUint8ArrayCid: | 773 case kTypedDataUint8ArrayCid: |
| 774 case kTypedDataUint8ClampedArrayCid: | 774 case kTypedDataUint8ClampedArrayCid: |
| 775 case kExternalTypedDataUint8ArrayCid: | 775 case kExternalTypedDataUint8ArrayCid: |
| 776 case kExternalTypedDataUint8ClampedArrayCid: | 776 case kExternalTypedDataUint8ClampedArrayCid: |
| 777 case kTypedDataInt16ArrayCid: | 777 case kTypedDataInt16ArrayCid: |
| 778 case kTypedDataUint16ArrayCid: | 778 case kTypedDataUint16ArrayCid: |
| 779 case kOneByteStringCid: | 779 case kOneByteStringCid: |
| 780 case kTwoByteStringCid: | 780 case kTwoByteStringCid: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 case kTypedDataInt32ArrayCid: | 812 case kTypedDataInt32ArrayCid: |
| 813 case kTypedDataUint32ArrayCid: | 813 case kTypedDataUint32ArrayCid: |
| 814 // Instruction can deoptimize if we optimistically assumed that the result | 814 // Instruction can deoptimize if we optimistically assumed that the result |
| 815 // fits into Smi. | 815 // fits into Smi. |
| 816 return CanDeoptimize() ? kTagged : kUnboxedMint; | 816 return CanDeoptimize() ? kTagged : kUnboxedMint; |
| 817 case kTypedDataFloat32ArrayCid: | 817 case kTypedDataFloat32ArrayCid: |
| 818 case kTypedDataFloat64ArrayCid: | 818 case kTypedDataFloat64ArrayCid: |
| 819 return kUnboxedDouble; | 819 return kUnboxedDouble; |
| 820 case kTypedDataFloat32x4ArrayCid: | 820 case kTypedDataFloat32x4ArrayCid: |
| 821 return kUnboxedFloat32x4; | 821 return kUnboxedFloat32x4; |
| 822 case kTypedDataUint32x4ArrayCid: | 822 case kTypedDataInt32x4ArrayCid: |
| 823 return kUnboxedUint32x4; | 823 return kUnboxedInt32x4; |
| 824 default: | 824 default: |
| 825 UNIMPLEMENTED(); | 825 UNIMPLEMENTED(); |
| 826 return kTagged; | 826 return kTagged; |
| 827 } | 827 } |
| 828 } | 828 } |
| 829 | 829 |
| 830 | 830 |
| 831 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 831 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 832 const intptr_t kNumInputs = 2; | 832 const intptr_t kNumInputs = 2; |
| 833 const intptr_t kNumTemps = 0; | 833 const intptr_t kNumTemps = 0; |
| 834 LocationSummary* locs = | 834 LocationSummary* locs = |
| 835 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 835 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 836 locs->set_in(0, Location::RequiresRegister()); | 836 locs->set_in(0, Location::RequiresRegister()); |
| 837 if (CanBeImmediateIndex(index(), class_id())) { | 837 if (CanBeImmediateIndex(index(), class_id())) { |
| 838 // CanBeImmediateIndex must return false for unsafe smis. | 838 // CanBeImmediateIndex must return false for unsafe smis. |
| 839 locs->set_in(1, Location::Constant(index()->BoundConstant())); | 839 locs->set_in(1, Location::Constant(index()->BoundConstant())); |
| 840 } else { | 840 } else { |
| 841 // The index is either untagged (element size == 1) or a smi (for all | 841 // The index is either untagged (element size == 1) or a smi (for all |
| 842 // element sizes > 1). | 842 // element sizes > 1). |
| 843 locs->set_in(1, (index_scale() == 1) | 843 locs->set_in(1, (index_scale() == 1) |
| 844 ? Location::WritableRegister() | 844 ? Location::WritableRegister() |
| 845 : Location::RequiresRegister()); | 845 : Location::RequiresRegister()); |
| 846 } | 846 } |
| 847 if ((representation() == kUnboxedDouble) || | 847 if ((representation() == kUnboxedDouble) || |
| 848 (representation() == kUnboxedFloat32x4) || | 848 (representation() == kUnboxedFloat32x4) || |
| 849 (representation() == kUnboxedUint32x4)) { | 849 (representation() == kUnboxedInt32x4)) { |
| 850 locs->set_out(Location::RequiresFpuRegister()); | 850 locs->set_out(Location::RequiresFpuRegister()); |
| 851 } else { | 851 } else { |
| 852 locs->set_out(Location::RequiresRegister()); | 852 locs->set_out(Location::RequiresRegister()); |
| 853 } | 853 } |
| 854 return locs; | 854 return locs; |
| 855 } | 855 } |
| 856 | 856 |
| 857 | 857 |
| 858 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 858 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 859 Register array = locs()->in(0).reg(); | 859 Register array = locs()->in(0).reg(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 872 ? FlowGraphCompiler::ElementAddressForRegIndex( | 872 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 873 class_id(), index_scale(), array, index.reg()) | 873 class_id(), index_scale(), array, index.reg()) |
| 874 : FlowGraphCompiler::ElementAddressForIntIndex( | 874 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 875 class_id(), index_scale(), array, | 875 class_id(), index_scale(), array, |
| 876 Smi::Cast(index.constant()).Value()); | 876 Smi::Cast(index.constant()).Value()); |
| 877 } | 877 } |
| 878 | 878 |
| 879 if ((representation() == kUnboxedDouble) || | 879 if ((representation() == kUnboxedDouble) || |
| 880 (representation() == kUnboxedMint) || | 880 (representation() == kUnboxedMint) || |
| 881 (representation() == kUnboxedFloat32x4) || | 881 (representation() == kUnboxedFloat32x4) || |
| 882 (representation() == kUnboxedUint32x4)) { | 882 (representation() == kUnboxedInt32x4)) { |
| 883 XmmRegister result = locs()->out().fpu_reg(); | 883 XmmRegister result = locs()->out().fpu_reg(); |
| 884 if ((index_scale() == 1) && index.IsRegister()) { | 884 if ((index_scale() == 1) && index.IsRegister()) { |
| 885 __ SmiUntag(index.reg()); | 885 __ SmiUntag(index.reg()); |
| 886 } | 886 } |
| 887 switch (class_id()) { | 887 switch (class_id()) { |
| 888 case kTypedDataInt32ArrayCid: | 888 case kTypedDataInt32ArrayCid: |
| 889 __ movss(result, element_address); | 889 __ movss(result, element_address); |
| 890 __ pmovsxdq(result, result); | 890 __ pmovsxdq(result, result); |
| 891 break; | 891 break; |
| 892 case kTypedDataUint32ArrayCid: | 892 case kTypedDataUint32ArrayCid: |
| 893 __ xorpd(result, result); | 893 __ xorpd(result, result); |
| 894 __ movss(result, element_address); | 894 __ movss(result, element_address); |
| 895 break; | 895 break; |
| 896 case kTypedDataFloat32ArrayCid: | 896 case kTypedDataFloat32ArrayCid: |
| 897 // Load single precision float and promote to double. | 897 // Load single precision float and promote to double. |
| 898 __ movss(result, element_address); | 898 __ movss(result, element_address); |
| 899 __ cvtss2sd(result, locs()->out().fpu_reg()); | 899 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 900 break; | 900 break; |
| 901 case kTypedDataFloat64ArrayCid: | 901 case kTypedDataFloat64ArrayCid: |
| 902 __ movsd(result, element_address); | 902 __ movsd(result, element_address); |
| 903 break; | 903 break; |
| 904 case kTypedDataUint32x4ArrayCid: | 904 case kTypedDataInt32x4ArrayCid: |
| 905 case kTypedDataFloat32x4ArrayCid: | 905 case kTypedDataFloat32x4ArrayCid: |
| 906 __ movups(result, element_address); | 906 __ movups(result, element_address); |
| 907 break; | 907 break; |
| 908 } | 908 } |
| 909 return; | 909 return; |
| 910 } | 910 } |
| 911 | 911 |
| 912 Register result = locs()->out().reg(); | 912 Register result = locs()->out().reg(); |
| 913 if ((index_scale() == 1) && index.IsRegister()) { | 913 if ((index_scale() == 1) && index.IsRegister()) { |
| 914 __ SmiUntag(index.reg()); | 914 __ SmiUntag(index.reg()); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 981 case kTypedDataUint16ArrayCid: | 981 case kTypedDataUint16ArrayCid: |
| 982 return kTagged; | 982 return kTagged; |
| 983 case kTypedDataInt32ArrayCid: | 983 case kTypedDataInt32ArrayCid: |
| 984 case kTypedDataUint32ArrayCid: | 984 case kTypedDataUint32ArrayCid: |
| 985 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 985 return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
| 986 case kTypedDataFloat32ArrayCid: | 986 case kTypedDataFloat32ArrayCid: |
| 987 case kTypedDataFloat64ArrayCid: | 987 case kTypedDataFloat64ArrayCid: |
| 988 return kUnboxedDouble; | 988 return kUnboxedDouble; |
| 989 case kTypedDataFloat32x4ArrayCid: | 989 case kTypedDataFloat32x4ArrayCid: |
| 990 return kUnboxedFloat32x4; | 990 return kUnboxedFloat32x4; |
| 991 case kTypedDataUint32x4ArrayCid: | 991 case kTypedDataInt32x4ArrayCid: |
| 992 return kUnboxedUint32x4; | 992 return kUnboxedInt32x4; |
| 993 default: | 993 default: |
| 994 UNIMPLEMENTED(); | 994 UNIMPLEMENTED(); |
| 995 return kTagged; | 995 return kTagged; |
| 996 } | 996 } |
| 997 } | 997 } |
| 998 | 998 |
| 999 | 999 |
| 1000 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1000 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1001 const intptr_t kNumInputs = 3; | 1001 const intptr_t kNumInputs = 3; |
| 1002 const intptr_t kNumTemps = 0; | 1002 const intptr_t kNumTemps = 0; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 : Location::RequiresFpuRegister()); | 1043 : Location::RequiresFpuRegister()); |
| 1044 break; | 1044 break; |
| 1045 case kTypedDataFloat32ArrayCid: | 1045 case kTypedDataFloat32ArrayCid: |
| 1046 // Need temp register for float-to-double conversion. | 1046 // Need temp register for float-to-double conversion. |
| 1047 locs->AddTemp(Location::RequiresFpuRegister()); | 1047 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1048 // Fall through. | 1048 // Fall through. |
| 1049 case kTypedDataFloat64ArrayCid: | 1049 case kTypedDataFloat64ArrayCid: |
| 1050 // TODO(srdjan): Support Float64 constants. | 1050 // TODO(srdjan): Support Float64 constants. |
| 1051 locs->set_in(2, Location::RequiresFpuRegister()); | 1051 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1052 break; | 1052 break; |
| 1053 case kTypedDataUint32x4ArrayCid: | 1053 case kTypedDataInt32x4ArrayCid: |
| 1054 case kTypedDataFloat32x4ArrayCid: | 1054 case kTypedDataFloat32x4ArrayCid: |
| 1055 locs->set_in(2, Location::RequiresFpuRegister()); | 1055 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1056 break; | 1056 break; |
| 1057 default: | 1057 default: |
| 1058 UNREACHABLE(); | 1058 UNREACHABLE(); |
| 1059 return NULL; | 1059 return NULL; |
| 1060 } | 1060 } |
| 1061 return locs; | 1061 return locs; |
| 1062 } | 1062 } |
| 1063 | 1063 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 break; | 1164 break; |
| 1165 case kTypedDataFloat32ArrayCid: | 1165 case kTypedDataFloat32ArrayCid: |
| 1166 // Convert to single precision. | 1166 // Convert to single precision. |
| 1167 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1167 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1168 // Store. | 1168 // Store. |
| 1169 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1169 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1170 break; | 1170 break; |
| 1171 case kTypedDataFloat64ArrayCid: | 1171 case kTypedDataFloat64ArrayCid: |
| 1172 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1172 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1173 break; | 1173 break; |
| 1174 case kTypedDataUint32x4ArrayCid: | 1174 case kTypedDataInt32x4ArrayCid: |
| 1175 case kTypedDataFloat32x4ArrayCid: | 1175 case kTypedDataFloat32x4ArrayCid: |
| 1176 __ movups(element_address, locs()->in(2).fpu_reg()); | 1176 __ movups(element_address, locs()->in(2).fpu_reg()); |
| 1177 break; | 1177 break; |
| 1178 default: | 1178 default: |
| 1179 UNREACHABLE(); | 1179 UNREACHABLE(); |
| 1180 } | 1180 } |
| 1181 } | 1181 } |
| 1182 | 1182 |
| 1183 | 1183 |
| 1184 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1184 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 // without triggering a deoptimization. | 1294 // without triggering a deoptimization. |
| 1295 Label check_array, length_compared, no_fixed_length; | 1295 Label check_array, length_compared, no_fixed_length; |
| 1296 // If length is negative the length guard is either disabled or | 1296 // If length is negative the length guard is either disabled or |
| 1297 // has not been initialized, either way it is safe to skip the | 1297 // has not been initialized, either way it is safe to skip the |
| 1298 // length check. | 1298 // length check. |
| 1299 __ cmpl(field_length_operand, Immediate(Smi::RawValue(0))); | 1299 __ cmpl(field_length_operand, Immediate(Smi::RawValue(0))); |
| 1300 __ j(LESS, &skip_length_check); | 1300 __ j(LESS, &skip_length_check); |
| 1301 __ cmpl(value_cid_reg, Immediate(kNullCid)); | 1301 __ cmpl(value_cid_reg, Immediate(kNullCid)); |
| 1302 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1302 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1303 // Check for typed data array. | 1303 // Check for typed data array. |
| 1304 __ cmpl(value_cid_reg, Immediate(kTypedDataUint32x4ArrayCid)); | 1304 __ cmpl(value_cid_reg, Immediate(kTypedDataInt32x4ArrayCid)); |
| 1305 // Not a typed array or a regular array. | 1305 // Not a typed array or a regular array. |
| 1306 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); | 1306 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); |
| 1307 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); | 1307 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); |
| 1308 // Could still be a regular array. | 1308 // Could still be a regular array. |
| 1309 __ j(LESS, &check_array, Assembler::kNearJump); | 1309 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1310 __ pushl(value_cid_reg); | 1310 __ pushl(value_cid_reg); |
| 1311 __ movl(value_cid_reg, | 1311 __ movl(value_cid_reg, |
| 1312 FieldAddress(value_reg, TypedData::length_offset())); | 1312 FieldAddress(value_reg, TypedData::length_offset())); |
| 1313 __ cmpl(field_length_operand, value_cid_reg); | 1313 __ cmpl(field_length_operand, value_cid_reg); |
| 1314 __ popl(value_cid_reg); | 1314 __ popl(value_cid_reg); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 // At this point the field guard is being initialized for the first time. | 1381 // At this point the field guard is being initialized for the first time. |
| 1382 if (value_cid == kDynamicCid) { | 1382 if (value_cid == kDynamicCid) { |
| 1383 // Do not know value's class id. | 1383 // Do not know value's class id. |
| 1384 __ movl(field_cid_operand, value_cid_reg); | 1384 __ movl(field_cid_operand, value_cid_reg); |
| 1385 __ movl(field_nullability_operand, value_cid_reg); | 1385 __ movl(field_nullability_operand, value_cid_reg); |
| 1386 if (field_has_length) { | 1386 if (field_has_length) { |
| 1387 Label check_array, length_set, no_fixed_length; | 1387 Label check_array, length_set, no_fixed_length; |
| 1388 __ cmpl(value_cid_reg, Immediate(kNullCid)); | 1388 __ cmpl(value_cid_reg, Immediate(kNullCid)); |
| 1389 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1389 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1390 // Check for typed data array. | 1390 // Check for typed data array. |
| 1391 __ cmpl(value_cid_reg, Immediate(kTypedDataUint32x4ArrayCid)); | 1391 __ cmpl(value_cid_reg, Immediate(kTypedDataInt32x4ArrayCid)); |
| 1392 // Not a typed array or a regular array. | 1392 // Not a typed array or a regular array. |
| 1393 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); | 1393 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); |
| 1394 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); | 1394 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); |
| 1395 // Could still be a regular array. | 1395 // Could still be a regular array. |
| 1396 __ j(LESS, &check_array, Assembler::kNearJump); | 1396 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1397 // Destroy value_cid_reg (safe because we are finished with it). | 1397 // Destroy value_cid_reg (safe because we are finished with it). |
| 1398 __ movl(value_cid_reg, | 1398 __ movl(value_cid_reg, |
| 1399 FieldAddress(value_reg, TypedData::length_offset())); | 1399 FieldAddress(value_reg, TypedData::length_offset())); |
| 1400 __ movl(field_length_operand, value_cid_reg); | 1400 __ movl(field_length_operand, value_cid_reg); |
| 1401 // Updated field length typed data array. | 1401 // Updated field length typed data array. |
| (...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2693 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 2693 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 2694 __ testl(value, Immediate(kSmiTagMask)); | 2694 __ testl(value, Immediate(kSmiTagMask)); |
| 2695 __ j(ZERO, deopt); | 2695 __ j(ZERO, deopt); |
| 2696 __ CompareClassId(value, kFloat32x4Cid, temp); | 2696 __ CompareClassId(value, kFloat32x4Cid, temp); |
| 2697 __ j(NOT_EQUAL, deopt); | 2697 __ j(NOT_EQUAL, deopt); |
| 2698 } | 2698 } |
| 2699 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | 2699 __ movups(result, FieldAddress(value, Float32x4::value_offset())); |
| 2700 } | 2700 } |
| 2701 | 2701 |
| 2702 | 2702 |
| 2703 LocationSummary* BoxUint32x4Instr::MakeLocationSummary() const { | 2703 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { |
| 2704 const intptr_t kNumInputs = 1; | 2704 const intptr_t kNumInputs = 1; |
| 2705 const intptr_t kNumTemps = 0; | 2705 const intptr_t kNumTemps = 0; |
| 2706 LocationSummary* summary = | 2706 LocationSummary* summary = |
| 2707 new LocationSummary(kNumInputs, | 2707 new LocationSummary(kNumInputs, |
| 2708 kNumTemps, | 2708 kNumTemps, |
| 2709 LocationSummary::kCallOnSlowPath); | 2709 LocationSummary::kCallOnSlowPath); |
| 2710 summary->set_in(0, Location::RequiresFpuRegister()); | 2710 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2711 summary->set_out(Location::RequiresRegister()); | 2711 summary->set_out(Location::RequiresRegister()); |
| 2712 return summary; | 2712 return summary; |
| 2713 } | 2713 } |
| 2714 | 2714 |
| 2715 | 2715 |
| 2716 class BoxUint32x4SlowPath : public SlowPathCode { | 2716 class BoxInt32x4SlowPath : public SlowPathCode { |
| 2717 public: | 2717 public: |
| 2718 explicit BoxUint32x4SlowPath(BoxUint32x4Instr* instruction) | 2718 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) |
| 2719 : instruction_(instruction) { } | 2719 : instruction_(instruction) { } |
| 2720 | 2720 |
| 2721 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2721 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2722 __ Comment("BoxUint32x4SlowPath"); | 2722 __ Comment("BoxInt32x4SlowPath"); |
| 2723 __ Bind(entry_label()); | 2723 __ Bind(entry_label()); |
| 2724 const Class& uint32x4_class = compiler->uint32x4_class(); | 2724 const Class& int32x4_class = compiler->int32x4_class(); |
| 2725 const Code& stub = | 2725 const Code& stub = |
| 2726 Code::Handle(StubCode::GetAllocationStubForClass(uint32x4_class)); | 2726 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); |
| 2727 const ExternalLabel label(uint32x4_class.ToCString(), stub.EntryPoint()); | 2727 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); |
| 2728 | 2728 |
| 2729 LocationSummary* locs = instruction_->locs(); | 2729 LocationSummary* locs = instruction_->locs(); |
| 2730 locs->live_registers()->Remove(locs->out()); | 2730 locs->live_registers()->Remove(locs->out()); |
| 2731 | 2731 |
| 2732 compiler->SaveLiveRegisters(locs); | 2732 compiler->SaveLiveRegisters(locs); |
| 2733 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | 2733 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 2734 &label, | 2734 &label, |
| 2735 PcDescriptors::kOther, | 2735 PcDescriptors::kOther, |
| 2736 locs); | 2736 locs); |
| 2737 __ MoveRegister(locs->out().reg(), EAX); | 2737 __ MoveRegister(locs->out().reg(), EAX); |
| 2738 compiler->RestoreLiveRegisters(locs); | 2738 compiler->RestoreLiveRegisters(locs); |
| 2739 | 2739 |
| 2740 __ jmp(exit_label()); | 2740 __ jmp(exit_label()); |
| 2741 } | 2741 } |
| 2742 | 2742 |
| 2743 private: | 2743 private: |
| 2744 BoxUint32x4Instr* instruction_; | 2744 BoxInt32x4Instr* instruction_; |
| 2745 }; | 2745 }; |
| 2746 | 2746 |
| 2747 | 2747 |
| 2748 void BoxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2748 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2749 BoxUint32x4SlowPath* slow_path = new BoxUint32x4SlowPath(this); | 2749 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); |
| 2750 compiler->AddSlowPathCode(slow_path); | 2750 compiler->AddSlowPathCode(slow_path); |
| 2751 | 2751 |
| 2752 Register out_reg = locs()->out().reg(); | 2752 Register out_reg = locs()->out().reg(); |
| 2753 XmmRegister value = locs()->in(0).fpu_reg(); | 2753 XmmRegister value = locs()->in(0).fpu_reg(); |
| 2754 | 2754 |
| 2755 __ TryAllocate(compiler->uint32x4_class(), | 2755 __ TryAllocate(compiler->int32x4_class(), |
| 2756 slow_path->entry_label(), | 2756 slow_path->entry_label(), |
| 2757 Assembler::kFarJump, | 2757 Assembler::kFarJump, |
| 2758 out_reg); | 2758 out_reg); |
| 2759 __ Bind(slow_path->exit_label()); | 2759 __ Bind(slow_path->exit_label()); |
| 2760 __ movups(FieldAddress(out_reg, Uint32x4::value_offset()), value); | 2760 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); |
| 2761 } | 2761 } |
| 2762 | 2762 |
| 2763 | 2763 |
| 2764 LocationSummary* UnboxUint32x4Instr::MakeLocationSummary() const { | 2764 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { |
| 2765 const intptr_t value_cid = value()->Type()->ToCid(); | 2765 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2766 const intptr_t kNumInputs = 1; | 2766 const intptr_t kNumInputs = 1; |
| 2767 const intptr_t kNumTemps = value_cid == kUint32x4Cid ? 0 : 1; | 2767 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
| 2768 LocationSummary* summary = | 2768 LocationSummary* summary = |
| 2769 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2769 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2770 summary->set_in(0, Location::RequiresRegister()); | 2770 summary->set_in(0, Location::RequiresRegister()); |
| 2771 if (kNumTemps > 0) { | 2771 if (kNumTemps > 0) { |
| 2772 ASSERT(kNumTemps == 1); | 2772 ASSERT(kNumTemps == 1); |
| 2773 summary->set_temp(0, Location::RequiresRegister()); | 2773 summary->set_temp(0, Location::RequiresRegister()); |
| 2774 } | 2774 } |
| 2775 summary->set_out(Location::RequiresFpuRegister()); | 2775 summary->set_out(Location::RequiresFpuRegister()); |
| 2776 return summary; | 2776 return summary; |
| 2777 } | 2777 } |
| 2778 | 2778 |
| 2779 | 2779 |
| 2780 void UnboxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2780 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2781 const intptr_t value_cid = value()->Type()->ToCid(); | 2781 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2782 const Register value = locs()->in(0).reg(); | 2782 const Register value = locs()->in(0).reg(); |
| 2783 const XmmRegister result = locs()->out().fpu_reg(); | 2783 const XmmRegister result = locs()->out().fpu_reg(); |
| 2784 | 2784 |
| 2785 if (value_cid != kUint32x4Cid) { | 2785 if (value_cid != kInt32x4Cid) { |
| 2786 const Register temp = locs()->temp(0).reg(); | 2786 const Register temp = locs()->temp(0).reg(); |
| 2787 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 2787 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 2788 __ testl(value, Immediate(kSmiTagMask)); | 2788 __ testl(value, Immediate(kSmiTagMask)); |
| 2789 __ j(ZERO, deopt); | 2789 __ j(ZERO, deopt); |
| 2790 __ CompareClassId(value, kUint32x4Cid, temp); | 2790 __ CompareClassId(value, kInt32x4Cid, temp); |
| 2791 __ j(NOT_EQUAL, deopt); | 2791 __ j(NOT_EQUAL, deopt); |
| 2792 } | 2792 } |
| 2793 __ movups(result, FieldAddress(value, Uint32x4::value_offset())); | 2793 __ movups(result, FieldAddress(value, Int32x4::value_offset())); |
| 2794 } | 2794 } |
| 2795 | 2795 |
| 2796 | 2796 |
| 2797 | 2797 |
| 2798 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2798 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
| 2799 const intptr_t kNumInputs = 2; | 2799 const intptr_t kNumInputs = 2; |
| 2800 const intptr_t kNumTemps = 0; | 2800 const intptr_t kNumTemps = 0; |
| 2801 LocationSummary* summary = | 2801 LocationSummary* summary = |
| 2802 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2802 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2803 summary->set_in(0, Location::RequiresFpuRegister()); | 2803 summary->set_in(0, Location::RequiresFpuRegister()); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2878 break; | 2878 break; |
| 2879 case MethodRecognizer::kFloat32x4ShuffleZ: | 2879 case MethodRecognizer::kFloat32x4ShuffleZ: |
| 2880 __ shufps(value, value, Immediate(0xAA)); | 2880 __ shufps(value, value, Immediate(0xAA)); |
| 2881 __ cvtss2sd(value, value); | 2881 __ cvtss2sd(value, value); |
| 2882 break; | 2882 break; |
| 2883 case MethodRecognizer::kFloat32x4ShuffleW: | 2883 case MethodRecognizer::kFloat32x4ShuffleW: |
| 2884 __ shufps(value, value, Immediate(0xFF)); | 2884 __ shufps(value, value, Immediate(0xFF)); |
| 2885 __ cvtss2sd(value, value); | 2885 __ cvtss2sd(value, value); |
| 2886 break; | 2886 break; |
| 2887 case MethodRecognizer::kFloat32x4Shuffle: | 2887 case MethodRecognizer::kFloat32x4Shuffle: |
| 2888 case MethodRecognizer::kUint32x4Shuffle: | 2888 case MethodRecognizer::kInt32x4Shuffle: |
| 2889 __ shufps(value, value, Immediate(mask_)); | 2889 __ shufps(value, value, Immediate(mask_)); |
| 2890 break; | 2890 break; |
| 2891 default: UNREACHABLE(); | 2891 default: UNREACHABLE(); |
| 2892 } | 2892 } |
| 2893 } | 2893 } |
| 2894 | 2894 |
| 2895 | 2895 |
| 2896 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { | 2896 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { |
| 2897 const intptr_t kNumInputs = 2; | 2897 const intptr_t kNumInputs = 2; |
| 2898 const intptr_t kNumTemps = 0; | 2898 const intptr_t kNumTemps = 0; |
| 2899 LocationSummary* summary = | 2899 LocationSummary* summary = |
| 2900 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2900 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2901 summary->set_in(0, Location::RequiresFpuRegister()); | 2901 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2902 summary->set_in(1, Location::RequiresFpuRegister()); | 2902 summary->set_in(1, Location::RequiresFpuRegister()); |
| 2903 summary->set_out(Location::SameAsFirstInput()); | 2903 summary->set_out(Location::SameAsFirstInput()); |
| 2904 return summary; | 2904 return summary; |
| 2905 } | 2905 } |
| 2906 | 2906 |
| 2907 | 2907 |
| 2908 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2908 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2909 XmmRegister left = locs()->in(0).fpu_reg(); | 2909 XmmRegister left = locs()->in(0).fpu_reg(); |
| 2910 XmmRegister right = locs()->in(1).fpu_reg(); | 2910 XmmRegister right = locs()->in(1).fpu_reg(); |
| 2911 | 2911 |
| 2912 ASSERT(locs()->out().fpu_reg() == left); | 2912 ASSERT(locs()->out().fpu_reg() == left); |
| 2913 switch (op_kind()) { | 2913 switch (op_kind()) { |
| 2914 case MethodRecognizer::kFloat32x4ShuffleMix: | 2914 case MethodRecognizer::kFloat32x4ShuffleMix: |
| 2915 case MethodRecognizer::kUint32x4ShuffleMix: | 2915 case MethodRecognizer::kInt32x4ShuffleMix: |
| 2916 __ shufps(left, right, Immediate(mask_)); | 2916 __ shufps(left, right, Immediate(mask_)); |
| 2917 break; | 2917 break; |
| 2918 default: UNREACHABLE(); | 2918 default: UNREACHABLE(); |
| 2919 } | 2919 } |
| 2920 } | 2920 } |
| 2921 | 2921 |
| 2922 | 2922 |
| 2923 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { | 2923 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { |
| 2924 const intptr_t kNumInputs = 1; | 2924 const intptr_t kNumInputs = 1; |
| 2925 const intptr_t kNumTemps = 0; | 2925 const intptr_t kNumTemps = 0; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3258 __ movss(Address(ESP, 12), replacement); | 3258 __ movss(Address(ESP, 12), replacement); |
| 3259 // Move updated value into output register. | 3259 // Move updated value into output register. |
| 3260 __ movups(replacement, Address(ESP, 0)); | 3260 __ movups(replacement, Address(ESP, 0)); |
| 3261 __ addl(ESP, Immediate(16)); | 3261 __ addl(ESP, Immediate(16)); |
| 3262 break; | 3262 break; |
| 3263 default: UNREACHABLE(); | 3263 default: UNREACHABLE(); |
| 3264 } | 3264 } |
| 3265 } | 3265 } |
| 3266 | 3266 |
| 3267 | 3267 |
| 3268 LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const { | 3268 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { |
| 3269 const intptr_t kNumInputs = 1; | 3269 const intptr_t kNumInputs = 1; |
| 3270 const intptr_t kNumTemps = 0; | 3270 const intptr_t kNumTemps = 0; |
| 3271 LocationSummary* summary = | 3271 LocationSummary* summary = |
| 3272 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3272 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3273 summary->set_in(0, Location::RequiresFpuRegister()); | 3273 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3274 summary->set_out(Location::SameAsFirstInput()); | 3274 summary->set_out(Location::SameAsFirstInput()); |
| 3275 return summary; | 3275 return summary; |
| 3276 } | 3276 } |
| 3277 | 3277 |
| 3278 | 3278 |
| 3279 void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3279 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3280 // NOP. | 3280 // NOP. |
| 3281 } | 3281 } |
| 3282 | 3282 |
| 3283 | 3283 |
| 3284 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const { | 3284 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { |
| 3285 const intptr_t kNumInputs = 4; | 3285 const intptr_t kNumInputs = 4; |
| 3286 const intptr_t kNumTemps = 0; | 3286 const intptr_t kNumTemps = 0; |
| 3287 LocationSummary* summary = | 3287 LocationSummary* summary = |
| 3288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3289 summary->set_in(0, Location::RequiresRegister()); | 3289 summary->set_in(0, Location::RequiresRegister()); |
| 3290 summary->set_in(1, Location::RequiresRegister()); | 3290 summary->set_in(1, Location::RequiresRegister()); |
| 3291 summary->set_in(2, Location::RequiresRegister()); | 3291 summary->set_in(2, Location::RequiresRegister()); |
| 3292 summary->set_in(3, Location::RequiresRegister()); | 3292 summary->set_in(3, Location::RequiresRegister()); |
| 3293 summary->set_out(Location::RequiresFpuRegister()); | 3293 summary->set_out(Location::RequiresFpuRegister()); |
| 3294 return summary; | 3294 return summary; |
| 3295 } | 3295 } |
| 3296 | 3296 |
| 3297 | 3297 |
| 3298 void Uint32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3298 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3299 Register v0 = locs()->in(0).reg(); | 3299 Register v0 = locs()->in(0).reg(); |
| 3300 Register v1 = locs()->in(1).reg(); | 3300 Register v1 = locs()->in(1).reg(); |
| 3301 Register v2 = locs()->in(2).reg(); | 3301 Register v2 = locs()->in(2).reg(); |
| 3302 Register v3 = locs()->in(3).reg(); | 3302 Register v3 = locs()->in(3).reg(); |
| 3303 XmmRegister result = locs()->out().fpu_reg(); | 3303 XmmRegister result = locs()->out().fpu_reg(); |
| 3304 Label x_false, x_done; | 3304 Label x_false, x_done; |
| 3305 Label y_false, y_done; | 3305 Label y_false, y_done; |
| 3306 Label z_false, z_done; | 3306 Label z_false, z_done; |
| 3307 Label w_false, w_done; | 3307 Label w_false, w_done; |
| 3308 __ subl(ESP, Immediate(16)); | 3308 __ subl(ESP, Immediate(16)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3336 __ jmp(&w_done); | 3336 __ jmp(&w_done); |
| 3337 __ Bind(&w_false); | 3337 __ Bind(&w_false); |
| 3338 __ movl(Address(ESP, 12), Immediate(0x0)); | 3338 __ movl(Address(ESP, 12), Immediate(0x0)); |
| 3339 __ Bind(&w_done); | 3339 __ Bind(&w_done); |
| 3340 | 3340 |
| 3341 __ movups(result, Address(ESP, 0)); | 3341 __ movups(result, Address(ESP, 0)); |
| 3342 __ addl(ESP, Immediate(16)); | 3342 __ addl(ESP, Immediate(16)); |
| 3343 } | 3343 } |
| 3344 | 3344 |
| 3345 | 3345 |
| 3346 LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const { | 3346 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { |
| 3347 const intptr_t kNumInputs = 1; | 3347 const intptr_t kNumInputs = 1; |
| 3348 const intptr_t kNumTemps = 0; | 3348 const intptr_t kNumTemps = 0; |
| 3349 LocationSummary* summary = | 3349 LocationSummary* summary = |
| 3350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3351 summary->set_in(0, Location::RequiresFpuRegister()); | 3351 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3352 summary->set_out(Location::RequiresRegister()); | 3352 summary->set_out(Location::RequiresRegister()); |
| 3353 return summary; | 3353 return summary; |
| 3354 } | 3354 } |
| 3355 | 3355 |
| 3356 | 3356 |
| 3357 void Uint32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3357 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3358 XmmRegister value = locs()->in(0).fpu_reg(); | 3358 XmmRegister value = locs()->in(0).fpu_reg(); |
| 3359 Register result = locs()->out().reg(); | 3359 Register result = locs()->out().reg(); |
| 3360 Label done; | 3360 Label done; |
| 3361 Label non_zero; | 3361 Label non_zero; |
| 3362 __ subl(ESP, Immediate(16)); | 3362 __ subl(ESP, Immediate(16)); |
| 3363 // Move value to stack. | 3363 // Move value to stack. |
| 3364 __ movups(Address(ESP, 0), value); | 3364 __ movups(Address(ESP, 0), value); |
| 3365 switch (op_kind()) { | 3365 switch (op_kind()) { |
| 3366 case MethodRecognizer::kUint32x4GetFlagX: | 3366 case MethodRecognizer::kInt32x4GetFlagX: |
| 3367 __ movl(result, Address(ESP, 0)); | 3367 __ movl(result, Address(ESP, 0)); |
| 3368 break; | 3368 break; |
| 3369 case MethodRecognizer::kUint32x4GetFlagY: | 3369 case MethodRecognizer::kInt32x4GetFlagY: |
| 3370 __ movl(result, Address(ESP, 4)); | 3370 __ movl(result, Address(ESP, 4)); |
| 3371 break; | 3371 break; |
| 3372 case MethodRecognizer::kUint32x4GetFlagZ: | 3372 case MethodRecognizer::kInt32x4GetFlagZ: |
| 3373 __ movl(result, Address(ESP, 8)); | 3373 __ movl(result, Address(ESP, 8)); |
| 3374 break; | 3374 break; |
| 3375 case MethodRecognizer::kUint32x4GetFlagW: | 3375 case MethodRecognizer::kInt32x4GetFlagW: |
| 3376 __ movl(result, Address(ESP, 12)); | 3376 __ movl(result, Address(ESP, 12)); |
| 3377 break; | 3377 break; |
| 3378 default: UNREACHABLE(); | 3378 default: UNREACHABLE(); |
| 3379 } | 3379 } |
| 3380 __ addl(ESP, Immediate(16)); | 3380 __ addl(ESP, Immediate(16)); |
| 3381 __ testl(result, result); | 3381 __ testl(result, result); |
| 3382 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); | 3382 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); |
| 3383 __ LoadObject(result, Bool::False()); | 3383 __ LoadObject(result, Bool::False()); |
| 3384 __ jmp(&done); | 3384 __ jmp(&done); |
| 3385 __ Bind(&non_zero); | 3385 __ Bind(&non_zero); |
| 3386 __ LoadObject(result, Bool::True()); | 3386 __ LoadObject(result, Bool::True()); |
| 3387 __ Bind(&done); | 3387 __ Bind(&done); |
| 3388 } | 3388 } |
| 3389 | 3389 |
| 3390 | 3390 |
| 3391 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const { | 3391 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { |
| 3392 const intptr_t kNumInputs = 3; | 3392 const intptr_t kNumInputs = 3; |
| 3393 const intptr_t kNumTemps = 1; | 3393 const intptr_t kNumTemps = 1; |
| 3394 LocationSummary* summary = | 3394 LocationSummary* summary = |
| 3395 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3395 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3396 summary->set_in(0, Location::RequiresFpuRegister()); | 3396 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3397 summary->set_in(1, Location::RequiresFpuRegister()); | 3397 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3398 summary->set_in(2, Location::RequiresFpuRegister()); | 3398 summary->set_in(2, Location::RequiresFpuRegister()); |
| 3399 summary->set_temp(0, Location::RequiresFpuRegister()); | 3399 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 3400 summary->set_out(Location::SameAsFirstInput()); | 3400 summary->set_out(Location::SameAsFirstInput()); |
| 3401 return summary; | 3401 return summary; |
| 3402 } | 3402 } |
| 3403 | 3403 |
| 3404 | 3404 |
| 3405 void Uint32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3405 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3406 XmmRegister mask = locs()->in(0).fpu_reg(); | 3406 XmmRegister mask = locs()->in(0).fpu_reg(); |
| 3407 XmmRegister trueValue = locs()->in(1).fpu_reg(); | 3407 XmmRegister trueValue = locs()->in(1).fpu_reg(); |
| 3408 XmmRegister falseValue = locs()->in(2).fpu_reg(); | 3408 XmmRegister falseValue = locs()->in(2).fpu_reg(); |
| 3409 XmmRegister out = locs()->out().fpu_reg(); | 3409 XmmRegister out = locs()->out().fpu_reg(); |
| 3410 XmmRegister temp = locs()->temp(0).fpu_reg(); | 3410 XmmRegister temp = locs()->temp(0).fpu_reg(); |
| 3411 ASSERT(out == mask); | 3411 ASSERT(out == mask); |
| 3412 // Copy mask. | 3412 // Copy mask. |
| 3413 __ movaps(temp, mask); | 3413 __ movaps(temp, mask); |
| 3414 // Invert it. | 3414 // Invert it. |
| 3415 __ notps(temp); | 3415 __ notps(temp); |
| 3416 // mask = mask & trueValue. | 3416 // mask = mask & trueValue. |
| 3417 __ andps(mask, trueValue); | 3417 __ andps(mask, trueValue); |
| 3418 // temp = temp & falseValue. | 3418 // temp = temp & falseValue. |
| 3419 __ andps(temp, falseValue); | 3419 __ andps(temp, falseValue); |
| 3420 // out = mask | temp. | 3420 // out = mask | temp. |
| 3421 __ orps(mask, temp); | 3421 __ orps(mask, temp); |
| 3422 } | 3422 } |
| 3423 | 3423 |
| 3424 | 3424 |
| 3425 LocationSummary* Uint32x4SetFlagInstr::MakeLocationSummary() const { | 3425 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { |
| 3426 const intptr_t kNumInputs = 2; | 3426 const intptr_t kNumInputs = 2; |
| 3427 const intptr_t kNumTemps = 0; | 3427 const intptr_t kNumTemps = 0; |
| 3428 LocationSummary* summary = | 3428 LocationSummary* summary = |
| 3429 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3429 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3430 summary->set_in(0, Location::RequiresFpuRegister()); | 3430 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3431 summary->set_in(1, Location::RequiresRegister()); | 3431 summary->set_in(1, Location::RequiresRegister()); |
| 3432 summary->set_out(Location::SameAsFirstInput()); | 3432 summary->set_out(Location::SameAsFirstInput()); |
| 3433 return summary; | 3433 return summary; |
| 3434 } | 3434 } |
| 3435 | 3435 |
| 3436 | 3436 |
| 3437 void Uint32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3437 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3438 XmmRegister mask = locs()->in(0).fpu_reg(); | 3438 XmmRegister mask = locs()->in(0).fpu_reg(); |
| 3439 Register flag = locs()->in(1).reg(); | 3439 Register flag = locs()->in(1).reg(); |
| 3440 ASSERT(mask == locs()->out().fpu_reg()); | 3440 ASSERT(mask == locs()->out().fpu_reg()); |
| 3441 __ subl(ESP, Immediate(16)); | 3441 __ subl(ESP, Immediate(16)); |
| 3442 // Copy mask to stack. | 3442 // Copy mask to stack. |
| 3443 __ movups(Address(ESP, 0), mask); | 3443 __ movups(Address(ESP, 0), mask); |
| 3444 Label falsePath, exitPath; | 3444 Label falsePath, exitPath; |
| 3445 __ CompareObject(flag, Bool::True()); | 3445 __ CompareObject(flag, Bool::True()); |
| 3446 __ j(NOT_EQUAL, &falsePath); | 3446 __ j(NOT_EQUAL, &falsePath); |
| 3447 switch (op_kind()) { | 3447 switch (op_kind()) { |
| 3448 case MethodRecognizer::kUint32x4WithFlagX: | 3448 case MethodRecognizer::kInt32x4WithFlagX: |
| 3449 __ movl(Address(ESP, 0), Immediate(0xFFFFFFFF)); | 3449 __ movl(Address(ESP, 0), Immediate(0xFFFFFFFF)); |
| 3450 __ jmp(&exitPath); | 3450 __ jmp(&exitPath); |
| 3451 __ Bind(&falsePath); | 3451 __ Bind(&falsePath); |
| 3452 __ movl(Address(ESP, 0), Immediate(0x0)); | 3452 __ movl(Address(ESP, 0), Immediate(0x0)); |
| 3453 break; | 3453 break; |
| 3454 case MethodRecognizer::kUint32x4WithFlagY: | 3454 case MethodRecognizer::kInt32x4WithFlagY: |
| 3455 __ movl(Address(ESP, 4), Immediate(0xFFFFFFFF)); | 3455 __ movl(Address(ESP, 4), Immediate(0xFFFFFFFF)); |
| 3456 __ jmp(&exitPath); | 3456 __ jmp(&exitPath); |
| 3457 __ Bind(&falsePath); | 3457 __ Bind(&falsePath); |
| 3458 __ movl(Address(ESP, 4), Immediate(0x0)); | 3458 __ movl(Address(ESP, 4), Immediate(0x0)); |
| 3459 break; | 3459 break; |
| 3460 case MethodRecognizer::kUint32x4WithFlagZ: | 3460 case MethodRecognizer::kInt32x4WithFlagZ: |
| 3461 __ movl(Address(ESP, 8), Immediate(0xFFFFFFFF)); | 3461 __ movl(Address(ESP, 8), Immediate(0xFFFFFFFF)); |
| 3462 __ jmp(&exitPath); | 3462 __ jmp(&exitPath); |
| 3463 __ Bind(&falsePath); | 3463 __ Bind(&falsePath); |
| 3464 __ movl(Address(ESP, 8), Immediate(0x0)); | 3464 __ movl(Address(ESP, 8), Immediate(0x0)); |
| 3465 break; | 3465 break; |
| 3466 case MethodRecognizer::kUint32x4WithFlagW: | 3466 case MethodRecognizer::kInt32x4WithFlagW: |
| 3467 __ movl(Address(ESP, 12), Immediate(0xFFFFFFFF)); | 3467 __ movl(Address(ESP, 12), Immediate(0xFFFFFFFF)); |
| 3468 __ jmp(&exitPath); | 3468 __ jmp(&exitPath); |
| 3469 __ Bind(&falsePath); | 3469 __ Bind(&falsePath); |
| 3470 __ movl(Address(ESP, 12), Immediate(0x0)); | 3470 __ movl(Address(ESP, 12), Immediate(0x0)); |
| 3471 break; | 3471 break; |
| 3472 default: UNREACHABLE(); | 3472 default: UNREACHABLE(); |
| 3473 } | 3473 } |
| 3474 __ Bind(&exitPath); | 3474 __ Bind(&exitPath); |
| 3475 // Copy mask back to register. | 3475 // Copy mask back to register. |
| 3476 __ movups(mask, Address(ESP, 0)); | 3476 __ movups(mask, Address(ESP, 0)); |
| 3477 __ addl(ESP, Immediate(16)); | 3477 __ addl(ESP, Immediate(16)); |
| 3478 } | 3478 } |
| 3479 | 3479 |
| 3480 | 3480 |
| 3481 LocationSummary* Uint32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3481 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { |
| 3482 const intptr_t kNumInputs = 1; | 3482 const intptr_t kNumInputs = 1; |
| 3483 const intptr_t kNumTemps = 0; | 3483 const intptr_t kNumTemps = 0; |
| 3484 LocationSummary* summary = | 3484 LocationSummary* summary = |
| 3485 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3485 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3486 summary->set_in(0, Location::RequiresFpuRegister()); | 3486 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3487 summary->set_out(Location::SameAsFirstInput()); | 3487 summary->set_out(Location::SameAsFirstInput()); |
| 3488 return summary; | 3488 return summary; |
| 3489 } | 3489 } |
| 3490 | 3490 |
| 3491 | 3491 |
| 3492 void Uint32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3492 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3493 // NOP. | 3493 // NOP. |
| 3494 } | 3494 } |
| 3495 | 3495 |
| 3496 | 3496 |
| 3497 LocationSummary* BinaryUint32x4OpInstr::MakeLocationSummary() const { | 3497 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { |
| 3498 const intptr_t kNumInputs = 2; | 3498 const intptr_t kNumInputs = 2; |
| 3499 const intptr_t kNumTemps = 0; | 3499 const intptr_t kNumTemps = 0; |
| 3500 LocationSummary* summary = | 3500 LocationSummary* summary = |
| 3501 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3501 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3502 summary->set_in(0, Location::RequiresFpuRegister()); | 3502 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3503 summary->set_in(1, Location::RequiresFpuRegister()); | 3503 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3504 summary->set_out(Location::SameAsFirstInput()); | 3504 summary->set_out(Location::SameAsFirstInput()); |
| 3505 return summary; | 3505 return summary; |
| 3506 } | 3506 } |
| 3507 | 3507 |
| 3508 | 3508 |
| 3509 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3509 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3510 XmmRegister left = locs()->in(0).fpu_reg(); | 3510 XmmRegister left = locs()->in(0).fpu_reg(); |
| 3511 XmmRegister right = locs()->in(1).fpu_reg(); | 3511 XmmRegister right = locs()->in(1).fpu_reg(); |
| 3512 ASSERT(left == locs()->out().fpu_reg()); | 3512 ASSERT(left == locs()->out().fpu_reg()); |
| 3513 switch (op_kind()) { | 3513 switch (op_kind()) { |
| 3514 case Token::kBIT_AND: { | 3514 case Token::kBIT_AND: { |
| 3515 __ andps(left, right); | 3515 __ andps(left, right); |
| 3516 break; | 3516 break; |
| 3517 } | 3517 } |
| 3518 case Token::kBIT_OR: { | 3518 case Token::kBIT_OR: { |
| 3519 __ orps(left, right); | 3519 __ orps(left, right); |
| (...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4890 PcDescriptors::kOther, | 4890 PcDescriptors::kOther, |
| 4891 locs()); | 4891 locs()); |
| 4892 __ Drop(2); // Discard type arguments and receiver. | 4892 __ Drop(2); // Discard type arguments and receiver. |
| 4893 } | 4893 } |
| 4894 | 4894 |
| 4895 } // namespace dart | 4895 } // namespace dart |
| 4896 | 4896 |
| 4897 #undef __ | 4897 #undef __ |
| 4898 | 4898 |
| 4899 #endif // defined TARGET_ARCH_IA32 | 4899 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |