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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_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 816 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 case kImmutableArrayCid: 827 case kImmutableArrayCid:
828 return CompileType::Dynamic(); 828 return CompileType::Dynamic();
829 829
830 case kTypedDataFloat32ArrayCid: 830 case kTypedDataFloat32ArrayCid:
831 case kTypedDataFloat64ArrayCid: 831 case kTypedDataFloat64ArrayCid:
832 return CompileType::FromCid(kDoubleCid); 832 return CompileType::FromCid(kDoubleCid);
833 case kTypedDataFloat32x4ArrayCid: 833 case kTypedDataFloat32x4ArrayCid:
834 return CompileType::FromCid(kFloat32x4Cid); 834 return CompileType::FromCid(kFloat32x4Cid);
835 case kTypedDataInt32x4ArrayCid: 835 case kTypedDataInt32x4ArrayCid:
836 return CompileType::FromCid(kInt32x4Cid); 836 return CompileType::FromCid(kInt32x4Cid);
837 case kTypedDataFloat64x2ArrayCid:
838 return CompileType::FromCid(kFloat64x2Cid);
837 839
838 case kTypedDataInt8ArrayCid: 840 case kTypedDataInt8ArrayCid:
839 case kTypedDataUint8ArrayCid: 841 case kTypedDataUint8ArrayCid:
840 case kTypedDataUint8ClampedArrayCid: 842 case kTypedDataUint8ClampedArrayCid:
841 case kExternalTypedDataUint8ArrayCid: 843 case kExternalTypedDataUint8ArrayCid:
842 case kExternalTypedDataUint8ClampedArrayCid: 844 case kExternalTypedDataUint8ClampedArrayCid:
843 case kTypedDataInt16ArrayCid: 845 case kTypedDataInt16ArrayCid:
844 case kTypedDataUint16ArrayCid: 846 case kTypedDataUint16ArrayCid:
845 case kOneByteStringCid: 847 case kOneByteStringCid:
846 case kTwoByteStringCid: 848 case kTwoByteStringCid:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 // Instruction can deoptimize if we optimistically assumed that the result 882 // Instruction can deoptimize if we optimistically assumed that the result
881 // fits into Smi. 883 // fits into Smi.
882 return CanDeoptimize() ? kTagged : kUnboxedMint; 884 return CanDeoptimize() ? kTagged : kUnboxedMint;
883 case kTypedDataFloat32ArrayCid: 885 case kTypedDataFloat32ArrayCid:
884 case kTypedDataFloat64ArrayCid: 886 case kTypedDataFloat64ArrayCid:
885 return kUnboxedDouble; 887 return kUnboxedDouble;
886 case kTypedDataFloat32x4ArrayCid: 888 case kTypedDataFloat32x4ArrayCid:
887 return kUnboxedFloat32x4; 889 return kUnboxedFloat32x4;
888 case kTypedDataInt32x4ArrayCid: 890 case kTypedDataInt32x4ArrayCid:
889 return kUnboxedInt32x4; 891 return kUnboxedInt32x4;
892 case kTypedDataFloat64x2ArrayCid:
893 return kUnboxedFloat64x2;
890 default: 894 default:
891 UNIMPLEMENTED(); 895 UNIMPLEMENTED();
892 return kTagged; 896 return kTagged;
893 } 897 }
894 } 898 }
895 899
896 900
897 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { 901 LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const {
898 const intptr_t kNumInputs = 2; 902 const intptr_t kNumInputs = 2;
899 const intptr_t kNumTemps = 0; 903 const intptr_t kNumTemps = 0;
900 LocationSummary* locs = 904 LocationSummary* locs =
901 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 905 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
902 locs->set_in(0, Location::RequiresRegister()); 906 locs->set_in(0, Location::RequiresRegister());
903 if (CanBeImmediateIndex(index(), class_id())) { 907 if (CanBeImmediateIndex(index(), class_id())) {
904 // CanBeImmediateIndex must return false for unsafe smis. 908 // CanBeImmediateIndex must return false for unsafe smis.
905 locs->set_in(1, Location::Constant(index()->BoundConstant())); 909 locs->set_in(1, Location::Constant(index()->BoundConstant()));
906 } else { 910 } else {
907 // The index is either untagged (element size == 1) or a smi (for all 911 // The index is either untagged (element size == 1) or a smi (for all
908 // element sizes > 1). 912 // element sizes > 1).
909 locs->set_in(1, (index_scale() == 1) 913 locs->set_in(1, (index_scale() == 1)
910 ? Location::WritableRegister() 914 ? Location::WritableRegister()
911 : Location::RequiresRegister()); 915 : Location::RequiresRegister());
912 } 916 }
913 if ((representation() == kUnboxedDouble) || 917 if ((representation() == kUnboxedDouble) ||
914 (representation() == kUnboxedFloat32x4) || 918 (representation() == kUnboxedFloat32x4) ||
915 (representation() == kUnboxedInt32x4)) { 919 (representation() == kUnboxedInt32x4) ||
920 (representation() == kUnboxedFloat64x2)) {
916 locs->set_out(Location::RequiresFpuRegister()); 921 locs->set_out(Location::RequiresFpuRegister());
917 } else { 922 } else {
918 locs->set_out(Location::RequiresRegister()); 923 locs->set_out(Location::RequiresRegister());
919 } 924 }
920 return locs; 925 return locs;
921 } 926 }
922 927
923 928
924 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 929 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
925 Register array = locs()->in(0).reg(); 930 Register array = locs()->in(0).reg();
(...skipping 12 matching lines...) Expand all
938 ? FlowGraphCompiler::ElementAddressForRegIndex( 943 ? FlowGraphCompiler::ElementAddressForRegIndex(
939 class_id(), index_scale(), array, index.reg()) 944 class_id(), index_scale(), array, index.reg())
940 : FlowGraphCompiler::ElementAddressForIntIndex( 945 : FlowGraphCompiler::ElementAddressForIntIndex(
941 class_id(), index_scale(), array, 946 class_id(), index_scale(), array,
942 Smi::Cast(index.constant()).Value()); 947 Smi::Cast(index.constant()).Value());
943 } 948 }
944 949
945 if ((representation() == kUnboxedDouble) || 950 if ((representation() == kUnboxedDouble) ||
946 (representation() == kUnboxedMint) || 951 (representation() == kUnboxedMint) ||
947 (representation() == kUnboxedFloat32x4) || 952 (representation() == kUnboxedFloat32x4) ||
948 (representation() == kUnboxedInt32x4)) { 953 (representation() == kUnboxedInt32x4) ||
954 (representation() == kUnboxedFloat64x2)) {
949 XmmRegister result = locs()->out().fpu_reg(); 955 XmmRegister result = locs()->out().fpu_reg();
950 if ((index_scale() == 1) && index.IsRegister()) { 956 if ((index_scale() == 1) && index.IsRegister()) {
951 __ SmiUntag(index.reg()); 957 __ SmiUntag(index.reg());
952 } 958 }
953 switch (class_id()) { 959 switch (class_id()) {
954 case kTypedDataInt32ArrayCid: 960 case kTypedDataInt32ArrayCid:
955 __ movss(result, element_address); 961 __ movss(result, element_address);
956 __ pmovsxdq(result, result); 962 __ pmovsxdq(result, result);
957 break; 963 break;
958 case kTypedDataUint32ArrayCid: 964 case kTypedDataUint32ArrayCid:
959 __ xorpd(result, result); 965 __ xorpd(result, result);
960 __ movss(result, element_address); 966 __ movss(result, element_address);
961 break; 967 break;
962 case kTypedDataFloat32ArrayCid: 968 case kTypedDataFloat32ArrayCid:
963 // Load single precision float and promote to double. 969 // Load single precision float and promote to double.
964 __ movss(result, element_address); 970 __ movss(result, element_address);
965 __ cvtss2sd(result, locs()->out().fpu_reg()); 971 __ cvtss2sd(result, locs()->out().fpu_reg());
966 break; 972 break;
967 case kTypedDataFloat64ArrayCid: 973 case kTypedDataFloat64ArrayCid:
968 __ movsd(result, element_address); 974 __ movsd(result, element_address);
969 break; 975 break;
970 case kTypedDataInt32x4ArrayCid: 976 case kTypedDataInt32x4ArrayCid:
971 case kTypedDataFloat32x4ArrayCid: 977 case kTypedDataFloat32x4ArrayCid:
978 case kTypedDataFloat64x2ArrayCid:
972 __ movups(result, element_address); 979 __ movups(result, element_address);
973 break; 980 break;
974 } 981 }
975 return; 982 return;
976 } 983 }
977 984
978 Register result = locs()->out().reg(); 985 Register result = locs()->out().reg();
979 if ((index_scale() == 1) && index.IsRegister()) { 986 if ((index_scale() == 1) && index.IsRegister()) {
980 __ SmiUntag(index.reg()); 987 __ SmiUntag(index.reg());
981 } 988 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 case kTypedDataInt32ArrayCid: 1056 case kTypedDataInt32ArrayCid:
1050 case kTypedDataUint32ArrayCid: 1057 case kTypedDataUint32ArrayCid:
1051 return value()->IsSmiValue() ? kTagged : kUnboxedMint; 1058 return value()->IsSmiValue() ? kTagged : kUnboxedMint;
1052 case kTypedDataFloat32ArrayCid: 1059 case kTypedDataFloat32ArrayCid:
1053 case kTypedDataFloat64ArrayCid: 1060 case kTypedDataFloat64ArrayCid:
1054 return kUnboxedDouble; 1061 return kUnboxedDouble;
1055 case kTypedDataFloat32x4ArrayCid: 1062 case kTypedDataFloat32x4ArrayCid:
1056 return kUnboxedFloat32x4; 1063 return kUnboxedFloat32x4;
1057 case kTypedDataInt32x4ArrayCid: 1064 case kTypedDataInt32x4ArrayCid:
1058 return kUnboxedInt32x4; 1065 return kUnboxedInt32x4;
1066 case kTypedDataFloat64x2ArrayCid:
1067 return kUnboxedFloat64x2;
1059 default: 1068 default:
1060 UNIMPLEMENTED(); 1069 UNIMPLEMENTED();
1061 return kTagged; 1070 return kTagged;
1062 } 1071 }
1063 } 1072 }
1064 1073
1065 1074
1066 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { 1075 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const {
1067 const intptr_t kNumInputs = 3; 1076 const intptr_t kNumInputs = 3;
1068 const intptr_t kNumTemps = 0; 1077 const intptr_t kNumTemps = 0;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 case kTypedDataFloat32ArrayCid: 1120 case kTypedDataFloat32ArrayCid:
1112 // Need temp register for float-to-double conversion. 1121 // Need temp register for float-to-double conversion.
1113 locs->AddTemp(Location::RequiresFpuRegister()); 1122 locs->AddTemp(Location::RequiresFpuRegister());
1114 // Fall through. 1123 // Fall through.
1115 case kTypedDataFloat64ArrayCid: 1124 case kTypedDataFloat64ArrayCid:
1116 // TODO(srdjan): Support Float64 constants. 1125 // TODO(srdjan): Support Float64 constants.
1117 locs->set_in(2, Location::RequiresFpuRegister()); 1126 locs->set_in(2, Location::RequiresFpuRegister());
1118 break; 1127 break;
1119 case kTypedDataInt32x4ArrayCid: 1128 case kTypedDataInt32x4ArrayCid:
1120 case kTypedDataFloat32x4ArrayCid: 1129 case kTypedDataFloat32x4ArrayCid:
1130 case kTypedDataFloat64x2ArrayCid:
1121 locs->set_in(2, Location::RequiresFpuRegister()); 1131 locs->set_in(2, Location::RequiresFpuRegister());
1122 break; 1132 break;
1123 default: 1133 default:
1124 UNREACHABLE(); 1134 UNREACHABLE();
1125 return NULL; 1135 return NULL;
1126 } 1136 }
1127 return locs; 1137 return locs;
1128 } 1138 }
1129 1139
1130 1140
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 // Convert to single precision. 1242 // Convert to single precision.
1233 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); 1243 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
1234 // Store. 1244 // Store.
1235 __ movss(element_address, locs()->temp(0).fpu_reg()); 1245 __ movss(element_address, locs()->temp(0).fpu_reg());
1236 break; 1246 break;
1237 case kTypedDataFloat64ArrayCid: 1247 case kTypedDataFloat64ArrayCid:
1238 __ movsd(element_address, locs()->in(2).fpu_reg()); 1248 __ movsd(element_address, locs()->in(2).fpu_reg());
1239 break; 1249 break;
1240 case kTypedDataInt32x4ArrayCid: 1250 case kTypedDataInt32x4ArrayCid:
1241 case kTypedDataFloat32x4ArrayCid: 1251 case kTypedDataFloat32x4ArrayCid:
1252 case kTypedDataFloat64x2ArrayCid:
1242 __ movups(element_address, locs()->in(2).fpu_reg()); 1253 __ movups(element_address, locs()->in(2).fpu_reg());
1243 break; 1254 break;
1244 default: 1255 default:
1245 UNREACHABLE(); 1256 UNREACHABLE();
1246 } 1257 }
1247 } 1258 }
1248 1259
1249 1260
1250 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { 1261 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const {
1251 const intptr_t kNumInputs = 1; 1262 const intptr_t kNumInputs = 1;
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
1988 compiler->RestoreLiveRegisters(locs); 1999 compiler->RestoreLiveRegisters(locs);
1989 2000
1990 __ jmp(exit_label()); 2001 __ jmp(exit_label());
1991 } 2002 }
1992 2003
1993 private: 2004 private:
1994 Instruction* instruction_; 2005 Instruction* instruction_;
1995 }; 2006 };
1996 2007
1997 2008
2009 class BoxFloat64x2SlowPath : public SlowPathCode {
2010 public:
2011 explicit BoxFloat64x2SlowPath(Instruction* instruction)
2012 : instruction_(instruction) { }
2013
2014 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2015 __ Comment("BoxFloat64x2SlowPath");
2016 __ Bind(entry_label());
2017 const Class& float64x2_class = compiler->float64x2_class();
2018 const Code& stub =
2019 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class));
2020 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint());
2021
2022 LocationSummary* locs = instruction_->locs();
2023 locs->live_registers()->Remove(locs->out());
2024
2025 compiler->SaveLiveRegisters(locs);
2026 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2027 &label,
2028 PcDescriptors::kOther,
2029 locs);
2030 __ MoveRegister(locs->out().reg(), EAX);
2031 compiler->RestoreLiveRegisters(locs);
2032
2033 __ jmp(exit_label());
2034 }
2035
2036 private:
2037 Instruction* instruction_;
2038 };
2039
1998 2040
1999 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 2041 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
2000 const intptr_t kNumInputs = 1; 2042 const intptr_t kNumInputs = 1;
2001 const intptr_t kNumTemps = 0; 2043 const intptr_t kNumTemps = 0;
2002 LocationSummary* locs = 2044 LocationSummary* locs =
2003 new LocationSummary( 2045 new LocationSummary(
2004 kNumInputs, kNumTemps, 2046 kNumInputs, kNumTemps,
2005 (opt && !IsPotentialUnboxedLoad()) 2047 (opt && !IsPotentialUnboxedLoad())
2006 ? LocationSummary::kNoCall 2048 ? LocationSummary::kNoCall
2007 : LocationSummary::kCallOnSlowPath); 2049 : LocationSummary::kCallOnSlowPath);
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
3035 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3077 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3036 __ testl(value, Immediate(kSmiTagMask)); 3078 __ testl(value, Immediate(kSmiTagMask));
3037 __ j(ZERO, deopt); 3079 __ j(ZERO, deopt);
3038 __ CompareClassId(value, kFloat32x4Cid, temp); 3080 __ CompareClassId(value, kFloat32x4Cid, temp);
3039 __ j(NOT_EQUAL, deopt); 3081 __ j(NOT_EQUAL, deopt);
3040 } 3082 }
3041 __ movups(result, FieldAddress(value, Float32x4::value_offset())); 3083 __ movups(result, FieldAddress(value, Float32x4::value_offset()));
3042 } 3084 }
3043 3085
3044 3086
3087 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3088 const intptr_t kNumInputs = 1;
3089 const intptr_t kNumTemps = 0;
3090 LocationSummary* summary =
3091 new LocationSummary(kNumInputs,
3092 kNumTemps,
3093 LocationSummary::kCallOnSlowPath);
3094 summary->set_in(0, Location::RequiresFpuRegister());
3095 summary->set_out(Location::RequiresRegister());
3096 return summary;
3097 }
3098
3099
3100 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3101 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this);
3102 compiler->AddSlowPathCode(slow_path);
3103
3104 Register out_reg = locs()->out().reg();
3105 XmmRegister value = locs()->in(0).fpu_reg();
3106
3107 __ TryAllocate(compiler->float64x2_class(),
3108 slow_path->entry_label(),
3109 Assembler::kFarJump,
3110 out_reg,
3111 kNoRegister);
3112 __ Bind(slow_path->exit_label());
3113 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value);
3114 }
3115
3116
3117 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3118 const intptr_t value_cid = value()->Type()->ToCid();
3119 const intptr_t kNumInputs = 1;
3120 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
3121 LocationSummary* summary =
3122 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3123 summary->set_in(0, Location::RequiresRegister());
3124 if (kNumTemps > 0) {
3125 ASSERT(kNumTemps == 1);
3126 summary->set_temp(0, Location::RequiresRegister());
3127 }
3128 summary->set_out(Location::RequiresFpuRegister());
3129 return summary;
3130 }
3131
3132
3133 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3134 const intptr_t value_cid = value()->Type()->ToCid();
3135 const Register value = locs()->in(0).reg();
3136 const XmmRegister result = locs()->out().fpu_reg();
3137
3138 if (value_cid != kFloat64x2Cid) {
3139 const Register temp = locs()->temp(0).reg();
3140 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3141 __ testl(value, Immediate(kSmiTagMask));
3142 __ j(ZERO, deopt);
3143 __ CompareClassId(value, kFloat64x2Cid, temp);
3144 __ j(NOT_EQUAL, deopt);
3145 }
3146 __ movups(result, FieldAddress(value, Float64x2::value_offset()));
3147 }
3148
3149
3045 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { 3150 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
3046 const intptr_t kNumInputs = 1; 3151 const intptr_t kNumInputs = 1;
3047 const intptr_t kNumTemps = 0; 3152 const intptr_t kNumTemps = 0;
3048 LocationSummary* summary = 3153 LocationSummary* summary =
3049 new LocationSummary(kNumInputs, 3154 new LocationSummary(kNumInputs,
3050 kNumTemps, 3155 kNumTemps,
3051 LocationSummary::kCallOnSlowPath); 3156 LocationSummary::kCallOnSlowPath);
3052 summary->set_in(0, Location::RequiresFpuRegister()); 3157 summary->set_in(0, Location::RequiresFpuRegister());
3053 summary->set_out(Location::RequiresRegister()); 3158 summary->set_out(Location::RequiresRegister());
3054 return summary; 3159 return summary;
(...skipping 2220 matching lines...) Expand 10 before | Expand all | Expand 10 after
5275 PcDescriptors::kOther, 5380 PcDescriptors::kOther,
5276 locs()); 5381 locs());
5277 __ Drop(2); // Discard type arguments and receiver. 5382 __ Drop(2); // Discard type arguments and receiver.
5278 } 5383 }
5279 5384
5280 } // namespace dart 5385 } // namespace dart
5281 5386
5282 #undef __ 5387 #undef __
5283 5388
5284 #endif // defined TARGET_ARCH_IA32 5389 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698