| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 return OVERFLOW; | 255 return OVERFLOW; |
| 256 } | 256 } |
| 257 } | 257 } |
| 258 | 258 |
| 259 | 259 |
| 260 static void EmitSmiRelationalOp(FlowGraphCompiler* compiler, | 260 static void EmitSmiRelationalOp(FlowGraphCompiler* compiler, |
| 261 RelationalOpComp* comp) { | 261 RelationalOpComp* comp) { |
| 262 Register left = comp->locs()->in(0).reg(); | 262 Register left = comp->locs()->in(0).reg(); |
| 263 Register right = comp->locs()->in(1).reg(); | 263 Register right = comp->locs()->in(1).reg(); |
| 264 Register result = comp->locs()->out().reg(); | 264 Register result = comp->locs()->out().reg(); |
| 265 Register temp = comp->locs()->temp(0).reg(); |
| 265 Label* deopt = compiler->AddDeoptStub(comp->cid(), | 266 Label* deopt = compiler->AddDeoptStub(comp->cid(), |
| 266 comp->token_index(), | 267 comp->token_index(), |
| 267 comp->try_index(), | 268 comp->try_index(), |
| 268 kDeoptSmiCompareSmis, | 269 kDeoptSmiCompareSmis, |
| 269 left, | 270 left, |
| 270 right); | 271 right); |
| 271 __ movq(TMP, left); | 272 __ movq(temp, left); |
| 272 __ orq(TMP, right); | 273 __ orq(temp, right); |
| 273 __ testq(TMP, Immediate(kSmiTagMask)); | 274 __ testq(temp, Immediate(kSmiTagMask)); |
| 274 __ j(NOT_ZERO, deopt); | 275 __ j(NOT_ZERO, deopt); |
| 275 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 276 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 276 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 277 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 277 Condition condition = TokenKindToSmiCondition(comp->kind()); | 278 Condition condition = TokenKindToSmiCondition(comp->kind()); |
| 278 | 279 |
| 279 Label done, is_true; | 280 Label done, is_true; |
| 280 __ cmpq(left, right); | 281 __ cmpq(left, right); |
| 281 __ j(condition, &is_true); | 282 __ j(condition, &is_true); |
| 282 __ LoadObject(result, bool_false); | 283 __ LoadObject(result, bool_false); |
| 283 __ jmp(&done); | 284 __ jmp(&done); |
| 284 __ Bind(&is_true); | 285 __ Bind(&is_true); |
| 285 __ LoadObject(result, bool_true); | 286 __ LoadObject(result, bool_true); |
| 286 __ Bind(&done); | 287 __ Bind(&done); |
| 287 } | 288 } |
| 288 | 289 |
| 289 | 290 |
| 290 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 291 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 291 if (operands_class_id() == kSmi) { | 292 if (operands_class_id() == kSmi) { |
| 292 const intptr_t kNumInputs = 2; | 293 const intptr_t kNumInputs = 2; |
| 293 const intptr_t kNumTemps = 0; | 294 const intptr_t kNumTemps = 1; |
| 294 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 295 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 295 summary->set_in(0, Location::RequiresRegister()); | 296 summary->set_in(0, Location::RequiresRegister()); |
| 296 summary->set_in(1, Location::RequiresRegister()); | 297 summary->set_in(1, Location::RequiresRegister()); |
| 297 summary->set_out(Location::RequiresRegister()); | 298 summary->set_out(Location::RequiresRegister()); |
| 299 summary->set_temp(0, Location::RequiresRegister()); |
| 298 return summary; | 300 return summary; |
| 299 } | 301 } |
| 300 if (operands_class_id() == kDouble) { | 302 if (operands_class_id() == kDouble) { |
| 301 const intptr_t kNumInputs = 2; | 303 const intptr_t kNumInputs = 2; |
| 302 const intptr_t kNumTemps = 1; | 304 const intptr_t kNumTemps = 1; |
| 303 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 305 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 304 summary->set_in(0, Location::RequiresRegister()); | 306 summary->set_in(0, Location::RequiresRegister()); |
| 305 summary->set_in(1, Location::RequiresRegister()); | 307 summary->set_in(1, Location::RequiresRegister()); |
| 306 summary->set_out(Location::RequiresRegister()); | 308 summary->set_out(Location::RequiresRegister()); |
| 307 summary->set_temp(0, Location::RequiresRegister()); | 309 summary->set_temp(0, Location::RequiresRegister()); |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 __ popq(result); // Pop new instance. | 749 __ popq(result); // Pop new instance. |
| 748 } | 750 } |
| 749 | 751 |
| 750 | 752 |
| 751 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 753 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
| 752 return LocationSummary::Make(1, Location::RequiresRegister()); | 754 return LocationSummary::Make(1, Location::RequiresRegister()); |
| 753 } | 755 } |
| 754 | 756 |
| 755 | 757 |
| 756 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 758 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 757 Register obj = locs()->in(0).reg(); | 759 Register instance = locs()->in(0).reg(); |
| 758 Register result = locs()->out().reg(); | 760 Register result = locs()->out().reg(); |
| 761 if (class_ids() != NULL) { |
| 762 ASSERT(original() != NULL); |
| 763 Label* deopt = compiler->AddDeoptStub(original()->cid(), |
| 764 original()->token_index(), |
| 765 original()->try_index(), |
| 766 kDeoptInstanceGetterSameTarget, |
| 767 instance, |
| 768 kNoRegister); |
| 769 // Smis do not have instance fields (Smi class is always first). |
| 770 // Use 'result' as temporary register. |
| 771 ASSERT(result != instance); |
| 772 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt); |
| 773 } |
| 759 | 774 |
| 760 __ movq(result, FieldAddress(obj, offset_in_bytes())); | 775 __ movq(result, FieldAddress(instance, offset_in_bytes())); |
| 761 } | 776 } |
| 762 | 777 |
| 763 | 778 |
| 764 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { | 779 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
| 765 const intptr_t kNumInputs = 1; | 780 const intptr_t kNumInputs = 1; |
| 766 const intptr_t kNumTemps = 0; | 781 const intptr_t kNumTemps = 0; |
| 767 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 782 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| 768 locs->set_in(0, Location::RequiresRegister()); | 783 locs->set_in(0, Location::RequiresRegister()); |
| 769 locs->set_out(Location::SameAsFirstInput()); | 784 locs->set_out(Location::SameAsFirstInput()); |
| 770 return locs; | 785 return locs; |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1219 } | 1234 } |
| 1220 | 1235 |
| 1221 | 1236 |
| 1222 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, | 1237 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, |
| 1223 BinaryOpComp* comp) { | 1238 BinaryOpComp* comp) { |
| 1224 Register left = comp->locs()->in(0).reg(); | 1239 Register left = comp->locs()->in(0).reg(); |
| 1225 Register right = comp->locs()->in(1).reg(); | 1240 Register right = comp->locs()->in(1).reg(); |
| 1226 Register temp = comp->locs()->temp(0).reg(); | 1241 Register temp = comp->locs()->temp(0).reg(); |
| 1227 Register result = comp->locs()->out().reg(); | 1242 Register result = comp->locs()->out().reg(); |
| 1228 | 1243 |
| 1229 | |
| 1230 const Class& double_class = | 1244 const Class& double_class = |
| 1231 Class::ZoneHandle(Isolate::Current()->object_store()->double_class()); | 1245 Class::ZoneHandle(Isolate::Current()->object_store()->double_class()); |
| 1232 const Code& stub = | 1246 const Code& stub = |
| 1233 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1247 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1234 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1248 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1235 __ pushq(left); | 1249 __ pushq(left); |
| 1236 __ pushq(right); | 1250 __ pushq(right); |
| 1237 compiler->GenerateCall(comp->instance_call()->token_index(), | 1251 compiler->GenerateCall(comp->instance_call()->token_index(), |
| 1238 comp->instance_call()->try_index(), | 1252 comp->instance_call()->try_index(), |
| 1239 &label, | 1253 &label, |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1389 } else { | 1403 } else { |
| 1390 UNREACHABLE(); | 1404 UNREACHABLE(); |
| 1391 } | 1405 } |
| 1392 } | 1406 } |
| 1393 | 1407 |
| 1394 } // namespace dart | 1408 } // namespace dart |
| 1395 | 1409 |
| 1396 #undef __ | 1410 #undef __ |
| 1397 | 1411 |
| 1398 #endif // defined TARGET_ARCH_X64 | 1412 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |