OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "ia32/lithium-codegen-ia32.h" | 9 #include "ia32/lithium-codegen-ia32.h" |
10 #include "ic.h" | 10 #include "ic.h" |
(...skipping 3023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3034 if (!key->IsConstantOperand() && | 3034 if (!key->IsConstantOperand() && |
3035 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), | 3035 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), |
3036 elements_kind)) { | 3036 elements_kind)) { |
3037 __ SmiUntag(ToRegister(key)); | 3037 __ SmiUntag(ToRegister(key)); |
3038 } | 3038 } |
3039 Operand operand(BuildFastArrayOperand( | 3039 Operand operand(BuildFastArrayOperand( |
3040 instr->elements(), | 3040 instr->elements(), |
3041 key, | 3041 key, |
3042 instr->hydrogen()->key()->representation(), | 3042 instr->hydrogen()->key()->representation(), |
3043 elements_kind, | 3043 elements_kind, |
3044 0, | 3044 instr->base_offset())); |
3045 instr->additional_index())); | |
3046 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 3045 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
3047 elements_kind == FLOAT32_ELEMENTS) { | 3046 elements_kind == FLOAT32_ELEMENTS) { |
3048 XMMRegister result(ToDoubleRegister(instr->result())); | 3047 XMMRegister result(ToDoubleRegister(instr->result())); |
3049 __ movss(result, operand); | 3048 __ movss(result, operand); |
3050 __ cvtss2sd(result, result); | 3049 __ cvtss2sd(result, result); |
3051 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 3050 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
3052 elements_kind == FLOAT64_ELEMENTS) { | 3051 elements_kind == FLOAT64_ELEMENTS) { |
3053 __ movsd(ToDoubleRegister(instr->result()), operand); | 3052 __ movsd(ToDoubleRegister(instr->result()), operand); |
3054 } else { | 3053 } else { |
3055 Register result(ToRegister(instr->result())); | 3054 Register result(ToRegister(instr->result())); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3098 case SLOPPY_ARGUMENTS_ELEMENTS: | 3097 case SLOPPY_ARGUMENTS_ELEMENTS: |
3099 UNREACHABLE(); | 3098 UNREACHABLE(); |
3100 break; | 3099 break; |
3101 } | 3100 } |
3102 } | 3101 } |
3103 } | 3102 } |
3104 | 3103 |
3105 | 3104 |
3106 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3105 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
3107 if (instr->hydrogen()->RequiresHoleCheck()) { | 3106 if (instr->hydrogen()->RequiresHoleCheck()) { |
3108 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | |
3109 sizeof(kHoleNanLower32); | |
3110 Operand hole_check_operand = BuildFastArrayOperand( | 3107 Operand hole_check_operand = BuildFastArrayOperand( |
3111 instr->elements(), instr->key(), | 3108 instr->elements(), instr->key(), |
3112 instr->hydrogen()->key()->representation(), | 3109 instr->hydrogen()->key()->representation(), |
3113 FAST_DOUBLE_ELEMENTS, | 3110 FAST_DOUBLE_ELEMENTS, |
3114 offset, | 3111 instr->base_offset() + sizeof(kHoleNanLower32)); |
3115 instr->additional_index()); | |
3116 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); | 3112 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); |
3117 DeoptimizeIf(equal, instr->environment()); | 3113 DeoptimizeIf(equal, instr->environment()); |
3118 } | 3114 } |
3119 | 3115 |
3120 Operand double_load_operand = BuildFastArrayOperand( | 3116 Operand double_load_operand = BuildFastArrayOperand( |
3121 instr->elements(), | 3117 instr->elements(), |
3122 instr->key(), | 3118 instr->key(), |
3123 instr->hydrogen()->key()->representation(), | 3119 instr->hydrogen()->key()->representation(), |
3124 FAST_DOUBLE_ELEMENTS, | 3120 FAST_DOUBLE_ELEMENTS, |
3125 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3121 instr->base_offset()); |
3126 instr->additional_index()); | |
3127 XMMRegister result = ToDoubleRegister(instr->result()); | 3122 XMMRegister result = ToDoubleRegister(instr->result()); |
3128 __ movsd(result, double_load_operand); | 3123 __ movsd(result, double_load_operand); |
3129 } | 3124 } |
3130 | 3125 |
3131 | 3126 |
3132 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3127 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
3133 Register result = ToRegister(instr->result()); | 3128 Register result = ToRegister(instr->result()); |
3134 | 3129 |
3135 // Load the result. | 3130 // Load the result. |
3136 __ mov(result, | 3131 __ mov(result, |
3137 BuildFastArrayOperand(instr->elements(), | 3132 BuildFastArrayOperand(instr->elements(), |
3138 instr->key(), | 3133 instr->key(), |
3139 instr->hydrogen()->key()->representation(), | 3134 instr->hydrogen()->key()->representation(), |
3140 FAST_ELEMENTS, | 3135 FAST_ELEMENTS, |
3141 FixedArray::kHeaderSize - kHeapObjectTag, | 3136 instr->base_offset())); |
3142 instr->additional_index())); | |
3143 | 3137 |
3144 // Check for the hole value. | 3138 // Check for the hole value. |
3145 if (instr->hydrogen()->RequiresHoleCheck()) { | 3139 if (instr->hydrogen()->RequiresHoleCheck()) { |
3146 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 3140 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
3147 __ test(result, Immediate(kSmiTagMask)); | 3141 __ test(result, Immediate(kSmiTagMask)); |
3148 DeoptimizeIf(not_equal, instr->environment()); | 3142 DeoptimizeIf(not_equal, instr->environment()); |
3149 } else { | 3143 } else { |
3150 __ cmp(result, factory()->the_hole_value()); | 3144 __ cmp(result, factory()->the_hole_value()); |
3151 DeoptimizeIf(equal, instr->environment()); | 3145 DeoptimizeIf(equal, instr->environment()); |
3152 } | 3146 } |
(...skipping 10 matching lines...) Expand all Loading... |
3163 DoLoadKeyedFixedArray(instr); | 3157 DoLoadKeyedFixedArray(instr); |
3164 } | 3158 } |
3165 } | 3159 } |
3166 | 3160 |
3167 | 3161 |
3168 Operand LCodeGen::BuildFastArrayOperand( | 3162 Operand LCodeGen::BuildFastArrayOperand( |
3169 LOperand* elements_pointer, | 3163 LOperand* elements_pointer, |
3170 LOperand* key, | 3164 LOperand* key, |
3171 Representation key_representation, | 3165 Representation key_representation, |
3172 ElementsKind elements_kind, | 3166 ElementsKind elements_kind, |
3173 uint32_t offset, | 3167 uint32_t base_offset) { |
3174 uint32_t additional_index) { | |
3175 Register elements_pointer_reg = ToRegister(elements_pointer); | 3168 Register elements_pointer_reg = ToRegister(elements_pointer); |
3176 int element_shift_size = ElementsKindToShiftSize(elements_kind); | 3169 int element_shift_size = ElementsKindToShiftSize(elements_kind); |
3177 if (IsFixedTypedArrayElementsKind(elements_kind)) { | |
3178 offset += FixedTypedArrayBase::kDataOffset - kHeapObjectTag; | |
3179 } | |
3180 int shift_size = element_shift_size; | 3170 int shift_size = element_shift_size; |
3181 if (key->IsConstantOperand()) { | 3171 if (key->IsConstantOperand()) { |
3182 int constant_value = ToInteger32(LConstantOperand::cast(key)); | 3172 int constant_value = ToInteger32(LConstantOperand::cast(key)); |
3183 if (constant_value & 0xF0000000) { | 3173 if (constant_value & 0xF0000000) { |
3184 Abort(kArrayIndexConstantValueTooBig); | 3174 Abort(kArrayIndexConstantValueTooBig); |
3185 } | 3175 } |
3186 return Operand(elements_pointer_reg, | 3176 return Operand(elements_pointer_reg, |
3187 ((constant_value + additional_index) << shift_size) | 3177 ((constant_value) << shift_size) |
3188 + offset); | 3178 + base_offset); |
3189 } else { | 3179 } else { |
3190 // Take the tag bit into account while computing the shift size. | 3180 // Take the tag bit into account while computing the shift size. |
3191 if (key_representation.IsSmi() && (shift_size >= 1)) { | 3181 if (key_representation.IsSmi() && (shift_size >= 1)) { |
3192 shift_size -= kSmiTagSize; | 3182 shift_size -= kSmiTagSize; |
3193 } | 3183 } |
3194 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); | 3184 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
3195 return Operand(elements_pointer_reg, | 3185 return Operand(elements_pointer_reg, |
3196 ToRegister(key), | 3186 ToRegister(key), |
3197 scale_factor, | 3187 scale_factor, |
3198 offset + (additional_index << element_shift_size)); | 3188 base_offset); |
3199 } | 3189 } |
3200 } | 3190 } |
3201 | 3191 |
3202 | 3192 |
3203 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3193 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
3204 ASSERT(ToRegister(instr->context()).is(esi)); | 3194 ASSERT(ToRegister(instr->context()).is(esi)); |
3205 ASSERT(ToRegister(instr->object()).is(edx)); | 3195 ASSERT(ToRegister(instr->object()).is(edx)); |
3206 ASSERT(ToRegister(instr->key()).is(ecx)); | 3196 ASSERT(ToRegister(instr->key()).is(ecx)); |
3207 | 3197 |
3208 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 3198 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4115 if (!key->IsConstantOperand() && | 4105 if (!key->IsConstantOperand() && |
4116 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), | 4106 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), |
4117 elements_kind)) { | 4107 elements_kind)) { |
4118 __ SmiUntag(ToRegister(key)); | 4108 __ SmiUntag(ToRegister(key)); |
4119 } | 4109 } |
4120 Operand operand(BuildFastArrayOperand( | 4110 Operand operand(BuildFastArrayOperand( |
4121 instr->elements(), | 4111 instr->elements(), |
4122 key, | 4112 key, |
4123 instr->hydrogen()->key()->representation(), | 4113 instr->hydrogen()->key()->representation(), |
4124 elements_kind, | 4114 elements_kind, |
4125 0, | 4115 instr->base_offset())); |
4126 instr->additional_index())); | |
4127 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 4116 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
4128 elements_kind == FLOAT32_ELEMENTS) { | 4117 elements_kind == FLOAT32_ELEMENTS) { |
4129 XMMRegister xmm_scratch = double_scratch0(); | 4118 XMMRegister xmm_scratch = double_scratch0(); |
4130 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); | 4119 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); |
4131 __ movss(operand, xmm_scratch); | 4120 __ movss(operand, xmm_scratch); |
4132 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 4121 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
4133 elements_kind == FLOAT64_ELEMENTS) { | 4122 elements_kind == FLOAT64_ELEMENTS) { |
4134 __ movsd(operand, ToDoubleRegister(instr->value())); | 4123 __ movsd(operand, ToDoubleRegister(instr->value())); |
4135 } else { | 4124 } else { |
4136 Register value = ToRegister(instr->value()); | 4125 Register value = ToRegister(instr->value()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4175 | 4164 |
4176 | 4165 |
4177 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4166 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4178 ExternalReference canonical_nan_reference = | 4167 ExternalReference canonical_nan_reference = |
4179 ExternalReference::address_of_canonical_non_hole_nan(); | 4168 ExternalReference::address_of_canonical_non_hole_nan(); |
4180 Operand double_store_operand = BuildFastArrayOperand( | 4169 Operand double_store_operand = BuildFastArrayOperand( |
4181 instr->elements(), | 4170 instr->elements(), |
4182 instr->key(), | 4171 instr->key(), |
4183 instr->hydrogen()->key()->representation(), | 4172 instr->hydrogen()->key()->representation(), |
4184 FAST_DOUBLE_ELEMENTS, | 4173 FAST_DOUBLE_ELEMENTS, |
4185 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 4174 instr->base_offset()); |
4186 instr->additional_index()); | |
4187 | 4175 |
4188 XMMRegister value = ToDoubleRegister(instr->value()); | 4176 XMMRegister value = ToDoubleRegister(instr->value()); |
4189 | 4177 |
4190 if (instr->NeedsCanonicalization()) { | 4178 if (instr->NeedsCanonicalization()) { |
4191 Label have_value; | 4179 Label have_value; |
4192 | 4180 |
4193 __ ucomisd(value, value); | 4181 __ ucomisd(value, value); |
4194 __ j(parity_odd, &have_value, Label::kNear); // NaN. | 4182 __ j(parity_odd, &have_value, Label::kNear); // NaN. |
4195 | 4183 |
4196 __ movsd(value, Operand::StaticVariable(canonical_nan_reference)); | 4184 __ movsd(value, Operand::StaticVariable(canonical_nan_reference)); |
4197 __ bind(&have_value); | 4185 __ bind(&have_value); |
4198 } | 4186 } |
4199 | 4187 |
4200 __ movsd(double_store_operand, value); | 4188 __ movsd(double_store_operand, value); |
4201 } | 4189 } |
4202 | 4190 |
4203 | 4191 |
4204 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4192 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
4205 Register elements = ToRegister(instr->elements()); | 4193 Register elements = ToRegister(instr->elements()); |
4206 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; | 4194 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
4207 | 4195 |
4208 Operand operand = BuildFastArrayOperand( | 4196 Operand operand = BuildFastArrayOperand( |
4209 instr->elements(), | 4197 instr->elements(), |
4210 instr->key(), | 4198 instr->key(), |
4211 instr->hydrogen()->key()->representation(), | 4199 instr->hydrogen()->key()->representation(), |
4212 FAST_ELEMENTS, | 4200 FAST_ELEMENTS, |
4213 FixedArray::kHeaderSize - kHeapObjectTag, | 4201 instr->base_offset()); |
4214 instr->additional_index()); | |
4215 if (instr->value()->IsRegister()) { | 4202 if (instr->value()->IsRegister()) { |
4216 __ mov(operand, ToRegister(instr->value())); | 4203 __ mov(operand, ToRegister(instr->value())); |
4217 } else { | 4204 } else { |
4218 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4205 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
4219 if (IsSmi(operand_value)) { | 4206 if (IsSmi(operand_value)) { |
4220 Immediate immediate = ToImmediate(operand_value, Representation::Smi()); | 4207 Immediate immediate = ToImmediate(operand_value, Representation::Smi()); |
4221 __ mov(operand, immediate); | 4208 __ mov(operand, immediate); |
4222 } else { | 4209 } else { |
4223 ASSERT(!IsInteger32(operand_value)); | 4210 ASSERT(!IsInteger32(operand_value)); |
4224 Handle<Object> handle_value = ToHandle(operand_value); | 4211 Handle<Object> handle_value = ToHandle(operand_value); |
(...skipping 1458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5683 __ bind(deferred->exit()); | 5670 __ bind(deferred->exit()); |
5684 __ bind(&done); | 5671 __ bind(&done); |
5685 } | 5672 } |
5686 | 5673 |
5687 | 5674 |
5688 #undef __ | 5675 #undef __ |
5689 | 5676 |
5690 } } // namespace v8::internal | 5677 } } // namespace v8::internal |
5691 | 5678 |
5692 #endif // V8_TARGET_ARCH_IA32 | 5679 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |