OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved.7 | 1 // Copyright 2012 the V8 project authors. All rights reserved.7 |
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 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1404 int32_t mask = constant >> 31; | 1404 int32_t mask = constant >> 31; |
1405 uint32_t constant_abs = (constant + mask) ^ mask; | 1405 uint32_t constant_abs = (constant + mask) ^ mask; |
1406 | 1406 |
1407 if (base::bits::IsPowerOfTwo32(constant_abs)) { | 1407 if (base::bits::IsPowerOfTwo32(constant_abs)) { |
1408 int32_t shift = WhichPowerOf2(constant_abs); | 1408 int32_t shift = WhichPowerOf2(constant_abs); |
1409 __ sll(result, left, shift); | 1409 __ sll(result, left, shift); |
1410 // Correct the sign of the result if the constant is negative. | 1410 // Correct the sign of the result if the constant is negative. |
1411 if (constant < 0) __ Subu(result, zero_reg, result); | 1411 if (constant < 0) __ Subu(result, zero_reg, result); |
1412 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { | 1412 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { |
1413 int32_t shift = WhichPowerOf2(constant_abs - 1); | 1413 int32_t shift = WhichPowerOf2(constant_abs - 1); |
1414 __ sll(scratch, left, shift); | 1414 __ Lsa(result, left, left, shift); |
1415 __ Addu(result, scratch, left); | |
1416 // Correct the sign of the result if the constant is negative. | 1415 // Correct the sign of the result if the constant is negative. |
1417 if (constant < 0) __ Subu(result, zero_reg, result); | 1416 if (constant < 0) __ Subu(result, zero_reg, result); |
1418 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { | 1417 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { |
1419 int32_t shift = WhichPowerOf2(constant_abs + 1); | 1418 int32_t shift = WhichPowerOf2(constant_abs + 1); |
1420 __ sll(scratch, left, shift); | 1419 __ sll(scratch, left, shift); |
1421 __ Subu(result, scratch, left); | 1420 __ Subu(result, scratch, left); |
1422 // Correct the sign of the result if the constant is negative. | 1421 // Correct the sign of the result if the constant is negative. |
1423 if (constant < 0) __ Subu(result, zero_reg, result); | 1422 if (constant < 0) __ Subu(result, zero_reg, result); |
1424 } else { | 1423 } else { |
1425 // Generate standard code. | 1424 // Generate standard code. |
(...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2571 int parameter_count = ToInteger32(instr->constant_parameter_count()); | 2570 int parameter_count = ToInteger32(instr->constant_parameter_count()); |
2572 int32_t sp_delta = (parameter_count + 1) * kPointerSize; | 2571 int32_t sp_delta = (parameter_count + 1) * kPointerSize; |
2573 if (sp_delta != 0) { | 2572 if (sp_delta != 0) { |
2574 __ Addu(sp, sp, Operand(sp_delta)); | 2573 __ Addu(sp, sp, Operand(sp_delta)); |
2575 } | 2574 } |
2576 } else { | 2575 } else { |
2577 DCHECK(info()->IsStub()); // Functions would need to drop one more value. | 2576 DCHECK(info()->IsStub()); // Functions would need to drop one more value. |
2578 Register reg = ToRegister(instr->parameter_count()); | 2577 Register reg = ToRegister(instr->parameter_count()); |
2579 // The argument count parameter is a smi | 2578 // The argument count parameter is a smi |
2580 __ SmiUntag(reg); | 2579 __ SmiUntag(reg); |
2581 __ sll(at, reg, kPointerSizeLog2); | 2580 __ Lsa(sp, sp, reg, kPointerSizeLog2); |
2582 __ Addu(sp, sp, at); | |
2583 } | 2581 } |
2584 | 2582 |
2585 __ Jump(ra); | 2583 __ Jump(ra); |
2586 } | 2584 } |
2587 | 2585 |
2588 | 2586 |
2589 template <class T> | 2587 template <class T> |
2590 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { | 2588 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { |
2591 Register vector_register = ToRegister(instr->temp_vector()); | 2589 Register vector_register = ToRegister(instr->temp_vector()); |
2592 Register slot_register = LoadWithVectorDescriptor::SlotRegister(); | 2590 Register slot_register = LoadWithVectorDescriptor::SlotRegister(); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2774 if (instr->length()->IsConstantOperand()) { | 2772 if (instr->length()->IsConstantOperand()) { |
2775 int const_length = ToInteger32(LConstantOperand::cast(instr->length())); | 2773 int const_length = ToInteger32(LConstantOperand::cast(instr->length())); |
2776 if (instr->index()->IsConstantOperand()) { | 2774 if (instr->index()->IsConstantOperand()) { |
2777 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); | 2775 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
2778 int index = (const_length - const_index) + 1; | 2776 int index = (const_length - const_index) + 1; |
2779 __ lw(result, MemOperand(arguments, index * kPointerSize)); | 2777 __ lw(result, MemOperand(arguments, index * kPointerSize)); |
2780 } else { | 2778 } else { |
2781 Register index = ToRegister(instr->index()); | 2779 Register index = ToRegister(instr->index()); |
2782 __ li(at, Operand(const_length + 1)); | 2780 __ li(at, Operand(const_length + 1)); |
2783 __ Subu(result, at, index); | 2781 __ Subu(result, at, index); |
2784 __ sll(at, result, kPointerSizeLog2); | 2782 __ Lsa(at, arguments, result, kPointerSizeLog2); |
2785 __ Addu(at, arguments, at); | |
2786 __ lw(result, MemOperand(at)); | 2783 __ lw(result, MemOperand(at)); |
2787 } | 2784 } |
2788 } else if (instr->index()->IsConstantOperand()) { | 2785 } else if (instr->index()->IsConstantOperand()) { |
2789 Register length = ToRegister(instr->length()); | 2786 Register length = ToRegister(instr->length()); |
2790 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); | 2787 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
2791 int loc = const_index - 1; | 2788 int loc = const_index - 1; |
2792 if (loc != 0) { | 2789 if (loc != 0) { |
2793 __ Subu(result, length, Operand(loc)); | 2790 __ Subu(result, length, Operand(loc)); |
2794 __ sll(at, result, kPointerSizeLog2); | 2791 __ Lsa(at, arguments, result, kPointerSizeLog2); |
2795 __ Addu(at, arguments, at); | |
2796 __ lw(result, MemOperand(at)); | 2792 __ lw(result, MemOperand(at)); |
2797 } else { | 2793 } else { |
2798 __ sll(at, length, kPointerSizeLog2); | 2794 __ Lsa(at, arguments, length, kPointerSizeLog2); |
2799 __ Addu(at, arguments, at); | |
2800 __ lw(result, MemOperand(at)); | 2795 __ lw(result, MemOperand(at)); |
2801 } | 2796 } |
2802 } else { | 2797 } else { |
2803 Register length = ToRegister(instr->length()); | 2798 Register length = ToRegister(instr->length()); |
2804 Register index = ToRegister(instr->index()); | 2799 Register index = ToRegister(instr->index()); |
2805 __ Subu(result, length, index); | 2800 __ Subu(result, length, index); |
2806 __ Addu(result, result, 1); | 2801 __ Addu(result, result, 1); |
2807 __ sll(at, result, kPointerSizeLog2); | 2802 __ Lsa(at, arguments, result, kPointerSizeLog2); |
2808 __ Addu(at, arguments, at); | |
2809 __ lw(result, MemOperand(at)); | 2803 __ lw(result, MemOperand(at)); |
2810 } | 2804 } |
2811 } | 2805 } |
2812 | 2806 |
2813 | 2807 |
2814 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 2808 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
2815 Register external_pointer = ToRegister(instr->elements()); | 2809 Register external_pointer = ToRegister(instr->elements()); |
2816 Register key = no_reg; | 2810 Register key = no_reg; |
2817 ElementsKind elements_kind = instr->elements_kind(); | 2811 ElementsKind elements_kind = instr->elements_kind(); |
2818 bool key_is_constant = instr->key()->IsConstantOperand(); | 2812 bool key_is_constant = instr->key()->IsConstantOperand(); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2907 Abort(kArrayIndexConstantValueTooBig); | 2901 Abort(kArrayIndexConstantValueTooBig); |
2908 } | 2902 } |
2909 base_offset += constant_key * kDoubleSize; | 2903 base_offset += constant_key * kDoubleSize; |
2910 } | 2904 } |
2911 __ Addu(scratch, elements, Operand(base_offset)); | 2905 __ Addu(scratch, elements, Operand(base_offset)); |
2912 | 2906 |
2913 if (!key_is_constant) { | 2907 if (!key_is_constant) { |
2914 key = ToRegister(instr->key()); | 2908 key = ToRegister(instr->key()); |
2915 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 2909 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
2916 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 2910 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
2917 __ sll(at, key, shift_size); | 2911 __ Lsa(scratch, scratch, key, shift_size); |
2918 __ Addu(scratch, scratch, at); | |
2919 } | 2912 } |
2920 | 2913 |
2921 __ ldc1(result, MemOperand(scratch)); | 2914 __ ldc1(result, MemOperand(scratch)); |
2922 | 2915 |
2923 if (instr->hydrogen()->RequiresHoleCheck()) { | 2916 if (instr->hydrogen()->RequiresHoleCheck()) { |
2924 __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset)); | 2917 __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset)); |
2925 DeoptimizeIf(eq, instr, Deoptimizer::kHole, scratch, | 2918 DeoptimizeIf(eq, instr, Deoptimizer::kHole, scratch, |
2926 Operand(kHoleNanUpper32)); | 2919 Operand(kHoleNanUpper32)); |
2927 } | 2920 } |
2928 } | 2921 } |
(...skipping 10 matching lines...) Expand all Loading... |
2939 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 2932 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
2940 offset += ToInteger32(const_operand) * kPointerSize; | 2933 offset += ToInteger32(const_operand) * kPointerSize; |
2941 store_base = elements; | 2934 store_base = elements; |
2942 } else { | 2935 } else { |
2943 Register key = ToRegister(instr->key()); | 2936 Register key = ToRegister(instr->key()); |
2944 // Even though the HLoadKeyed instruction forces the input | 2937 // Even though the HLoadKeyed instruction forces the input |
2945 // representation for the key to be an integer, the input gets replaced | 2938 // representation for the key to be an integer, the input gets replaced |
2946 // during bound check elimination with the index argument to the bounds | 2939 // during bound check elimination with the index argument to the bounds |
2947 // check, which can be tagged, so that case must be handled here, too. | 2940 // check, which can be tagged, so that case must be handled here, too. |
2948 if (instr->hydrogen()->key()->representation().IsSmi()) { | 2941 if (instr->hydrogen()->key()->representation().IsSmi()) { |
2949 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize); | 2942 __ Lsa(scratch, elements, key, kPointerSizeLog2 - kSmiTagSize); |
2950 __ addu(scratch, elements, scratch); | |
2951 } else { | 2943 } else { |
2952 __ sll(scratch, key, kPointerSizeLog2); | 2944 __ Lsa(scratch, elements, key, kPointerSizeLog2); |
2953 __ addu(scratch, elements, scratch); | |
2954 } | 2945 } |
2955 } | 2946 } |
2956 __ lw(result, MemOperand(store_base, offset)); | 2947 __ lw(result, MemOperand(store_base, offset)); |
2957 | 2948 |
2958 // Check for the hole value. | 2949 // Check for the hole value. |
2959 if (instr->hydrogen()->RequiresHoleCheck()) { | 2950 if (instr->hydrogen()->RequiresHoleCheck()) { |
2960 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 2951 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
2961 __ SmiTst(result, scratch); | 2952 __ SmiTst(result, scratch); |
2962 DeoptimizeIf(ne, instr, Deoptimizer::kNotASmi, scratch, | 2953 DeoptimizeIf(ne, instr, Deoptimizer::kNotASmi, scratch, |
2963 Operand(zero_reg)); | 2954 Operand(zero_reg)); |
(...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3938 Register address = scratch0(); | 3929 Register address = scratch0(); |
3939 FPURegister value(ToDoubleRegister(instr->value())); | 3930 FPURegister value(ToDoubleRegister(instr->value())); |
3940 if (key_is_constant) { | 3931 if (key_is_constant) { |
3941 if (constant_key != 0) { | 3932 if (constant_key != 0) { |
3942 __ Addu(address, external_pointer, | 3933 __ Addu(address, external_pointer, |
3943 Operand(constant_key << element_size_shift)); | 3934 Operand(constant_key << element_size_shift)); |
3944 } else { | 3935 } else { |
3945 address = external_pointer; | 3936 address = external_pointer; |
3946 } | 3937 } |
3947 } else { | 3938 } else { |
3948 __ sll(address, key, shift_size); | 3939 __ Lsa(address, external_pointer, key, shift_size); |
3949 __ Addu(address, external_pointer, address); | |
3950 } | 3940 } |
3951 | 3941 |
3952 if (elements_kind == FLOAT32_ELEMENTS) { | 3942 if (elements_kind == FLOAT32_ELEMENTS) { |
3953 __ cvt_s_d(double_scratch0(), value); | 3943 __ cvt_s_d(double_scratch0(), value); |
3954 __ swc1(double_scratch0(), MemOperand(address, base_offset)); | 3944 __ swc1(double_scratch0(), MemOperand(address, base_offset)); |
3955 } else { // Storing doubles, not floats. | 3945 } else { // Storing doubles, not floats. |
3956 __ sdc1(value, MemOperand(address, base_offset)); | 3946 __ sdc1(value, MemOperand(address, base_offset)); |
3957 } | 3947 } |
3958 } else { | 3948 } else { |
3959 Register value(ToRegister(instr->value())); | 3949 Register value(ToRegister(instr->value())); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4056 DCHECK(!instr->hydrogen()->NeedsWriteBarrier()); | 4046 DCHECK(!instr->hydrogen()->NeedsWriteBarrier()); |
4057 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 4047 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
4058 offset += ToInteger32(const_operand) * kPointerSize; | 4048 offset += ToInteger32(const_operand) * kPointerSize; |
4059 store_base = elements; | 4049 store_base = elements; |
4060 } else { | 4050 } else { |
4061 // Even though the HLoadKeyed instruction forces the input | 4051 // Even though the HLoadKeyed instruction forces the input |
4062 // representation for the key to be an integer, the input gets replaced | 4052 // representation for the key to be an integer, the input gets replaced |
4063 // during bound check elimination with the index argument to the bounds | 4053 // during bound check elimination with the index argument to the bounds |
4064 // check, which can be tagged, so that case must be handled here, too. | 4054 // check, which can be tagged, so that case must be handled here, too. |
4065 if (instr->hydrogen()->key()->representation().IsSmi()) { | 4055 if (instr->hydrogen()->key()->representation().IsSmi()) { |
4066 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize); | 4056 __ Lsa(scratch, elements, key, kPointerSizeLog2 - kSmiTagSize); |
4067 __ addu(scratch, elements, scratch); | |
4068 } else { | 4057 } else { |
4069 __ sll(scratch, key, kPointerSizeLog2); | 4058 __ Lsa(scratch, elements, key, kPointerSizeLog2); |
4070 __ addu(scratch, elements, scratch); | |
4071 } | 4059 } |
4072 } | 4060 } |
4073 __ sw(value, MemOperand(store_base, offset)); | 4061 __ sw(value, MemOperand(store_base, offset)); |
4074 | 4062 |
4075 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4063 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4076 SmiCheck check_needed = | 4064 SmiCheck check_needed = |
4077 instr->hydrogen()->value()->type().IsHeapObject() | 4065 instr->hydrogen()->value()->type().IsHeapObject() |
4078 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4066 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4079 // Compute address of modified element and store it into key register. | 4067 // Compute address of modified element and store it into key register. |
4080 __ Addu(key, store_base, Operand(offset)); | 4068 __ Addu(key, store_base, Operand(offset)); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4347 | 4335 |
4348 DCHECK(instr->hydrogen()->value()->representation().IsInteger32()); | 4336 DCHECK(instr->hydrogen()->value()->representation().IsInteger32()); |
4349 Register char_code = ToRegister(instr->char_code()); | 4337 Register char_code = ToRegister(instr->char_code()); |
4350 Register result = ToRegister(instr->result()); | 4338 Register result = ToRegister(instr->result()); |
4351 Register scratch = scratch0(); | 4339 Register scratch = scratch0(); |
4352 DCHECK(!char_code.is(result)); | 4340 DCHECK(!char_code.is(result)); |
4353 | 4341 |
4354 __ Branch(deferred->entry(), hi, | 4342 __ Branch(deferred->entry(), hi, |
4355 char_code, Operand(String::kMaxOneByteCharCode)); | 4343 char_code, Operand(String::kMaxOneByteCharCode)); |
4356 __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); | 4344 __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); |
4357 __ sll(scratch, char_code, kPointerSizeLog2); | 4345 __ Lsa(result, result, char_code, kPointerSizeLog2); |
4358 __ Addu(result, result, scratch); | |
4359 __ lw(result, FieldMemOperand(result, FixedArray::kHeaderSize)); | 4346 __ lw(result, FieldMemOperand(result, FixedArray::kHeaderSize)); |
4360 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 4347 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
4361 __ Branch(deferred->entry(), eq, result, Operand(scratch)); | 4348 __ Branch(deferred->entry(), eq, result, Operand(scratch)); |
4362 __ bind(deferred->exit()); | 4349 __ bind(deferred->exit()); |
4363 } | 4350 } |
4364 | 4351 |
4365 | 4352 |
4366 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { | 4353 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { |
4367 Register char_code = ToRegister(instr->char_code()); | 4354 Register char_code = ToRegister(instr->char_code()); |
4368 Register result = ToRegister(instr->result()); | 4355 Register result = ToRegister(instr->result()); |
(...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5629 __ Push(at, ToRegister(instr->function())); | 5616 __ Push(at, ToRegister(instr->function())); |
5630 CallRuntime(Runtime::kPushBlockContext, instr); | 5617 CallRuntime(Runtime::kPushBlockContext, instr); |
5631 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5618 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5632 } | 5619 } |
5633 | 5620 |
5634 | 5621 |
5635 #undef __ | 5622 #undef __ |
5636 | 5623 |
5637 } // namespace internal | 5624 } // namespace internal |
5638 } // namespace v8 | 5625 } // namespace v8 |
OLD | NEW |