| 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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 // Right is the smi. Left is a heap number. Load left value into left_d, and | 418 // Right is the smi. Left is a heap number. Load left value into left_d, and |
| 419 // convert right smi into double in right_d. | 419 // convert right smi into double in right_d. |
| 420 __ Ldr(left_d, FieldMemOperand(left, HeapNumber::kValueOffset)); | 420 __ Ldr(left_d, FieldMemOperand(left, HeapNumber::kValueOffset)); |
| 421 __ SmiUntagToDouble(right_d, right); | 421 __ SmiUntagToDouble(right_d, right); |
| 422 | 422 |
| 423 // Fall through to both_loaded_as_doubles. | 423 // Fall through to both_loaded_as_doubles. |
| 424 __ Bind(&done); | 424 __ Bind(&done); |
| 425 } | 425 } |
| 426 | 426 |
| 427 | 427 |
| 428 // Fast negative check for internalized-to-internalized equality. | 428 // Fast negative check for internalized-to-internalized equality or receiver |
| 429 // equality. Also handles the undetectable receiver to null/undefined |
| 430 // comparison. |
| 429 // See call site for description. | 431 // See call site for description. |
| 430 static void EmitCheckForInternalizedStringsOrObjects( | 432 static void EmitCheckForInternalizedStringsOrObjects( |
| 431 MacroAssembler* masm, Register left, Register right, Register left_map, | 433 MacroAssembler* masm, Register left, Register right, Register left_map, |
| 432 Register right_map, Register left_type, Register right_type, | 434 Register right_map, Register left_type, Register right_type, |
| 433 Label* possible_strings, Label* runtime_call) { | 435 Label* possible_strings, Label* runtime_call) { |
| 434 DCHECK(!AreAliased(left, right, left_map, right_map, left_type, right_type)); | 436 DCHECK(!AreAliased(left, right, left_map, right_map, left_type, right_type)); |
| 435 Register result = x0; | 437 Register result = x0; |
| 436 DCHECK(left.is(x0) || right.is(x0)); | 438 DCHECK(left.is(x0) || right.is(x0)); |
| 437 | 439 |
| 438 Label object_test, return_unequal, undetectable; | 440 Label object_test, return_equal, return_unequal, undetectable; |
| 439 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); | 441 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); |
| 440 // TODO(all): reexamine this branch sequence for optimisation wrt branch | 442 // TODO(all): reexamine this branch sequence for optimisation wrt branch |
| 441 // prediction. | 443 // prediction. |
| 442 __ Tbnz(right_type, MaskToBit(kIsNotStringMask), &object_test); | 444 __ Tbnz(right_type, MaskToBit(kIsNotStringMask), &object_test); |
| 443 __ Tbnz(right_type, MaskToBit(kIsNotInternalizedMask), possible_strings); | 445 __ Tbnz(right_type, MaskToBit(kIsNotInternalizedMask), possible_strings); |
| 444 __ Tbnz(left_type, MaskToBit(kIsNotStringMask), runtime_call); | 446 __ Tbnz(left_type, MaskToBit(kIsNotStringMask), runtime_call); |
| 445 __ Tbnz(left_type, MaskToBit(kIsNotInternalizedMask), possible_strings); | 447 __ Tbnz(left_type, MaskToBit(kIsNotInternalizedMask), possible_strings); |
| 446 | 448 |
| 447 // Both are internalized. We already checked they weren't the same pointer so | 449 // Both are internalized. We already checked they weren't the same pointer so |
| 448 // they are not equal. Return non-equal by returning the non-zero object | 450 // they are not equal. Return non-equal by returning the non-zero object |
| 449 // pointer in x0. | 451 // pointer in x0. |
| 450 __ Ret(); | 452 __ Ret(); |
| 451 | 453 |
| 452 __ Bind(&object_test); | 454 __ Bind(&object_test); |
| 453 | 455 |
| 454 Register left_bitfield = left_type; | 456 Register left_bitfield = left_type; |
| 455 Register right_bitfield = right_type; | 457 Register right_bitfield = right_type; |
| 456 __ Ldrb(right_bitfield, FieldMemOperand(right_map, Map::kBitFieldOffset)); | 458 __ Ldrb(right_bitfield, FieldMemOperand(right_map, Map::kBitFieldOffset)); |
| 457 __ Ldrb(left_bitfield, FieldMemOperand(left_map, Map::kBitFieldOffset)); | 459 __ Ldrb(left_bitfield, FieldMemOperand(left_map, Map::kBitFieldOffset)); |
| 458 __ Tbnz(right_bitfield, MaskToBit(1 << Map::kIsUndetectable), &undetectable); | 460 __ Tbnz(right_bitfield, MaskToBit(1 << Map::kIsUndetectable), &undetectable); |
| 459 __ Tbnz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); | 461 __ Tbnz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); |
| 460 | 462 |
| 461 __ CompareInstanceType(right_map, right_type, FIRST_JS_RECEIVER_TYPE); | 463 __ CompareInstanceType(right_map, right_type, FIRST_JS_RECEIVER_TYPE); |
| 462 __ B(lt, runtime_call); | 464 __ B(lt, runtime_call); |
| 463 __ CompareInstanceType(left_map, left_type, FIRST_JS_RECEIVER_TYPE); | 465 __ CompareInstanceType(left_map, left_type, FIRST_JS_RECEIVER_TYPE); |
| 464 __ B(lt, runtime_call); | 466 __ B(lt, runtime_call); |
| 465 | 467 |
| 466 __ bind(&return_unequal); | 468 __ Bind(&return_unequal); |
| 467 // Return non-equal by returning the non-zero object pointer in x0. | 469 // Return non-equal by returning the non-zero object pointer in x0. |
| 468 __ Ret(); | 470 __ Ret(); |
| 469 | 471 |
| 470 __ bind(&undetectable); | 472 __ Bind(&undetectable); |
| 471 __ Tbz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); | 473 __ Tbz(left_bitfield, MaskToBit(1 << Map::kIsUndetectable), &return_unequal); |
| 474 |
| 475 // If both sides are JSReceivers, then the result is false according to |
| 476 // the HTML specification, which says that only comparisons with null or |
| 477 // undefined are affected by special casing for document.all. |
| 478 __ CompareInstanceType(right_map, right_type, ODDBALL_TYPE); |
| 479 __ B(eq, &return_equal); |
| 480 __ CompareInstanceType(left_map, left_type, ODDBALL_TYPE); |
| 481 __ B(ne, &return_unequal); |
| 482 |
| 483 __ Bind(&return_equal); |
| 472 __ Mov(result, EQUAL); | 484 __ Mov(result, EQUAL); |
| 473 __ Ret(); | 485 __ Ret(); |
| 474 } | 486 } |
| 475 | 487 |
| 476 | 488 |
| 477 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input, | 489 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input, |
| 478 CompareICState::State expected, | 490 CompareICState::State expected, |
| 479 Label* fail) { | 491 Label* fail) { |
| 480 Label ok; | 492 Label ok; |
| 481 if (expected == CompareICState::SMI) { | 493 if (expected == CompareICState::SMI) { |
| (...skipping 5492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5974 return_value_operand, NULL); | 5986 return_value_operand, NULL); |
| 5975 } | 5987 } |
| 5976 | 5988 |
| 5977 | 5989 |
| 5978 #undef __ | 5990 #undef __ |
| 5979 | 5991 |
| 5980 } // namespace internal | 5992 } // namespace internal |
| 5981 } // namespace v8 | 5993 } // namespace v8 |
| 5982 | 5994 |
| 5983 #endif // V8_TARGET_ARCH_ARM64 | 5995 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |