OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/cpu-profiler.h" | 10 #include "src/cpu-profiler.h" |
(...skipping 2289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2300 } | 2300 } |
2301 | 2301 |
2302 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 2302 if (expected.Contains(ToBooleanStub::SYMBOL)) { |
2303 // Symbol value -> true. | 2303 // Symbol value -> true. |
2304 __ CompareInstanceType(map, ip, SYMBOL_TYPE); | 2304 __ CompareInstanceType(map, ip, SYMBOL_TYPE); |
2305 __ beq(instr->TrueLabel(chunk_)); | 2305 __ beq(instr->TrueLabel(chunk_)); |
2306 } | 2306 } |
2307 | 2307 |
2308 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { | 2308 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { |
2309 // SIMD value -> true. | 2309 // SIMD value -> true. |
2310 __ CompareInstanceType(map, ip, FLOAT32X4_TYPE); | 2310 Label not_simd; |
2311 __ beq(instr->TrueLabel(chunk_)); | 2311 __ CompareInstanceType(map, ip, FIRST_SIMD_VALUE_TYPE); |
| 2312 __ blt(¬_simd); |
| 2313 __ CompareInstanceType(map, ip, LAST_SIMD_VALUE_TYPE); |
| 2314 __ ble(instr->TrueLabel(chunk_)); |
| 2315 __ bind(¬_simd); |
2312 } | 2316 } |
2313 | 2317 |
2314 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2318 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
2315 // heap number -> false iff +0, -0, or NaN. | 2319 // heap number -> false iff +0, -0, or NaN. |
2316 Label not_heap_number; | 2320 Label not_heap_number; |
2317 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 2321 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
2318 __ bne(¬_heap_number); | 2322 __ bne(¬_heap_number); |
2319 __ lfd(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 2323 __ lfd(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
2320 // Test the double value. Zero and NaN are false. | 2324 // Test the double value. Zero and NaN are false. |
2321 __ fcmpu(dbl_scratch, kDoubleRegZero, cr7); | 2325 __ fcmpu(dbl_scratch, kDoubleRegZero, cr7); |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3057 CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(), | 3061 CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(), |
3058 SLOPPY, PREMONOMORPHIC).code(); | 3062 SLOPPY, PREMONOMORPHIC).code(); |
3059 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3063 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
3060 } | 3064 } |
3061 | 3065 |
3062 | 3066 |
3063 void LCodeGen::DoLoadGlobalViaContext(LLoadGlobalViaContext* instr) { | 3067 void LCodeGen::DoLoadGlobalViaContext(LLoadGlobalViaContext* instr) { |
3064 DCHECK(ToRegister(instr->context()).is(cp)); | 3068 DCHECK(ToRegister(instr->context()).is(cp)); |
3065 DCHECK(ToRegister(instr->result()).is(r3)); | 3069 DCHECK(ToRegister(instr->result()).is(r3)); |
3066 | 3070 |
3067 int const slot = instr->slot_index(); | 3071 __ mov(LoadGlobalViaContextDescriptor::DepthRegister(), |
3068 int const depth = instr->depth(); | 3072 Operand(Smi::FromInt(instr->depth()))); |
3069 if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { | 3073 __ mov(LoadGlobalViaContextDescriptor::SlotRegister(), |
3070 __ mov(LoadGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); | 3074 Operand(Smi::FromInt(instr->slot_index()))); |
3071 Handle<Code> stub = | 3075 __ mov(LoadGlobalViaContextDescriptor::NameRegister(), |
3072 CodeFactory::LoadGlobalViaContext(isolate(), depth).code(); | 3076 Operand(instr->name())); |
3073 CallCode(stub, RelocInfo::CODE_TARGET, instr); | 3077 |
3074 } else { | 3078 Handle<Code> stub = |
3075 __ Push(Smi::FromInt(slot)); | 3079 CodeFactory::LoadGlobalViaContext(isolate(), instr->depth()).code(); |
3076 __ CallRuntime(Runtime::kLoadGlobalViaContext, 1); | 3080 CallCode(stub, RelocInfo::CODE_TARGET, instr); |
3077 } | |
3078 } | 3081 } |
3079 | 3082 |
3080 | 3083 |
3081 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 3084 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
3082 Register context = ToRegister(instr->context()); | 3085 Register context = ToRegister(instr->context()); |
3083 Register result = ToRegister(instr->result()); | 3086 Register result = ToRegister(instr->result()); |
3084 __ LoadP(result, ContextOperand(context, instr->slot_index())); | 3087 __ LoadP(result, ContextOperand(context, instr->slot_index())); |
3085 if (instr->hydrogen()->RequiresHoleCheck()) { | 3088 if (instr->hydrogen()->RequiresHoleCheck()) { |
3086 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 3089 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
3087 if (instr->hydrogen()->DeoptimizesOnHole()) { | 3090 if (instr->hydrogen()->DeoptimizesOnHole()) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3287 if (constant_key & 0xF0000000) { | 3290 if (constant_key & 0xF0000000) { |
3288 Abort(kArrayIndexConstantValueTooBig); | 3291 Abort(kArrayIndexConstantValueTooBig); |
3289 } | 3292 } |
3290 } else { | 3293 } else { |
3291 key = ToRegister(instr->key()); | 3294 key = ToRegister(instr->key()); |
3292 } | 3295 } |
3293 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3296 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
3294 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 3297 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
3295 int base_offset = instr->base_offset(); | 3298 int base_offset = instr->base_offset(); |
3296 | 3299 |
3297 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 3300 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3301 elements_kind == FLOAT32_ELEMENTS || |
| 3302 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 3303 elements_kind == FLOAT64_ELEMENTS) { |
3298 DoubleRegister result = ToDoubleRegister(instr->result()); | 3304 DoubleRegister result = ToDoubleRegister(instr->result()); |
3299 if (key_is_constant) { | 3305 if (key_is_constant) { |
3300 __ Add(scratch0(), external_pointer, constant_key << element_size_shift, | 3306 __ Add(scratch0(), external_pointer, constant_key << element_size_shift, |
3301 r0); | 3307 r0); |
3302 } else { | 3308 } else { |
3303 __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi); | 3309 __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi); |
3304 __ add(scratch0(), external_pointer, r0); | 3310 __ add(scratch0(), external_pointer, r0); |
3305 } | 3311 } |
3306 if (elements_kind == FLOAT32_ELEMENTS) { | 3312 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3313 elements_kind == FLOAT32_ELEMENTS) { |
3307 __ lfs(result, MemOperand(scratch0(), base_offset)); | 3314 __ lfs(result, MemOperand(scratch0(), base_offset)); |
3308 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3315 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
3309 __ lfd(result, MemOperand(scratch0(), base_offset)); | 3316 __ lfd(result, MemOperand(scratch0(), base_offset)); |
3310 } | 3317 } |
3311 } else { | 3318 } else { |
3312 Register result = ToRegister(instr->result()); | 3319 Register result = ToRegister(instr->result()); |
3313 MemOperand mem_operand = | 3320 MemOperand mem_operand = |
3314 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, | 3321 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, |
3315 constant_key, element_size_shift, base_offset); | 3322 constant_key, element_size_shift, base_offset); |
3316 switch (elements_kind) { | 3323 switch (elements_kind) { |
| 3324 case EXTERNAL_INT8_ELEMENTS: |
3317 case INT8_ELEMENTS: | 3325 case INT8_ELEMENTS: |
3318 if (key_is_constant) { | 3326 if (key_is_constant) { |
3319 __ LoadByte(result, mem_operand, r0); | 3327 __ LoadByte(result, mem_operand, r0); |
3320 } else { | 3328 } else { |
3321 __ lbzx(result, mem_operand); | 3329 __ lbzx(result, mem_operand); |
3322 } | 3330 } |
3323 __ extsb(result, result); | 3331 __ extsb(result, result); |
3324 break; | 3332 break; |
| 3333 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 3334 case EXTERNAL_UINT8_ELEMENTS: |
3325 case UINT8_ELEMENTS: | 3335 case UINT8_ELEMENTS: |
3326 case UINT8_CLAMPED_ELEMENTS: | 3336 case UINT8_CLAMPED_ELEMENTS: |
3327 if (key_is_constant) { | 3337 if (key_is_constant) { |
3328 __ LoadByte(result, mem_operand, r0); | 3338 __ LoadByte(result, mem_operand, r0); |
3329 } else { | 3339 } else { |
3330 __ lbzx(result, mem_operand); | 3340 __ lbzx(result, mem_operand); |
3331 } | 3341 } |
3332 break; | 3342 break; |
| 3343 case EXTERNAL_INT16_ELEMENTS: |
3333 case INT16_ELEMENTS: | 3344 case INT16_ELEMENTS: |
3334 if (key_is_constant) { | 3345 if (key_is_constant) { |
3335 __ LoadHalfWordArith(result, mem_operand, r0); | 3346 __ LoadHalfWordArith(result, mem_operand, r0); |
3336 } else { | 3347 } else { |
3337 __ lhax(result, mem_operand); | 3348 __ lhax(result, mem_operand); |
3338 } | 3349 } |
3339 break; | 3350 break; |
| 3351 case EXTERNAL_UINT16_ELEMENTS: |
3340 case UINT16_ELEMENTS: | 3352 case UINT16_ELEMENTS: |
3341 if (key_is_constant) { | 3353 if (key_is_constant) { |
3342 __ LoadHalfWord(result, mem_operand, r0); | 3354 __ LoadHalfWord(result, mem_operand, r0); |
3343 } else { | 3355 } else { |
3344 __ lhzx(result, mem_operand); | 3356 __ lhzx(result, mem_operand); |
3345 } | 3357 } |
3346 break; | 3358 break; |
| 3359 case EXTERNAL_INT32_ELEMENTS: |
3347 case INT32_ELEMENTS: | 3360 case INT32_ELEMENTS: |
3348 if (key_is_constant) { | 3361 if (key_is_constant) { |
3349 __ LoadWordArith(result, mem_operand, r0); | 3362 __ LoadWordArith(result, mem_operand, r0); |
3350 } else { | 3363 } else { |
3351 __ lwax(result, mem_operand); | 3364 __ lwax(result, mem_operand); |
3352 } | 3365 } |
3353 break; | 3366 break; |
| 3367 case EXTERNAL_UINT32_ELEMENTS: |
3354 case UINT32_ELEMENTS: | 3368 case UINT32_ELEMENTS: |
3355 if (key_is_constant) { | 3369 if (key_is_constant) { |
3356 __ LoadWord(result, mem_operand, r0); | 3370 __ LoadWord(result, mem_operand, r0); |
3357 } else { | 3371 } else { |
3358 __ lwzx(result, mem_operand); | 3372 __ lwzx(result, mem_operand); |
3359 } | 3373 } |
3360 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 3374 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
3361 __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 3375 __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); |
3362 __ cmplw(result, r0); | 3376 __ cmplw(result, r0); |
3363 DeoptimizeIf(ge, instr, Deoptimizer::kNegativeValue); | 3377 DeoptimizeIf(ge, instr, Deoptimizer::kNegativeValue); |
3364 } | 3378 } |
3365 break; | 3379 break; |
3366 case FLOAT32_ELEMENTS: | 3380 case FLOAT32_ELEMENTS: |
3367 case FLOAT64_ELEMENTS: | 3381 case FLOAT64_ELEMENTS: |
| 3382 case EXTERNAL_FLOAT32_ELEMENTS: |
| 3383 case EXTERNAL_FLOAT64_ELEMENTS: |
3368 case FAST_HOLEY_DOUBLE_ELEMENTS: | 3384 case FAST_HOLEY_DOUBLE_ELEMENTS: |
3369 case FAST_HOLEY_ELEMENTS: | 3385 case FAST_HOLEY_ELEMENTS: |
3370 case FAST_HOLEY_SMI_ELEMENTS: | 3386 case FAST_HOLEY_SMI_ELEMENTS: |
3371 case FAST_DOUBLE_ELEMENTS: | 3387 case FAST_DOUBLE_ELEMENTS: |
3372 case FAST_ELEMENTS: | 3388 case FAST_ELEMENTS: |
3373 case FAST_SMI_ELEMENTS: | 3389 case FAST_SMI_ELEMENTS: |
3374 case DICTIONARY_ELEMENTS: | 3390 case DICTIONARY_ELEMENTS: |
3375 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 3391 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
3376 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 3392 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
3377 UNREACHABLE(); | 3393 UNREACHABLE(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3494 __ CmpSmiLiteral(result, Smi::FromInt(Isolate::kArrayProtectorValid), r0); | 3510 __ CmpSmiLiteral(result, Smi::FromInt(Isolate::kArrayProtectorValid), r0); |
3495 DeoptimizeIf(ne, instr, Deoptimizer::kHole); | 3511 DeoptimizeIf(ne, instr, Deoptimizer::kHole); |
3496 } | 3512 } |
3497 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); | 3513 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); |
3498 __ bind(&done); | 3514 __ bind(&done); |
3499 } | 3515 } |
3500 } | 3516 } |
3501 | 3517 |
3502 | 3518 |
3503 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 3519 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
3504 if (instr->is_fixed_typed_array()) { | 3520 if (instr->is_typed_elements()) { |
3505 DoLoadKeyedExternalArray(instr); | 3521 DoLoadKeyedExternalArray(instr); |
3506 } else if (instr->hydrogen()->representation().IsDouble()) { | 3522 } else if (instr->hydrogen()->representation().IsDouble()) { |
3507 DoLoadKeyedFixedDoubleArray(instr); | 3523 DoLoadKeyedFixedDoubleArray(instr); |
3508 } else { | 3524 } else { |
3509 DoLoadKeyedFixedArray(instr); | 3525 DoLoadKeyedFixedArray(instr); |
3510 } | 3526 } |
3511 } | 3527 } |
3512 | 3528 |
3513 | 3529 |
3514 MemOperand LCodeGen::PrepareKeyedOperand(Register key, Register base, | 3530 MemOperand LCodeGen::PrepareKeyedOperand(Register key, Register base, |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3755 __ LoadP(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3771 __ LoadP(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3756 } else { | 3772 } else { |
3757 // If there is no frame, the context must be in cp. | 3773 // If there is no frame, the context must be in cp. |
3758 DCHECK(result.is(cp)); | 3774 DCHECK(result.is(cp)); |
3759 } | 3775 } |
3760 } | 3776 } |
3761 | 3777 |
3762 | 3778 |
3763 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { | 3779 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { |
3764 DCHECK(ToRegister(instr->context()).is(cp)); | 3780 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3781 __ push(cp); // The context is the first argument. |
3765 __ Move(scratch0(), instr->hydrogen()->pairs()); | 3782 __ Move(scratch0(), instr->hydrogen()->pairs()); |
3766 __ push(scratch0()); | 3783 __ push(scratch0()); |
3767 __ LoadSmiLiteral(scratch0(), Smi::FromInt(instr->hydrogen()->flags())); | 3784 __ LoadSmiLiteral(scratch0(), Smi::FromInt(instr->hydrogen()->flags())); |
3768 __ push(scratch0()); | 3785 __ push(scratch0()); |
3769 CallRuntime(Runtime::kDeclareGlobals, 2, instr); | 3786 CallRuntime(Runtime::kDeclareGlobals, 3, instr); |
3770 } | 3787 } |
3771 | 3788 |
3772 | 3789 |
3773 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3790 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
3774 int formal_parameter_count, int arity, | 3791 int formal_parameter_count, int arity, |
3775 LInstruction* instr) { | 3792 LInstruction* instr) { |
3776 bool dont_adapt_arguments = | 3793 bool dont_adapt_arguments = |
3777 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3794 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
3778 bool can_invoke_directly = | 3795 bool can_invoke_directly = |
3779 dont_adapt_arguments || formal_parameter_count == arity; | 3796 dont_adapt_arguments || formal_parameter_count == arity; |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4465 instr->hydrogen()->initialization_state()).code(); | 4482 instr->hydrogen()->initialization_state()).code(); |
4466 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4483 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
4467 } | 4484 } |
4468 | 4485 |
4469 | 4486 |
4470 void LCodeGen::DoStoreGlobalViaContext(LStoreGlobalViaContext* instr) { | 4487 void LCodeGen::DoStoreGlobalViaContext(LStoreGlobalViaContext* instr) { |
4471 DCHECK(ToRegister(instr->context()).is(cp)); | 4488 DCHECK(ToRegister(instr->context()).is(cp)); |
4472 DCHECK(ToRegister(instr->value()) | 4489 DCHECK(ToRegister(instr->value()) |
4473 .is(StoreGlobalViaContextDescriptor::ValueRegister())); | 4490 .is(StoreGlobalViaContextDescriptor::ValueRegister())); |
4474 | 4491 |
4475 int const slot = instr->slot_index(); | 4492 __ mov(StoreGlobalViaContextDescriptor::DepthRegister(), |
4476 int const depth = instr->depth(); | 4493 Operand(Smi::FromInt(instr->depth()))); |
4477 if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { | 4494 __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), |
4478 __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); | 4495 Operand(Smi::FromInt(instr->slot_index()))); |
4479 Handle<Code> stub = CodeFactory::StoreGlobalViaContext( | 4496 __ mov(StoreGlobalViaContextDescriptor::NameRegister(), |
4480 isolate(), depth, instr->language_mode()).code(); | 4497 Operand(instr->name())); |
4481 CallCode(stub, RelocInfo::CODE_TARGET, instr); | 4498 |
4482 } else { | 4499 Handle<Code> stub = CodeFactory::StoreGlobalViaContext( |
4483 __ Push(Smi::FromInt(slot)); | 4500 isolate(), instr->depth(), instr->language_mode()) |
4484 __ push(StoreGlobalViaContextDescriptor::ValueRegister()); | 4501 .code(); |
4485 __ CallRuntime(is_strict(instr->language_mode()) | 4502 CallCode(stub, RelocInfo::CODE_TARGET, instr); |
4486 ? Runtime::kStoreGlobalViaContext_Strict | |
4487 : Runtime::kStoreGlobalViaContext_Sloppy, | |
4488 2); | |
4489 } | |
4490 } | 4503 } |
4491 | 4504 |
4492 | 4505 |
4493 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 4506 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
4494 Representation representation = instr->hydrogen()->length()->representation(); | 4507 Representation representation = instr->hydrogen()->length()->representation(); |
4495 DCHECK(representation.Equals(instr->hydrogen()->index()->representation())); | 4508 DCHECK(representation.Equals(instr->hydrogen()->index()->representation())); |
4496 DCHECK(representation.IsSmiOrInteger32()); | 4509 DCHECK(representation.IsSmiOrInteger32()); |
4497 | 4510 |
4498 Condition cc = instr->hydrogen()->allow_equality() ? lt : le; | 4511 Condition cc = instr->hydrogen()->allow_equality() ? lt : le; |
4499 if (instr->length()->IsConstantOperand()) { | 4512 if (instr->length()->IsConstantOperand()) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4544 if (constant_key & 0xF0000000) { | 4557 if (constant_key & 0xF0000000) { |
4545 Abort(kArrayIndexConstantValueTooBig); | 4558 Abort(kArrayIndexConstantValueTooBig); |
4546 } | 4559 } |
4547 } else { | 4560 } else { |
4548 key = ToRegister(instr->key()); | 4561 key = ToRegister(instr->key()); |
4549 } | 4562 } |
4550 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4563 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
4551 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 4564 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
4552 int base_offset = instr->base_offset(); | 4565 int base_offset = instr->base_offset(); |
4553 | 4566 |
4554 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 4567 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4568 elements_kind == FLOAT32_ELEMENTS || |
| 4569 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 4570 elements_kind == FLOAT64_ELEMENTS) { |
4555 Register address = scratch0(); | 4571 Register address = scratch0(); |
4556 DoubleRegister value(ToDoubleRegister(instr->value())); | 4572 DoubleRegister value(ToDoubleRegister(instr->value())); |
4557 if (key_is_constant) { | 4573 if (key_is_constant) { |
4558 if (constant_key != 0) { | 4574 if (constant_key != 0) { |
4559 __ Add(address, external_pointer, constant_key << element_size_shift, | 4575 __ Add(address, external_pointer, constant_key << element_size_shift, |
4560 r0); | 4576 r0); |
4561 } else { | 4577 } else { |
4562 address = external_pointer; | 4578 address = external_pointer; |
4563 } | 4579 } |
4564 } else { | 4580 } else { |
4565 __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi); | 4581 __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi); |
4566 __ add(address, external_pointer, r0); | 4582 __ add(address, external_pointer, r0); |
4567 } | 4583 } |
4568 if (elements_kind == FLOAT32_ELEMENTS) { | 4584 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4585 elements_kind == FLOAT32_ELEMENTS) { |
4569 __ frsp(double_scratch0(), value); | 4586 __ frsp(double_scratch0(), value); |
4570 __ stfs(double_scratch0(), MemOperand(address, base_offset)); | 4587 __ stfs(double_scratch0(), MemOperand(address, base_offset)); |
4571 } else { // Storing doubles, not floats. | 4588 } else { // Storing doubles, not floats. |
4572 __ stfd(value, MemOperand(address, base_offset)); | 4589 __ stfd(value, MemOperand(address, base_offset)); |
4573 } | 4590 } |
4574 } else { | 4591 } else { |
4575 Register value(ToRegister(instr->value())); | 4592 Register value(ToRegister(instr->value())); |
4576 MemOperand mem_operand = | 4593 MemOperand mem_operand = |
4577 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, | 4594 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, |
4578 constant_key, element_size_shift, base_offset); | 4595 constant_key, element_size_shift, base_offset); |
4579 switch (elements_kind) { | 4596 switch (elements_kind) { |
| 4597 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 4598 case EXTERNAL_INT8_ELEMENTS: |
| 4599 case EXTERNAL_UINT8_ELEMENTS: |
4580 case UINT8_ELEMENTS: | 4600 case UINT8_ELEMENTS: |
4581 case UINT8_CLAMPED_ELEMENTS: | 4601 case UINT8_CLAMPED_ELEMENTS: |
4582 case INT8_ELEMENTS: | 4602 case INT8_ELEMENTS: |
4583 if (key_is_constant) { | 4603 if (key_is_constant) { |
4584 __ StoreByte(value, mem_operand, r0); | 4604 __ StoreByte(value, mem_operand, r0); |
4585 } else { | 4605 } else { |
4586 __ stbx(value, mem_operand); | 4606 __ stbx(value, mem_operand); |
4587 } | 4607 } |
4588 break; | 4608 break; |
| 4609 case EXTERNAL_INT16_ELEMENTS: |
| 4610 case EXTERNAL_UINT16_ELEMENTS: |
4589 case INT16_ELEMENTS: | 4611 case INT16_ELEMENTS: |
4590 case UINT16_ELEMENTS: | 4612 case UINT16_ELEMENTS: |
4591 if (key_is_constant) { | 4613 if (key_is_constant) { |
4592 __ StoreHalfWord(value, mem_operand, r0); | 4614 __ StoreHalfWord(value, mem_operand, r0); |
4593 } else { | 4615 } else { |
4594 __ sthx(value, mem_operand); | 4616 __ sthx(value, mem_operand); |
4595 } | 4617 } |
4596 break; | 4618 break; |
| 4619 case EXTERNAL_INT32_ELEMENTS: |
| 4620 case EXTERNAL_UINT32_ELEMENTS: |
4597 case INT32_ELEMENTS: | 4621 case INT32_ELEMENTS: |
4598 case UINT32_ELEMENTS: | 4622 case UINT32_ELEMENTS: |
4599 if (key_is_constant) { | 4623 if (key_is_constant) { |
4600 __ StoreWord(value, mem_operand, r0); | 4624 __ StoreWord(value, mem_operand, r0); |
4601 } else { | 4625 } else { |
4602 __ stwx(value, mem_operand); | 4626 __ stwx(value, mem_operand); |
4603 } | 4627 } |
4604 break; | 4628 break; |
4605 case FLOAT32_ELEMENTS: | 4629 case FLOAT32_ELEMENTS: |
4606 case FLOAT64_ELEMENTS: | 4630 case FLOAT64_ELEMENTS: |
| 4631 case EXTERNAL_FLOAT32_ELEMENTS: |
| 4632 case EXTERNAL_FLOAT64_ELEMENTS: |
4607 case FAST_DOUBLE_ELEMENTS: | 4633 case FAST_DOUBLE_ELEMENTS: |
4608 case FAST_ELEMENTS: | 4634 case FAST_ELEMENTS: |
4609 case FAST_SMI_ELEMENTS: | 4635 case FAST_SMI_ELEMENTS: |
4610 case FAST_HOLEY_DOUBLE_ELEMENTS: | 4636 case FAST_HOLEY_DOUBLE_ELEMENTS: |
4611 case FAST_HOLEY_ELEMENTS: | 4637 case FAST_HOLEY_ELEMENTS: |
4612 case FAST_HOLEY_SMI_ELEMENTS: | 4638 case FAST_HOLEY_SMI_ELEMENTS: |
4613 case DICTIONARY_ELEMENTS: | 4639 case DICTIONARY_ELEMENTS: |
4614 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 4640 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
4615 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 4641 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
4616 UNREACHABLE(); | 4642 UNREACHABLE(); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4714 __ Add(key, store_base, offset, r0); | 4740 __ Add(key, store_base, offset, r0); |
4715 __ RecordWrite(elements, key, value, GetLinkRegisterState(), kSaveFPRegs, | 4741 __ RecordWrite(elements, key, value, GetLinkRegisterState(), kSaveFPRegs, |
4716 EMIT_REMEMBERED_SET, check_needed, | 4742 EMIT_REMEMBERED_SET, check_needed, |
4717 hinstr->PointersToHereCheckForValue()); | 4743 hinstr->PointersToHereCheckForValue()); |
4718 } | 4744 } |
4719 } | 4745 } |
4720 | 4746 |
4721 | 4747 |
4722 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4748 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
4723 // By cases: external, fast double | 4749 // By cases: external, fast double |
4724 if (instr->is_fixed_typed_array()) { | 4750 if (instr->is_typed_elements()) { |
4725 DoStoreKeyedExternalArray(instr); | 4751 DoStoreKeyedExternalArray(instr); |
4726 } else if (instr->hydrogen()->value()->representation().IsDouble()) { | 4752 } else if (instr->hydrogen()->value()->representation().IsDouble()) { |
4727 DoStoreKeyedFixedDoubleArray(instr); | 4753 DoStoreKeyedFixedDoubleArray(instr); |
4728 } else { | 4754 } else { |
4729 DoStoreKeyedFixedArray(instr); | 4755 DoStoreKeyedFixedArray(instr); |
4730 } | 4756 } |
4731 } | 4757 } |
4732 | 4758 |
4733 | 4759 |
4734 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4760 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
(...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5985 __ lbz(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 6011 __ lbz(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); |
5986 __ ExtractBit(r0, scratch, Map::kIsUndetectable); | 6012 __ ExtractBit(r0, scratch, Map::kIsUndetectable); |
5987 __ cmpi(r0, Operand::Zero()); | 6013 __ cmpi(r0, Operand::Zero()); |
5988 final_branch_condition = eq; | 6014 final_branch_condition = eq; |
5989 | 6015 |
5990 } else if (String::Equals(type_name, factory->float32x4_string())) { | 6016 } else if (String::Equals(type_name, factory->float32x4_string())) { |
5991 __ JumpIfSmi(input, false_label); | 6017 __ JumpIfSmi(input, false_label); |
5992 __ CompareObjectType(input, scratch, no_reg, FLOAT32X4_TYPE); | 6018 __ CompareObjectType(input, scratch, no_reg, FLOAT32X4_TYPE); |
5993 final_branch_condition = eq; | 6019 final_branch_condition = eq; |
5994 | 6020 |
| 6021 } else if (String::Equals(type_name, factory->int32x4_string())) { |
| 6022 __ JumpIfSmi(input, false_label); |
| 6023 __ CompareObjectType(input, scratch, no_reg, INT32X4_TYPE); |
| 6024 final_branch_condition = eq; |
| 6025 |
| 6026 } else if (String::Equals(type_name, factory->bool32x4_string())) { |
| 6027 __ JumpIfSmi(input, false_label); |
| 6028 __ CompareObjectType(input, scratch, no_reg, BOOL32X4_TYPE); |
| 6029 final_branch_condition = eq; |
| 6030 |
| 6031 } else if (String::Equals(type_name, factory->int16x8_string())) { |
| 6032 __ JumpIfSmi(input, false_label); |
| 6033 __ CompareObjectType(input, scratch, no_reg, INT16X8_TYPE); |
| 6034 final_branch_condition = eq; |
| 6035 |
| 6036 } else if (String::Equals(type_name, factory->bool16x8_string())) { |
| 6037 __ JumpIfSmi(input, false_label); |
| 6038 __ CompareObjectType(input, scratch, no_reg, BOOL16X8_TYPE); |
| 6039 final_branch_condition = eq; |
| 6040 |
| 6041 } else if (String::Equals(type_name, factory->int8x16_string())) { |
| 6042 __ JumpIfSmi(input, false_label); |
| 6043 __ CompareObjectType(input, scratch, no_reg, INT8X16_TYPE); |
| 6044 final_branch_condition = eq; |
| 6045 |
| 6046 } else if (String::Equals(type_name, factory->bool8x16_string())) { |
| 6047 __ JumpIfSmi(input, false_label); |
| 6048 __ CompareObjectType(input, scratch, no_reg, BOOL8X16_TYPE); |
| 6049 final_branch_condition = eq; |
| 6050 |
5995 } else { | 6051 } else { |
5996 __ b(false_label); | 6052 __ b(false_label); |
5997 } | 6053 } |
5998 | 6054 |
5999 return final_branch_condition; | 6055 return final_branch_condition; |
6000 } | 6056 } |
6001 | 6057 |
6002 | 6058 |
6003 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 6059 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
6004 Register temp1 = ToRegister(instr->temp()); | 6060 Register temp1 = ToRegister(instr->temp()); |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6292 __ Push(scope_info); | 6348 __ Push(scope_info); |
6293 __ push(ToRegister(instr->function())); | 6349 __ push(ToRegister(instr->function())); |
6294 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6350 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
6295 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6351 RecordSafepoint(Safepoint::kNoLazyDeopt); |
6296 } | 6352 } |
6297 | 6353 |
6298 | 6354 |
6299 #undef __ | 6355 #undef __ |
6300 } // namespace internal | 6356 } // namespace internal |
6301 } // namespace v8 | 6357 } // namespace v8 |
OLD | NEW |