OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 } | 422 } |
423 | 423 |
424 | 424 |
425 double LCodeGen::ToDouble(LConstantOperand* op) const { | 425 double LCodeGen::ToDouble(LConstantOperand* op) const { |
426 HConstant* constant = chunk_->LookupConstant(op); | 426 HConstant* constant = chunk_->LookupConstant(op); |
427 ASSERT(constant->HasDoubleValue()); | 427 ASSERT(constant->HasDoubleValue()); |
428 return constant->DoubleValue(); | 428 return constant->DoubleValue(); |
429 } | 429 } |
430 | 430 |
431 | 431 |
432 ExternalReference LCodeGen::ToExternalReference(LConstantOperand* op) const { | |
433 HConstant* constant = chunk_->LookupConstant(op); | |
434 ASSERT(constant->HasExternalReferenceValue()); | |
435 return constant->ExternalReferenceValue(); | |
436 } | |
437 | |
438 | |
439 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { | 432 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
440 HConstant* constant = chunk_->LookupConstant(op); | 433 HConstant* constant = chunk_->LookupConstant(op); |
441 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); | 434 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); |
442 return constant->handle(); | 435 return constant->handle(); |
443 } | 436 } |
444 | 437 |
445 | 438 |
446 Operand LCodeGen::ToOperand(LOperand* op) const { | 439 Operand LCodeGen::ToOperand(LOperand* op) const { |
447 // Does not handle registers. In X64 assembler, plain registers are not | 440 // Does not handle registers. In X64 assembler, plain registers are not |
448 // representable as an Operand. | 441 // representable as an Operand. |
(...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1453 case Token::SHR: | 1446 case Token::SHR: |
1454 if (shift_count == 0 && instr->can_deopt()) { | 1447 if (shift_count == 0 && instr->can_deopt()) { |
1455 __ testl(ToRegister(left), ToRegister(left)); | 1448 __ testl(ToRegister(left), ToRegister(left)); |
1456 DeoptimizeIf(negative, instr->environment()); | 1449 DeoptimizeIf(negative, instr->environment()); |
1457 } else { | 1450 } else { |
1458 __ shrl(ToRegister(left), Immediate(shift_count)); | 1451 __ shrl(ToRegister(left), Immediate(shift_count)); |
1459 } | 1452 } |
1460 break; | 1453 break; |
1461 case Token::SHL: | 1454 case Token::SHL: |
1462 if (shift_count != 0) { | 1455 if (shift_count != 0) { |
1463 if (instr->hydrogen_value()->representation().IsSmi()) { | 1456 __ shll(ToRegister(left), Immediate(shift_count)); |
1464 __ shl(ToRegister(left), Immediate(shift_count)); | |
1465 } else { | |
1466 __ shll(ToRegister(left), Immediate(shift_count)); | |
1467 } | |
1468 } | 1457 } |
1469 break; | 1458 break; |
1470 default: | 1459 default: |
1471 UNREACHABLE(); | 1460 UNREACHABLE(); |
1472 break; | 1461 break; |
1473 } | 1462 } |
1474 } | 1463 } |
1475 } | 1464 } |
1476 | 1465 |
1477 | 1466 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1523 if (int_val == 0) { | 1512 if (int_val == 0) { |
1524 __ xorps(res, res); | 1513 __ xorps(res, res); |
1525 } else { | 1514 } else { |
1526 Register tmp = ToRegister(instr->temp()); | 1515 Register tmp = ToRegister(instr->temp()); |
1527 __ Set(tmp, int_val); | 1516 __ Set(tmp, int_val); |
1528 __ movq(res, tmp); | 1517 __ movq(res, tmp); |
1529 } | 1518 } |
1530 } | 1519 } |
1531 | 1520 |
1532 | 1521 |
1533 void LCodeGen::DoConstantE(LConstantE* instr) { | |
1534 __ LoadAddress(ToRegister(instr->result()), instr->value()); | |
1535 } | |
1536 | |
1537 | |
1538 void LCodeGen::DoConstantT(LConstantT* instr) { | 1522 void LCodeGen::DoConstantT(LConstantT* instr) { |
1539 Handle<Object> value = instr->value(); | 1523 Handle<Object> value = instr->value(); |
1540 AllowDeferredHandleDereference smi_check; | 1524 AllowDeferredHandleDereference smi_check; |
1541 __ LoadObject(ToRegister(instr->result()), value); | 1525 __ LoadObject(ToRegister(instr->result()), value); |
1542 } | 1526 } |
1543 | 1527 |
1544 | 1528 |
1545 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { | 1529 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { |
1546 Register result = ToRegister(instr->result()); | 1530 Register result = ToRegister(instr->result()); |
1547 Register map = ToRegister(instr->value()); | 1531 Register map = ToRegister(instr->value()); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 } | 1692 } |
1709 } | 1693 } |
1710 } | 1694 } |
1711 | 1695 |
1712 | 1696 |
1713 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 1697 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
1714 LOperand* left = instr->left(); | 1698 LOperand* left = instr->left(); |
1715 LOperand* right = instr->right(); | 1699 LOperand* right = instr->right(); |
1716 ASSERT(left->Equals(instr->result())); | 1700 ASSERT(left->Equals(instr->result())); |
1717 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1701 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
1718 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { | 1702 if (instr->hydrogen()->representation().IsInteger32()) { |
1719 Label return_left; | 1703 Label return_left; |
1720 Condition condition = (operation == HMathMinMax::kMathMin) | 1704 Condition condition = (operation == HMathMinMax::kMathMin) |
1721 ? less_equal | 1705 ? less_equal |
1722 : greater_equal; | 1706 : greater_equal; |
1723 Register left_reg = ToRegister(left); | 1707 Register left_reg = ToRegister(left); |
1724 if (right->IsConstantOperand()) { | 1708 if (right->IsConstantOperand()) { |
1725 Immediate right_imm = | 1709 Immediate right_imm = |
1726 Immediate(ToInteger32(LConstantOperand::cast(right))); | 1710 Immediate(ToInteger32(LConstantOperand::cast(right))); |
1727 ASSERT(!instr->hydrogen_value()->representation().IsSmi()); | |
1728 __ cmpl(left_reg, right_imm); | 1711 __ cmpl(left_reg, right_imm); |
1729 __ j(condition, &return_left, Label::kNear); | 1712 __ j(condition, &return_left, Label::kNear); |
1730 __ movq(left_reg, right_imm); | 1713 __ movq(left_reg, right_imm); |
1731 } else if (right->IsRegister()) { | 1714 } else if (right->IsRegister()) { |
1732 Register right_reg = ToRegister(right); | 1715 Register right_reg = ToRegister(right); |
1733 if (instr->hydrogen_value()->representation().IsSmi()) { | 1716 __ cmpl(left_reg, right_reg); |
1734 __ cmpq(left_reg, right_reg); | |
1735 } else { | |
1736 __ cmpl(left_reg, right_reg); | |
1737 } | |
1738 __ j(condition, &return_left, Label::kNear); | 1717 __ j(condition, &return_left, Label::kNear); |
1739 __ movq(left_reg, right_reg); | 1718 __ movq(left_reg, right_reg); |
1740 } else { | 1719 } else { |
1741 Operand right_op = ToOperand(right); | 1720 Operand right_op = ToOperand(right); |
1742 if (instr->hydrogen_value()->representation().IsSmi()) { | 1721 __ cmpl(left_reg, right_op); |
1743 __ cmpq(left_reg, right_op); | |
1744 } else { | |
1745 __ cmpl(left_reg, right_op); | |
1746 } | |
1747 __ j(condition, &return_left, Label::kNear); | 1722 __ j(condition, &return_left, Label::kNear); |
1748 __ movq(left_reg, right_op); | 1723 __ movq(left_reg, right_op); |
1749 } | 1724 } |
1750 __ bind(&return_left); | 1725 __ bind(&return_left); |
1751 } else { | 1726 } else { |
1752 ASSERT(instr->hydrogen()->representation().IsDouble()); | 1727 ASSERT(instr->hydrogen()->representation().IsDouble()); |
1753 Label check_nan_left, check_zero, return_left, return_right; | 1728 Label check_nan_left, check_zero, return_left, return_right; |
1754 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; | 1729 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; |
1755 XMMRegister left_reg = ToDoubleRegister(left); | 1730 XMMRegister left_reg = ToDoubleRegister(left); |
1756 XMMRegister right_reg = ToDoubleRegister(right); | 1731 XMMRegister right_reg = ToDoubleRegister(right); |
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2694 check_needed); | 2669 check_needed); |
2695 } | 2670 } |
2696 | 2671 |
2697 __ bind(&skip_assignment); | 2672 __ bind(&skip_assignment); |
2698 } | 2673 } |
2699 | 2674 |
2700 | 2675 |
2701 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 2676 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
2702 HObjectAccess access = instr->hydrogen()->access(); | 2677 HObjectAccess access = instr->hydrogen()->access(); |
2703 int offset = access.offset(); | 2678 int offset = access.offset(); |
2704 | |
2705 if (access.IsExternalMemory()) { | |
2706 Register result = ToRegister(instr->result()); | |
2707 if (instr->object()->IsConstantOperand()) { | |
2708 ASSERT(result.is(rax)); | |
2709 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object()))); | |
2710 } else { | |
2711 Register object = ToRegister(instr->object()); | |
2712 __ movq(result, MemOperand(object, offset)); | |
2713 } | |
2714 return; | |
2715 } | |
2716 | |
2717 Register object = ToRegister(instr->object()); | 2679 Register object = ToRegister(instr->object()); |
2718 if (FLAG_track_double_fields && | 2680 if (FLAG_track_double_fields && |
2719 instr->hydrogen()->representation().IsDouble()) { | 2681 instr->hydrogen()->representation().IsDouble()) { |
2720 XMMRegister result = ToDoubleRegister(instr->result()); | 2682 XMMRegister result = ToDoubleRegister(instr->result()); |
2721 __ movsd(result, FieldOperand(object, offset)); | 2683 __ movsd(result, FieldOperand(object, offset)); |
2722 return; | 2684 return; |
2723 } | 2685 } |
2724 | 2686 |
2725 Register result = ToRegister(instr->result()); | 2687 Register result = ToRegister(instr->result()); |
2726 if (access.IsInobject()) { | 2688 if (access.IsInobject()) { |
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3944 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { | 3906 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
3945 Register result = ToRegister(instr->result()); | 3907 Register result = ToRegister(instr->result()); |
3946 Register base = ToRegister(instr->base_object()); | 3908 Register base = ToRegister(instr->base_object()); |
3947 __ lea(result, Operand(base, instr->offset())); | 3909 __ lea(result, Operand(base, instr->offset())); |
3948 } | 3910 } |
3949 | 3911 |
3950 | 3912 |
3951 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 3913 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
3952 Representation representation = instr->representation(); | 3914 Representation representation = instr->representation(); |
3953 | 3915 |
| 3916 Register object = ToRegister(instr->object()); |
| 3917 |
3954 HObjectAccess access = instr->hydrogen()->access(); | 3918 HObjectAccess access = instr->hydrogen()->access(); |
3955 int offset = access.offset(); | 3919 int offset = access.offset(); |
3956 | 3920 |
3957 if (access.IsExternalMemory()) { | |
3958 Register value = ToRegister(instr->value()); | |
3959 if (instr->object()->IsConstantOperand()) { | |
3960 ASSERT(value.is(rax)); | |
3961 LConstantOperand* object = LConstantOperand::cast(instr->object()); | |
3962 __ store_rax(ToExternalReference(object)); | |
3963 } else { | |
3964 Register object = ToRegister(instr->object()); | |
3965 __ movq(MemOperand(object, offset), value); | |
3966 } | |
3967 return; | |
3968 } | |
3969 | |
3970 Register object = ToRegister(instr->object()); | |
3971 Handle<Map> transition = instr->transition(); | 3921 Handle<Map> transition = instr->transition(); |
3972 | 3922 |
3973 if (FLAG_track_fields && representation.IsSmi()) { | 3923 if (FLAG_track_fields && representation.IsSmi()) { |
3974 if (instr->value()->IsConstantOperand()) { | 3924 if (instr->value()->IsConstantOperand()) { |
3975 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 3925 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
3976 if (!IsSmiConstant(operand_value)) { | 3926 if (!IsSmiConstant(operand_value)) { |
3977 DeoptimizeIf(no_condition, instr->environment()); | 3927 DeoptimizeIf(no_condition, instr->environment()); |
3978 } | 3928 } |
3979 } | 3929 } |
3980 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 3930 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4318 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); | 4268 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); |
4319 __ j(not_equal, ¬_applicable); | 4269 __ j(not_equal, ¬_applicable); |
4320 if (IsSimpleMapChangeTransition(from_kind, to_kind)) { | 4270 if (IsSimpleMapChangeTransition(from_kind, to_kind)) { |
4321 Register new_map_reg = ToRegister(instr->new_map_temp()); | 4271 Register new_map_reg = ToRegister(instr->new_map_temp()); |
4322 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); | 4272 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); |
4323 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); | 4273 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); |
4324 // Write barrier. | 4274 // Write barrier. |
4325 ASSERT_NE(instr->temp(), NULL); | 4275 ASSERT_NE(instr->temp(), NULL); |
4326 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, | 4276 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, |
4327 ToRegister(instr->temp()), kDontSaveFPRegs); | 4277 ToRegister(instr->temp()), kDontSaveFPRegs); |
4328 } else { | 4278 } else if (FLAG_compiled_transitions) { |
4329 PushSafepointRegistersScope scope(this); | 4279 PushSafepointRegistersScope scope(this); |
4330 if (!object_reg.is(rax)) { | 4280 if (!object_reg.is(rax)) { |
4331 __ movq(rax, object_reg); | 4281 __ movq(rax, object_reg); |
4332 } | 4282 } |
4333 __ Move(rbx, to_map); | 4283 __ Move(rbx, to_map); |
4334 TransitionElementsKindStub stub(from_kind, to_kind); | 4284 TransitionElementsKindStub stub(from_kind, to_kind); |
4335 __ CallStub(&stub); | 4285 __ CallStub(&stub); |
4336 RecordSafepointWithRegisters( | 4286 RecordSafepointWithRegisters( |
4337 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4287 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 4288 } else if (IsFastSmiElementsKind(from_kind) && |
| 4289 IsFastDoubleElementsKind(to_kind)) { |
| 4290 Register fixed_object_reg = ToRegister(instr->temp()); |
| 4291 ASSERT(fixed_object_reg.is(rdx)); |
| 4292 Register new_map_reg = ToRegister(instr->new_map_temp()); |
| 4293 ASSERT(new_map_reg.is(rbx)); |
| 4294 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); |
| 4295 __ movq(fixed_object_reg, object_reg); |
| 4296 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), |
| 4297 RelocInfo::CODE_TARGET, instr); |
| 4298 } else if (IsFastDoubleElementsKind(from_kind) && |
| 4299 IsFastObjectElementsKind(to_kind)) { |
| 4300 Register fixed_object_reg = ToRegister(instr->temp()); |
| 4301 ASSERT(fixed_object_reg.is(rdx)); |
| 4302 Register new_map_reg = ToRegister(instr->new_map_temp()); |
| 4303 ASSERT(new_map_reg.is(rbx)); |
| 4304 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); |
| 4305 __ movq(fixed_object_reg, object_reg); |
| 4306 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), |
| 4307 RelocInfo::CODE_TARGET, instr); |
| 4308 } else { |
| 4309 UNREACHABLE(); |
4338 } | 4310 } |
4339 __ bind(¬_applicable); | 4311 __ bind(¬_applicable); |
4340 } | 4312 } |
4341 | 4313 |
4342 | 4314 |
4343 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { | 4315 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { |
4344 Register object = ToRegister(instr->object()); | 4316 Register object = ToRegister(instr->object()); |
4345 Register temp = ToRegister(instr->temp()); | 4317 Register temp = ToRegister(instr->temp()); |
4346 __ TestJSArrayForAllocationMemento(object, temp); | 4318 __ TestJSArrayForAllocationMemento(object, temp); |
4347 DeoptimizeIf(equal, instr->environment()); | 4319 DeoptimizeIf(equal, instr->environment()); |
(...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5574 FixedArray::kHeaderSize - kPointerSize)); | 5546 FixedArray::kHeaderSize - kPointerSize)); |
5575 __ bind(&done); | 5547 __ bind(&done); |
5576 } | 5548 } |
5577 | 5549 |
5578 | 5550 |
5579 #undef __ | 5551 #undef __ |
5580 | 5552 |
5581 } } // namespace v8::internal | 5553 } } // namespace v8::internal |
5582 | 5554 |
5583 #endif // V8_TARGET_ARCH_X64 | 5555 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |