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

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

Issue 11956004: Fix vm code base so that it can be built for --arch=simarm (no snapshot yet). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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) 2012, 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 "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/dart_entry.h"
11 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
12 #include "vm/locations.h" 13 #include "vm/locations.h"
13 #include "vm/object_store.h" 14 #include "vm/object_store.h"
14 #include "vm/parser.h" 15 #include "vm/parser.h"
15 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
16 #include "vm/symbols.h" 17 #include "vm/symbols.h"
17 18
18 #define __ compiler->assembler()-> 19 #define __ compiler->assembler()->
19 20
20 namespace dart { 21 namespace dart {
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 261
261 262
262 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { 263 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
263 const intptr_t kNumInputs = 2; 264 const intptr_t kNumInputs = 2;
264 const bool is_checked_strict_equal = 265 const bool is_checked_strict_equal =
265 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 266 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
266 if (receiver_class_id() == kMintCid) { 267 if (receiver_class_id() == kMintCid) {
267 const intptr_t kNumTemps = 1; 268 const intptr_t kNumTemps = 1;
268 LocationSummary* locs = 269 LocationSummary* locs =
269 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 270 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
270 locs->set_in(0, Location::RequiresXmmRegister()); 271 locs->set_in(0, Location::RequiresFpuRegister());
271 locs->set_in(1, Location::RequiresXmmRegister()); 272 locs->set_in(1, Location::RequiresFpuRegister());
272 locs->set_temp(0, Location::RequiresRegister()); 273 locs->set_temp(0, Location::RequiresRegister());
273 locs->set_out(Location::RequiresRegister()); 274 locs->set_out(Location::RequiresRegister());
274 return locs; 275 return locs;
275 } 276 }
276 if (receiver_class_id() == kDoubleCid) { 277 if (receiver_class_id() == kDoubleCid) {
277 const intptr_t kNumTemps = 0; 278 const intptr_t kNumTemps = 0;
278 LocationSummary* locs = 279 LocationSummary* locs =
279 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 280 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
280 locs->set_in(0, Location::RequiresXmmRegister()); 281 locs->set_in(0, Location::RequiresFpuRegister());
281 locs->set_in(1, Location::RequiresXmmRegister()); 282 locs->set_in(1, Location::RequiresFpuRegister());
282 locs->set_out(Location::RequiresRegister()); 283 locs->set_out(Location::RequiresRegister());
283 return locs; 284 return locs;
284 } 285 }
285 if (receiver_class_id() == kSmiCid) { 286 if (receiver_class_id() == kSmiCid) {
286 const intptr_t kNumTemps = 0; 287 const intptr_t kNumTemps = 0;
287 LocationSummary* locs = 288 LocationSummary* locs =
288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 289 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
289 locs->set_in(0, Location::RegisterOrConstant(left())); 290 locs->set_in(0, Location::RegisterOrConstant(left()));
290 // Only one input can be a constant operand. The case of two constant 291 // Only one input can be a constant operand. The case of two constant
291 // operands should be handled by constant propagation. 292 // operands should be handled by constant propagation.
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 return OVERFLOW; 658 return OVERFLOW;
658 } 659 }
659 } 660 }
660 661
661 662
662 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler, 663 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
663 const LocationSummary& locs, 664 const LocationSummary& locs,
664 Token::Kind kind, 665 Token::Kind kind,
665 BranchInstr* branch) { 666 BranchInstr* branch) {
666 ASSERT(Token::IsEqualityOperator(kind)); 667 ASSERT(Token::IsEqualityOperator(kind));
667 XmmRegister left = locs.in(0).xmm_reg(); 668 XmmRegister left = locs.in(0).fpu_reg();
668 XmmRegister right = locs.in(1).xmm_reg(); 669 XmmRegister right = locs.in(1).fpu_reg();
669 Register temp = locs.temp(0).reg(); 670 Register temp = locs.temp(0).reg();
670 __ movaps(XMM0, left); 671 __ movaps(XMM0, left);
671 __ pcmpeqq(XMM0, right); 672 __ pcmpeqq(XMM0, right);
672 __ movd(temp, XMM0); 673 __ movd(temp, XMM0);
673 674
674 Condition true_condition = TokenKindToMintCondition(kind); 675 Condition true_condition = TokenKindToMintCondition(kind);
675 __ cmpl(temp, Immediate(-1)); 676 __ cmpl(temp, Immediate(-1));
676 677
677 if (branch != NULL) { 678 if (branch != NULL) {
678 branch->EmitBranchOnCondition(compiler, true_condition); 679 branch->EmitBranchOnCondition(compiler, true_condition);
679 } else { 680 } else {
680 Register result = locs.out().reg(); 681 Register result = locs.out().reg();
681 Label done, is_true; 682 Label done, is_true;
682 __ j(true_condition, &is_true); 683 __ j(true_condition, &is_true);
683 __ LoadObject(result, Bool::False()); 684 __ LoadObject(result, Bool::False());
684 __ jmp(&done); 685 __ jmp(&done);
685 __ Bind(&is_true); 686 __ Bind(&is_true);
686 __ LoadObject(result, Bool::True()); 687 __ LoadObject(result, Bool::True());
687 __ Bind(&done); 688 __ Bind(&done);
688 } 689 }
689 } 690 }
690 691
691 692
692 static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, 693 static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
693 const LocationSummary& locs, 694 const LocationSummary& locs,
694 Token::Kind kind, 695 Token::Kind kind,
695 BranchInstr* branch) { 696 BranchInstr* branch) {
696 XmmRegister left = locs.in(0).xmm_reg(); 697 XmmRegister left = locs.in(0).fpu_reg();
697 XmmRegister right = locs.in(1).xmm_reg(); 698 XmmRegister right = locs.in(1).fpu_reg();
698 Register left_tmp = locs.temp(0).reg(); 699 Register left_tmp = locs.temp(0).reg();
699 Register right_tmp = locs.temp(1).reg(); 700 Register right_tmp = locs.temp(1).reg();
700 Register result = branch == NULL ? locs.out().reg() : kNoRegister; 701 Register result = branch == NULL ? locs.out().reg() : kNoRegister;
701 702
702 Condition hi_cond = OVERFLOW, lo_cond = OVERFLOW; 703 Condition hi_cond = OVERFLOW, lo_cond = OVERFLOW;
703 switch (kind) { 704 switch (kind) {
704 case Token::kLT: 705 case Token::kLT:
705 hi_cond = LESS; 706 hi_cond = LESS;
706 lo_cond = BELOW; 707 lo_cond = BELOW;
707 break; 708 break;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 UNREACHABLE(); 767 UNREACHABLE();
767 return OVERFLOW; 768 return OVERFLOW;
768 } 769 }
769 } 770 }
770 771
771 772
772 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 773 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
773 const LocationSummary& locs, 774 const LocationSummary& locs,
774 Token::Kind kind, 775 Token::Kind kind,
775 BranchInstr* branch) { 776 BranchInstr* branch) {
776 XmmRegister left = locs.in(0).xmm_reg(); 777 XmmRegister left = locs.in(0).fpu_reg();
777 XmmRegister right = locs.in(1).xmm_reg(); 778 XmmRegister right = locs.in(1).fpu_reg();
778 779
779 Condition true_condition = TokenKindToDoubleCondition(kind); 780 Condition true_condition = TokenKindToDoubleCondition(kind);
780 if (branch != NULL) { 781 if (branch != NULL) {
781 compiler->EmitDoubleCompareBranch( 782 compiler->EmitDoubleCompareBranch(
782 true_condition, left, right, branch); 783 true_condition, left, right, branch);
783 } else { 784 } else {
784 compiler->EmitDoubleCompareBool( 785 compiler->EmitDoubleCompareBool(
785 true_condition, left, right, locs.out().reg()); 786 true_condition, left, right, locs.out().reg());
786 } 787 }
787 } 788 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 } 877 }
877 878
878 879
879 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 880 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
880 const intptr_t kNumInputs = 2; 881 const intptr_t kNumInputs = 2;
881 const intptr_t kNumTemps = 0; 882 const intptr_t kNumTemps = 0;
882 if (operands_class_id() == kMintCid) { 883 if (operands_class_id() == kMintCid) {
883 const intptr_t kNumTemps = 2; 884 const intptr_t kNumTemps = 2;
884 LocationSummary* locs = 885 LocationSummary* locs =
885 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 886 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
886 locs->set_in(0, Location::RequiresXmmRegister()); 887 locs->set_in(0, Location::RequiresFpuRegister());
887 locs->set_in(1, Location::RequiresXmmRegister()); 888 locs->set_in(1, Location::RequiresFpuRegister());
888 locs->set_temp(0, Location::RequiresRegister()); 889 locs->set_temp(0, Location::RequiresRegister());
889 locs->set_temp(1, Location::RequiresRegister()); 890 locs->set_temp(1, Location::RequiresRegister());
890 locs->set_out(Location::RequiresRegister()); 891 locs->set_out(Location::RequiresRegister());
891 return locs; 892 return locs;
892 } 893 }
893 if (operands_class_id() == kDoubleCid) { 894 if (operands_class_id() == kDoubleCid) {
894 LocationSummary* summary = 895 LocationSummary* summary =
895 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 896 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
896 summary->set_in(0, Location::RequiresXmmRegister()); 897 summary->set_in(0, Location::RequiresFpuRegister());
897 summary->set_in(1, Location::RequiresXmmRegister()); 898 summary->set_in(1, Location::RequiresFpuRegister());
898 summary->set_out(Location::RequiresRegister()); 899 summary->set_out(Location::RequiresRegister());
899 return summary; 900 return summary;
900 } else if (operands_class_id() == kSmiCid) { 901 } else if (operands_class_id() == kSmiCid) {
901 LocationSummary* summary = 902 LocationSummary* summary =
902 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 903 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
903 summary->set_in(0, Location::RegisterOrConstant(left())); 904 summary->set_in(0, Location::RegisterOrConstant(left()));
904 // Only one input can be a constant operand. The case of two constant 905 // Only one input can be a constant operand. The case of two constant
905 // operands should be handled by constant propagation. 906 // operands should be handled by constant propagation.
906 summary->set_in(1, summary->in(0).IsConstant() 907 summary->set_in(1, summary->in(0).IsConstant()
907 ? Location::RequiresRegister() 908 ? Location::RequiresRegister()
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { 1139 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
1139 const intptr_t kNumInputs = 2; 1140 const intptr_t kNumInputs = 2;
1140 const intptr_t kNumTemps = 0; 1141 const intptr_t kNumTemps = 0;
1141 LocationSummary* locs = 1142 LocationSummary* locs =
1142 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1143 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1143 locs->set_in(0, Location::RequiresRegister()); 1144 locs->set_in(0, Location::RequiresRegister());
1144 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 1145 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
1145 ? Location::RegisterOrSmiConstant(index()) 1146 ? Location::RegisterOrSmiConstant(index())
1146 : Location::RequiresRegister()); 1147 : Location::RequiresRegister());
1147 if (representation() == kUnboxedDouble) { 1148 if (representation() == kUnboxedDouble) {
1148 locs->set_out(Location::RequiresXmmRegister()); 1149 locs->set_out(Location::RequiresFpuRegister());
1149 } else { 1150 } else {
1150 locs->set_out(Location::RequiresRegister()); 1151 locs->set_out(Location::RequiresRegister());
1151 } 1152 }
1152 return locs; 1153 return locs;
1153 } 1154 }
1154 1155
1155 1156
1156 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1157 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1157 Register array = locs()->in(0).reg(); 1158 Register array = locs()->in(0).reg();
1158 Location index = locs()->in(1); 1159 Location index = locs()->in(1);
(...skipping 18 matching lines...) Expand all
1177 return; 1178 return;
1178 } 1179 }
1179 1180
1180 FieldAddress element_address = index.IsRegister() ? 1181 FieldAddress element_address = index.IsRegister() ?
1181 FlowGraphCompiler::ElementAddressForRegIndex( 1182 FlowGraphCompiler::ElementAddressForRegIndex(
1182 class_id(), array, index.reg()) : 1183 class_id(), array, index.reg()) :
1183 FlowGraphCompiler::ElementAddressForIntIndex( 1184 FlowGraphCompiler::ElementAddressForIntIndex(
1184 class_id(), array, Smi::Cast(index.constant()).Value()); 1185 class_id(), array, Smi::Cast(index.constant()).Value());
1185 1186
1186 if (representation() == kUnboxedDouble) { 1187 if (representation() == kUnboxedDouble) {
1187 XmmRegister result = locs()->out().xmm_reg(); 1188 XmmRegister result = locs()->out().fpu_reg();
1188 if (class_id() == kFloat32ArrayCid) { 1189 if (class_id() == kFloat32ArrayCid) {
1189 // Load single precision float. 1190 // Load single precision float.
1190 __ movss(result, element_address); 1191 __ movss(result, element_address);
1191 // Promote to double. 1192 // Promote to double.
1192 __ cvtss2sd(result, locs()->out().xmm_reg()); 1193 __ cvtss2sd(result, locs()->out().fpu_reg());
1193 } else { 1194 } else {
1194 ASSERT(class_id() == kFloat64ArrayCid); 1195 ASSERT(class_id() == kFloat64ArrayCid);
1195 __ movsd(result, element_address); 1196 __ movsd(result, element_address);
1196 } 1197 }
1197 return; 1198 return;
1198 } 1199 }
1199 1200
1200 Register result = locs()->out().reg(); 1201 Register result = locs()->out().reg();
1201 if ((class_id() == kUint8ArrayCid) || 1202 if ((class_id() == kUint8ArrayCid) ||
1202 (class_id() == kUint8ClampedArrayCid)) { 1203 (class_id() == kUint8ClampedArrayCid)) {
(...skipping 28 matching lines...) Expand all
1231 ? Location::WritableRegister() 1232 ? Location::WritableRegister()
1232 : Location::RegisterOrConstant(value())); 1233 : Location::RegisterOrConstant(value()));
1233 break; 1234 break;
1234 case kUint8ArrayCid: 1235 case kUint8ArrayCid:
1235 // TODO(fschneider): Add location constraint for byte registers (EAX, 1236 // TODO(fschneider): Add location constraint for byte registers (EAX,
1236 // EBX, ECX, EDX) instead of using a fixed register. 1237 // EBX, ECX, EDX) instead of using a fixed register.
1237 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); 1238 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX));
1238 break; 1239 break;
1239 case kFloat32ArrayCid: 1240 case kFloat32ArrayCid:
1240 // Need temp register for float-to-double conversion. 1241 // Need temp register for float-to-double conversion.
1241 locs->AddTemp(Location::RequiresXmmRegister()); 1242 locs->AddTemp(Location::RequiresFpuRegister());
1242 // Fall through. 1243 // Fall through.
1243 case kFloat64ArrayCid: 1244 case kFloat64ArrayCid:
1244 // TODO(srdjan): Support Float64 constants. 1245 // TODO(srdjan): Support Float64 constants.
1245 locs->set_in(2, Location::RequiresXmmRegister()); 1246 locs->set_in(2, Location::RequiresFpuRegister());
1246 break; 1247 break;
1247 default: 1248 default:
1248 UNREACHABLE(); 1249 UNREACHABLE();
1249 return NULL; 1250 return NULL;
1250 } 1251 }
1251 return locs; 1252 return locs;
1252 } 1253 }
1253 1254
1254 1255
1255 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1256 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 ASSERT(locs()->in(2).reg() == EAX); 1288 ASSERT(locs()->in(2).reg() == EAX);
1288 __ SmiUntag(EAX); 1289 __ SmiUntag(EAX);
1289 __ movb(element_address, AL); 1290 __ movb(element_address, AL);
1290 } 1291 }
1291 if (index.IsRegister()) { 1292 if (index.IsRegister()) {
1292 __ SmiTag(index.reg()); // Re-tag. 1293 __ SmiTag(index.reg()); // Re-tag.
1293 } 1294 }
1294 break; 1295 break;
1295 case kFloat32ArrayCid: 1296 case kFloat32ArrayCid:
1296 // Convert to single precision. 1297 // Convert to single precision.
1297 __ cvtsd2ss(locs()->temp(0).xmm_reg(), locs()->in(2).xmm_reg()); 1298 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
1298 // Store. 1299 // Store.
1299 __ movss(element_address, locs()->temp(0).xmm_reg()); 1300 __ movss(element_address, locs()->temp(0).fpu_reg());
1300 break; 1301 break;
1301 case kFloat64ArrayCid: 1302 case kFloat64ArrayCid:
1302 __ movsd(element_address, locs()->in(2).xmm_reg()); 1303 __ movsd(element_address, locs()->in(2).fpu_reg());
1303 break; 1304 break;
1304 default: 1305 default:
1305 UNREACHABLE(); 1306 UNREACHABLE();
1306 } 1307 }
1307 } 1308 }
1308 1309
1309 1310
1310 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { 1311 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const {
1311 const intptr_t kNumInputs = 2; 1312 const intptr_t kNumInputs = 2;
1312 const intptr_t num_temps = 0; 1313 const intptr_t num_temps = 0;
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after
2081 } 2082 }
2082 2083
2083 2084
2084 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { 2085 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const {
2085 const intptr_t kNumInputs = 1; 2086 const intptr_t kNumInputs = 1;
2086 const intptr_t kNumTemps = 0; 2087 const intptr_t kNumTemps = 0;
2087 LocationSummary* summary = 2088 LocationSummary* summary =
2088 new LocationSummary(kNumInputs, 2089 new LocationSummary(kNumInputs,
2089 kNumTemps, 2090 kNumTemps,
2090 LocationSummary::kCallOnSlowPath); 2091 LocationSummary::kCallOnSlowPath);
2091 summary->set_in(0, Location::RequiresXmmRegister()); 2092 summary->set_in(0, Location::RequiresFpuRegister());
2092 summary->set_out(Location::RequiresRegister()); 2093 summary->set_out(Location::RequiresRegister());
2093 return summary; 2094 return summary;
2094 } 2095 }
2095 2096
2096 2097
2097 class BoxDoubleSlowPath : public SlowPathCode { 2098 class BoxDoubleSlowPath : public SlowPathCode {
2098 public: 2099 public:
2099 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) 2100 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction)
2100 : instruction_(instruction) { } 2101 : instruction_(instruction) { }
2101 2102
(...skipping 22 matching lines...) Expand all
2124 private: 2125 private:
2125 BoxDoubleInstr* instruction_; 2126 BoxDoubleInstr* instruction_;
2126 }; 2127 };
2127 2128
2128 2129
2129 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2130 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2130 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2131 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
2131 compiler->AddSlowPathCode(slow_path); 2132 compiler->AddSlowPathCode(slow_path);
2132 2133
2133 Register out_reg = locs()->out().reg(); 2134 Register out_reg = locs()->out().reg();
2134 XmmRegister value = locs()->in(0).xmm_reg(); 2135 XmmRegister value = locs()->in(0).fpu_reg();
2135 2136
2136 AssemblerMacros::TryAllocate(compiler->assembler(), 2137 AssemblerMacros::TryAllocate(compiler->assembler(),
2137 compiler->double_class(), 2138 compiler->double_class(),
2138 slow_path->entry_label(), 2139 slow_path->entry_label(),
2139 Assembler::kFarJump, 2140 Assembler::kFarJump,
2140 out_reg); 2141 out_reg);
2141 __ Bind(slow_path->exit_label()); 2142 __ Bind(slow_path->exit_label());
2142 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); 2143 __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
2143 } 2144 }
2144 2145
2145 2146
2146 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { 2147 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const {
2147 const intptr_t kNumInputs = 1; 2148 const intptr_t kNumInputs = 1;
2148 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; 2149 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0;
2149 LocationSummary* summary = 2150 LocationSummary* summary =
2150 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2151 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2151 summary->set_in(0, Location::RequiresRegister()); 2152 summary->set_in(0, Location::RequiresRegister());
2152 if (CanDeoptimize()) summary->set_temp(0, Location::RequiresRegister()); 2153 if (CanDeoptimize()) summary->set_temp(0, Location::RequiresRegister());
2153 summary->set_out(Location::RequiresXmmRegister()); 2154 summary->set_out(Location::RequiresFpuRegister());
2154 return summary; 2155 return summary;
2155 } 2156 }
2156 2157
2157 2158
2158 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2159 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2159 const intptr_t value_cid = value()->ResultCid(); 2160 const intptr_t value_cid = value()->ResultCid();
2160 const Register value = locs()->in(0).reg(); 2161 const Register value = locs()->in(0).reg();
2161 const XmmRegister result = locs()->out().xmm_reg(); 2162 const XmmRegister result = locs()->out().fpu_reg();
2162 2163
2163 if (value_cid == kDoubleCid) { 2164 if (value_cid == kDoubleCid) {
2164 __ movsd(result, FieldAddress(value, Double::value_offset())); 2165 __ movsd(result, FieldAddress(value, Double::value_offset()));
2165 } else if (value_cid == kSmiCid) { 2166 } else if (value_cid == kSmiCid) {
2166 __ SmiUntag(value); // Untag input before conversion. 2167 __ SmiUntag(value); // Untag input before conversion.
2167 __ cvtsi2sd(result, value); 2168 __ cvtsi2sd(result, value);
2168 __ SmiTag(value); // Restore input register. 2169 __ SmiTag(value); // Restore input register.
2169 } else { 2170 } else {
2170 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 2171 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
2171 compiler->LoadDoubleOrSmiToXmm(result, 2172 compiler->LoadDoubleOrSmiToFpu(result,
2172 value, 2173 value,
2173 locs()->temp(0).reg(), 2174 locs()->temp(0).reg(),
2174 deopt); 2175 deopt);
2175 } 2176 }
2176 } 2177 }
2177 2178
2178 2179
2179 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { 2180 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const {
2180 const intptr_t kNumInputs = 2; 2181 const intptr_t kNumInputs = 2;
2181 const intptr_t kNumTemps = 0; 2182 const intptr_t kNumTemps = 0;
2182 LocationSummary* summary = 2183 LocationSummary* summary =
2183 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2184 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2184 summary->set_in(0, Location::RequiresXmmRegister()); 2185 summary->set_in(0, Location::RequiresFpuRegister());
2185 summary->set_in(1, Location::RequiresXmmRegister()); 2186 summary->set_in(1, Location::RequiresFpuRegister());
2186 summary->set_out(Location::SameAsFirstInput()); 2187 summary->set_out(Location::SameAsFirstInput());
2187 return summary; 2188 return summary;
2188 } 2189 }
2189 2190
2190 2191
2191 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2192 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2192 XmmRegister left = locs()->in(0).xmm_reg(); 2193 XmmRegister left = locs()->in(0).fpu_reg();
2193 XmmRegister right = locs()->in(1).xmm_reg(); 2194 XmmRegister right = locs()->in(1).fpu_reg();
2194 2195
2195 ASSERT(locs()->out().xmm_reg() == left); 2196 ASSERT(locs()->out().fpu_reg() == left);
2196 2197
2197 switch (op_kind()) { 2198 switch (op_kind()) {
2198 case Token::kADD: __ addsd(left, right); break; 2199 case Token::kADD: __ addsd(left, right); break;
2199 case Token::kSUB: __ subsd(left, right); break; 2200 case Token::kSUB: __ subsd(left, right); break;
2200 case Token::kMUL: __ mulsd(left, right); break; 2201 case Token::kMUL: __ mulsd(left, right); break;
2201 case Token::kDIV: __ divsd(left, right); break; 2202 case Token::kDIV: __ divsd(left, right); break;
2202 default: UNREACHABLE(); 2203 default: UNREACHABLE();
2203 } 2204 }
2204 } 2205 }
2205 2206
2206 2207
2207 LocationSummary* MathSqrtInstr::MakeLocationSummary() const { 2208 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
2208 const intptr_t kNumInputs = 1; 2209 const intptr_t kNumInputs = 1;
2209 const intptr_t kNumTemps = 0; 2210 const intptr_t kNumTemps = 0;
2210 LocationSummary* summary = 2211 LocationSummary* summary =
2211 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2212 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2212 summary->set_in(0, Location::RequiresXmmRegister()); 2213 summary->set_in(0, Location::RequiresFpuRegister());
2213 summary->set_out(Location::RequiresXmmRegister()); 2214 summary->set_out(Location::RequiresFpuRegister());
2214 return summary; 2215 return summary;
2215 } 2216 }
2216 2217
2217 2218
2218 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2219 void MathSqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2219 __ sqrtsd(locs()->out().xmm_reg(), locs()->in(0).xmm_reg()); 2220 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
2220 } 2221 }
2221 2222
2222 2223
2223 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 2224 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
2224 const intptr_t kNumInputs = 1; 2225 const intptr_t kNumInputs = 1;
2225 const intptr_t kNumTemps = 0; 2226 const intptr_t kNumTemps = 0;
2226 LocationSummary* summary = 2227 LocationSummary* summary =
2227 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2228 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2228 summary->set_in(0, Location::RequiresRegister()); 2229 summary->set_in(0, Location::RequiresRegister());
2229 summary->set_out(Location::SameAsFirstInput()); 2230 summary->set_out(Location::SameAsFirstInput());
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 locs()); 2330 locs());
2330 __ Bind(&done); 2331 __ Bind(&done);
2331 } 2332 }
2332 2333
2333 2334
2334 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { 2335 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const {
2335 const intptr_t kNumInputs = 1; 2336 const intptr_t kNumInputs = 1;
2336 const intptr_t kNumTemps = 0; 2337 const intptr_t kNumTemps = 0;
2337 LocationSummary* result = new LocationSummary( 2338 LocationSummary* result = new LocationSummary(
2338 kNumInputs, kNumTemps, LocationSummary::kNoCall); 2339 kNumInputs, kNumTemps, LocationSummary::kNoCall);
2339 result->set_in(0, Location::RequiresXmmRegister()); 2340 result->set_in(0, Location::RequiresFpuRegister());
2340 result->set_out(Location::RequiresRegister()); 2341 result->set_out(Location::RequiresRegister());
2341 return result; 2342 return result;
2342 } 2343 }
2343 2344
2344 2345
2345 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2346 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2346 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); 2347 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
2347 Register result = locs()->out().reg(); 2348 Register result = locs()->out().reg();
2348 XmmRegister value = locs()->in(0).xmm_reg(); 2349 XmmRegister value = locs()->in(0).fpu_reg();
2349 __ cvttsd2si(result, value); 2350 __ cvttsd2si(result, value);
2350 // Overflow is signalled with minint. 2351 // Overflow is signalled with minint.
2351 Label do_call, done; 2352 Label do_call, done;
2352 // Check for overflow and that it fits into Smi. 2353 // Check for overflow and that it fits into Smi.
2353 __ cmpl(result, Immediate(0xC0000000)); 2354 __ cmpl(result, Immediate(0xC0000000));
2354 __ j(NEGATIVE, deopt); 2355 __ j(NEGATIVE, deopt);
2355 __ SmiTag(result); 2356 __ SmiTag(result);
2356 } 2357 }
2357 2358
2358 2359
2359 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { 2360 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const {
2360 const intptr_t kNumInputs = 1; 2361 const intptr_t kNumInputs = 1;
2361 const intptr_t kNumTemps = 2362 const intptr_t kNumTemps =
2362 (recognized_kind() == MethodRecognizer::kDoubleRound) ? 1 : 0; 2363 (recognized_kind() == MethodRecognizer::kDoubleRound) ? 1 : 0;
2363 LocationSummary* result = 2364 LocationSummary* result =
2364 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2365 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2365 result->set_in(0, Location::RequiresXmmRegister()); 2366 result->set_in(0, Location::RequiresFpuRegister());
2366 result->set_out(Location::RequiresXmmRegister()); 2367 result->set_out(Location::RequiresFpuRegister());
2367 if (recognized_kind() == MethodRecognizer::kDoubleRound) { 2368 if (recognized_kind() == MethodRecognizer::kDoubleRound) {
2368 result->set_temp(0, Location::RequiresXmmRegister()); 2369 result->set_temp(0, Location::RequiresFpuRegister());
2369 } 2370 }
2370 return result; 2371 return result;
2371 } 2372 }
2372 2373
2373 2374
2374 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2375 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2375 XmmRegister value = locs()->in(0).xmm_reg(); 2376 XmmRegister value = locs()->in(0).fpu_reg();
2376 XmmRegister result = locs()->out().xmm_reg(); 2377 XmmRegister result = locs()->out().fpu_reg();
2377 if (recognized_kind() == MethodRecognizer::kDoubleTruncate) { 2378 if (recognized_kind() == MethodRecognizer::kDoubleTruncate) {
2378 __ roundsd(result, value, Assembler::kRoundToZero); 2379 __ roundsd(result, value, Assembler::kRoundToZero);
2379 } else { 2380 } else {
2380 XmmRegister temp = locs()->temp(0).xmm_reg(); 2381 XmmRegister temp = locs()->temp(0).fpu_reg();
2381 __ DoubleRound(result, value, temp); 2382 __ DoubleRound(result, value, temp);
2382 } 2383 }
2383 } 2384 }
2384 2385
2385 2386
2386 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { 2387 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const {
2387 return MakeCallSummary(); 2388 return MakeCallSummary();
2388 } 2389 }
2389 2390
2390 2391
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2563 } 2564 }
2564 2565
2565 2566
2566 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { 2567 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const {
2567 const intptr_t kNumInputs = 1; 2568 const intptr_t kNumInputs = 1;
2568 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; 2569 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0;
2569 LocationSummary* summary = 2570 LocationSummary* summary =
2570 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2571 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2571 summary->set_in(0, Location::RequiresRegister()); 2572 summary->set_in(0, Location::RequiresRegister());
2572 if (CanDeoptimize()) summary->set_temp(0, Location::RequiresRegister()); 2573 if (CanDeoptimize()) summary->set_temp(0, Location::RequiresRegister());
2573 summary->set_out(Location::RequiresXmmRegister()); 2574 summary->set_out(Location::RequiresFpuRegister());
2574 return summary; 2575 return summary;
2575 } 2576 }
2576 2577
2577 2578
2578 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2579 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2579 const intptr_t value_cid = value()->ResultCid(); 2580 const intptr_t value_cid = value()->ResultCid();
2580 const Register value = locs()->in(0).reg(); 2581 const Register value = locs()->in(0).reg();
2581 const XmmRegister result = locs()->out().xmm_reg(); 2582 const XmmRegister result = locs()->out().fpu_reg();
2582 2583
2583 if (value_cid == kMintCid) { 2584 if (value_cid == kMintCid) {
2584 __ movsd(result, FieldAddress(value, Mint::value_offset())); 2585 __ movsd(result, FieldAddress(value, Mint::value_offset()));
2585 } else if (value_cid == kSmiCid) { 2586 } else if (value_cid == kSmiCid) {
2586 __ SmiUntag(value); // Untag input before conversion. 2587 __ SmiUntag(value); // Untag input before conversion.
2587 __ movd(result, value); 2588 __ movd(result, value);
2588 __ pmovsxdq(result, result); 2589 __ pmovsxdq(result, result);
2589 __ SmiTag(value); // Restore input register. 2590 __ SmiTag(value); // Restore input register.
2590 } else { 2591 } else {
2591 Register temp = locs()->temp(0).reg(); 2592 Register temp = locs()->temp(0).reg();
(...skipping 15 matching lines...) Expand all
2607 } 2608 }
2608 2609
2609 2610
2610 LocationSummary* BoxIntegerInstr::MakeLocationSummary() const { 2611 LocationSummary* BoxIntegerInstr::MakeLocationSummary() const {
2611 const intptr_t kNumInputs = 1; 2612 const intptr_t kNumInputs = 1;
2612 const intptr_t kNumTemps = 2; 2613 const intptr_t kNumTemps = 2;
2613 LocationSummary* summary = 2614 LocationSummary* summary =
2614 new LocationSummary(kNumInputs, 2615 new LocationSummary(kNumInputs,
2615 kNumTemps, 2616 kNumTemps,
2616 LocationSummary::kCallOnSlowPath); 2617 LocationSummary::kCallOnSlowPath);
2617 summary->set_in(0, Location::RequiresXmmRegister()); 2618 summary->set_in(0, Location::RequiresFpuRegister());
2618 summary->set_temp(0, Location::RegisterLocation(EAX)); 2619 summary->set_temp(0, Location::RegisterLocation(EAX));
2619 summary->set_temp(1, Location::RegisterLocation(EDX)); 2620 summary->set_temp(1, Location::RegisterLocation(EDX));
2620 // TODO(fschneider): Save one temp by using result register as a temp. 2621 // TODO(fschneider): Save one temp by using result register as a temp.
2621 summary->set_out(Location::RequiresRegister()); 2622 summary->set_out(Location::RequiresRegister());
2622 return summary; 2623 return summary;
2623 } 2624 }
2624 2625
2625 2626
2626 class BoxIntegerSlowPath : public SlowPathCode { 2627 class BoxIntegerSlowPath : public SlowPathCode {
2627 public: 2628 public:
(...skipping 26 matching lines...) Expand all
2654 private: 2655 private:
2655 BoxIntegerInstr* instruction_; 2656 BoxIntegerInstr* instruction_;
2656 }; 2657 };
2657 2658
2658 2659
2659 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2660 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2660 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); 2661 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this);
2661 compiler->AddSlowPathCode(slow_path); 2662 compiler->AddSlowPathCode(slow_path);
2662 2663
2663 Register out_reg = locs()->out().reg(); 2664 Register out_reg = locs()->out().reg();
2664 XmmRegister value = locs()->in(0).xmm_reg(); 2665 XmmRegister value = locs()->in(0).fpu_reg();
2665 2666
2666 // Unboxed operations produce smis or mint-sized values. 2667 // Unboxed operations produce smis or mint-sized values.
2667 // Check if value fits into a smi. 2668 // Check if value fits into a smi.
2668 Label not_smi, done; 2669 Label not_smi, done;
2669 __ pextrd(EDX, value, Immediate(1)); // Upper half. 2670 __ pextrd(EDX, value, Immediate(1)); // Upper half.
2670 __ pextrd(EAX, value, Immediate(0)); // Lower half. 2671 __ pextrd(EAX, value, Immediate(0)); // Lower half.
2671 // 1. Compute (x + -kMinSmi) which has to be in the range 2672 // 1. Compute (x + -kMinSmi) which has to be in the range
2672 // 0 .. -kMinSmi+kMaxSmi for x to fit into a smi. 2673 // 0 .. -kMinSmi+kMaxSmi for x to fit into a smi.
2673 __ addl(EAX, Immediate(0x40000000)); 2674 __ addl(EAX, Immediate(0x40000000));
2674 __ adcl(EDX, Immediate(0)); 2675 __ adcl(EDX, Immediate(0));
(...skipping 23 matching lines...) Expand all
2698 2699
2699 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { 2700 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const {
2700 const intptr_t kNumInputs = 2; 2701 const intptr_t kNumInputs = 2;
2701 switch (op_kind()) { 2702 switch (op_kind()) {
2702 case Token::kBIT_AND: 2703 case Token::kBIT_AND:
2703 case Token::kBIT_OR: 2704 case Token::kBIT_OR:
2704 case Token::kBIT_XOR: { 2705 case Token::kBIT_XOR: {
2705 const intptr_t kNumTemps = 0; 2706 const intptr_t kNumTemps = 0;
2706 LocationSummary* summary = 2707 LocationSummary* summary =
2707 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2708 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2708 summary->set_in(0, Location::RequiresXmmRegister()); 2709 summary->set_in(0, Location::RequiresFpuRegister());
2709 summary->set_in(1, Location::RequiresXmmRegister()); 2710 summary->set_in(1, Location::RequiresFpuRegister());
2710 summary->set_out(Location::SameAsFirstInput()); 2711 summary->set_out(Location::SameAsFirstInput());
2711 return summary; 2712 return summary;
2712 } 2713 }
2713 case Token::kADD: 2714 case Token::kADD:
2714 case Token::kSUB: { 2715 case Token::kSUB: {
2715 const intptr_t kNumTemps = 2; 2716 const intptr_t kNumTemps = 2;
2716 LocationSummary* summary = 2717 LocationSummary* summary =
2717 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2718 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2718 summary->set_in(0, Location::RequiresXmmRegister()); 2719 summary->set_in(0, Location::RequiresFpuRegister());
2719 summary->set_in(1, Location::RequiresXmmRegister()); 2720 summary->set_in(1, Location::RequiresFpuRegister());
2720 summary->set_temp(0, Location::RequiresRegister()); 2721 summary->set_temp(0, Location::RequiresRegister());
2721 summary->set_temp(1, Location::RequiresRegister()); 2722 summary->set_temp(1, Location::RequiresRegister());
2722 summary->set_out(Location::SameAsFirstInput()); 2723 summary->set_out(Location::SameAsFirstInput());
2723 return summary; 2724 return summary;
2724 } 2725 }
2725 default: 2726 default:
2726 UNREACHABLE(); 2727 UNREACHABLE();
2727 return NULL; 2728 return NULL;
2728 } 2729 }
2729 } 2730 }
2730 2731
2731 2732
2732 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2733 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2733 XmmRegister left = locs()->in(0).xmm_reg(); 2734 XmmRegister left = locs()->in(0).fpu_reg();
2734 XmmRegister right = locs()->in(1).xmm_reg(); 2735 XmmRegister right = locs()->in(1).fpu_reg();
2735 2736
2736 ASSERT(locs()->out().xmm_reg() == left); 2737 ASSERT(locs()->out().fpu_reg() == left);
2737 2738
2738 switch (op_kind()) { 2739 switch (op_kind()) {
2739 case Token::kBIT_AND: __ andpd(left, right); break; 2740 case Token::kBIT_AND: __ andpd(left, right); break;
2740 case Token::kBIT_OR: __ orpd(left, right); break; 2741 case Token::kBIT_OR: __ orpd(left, right); break;
2741 case Token::kBIT_XOR: __ xorpd(left, right); break; 2742 case Token::kBIT_XOR: __ xorpd(left, right); break;
2742 case Token::kADD: 2743 case Token::kADD:
2743 case Token::kSUB: { 2744 case Token::kSUB: {
2744 Register lo = locs()->temp(0).reg(); 2745 Register lo = locs()->temp(0).reg();
2745 Register hi = locs()->temp(1).reg(); 2746 Register hi = locs()->temp(1).reg();
2746 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2747 Label* deopt = compiler->AddDeoptStub(deopt_id(),
(...skipping 23 matching lines...) Expand all
2770 default: UNREACHABLE(); 2771 default: UNREACHABLE();
2771 } 2772 }
2772 } 2773 }
2773 2774
2774 2775
2775 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const { 2776 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const {
2776 const intptr_t kNumInputs = 2; 2777 const intptr_t kNumInputs = 2;
2777 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1; 2778 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1;
2778 LocationSummary* summary = 2779 LocationSummary* summary =
2779 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2780 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2780 summary->set_in(0, Location::RequiresXmmRegister()); 2781 summary->set_in(0, Location::RequiresFpuRegister());
2781 summary->set_in(1, Location::RegisterLocation(ECX)); 2782 summary->set_in(1, Location::RegisterLocation(ECX));
2782 summary->set_temp(0, Location::RequiresRegister()); 2783 summary->set_temp(0, Location::RequiresRegister());
2783 if (op_kind() == Token::kSHL) { 2784 if (op_kind() == Token::kSHL) {
2784 summary->set_temp(1, Location::RequiresRegister()); 2785 summary->set_temp(1, Location::RequiresRegister());
2785 } 2786 }
2786 summary->set_out(Location::SameAsFirstInput()); 2787 summary->set_out(Location::SameAsFirstInput());
2787 return summary; 2788 return summary;
2788 } 2789 }
2789 2790
2790 2791
2791 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2792 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2792 XmmRegister left = locs()->in(0).xmm_reg(); 2793 XmmRegister left = locs()->in(0).fpu_reg();
2793 ASSERT(locs()->in(1).reg() == ECX); 2794 ASSERT(locs()->in(1).reg() == ECX);
2794 ASSERT(locs()->out().xmm_reg() == left); 2795 ASSERT(locs()->out().fpu_reg() == left);
2795 2796
2796 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2797 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2797 kDeoptShiftMintOp); 2798 kDeoptShiftMintOp);
2798 Label done; 2799 Label done;
2799 __ testl(ECX, ECX); 2800 __ testl(ECX, ECX);
2800 __ j(ZERO, &done); // Shift by 0 is a nop. 2801 __ j(ZERO, &done); // Shift by 0 is a nop.
2801 __ subl(ESP, Immediate(2 * kWordSize)); 2802 __ subl(ESP, Immediate(2 * kWordSize));
2802 __ movq(Address(ESP, 0), left); 2803 __ movq(Address(ESP, 0), left);
2803 // Deoptimize if shift count is > 31. 2804 // Deoptimize if shift count is > 31.
2804 // sarl operation masks the count to 5 bits and 2805 // sarl operation masks the count to 5 bits and
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2840 __ addl(ESP, Immediate(2 * kWordSize)); 2841 __ addl(ESP, Immediate(2 * kWordSize));
2841 __ Bind(&done); 2842 __ Bind(&done);
2842 } 2843 }
2843 2844
2844 2845
2845 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const { 2846 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const {
2846 const intptr_t kNumInputs = 1; 2847 const intptr_t kNumInputs = 1;
2847 const intptr_t kNumTemps = 0; 2848 const intptr_t kNumTemps = 0;
2848 LocationSummary* summary = 2849 LocationSummary* summary =
2849 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2850 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2850 summary->set_in(0, Location::RequiresXmmRegister()); 2851 summary->set_in(0, Location::RequiresFpuRegister());
2851 summary->set_out(Location::SameAsFirstInput()); 2852 summary->set_out(Location::SameAsFirstInput());
2852 return summary; 2853 return summary;
2853 } 2854 }
2854 2855
2855 2856
2856 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2857 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2857 ASSERT(op_kind() == Token::kBIT_NOT); 2858 ASSERT(op_kind() == Token::kBIT_NOT);
2858 XmmRegister value = locs()->in(0).xmm_reg(); 2859 XmmRegister value = locs()->in(0).fpu_reg();
2859 ASSERT(value == locs()->out().xmm_reg()); 2860 ASSERT(value == locs()->out().fpu_reg());
2860 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. 2861 __ pcmpeqq(XMM0, XMM0); // Generate all 1's.
2861 __ pxor(value, XMM0); 2862 __ pxor(value, XMM0);
2862 } 2863 }
2863 2864
2864 2865
2866 LocationSummary* ThrowInstr::MakeLocationSummary() const {
2867 return new LocationSummary(0, 0, LocationSummary::kCall);
2868 }
2869
2870
2871
2872 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2873 compiler->GenerateCallRuntime(token_pos(),
2874 kThrowRuntimeEntry,
2875 locs());
2876 __ int3();
2877 }
2878
2879
2880 LocationSummary* ReThrowInstr::MakeLocationSummary() const {
2881 return new LocationSummary(0, 0, LocationSummary::kCall);
2882 }
2883
2884
2885 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2886 compiler->GenerateCallRuntime(token_pos(),
2887 kReThrowRuntimeEntry,
2888 locs());
2889 __ int3();
2890 }
2891
2892
2893 LocationSummary* GotoInstr::MakeLocationSummary() const {
2894 return new LocationSummary(0, 0, LocationSummary::kNoCall);
2895 }
2896
2897
2898 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2899 // Add deoptimization descriptor for deoptimizing instructions
2900 // that may be inserted before this instruction.
2901 if (!compiler->is_optimizing()) {
2902 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
2903 GetDeoptId(),
2904 0); // No token position.
2905 }
2906
2907 if (HasParallelMove()) {
2908 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
2909 }
2910
2911 // We can fall through if the successor is the next block in the list.
2912 // Otherwise, we need a jump.
2913 if (!compiler->IsNextBlock(successor())) {
2914 __ jmp(compiler->GetBlockLabel(successor()));
2915 }
2916 }
2917
2918
2919 static Condition NegateCondition(Condition condition) {
2920 switch (condition) {
2921 case EQUAL: return NOT_EQUAL;
2922 case NOT_EQUAL: return EQUAL;
2923 case LESS: return GREATER_EQUAL;
2924 case LESS_EQUAL: return GREATER;
2925 case GREATER: return LESS_EQUAL;
2926 case GREATER_EQUAL: return LESS;
2927 case BELOW: return ABOVE_EQUAL;
2928 case BELOW_EQUAL: return ABOVE;
2929 case ABOVE: return BELOW_EQUAL;
2930 case ABOVE_EQUAL: return BELOW;
2931 default:
2932 OS::Print("Error %d\n", condition);
2933 UNIMPLEMENTED();
2934 return EQUAL;
2935 }
2936 }
2937
2938
2939 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler,
2940 bool value) {
2941 if (value && compiler->IsNextBlock(false_successor())) {
2942 __ jmp(compiler->GetBlockLabel(true_successor()));
2943 } else if (!value && compiler->IsNextBlock(true_successor())) {
2944 __ jmp(compiler->GetBlockLabel(false_successor()));
2945 }
2946 }
2947
2948
2949 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler,
2950 Condition true_condition) {
2951 if (compiler->IsNextBlock(false_successor())) {
2952 // If the next block is the false successor we will fall through to it.
2953 __ j(true_condition, compiler->GetBlockLabel(true_successor()));
2954 } else {
2955 // If the next block is the true successor we negate comparison and fall
2956 // through to it.
2957 ASSERT(compiler->IsNextBlock(true_successor()));
2958 Condition false_condition = NegateCondition(true_condition);
2959 __ j(false_condition, compiler->GetBlockLabel(false_successor()));
2960 }
2961 }
2962
2963
2964 LocationSummary* CurrentContextInstr::MakeLocationSummary() const {
2965 return LocationSummary::Make(0,
2966 Location::RequiresRegister(),
2967 LocationSummary::kNoCall);
2968 }
2969
2970
2971 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2972 __ MoveRegister(locs()->out().reg(), CTX);
2973 }
2974
2975
2976 LocationSummary* StrictCompareInstr::MakeLocationSummary() const {
2977 const intptr_t kNumInputs = 2;
2978 const intptr_t kNumTemps = 0;
2979 LocationSummary* locs =
2980 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2981 locs->set_in(0, Location::RegisterOrConstant(left()));
2982 locs->set_in(1, Location::RegisterOrConstant(right()));
2983 locs->set_out(Location::RequiresRegister());
2984 return locs;
2985 }
2986
2987
2988 // Special code for numbers (compare values instead of references.)
2989 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2990 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
2991 Location left = locs()->in(0);
2992 Location right = locs()->in(1);
2993 if (left.IsConstant() && right.IsConstant()) {
2994 // TODO(vegorov): should be eliminated earlier by constant propagation.
2995 const bool result = (kind() == Token::kEQ_STRICT) ?
2996 left.constant().raw() == right.constant().raw() :
2997 left.constant().raw() != right.constant().raw();
2998 __ LoadObject(locs()->out().reg(), result ? Bool::True() : Bool::False());
2999 return;
3000 }
3001 if (left.IsConstant()) {
3002 compiler->EmitEqualityRegConstCompare(right.reg(),
3003 left.constant(),
3004 needs_number_check());
3005 } else if (right.IsConstant()) {
3006 compiler->EmitEqualityRegConstCompare(left.reg(),
3007 right.constant(),
3008 needs_number_check());
3009 } else {
3010 compiler->EmitEqualityRegRegCompare(left.reg(),
3011 right.reg(),
3012 needs_number_check());
3013 }
3014
3015 Register result = locs()->out().reg();
3016 Label load_true, done;
3017 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
3018 __ j(true_condition, &load_true, Assembler::kNearJump);
3019 __ LoadObject(result, Bool::False());
3020 __ jmp(&done, Assembler::kNearJump);
3021 __ Bind(&load_true);
3022 __ LoadObject(result, Bool::True());
3023 __ Bind(&done);
3024 }
3025
3026
3027 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
3028 BranchInstr* branch) {
3029 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
3030 Location left = locs()->in(0);
3031 Location right = locs()->in(1);
3032 if (left.IsConstant() && right.IsConstant()) {
3033 // TODO(vegorov): should be eliminated earlier by constant propagation.
3034 const bool result = (kind() == Token::kEQ_STRICT) ?
3035 left.constant().raw() == right.constant().raw() :
3036 left.constant().raw() != right.constant().raw();
3037 branch->EmitBranchOnValue(compiler, result);
3038 return;
3039 }
3040 if (left.IsConstant()) {
3041 compiler->EmitEqualityRegConstCompare(right.reg(),
3042 left.constant(),
3043 needs_number_check());
3044 } else if (right.IsConstant()) {
3045 compiler->EmitEqualityRegConstCompare(left.reg(),
3046 right.constant(),
3047 needs_number_check());
3048 } else {
3049 compiler->EmitEqualityRegRegCompare(left.reg(),
3050 right.reg(),
3051 needs_number_check());
3052 }
3053
3054 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
3055 branch->EmitBranchOnCondition(compiler, true_condition);
3056 }
3057
3058
3059 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3060 // The arguments to the stub include the closure, as does the arguments
3061 // descriptor.
3062 Register temp_reg = locs()->temp(0).reg();
3063 int argument_count = ArgumentCount();
3064 const Array& arguments_descriptor =
3065 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
3066 argument_names()));
3067 __ LoadObject(temp_reg, arguments_descriptor);
3068 compiler->GenerateDartCall(deopt_id(),
3069 token_pos(),
3070 &StubCode::CallClosureFunctionLabel(),
3071 PcDescriptors::kOther,
3072 locs());
3073 __ Drop(argument_count);
3074 }
3075
3076
3077 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
3078 return LocationSummary::Make(1,
3079 Location::RequiresRegister(),
3080 LocationSummary::kNoCall);
3081 }
3082
3083
3084 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3085 Register value = locs()->in(0).reg();
3086 Register result = locs()->out().reg();
3087
3088 Label done;
3089 __ LoadObject(result, Bool::True());
3090 __ CompareRegisters(result, value);
3091 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
3092 __ LoadObject(result, Bool::False());
3093 __ Bind(&done);
3094 }
3095
3096
3097 LocationSummary* ChainContextInstr::MakeLocationSummary() const {
3098 return LocationSummary::Make(1,
3099 Location::NoLocation(),
3100 LocationSummary::kNoCall);
3101 }
3102
3103
3104 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3105 Register context_value = locs()->in(0).reg();
3106
3107 // Chain the new context in context_value to its parent in CTX.
3108 __ StoreIntoObject(context_value,
3109 FieldAddress(context_value, Context::parent_offset()),
3110 CTX);
3111 // Set new context as current context.
3112 __ MoveRegister(CTX, context_value);
3113 }
3114
3115
3116 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const {
3117 const intptr_t kNumInputs = 2;
3118 const intptr_t kNumTemps = 0;
3119 LocationSummary* locs =
3120 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3121 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
3122 : Location::RequiresRegister());
3123 locs->set_in(1, Location::RequiresRegister());
3124 return locs;
3125 }
3126
3127
3128 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3129 Register value_reg = locs()->in(0).reg();
3130 Register dest_reg = locs()->in(1).reg();
3131
3132 if (value()->NeedsStoreBuffer()) {
3133 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
3134 value_reg);
3135 } else {
3136 __ StoreIntoObjectNoBarrier(
3137 dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg);
3138 }
3139 }
3140
3141
3142 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const {
3143 return MakeCallSummary();
3144 }
3145
3146
3147 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3148 const Class& cls = Class::ZoneHandle(constructor().Owner());
3149 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
3150 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
3151 compiler->GenerateCall(token_pos(),
3152 &label,
3153 PcDescriptors::kOther,
3154 locs());
3155 __ Drop(ArgumentCount()); // Discard arguments.
3156 }
3157
3158
3159 LocationSummary* CreateClosureInstr::MakeLocationSummary() const {
3160 return MakeCallSummary();
3161 }
3162
3163
3164 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3165 const Function& closure_function = function();
3166 ASSERT(!closure_function.IsImplicitStaticClosureFunction());
3167 const Code& stub = Code::Handle(
3168 StubCode::GetAllocationStubForClosure(closure_function));
3169 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint());
3170 compiler->GenerateCall(token_pos(),
3171 &label,
3172 PcDescriptors::kOther,
3173 locs());
3174 __ Drop(2); // Discard type arguments and receiver.
3175 }
3176
2865 } // namespace dart 3177 } // namespace dart
2866 3178
2867 #undef __ 3179 #undef __
2868 3180
2869 #endif // defined TARGET_ARCH_X64 3181 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698