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

Side by Side Diff: runtime/vm/intermediate_language_x64.cc

Issue 172653002: Unbox/Box Float64x2 and inline typed array loads and stores (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_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 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 case kImmutableArrayCid: 762 case kImmutableArrayCid:
763 return CompileType::Dynamic(); 763 return CompileType::Dynamic();
764 764
765 case kTypedDataFloat32ArrayCid: 765 case kTypedDataFloat32ArrayCid:
766 case kTypedDataFloat64ArrayCid: 766 case kTypedDataFloat64ArrayCid:
767 return CompileType::FromCid(kDoubleCid); 767 return CompileType::FromCid(kDoubleCid);
768 case kTypedDataFloat32x4ArrayCid: 768 case kTypedDataFloat32x4ArrayCid:
769 return CompileType::FromCid(kFloat32x4Cid); 769 return CompileType::FromCid(kFloat32x4Cid);
770 case kTypedDataInt32x4ArrayCid: 770 case kTypedDataInt32x4ArrayCid:
771 return CompileType::FromCid(kInt32x4Cid); 771 return CompileType::FromCid(kInt32x4Cid);
772 case kTypedDataFloat64x2ArrayCid:
773 return CompileType::FromCid(kFloat64x2Cid);
772 774
773 case kTypedDataInt8ArrayCid: 775 case kTypedDataInt8ArrayCid:
774 case kTypedDataUint8ArrayCid: 776 case kTypedDataUint8ArrayCid:
775 case kTypedDataUint8ClampedArrayCid: 777 case kTypedDataUint8ClampedArrayCid:
776 case kExternalTypedDataUint8ArrayCid: 778 case kExternalTypedDataUint8ArrayCid:
777 case kExternalTypedDataUint8ClampedArrayCid: 779 case kExternalTypedDataUint8ClampedArrayCid:
778 case kTypedDataInt16ArrayCid: 780 case kTypedDataInt16ArrayCid:
779 case kTypedDataUint16ArrayCid: 781 case kTypedDataUint16ArrayCid:
780 case kOneByteStringCid: 782 case kOneByteStringCid:
781 case kTwoByteStringCid: 783 case kTwoByteStringCid:
(...skipping 24 matching lines...) Expand all
806 case kTypedDataInt32ArrayCid: 808 case kTypedDataInt32ArrayCid:
807 case kTypedDataUint32ArrayCid: 809 case kTypedDataUint32ArrayCid:
808 return kTagged; 810 return kTagged;
809 case kTypedDataFloat32ArrayCid: 811 case kTypedDataFloat32ArrayCid:
810 case kTypedDataFloat64ArrayCid: 812 case kTypedDataFloat64ArrayCid:
811 return kUnboxedDouble; 813 return kUnboxedDouble;
812 case kTypedDataInt32x4ArrayCid: 814 case kTypedDataInt32x4ArrayCid:
813 return kUnboxedInt32x4; 815 return kUnboxedInt32x4;
814 case kTypedDataFloat32x4ArrayCid: 816 case kTypedDataFloat32x4ArrayCid:
815 return kUnboxedFloat32x4; 817 return kUnboxedFloat32x4;
818 case kTypedDataFloat64x2ArrayCid:
819 return kUnboxedFloat64x2;
816 default: 820 default:
817 UNIMPLEMENTED(); 821 UNIMPLEMENTED();
818 return kTagged; 822 return kTagged;
819 } 823 }
820 } 824 }
821 825
822 826
823 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { 827 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const {
824 const intptr_t kNumInputs = 2; 828 const intptr_t kNumInputs = 2;
825 const intptr_t kNumTemps = 0; 829 const intptr_t kNumTemps = 0;
826 LocationSummary* locs = 830 LocationSummary* locs =
827 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 831 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
828 locs->set_in(0, Location::RequiresRegister()); 832 locs->set_in(0, Location::RequiresRegister());
829 // The smi index is either untagged (element size == 1), or it is left smi 833 // The smi index is either untagged (element size == 1), or it is left smi
830 // tagged (for all element sizes > 1). 834 // tagged (for all element sizes > 1).
831 if (index_scale() == 1) { 835 if (index_scale() == 1) {
832 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 836 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
833 ? Location::Constant( 837 ? Location::Constant(
834 index()->definition()->AsConstant()->value()) 838 index()->definition()->AsConstant()->value())
835 : Location::WritableRegister()); 839 : Location::WritableRegister());
836 } else { 840 } else {
837 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 841 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
838 ? Location::Constant( 842 ? Location::Constant(
839 index()->definition()->AsConstant()->value()) 843 index()->definition()->AsConstant()->value())
840 : Location::RequiresRegister()); 844 : Location::RequiresRegister());
841 } 845 }
842 if ((representation() == kUnboxedDouble) || 846 if ((representation() == kUnboxedDouble) ||
843 (representation() == kUnboxedFloat32x4) || 847 (representation() == kUnboxedFloat32x4) ||
844 (representation() == kUnboxedInt32x4)) { 848 (representation() == kUnboxedInt32x4) ||
849 (representation() == kUnboxedFloat64x2)) {
845 locs->set_out(Location::RequiresFpuRegister()); 850 locs->set_out(Location::RequiresFpuRegister());
846 } else { 851 } else {
847 locs->set_out(Location::RequiresRegister()); 852 locs->set_out(Location::RequiresRegister());
848 } 853 }
849 return locs; 854 return locs;
850 } 855 }
851 856
852 857
853 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 858 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
854 Register array = locs()->in(0).reg(); 859 Register array = locs()->in(0).reg();
(...skipping 12 matching lines...) Expand all
867 } else { 872 } else {
868 ASSERT(this->array()->definition()->representation() == kTagged); 873 ASSERT(this->array()->definition()->representation() == kTagged);
869 element_address = index.IsRegister() 874 element_address = index.IsRegister()
870 ? FlowGraphCompiler::ElementAddressForRegIndex( 875 ? FlowGraphCompiler::ElementAddressForRegIndex(
871 class_id(), index_scale(), array, index.reg()) 876 class_id(), index_scale(), array, index.reg())
872 : FlowGraphCompiler::ElementAddressForIntIndex( 877 : FlowGraphCompiler::ElementAddressForIntIndex(
873 class_id(), index_scale(), array, 878 class_id(), index_scale(), array,
874 Smi::Cast(index.constant()).Value()); 879 Smi::Cast(index.constant()).Value());
875 } 880 }
876 881
877 if ((representation() == kUnboxedDouble) || 882 if ((representation() == kUnboxedDouble) ||
878 (representation() == kUnboxedFloat32x4) || 883 (representation() == kUnboxedFloat32x4) ||
879 (representation() == kUnboxedInt32x4)) { 884 (representation() == kUnboxedInt32x4) ||
885 (representation() == kUnboxedFloat64x2)) {
880 if ((index_scale() == 1) && index.IsRegister()) { 886 if ((index_scale() == 1) && index.IsRegister()) {
881 __ SmiUntag(index.reg()); 887 __ SmiUntag(index.reg());
882 } 888 }
883 889
884 XmmRegister result = locs()->out().fpu_reg(); 890 XmmRegister result = locs()->out().fpu_reg();
885 if (class_id() == kTypedDataFloat32ArrayCid) { 891 if (class_id() == kTypedDataFloat32ArrayCid) {
886 // Load single precision float. 892 // Load single precision float.
887 __ movss(result, element_address); 893 __ movss(result, element_address);
888 // Promote to double. 894 // Promote to double.
889 __ cvtss2sd(result, locs()->out().fpu_reg()); 895 __ cvtss2sd(result, locs()->out().fpu_reg());
890 } else if (class_id() == kTypedDataFloat64ArrayCid) { 896 } else if (class_id() == kTypedDataFloat64ArrayCid) {
891 __ movsd(result, element_address); 897 __ movsd(result, element_address);
892 } else { 898 } else {
893 ASSERT((class_id() == kTypedDataInt32x4ArrayCid) || 899 ASSERT((class_id() == kTypedDataInt32x4ArrayCid) ||
894 (class_id() == kTypedDataFloat32x4ArrayCid)); 900 (class_id() == kTypedDataFloat32x4ArrayCid) ||
901 (class_id() == kTypedDataFloat64x2ArrayCid));
895 __ movups(result, element_address); 902 __ movups(result, element_address);
896 } 903 }
897 return; 904 return;
898 } 905 }
899 906
900 if ((index_scale() == 1) && index.IsRegister()) { 907 if ((index_scale() == 1) && index.IsRegister()) {
901 __ SmiUntag(index.reg()); 908 __ SmiUntag(index.reg());
902 } 909 }
903 Register result = locs()->out().reg(); 910 Register result = locs()->out().reg();
904 switch (class_id()) { 911 switch (class_id()) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 case kTypedDataInt32ArrayCid: 964 case kTypedDataInt32ArrayCid:
958 case kTypedDataUint32ArrayCid: 965 case kTypedDataUint32ArrayCid:
959 return kTagged; 966 return kTagged;
960 case kTypedDataFloat32ArrayCid: 967 case kTypedDataFloat32ArrayCid:
961 case kTypedDataFloat64ArrayCid: 968 case kTypedDataFloat64ArrayCid:
962 return kUnboxedDouble; 969 return kUnboxedDouble;
963 case kTypedDataFloat32x4ArrayCid: 970 case kTypedDataFloat32x4ArrayCid:
964 return kUnboxedFloat32x4; 971 return kUnboxedFloat32x4;
965 case kTypedDataInt32x4ArrayCid: 972 case kTypedDataInt32x4ArrayCid:
966 return kUnboxedInt32x4; 973 return kUnboxedInt32x4;
974 case kTypedDataFloat64x2ArrayCid:
975 return kUnboxedFloat64x2;
967 default: 976 default:
968 UNIMPLEMENTED(); 977 UNIMPLEMENTED();
969 return kTagged; 978 return kTagged;
970 } 979 }
971 } 980 }
972 981
973 982
974 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { 983 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const {
975 const intptr_t kNumInputs = 3; 984 const intptr_t kNumInputs = 3;
976 const intptr_t kNumTemps = 0; 985 const intptr_t kNumTemps = 0;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 break; 1024 break;
1016 case kTypedDataFloat32ArrayCid: 1025 case kTypedDataFloat32ArrayCid:
1017 // Need temp register for float-to-double conversion. 1026 // Need temp register for float-to-double conversion.
1018 locs->AddTemp(Location::RequiresFpuRegister()); 1027 locs->AddTemp(Location::RequiresFpuRegister());
1019 // Fall through. 1028 // Fall through.
1020 case kTypedDataFloat64ArrayCid: 1029 case kTypedDataFloat64ArrayCid:
1021 // TODO(srdjan): Support Float64 constants. 1030 // TODO(srdjan): Support Float64 constants.
1022 locs->set_in(2, Location::RequiresFpuRegister()); 1031 locs->set_in(2, Location::RequiresFpuRegister());
1023 break; 1032 break;
1024 case kTypedDataInt32x4ArrayCid: 1033 case kTypedDataInt32x4ArrayCid:
1034 case kTypedDataFloat64x2ArrayCid:
1025 case kTypedDataFloat32x4ArrayCid: 1035 case kTypedDataFloat32x4ArrayCid:
1026 locs->set_in(2, Location::RequiresFpuRegister()); 1036 locs->set_in(2, Location::RequiresFpuRegister());
1027 break; 1037 break;
1028 default: 1038 default:
1029 UNREACHABLE(); 1039 UNREACHABLE();
1030 return NULL; 1040 return NULL;
1031 } 1041 }
1032 return locs; 1042 return locs;
1033 } 1043 }
1034 1044
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 case kTypedDataFloat32ArrayCid: 1143 case kTypedDataFloat32ArrayCid:
1134 // Convert to single precision. 1144 // Convert to single precision.
1135 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); 1145 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
1136 // Store. 1146 // Store.
1137 __ movss(element_address, locs()->temp(0).fpu_reg()); 1147 __ movss(element_address, locs()->temp(0).fpu_reg());
1138 break; 1148 break;
1139 case kTypedDataFloat64ArrayCid: 1149 case kTypedDataFloat64ArrayCid:
1140 __ movsd(element_address, locs()->in(2).fpu_reg()); 1150 __ movsd(element_address, locs()->in(2).fpu_reg());
1141 break; 1151 break;
1142 case kTypedDataInt32x4ArrayCid: 1152 case kTypedDataInt32x4ArrayCid:
1153 case kTypedDataFloat64x2ArrayCid:
1143 case kTypedDataFloat32x4ArrayCid: 1154 case kTypedDataFloat32x4ArrayCid:
1144 __ movups(element_address, locs()->in(2).fpu_reg()); 1155 __ movups(element_address, locs()->in(2).fpu_reg());
1145 break; 1156 break;
1146 default: 1157 default:
1147 UNREACHABLE(); 1158 UNREACHABLE();
1148 } 1159 }
1149 } 1160 }
1150 1161
1151 1162
1152 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { 1163 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const {
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
1880 compiler->RestoreLiveRegisters(locs); 1891 compiler->RestoreLiveRegisters(locs);
1881 1892
1882 __ jmp(exit_label()); 1893 __ jmp(exit_label());
1883 } 1894 }
1884 1895
1885 private: 1896 private:
1886 Instruction* instruction_; 1897 Instruction* instruction_;
1887 }; 1898 };
1888 1899
1889 1900
1901 class BoxFloat64x2SlowPath : public SlowPathCode {
1902 public:
1903 explicit BoxFloat64x2SlowPath(Instruction* instruction)
1904 : instruction_(instruction) { }
1905
1906 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1907 __ Comment("BoxFloat64x2SlowPath");
1908 __ Bind(entry_label());
1909 const Class& float64x2_class = compiler->float64x2_class();
1910 const Code& stub =
1911 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class));
1912 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint());
1913
1914 LocationSummary* locs = instruction_->locs();
1915 locs->live_registers()->Remove(locs->out());
1916
1917 compiler->SaveLiveRegisters(locs);
1918 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1919 &label,
1920 PcDescriptors::kOther,
1921 locs);
1922 __ MoveRegister(locs->out().reg(), RAX);
1923 compiler->RestoreLiveRegisters(locs);
1924
1925 __ jmp(exit_label());
1926 }
1927
1928 private:
1929 Instruction* instruction_;
1930 };
1931
1932
1890 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 1933 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
1891 const intptr_t kNumInputs = 1; 1934 const intptr_t kNumInputs = 1;
1892 const intptr_t kNumTemps = 0; 1935 const intptr_t kNumTemps = 0;
1893 LocationSummary* locs = 1936 LocationSummary* locs =
1894 new LocationSummary( 1937 new LocationSummary(
1895 kNumInputs, kNumTemps, 1938 kNumInputs, kNumTemps,
1896 (opt && !IsPotentialUnboxedLoad()) 1939 (opt && !IsPotentialUnboxedLoad())
1897 ? LocationSummary::kNoCall 1940 ? LocationSummary::kNoCall
1898 : LocationSummary::kCallOnSlowPath); 1941 : LocationSummary::kCallOnSlowPath);
1899 1942
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after
3024 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3067 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3025 __ testq(value, Immediate(kSmiTagMask)); 3068 __ testq(value, Immediate(kSmiTagMask));
3026 __ j(ZERO, deopt); 3069 __ j(ZERO, deopt);
3027 __ CompareClassId(value, kFloat32x4Cid); 3070 __ CompareClassId(value, kFloat32x4Cid);
3028 __ j(NOT_EQUAL, deopt); 3071 __ j(NOT_EQUAL, deopt);
3029 } 3072 }
3030 __ movups(result, FieldAddress(value, Float32x4::value_offset())); 3073 __ movups(result, FieldAddress(value, Float32x4::value_offset()));
3031 } 3074 }
3032 3075
3033 3076
3077 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3078 const intptr_t kNumInputs = 1;
3079 const intptr_t kNumTemps = 0;
3080 LocationSummary* summary =
3081 new LocationSummary(kNumInputs,
3082 kNumTemps,
3083 LocationSummary::kCallOnSlowPath);
3084 summary->set_in(0, Location::RequiresFpuRegister());
3085 summary->set_out(Location::RequiresRegister());
3086 return summary;
3087 }
3088
3089
3090 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3091 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this);
3092 compiler->AddSlowPathCode(slow_path);
3093
3094 Register out_reg = locs()->out().reg();
3095 XmmRegister value = locs()->in(0).fpu_reg();
3096
3097 __ TryAllocate(compiler->float64x2_class(),
3098 slow_path->entry_label(),
3099 Assembler::kFarJump,
3100 out_reg,
3101 kNoRegister);
3102 __ Bind(slow_path->exit_label());
3103 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value);
3104 }
3105
3106
3107 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3108 const intptr_t value_cid = value()->Type()->ToCid();
3109 const intptr_t kNumInputs = 1;
3110 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
3111 LocationSummary* summary =
3112 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3113 summary->set_in(0, Location::RequiresRegister());
3114 summary->set_out(Location::RequiresFpuRegister());
3115 return summary;
3116 }
3117
3118
3119 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3120 const intptr_t value_cid = value()->Type()->ToCid();
3121 const Register value = locs()->in(0).reg();
3122 const XmmRegister result = locs()->out().fpu_reg();
3123
3124 if (value_cid != kFloat64x2Cid) {
3125 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3126 __ testq(value, Immediate(kSmiTagMask));
3127 __ j(ZERO, deopt);
3128 __ CompareClassId(value, kFloat64x2Cid);
3129 __ j(NOT_EQUAL, deopt);
3130 }
3131 __ movups(result, FieldAddress(value, Float64x2::value_offset()));
3132 }
3133
3134
3034 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { 3135 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
3035 const intptr_t kNumInputs = 1; 3136 const intptr_t kNumInputs = 1;
3036 const intptr_t kNumTemps = 0; 3137 const intptr_t kNumTemps = 0;
3037 LocationSummary* summary = 3138 LocationSummary* summary =
3038 new LocationSummary(kNumInputs, 3139 new LocationSummary(kNumInputs,
3039 kNumTemps, 3140 kNumTemps,
3040 LocationSummary::kCallOnSlowPath); 3141 LocationSummary::kCallOnSlowPath);
3041 summary->set_in(0, Location::RequiresFpuRegister()); 3142 summary->set_in(0, Location::RequiresFpuRegister());
3042 summary->set_out(Location::RequiresRegister()); 3143 summary->set_out(Location::RequiresRegister());
3043 return summary; 3144 return summary;
(...skipping 1946 matching lines...) Expand 10 before | Expand all | Expand 10 after
4990 PcDescriptors::kOther, 5091 PcDescriptors::kOther,
4991 locs()); 5092 locs());
4992 __ Drop(2); // Discard type arguments and receiver. 5093 __ Drop(2); // Discard type arguments and receiver.
4993 } 5094 }
4994 5095
4995 } // namespace dart 5096 } // namespace dart
4996 5097
4997 #undef __ 5098 #undef __
4998 5099
4999 #endif // defined TARGET_ARCH_X64 5100 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698