| 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 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 switch (class_id_) { | 744 switch (class_id_) { |
| 745 case kArrayCid: | 745 case kArrayCid: |
| 746 case kImmutableArrayCid: | 746 case kImmutableArrayCid: |
| 747 return CompileType::Dynamic(); | 747 return CompileType::Dynamic(); |
| 748 | 748 |
| 749 case kTypedDataFloat32ArrayCid: | 749 case kTypedDataFloat32ArrayCid: |
| 750 case kTypedDataFloat64ArrayCid: | 750 case kTypedDataFloat64ArrayCid: |
| 751 return CompileType::FromCid(kDoubleCid); | 751 return CompileType::FromCid(kDoubleCid); |
| 752 case kTypedDataFloat32x4ArrayCid: | 752 case kTypedDataFloat32x4ArrayCid: |
| 753 return CompileType::FromCid(kFloat32x4Cid); | 753 return CompileType::FromCid(kFloat32x4Cid); |
| 754 case kTypedDataUint32x4ArrayCid: | 754 case kTypedDataInt32x4ArrayCid: |
| 755 return CompileType::FromCid(kUint32x4Cid); | 755 return CompileType::FromCid(kInt32x4Cid); |
| 756 | 756 |
| 757 case kTypedDataInt8ArrayCid: | 757 case kTypedDataInt8ArrayCid: |
| 758 case kTypedDataUint8ArrayCid: | 758 case kTypedDataUint8ArrayCid: |
| 759 case kTypedDataUint8ClampedArrayCid: | 759 case kTypedDataUint8ClampedArrayCid: |
| 760 case kExternalTypedDataUint8ArrayCid: | 760 case kExternalTypedDataUint8ArrayCid: |
| 761 case kExternalTypedDataUint8ClampedArrayCid: | 761 case kExternalTypedDataUint8ClampedArrayCid: |
| 762 case kTypedDataInt16ArrayCid: | 762 case kTypedDataInt16ArrayCid: |
| 763 case kTypedDataUint16ArrayCid: | 763 case kTypedDataUint16ArrayCid: |
| 764 case kOneByteStringCid: | 764 case kOneByteStringCid: |
| 765 case kTwoByteStringCid: | 765 case kTwoByteStringCid: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 786 case kTypedDataInt16ArrayCid: | 786 case kTypedDataInt16ArrayCid: |
| 787 case kTypedDataUint16ArrayCid: | 787 case kTypedDataUint16ArrayCid: |
| 788 case kOneByteStringCid: | 788 case kOneByteStringCid: |
| 789 case kTwoByteStringCid: | 789 case kTwoByteStringCid: |
| 790 case kTypedDataInt32ArrayCid: | 790 case kTypedDataInt32ArrayCid: |
| 791 case kTypedDataUint32ArrayCid: | 791 case kTypedDataUint32ArrayCid: |
| 792 return kTagged; | 792 return kTagged; |
| 793 case kTypedDataFloat32ArrayCid: | 793 case kTypedDataFloat32ArrayCid: |
| 794 case kTypedDataFloat64ArrayCid: | 794 case kTypedDataFloat64ArrayCid: |
| 795 return kUnboxedDouble; | 795 return kUnboxedDouble; |
| 796 case kTypedDataUint32x4ArrayCid: | 796 case kTypedDataInt32x4ArrayCid: |
| 797 return kUnboxedUint32x4; | 797 return kUnboxedInt32x4; |
| 798 case kTypedDataFloat32x4ArrayCid: | 798 case kTypedDataFloat32x4ArrayCid: |
| 799 return kUnboxedFloat32x4; | 799 return kUnboxedFloat32x4; |
| 800 default: | 800 default: |
| 801 UNIMPLEMENTED(); | 801 UNIMPLEMENTED(); |
| 802 return kTagged; | 802 return kTagged; |
| 803 } | 803 } |
| 804 } | 804 } |
| 805 | 805 |
| 806 | 806 |
| 807 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 807 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 818 index()->definition()->AsConstant()->value()) | 818 index()->definition()->AsConstant()->value()) |
| 819 : Location::WritableRegister()); | 819 : Location::WritableRegister()); |
| 820 } else { | 820 } else { |
| 821 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 821 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| 822 ? Location::Constant( | 822 ? Location::Constant( |
| 823 index()->definition()->AsConstant()->value()) | 823 index()->definition()->AsConstant()->value()) |
| 824 : Location::RequiresRegister()); | 824 : Location::RequiresRegister()); |
| 825 } | 825 } |
| 826 if ((representation() == kUnboxedDouble) || | 826 if ((representation() == kUnboxedDouble) || |
| 827 (representation() == kUnboxedFloat32x4) || | 827 (representation() == kUnboxedFloat32x4) || |
| 828 (representation() == kUnboxedUint32x4)) { | 828 (representation() == kUnboxedInt32x4)) { |
| 829 locs->set_out(Location::RequiresFpuRegister()); | 829 locs->set_out(Location::RequiresFpuRegister()); |
| 830 } else { | 830 } else { |
| 831 locs->set_out(Location::RequiresRegister()); | 831 locs->set_out(Location::RequiresRegister()); |
| 832 } | 832 } |
| 833 return locs; | 833 return locs; |
| 834 } | 834 } |
| 835 | 835 |
| 836 | 836 |
| 837 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 837 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 838 Register array = locs()->in(0).reg(); | 838 Register array = locs()->in(0).reg(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 853 element_address = index.IsRegister() | 853 element_address = index.IsRegister() |
| 854 ? FlowGraphCompiler::ElementAddressForRegIndex( | 854 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 855 class_id(), index_scale(), array, index.reg()) | 855 class_id(), index_scale(), array, index.reg()) |
| 856 : FlowGraphCompiler::ElementAddressForIntIndex( | 856 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 857 class_id(), index_scale(), array, | 857 class_id(), index_scale(), array, |
| 858 Smi::Cast(index.constant()).Value()); | 858 Smi::Cast(index.constant()).Value()); |
| 859 } | 859 } |
| 860 | 860 |
| 861 if ((representation() == kUnboxedDouble) || | 861 if ((representation() == kUnboxedDouble) || |
| 862 (representation() == kUnboxedFloat32x4) || | 862 (representation() == kUnboxedFloat32x4) || |
| 863 (representation() == kUnboxedUint32x4)) { | 863 (representation() == kUnboxedInt32x4)) { |
| 864 if ((index_scale() == 1) && index.IsRegister()) { | 864 if ((index_scale() == 1) && index.IsRegister()) { |
| 865 __ SmiUntag(index.reg()); | 865 __ SmiUntag(index.reg()); |
| 866 } | 866 } |
| 867 | 867 |
| 868 XmmRegister result = locs()->out().fpu_reg(); | 868 XmmRegister result = locs()->out().fpu_reg(); |
| 869 if (class_id() == kTypedDataFloat32ArrayCid) { | 869 if (class_id() == kTypedDataFloat32ArrayCid) { |
| 870 // Load single precision float. | 870 // Load single precision float. |
| 871 __ movss(result, element_address); | 871 __ movss(result, element_address); |
| 872 // Promote to double. | 872 // Promote to double. |
| 873 __ cvtss2sd(result, locs()->out().fpu_reg()); | 873 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 874 } else if (class_id() == kTypedDataFloat64ArrayCid) { | 874 } else if (class_id() == kTypedDataFloat64ArrayCid) { |
| 875 __ movsd(result, element_address); | 875 __ movsd(result, element_address); |
| 876 } else { | 876 } else { |
| 877 ASSERT((class_id() == kTypedDataUint32x4ArrayCid) || | 877 ASSERT((class_id() == kTypedDataInt32x4ArrayCid) || |
| 878 (class_id() == kTypedDataFloat32x4ArrayCid)); | 878 (class_id() == kTypedDataFloat32x4ArrayCid)); |
| 879 __ movups(result, element_address); | 879 __ movups(result, element_address); |
| 880 } | 880 } |
| 881 return; | 881 return; |
| 882 } | 882 } |
| 883 | 883 |
| 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 Register result = locs()->out().reg(); | 887 Register result = locs()->out().reg(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 case kTypedDataInt16ArrayCid: | 939 case kTypedDataInt16ArrayCid: |
| 940 case kTypedDataUint16ArrayCid: | 940 case kTypedDataUint16ArrayCid: |
| 941 case kTypedDataInt32ArrayCid: | 941 case kTypedDataInt32ArrayCid: |
| 942 case kTypedDataUint32ArrayCid: | 942 case kTypedDataUint32ArrayCid: |
| 943 return kTagged; | 943 return kTagged; |
| 944 case kTypedDataFloat32ArrayCid: | 944 case kTypedDataFloat32ArrayCid: |
| 945 case kTypedDataFloat64ArrayCid: | 945 case kTypedDataFloat64ArrayCid: |
| 946 return kUnboxedDouble; | 946 return kUnboxedDouble; |
| 947 case kTypedDataFloat32x4ArrayCid: | 947 case kTypedDataFloat32x4ArrayCid: |
| 948 return kUnboxedFloat32x4; | 948 return kUnboxedFloat32x4; |
| 949 case kTypedDataUint32x4ArrayCid: | 949 case kTypedDataInt32x4ArrayCid: |
| 950 return kUnboxedUint32x4; | 950 return kUnboxedInt32x4; |
| 951 default: | 951 default: |
| 952 UNIMPLEMENTED(); | 952 UNIMPLEMENTED(); |
| 953 return kTagged; | 953 return kTagged; |
| 954 } | 954 } |
| 955 } | 955 } |
| 956 | 956 |
| 957 | 957 |
| 958 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 958 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 959 const intptr_t kNumInputs = 3; | 959 const intptr_t kNumInputs = 3; |
| 960 const intptr_t kNumTemps = 0; | 960 const intptr_t kNumTemps = 0; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 locs->set_in(2, Location::WritableRegister()); | 998 locs->set_in(2, Location::WritableRegister()); |
| 999 break; | 999 break; |
| 1000 case kTypedDataFloat32ArrayCid: | 1000 case kTypedDataFloat32ArrayCid: |
| 1001 // Need temp register for float-to-double conversion. | 1001 // Need temp register for float-to-double conversion. |
| 1002 locs->AddTemp(Location::RequiresFpuRegister()); | 1002 locs->AddTemp(Location::RequiresFpuRegister()); |
| 1003 // Fall through. | 1003 // Fall through. |
| 1004 case kTypedDataFloat64ArrayCid: | 1004 case kTypedDataFloat64ArrayCid: |
| 1005 // TODO(srdjan): Support Float64 constants. | 1005 // TODO(srdjan): Support Float64 constants. |
| 1006 locs->set_in(2, Location::RequiresFpuRegister()); | 1006 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1007 break; | 1007 break; |
| 1008 case kTypedDataUint32x4ArrayCid: | 1008 case kTypedDataInt32x4ArrayCid: |
| 1009 case kTypedDataFloat32x4ArrayCid: | 1009 case kTypedDataFloat32x4ArrayCid: |
| 1010 locs->set_in(2, Location::RequiresFpuRegister()); | 1010 locs->set_in(2, Location::RequiresFpuRegister()); |
| 1011 break; | 1011 break; |
| 1012 default: | 1012 default: |
| 1013 UNREACHABLE(); | 1013 UNREACHABLE(); |
| 1014 return NULL; | 1014 return NULL; |
| 1015 } | 1015 } |
| 1016 return locs; | 1016 return locs; |
| 1017 } | 1017 } |
| 1018 | 1018 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 } | 1116 } |
| 1117 case kTypedDataFloat32ArrayCid: | 1117 case kTypedDataFloat32ArrayCid: |
| 1118 // Convert to single precision. | 1118 // Convert to single precision. |
| 1119 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); | 1119 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); |
| 1120 // Store. | 1120 // Store. |
| 1121 __ movss(element_address, locs()->temp(0).fpu_reg()); | 1121 __ movss(element_address, locs()->temp(0).fpu_reg()); |
| 1122 break; | 1122 break; |
| 1123 case kTypedDataFloat64ArrayCid: | 1123 case kTypedDataFloat64ArrayCid: |
| 1124 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1124 __ movsd(element_address, locs()->in(2).fpu_reg()); |
| 1125 break; | 1125 break; |
| 1126 case kTypedDataUint32x4ArrayCid: | 1126 case kTypedDataInt32x4ArrayCid: |
| 1127 case kTypedDataFloat32x4ArrayCid: | 1127 case kTypedDataFloat32x4ArrayCid: |
| 1128 __ movups(element_address, locs()->in(2).fpu_reg()); | 1128 __ movups(element_address, locs()->in(2).fpu_reg()); |
| 1129 break; | 1129 break; |
| 1130 default: | 1130 default: |
| 1131 UNREACHABLE(); | 1131 UNREACHABLE(); |
| 1132 } | 1132 } |
| 1133 } | 1133 } |
| 1134 | 1134 |
| 1135 | 1135 |
| 1136 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1136 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 // If length is negative the length guard is either disabled or | 1251 // If length is negative the length guard is either disabled or |
| 1252 // has not been initialized, either way it is safe to skip the | 1252 // has not been initialized, either way it is safe to skip the |
| 1253 // length check. | 1253 // length check. |
| 1254 __ CompareImmediate( | 1254 __ CompareImmediate( |
| 1255 field_length_operand, Immediate(Smi::RawValue(0)), PP); | 1255 field_length_operand, Immediate(Smi::RawValue(0)), PP); |
| 1256 __ j(LESS, &skip_length_check); | 1256 __ j(LESS, &skip_length_check); |
| 1257 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); | 1257 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); |
| 1258 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1258 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1259 // Check for typed data array. | 1259 // Check for typed data array. |
| 1260 __ CompareImmediate( | 1260 __ CompareImmediate( |
| 1261 value_cid_reg, Immediate(kTypedDataUint32x4ArrayCid), PP); | 1261 value_cid_reg, Immediate(kTypedDataInt32x4ArrayCid), PP); |
| 1262 // Not a typed array or a regular array. | 1262 // Not a typed array or a regular array. |
| 1263 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); | 1263 __ j(GREATER, &no_fixed_length, Assembler::kNearJump); |
| 1264 __ CompareImmediate( | 1264 __ CompareImmediate( |
| 1265 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); | 1265 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); |
| 1266 // Could still be a regular array. | 1266 // Could still be a regular array. |
| 1267 __ j(LESS, &check_array, Assembler::kNearJump); | 1267 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1268 __ pushq(value_cid_reg); | 1268 __ pushq(value_cid_reg); |
| 1269 __ movq(value_cid_reg, | 1269 __ movq(value_cid_reg, |
| 1270 FieldAddress(value_reg, TypedData::length_offset())); | 1270 FieldAddress(value_reg, TypedData::length_offset())); |
| 1271 __ cmpq(field_length_operand, value_cid_reg); | 1271 __ cmpq(field_length_operand, value_cid_reg); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 | 1331 |
| 1332 if (value_cid == kDynamicCid) { | 1332 if (value_cid == kDynamicCid) { |
| 1333 __ movq(field_cid_operand, value_cid_reg); | 1333 __ movq(field_cid_operand, value_cid_reg); |
| 1334 __ movq(field_nullability_operand, value_cid_reg); | 1334 __ movq(field_nullability_operand, value_cid_reg); |
| 1335 if (field_has_length) { | 1335 if (field_has_length) { |
| 1336 Label check_array, length_set, no_fixed_length; | 1336 Label check_array, length_set, no_fixed_length; |
| 1337 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); | 1337 __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP); |
| 1338 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); | 1338 __ j(EQUAL, &no_fixed_length, Assembler::kNearJump); |
| 1339 // Check for typed data array. | 1339 // Check for typed data array. |
| 1340 __ CompareImmediate(value_cid_reg, | 1340 __ CompareImmediate(value_cid_reg, |
| 1341 Immediate(kTypedDataUint32x4ArrayCid), PP); | 1341 Immediate(kTypedDataInt32x4ArrayCid), PP); |
| 1342 // Not a typed array or a regular array. | 1342 // Not a typed array or a regular array. |
| 1343 __ j(GREATER, &no_fixed_length); | 1343 __ j(GREATER, &no_fixed_length); |
| 1344 __ CompareImmediate( | 1344 __ CompareImmediate( |
| 1345 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); | 1345 value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP); |
| 1346 // Could still be a regular array. | 1346 // Could still be a regular array. |
| 1347 __ j(LESS, &check_array, Assembler::kNearJump); | 1347 __ j(LESS, &check_array, Assembler::kNearJump); |
| 1348 // Destroy value_cid_reg (safe because we are finished with it). | 1348 // Destroy value_cid_reg (safe because we are finished with it). |
| 1349 __ movq(value_cid_reg, | 1349 __ movq(value_cid_reg, |
| 1350 FieldAddress(value_reg, TypedData::length_offset())); | 1350 FieldAddress(value_reg, TypedData::length_offset())); |
| 1351 __ movq(field_length_operand, value_cid_reg); | 1351 __ movq(field_length_operand, value_cid_reg); |
| (...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2715 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 2715 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 2716 __ testq(value, Immediate(kSmiTagMask)); | 2716 __ testq(value, Immediate(kSmiTagMask)); |
| 2717 __ j(ZERO, deopt); | 2717 __ j(ZERO, deopt); |
| 2718 __ CompareClassId(value, kFloat32x4Cid); | 2718 __ CompareClassId(value, kFloat32x4Cid); |
| 2719 __ j(NOT_EQUAL, deopt); | 2719 __ j(NOT_EQUAL, deopt); |
| 2720 } | 2720 } |
| 2721 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | 2721 __ movups(result, FieldAddress(value, Float32x4::value_offset())); |
| 2722 } | 2722 } |
| 2723 | 2723 |
| 2724 | 2724 |
| 2725 LocationSummary* BoxUint32x4Instr::MakeLocationSummary() const { | 2725 LocationSummary* BoxInt32x4Instr::MakeLocationSummary() const { |
| 2726 const intptr_t kNumInputs = 1; | 2726 const intptr_t kNumInputs = 1; |
| 2727 const intptr_t kNumTemps = 0; | 2727 const intptr_t kNumTemps = 0; |
| 2728 LocationSummary* summary = | 2728 LocationSummary* summary = |
| 2729 new LocationSummary(kNumInputs, | 2729 new LocationSummary(kNumInputs, |
| 2730 kNumTemps, | 2730 kNumTemps, |
| 2731 LocationSummary::kCallOnSlowPath); | 2731 LocationSummary::kCallOnSlowPath); |
| 2732 summary->set_in(0, Location::RequiresFpuRegister()); | 2732 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2733 summary->set_out(Location::RequiresRegister()); | 2733 summary->set_out(Location::RequiresRegister()); |
| 2734 return summary; | 2734 return summary; |
| 2735 } | 2735 } |
| 2736 | 2736 |
| 2737 | 2737 |
| 2738 class BoxUint32x4SlowPath : public SlowPathCode { | 2738 class BoxInt32x4SlowPath : public SlowPathCode { |
| 2739 public: | 2739 public: |
| 2740 explicit BoxUint32x4SlowPath(BoxUint32x4Instr* instruction) | 2740 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) |
| 2741 : instruction_(instruction) { } | 2741 : instruction_(instruction) { } |
| 2742 | 2742 |
| 2743 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2743 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2744 __ Comment("BoxUint32x4SlowPath"); | 2744 __ Comment("BoxInt32x4SlowPath"); |
| 2745 __ Bind(entry_label()); | 2745 __ Bind(entry_label()); |
| 2746 const Class& uint32x4_class = compiler->uint32x4_class(); | 2746 const Class& int32x4_class = compiler->int32x4_class(); |
| 2747 const Code& stub = | 2747 const Code& stub = |
| 2748 Code::Handle(StubCode::GetAllocationStubForClass(uint32x4_class)); | 2748 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); |
| 2749 const ExternalLabel label(uint32x4_class.ToCString(), stub.EntryPoint()); | 2749 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); |
| 2750 | 2750 |
| 2751 LocationSummary* locs = instruction_->locs(); | 2751 LocationSummary* locs = instruction_->locs(); |
| 2752 locs->live_registers()->Remove(locs->out()); | 2752 locs->live_registers()->Remove(locs->out()); |
| 2753 | 2753 |
| 2754 compiler->SaveLiveRegisters(locs); | 2754 compiler->SaveLiveRegisters(locs); |
| 2755 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. | 2755 compiler->GenerateCall(Scanner::kDummyTokenIndex, // No token position. |
| 2756 &label, | 2756 &label, |
| 2757 PcDescriptors::kOther, | 2757 PcDescriptors::kOther, |
| 2758 locs); | 2758 locs); |
| 2759 __ MoveRegister(locs->out().reg(), RAX); | 2759 __ MoveRegister(locs->out().reg(), RAX); |
| 2760 compiler->RestoreLiveRegisters(locs); | 2760 compiler->RestoreLiveRegisters(locs); |
| 2761 | 2761 |
| 2762 __ jmp(exit_label()); | 2762 __ jmp(exit_label()); |
| 2763 } | 2763 } |
| 2764 | 2764 |
| 2765 private: | 2765 private: |
| 2766 BoxUint32x4Instr* instruction_; | 2766 BoxInt32x4Instr* instruction_; |
| 2767 }; | 2767 }; |
| 2768 | 2768 |
| 2769 | 2769 |
| 2770 void BoxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2770 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2771 BoxUint32x4SlowPath* slow_path = new BoxUint32x4SlowPath(this); | 2771 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); |
| 2772 compiler->AddSlowPathCode(slow_path); | 2772 compiler->AddSlowPathCode(slow_path); |
| 2773 | 2773 |
| 2774 Register out_reg = locs()->out().reg(); | 2774 Register out_reg = locs()->out().reg(); |
| 2775 XmmRegister value = locs()->in(0).fpu_reg(); | 2775 XmmRegister value = locs()->in(0).fpu_reg(); |
| 2776 | 2776 |
| 2777 __ TryAllocate(compiler->uint32x4_class(), | 2777 __ TryAllocate(compiler->int32x4_class(), |
| 2778 slow_path->entry_label(), | 2778 slow_path->entry_label(), |
| 2779 Assembler::kFarJump, | 2779 Assembler::kFarJump, |
| 2780 out_reg, | 2780 out_reg, |
| 2781 PP); | 2781 PP); |
| 2782 __ Bind(slow_path->exit_label()); | 2782 __ Bind(slow_path->exit_label()); |
| 2783 __ movups(FieldAddress(out_reg, Uint32x4::value_offset()), value); | 2783 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); |
| 2784 } | 2784 } |
| 2785 | 2785 |
| 2786 | 2786 |
| 2787 LocationSummary* UnboxUint32x4Instr::MakeLocationSummary() const { | 2787 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary() const { |
| 2788 const intptr_t kNumInputs = 1; | 2788 const intptr_t kNumInputs = 1; |
| 2789 const intptr_t kNumTemps = 0; | 2789 const intptr_t kNumTemps = 0; |
| 2790 LocationSummary* summary = | 2790 LocationSummary* summary = |
| 2791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2792 summary->set_in(0, Location::RequiresRegister()); | 2792 summary->set_in(0, Location::RequiresRegister()); |
| 2793 summary->set_out(Location::RequiresFpuRegister()); | 2793 summary->set_out(Location::RequiresFpuRegister()); |
| 2794 return summary; | 2794 return summary; |
| 2795 } | 2795 } |
| 2796 | 2796 |
| 2797 | 2797 |
| 2798 void UnboxUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2798 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2799 const intptr_t value_cid = value()->Type()->ToCid(); | 2799 const intptr_t value_cid = value()->Type()->ToCid(); |
| 2800 const Register value = locs()->in(0).reg(); | 2800 const Register value = locs()->in(0).reg(); |
| 2801 const XmmRegister result = locs()->out().fpu_reg(); | 2801 const XmmRegister result = locs()->out().fpu_reg(); |
| 2802 | 2802 |
| 2803 if (value_cid != kUint32x4Cid) { | 2803 if (value_cid != kInt32x4Cid) { |
| 2804 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 2804 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 2805 __ testq(value, Immediate(kSmiTagMask)); | 2805 __ testq(value, Immediate(kSmiTagMask)); |
| 2806 __ j(ZERO, deopt); | 2806 __ j(ZERO, deopt); |
| 2807 __ CompareClassId(value, kUint32x4Cid); | 2807 __ CompareClassId(value, kInt32x4Cid); |
| 2808 __ j(NOT_EQUAL, deopt); | 2808 __ j(NOT_EQUAL, deopt); |
| 2809 } | 2809 } |
| 2810 __ movups(result, FieldAddress(value, Uint32x4::value_offset())); | 2810 __ movups(result, FieldAddress(value, Int32x4::value_offset())); |
| 2811 } | 2811 } |
| 2812 | 2812 |
| 2813 | 2813 |
| 2814 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2814 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
| 2815 const intptr_t kNumInputs = 2; | 2815 const intptr_t kNumInputs = 2; |
| 2816 const intptr_t kNumTemps = 0; | 2816 const intptr_t kNumTemps = 0; |
| 2817 LocationSummary* summary = | 2817 LocationSummary* summary = |
| 2818 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2818 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2819 summary->set_in(0, Location::RequiresFpuRegister()); | 2819 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2820 summary->set_in(1, Location::RequiresFpuRegister()); | 2820 summary->set_in(1, Location::RequiresFpuRegister()); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2894 break; | 2894 break; |
| 2895 case MethodRecognizer::kFloat32x4ShuffleZ: | 2895 case MethodRecognizer::kFloat32x4ShuffleZ: |
| 2896 __ shufps(value, value, Immediate(0xAA)); | 2896 __ shufps(value, value, Immediate(0xAA)); |
| 2897 __ cvtss2sd(value, value); | 2897 __ cvtss2sd(value, value); |
| 2898 break; | 2898 break; |
| 2899 case MethodRecognizer::kFloat32x4ShuffleW: | 2899 case MethodRecognizer::kFloat32x4ShuffleW: |
| 2900 __ shufps(value, value, Immediate(0xFF)); | 2900 __ shufps(value, value, Immediate(0xFF)); |
| 2901 __ cvtss2sd(value, value); | 2901 __ cvtss2sd(value, value); |
| 2902 break; | 2902 break; |
| 2903 case MethodRecognizer::kFloat32x4Shuffle: | 2903 case MethodRecognizer::kFloat32x4Shuffle: |
| 2904 case MethodRecognizer::kUint32x4Shuffle: | 2904 case MethodRecognizer::kInt32x4Shuffle: |
| 2905 __ shufps(value, value, Immediate(mask_)); | 2905 __ shufps(value, value, Immediate(mask_)); |
| 2906 break; | 2906 break; |
| 2907 default: UNREACHABLE(); | 2907 default: UNREACHABLE(); |
| 2908 } | 2908 } |
| 2909 } | 2909 } |
| 2910 | 2910 |
| 2911 | 2911 |
| 2912 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { | 2912 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const { |
| 2913 const intptr_t kNumInputs = 2; | 2913 const intptr_t kNumInputs = 2; |
| 2914 const intptr_t kNumTemps = 0; | 2914 const intptr_t kNumTemps = 0; |
| 2915 LocationSummary* summary = | 2915 LocationSummary* summary = |
| 2916 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2916 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2917 summary->set_in(0, Location::RequiresFpuRegister()); | 2917 summary->set_in(0, Location::RequiresFpuRegister()); |
| 2918 summary->set_in(1, Location::RequiresFpuRegister()); | 2918 summary->set_in(1, Location::RequiresFpuRegister()); |
| 2919 summary->set_out(Location::SameAsFirstInput()); | 2919 summary->set_out(Location::SameAsFirstInput()); |
| 2920 return summary; | 2920 return summary; |
| 2921 } | 2921 } |
| 2922 | 2922 |
| 2923 | 2923 |
| 2924 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2924 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2925 XmmRegister left = locs()->in(0).fpu_reg(); | 2925 XmmRegister left = locs()->in(0).fpu_reg(); |
| 2926 XmmRegister right = locs()->in(1).fpu_reg(); | 2926 XmmRegister right = locs()->in(1).fpu_reg(); |
| 2927 | 2927 |
| 2928 ASSERT(locs()->out().fpu_reg() == left); | 2928 ASSERT(locs()->out().fpu_reg() == left); |
| 2929 switch (op_kind()) { | 2929 switch (op_kind()) { |
| 2930 case MethodRecognizer::kFloat32x4ShuffleMix: | 2930 case MethodRecognizer::kFloat32x4ShuffleMix: |
| 2931 case MethodRecognizer::kUint32x4ShuffleMix: | 2931 case MethodRecognizer::kInt32x4ShuffleMix: |
| 2932 __ shufps(left, right, Immediate(mask_)); | 2932 __ shufps(left, right, Immediate(mask_)); |
| 2933 break; | 2933 break; |
| 2934 default: UNREACHABLE(); | 2934 default: UNREACHABLE(); |
| 2935 } | 2935 } |
| 2936 } | 2936 } |
| 2937 | 2937 |
| 2938 | 2938 |
| 2939 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { | 2939 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const { |
| 2940 const intptr_t kNumInputs = 1; | 2940 const intptr_t kNumInputs = 1; |
| 2941 const intptr_t kNumTemps = 0; | 2941 const intptr_t kNumTemps = 0; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3274 __ movss(Address(RSP, 12), replacement); | 3274 __ movss(Address(RSP, 12), replacement); |
| 3275 // Move updated value into output register. | 3275 // Move updated value into output register. |
| 3276 __ movups(replacement, Address(RSP, 0)); | 3276 __ movups(replacement, Address(RSP, 0)); |
| 3277 __ AddImmediate(RSP, Immediate(16), PP); | 3277 __ AddImmediate(RSP, Immediate(16), PP); |
| 3278 break; | 3278 break; |
| 3279 default: UNREACHABLE(); | 3279 default: UNREACHABLE(); |
| 3280 } | 3280 } |
| 3281 } | 3281 } |
| 3282 | 3282 |
| 3283 | 3283 |
| 3284 LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const { | 3284 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary() const { |
| 3285 const intptr_t kNumInputs = 1; | 3285 const intptr_t kNumInputs = 1; |
| 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::RequiresFpuRegister()); | 3289 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3290 summary->set_out(Location::SameAsFirstInput()); | 3290 summary->set_out(Location::SameAsFirstInput()); |
| 3291 return summary; | 3291 return summary; |
| 3292 } | 3292 } |
| 3293 | 3293 |
| 3294 | 3294 |
| 3295 void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3295 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3296 // NOP. | 3296 // NOP. |
| 3297 } | 3297 } |
| 3298 | 3298 |
| 3299 | 3299 |
| 3300 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const { | 3300 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary() const { |
| 3301 const intptr_t kNumInputs = 4; | 3301 const intptr_t kNumInputs = 4; |
| 3302 const intptr_t kNumTemps = 1; | 3302 const intptr_t kNumTemps = 1; |
| 3303 LocationSummary* summary = | 3303 LocationSummary* summary = |
| 3304 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3304 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3305 summary->set_in(0, Location::RequiresRegister()); | 3305 summary->set_in(0, Location::RequiresRegister()); |
| 3306 summary->set_in(1, Location::RequiresRegister()); | 3306 summary->set_in(1, Location::RequiresRegister()); |
| 3307 summary->set_in(2, Location::RequiresRegister()); | 3307 summary->set_in(2, Location::RequiresRegister()); |
| 3308 summary->set_in(3, Location::RequiresRegister()); | 3308 summary->set_in(3, Location::RequiresRegister()); |
| 3309 summary->set_temp(0, Location::RequiresRegister()); | 3309 summary->set_temp(0, Location::RequiresRegister()); |
| 3310 summary->set_out(Location::RequiresFpuRegister()); | 3310 summary->set_out(Location::RequiresFpuRegister()); |
| 3311 return summary; | 3311 return summary; |
| 3312 } | 3312 } |
| 3313 | 3313 |
| 3314 | 3314 |
| 3315 void Uint32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3315 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3316 Register v0 = locs()->in(0).reg(); | 3316 Register v0 = locs()->in(0).reg(); |
| 3317 Register v1 = locs()->in(1).reg(); | 3317 Register v1 = locs()->in(1).reg(); |
| 3318 Register v2 = locs()->in(2).reg(); | 3318 Register v2 = locs()->in(2).reg(); |
| 3319 Register v3 = locs()->in(3).reg(); | 3319 Register v3 = locs()->in(3).reg(); |
| 3320 Register temp = locs()->temp(0).reg(); | 3320 Register temp = locs()->temp(0).reg(); |
| 3321 XmmRegister result = locs()->out().fpu_reg(); | 3321 XmmRegister result = locs()->out().fpu_reg(); |
| 3322 Label x_false, x_done; | 3322 Label x_false, x_done; |
| 3323 Label y_false, y_done; | 3323 Label y_false, y_done; |
| 3324 Label z_false, z_done; | 3324 Label z_false, z_done; |
| 3325 Label w_false, w_done; | 3325 Label w_false, w_done; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3359 __ Bind(&w_false); | 3359 __ Bind(&w_false); |
| 3360 __ LoadImmediate(temp, Immediate(0x0), PP); | 3360 __ LoadImmediate(temp, Immediate(0x0), PP); |
| 3361 __ Bind(&w_done); | 3361 __ Bind(&w_done); |
| 3362 __ movl(Address(RSP, 12), temp); | 3362 __ movl(Address(RSP, 12), temp); |
| 3363 | 3363 |
| 3364 __ movups(result, Address(RSP, 0)); | 3364 __ movups(result, Address(RSP, 0)); |
| 3365 __ AddImmediate(RSP, Immediate(16), PP); | 3365 __ AddImmediate(RSP, Immediate(16), PP); |
| 3366 } | 3366 } |
| 3367 | 3367 |
| 3368 | 3368 |
| 3369 LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const { | 3369 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary() const { |
| 3370 const intptr_t kNumInputs = 1; | 3370 const intptr_t kNumInputs = 1; |
| 3371 const intptr_t kNumTemps = 0; | 3371 const intptr_t kNumTemps = 0; |
| 3372 LocationSummary* summary = | 3372 LocationSummary* summary = |
| 3373 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3373 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3374 summary->set_in(0, Location::RequiresFpuRegister()); | 3374 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3375 summary->set_out(Location::RequiresRegister()); | 3375 summary->set_out(Location::RequiresRegister()); |
| 3376 return summary; | 3376 return summary; |
| 3377 } | 3377 } |
| 3378 | 3378 |
| 3379 | 3379 |
| 3380 void Uint32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3380 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3381 XmmRegister value = locs()->in(0).fpu_reg(); | 3381 XmmRegister value = locs()->in(0).fpu_reg(); |
| 3382 Register result = locs()->out().reg(); | 3382 Register result = locs()->out().reg(); |
| 3383 Label done; | 3383 Label done; |
| 3384 Label non_zero; | 3384 Label non_zero; |
| 3385 __ AddImmediate(RSP, Immediate(-16), PP); | 3385 __ AddImmediate(RSP, Immediate(-16), PP); |
| 3386 // Move value to stack. | 3386 // Move value to stack. |
| 3387 __ movups(Address(RSP, 0), value); | 3387 __ movups(Address(RSP, 0), value); |
| 3388 switch (op_kind()) { | 3388 switch (op_kind()) { |
| 3389 case MethodRecognizer::kUint32x4GetFlagX: | 3389 case MethodRecognizer::kInt32x4GetFlagX: |
| 3390 __ movl(result, Address(RSP, 0)); | 3390 __ movl(result, Address(RSP, 0)); |
| 3391 break; | 3391 break; |
| 3392 case MethodRecognizer::kUint32x4GetFlagY: | 3392 case MethodRecognizer::kInt32x4GetFlagY: |
| 3393 __ movl(result, Address(RSP, 4)); | 3393 __ movl(result, Address(RSP, 4)); |
| 3394 break; | 3394 break; |
| 3395 case MethodRecognizer::kUint32x4GetFlagZ: | 3395 case MethodRecognizer::kInt32x4GetFlagZ: |
| 3396 __ movl(result, Address(RSP, 8)); | 3396 __ movl(result, Address(RSP, 8)); |
| 3397 break; | 3397 break; |
| 3398 case MethodRecognizer::kUint32x4GetFlagW: | 3398 case MethodRecognizer::kInt32x4GetFlagW: |
| 3399 __ movl(result, Address(RSP, 12)); | 3399 __ movl(result, Address(RSP, 12)); |
| 3400 break; | 3400 break; |
| 3401 default: UNREACHABLE(); | 3401 default: UNREACHABLE(); |
| 3402 } | 3402 } |
| 3403 __ AddImmediate(RSP, Immediate(16), PP); | 3403 __ AddImmediate(RSP, Immediate(16), PP); |
| 3404 __ testl(result, result); | 3404 __ testl(result, result); |
| 3405 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); | 3405 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); |
| 3406 __ LoadObject(result, Bool::False(), PP); | 3406 __ LoadObject(result, Bool::False(), PP); |
| 3407 __ jmp(&done); | 3407 __ jmp(&done); |
| 3408 __ Bind(&non_zero); | 3408 __ Bind(&non_zero); |
| 3409 __ LoadObject(result, Bool::True(), PP); | 3409 __ LoadObject(result, Bool::True(), PP); |
| 3410 __ Bind(&done); | 3410 __ Bind(&done); |
| 3411 } | 3411 } |
| 3412 | 3412 |
| 3413 | 3413 |
| 3414 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const { | 3414 LocationSummary* Int32x4SelectInstr::MakeLocationSummary() const { |
| 3415 const intptr_t kNumInputs = 3; | 3415 const intptr_t kNumInputs = 3; |
| 3416 const intptr_t kNumTemps = 1; | 3416 const intptr_t kNumTemps = 1; |
| 3417 LocationSummary* summary = | 3417 LocationSummary* summary = |
| 3418 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3418 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3419 summary->set_in(0, Location::RequiresFpuRegister()); | 3419 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3420 summary->set_in(1, Location::RequiresFpuRegister()); | 3420 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3421 summary->set_in(2, Location::RequiresFpuRegister()); | 3421 summary->set_in(2, Location::RequiresFpuRegister()); |
| 3422 summary->set_temp(0, Location::RequiresFpuRegister()); | 3422 summary->set_temp(0, Location::RequiresFpuRegister()); |
| 3423 summary->set_out(Location::SameAsFirstInput()); | 3423 summary->set_out(Location::SameAsFirstInput()); |
| 3424 return summary; | 3424 return summary; |
| 3425 } | 3425 } |
| 3426 | 3426 |
| 3427 | 3427 |
| 3428 void Uint32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3428 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3429 XmmRegister mask = locs()->in(0).fpu_reg(); | 3429 XmmRegister mask = locs()->in(0).fpu_reg(); |
| 3430 XmmRegister trueValue = locs()->in(1).fpu_reg(); | 3430 XmmRegister trueValue = locs()->in(1).fpu_reg(); |
| 3431 XmmRegister falseValue = locs()->in(2).fpu_reg(); | 3431 XmmRegister falseValue = locs()->in(2).fpu_reg(); |
| 3432 XmmRegister out = locs()->out().fpu_reg(); | 3432 XmmRegister out = locs()->out().fpu_reg(); |
| 3433 XmmRegister temp = locs()->temp(0).fpu_reg(); | 3433 XmmRegister temp = locs()->temp(0).fpu_reg(); |
| 3434 ASSERT(out == mask); | 3434 ASSERT(out == mask); |
| 3435 // Copy mask. | 3435 // Copy mask. |
| 3436 __ movaps(temp, mask); | 3436 __ movaps(temp, mask); |
| 3437 // Invert it. | 3437 // Invert it. |
| 3438 __ notps(temp); | 3438 __ notps(temp); |
| 3439 // mask = mask & trueValue. | 3439 // mask = mask & trueValue. |
| 3440 __ andps(mask, trueValue); | 3440 __ andps(mask, trueValue); |
| 3441 // temp = temp & falseValue. | 3441 // temp = temp & falseValue. |
| 3442 __ andps(temp, falseValue); | 3442 __ andps(temp, falseValue); |
| 3443 // out = mask | temp. | 3443 // out = mask | temp. |
| 3444 __ orps(mask, temp); | 3444 __ orps(mask, temp); |
| 3445 } | 3445 } |
| 3446 | 3446 |
| 3447 | 3447 |
| 3448 LocationSummary* Uint32x4SetFlagInstr::MakeLocationSummary() const { | 3448 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary() const { |
| 3449 const intptr_t kNumInputs = 2; | 3449 const intptr_t kNumInputs = 2; |
| 3450 const intptr_t kNumTemps = 1; | 3450 const intptr_t kNumTemps = 1; |
| 3451 LocationSummary* summary = | 3451 LocationSummary* summary = |
| 3452 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3452 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3453 summary->set_in(0, Location::RequiresFpuRegister()); | 3453 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3454 summary->set_in(1, Location::RequiresRegister()); | 3454 summary->set_in(1, Location::RequiresRegister()); |
| 3455 summary->set_temp(0, Location::RequiresRegister()); | 3455 summary->set_temp(0, Location::RequiresRegister()); |
| 3456 summary->set_out(Location::SameAsFirstInput()); | 3456 summary->set_out(Location::SameAsFirstInput()); |
| 3457 return summary; | 3457 return summary; |
| 3458 } | 3458 } |
| 3459 | 3459 |
| 3460 | 3460 |
| 3461 void Uint32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3461 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3462 XmmRegister mask = locs()->in(0).fpu_reg(); | 3462 XmmRegister mask = locs()->in(0).fpu_reg(); |
| 3463 Register flag = locs()->in(1).reg(); | 3463 Register flag = locs()->in(1).reg(); |
| 3464 Register temp = locs()->temp(0).reg(); | 3464 Register temp = locs()->temp(0).reg(); |
| 3465 ASSERT(mask == locs()->out().fpu_reg()); | 3465 ASSERT(mask == locs()->out().fpu_reg()); |
| 3466 __ AddImmediate(RSP, Immediate(-16), PP); | 3466 __ AddImmediate(RSP, Immediate(-16), PP); |
| 3467 // Copy mask to stack. | 3467 // Copy mask to stack. |
| 3468 __ movups(Address(RSP, 0), mask); | 3468 __ movups(Address(RSP, 0), mask); |
| 3469 Label falsePath, exitPath; | 3469 Label falsePath, exitPath; |
| 3470 __ CompareObject(flag, Bool::True(), PP); | 3470 __ CompareObject(flag, Bool::True(), PP); |
| 3471 __ j(NOT_EQUAL, &falsePath); | 3471 __ j(NOT_EQUAL, &falsePath); |
| 3472 switch (op_kind()) { | 3472 switch (op_kind()) { |
| 3473 case MethodRecognizer::kUint32x4WithFlagX: | 3473 case MethodRecognizer::kInt32x4WithFlagX: |
| 3474 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); | 3474 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); |
| 3475 __ movl(Address(RSP, 0), temp); | 3475 __ movl(Address(RSP, 0), temp); |
| 3476 __ jmp(&exitPath); | 3476 __ jmp(&exitPath); |
| 3477 __ Bind(&falsePath); | 3477 __ Bind(&falsePath); |
| 3478 __ LoadImmediate(temp, Immediate(0x0), PP); | 3478 __ LoadImmediate(temp, Immediate(0x0), PP); |
| 3479 __ movl(Address(RSP, 0), temp); | 3479 __ movl(Address(RSP, 0), temp); |
| 3480 break; | 3480 break; |
| 3481 case MethodRecognizer::kUint32x4WithFlagY: | 3481 case MethodRecognizer::kInt32x4WithFlagY: |
| 3482 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); | 3482 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); |
| 3483 __ movl(Address(RSP, 4), temp); | 3483 __ movl(Address(RSP, 4), temp); |
| 3484 __ jmp(&exitPath); | 3484 __ jmp(&exitPath); |
| 3485 __ Bind(&falsePath); | 3485 __ Bind(&falsePath); |
| 3486 __ LoadImmediate(temp, Immediate(0x0), PP); | 3486 __ LoadImmediate(temp, Immediate(0x0), PP); |
| 3487 __ movl(Address(RSP, 4), temp); | 3487 __ movl(Address(RSP, 4), temp); |
| 3488 break; | 3488 break; |
| 3489 case MethodRecognizer::kUint32x4WithFlagZ: | 3489 case MethodRecognizer::kInt32x4WithFlagZ: |
| 3490 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); | 3490 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); |
| 3491 __ movl(Address(RSP, 8), temp); | 3491 __ movl(Address(RSP, 8), temp); |
| 3492 __ jmp(&exitPath); | 3492 __ jmp(&exitPath); |
| 3493 __ Bind(&falsePath); | 3493 __ Bind(&falsePath); |
| 3494 __ LoadImmediate(temp, Immediate(0x0), PP); | 3494 __ LoadImmediate(temp, Immediate(0x0), PP); |
| 3495 __ movl(Address(RSP, 8), temp); | 3495 __ movl(Address(RSP, 8), temp); |
| 3496 break; | 3496 break; |
| 3497 case MethodRecognizer::kUint32x4WithFlagW: | 3497 case MethodRecognizer::kInt32x4WithFlagW: |
| 3498 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); | 3498 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); |
| 3499 __ movl(Address(RSP, 12), temp); | 3499 __ movl(Address(RSP, 12), temp); |
| 3500 __ jmp(&exitPath); | 3500 __ jmp(&exitPath); |
| 3501 __ Bind(&falsePath); | 3501 __ Bind(&falsePath); |
| 3502 __ LoadImmediate(temp, Immediate(0x0), PP); | 3502 __ LoadImmediate(temp, Immediate(0x0), PP); |
| 3503 __ movl(Address(RSP, 12), temp); | 3503 __ movl(Address(RSP, 12), temp); |
| 3504 break; | 3504 break; |
| 3505 default: UNREACHABLE(); | 3505 default: UNREACHABLE(); |
| 3506 } | 3506 } |
| 3507 __ Bind(&exitPath); | 3507 __ Bind(&exitPath); |
| 3508 // Copy mask back to register. | 3508 // Copy mask back to register. |
| 3509 __ movups(mask, Address(RSP, 0)); | 3509 __ movups(mask, Address(RSP, 0)); |
| 3510 __ AddImmediate(RSP, Immediate(16), PP); | 3510 __ AddImmediate(RSP, Immediate(16), PP); |
| 3511 } | 3511 } |
| 3512 | 3512 |
| 3513 | 3513 |
| 3514 LocationSummary* Uint32x4ToFloat32x4Instr::MakeLocationSummary() const { | 3514 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary() const { |
| 3515 const intptr_t kNumInputs = 1; | 3515 const intptr_t kNumInputs = 1; |
| 3516 const intptr_t kNumTemps = 0; | 3516 const intptr_t kNumTemps = 0; |
| 3517 LocationSummary* summary = | 3517 LocationSummary* summary = |
| 3518 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3518 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3519 summary->set_in(0, Location::RequiresFpuRegister()); | 3519 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3520 summary->set_out(Location::SameAsFirstInput()); | 3520 summary->set_out(Location::SameAsFirstInput()); |
| 3521 return summary; | 3521 return summary; |
| 3522 } | 3522 } |
| 3523 | 3523 |
| 3524 | 3524 |
| 3525 void Uint32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3525 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3526 // NOP. | 3526 // NOP. |
| 3527 } | 3527 } |
| 3528 | 3528 |
| 3529 | 3529 |
| 3530 LocationSummary* BinaryUint32x4OpInstr::MakeLocationSummary() const { | 3530 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary() const { |
| 3531 const intptr_t kNumInputs = 2; | 3531 const intptr_t kNumInputs = 2; |
| 3532 const intptr_t kNumTemps = 0; | 3532 const intptr_t kNumTemps = 0; |
| 3533 LocationSummary* summary = | 3533 LocationSummary* summary = |
| 3534 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3534 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3535 summary->set_in(0, Location::RequiresFpuRegister()); | 3535 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3536 summary->set_in(1, Location::RequiresFpuRegister()); | 3536 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3537 summary->set_out(Location::SameAsFirstInput()); | 3537 summary->set_out(Location::SameAsFirstInput()); |
| 3538 return summary; | 3538 return summary; |
| 3539 } | 3539 } |
| 3540 | 3540 |
| 3541 | 3541 |
| 3542 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3542 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3543 XmmRegister left = locs()->in(0).fpu_reg(); | 3543 XmmRegister left = locs()->in(0).fpu_reg(); |
| 3544 XmmRegister right = locs()->in(1).fpu_reg(); | 3544 XmmRegister right = locs()->in(1).fpu_reg(); |
| 3545 ASSERT(left == locs()->out().fpu_reg()); | 3545 ASSERT(left == locs()->out().fpu_reg()); |
| 3546 switch (op_kind()) { | 3546 switch (op_kind()) { |
| 3547 case Token::kBIT_AND: { | 3547 case Token::kBIT_AND: { |
| 3548 __ andps(left, right); | 3548 __ andps(left, right); |
| 3549 break; | 3549 break; |
| 3550 } | 3550 } |
| 3551 case Token::kBIT_OR: { | 3551 case Token::kBIT_OR: { |
| 3552 __ orps(left, right); | 3552 __ orps(left, right); |
| (...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4523 PcDescriptors::kOther, | 4523 PcDescriptors::kOther, |
| 4524 locs()); | 4524 locs()); |
| 4525 __ Drop(2); // Discard type arguments and receiver. | 4525 __ Drop(2); // Discard type arguments and receiver. |
| 4526 } | 4526 } |
| 4527 | 4527 |
| 4528 } // namespace dart | 4528 } // namespace dart |
| 4529 | 4529 |
| 4530 #undef __ | 4530 #undef __ |
| 4531 | 4531 |
| 4532 #endif // defined TARGET_ARCH_X64 | 4532 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |