| 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/crankshaft/ppc/lithium-codegen-ppc.h" | 5 #include "src/crankshaft/ppc/lithium-codegen-ppc.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/crankshaft/hydrogen-osr.h" | 10 #include "src/crankshaft/hydrogen-osr.h" |
| (...skipping 2259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2270 if (expected.CanBeUndetectable()) { | 2270 if (expected.CanBeUndetectable()) { |
| 2271 // Undetectable -> false. | 2271 // Undetectable -> false. |
| 2272 __ lbz(ip, FieldMemOperand(map, Map::kBitFieldOffset)); | 2272 __ lbz(ip, FieldMemOperand(map, Map::kBitFieldOffset)); |
| 2273 __ TestBit(ip, Map::kIsUndetectable, r0); | 2273 __ TestBit(ip, Map::kIsUndetectable, r0); |
| 2274 __ bne(instr->FalseLabel(chunk_), cr0); | 2274 __ bne(instr->FalseLabel(chunk_), cr0); |
| 2275 } | 2275 } |
| 2276 } | 2276 } |
| 2277 | 2277 |
| 2278 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 2278 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { |
| 2279 // spec object -> true. | 2279 // spec object -> true. |
| 2280 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); | 2280 __ CompareInstanceType(map, ip, FIRST_JS_RECEIVER_TYPE); |
| 2281 __ bge(instr->TrueLabel(chunk_)); | 2281 __ bge(instr->TrueLabel(chunk_)); |
| 2282 } | 2282 } |
| 2283 | 2283 |
| 2284 if (expected.Contains(ToBooleanStub::STRING)) { | 2284 if (expected.Contains(ToBooleanStub::STRING)) { |
| 2285 // String value -> false iff empty. | 2285 // String value -> false iff empty. |
| 2286 Label not_string; | 2286 Label not_string; |
| 2287 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); | 2287 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); |
| 2288 __ bge(¬_string); | 2288 __ bge(¬_string); |
| 2289 __ LoadP(ip, FieldMemOperand(reg, String::kLengthOffset)); | 2289 __ LoadP(ip, FieldMemOperand(reg, String::kLengthOffset)); |
| 2290 __ cmpi(ip, Operand::Zero()); | 2290 __ cmpi(ip, Operand::Zero()); |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2663 DCHECK(!input.is(temp2)); | 2663 DCHECK(!input.is(temp2)); |
| 2664 DCHECK(!temp.is(temp2)); | 2664 DCHECK(!temp.is(temp2)); |
| 2665 | 2665 |
| 2666 __ JumpIfSmi(input, is_false); | 2666 __ JumpIfSmi(input, is_false); |
| 2667 | 2667 |
| 2668 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { | 2668 if (String::Equals(isolate()->factory()->Function_string(), class_name)) { |
| 2669 // Assuming the following assertions, we can use the same compares to test | 2669 // Assuming the following assertions, we can use the same compares to test |
| 2670 // for both being a function type and being in the object type range. | 2670 // for both being a function type and being in the object type range. |
| 2671 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 2671 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
| 2672 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2672 STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |
| 2673 FIRST_SPEC_OBJECT_TYPE + 1); | 2673 FIRST_JS_RECEIVER_TYPE + 1); |
| 2674 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == | 2674 STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == |
| 2675 LAST_SPEC_OBJECT_TYPE - 1); | 2675 LAST_JS_RECEIVER_TYPE - 1); |
| 2676 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 2676 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 2677 __ CompareObjectType(input, temp, temp2, FIRST_SPEC_OBJECT_TYPE); | 2677 __ CompareObjectType(input, temp, temp2, FIRST_JS_RECEIVER_TYPE); |
| 2678 __ blt(is_false); | 2678 __ blt(is_false); |
| 2679 __ beq(is_true); | 2679 __ beq(is_true); |
| 2680 __ cmpi(temp2, Operand(LAST_SPEC_OBJECT_TYPE)); | 2680 __ cmpi(temp2, Operand(LAST_JS_RECEIVER_TYPE)); |
| 2681 __ beq(is_true); | 2681 __ beq(is_true); |
| 2682 } else { | 2682 } else { |
| 2683 // Faster code path to avoid two compares: subtract lower bound from the | 2683 // Faster code path to avoid two compares: subtract lower bound from the |
| 2684 // actual type and do a signed compare with the width of the type range. | 2684 // actual type and do a signed compare with the width of the type range. |
| 2685 __ LoadP(temp, FieldMemOperand(input, HeapObject::kMapOffset)); | 2685 __ LoadP(temp, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 2686 __ lbz(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset)); | 2686 __ lbz(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset)); |
| 2687 __ subi(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2687 __ subi(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 2688 __ cmpi(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - | 2688 __ cmpi(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - |
| 2689 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2689 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 2690 __ bgt(is_false); | 2690 __ bgt(is_false); |
| (...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3456 __ LoadRoot(scratch, Heap::kNullValueRootIndex); | 3456 __ LoadRoot(scratch, Heap::kNullValueRootIndex); |
| 3457 __ cmp(receiver, scratch); | 3457 __ cmp(receiver, scratch); |
| 3458 __ beq(&global_object); | 3458 __ beq(&global_object); |
| 3459 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 3459 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
| 3460 __ cmp(receiver, scratch); | 3460 __ cmp(receiver, scratch); |
| 3461 __ beq(&global_object); | 3461 __ beq(&global_object); |
| 3462 | 3462 |
| 3463 // Deoptimize if the receiver is not a JS object. | 3463 // Deoptimize if the receiver is not a JS object. |
| 3464 __ TestIfSmi(receiver, r0); | 3464 __ TestIfSmi(receiver, r0); |
| 3465 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); | 3465 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); |
| 3466 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); | 3466 __ CompareObjectType(receiver, scratch, scratch, FIRST_JS_RECEIVER_TYPE); |
| 3467 DeoptimizeIf(lt, instr, Deoptimizer::kNotAJavaScriptObject); | 3467 DeoptimizeIf(lt, instr, Deoptimizer::kNotAJavaScriptObject); |
| 3468 | 3468 |
| 3469 __ b(&result_in_receiver); | 3469 __ b(&result_in_receiver); |
| 3470 __ bind(&global_object); | 3470 __ bind(&global_object); |
| 3471 __ LoadP(result, FieldMemOperand(function, JSFunction::kContextOffset)); | 3471 __ LoadP(result, FieldMemOperand(function, JSFunction::kContextOffset)); |
| 3472 __ LoadP(result, ContextOperand(result, Context::GLOBAL_OBJECT_INDEX)); | 3472 __ LoadP(result, ContextOperand(result, Context::GLOBAL_OBJECT_INDEX)); |
| 3473 __ LoadP(result, FieldMemOperand(result, JSGlobalObject::kGlobalProxyOffset)); | 3473 __ LoadP(result, FieldMemOperand(result, JSGlobalObject::kGlobalProxyOffset)); |
| 3474 if (result.is(receiver)) { | 3474 if (result.is(receiver)) { |
| 3475 __ bind(&result_in_receiver); | 3475 __ bind(&result_in_receiver); |
| 3476 } else { | 3476 } else { |
| (...skipping 2187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5664 __ lbz(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); | 5664 __ lbz(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); |
| 5665 __ andi(scratch, scratch, | 5665 __ andi(scratch, scratch, |
| 5666 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); | 5666 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); |
| 5667 __ cmpi(scratch, Operand(1 << Map::kIsCallable)); | 5667 __ cmpi(scratch, Operand(1 << Map::kIsCallable)); |
| 5668 final_branch_condition = eq; | 5668 final_branch_condition = eq; |
| 5669 | 5669 |
| 5670 } else if (String::Equals(type_name, factory->object_string())) { | 5670 } else if (String::Equals(type_name, factory->object_string())) { |
| 5671 __ JumpIfSmi(input, false_label); | 5671 __ JumpIfSmi(input, false_label); |
| 5672 __ CompareRoot(input, Heap::kNullValueRootIndex); | 5672 __ CompareRoot(input, Heap::kNullValueRootIndex); |
| 5673 __ beq(true_label); | 5673 __ beq(true_label); |
| 5674 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 5674 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 5675 __ CompareObjectType(input, scratch, ip, FIRST_SPEC_OBJECT_TYPE); | 5675 __ CompareObjectType(input, scratch, ip, FIRST_JS_RECEIVER_TYPE); |
| 5676 __ blt(false_label); | 5676 __ blt(false_label); |
| 5677 // Check for callable or undetectable objects => false. | 5677 // Check for callable or undetectable objects => false. |
| 5678 __ lbz(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); | 5678 __ lbz(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); |
| 5679 __ andi(r0, scratch, | 5679 __ andi(r0, scratch, |
| 5680 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); | 5680 Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable))); |
| 5681 __ cmpi(r0, Operand::Zero()); | 5681 __ cmpi(r0, Operand::Zero()); |
| 5682 final_branch_condition = eq; | 5682 final_branch_condition = eq; |
| 5683 | 5683 |
| 5684 // clang-format off | 5684 // clang-format off |
| 5685 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ | 5685 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5848 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 5848 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
| 5849 | 5849 |
| 5850 GenerateOsrPrologue(); | 5850 GenerateOsrPrologue(); |
| 5851 } | 5851 } |
| 5852 | 5852 |
| 5853 | 5853 |
| 5854 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { | 5854 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { |
| 5855 __ TestIfSmi(r3, r0); | 5855 __ TestIfSmi(r3, r0); |
| 5856 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); | 5856 DeoptimizeIf(eq, instr, Deoptimizer::kSmi, cr0); |
| 5857 | 5857 |
| 5858 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 5858 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE); |
| 5859 __ CompareObjectType(r3, r4, r4, LAST_JS_PROXY_TYPE); | 5859 __ CompareObjectType(r3, r4, r4, LAST_JS_PROXY_TYPE); |
| 5860 DeoptimizeIf(le, instr, Deoptimizer::kWrongInstanceType); | 5860 DeoptimizeIf(le, instr, Deoptimizer::kWrongInstanceType); |
| 5861 | 5861 |
| 5862 Label use_cache, call_runtime; | 5862 Label use_cache, call_runtime; |
| 5863 Register null_value = r8; | 5863 Register null_value = r8; |
| 5864 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 5864 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
| 5865 __ CheckEnumCache(null_value, &call_runtime); | 5865 __ CheckEnumCache(null_value, &call_runtime); |
| 5866 | 5866 |
| 5867 __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset)); | 5867 __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset)); |
| 5868 __ b(&use_cache); | 5868 __ b(&use_cache); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5992 __ Push(scope_info); | 5992 __ Push(scope_info); |
| 5993 __ push(ToRegister(instr->function())); | 5993 __ push(ToRegister(instr->function())); |
| 5994 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5994 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5995 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5995 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5996 } | 5996 } |
| 5997 | 5997 |
| 5998 | 5998 |
| 5999 #undef __ | 5999 #undef __ |
| 6000 } // namespace internal | 6000 } // namespace internal |
| 6001 } // namespace v8 | 6001 } // namespace v8 |
| OLD | NEW |