| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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" |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 __ Bind(&done); | 293 __ Bind(&done); |
| 294 } | 294 } |
| 295 | 295 |
| 296 | 296 |
| 297 static Condition TokenKindToDoubleCondition(Token::Kind kind) { | 297 static Condition TokenKindToDoubleCondition(Token::Kind kind) { |
| 298 switch (kind) { | 298 switch (kind) { |
| 299 case Token::kEQ: return EQUAL; | 299 case Token::kEQ: return EQUAL; |
| 300 case Token::kLT: return BELOW; | 300 case Token::kLT: return BELOW; |
| 301 case Token::kGT: return ABOVE; | 301 case Token::kGT: return ABOVE; |
| 302 case Token::kLTE: return BELOW_EQUAL; | 302 case Token::kLTE: return BELOW_EQUAL; |
| 303 case Token::kGTE: return ABOVE_EQUAL; |
| 303 default: | 304 default: |
| 304 UNREACHABLE(); | 305 UNREACHABLE(); |
| 305 return OVERFLOW; | 306 return OVERFLOW; |
| 306 } | 307 } |
| 307 } | 308 } |
| 308 | 309 |
| 309 | 310 |
| 310 static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler, | 311 static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler, |
| 311 RelationalOpComp* comp) { | 312 RelationalOpComp* comp) { |
| 312 Register left = comp->locs()->in(0).reg(); | 313 Register left = comp->locs()->in(0).reg(); |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 __ popl(result); // Pop new instance. | 642 __ popl(result); // Pop new instance. |
| 642 } | 643 } |
| 643 | 644 |
| 644 | 645 |
| 645 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 646 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
| 646 return LocationSummary::Make(1, Location::RequiresRegister()); | 647 return LocationSummary::Make(1, Location::RequiresRegister()); |
| 647 } | 648 } |
| 648 | 649 |
| 649 | 650 |
| 650 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 651 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 651 Register obj = locs()->in(0).reg(); | 652 Register instance = locs()->in(0).reg(); |
| 652 Register result = locs()->out().reg(); | 653 Register result = locs()->out().reg(); |
| 654 if (class_ids() != NULL) { |
| 655 ASSERT(original() != NULL); |
| 656 Label* deopt = compiler->AddDeoptStub(original()->cid(), |
| 657 original()->token_index(), |
| 658 original()->try_index(), |
| 659 kDeoptInstanceGetterSameTarget, |
| 660 instance, |
| 661 kNoRegister); |
| 662 // Smis do not have instance fields (Smi class is always first). |
| 663 // Use 'result' as temporary register. |
| 664 ASSERT(result != instance); |
| 665 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt); |
| 666 } |
| 653 | 667 |
| 654 __ movl(result, FieldAddress(obj, offset_in_bytes())); | 668 __ movl(result, FieldAddress(instance, offset_in_bytes())); |
| 655 } | 669 } |
| 656 | 670 |
| 657 | 671 |
| 658 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { | 672 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
| 659 const intptr_t kNumInputs = 1; | 673 const intptr_t kNumInputs = 1; |
| 660 const intptr_t kNumTemps = 1; | 674 const intptr_t kNumTemps = 1; |
| 661 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 675 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| 662 locs->set_in(0, Location::RequiresRegister()); | 676 locs->set_in(0, Location::RequiresRegister()); |
| 663 locs->set_temp(0, Location::RequiresRegister()); | 677 locs->set_temp(0, Location::RequiresRegister()); |
| 664 locs->set_out(Location::SameAsFirstInput()); | 678 locs->set_out(Location::SameAsFirstInput()); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 compiler->GenerateCallRuntime(cid(), | 934 compiler->GenerateCallRuntime(cid(), |
| 921 token_index(), | 935 token_index(), |
| 922 try_index(), | 936 try_index(), |
| 923 kStackOverflowRuntimeEntry); | 937 kStackOverflowRuntimeEntry); |
| 924 __ Bind(&no_stack_overflow); | 938 __ Bind(&no_stack_overflow); |
| 925 } | 939 } |
| 926 | 940 |
| 927 | 941 |
| 928 LocationSummary* BinaryOpComp::MakeLocationSummary() const { | 942 LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
| 929 const intptr_t kNumInputs = 2; | 943 const intptr_t kNumInputs = 2; |
| 930 const intptr_t kNumTemps = 0; | |
| 931 if (operands_type() == kDoubleOperands) { | 944 if (operands_type() == kDoubleOperands) { |
| 945 const intptr_t kNumTemps = 1; |
| 932 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 946 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 933 summary->set_in(0, Location::RequiresRegister()); | 947 summary->set_in(0, Location::RequiresRegister()); |
| 934 summary->set_in(1, Location::RequiresRegister()); | 948 summary->set_in(1, Location::RequiresRegister()); |
| 935 summary->set_out(Location::SameAsFirstInput()); | 949 summary->set_out(Location::RegisterLocation(EAX)); |
| 950 summary->set_temp(0, Location::RequiresRegister()); |
| 936 return summary; | 951 return summary; |
| 937 } | 952 } |
| 938 ASSERT(operands_type() == kSmiOperands); | 953 ASSERT(operands_type() == kSmiOperands); |
| 939 if (op_kind() == Token::kTRUNCDIV) { | 954 if (op_kind() == Token::kTRUNCDIV) { |
| 940 const intptr_t kNumTemps = 3; | 955 const intptr_t kNumTemps = 3; |
| 941 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 956 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 942 summary->set_in(0, Location::RegisterLocation(EAX)); | 957 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 943 summary->set_in(1, Location::RegisterLocation(ECX)); | 958 summary->set_in(1, Location::RegisterLocation(ECX)); |
| 944 summary->set_out(Location::SameAsFirstInput()); | 959 summary->set_out(Location::SameAsFirstInput()); |
| 945 summary->set_temp(0, Location::RegisterLocation(EBX)); | 960 summary->set_temp(0, Location::RegisterLocation(EBX)); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1103 } | 1118 } |
| 1104 default: | 1119 default: |
| 1105 UNREACHABLE(); | 1120 UNREACHABLE(); |
| 1106 break; | 1121 break; |
| 1107 } | 1122 } |
| 1108 } | 1123 } |
| 1109 | 1124 |
| 1110 | 1125 |
| 1111 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, | 1126 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, |
| 1112 BinaryOpComp* comp) { | 1127 BinaryOpComp* comp) { |
| 1113 // TODO(srdjan): Remove this code once BinaryOpComp has been implemeneted | |
| 1114 // for all intended operations. | |
| 1115 Register left = comp->locs()->in(0).reg(); | 1128 Register left = comp->locs()->in(0).reg(); |
| 1116 Register right = comp->locs()->in(1).reg(); | 1129 Register right = comp->locs()->in(1).reg(); |
| 1130 Register temp = comp->locs()->temp(0).reg(); |
| 1131 Register result = comp->locs()->out().reg(); |
| 1132 |
| 1133 const Class& double_class = |
| 1134 Class::ZoneHandle(Isolate::Current()->object_store()->double_class()); |
| 1135 const Code& stub = |
| 1136 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1137 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1117 __ pushl(left); | 1138 __ pushl(left); |
| 1118 __ pushl(right); | 1139 __ pushl(right); |
| 1119 InstanceCallComp* instance_call_comp = comp->instance_call(); | 1140 compiler->GenerateCall(comp->instance_call()->token_index(), |
| 1120 instance_call_comp->EmitNativeCode(compiler); | 1141 comp->instance_call()->try_index(), |
| 1121 __ MoveRegister(comp->locs()->out().reg(), EAX); | 1142 &label, |
| 1143 PcDescriptors::kOther); |
| 1144 // Newly allocated object is now in the result register (RAX). |
| 1145 ASSERT(result == EAX); |
| 1146 __ popl(right); |
| 1147 __ popl(left); |
| 1148 |
| 1149 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), |
| 1150 comp->instance_call()->token_index(), |
| 1151 comp->instance_call()->try_index(), |
| 1152 kDeoptDoubleBinaryOp, |
| 1153 left, |
| 1154 right); |
| 1155 |
| 1156 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); |
| 1157 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); |
| 1158 |
| 1159 switch (comp->op_kind()) { |
| 1160 case Token::kADD: __ addsd(XMM0, XMM1); break; |
| 1161 case Token::kSUB: __ subsd(XMM0, XMM1); break; |
| 1162 case Token::kMUL: __ mulsd(XMM0, XMM1); break; |
| 1163 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
| 1164 default: UNREACHABLE(); |
| 1165 } |
| 1166 |
| 1167 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 1122 } | 1168 } |
| 1123 | 1169 |
| 1124 | 1170 |
| 1125 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1171 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1126 switch (operands_type()) { | 1172 switch (operands_type()) { |
| 1127 case kSmiOperands: | 1173 case kSmiOperands: |
| 1128 EmitSmiBinaryOp(compiler, this); | 1174 EmitSmiBinaryOp(compiler, this); |
| 1129 break; | 1175 break; |
| 1130 | 1176 |
| 1131 case kDoubleOperands: | 1177 case kDoubleOperands: |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 UNREACHABLE(); | 1293 UNREACHABLE(); |
| 1248 } | 1294 } |
| 1249 } | 1295 } |
| 1250 | 1296 |
| 1251 | 1297 |
| 1252 } // namespace dart | 1298 } // namespace dart |
| 1253 | 1299 |
| 1254 #undef __ | 1300 #undef __ |
| 1255 | 1301 |
| 1256 #endif // defined TARGET_ARCH_X64 | 1302 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |