OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3444 if (!key->IsConstantOperand() && | 3444 if (!key->IsConstantOperand() && |
3445 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), | 3445 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), |
3446 elements_kind)) { | 3446 elements_kind)) { |
3447 __ SmiUntag(ToRegister(key)); | 3447 __ SmiUntag(ToRegister(key)); |
3448 } | 3448 } |
3449 Operand operand(BuildFastArrayOperand( | 3449 Operand operand(BuildFastArrayOperand( |
3450 instr->elements(), | 3450 instr->elements(), |
3451 key, | 3451 key, |
3452 instr->hydrogen()->key()->representation(), | 3452 instr->hydrogen()->key()->representation(), |
3453 elements_kind, | 3453 elements_kind, |
3454 0, | 3454 instr->base_offset())); |
3455 instr->additional_index())); | |
3456 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3455 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
3457 if (CpuFeatures::IsSupported(SSE2)) { | 3456 if (CpuFeatures::IsSupported(SSE2)) { |
3458 CpuFeatureScope scope(masm(), SSE2); | 3457 CpuFeatureScope scope(masm(), SSE2); |
3459 XMMRegister result(ToDoubleRegister(instr->result())); | 3458 XMMRegister result(ToDoubleRegister(instr->result())); |
3460 __ movss(result, operand); | 3459 __ movss(result, operand); |
3461 __ cvtss2sd(result, result); | 3460 __ cvtss2sd(result, result); |
3462 } else { | 3461 } else { |
3463 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); | 3462 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); |
3464 } | 3463 } |
3465 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3464 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3507 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3506 case NON_STRICT_ARGUMENTS_ELEMENTS: |
3508 UNREACHABLE(); | 3507 UNREACHABLE(); |
3509 break; | 3508 break; |
3510 } | 3509 } |
3511 } | 3510 } |
3512 } | 3511 } |
3513 | 3512 |
3514 | 3513 |
3515 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3514 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
3516 if (instr->hydrogen()->RequiresHoleCheck()) { | 3515 if (instr->hydrogen()->RequiresHoleCheck()) { |
3517 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | |
3518 sizeof(kHoleNanLower32); | |
3519 Operand hole_check_operand = BuildFastArrayOperand( | 3516 Operand hole_check_operand = BuildFastArrayOperand( |
3520 instr->elements(), instr->key(), | 3517 instr->elements(), instr->key(), |
3521 instr->hydrogen()->key()->representation(), | 3518 instr->hydrogen()->key()->representation(), |
3522 FAST_DOUBLE_ELEMENTS, | 3519 FAST_DOUBLE_ELEMENTS, |
3523 offset, | 3520 instr->base_offset() + sizeof(kHoleNanLower32)); |
3524 instr->additional_index()); | |
3525 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); | 3521 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); |
3526 DeoptimizeIf(equal, instr->environment()); | 3522 DeoptimizeIf(equal, instr->environment()); |
3527 } | 3523 } |
3528 | 3524 |
3529 Operand double_load_operand = BuildFastArrayOperand( | 3525 Operand double_load_operand = BuildFastArrayOperand( |
3530 instr->elements(), | 3526 instr->elements(), |
3531 instr->key(), | 3527 instr->key(), |
3532 instr->hydrogen()->key()->representation(), | 3528 instr->hydrogen()->key()->representation(), |
3533 FAST_DOUBLE_ELEMENTS, | 3529 FAST_DOUBLE_ELEMENTS, |
3534 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3530 instr->base_offset()); |
3535 instr->additional_index()); | |
3536 if (CpuFeatures::IsSupported(SSE2)) { | 3531 if (CpuFeatures::IsSupported(SSE2)) { |
3537 CpuFeatureScope scope(masm(), SSE2); | 3532 CpuFeatureScope scope(masm(), SSE2); |
3538 XMMRegister result = ToDoubleRegister(instr->result()); | 3533 XMMRegister result = ToDoubleRegister(instr->result()); |
3539 __ movsd(result, double_load_operand); | 3534 __ movsd(result, double_load_operand); |
3540 } else { | 3535 } else { |
3541 X87Mov(ToX87Register(instr->result()), double_load_operand); | 3536 X87Mov(ToX87Register(instr->result()), double_load_operand); |
3542 } | 3537 } |
3543 } | 3538 } |
3544 | 3539 |
3545 | 3540 |
3546 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3541 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
3547 Register result = ToRegister(instr->result()); | 3542 Register result = ToRegister(instr->result()); |
3548 | 3543 |
3549 // Load the result. | 3544 // Load the result. |
3550 __ mov(result, | 3545 __ mov(result, |
3551 BuildFastArrayOperand(instr->elements(), | 3546 BuildFastArrayOperand(instr->elements(), |
3552 instr->key(), | 3547 instr->key(), |
3553 instr->hydrogen()->key()->representation(), | 3548 instr->hydrogen()->key()->representation(), |
3554 FAST_ELEMENTS, | 3549 FAST_ELEMENTS, |
3555 FixedArray::kHeaderSize - kHeapObjectTag, | 3550 instr->base_offset())); |
3556 instr->additional_index())); | |
3557 | 3551 |
3558 // Check for the hole value. | 3552 // Check for the hole value. |
3559 if (instr->hydrogen()->RequiresHoleCheck()) { | 3553 if (instr->hydrogen()->RequiresHoleCheck()) { |
3560 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 3554 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
3561 __ test(result, Immediate(kSmiTagMask)); | 3555 __ test(result, Immediate(kSmiTagMask)); |
3562 DeoptimizeIf(not_equal, instr->environment()); | 3556 DeoptimizeIf(not_equal, instr->environment()); |
3563 } else { | 3557 } else { |
3564 __ cmp(result, factory()->the_hole_value()); | 3558 __ cmp(result, factory()->the_hole_value()); |
3565 DeoptimizeIf(equal, instr->environment()); | 3559 DeoptimizeIf(equal, instr->environment()); |
3566 } | 3560 } |
(...skipping 10 matching lines...) Expand all Loading... |
3577 DoLoadKeyedFixedArray(instr); | 3571 DoLoadKeyedFixedArray(instr); |
3578 } | 3572 } |
3579 } | 3573 } |
3580 | 3574 |
3581 | 3575 |
3582 Operand LCodeGen::BuildFastArrayOperand( | 3576 Operand LCodeGen::BuildFastArrayOperand( |
3583 LOperand* elements_pointer, | 3577 LOperand* elements_pointer, |
3584 LOperand* key, | 3578 LOperand* key, |
3585 Representation key_representation, | 3579 Representation key_representation, |
3586 ElementsKind elements_kind, | 3580 ElementsKind elements_kind, |
3587 uint32_t offset, | 3581 uint32_t base_offset) { |
3588 uint32_t additional_index) { | |
3589 Register elements_pointer_reg = ToRegister(elements_pointer); | 3582 Register elements_pointer_reg = ToRegister(elements_pointer); |
3590 int element_shift_size = ElementsKindToShiftSize(elements_kind); | 3583 int element_shift_size = ElementsKindToShiftSize(elements_kind); |
3591 int shift_size = element_shift_size; | 3584 int shift_size = element_shift_size; |
3592 if (key->IsConstantOperand()) { | 3585 if (key->IsConstantOperand()) { |
3593 int constant_value = ToInteger32(LConstantOperand::cast(key)); | 3586 int constant_value = ToInteger32(LConstantOperand::cast(key)); |
3594 if (constant_value & 0xF0000000) { | 3587 if (constant_value & 0xF0000000) { |
3595 Abort(kArrayIndexConstantValueTooBig); | 3588 Abort(kArrayIndexConstantValueTooBig); |
3596 } | 3589 } |
3597 return Operand(elements_pointer_reg, | 3590 return Operand(elements_pointer_reg, |
3598 ((constant_value + additional_index) << shift_size) | 3591 ((constant_value) << shift_size) |
3599 + offset); | 3592 + base_offset); |
3600 } else { | 3593 } else { |
3601 // Take the tag bit into account while computing the shift size. | 3594 // Take the tag bit into account while computing the shift size. |
3602 if (key_representation.IsSmi() && (shift_size >= 1)) { | 3595 if (key_representation.IsSmi() && (shift_size >= 1)) { |
3603 shift_size -= kSmiTagSize; | 3596 shift_size -= kSmiTagSize; |
3604 } | 3597 } |
3605 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); | 3598 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
3606 return Operand(elements_pointer_reg, | 3599 return Operand(elements_pointer_reg, |
3607 ToRegister(key), | 3600 ToRegister(key), |
3608 scale_factor, | 3601 scale_factor, |
3609 offset + (additional_index << element_shift_size)); | 3602 base_offset); |
3610 } | 3603 } |
3611 } | 3604 } |
3612 | 3605 |
3613 | 3606 |
3614 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3607 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
3615 ASSERT(ToRegister(instr->context()).is(esi)); | 3608 ASSERT(ToRegister(instr->context()).is(esi)); |
3616 ASSERT(ToRegister(instr->object()).is(edx)); | 3609 ASSERT(ToRegister(instr->object()).is(edx)); |
3617 ASSERT(ToRegister(instr->key()).is(ecx)); | 3610 ASSERT(ToRegister(instr->key()).is(ecx)); |
3618 | 3611 |
3619 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 3612 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4606 if (!key->IsConstantOperand() && | 4599 if (!key->IsConstantOperand() && |
4607 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), | 4600 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), |
4608 elements_kind)) { | 4601 elements_kind)) { |
4609 __ SmiUntag(ToRegister(key)); | 4602 __ SmiUntag(ToRegister(key)); |
4610 } | 4603 } |
4611 Operand operand(BuildFastArrayOperand( | 4604 Operand operand(BuildFastArrayOperand( |
4612 instr->elements(), | 4605 instr->elements(), |
4613 key, | 4606 key, |
4614 instr->hydrogen()->key()->representation(), | 4607 instr->hydrogen()->key()->representation(), |
4615 elements_kind, | 4608 elements_kind, |
4616 0, | 4609 instr->base_offset())); |
4617 instr->additional_index())); | |
4618 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4610 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
4619 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4611 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
4620 CpuFeatureScope scope(masm(), SSE2); | 4612 CpuFeatureScope scope(masm(), SSE2); |
4621 XMMRegister xmm_scratch = double_scratch0(); | 4613 XMMRegister xmm_scratch = double_scratch0(); |
4622 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); | 4614 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); |
4623 __ movss(operand, xmm_scratch); | 4615 __ movss(operand, xmm_scratch); |
4624 } else { | 4616 } else { |
4625 __ fld(0); | 4617 __ fld(0); |
4626 __ fstp_s(operand); | 4618 __ fstp_s(operand); |
4627 } | 4619 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4666 | 4658 |
4667 | 4659 |
4668 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4660 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4669 ExternalReference canonical_nan_reference = | 4661 ExternalReference canonical_nan_reference = |
4670 ExternalReference::address_of_canonical_non_hole_nan(); | 4662 ExternalReference::address_of_canonical_non_hole_nan(); |
4671 Operand double_store_operand = BuildFastArrayOperand( | 4663 Operand double_store_operand = BuildFastArrayOperand( |
4672 instr->elements(), | 4664 instr->elements(), |
4673 instr->key(), | 4665 instr->key(), |
4674 instr->hydrogen()->key()->representation(), | 4666 instr->hydrogen()->key()->representation(), |
4675 FAST_DOUBLE_ELEMENTS, | 4667 FAST_DOUBLE_ELEMENTS, |
4676 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 4668 instr->base_offset()); |
4677 instr->additional_index()); | |
4678 | 4669 |
4679 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4670 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
4680 CpuFeatureScope scope(masm(), SSE2); | 4671 CpuFeatureScope scope(masm(), SSE2); |
4681 XMMRegister value = ToDoubleRegister(instr->value()); | 4672 XMMRegister value = ToDoubleRegister(instr->value()); |
4682 | 4673 |
4683 if (instr->NeedsCanonicalization()) { | 4674 if (instr->NeedsCanonicalization()) { |
4684 Label have_value; | 4675 Label have_value; |
4685 | 4676 |
4686 __ ucomisd(value, value); | 4677 __ ucomisd(value, value); |
4687 __ j(parity_odd, &have_value, Label::kNear); // NaN. | 4678 __ j(parity_odd, &have_value, Label::kNear); // NaN. |
(...skipping 12 matching lines...) Expand all Loading... |
4700 uint64_t int_val = BitCast<uint64_t, double>(nan_double); | 4691 uint64_t int_val = BitCast<uint64_t, double>(nan_double); |
4701 int32_t lower = static_cast<int32_t>(int_val); | 4692 int32_t lower = static_cast<int32_t>(int_val); |
4702 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); | 4693 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); |
4703 | 4694 |
4704 __ mov(double_store_operand, Immediate(lower)); | 4695 __ mov(double_store_operand, Immediate(lower)); |
4705 Operand double_store_operand2 = BuildFastArrayOperand( | 4696 Operand double_store_operand2 = BuildFastArrayOperand( |
4706 instr->elements(), | 4697 instr->elements(), |
4707 instr->key(), | 4698 instr->key(), |
4708 instr->hydrogen()->key()->representation(), | 4699 instr->hydrogen()->key()->representation(), |
4709 FAST_DOUBLE_ELEMENTS, | 4700 FAST_DOUBLE_ELEMENTS, |
4710 FixedDoubleArray::kHeaderSize - kHeapObjectTag + kPointerSize, | 4701 kPointerSize + instr->base_offset()); |
4711 instr->additional_index()); | |
4712 __ mov(double_store_operand2, Immediate(upper)); | 4702 __ mov(double_store_operand2, Immediate(upper)); |
4713 } else { | 4703 } else { |
4714 Label no_special_nan_handling; | 4704 Label no_special_nan_handling; |
4715 X87Register value = ToX87Register(instr->value()); | 4705 X87Register value = ToX87Register(instr->value()); |
4716 X87Fxch(value); | 4706 X87Fxch(value); |
4717 | 4707 |
4718 if (instr->NeedsCanonicalization()) { | 4708 if (instr->NeedsCanonicalization()) { |
4719 __ fld(0); | 4709 __ fld(0); |
4720 __ fld(0); | 4710 __ fld(0); |
4721 __ FCmp(); | 4711 __ FCmp(); |
(...skipping 21 matching lines...) Expand all Loading... |
4743 | 4733 |
4744 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4734 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
4745 Register elements = ToRegister(instr->elements()); | 4735 Register elements = ToRegister(instr->elements()); |
4746 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; | 4736 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
4747 | 4737 |
4748 Operand operand = BuildFastArrayOperand( | 4738 Operand operand = BuildFastArrayOperand( |
4749 instr->elements(), | 4739 instr->elements(), |
4750 instr->key(), | 4740 instr->key(), |
4751 instr->hydrogen()->key()->representation(), | 4741 instr->hydrogen()->key()->representation(), |
4752 FAST_ELEMENTS, | 4742 FAST_ELEMENTS, |
4753 FixedArray::kHeaderSize - kHeapObjectTag, | 4743 instr->base_offset()); |
4754 instr->additional_index()); | |
4755 if (instr->value()->IsRegister()) { | 4744 if (instr->value()->IsRegister()) { |
4756 __ mov(operand, ToRegister(instr->value())); | 4745 __ mov(operand, ToRegister(instr->value())); |
4757 } else { | 4746 } else { |
4758 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4747 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
4759 if (IsSmi(operand_value)) { | 4748 if (IsSmi(operand_value)) { |
4760 Immediate immediate = ToImmediate(operand_value, Representation::Smi()); | 4749 Immediate immediate = ToImmediate(operand_value, Representation::Smi()); |
4761 __ mov(operand, immediate); | 4750 __ mov(operand, immediate); |
4762 } else { | 4751 } else { |
4763 ASSERT(!IsInteger32(operand_value)); | 4752 ASSERT(!IsInteger32(operand_value)); |
4764 Handle<Object> handle_value = ToHandle(operand_value); | 4753 Handle<Object> handle_value = ToHandle(operand_value); |
(...skipping 1642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6407 | 6396 |
6408 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { | 6397 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { |
6409 Register object = ToRegister(instr->object()); | 6398 Register object = ToRegister(instr->object()); |
6410 Register index = ToRegister(instr->index()); | 6399 Register index = ToRegister(instr->index()); |
6411 | 6400 |
6412 Label out_of_object, done; | 6401 Label out_of_object, done; |
6413 __ cmp(index, Immediate(0)); | 6402 __ cmp(index, Immediate(0)); |
6414 __ j(less, &out_of_object, Label::kNear); | 6403 __ j(less, &out_of_object, Label::kNear); |
6415 __ mov(object, FieldOperand(object, | 6404 __ mov(object, FieldOperand(object, |
6416 index, | 6405 index, |
6417 times_half_pointer_size, | 6406 times_pointer_size, |
6418 JSObject::kHeaderSize)); | 6407 JSObject::kHeaderSize)); |
6419 __ jmp(&done, Label::kNear); | 6408 __ jmp(&done, Label::kNear); |
6420 | 6409 |
6421 __ bind(&out_of_object); | 6410 __ bind(&out_of_object); |
6422 __ mov(object, FieldOperand(object, JSObject::kPropertiesOffset)); | 6411 __ mov(object, FieldOperand(object, JSObject::kPropertiesOffset)); |
6423 __ neg(index); | 6412 __ neg(index); |
6424 // Index is now equal to out of object property index plus 1. | 6413 // Index is now equal to out of object property index plus 1. |
6425 __ mov(object, FieldOperand(object, | 6414 __ mov(object, FieldOperand(object, |
6426 index, | 6415 index, |
6427 times_half_pointer_size, | 6416 times_pointer_size, |
6428 FixedArray::kHeaderSize - kPointerSize)); | 6417 FixedArray::kHeaderSize - kPointerSize)); |
6429 __ bind(&done); | 6418 __ bind(&done); |
6430 } | 6419 } |
6431 | 6420 |
6432 | 6421 |
6433 #undef __ | 6422 #undef __ |
6434 | 6423 |
6435 } } // namespace v8::internal | 6424 } } // namespace v8::internal |
6436 | 6425 |
6437 #endif // V8_TARGET_ARCH_IA32 | 6426 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |