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 "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/arm/lithium-codegen-arm.h" | 7 #include "src/arm/lithium-codegen-arm.h" |
8 #include "src/arm/lithium-gap-resolver-arm.h" | 8 #include "src/arm/lithium-gap-resolver-arm.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 2252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2263 } | 2263 } |
2264 | 2264 |
2265 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 2265 if (expected.Contains(ToBooleanStub::SYMBOL)) { |
2266 // Symbol value -> true. | 2266 // Symbol value -> true. |
2267 __ CompareInstanceType(map, ip, SYMBOL_TYPE); | 2267 __ CompareInstanceType(map, ip, SYMBOL_TYPE); |
2268 __ b(eq, instr->TrueLabel(chunk_)); | 2268 __ b(eq, instr->TrueLabel(chunk_)); |
2269 } | 2269 } |
2270 | 2270 |
2271 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { | 2271 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { |
2272 // SIMD value -> true. | 2272 // SIMD value -> true. |
2273 __ CompareInstanceType(map, ip, FLOAT32X4_TYPE); | 2273 Label not_simd; |
2274 __ b(eq, instr->TrueLabel(chunk_)); | 2274 __ CompareInstanceType(map, ip, FIRST_SIMD_VALUE_TYPE); |
| 2275 __ b(lt, ¬_simd); |
| 2276 __ CompareInstanceType(map, ip, LAST_SIMD_VALUE_TYPE); |
| 2277 __ b(le, instr->TrueLabel(chunk_)); |
| 2278 __ bind(¬_simd); |
2275 } | 2279 } |
2276 | 2280 |
2277 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2281 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
2278 // heap number -> false iff +0, -0, or NaN. | 2282 // heap number -> false iff +0, -0, or NaN. |
2279 DwVfpRegister dbl_scratch = double_scratch0(); | 2283 DwVfpRegister dbl_scratch = double_scratch0(); |
2280 Label not_heap_number; | 2284 Label not_heap_number; |
2281 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 2285 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
2282 __ b(ne, ¬_heap_number); | 2286 __ b(ne, ¬_heap_number); |
2283 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 2287 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
2284 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); | 2288 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2980 CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(), | 2984 CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(), |
2981 SLOPPY, PREMONOMORPHIC).code(); | 2985 SLOPPY, PREMONOMORPHIC).code(); |
2982 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2986 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
2983 } | 2987 } |
2984 | 2988 |
2985 | 2989 |
2986 void LCodeGen::DoLoadGlobalViaContext(LLoadGlobalViaContext* instr) { | 2990 void LCodeGen::DoLoadGlobalViaContext(LLoadGlobalViaContext* instr) { |
2987 DCHECK(ToRegister(instr->context()).is(cp)); | 2991 DCHECK(ToRegister(instr->context()).is(cp)); |
2988 DCHECK(ToRegister(instr->result()).is(r0)); | 2992 DCHECK(ToRegister(instr->result()).is(r0)); |
2989 | 2993 |
2990 int const slot = instr->slot_index(); | 2994 __ mov(LoadGlobalViaContextDescriptor::DepthRegister(), |
2991 int const depth = instr->depth(); | 2995 Operand(Smi::FromInt(instr->depth()))); |
2992 if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { | 2996 __ mov(LoadGlobalViaContextDescriptor::SlotRegister(), |
2993 __ mov(LoadGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); | 2997 Operand(Smi::FromInt(instr->slot_index()))); |
2994 Handle<Code> stub = | 2998 __ mov(LoadGlobalViaContextDescriptor::NameRegister(), |
2995 CodeFactory::LoadGlobalViaContext(isolate(), depth).code(); | 2999 Operand(instr->name())); |
2996 CallCode(stub, RelocInfo::CODE_TARGET, instr); | 3000 |
2997 } else { | 3001 Handle<Code> stub = |
2998 __ Push(Smi::FromInt(slot)); | 3002 CodeFactory::LoadGlobalViaContext(isolate(), instr->depth()).code(); |
2999 __ CallRuntime(Runtime::kLoadGlobalViaContext, 1); | 3003 CallCode(stub, RelocInfo::CODE_TARGET, instr); |
3000 } | |
3001 } | 3004 } |
3002 | 3005 |
3003 | 3006 |
3004 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 3007 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
3005 Register context = ToRegister(instr->context()); | 3008 Register context = ToRegister(instr->context()); |
3006 Register result = ToRegister(instr->result()); | 3009 Register result = ToRegister(instr->result()); |
3007 __ ldr(result, ContextOperand(context, instr->slot_index())); | 3010 __ ldr(result, ContextOperand(context, instr->slot_index())); |
3008 if (instr->hydrogen()->RequiresHoleCheck()) { | 3011 if (instr->hydrogen()->RequiresHoleCheck()) { |
3009 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 3012 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
3010 __ cmp(result, ip); | 3013 __ cmp(result, ip); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3180 Abort(kArrayIndexConstantValueTooBig); | 3183 Abort(kArrayIndexConstantValueTooBig); |
3181 } | 3184 } |
3182 } else { | 3185 } else { |
3183 key = ToRegister(instr->key()); | 3186 key = ToRegister(instr->key()); |
3184 } | 3187 } |
3185 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3188 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
3186 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3189 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
3187 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3190 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
3188 int base_offset = instr->base_offset(); | 3191 int base_offset = instr->base_offset(); |
3189 | 3192 |
3190 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 3193 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3194 elements_kind == FLOAT32_ELEMENTS || |
| 3195 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 3196 elements_kind == FLOAT64_ELEMENTS) { |
3191 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3197 DwVfpRegister result = ToDoubleRegister(instr->result()); |
3192 Operand operand = key_is_constant | 3198 Operand operand = key_is_constant |
3193 ? Operand(constant_key << element_size_shift) | 3199 ? Operand(constant_key << element_size_shift) |
3194 : Operand(key, LSL, shift_size); | 3200 : Operand(key, LSL, shift_size); |
3195 __ add(scratch0(), external_pointer, operand); | 3201 __ add(scratch0(), external_pointer, operand); |
3196 if (elements_kind == FLOAT32_ELEMENTS) { | 3202 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3203 elements_kind == FLOAT32_ELEMENTS) { |
3197 __ vldr(double_scratch0().low(), scratch0(), base_offset); | 3204 __ vldr(double_scratch0().low(), scratch0(), base_offset); |
3198 __ vcvt_f64_f32(result, double_scratch0().low()); | 3205 __ vcvt_f64_f32(result, double_scratch0().low()); |
3199 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3206 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
3200 __ vldr(result, scratch0(), base_offset); | 3207 __ vldr(result, scratch0(), base_offset); |
3201 } | 3208 } |
3202 } else { | 3209 } else { |
3203 Register result = ToRegister(instr->result()); | 3210 Register result = ToRegister(instr->result()); |
3204 MemOperand mem_operand = PrepareKeyedOperand( | 3211 MemOperand mem_operand = PrepareKeyedOperand( |
3205 key, external_pointer, key_is_constant, constant_key, | 3212 key, external_pointer, key_is_constant, constant_key, |
3206 element_size_shift, shift_size, base_offset); | 3213 element_size_shift, shift_size, base_offset); |
3207 switch (elements_kind) { | 3214 switch (elements_kind) { |
| 3215 case EXTERNAL_INT8_ELEMENTS: |
3208 case INT8_ELEMENTS: | 3216 case INT8_ELEMENTS: |
3209 __ ldrsb(result, mem_operand); | 3217 __ ldrsb(result, mem_operand); |
3210 break; | 3218 break; |
| 3219 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 3220 case EXTERNAL_UINT8_ELEMENTS: |
3211 case UINT8_ELEMENTS: | 3221 case UINT8_ELEMENTS: |
3212 case UINT8_CLAMPED_ELEMENTS: | 3222 case UINT8_CLAMPED_ELEMENTS: |
3213 __ ldrb(result, mem_operand); | 3223 __ ldrb(result, mem_operand); |
3214 break; | 3224 break; |
| 3225 case EXTERNAL_INT16_ELEMENTS: |
3215 case INT16_ELEMENTS: | 3226 case INT16_ELEMENTS: |
3216 __ ldrsh(result, mem_operand); | 3227 __ ldrsh(result, mem_operand); |
3217 break; | 3228 break; |
| 3229 case EXTERNAL_UINT16_ELEMENTS: |
3218 case UINT16_ELEMENTS: | 3230 case UINT16_ELEMENTS: |
3219 __ ldrh(result, mem_operand); | 3231 __ ldrh(result, mem_operand); |
3220 break; | 3232 break; |
| 3233 case EXTERNAL_INT32_ELEMENTS: |
3221 case INT32_ELEMENTS: | 3234 case INT32_ELEMENTS: |
3222 __ ldr(result, mem_operand); | 3235 __ ldr(result, mem_operand); |
3223 break; | 3236 break; |
| 3237 case EXTERNAL_UINT32_ELEMENTS: |
3224 case UINT32_ELEMENTS: | 3238 case UINT32_ELEMENTS: |
3225 __ ldr(result, mem_operand); | 3239 __ ldr(result, mem_operand); |
3226 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 3240 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
3227 __ cmp(result, Operand(0x80000000)); | 3241 __ cmp(result, Operand(0x80000000)); |
3228 DeoptimizeIf(cs, instr, Deoptimizer::kNegativeValue); | 3242 DeoptimizeIf(cs, instr, Deoptimizer::kNegativeValue); |
3229 } | 3243 } |
3230 break; | 3244 break; |
3231 case FLOAT32_ELEMENTS: | 3245 case FLOAT32_ELEMENTS: |
3232 case FLOAT64_ELEMENTS: | 3246 case FLOAT64_ELEMENTS: |
| 3247 case EXTERNAL_FLOAT32_ELEMENTS: |
| 3248 case EXTERNAL_FLOAT64_ELEMENTS: |
3233 case FAST_HOLEY_DOUBLE_ELEMENTS: | 3249 case FAST_HOLEY_DOUBLE_ELEMENTS: |
3234 case FAST_HOLEY_ELEMENTS: | 3250 case FAST_HOLEY_ELEMENTS: |
3235 case FAST_HOLEY_SMI_ELEMENTS: | 3251 case FAST_HOLEY_SMI_ELEMENTS: |
3236 case FAST_DOUBLE_ELEMENTS: | 3252 case FAST_DOUBLE_ELEMENTS: |
3237 case FAST_ELEMENTS: | 3253 case FAST_ELEMENTS: |
3238 case FAST_SMI_ELEMENTS: | 3254 case FAST_SMI_ELEMENTS: |
3239 case DICTIONARY_ELEMENTS: | 3255 case DICTIONARY_ELEMENTS: |
3240 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 3256 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
3241 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 3257 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
3242 UNREACHABLE(); | 3258 UNREACHABLE(); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3332 __ cmp(result, Operand(Smi::FromInt(Isolate::kArrayProtectorValid))); | 3348 __ cmp(result, Operand(Smi::FromInt(Isolate::kArrayProtectorValid))); |
3333 DeoptimizeIf(ne, instr, Deoptimizer::kHole); | 3349 DeoptimizeIf(ne, instr, Deoptimizer::kHole); |
3334 } | 3350 } |
3335 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); | 3351 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); |
3336 __ bind(&done); | 3352 __ bind(&done); |
3337 } | 3353 } |
3338 } | 3354 } |
3339 | 3355 |
3340 | 3356 |
3341 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 3357 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
3342 if (instr->is_fixed_typed_array()) { | 3358 if (instr->is_typed_elements()) { |
3343 DoLoadKeyedExternalArray(instr); | 3359 DoLoadKeyedExternalArray(instr); |
3344 } else if (instr->hydrogen()->representation().IsDouble()) { | 3360 } else if (instr->hydrogen()->representation().IsDouble()) { |
3345 DoLoadKeyedFixedDoubleArray(instr); | 3361 DoLoadKeyedFixedDoubleArray(instr); |
3346 } else { | 3362 } else { |
3347 DoLoadKeyedFixedArray(instr); | 3363 DoLoadKeyedFixedArray(instr); |
3348 } | 3364 } |
3349 } | 3365 } |
3350 | 3366 |
3351 | 3367 |
3352 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | 3368 MemOperand LCodeGen::PrepareKeyedOperand(Register key, |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3575 __ ldr(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3591 __ ldr(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3576 } else { | 3592 } else { |
3577 // If there is no frame, the context must be in cp. | 3593 // If there is no frame, the context must be in cp. |
3578 DCHECK(result.is(cp)); | 3594 DCHECK(result.is(cp)); |
3579 } | 3595 } |
3580 } | 3596 } |
3581 | 3597 |
3582 | 3598 |
3583 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { | 3599 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { |
3584 DCHECK(ToRegister(instr->context()).is(cp)); | 3600 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3601 __ push(cp); // The context is the first argument. |
3585 __ Move(scratch0(), instr->hydrogen()->pairs()); | 3602 __ Move(scratch0(), instr->hydrogen()->pairs()); |
3586 __ push(scratch0()); | 3603 __ push(scratch0()); |
3587 __ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); | 3604 __ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); |
3588 __ push(scratch0()); | 3605 __ push(scratch0()); |
3589 CallRuntime(Runtime::kDeclareGlobals, 2, instr); | 3606 CallRuntime(Runtime::kDeclareGlobals, 3, instr); |
3590 } | 3607 } |
3591 | 3608 |
3592 | 3609 |
3593 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3610 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
3594 int formal_parameter_count, int arity, | 3611 int formal_parameter_count, int arity, |
3595 LInstruction* instr) { | 3612 LInstruction* instr) { |
3596 bool dont_adapt_arguments = | 3613 bool dont_adapt_arguments = |
3597 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3614 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
3598 bool can_invoke_directly = | 3615 bool can_invoke_directly = |
3599 dont_adapt_arguments || formal_parameter_count == arity; | 3616 dont_adapt_arguments || formal_parameter_count == arity; |
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4229 instr->hydrogen()->initialization_state()).code(); | 4246 instr->hydrogen()->initialization_state()).code(); |
4230 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); | 4247 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
4231 } | 4248 } |
4232 | 4249 |
4233 | 4250 |
4234 void LCodeGen::DoStoreGlobalViaContext(LStoreGlobalViaContext* instr) { | 4251 void LCodeGen::DoStoreGlobalViaContext(LStoreGlobalViaContext* instr) { |
4235 DCHECK(ToRegister(instr->context()).is(cp)); | 4252 DCHECK(ToRegister(instr->context()).is(cp)); |
4236 DCHECK(ToRegister(instr->value()) | 4253 DCHECK(ToRegister(instr->value()) |
4237 .is(StoreGlobalViaContextDescriptor::ValueRegister())); | 4254 .is(StoreGlobalViaContextDescriptor::ValueRegister())); |
4238 | 4255 |
4239 int const slot = instr->slot_index(); | 4256 __ mov(StoreGlobalViaContextDescriptor::DepthRegister(), |
4240 int const depth = instr->depth(); | 4257 Operand(Smi::FromInt(instr->depth()))); |
4241 if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { | 4258 __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), |
4242 __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); | 4259 Operand(Smi::FromInt(instr->slot_index()))); |
4243 Handle<Code> stub = CodeFactory::StoreGlobalViaContext( | 4260 __ mov(StoreGlobalViaContextDescriptor::NameRegister(), |
4244 isolate(), depth, instr->language_mode()) | 4261 Operand(instr->name())); |
4245 .code(); | 4262 |
4246 CallCode(stub, RelocInfo::CODE_TARGET, instr); | 4263 Handle<Code> stub = CodeFactory::StoreGlobalViaContext( |
4247 } else { | 4264 isolate(), instr->depth(), instr->language_mode()) |
4248 __ Push(Smi::FromInt(slot)); | 4265 .code(); |
4249 __ push(StoreGlobalViaContextDescriptor::ValueRegister()); | 4266 CallCode(stub, RelocInfo::CODE_TARGET, instr); |
4250 __ CallRuntime(is_strict(instr->language_mode()) | |
4251 ? Runtime::kStoreGlobalViaContext_Strict | |
4252 : Runtime::kStoreGlobalViaContext_Sloppy, | |
4253 2); | |
4254 } | |
4255 } | 4267 } |
4256 | 4268 |
4257 | 4269 |
4258 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 4270 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
4259 Condition cc = instr->hydrogen()->allow_equality() ? hi : hs; | 4271 Condition cc = instr->hydrogen()->allow_equality() ? hi : hs; |
4260 if (instr->index()->IsConstantOperand()) { | 4272 if (instr->index()->IsConstantOperand()) { |
4261 Operand index = ToOperand(instr->index()); | 4273 Operand index = ToOperand(instr->index()); |
4262 Register length = ToRegister(instr->length()); | 4274 Register length = ToRegister(instr->length()); |
4263 __ cmp(length, index); | 4275 __ cmp(length, index); |
4264 cc = CommuteCondition(cc); | 4276 cc = CommuteCondition(cc); |
(...skipping 25 matching lines...) Expand all Loading... |
4290 Abort(kArrayIndexConstantValueTooBig); | 4302 Abort(kArrayIndexConstantValueTooBig); |
4291 } | 4303 } |
4292 } else { | 4304 } else { |
4293 key = ToRegister(instr->key()); | 4305 key = ToRegister(instr->key()); |
4294 } | 4306 } |
4295 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4307 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
4296 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4308 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
4297 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4309 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
4298 int base_offset = instr->base_offset(); | 4310 int base_offset = instr->base_offset(); |
4299 | 4311 |
4300 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 4312 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4313 elements_kind == FLOAT32_ELEMENTS || |
| 4314 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 4315 elements_kind == FLOAT64_ELEMENTS) { |
4301 Register address = scratch0(); | 4316 Register address = scratch0(); |
4302 DwVfpRegister value(ToDoubleRegister(instr->value())); | 4317 DwVfpRegister value(ToDoubleRegister(instr->value())); |
4303 if (key_is_constant) { | 4318 if (key_is_constant) { |
4304 if (constant_key != 0) { | 4319 if (constant_key != 0) { |
4305 __ add(address, external_pointer, | 4320 __ add(address, external_pointer, |
4306 Operand(constant_key << element_size_shift)); | 4321 Operand(constant_key << element_size_shift)); |
4307 } else { | 4322 } else { |
4308 address = external_pointer; | 4323 address = external_pointer; |
4309 } | 4324 } |
4310 } else { | 4325 } else { |
4311 __ add(address, external_pointer, Operand(key, LSL, shift_size)); | 4326 __ add(address, external_pointer, Operand(key, LSL, shift_size)); |
4312 } | 4327 } |
4313 if (elements_kind == FLOAT32_ELEMENTS) { | 4328 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4329 elements_kind == FLOAT32_ELEMENTS) { |
4314 __ vcvt_f32_f64(double_scratch0().low(), value); | 4330 __ vcvt_f32_f64(double_scratch0().low(), value); |
4315 __ vstr(double_scratch0().low(), address, base_offset); | 4331 __ vstr(double_scratch0().low(), address, base_offset); |
4316 } else { // Storing doubles, not floats. | 4332 } else { // Storing doubles, not floats. |
4317 __ vstr(value, address, base_offset); | 4333 __ vstr(value, address, base_offset); |
4318 } | 4334 } |
4319 } else { | 4335 } else { |
4320 Register value(ToRegister(instr->value())); | 4336 Register value(ToRegister(instr->value())); |
4321 MemOperand mem_operand = PrepareKeyedOperand( | 4337 MemOperand mem_operand = PrepareKeyedOperand( |
4322 key, external_pointer, key_is_constant, constant_key, | 4338 key, external_pointer, key_is_constant, constant_key, |
4323 element_size_shift, shift_size, | 4339 element_size_shift, shift_size, |
4324 base_offset); | 4340 base_offset); |
4325 switch (elements_kind) { | 4341 switch (elements_kind) { |
| 4342 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 4343 case EXTERNAL_INT8_ELEMENTS: |
| 4344 case EXTERNAL_UINT8_ELEMENTS: |
4326 case UINT8_ELEMENTS: | 4345 case UINT8_ELEMENTS: |
4327 case UINT8_CLAMPED_ELEMENTS: | 4346 case UINT8_CLAMPED_ELEMENTS: |
4328 case INT8_ELEMENTS: | 4347 case INT8_ELEMENTS: |
4329 __ strb(value, mem_operand); | 4348 __ strb(value, mem_operand); |
4330 break; | 4349 break; |
| 4350 case EXTERNAL_INT16_ELEMENTS: |
| 4351 case EXTERNAL_UINT16_ELEMENTS: |
4331 case INT16_ELEMENTS: | 4352 case INT16_ELEMENTS: |
4332 case UINT16_ELEMENTS: | 4353 case UINT16_ELEMENTS: |
4333 __ strh(value, mem_operand); | 4354 __ strh(value, mem_operand); |
4334 break; | 4355 break; |
| 4356 case EXTERNAL_INT32_ELEMENTS: |
| 4357 case EXTERNAL_UINT32_ELEMENTS: |
4335 case INT32_ELEMENTS: | 4358 case INT32_ELEMENTS: |
4336 case UINT32_ELEMENTS: | 4359 case UINT32_ELEMENTS: |
4337 __ str(value, mem_operand); | 4360 __ str(value, mem_operand); |
4338 break; | 4361 break; |
4339 case FLOAT32_ELEMENTS: | 4362 case FLOAT32_ELEMENTS: |
4340 case FLOAT64_ELEMENTS: | 4363 case FLOAT64_ELEMENTS: |
| 4364 case EXTERNAL_FLOAT32_ELEMENTS: |
| 4365 case EXTERNAL_FLOAT64_ELEMENTS: |
4341 case FAST_DOUBLE_ELEMENTS: | 4366 case FAST_DOUBLE_ELEMENTS: |
4342 case FAST_ELEMENTS: | 4367 case FAST_ELEMENTS: |
4343 case FAST_SMI_ELEMENTS: | 4368 case FAST_SMI_ELEMENTS: |
4344 case FAST_HOLEY_DOUBLE_ELEMENTS: | 4369 case FAST_HOLEY_DOUBLE_ELEMENTS: |
4345 case FAST_HOLEY_ELEMENTS: | 4370 case FAST_HOLEY_ELEMENTS: |
4346 case FAST_HOLEY_SMI_ELEMENTS: | 4371 case FAST_HOLEY_SMI_ELEMENTS: |
4347 case DICTIONARY_ELEMENTS: | 4372 case DICTIONARY_ELEMENTS: |
4348 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 4373 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
4349 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 4374 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
4350 UNREACHABLE(); | 4375 UNREACHABLE(); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4436 kSaveFPRegs, | 4461 kSaveFPRegs, |
4437 EMIT_REMEMBERED_SET, | 4462 EMIT_REMEMBERED_SET, |
4438 check_needed, | 4463 check_needed, |
4439 instr->hydrogen()->PointersToHereCheckForValue()); | 4464 instr->hydrogen()->PointersToHereCheckForValue()); |
4440 } | 4465 } |
4441 } | 4466 } |
4442 | 4467 |
4443 | 4468 |
4444 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4469 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
4445 // By cases: external, fast double | 4470 // By cases: external, fast double |
4446 if (instr->is_fixed_typed_array()) { | 4471 if (instr->is_typed_elements()) { |
4447 DoStoreKeyedExternalArray(instr); | 4472 DoStoreKeyedExternalArray(instr); |
4448 } else if (instr->hydrogen()->value()->representation().IsDouble()) { | 4473 } else if (instr->hydrogen()->value()->representation().IsDouble()) { |
4449 DoStoreKeyedFixedDoubleArray(instr); | 4474 DoStoreKeyedFixedDoubleArray(instr); |
4450 } else { | 4475 } else { |
4451 DoStoreKeyedFixedArray(instr); | 4476 DoStoreKeyedFixedArray(instr); |
4452 } | 4477 } |
4453 } | 4478 } |
4454 | 4479 |
4455 | 4480 |
4456 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4481 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5700 // Check for undetectable objects => false. | 5725 // Check for undetectable objects => false. |
5701 __ ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 5726 __ ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); |
5702 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); | 5727 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); |
5703 final_branch_condition = eq; | 5728 final_branch_condition = eq; |
5704 | 5729 |
5705 } else if (String::Equals(type_name, factory->float32x4_string())) { | 5730 } else if (String::Equals(type_name, factory->float32x4_string())) { |
5706 __ JumpIfSmi(input, false_label); | 5731 __ JumpIfSmi(input, false_label); |
5707 __ CompareObjectType(input, scratch, no_reg, FLOAT32X4_TYPE); | 5732 __ CompareObjectType(input, scratch, no_reg, FLOAT32X4_TYPE); |
5708 final_branch_condition = eq; | 5733 final_branch_condition = eq; |
5709 | 5734 |
| 5735 } else if (String::Equals(type_name, factory->int32x4_string())) { |
| 5736 __ JumpIfSmi(input, false_label); |
| 5737 __ CompareObjectType(input, scratch, no_reg, INT32X4_TYPE); |
| 5738 final_branch_condition = eq; |
| 5739 |
| 5740 } else if (String::Equals(type_name, factory->bool32x4_string())) { |
| 5741 __ JumpIfSmi(input, false_label); |
| 5742 __ CompareObjectType(input, scratch, no_reg, BOOL32X4_TYPE); |
| 5743 final_branch_condition = eq; |
| 5744 |
| 5745 } else if (String::Equals(type_name, factory->int16x8_string())) { |
| 5746 __ JumpIfSmi(input, false_label); |
| 5747 __ CompareObjectType(input, scratch, no_reg, INT16X8_TYPE); |
| 5748 final_branch_condition = eq; |
| 5749 |
| 5750 } else if (String::Equals(type_name, factory->bool16x8_string())) { |
| 5751 __ JumpIfSmi(input, false_label); |
| 5752 __ CompareObjectType(input, scratch, no_reg, BOOL16X8_TYPE); |
| 5753 final_branch_condition = eq; |
| 5754 |
| 5755 } else if (String::Equals(type_name, factory->int8x16_string())) { |
| 5756 __ JumpIfSmi(input, false_label); |
| 5757 __ CompareObjectType(input, scratch, no_reg, INT8X16_TYPE); |
| 5758 final_branch_condition = eq; |
| 5759 |
| 5760 } else if (String::Equals(type_name, factory->bool8x16_string())) { |
| 5761 __ JumpIfSmi(input, false_label); |
| 5762 __ CompareObjectType(input, scratch, no_reg, BOOL8X16_TYPE); |
| 5763 final_branch_condition = eq; |
| 5764 |
5710 } else { | 5765 } else { |
5711 __ b(false_label); | 5766 __ b(false_label); |
5712 } | 5767 } |
5713 | 5768 |
5714 return final_branch_condition; | 5769 return final_branch_condition; |
5715 } | 5770 } |
5716 | 5771 |
5717 | 5772 |
5718 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 5773 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
5719 Register temp1 = ToRegister(instr->temp()); | 5774 Register temp1 = ToRegister(instr->temp()); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6016 __ push(ToRegister(instr->function())); | 6071 __ push(ToRegister(instr->function())); |
6017 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6072 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
6018 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6073 RecordSafepoint(Safepoint::kNoLazyDeopt); |
6019 } | 6074 } |
6020 | 6075 |
6021 | 6076 |
6022 #undef __ | 6077 #undef __ |
6023 | 6078 |
6024 } // namespace internal | 6079 } // namespace internal |
6025 } // namespace v8 | 6080 } // namespace v8 |
OLD | NEW |