| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "x64/lithium-codegen-x64.h" | 9 #include "x64/lithium-codegen-x64.h" |
| 10 #include "code-stubs.h" | 10 #include "code-stubs.h" |
| (...skipping 3006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3017 StackArgumentsAccessor args(arguments, length, | 3017 StackArgumentsAccessor args(arguments, length, |
| 3018 ARGUMENTS_DONT_CONTAIN_RECEIVER); | 3018 ARGUMENTS_DONT_CONTAIN_RECEIVER); |
| 3019 __ movp(result, args.GetArgumentOperand(0)); | 3019 __ movp(result, args.GetArgumentOperand(0)); |
| 3020 } | 3020 } |
| 3021 } | 3021 } |
| 3022 | 3022 |
| 3023 | 3023 |
| 3024 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 3024 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
| 3025 ElementsKind elements_kind = instr->elements_kind(); | 3025 ElementsKind elements_kind = instr->elements_kind(); |
| 3026 LOperand* key = instr->key(); | 3026 LOperand* key = instr->key(); |
| 3027 int base_offset = instr->is_fixed_typed_array() | |
| 3028 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | |
| 3029 : 0; | |
| 3030 Operand operand(BuildFastArrayOperand( | 3027 Operand operand(BuildFastArrayOperand( |
| 3031 instr->elements(), | 3028 instr->elements(), |
| 3032 key, | 3029 key, |
| 3033 elements_kind, | 3030 elements_kind, |
| 3034 base_offset, | 3031 instr->base_offset())); |
| 3035 instr->additional_index())); | |
| 3036 | 3032 |
| 3037 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 3033 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3038 elements_kind == FLOAT32_ELEMENTS) { | 3034 elements_kind == FLOAT32_ELEMENTS) { |
| 3039 XMMRegister result(ToDoubleRegister(instr->result())); | 3035 XMMRegister result(ToDoubleRegister(instr->result())); |
| 3040 __ movss(result, operand); | 3036 __ movss(result, operand); |
| 3041 __ cvtss2sd(result, result); | 3037 __ cvtss2sd(result, result); |
| 3042 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 3038 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 3043 elements_kind == FLOAT64_ELEMENTS) { | 3039 elements_kind == FLOAT64_ELEMENTS) { |
| 3044 __ movsd(ToDoubleRegister(instr->result()), operand); | 3040 __ movsd(ToDoubleRegister(instr->result()), operand); |
| 3045 } else { | 3041 } else { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3091 break; | 3087 break; |
| 3092 } | 3088 } |
| 3093 } | 3089 } |
| 3094 } | 3090 } |
| 3095 | 3091 |
| 3096 | 3092 |
| 3097 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3093 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
| 3098 XMMRegister result(ToDoubleRegister(instr->result())); | 3094 XMMRegister result(ToDoubleRegister(instr->result())); |
| 3099 LOperand* key = instr->key(); | 3095 LOperand* key = instr->key(); |
| 3100 if (instr->hydrogen()->RequiresHoleCheck()) { | 3096 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3101 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | |
| 3102 sizeof(kHoleNanLower32); | |
| 3103 Operand hole_check_operand = BuildFastArrayOperand( | 3097 Operand hole_check_operand = BuildFastArrayOperand( |
| 3104 instr->elements(), | 3098 instr->elements(), |
| 3105 key, | 3099 key, |
| 3106 FAST_DOUBLE_ELEMENTS, | 3100 FAST_DOUBLE_ELEMENTS, |
| 3107 offset, | 3101 instr->base_offset() + sizeof(kHoleNanLower32)); |
| 3108 instr->additional_index()); | |
| 3109 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); | 3102 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
| 3110 DeoptimizeIf(equal, instr->environment()); | 3103 DeoptimizeIf(equal, instr->environment()); |
| 3111 } | 3104 } |
| 3112 | 3105 |
| 3113 Operand double_load_operand = BuildFastArrayOperand( | 3106 Operand double_load_operand = BuildFastArrayOperand( |
| 3114 instr->elements(), | 3107 instr->elements(), |
| 3115 key, | 3108 key, |
| 3116 FAST_DOUBLE_ELEMENTS, | 3109 FAST_DOUBLE_ELEMENTS, |
| 3117 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3110 instr->base_offset()); |
| 3118 instr->additional_index()); | |
| 3119 __ movsd(result, double_load_operand); | 3111 __ movsd(result, double_load_operand); |
| 3120 } | 3112 } |
| 3121 | 3113 |
| 3122 | 3114 |
| 3123 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3115 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3124 HLoadKeyed* hinstr = instr->hydrogen(); | 3116 HLoadKeyed* hinstr = instr->hydrogen(); |
| 3125 Register result = ToRegister(instr->result()); | 3117 Register result = ToRegister(instr->result()); |
| 3126 LOperand* key = instr->key(); | 3118 LOperand* key = instr->key(); |
| 3127 bool requires_hole_check = hinstr->RequiresHoleCheck(); | 3119 bool requires_hole_check = hinstr->RequiresHoleCheck(); |
| 3128 int offset = FixedArray::kHeaderSize - kHeapObjectTag; | |
| 3129 Representation representation = hinstr->representation(); | 3120 Representation representation = hinstr->representation(); |
| 3121 int offset = instr->base_offset(); |
| 3130 | 3122 |
| 3131 if (representation.IsInteger32() && SmiValuesAre32Bits() && | 3123 if (representation.IsInteger32() && SmiValuesAre32Bits() && |
| 3132 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { | 3124 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { |
| 3133 ASSERT(!requires_hole_check); | 3125 ASSERT(!requires_hole_check); |
| 3134 if (FLAG_debug_code) { | 3126 if (FLAG_debug_code) { |
| 3135 Register scratch = kScratchRegister; | 3127 Register scratch = kScratchRegister; |
| 3136 __ Load(scratch, | 3128 __ Load(scratch, |
| 3137 BuildFastArrayOperand(instr->elements(), | 3129 BuildFastArrayOperand(instr->elements(), |
| 3138 key, | 3130 key, |
| 3139 FAST_ELEMENTS, | 3131 FAST_ELEMENTS, |
| 3140 offset, | 3132 offset), |
| 3141 instr->additional_index()), | |
| 3142 Representation::Smi()); | 3133 Representation::Smi()); |
| 3143 __ AssertSmi(scratch); | 3134 __ AssertSmi(scratch); |
| 3144 } | 3135 } |
| 3145 // Read int value directly from upper half of the smi. | 3136 // Read int value directly from upper half of the smi. |
| 3146 STATIC_ASSERT(kSmiTag == 0); | 3137 STATIC_ASSERT(kSmiTag == 0); |
| 3147 ASSERT(kSmiTagSize + kSmiShiftSize == 32); | 3138 ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
| 3148 offset += kPointerSize / 2; | 3139 offset += kPointerSize / 2; |
| 3149 } | 3140 } |
| 3150 | 3141 |
| 3151 __ Load(result, | 3142 __ Load(result, |
| 3152 BuildFastArrayOperand(instr->elements(), | 3143 BuildFastArrayOperand(instr->elements(), |
| 3153 key, | 3144 key, |
| 3154 FAST_ELEMENTS, | 3145 FAST_ELEMENTS, |
| 3155 offset, | 3146 offset), |
| 3156 instr->additional_index()), | |
| 3157 representation); | 3147 representation); |
| 3158 | 3148 |
| 3159 // Check for the hole value. | 3149 // Check for the hole value. |
| 3160 if (requires_hole_check) { | 3150 if (requires_hole_check) { |
| 3161 if (IsFastSmiElementsKind(hinstr->elements_kind())) { | 3151 if (IsFastSmiElementsKind(hinstr->elements_kind())) { |
| 3162 Condition smi = __ CheckSmi(result); | 3152 Condition smi = __ CheckSmi(result); |
| 3163 DeoptimizeIf(NegateCondition(smi), instr->environment()); | 3153 DeoptimizeIf(NegateCondition(smi), instr->environment()); |
| 3164 } else { | 3154 } else { |
| 3165 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 3155 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
| 3166 DeoptimizeIf(equal, instr->environment()); | 3156 DeoptimizeIf(equal, instr->environment()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3177 } else { | 3167 } else { |
| 3178 DoLoadKeyedFixedArray(instr); | 3168 DoLoadKeyedFixedArray(instr); |
| 3179 } | 3169 } |
| 3180 } | 3170 } |
| 3181 | 3171 |
| 3182 | 3172 |
| 3183 Operand LCodeGen::BuildFastArrayOperand( | 3173 Operand LCodeGen::BuildFastArrayOperand( |
| 3184 LOperand* elements_pointer, | 3174 LOperand* elements_pointer, |
| 3185 LOperand* key, | 3175 LOperand* key, |
| 3186 ElementsKind elements_kind, | 3176 ElementsKind elements_kind, |
| 3187 uint32_t offset, | 3177 uint32_t offset) { |
| 3188 uint32_t additional_index) { | |
| 3189 Register elements_pointer_reg = ToRegister(elements_pointer); | 3178 Register elements_pointer_reg = ToRegister(elements_pointer); |
| 3190 int shift_size = ElementsKindToShiftSize(elements_kind); | 3179 int shift_size = ElementsKindToShiftSize(elements_kind); |
| 3191 if (key->IsConstantOperand()) { | 3180 if (key->IsConstantOperand()) { |
| 3192 int32_t constant_value = ToInteger32(LConstantOperand::cast(key)); | 3181 int32_t constant_value = ToInteger32(LConstantOperand::cast(key)); |
| 3193 if (constant_value & 0xF0000000) { | 3182 if (constant_value & 0xF0000000) { |
| 3194 Abort(kArrayIndexConstantValueTooBig); | 3183 Abort(kArrayIndexConstantValueTooBig); |
| 3195 } | 3184 } |
| 3196 return Operand(elements_pointer_reg, | 3185 return Operand(elements_pointer_reg, |
| 3197 ((constant_value + additional_index) << shift_size) | 3186 (constant_value << shift_size) + offset); |
| 3198 + offset); | |
| 3199 } else { | 3187 } else { |
| 3200 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); | 3188 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
| 3201 return Operand(elements_pointer_reg, | 3189 return Operand(elements_pointer_reg, |
| 3202 ToRegister(key), | 3190 ToRegister(key), |
| 3203 scale_factor, | 3191 scale_factor, |
| 3204 offset + (additional_index << shift_size)); | 3192 offset); |
| 3205 } | 3193 } |
| 3206 } | 3194 } |
| 3207 | 3195 |
| 3208 | 3196 |
| 3209 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 3197 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 3210 ASSERT(ToRegister(instr->context()).is(rsi)); | 3198 ASSERT(ToRegister(instr->context()).is(rsi)); |
| 3211 ASSERT(ToRegister(instr->object()).is(rdx)); | 3199 ASSERT(ToRegister(instr->object()).is(rdx)); |
| 3212 ASSERT(ToRegister(instr->key()).is(rax)); | 3200 ASSERT(ToRegister(instr->key()).is(rax)); |
| 3213 | 3201 |
| 3214 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 3202 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| (...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4177 __ bind(&done); | 4165 __ bind(&done); |
| 4178 } else { | 4166 } else { |
| 4179 DeoptimizeIf(cc, instr->environment()); | 4167 DeoptimizeIf(cc, instr->environment()); |
| 4180 } | 4168 } |
| 4181 } | 4169 } |
| 4182 | 4170 |
| 4183 | 4171 |
| 4184 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4172 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 4185 ElementsKind elements_kind = instr->elements_kind(); | 4173 ElementsKind elements_kind = instr->elements_kind(); |
| 4186 LOperand* key = instr->key(); | 4174 LOperand* key = instr->key(); |
| 4187 int base_offset = instr->is_fixed_typed_array() | |
| 4188 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | |
| 4189 : 0; | |
| 4190 Operand operand(BuildFastArrayOperand( | 4175 Operand operand(BuildFastArrayOperand( |
| 4191 instr->elements(), | 4176 instr->elements(), |
| 4192 key, | 4177 key, |
| 4193 elements_kind, | 4178 elements_kind, |
| 4194 base_offset, | 4179 instr->base_offset())); |
| 4195 instr->additional_index())); | |
| 4196 | 4180 |
| 4197 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 4181 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4198 elements_kind == FLOAT32_ELEMENTS) { | 4182 elements_kind == FLOAT32_ELEMENTS) { |
| 4199 XMMRegister value(ToDoubleRegister(instr->value())); | 4183 XMMRegister value(ToDoubleRegister(instr->value())); |
| 4200 __ cvtsd2ss(value, value); | 4184 __ cvtsd2ss(value, value); |
| 4201 __ movss(operand, value); | 4185 __ movss(operand, value); |
| 4202 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 4186 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 4203 elements_kind == FLOAT64_ELEMENTS) { | 4187 elements_kind == FLOAT64_ELEMENTS) { |
| 4204 __ movsd(operand, ToDoubleRegister(instr->value())); | 4188 __ movsd(operand, ToDoubleRegister(instr->value())); |
| 4205 } else { | 4189 } else { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4257 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | 4241 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); |
| 4258 __ movq(value, kScratchRegister); | 4242 __ movq(value, kScratchRegister); |
| 4259 | 4243 |
| 4260 __ bind(&have_value); | 4244 __ bind(&have_value); |
| 4261 } | 4245 } |
| 4262 | 4246 |
| 4263 Operand double_store_operand = BuildFastArrayOperand( | 4247 Operand double_store_operand = BuildFastArrayOperand( |
| 4264 instr->elements(), | 4248 instr->elements(), |
| 4265 key, | 4249 key, |
| 4266 FAST_DOUBLE_ELEMENTS, | 4250 FAST_DOUBLE_ELEMENTS, |
| 4267 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 4251 instr->base_offset()); |
| 4268 instr->additional_index()); | |
| 4269 | 4252 |
| 4270 __ movsd(double_store_operand, value); | 4253 __ movsd(double_store_operand, value); |
| 4271 } | 4254 } |
| 4272 | 4255 |
| 4273 | 4256 |
| 4274 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4257 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4275 HStoreKeyed* hinstr = instr->hydrogen(); | 4258 HStoreKeyed* hinstr = instr->hydrogen(); |
| 4276 LOperand* key = instr->key(); | 4259 LOperand* key = instr->key(); |
| 4277 int offset = FixedArray::kHeaderSize - kHeapObjectTag; | 4260 int offset = instr->base_offset(); |
| 4278 Representation representation = hinstr->value()->representation(); | 4261 Representation representation = hinstr->value()->representation(); |
| 4279 | 4262 |
| 4280 if (representation.IsInteger32() && SmiValuesAre32Bits()) { | 4263 if (representation.IsInteger32() && SmiValuesAre32Bits()) { |
| 4281 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); | 4264 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
| 4282 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); | 4265 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); |
| 4283 if (FLAG_debug_code) { | 4266 if (FLAG_debug_code) { |
| 4284 Register scratch = kScratchRegister; | 4267 Register scratch = kScratchRegister; |
| 4285 __ Load(scratch, | 4268 __ Load(scratch, |
| 4286 BuildFastArrayOperand(instr->elements(), | 4269 BuildFastArrayOperand(instr->elements(), |
| 4287 key, | 4270 key, |
| 4288 FAST_ELEMENTS, | 4271 FAST_ELEMENTS, |
| 4289 offset, | 4272 offset), |
| 4290 instr->additional_index()), | |
| 4291 Representation::Smi()); | 4273 Representation::Smi()); |
| 4292 __ AssertSmi(scratch); | 4274 __ AssertSmi(scratch); |
| 4293 } | 4275 } |
| 4294 // Store int value directly to upper half of the smi. | 4276 // Store int value directly to upper half of the smi. |
| 4295 STATIC_ASSERT(kSmiTag == 0); | 4277 STATIC_ASSERT(kSmiTag == 0); |
| 4296 ASSERT(kSmiTagSize + kSmiShiftSize == 32); | 4278 ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
| 4297 offset += kPointerSize / 2; | 4279 offset += kPointerSize / 2; |
| 4298 } | 4280 } |
| 4299 | 4281 |
| 4300 Operand operand = | 4282 Operand operand = |
| 4301 BuildFastArrayOperand(instr->elements(), | 4283 BuildFastArrayOperand(instr->elements(), |
| 4302 key, | 4284 key, |
| 4303 FAST_ELEMENTS, | 4285 FAST_ELEMENTS, |
| 4304 offset, | 4286 offset); |
| 4305 instr->additional_index()); | |
| 4306 | |
| 4307 if (instr->value()->IsRegister()) { | 4287 if (instr->value()->IsRegister()) { |
| 4308 __ Store(operand, ToRegister(instr->value()), representation); | 4288 __ Store(operand, ToRegister(instr->value()), representation); |
| 4309 } else { | 4289 } else { |
| 4310 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4290 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4311 if (IsInteger32Constant(operand_value)) { | 4291 if (IsInteger32Constant(operand_value)) { |
| 4312 int32_t value = ToInteger32(operand_value); | 4292 int32_t value = ToInteger32(operand_value); |
| 4313 if (representation.IsSmi()) { | 4293 if (representation.IsSmi()) { |
| 4314 __ Move(operand, Smi::FromInt(value)); | 4294 __ Move(operand, Smi::FromInt(value)); |
| 4315 | 4295 |
| 4316 } else { | 4296 } else { |
| (...skipping 1403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5720 __ bind(deferred->exit()); | 5700 __ bind(deferred->exit()); |
| 5721 __ bind(&done); | 5701 __ bind(&done); |
| 5722 } | 5702 } |
| 5723 | 5703 |
| 5724 | 5704 |
| 5725 #undef __ | 5705 #undef __ |
| 5726 | 5706 |
| 5727 } } // namespace v8::internal | 5707 } } // namespace v8::internal |
| 5728 | 5708 |
| 5729 #endif // V8_TARGET_ARCH_X64 | 5709 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |