| 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 |