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

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
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)) {
955 if (class_id_ == kTypedDataFloat64x2ArrayCid) {
Florian Schneider 2014/02/20 15:54:44 Left-over debug printing?
Cutch 2014/02/20 19:33:11 Done.
956 printf("class id match\n");
957 printf("representation = %d\n", representation());
958 printf("%d\n", locs()->out().kind());
959 }
949 XmmRegister result = locs()->out().fpu_reg(); 960 XmmRegister result = locs()->out().fpu_reg();
950 if ((index_scale() == 1) && index.IsRegister()) { 961 if ((index_scale() == 1) && index.IsRegister()) {
951 __ SmiUntag(index.reg()); 962 __ SmiUntag(index.reg());
952 } 963 }
953 switch (class_id()) { 964 switch (class_id()) {
954 case kTypedDataInt32ArrayCid: 965 case kTypedDataInt32ArrayCid:
955 __ movss(result, element_address); 966 __ movss(result, element_address);
956 __ pmovsxdq(result, result); 967 __ pmovsxdq(result, result);
957 break; 968 break;
958 case kTypedDataUint32ArrayCid: 969 case kTypedDataUint32ArrayCid:
959 __ xorpd(result, result); 970 __ xorpd(result, result);
960 __ movss(result, element_address); 971 __ movss(result, element_address);
961 break; 972 break;
962 case kTypedDataFloat32ArrayCid: 973 case kTypedDataFloat32ArrayCid:
963 // Load single precision float and promote to double. 974 // Load single precision float and promote to double.
964 __ movss(result, element_address); 975 __ movss(result, element_address);
965 __ cvtss2sd(result, locs()->out().fpu_reg()); 976 __ cvtss2sd(result, locs()->out().fpu_reg());
966 break; 977 break;
967 case kTypedDataFloat64ArrayCid: 978 case kTypedDataFloat64ArrayCid:
968 __ movsd(result, element_address); 979 __ movsd(result, element_address);
969 break; 980 break;
970 case kTypedDataInt32x4ArrayCid: 981 case kTypedDataInt32x4ArrayCid:
971 case kTypedDataFloat32x4ArrayCid: 982 case kTypedDataFloat32x4ArrayCid:
983 case kTypedDataFloat64x2ArrayCid:
972 __ movups(result, element_address); 984 __ movups(result, element_address);
973 break; 985 break;
974 } 986 }
975 return; 987 return;
976 } 988 }
977 989
978 Register result = locs()->out().reg(); 990 Register result = locs()->out().reg();
979 if ((index_scale() == 1) && index.IsRegister()) { 991 if ((index_scale() == 1) && index.IsRegister()) {
980 __ SmiUntag(index.reg()); 992 __ SmiUntag(index.reg());
981 } 993 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 case kTypedDataInt32ArrayCid: 1061 case kTypedDataInt32ArrayCid:
1050 case kTypedDataUint32ArrayCid: 1062 case kTypedDataUint32ArrayCid:
1051 return value()->IsSmiValue() ? kTagged : kUnboxedMint; 1063 return value()->IsSmiValue() ? kTagged : kUnboxedMint;
1052 case kTypedDataFloat32ArrayCid: 1064 case kTypedDataFloat32ArrayCid:
1053 case kTypedDataFloat64ArrayCid: 1065 case kTypedDataFloat64ArrayCid:
1054 return kUnboxedDouble; 1066 return kUnboxedDouble;
1055 case kTypedDataFloat32x4ArrayCid: 1067 case kTypedDataFloat32x4ArrayCid:
1056 return kUnboxedFloat32x4; 1068 return kUnboxedFloat32x4;
1057 case kTypedDataInt32x4ArrayCid: 1069 case kTypedDataInt32x4ArrayCid:
1058 return kUnboxedInt32x4; 1070 return kUnboxedInt32x4;
1071 case kTypedDataFloat64x2ArrayCid:
1072 return kUnboxedFloat64x2;
1059 default: 1073 default:
1060 UNIMPLEMENTED(); 1074 UNIMPLEMENTED();
1061 return kTagged; 1075 return kTagged;
1062 } 1076 }
1063 } 1077 }
1064 1078
1065 1079
1066 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { 1080 LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const {
1067 const intptr_t kNumInputs = 3; 1081 const intptr_t kNumInputs = 3;
1068 const intptr_t kNumTemps = 0; 1082 const intptr_t kNumTemps = 0;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 case kTypedDataFloat32ArrayCid: 1125 case kTypedDataFloat32ArrayCid:
1112 // Need temp register for float-to-double conversion. 1126 // Need temp register for float-to-double conversion.
1113 locs->AddTemp(Location::RequiresFpuRegister()); 1127 locs->AddTemp(Location::RequiresFpuRegister());
1114 // Fall through. 1128 // Fall through.
1115 case kTypedDataFloat64ArrayCid: 1129 case kTypedDataFloat64ArrayCid:
1116 // TODO(srdjan): Support Float64 constants. 1130 // TODO(srdjan): Support Float64 constants.
1117 locs->set_in(2, Location::RequiresFpuRegister()); 1131 locs->set_in(2, Location::RequiresFpuRegister());
1118 break; 1132 break;
1119 case kTypedDataInt32x4ArrayCid: 1133 case kTypedDataInt32x4ArrayCid:
1120 case kTypedDataFloat32x4ArrayCid: 1134 case kTypedDataFloat32x4ArrayCid:
1135 case kTypedDataFloat64x2ArrayCid:
1121 locs->set_in(2, Location::RequiresFpuRegister()); 1136 locs->set_in(2, Location::RequiresFpuRegister());
1122 break; 1137 break;
1123 default: 1138 default:
1124 UNREACHABLE(); 1139 UNREACHABLE();
1125 return NULL; 1140 return NULL;
1126 } 1141 }
1127 return locs; 1142 return locs;
1128 } 1143 }
1129 1144
1130 1145
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 // Convert to single precision. 1247 // Convert to single precision.
1233 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); 1248 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
1234 // Store. 1249 // Store.
1235 __ movss(element_address, locs()->temp(0).fpu_reg()); 1250 __ movss(element_address, locs()->temp(0).fpu_reg());
1236 break; 1251 break;
1237 case kTypedDataFloat64ArrayCid: 1252 case kTypedDataFloat64ArrayCid:
1238 __ movsd(element_address, locs()->in(2).fpu_reg()); 1253 __ movsd(element_address, locs()->in(2).fpu_reg());
1239 break; 1254 break;
1240 case kTypedDataInt32x4ArrayCid: 1255 case kTypedDataInt32x4ArrayCid:
1241 case kTypedDataFloat32x4ArrayCid: 1256 case kTypedDataFloat32x4ArrayCid:
1257 case kTypedDataFloat64x2ArrayCid:
1242 __ movups(element_address, locs()->in(2).fpu_reg()); 1258 __ movups(element_address, locs()->in(2).fpu_reg());
1243 break; 1259 break;
1244 default: 1260 default:
1245 UNREACHABLE(); 1261 UNREACHABLE();
1246 } 1262 }
1247 } 1263 }
1248 1264
1249 1265
1250 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { 1266 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const {
1251 const intptr_t kNumInputs = 1; 1267 const intptr_t kNumInputs = 1;
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
1988 compiler->RestoreLiveRegisters(locs); 2004 compiler->RestoreLiveRegisters(locs);
1989 2005
1990 __ jmp(exit_label()); 2006 __ jmp(exit_label());
1991 } 2007 }
1992 2008
1993 private: 2009 private:
1994 Instruction* instruction_; 2010 Instruction* instruction_;
1995 }; 2011 };
1996 2012
1997 2013
2014 class BoxFloat64x2SlowPath : public SlowPathCode {
2015 public:
2016 explicit BoxFloat64x2SlowPath(Instruction* instruction)
2017 : instruction_(instruction) { }
2018
2019 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2020 __ Comment("BoxFloat64x2SlowPath");
2021 __ Bind(entry_label());
2022 const Class& float64x2_class = compiler->float64x2_class();
2023 const Code& stub =
2024 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class));
2025 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint());
2026
2027 LocationSummary* locs = instruction_->locs();
2028 locs->live_registers()->Remove(locs->out());
2029
2030 compiler->SaveLiveRegisters(locs);
2031 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2032 &label,
2033 PcDescriptors::kOther,
2034 locs);
2035 __ MoveRegister(locs->out().reg(), EAX);
2036 compiler->RestoreLiveRegisters(locs);
2037
2038 __ jmp(exit_label());
2039 }
2040
2041 private:
2042 Instruction* instruction_;
2043 };
2044
1998 2045
1999 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 2046 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
2000 const intptr_t kNumInputs = 1; 2047 const intptr_t kNumInputs = 1;
2001 const intptr_t kNumTemps = 0; 2048 const intptr_t kNumTemps = 0;
2002 LocationSummary* locs = 2049 LocationSummary* locs =
2003 new LocationSummary( 2050 new LocationSummary(
2004 kNumInputs, kNumTemps, 2051 kNumInputs, kNumTemps,
2005 (opt && !IsPotentialUnboxedLoad()) 2052 (opt && !IsPotentialUnboxedLoad())
2006 ? LocationSummary::kNoCall 2053 ? LocationSummary::kNoCall
2007 : LocationSummary::kCallOnSlowPath); 2054 : LocationSummary::kCallOnSlowPath);
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
3035 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3082 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3036 __ testl(value, Immediate(kSmiTagMask)); 3083 __ testl(value, Immediate(kSmiTagMask));
3037 __ j(ZERO, deopt); 3084 __ j(ZERO, deopt);
3038 __ CompareClassId(value, kFloat32x4Cid, temp); 3085 __ CompareClassId(value, kFloat32x4Cid, temp);
3039 __ j(NOT_EQUAL, deopt); 3086 __ j(NOT_EQUAL, deopt);
3040 } 3087 }
3041 __ movups(result, FieldAddress(value, Float32x4::value_offset())); 3088 __ movups(result, FieldAddress(value, Float32x4::value_offset()));
3042 } 3089 }
3043 3090
3044 3091
3092 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3093 const intptr_t kNumInputs = 1;
3094 const intptr_t kNumTemps = 0;
3095 LocationSummary* summary =
3096 new LocationSummary(kNumInputs,
3097 kNumTemps,
3098 LocationSummary::kCallOnSlowPath);
3099 summary->set_in(0, Location::RequiresFpuRegister());
3100 summary->set_out(Location::RequiresRegister());
3101 return summary;
3102 }
3103
3104
3105 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3106 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this);
3107 compiler->AddSlowPathCode(slow_path);
3108
3109 Register out_reg = locs()->out().reg();
3110 XmmRegister value = locs()->in(0).fpu_reg();
3111
3112 __ TryAllocate(compiler->float64x2_class(),
3113 slow_path->entry_label(),
3114 Assembler::kFarJump,
3115 out_reg,
3116 kNoRegister);
3117 __ Bind(slow_path->exit_label());
3118 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value);
3119 }
3120
3121
3122 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3123 const intptr_t value_cid = value()->Type()->ToCid();
3124 const intptr_t kNumInputs = 1;
3125 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
3126 LocationSummary* summary =
3127 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3128 summary->set_in(0, Location::RequiresRegister());
3129 if (kNumTemps > 0) {
3130 ASSERT(kNumTemps == 1);
3131 summary->set_temp(0, Location::RequiresRegister());
3132 }
3133 summary->set_out(Location::RequiresFpuRegister());
3134 return summary;
3135 }
3136
3137
3138 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3139 const intptr_t value_cid = value()->Type()->ToCid();
3140 const Register value = locs()->in(0).reg();
3141 const XmmRegister result = locs()->out().fpu_reg();
3142
3143 if (value_cid != kFloat64x2Cid) {
3144 const Register temp = locs()->temp(0).reg();
3145 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3146 __ testl(value, Immediate(kSmiTagMask));
3147 __ j(ZERO, deopt);
3148 __ CompareClassId(value, kFloat64x2Cid, temp);
3149 __ j(NOT_EQUAL, deopt);
3150 }
3151 __ movups(result, FieldAddress(value, Float64x2::value_offset()));
3152 }
3153
3154
3045 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { 3155 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
3046 const intptr_t kNumInputs = 1; 3156 const intptr_t kNumInputs = 1;
3047 const intptr_t kNumTemps = 0; 3157 const intptr_t kNumTemps = 0;
3048 LocationSummary* summary = 3158 LocationSummary* summary =
3049 new LocationSummary(kNumInputs, 3159 new LocationSummary(kNumInputs,
3050 kNumTemps, 3160 kNumTemps,
3051 LocationSummary::kCallOnSlowPath); 3161 LocationSummary::kCallOnSlowPath);
3052 summary->set_in(0, Location::RequiresFpuRegister()); 3162 summary->set_in(0, Location::RequiresFpuRegister());
3053 summary->set_out(Location::RequiresRegister()); 3163 summary->set_out(Location::RequiresRegister());
3054 return summary; 3164 return summary;
(...skipping 2220 matching lines...) Expand 10 before | Expand all | Expand 10 after
5275 PcDescriptors::kOther, 5385 PcDescriptors::kOther,
5276 locs()); 5386 locs());
5277 __ Drop(2); // Discard type arguments and receiver. 5387 __ Drop(2); // Discard type arguments and receiver.
5278 } 5388 }
5279 5389
5280 } // namespace dart 5390 } // namespace dart
5281 5391
5282 #undef __ 5392 #undef __
5283 5393
5284 #endif // defined TARGET_ARCH_IA32 5394 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698