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 |