| 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 __ Ldr(left_d, FieldMemOperand(left, HeapNumber::kValueOffset)); | 436 __ Ldr(left_d, FieldMemOperand(left, HeapNumber::kValueOffset)); |
| 437 __ SmiUntagToDouble(right_d, right); | 437 __ SmiUntagToDouble(right_d, right); |
| 438 | 438 |
| 439 // Fall through to both_loaded_as_doubles. | 439 // Fall through to both_loaded_as_doubles. |
| 440 __ Bind(&done); | 440 __ Bind(&done); |
| 441 } | 441 } |
| 442 | 442 |
| 443 | 443 |
| 444 // Fast negative check for internalized-to-internalized equality. | 444 // Fast negative check for internalized-to-internalized equality. |
| 445 // See call site for description. | 445 // See call site for description. |
| 446 static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm, | 446 static void EmitCheckForInternalizedStringsOrObjects( |
| 447 Register left, | 447 MacroAssembler* masm, Register left, Register right, Register left_map, |
| 448 Register right, | 448 Register right_map, Register left_type, Register right_type, |
| 449 Register left_map, | 449 Label* possible_strings, Label* runtime_call) { |
| 450 Register right_map, | |
| 451 Register left_type, | |
| 452 Register right_type, | |
| 453 Label* possible_strings, | |
| 454 Label* not_both_strings) { | |
| 455 DCHECK(!AreAliased(left, right, left_map, right_map, left_type, right_type)); | 450 DCHECK(!AreAliased(left, right, left_map, right_map, left_type, right_type)); |
| 456 Register result = x0; | 451 Register result = x0; |
| 452 DCHECK(left.is(x0) || right.is(x0)); |
| 457 | 453 |
| 458 Label object_test; | 454 Label object_test, return_unequal, undetectable; |
| 459 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); | 455 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); |
| 460 // TODO(all): reexamine this branch sequence for optimisation wrt branch | 456 // TODO(all): reexamine this branch sequence for optimisation wrt branch |
| 461 // prediction. | 457 // prediction. |
| 462 __ Tbnz(right_type, MaskToBit(kIsNotStringMask), &object_test); | 458 __ Tbnz(right_type, MaskToBit(kIsNotStringMask), &object_test); |
| 463 __ Tbnz(right_type, MaskToBit(kIsNotInternalizedMask), possible_strings); | 459 __ Tbnz(right_type, MaskToBit(kIsNotInternalizedMask), possible_strings); |
| 464 __ Tbnz(left_type, MaskToBit(kIsNotStringMask), not_both_strings); | 460 __ Tbnz(left_type, MaskToBit(kIsNotStringMask), runtime_call); |
| 465 __ Tbnz(left_type, MaskToBit(kIsNotInternalizedMask), possible_strings); | 461 __ Tbnz(left_type, MaskToBit(kIsNotInternalizedMask), possible_strings); |
| 466 | 462 |
| 467 // Both are internalized. We already checked that they weren't the same | 463 // Both are internalized. We already checked they weren't the same pointer so |
| 468 // pointer, so they are not equal. | 464 // they are not equal. Return non-equal by returning the non-zero object |
| 469 __ Mov(result, NOT_EQUAL); | 465 // pointer in x0. |
| 470 __ Ret(); | 466 __ Ret(); |
| 471 | 467 |
| 472 __ Bind(&object_test); | 468 __ Bind(&object_test); |
| 473 | 469 |
| 474 __ Cmp(right_type, FIRST_JS_RECEIVER_TYPE); | 470 Register left_bitfield = left_type; |
| 475 | |
| 476 // If right >= FIRST_JS_RECEIVER_TYPE, test left. | |
| 477 // Otherwise, right < FIRST_JS_RECEIVER_TYPE, so set lt condition. | |
| 478 __ Ccmp(left_type, FIRST_JS_RECEIVER_TYPE, NFlag, ge); | |
| 479 | |
| 480 __ B(lt, not_both_strings); | |
| 481 | |
| 482 // If both objects are undetectable, they are equal. Otherwise, they are not | |
| 483 // equal, since they are different objects and an object is not equal to | |
| 484 // undefined. | |
| 485 | |
| 486 // Returning here, so we can corrupt right_type and left_type. | |
| 487 Register right_bitfield = right_type; | 471 Register right_bitfield = right_type; |
| 488 Register left_bitfield = left_type; | |
| 489 __ Ldrb(right_bitfield, FieldMemOperand(right_map, Map::kBitFieldOffset)); | 472 __ Ldrb(right_bitfield, FieldMemOperand(right_map, Map::kBitFieldOffset)); |
| 490 __ Ldrb(left_bitfield, FieldMemOperand(left_map, Map::kBitFieldOffset)); | 473 __ Ldrb(left_bitfield, FieldMemOperand(left_map, Map::kBitFieldOffset)); |
| 491 __ And(result, right_bitfield, left_bitfield); | 474 __ Tbnz(right_bitfield, MaskToBit(1 << Map::kIsUndetectable), &undetectable); |
| 492 __ And(result, result, 1 << Map::kIsUndetectable); | 475 __ Tbnz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); |
| 493 __ Eor(result, result, 1 << Map::kIsUndetectable); | 476 |
| 477 __ CompareInstanceType(right_map, right_type, FIRST_JS_RECEIVER_TYPE); |
| 478 __ B(lt, runtime_call); |
| 479 __ CompareInstanceType(left_map, left_type, FIRST_JS_RECEIVER_TYPE); |
| 480 __ B(lt, runtime_call); |
| 481 |
| 482 __ bind(&return_unequal); |
| 483 // Return non-equal by returning the non-zero object pointer in x0. |
| 484 __ Ret(); |
| 485 |
| 486 __ bind(&undetectable); |
| 487 __ Tbz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); |
| 488 __ Mov(result, EQUAL); |
| 494 __ Ret(); | 489 __ Ret(); |
| 495 } | 490 } |
| 496 | 491 |
| 497 | 492 |
| 498 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input, | 493 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input, |
| 499 CompareICState::State expected, | 494 CompareICState::State expected, |
| 500 Label* fail) { | 495 Label* fail) { |
| 501 Label ok; | 496 Label ok; |
| 502 if (expected == CompareICState::SMI) { | 497 if (expected == CompareICState::SMI) { |
| 503 __ JumpIfNotSmi(input, fail); | 498 __ JumpIfNotSmi(input, fail); |
| (...skipping 5484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5988 return_value_operand, NULL); | 5983 return_value_operand, NULL); |
| 5989 } | 5984 } |
| 5990 | 5985 |
| 5991 | 5986 |
| 5992 #undef __ | 5987 #undef __ |
| 5993 | 5988 |
| 5994 } // namespace internal | 5989 } // namespace internal |
| 5995 } // namespace v8 | 5990 } // namespace v8 |
| 5996 | 5991 |
| 5997 #endif // V8_TARGET_ARCH_ARM64 | 5992 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |