Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: src/arm64/code-stubs-arm64.cc

Issue 1693833002: Remove strong mode support from binary operations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 } 200 }
201 __ Pop(scratch2, scratch1); 201 __ Pop(scratch2, scratch1);
202 __ Ret(); 202 __ Ret();
203 } 203 }
204 204
205 205
206 // See call site for description. 206 // See call site for description.
207 static void EmitIdenticalObjectComparison(MacroAssembler* masm, Register left, 207 static void EmitIdenticalObjectComparison(MacroAssembler* masm, Register left,
208 Register right, Register scratch, 208 Register right, Register scratch,
209 FPRegister double_scratch, 209 FPRegister double_scratch,
210 Label* slow, Condition cond, 210 Label* slow, Condition cond) {
211 Strength strength) {
212 DCHECK(!AreAliased(left, right, scratch)); 211 DCHECK(!AreAliased(left, right, scratch));
213 Label not_identical, return_equal, heap_number; 212 Label not_identical, return_equal, heap_number;
214 Register result = x0; 213 Register result = x0;
215 214
216 __ Cmp(right, left); 215 __ Cmp(right, left);
217 __ B(ne, &not_identical); 216 __ B(ne, &not_identical);
218 217
219 // Test for NaN. Sadly, we can't just compare to factory::nan_value(), 218 // Test for NaN. Sadly, we can't just compare to factory::nan_value(),
220 // so we do the second best thing - test it ourselves. 219 // so we do the second best thing - test it ourselves.
221 // They are both equal and they are not both Smis so both of them are not 220 // They are both equal and they are not both Smis so both of them are not
222 // Smis. If it's not a heap number, then return equal. 221 // Smis. If it's not a heap number, then return equal.
223 Register right_type = scratch; 222 Register right_type = scratch;
224 if ((cond == lt) || (cond == gt)) { 223 if ((cond == lt) || (cond == gt)) {
225 // Call runtime on identical JSObjects. Otherwise return equal. 224 // Call runtime on identical JSObjects. Otherwise return equal.
226 __ JumpIfObjectType(right, right_type, right_type, FIRST_JS_RECEIVER_TYPE, 225 __ JumpIfObjectType(right, right_type, right_type, FIRST_JS_RECEIVER_TYPE,
227 slow, ge); 226 slow, ge);
228 // Call runtime on identical symbols since we need to throw a TypeError. 227 // Call runtime on identical symbols since we need to throw a TypeError.
229 __ Cmp(right_type, SYMBOL_TYPE); 228 __ Cmp(right_type, SYMBOL_TYPE);
230 __ B(eq, slow); 229 __ B(eq, slow);
231 // Call runtime on identical SIMD values since we must throw a TypeError. 230 // Call runtime on identical SIMD values since we must throw a TypeError.
232 __ Cmp(right_type, SIMD128_VALUE_TYPE); 231 __ Cmp(right_type, SIMD128_VALUE_TYPE);
233 __ B(eq, slow); 232 __ B(eq, slow);
234 if (is_strong(strength)) {
235 // Call the runtime on anything that is converted in the semantics, since
236 // we need to throw a TypeError. Smis have already been ruled out.
237 __ Cmp(right_type, Operand(HEAP_NUMBER_TYPE));
238 __ B(eq, &return_equal);
239 __ Tst(right_type, Operand(kIsNotStringMask));
240 __ B(ne, slow);
241 }
242 } else if (cond == eq) { 233 } else if (cond == eq) {
243 __ JumpIfHeapNumber(right, &heap_number); 234 __ JumpIfHeapNumber(right, &heap_number);
244 } else { 235 } else {
245 __ JumpIfObjectType(right, right_type, right_type, HEAP_NUMBER_TYPE, 236 __ JumpIfObjectType(right, right_type, right_type, HEAP_NUMBER_TYPE,
246 &heap_number); 237 &heap_number);
247 // Comparing JS objects with <=, >= is complicated. 238 // Comparing JS objects with <=, >= is complicated.
248 __ Cmp(right_type, FIRST_JS_RECEIVER_TYPE); 239 __ Cmp(right_type, FIRST_JS_RECEIVER_TYPE);
249 __ B(ge, slow); 240 __ B(ge, slow);
250 // Call runtime on identical symbols since we need to throw a TypeError. 241 // Call runtime on identical symbols since we need to throw a TypeError.
251 __ Cmp(right_type, SYMBOL_TYPE); 242 __ Cmp(right_type, SYMBOL_TYPE);
252 __ B(eq, slow); 243 __ B(eq, slow);
253 // Call runtime on identical SIMD values since we must throw a TypeError. 244 // Call runtime on identical SIMD values since we must throw a TypeError.
254 __ Cmp(right_type, SIMD128_VALUE_TYPE); 245 __ Cmp(right_type, SIMD128_VALUE_TYPE);
255 __ B(eq, slow); 246 __ B(eq, slow);
256 if (is_strong(strength)) {
257 // Call the runtime on anything that is converted in the semantics,
258 // since we need to throw a TypeError. Smis and heap numbers have
259 // already been ruled out.
260 __ Tst(right_type, Operand(kIsNotStringMask));
261 __ B(ne, slow);
262 }
263 // Normally here we fall through to return_equal, but undefined is 247 // Normally here we fall through to return_equal, but undefined is
264 // special: (undefined == undefined) == true, but 248 // special: (undefined == undefined) == true, but
265 // (undefined <= undefined) == false! See ECMAScript 11.8.5. 249 // (undefined <= undefined) == false! See ECMAScript 11.8.5.
266 if ((cond == le) || (cond == ge)) { 250 if ((cond == le) || (cond == ge)) {
267 __ Cmp(right_type, ODDBALL_TYPE); 251 __ Cmp(right_type, ODDBALL_TYPE);
268 __ B(ne, &return_equal); 252 __ B(ne, &return_equal);
269 __ JumpIfNotRoot(right, Heap::kUndefinedValueRootIndex, &return_equal); 253 __ JumpIfNotRoot(right, Heap::kUndefinedValueRootIndex, &return_equal);
270 if (cond == le) { 254 if (cond == le) {
271 // undefined <= undefined should fail. 255 // undefined <= undefined should fail.
272 __ Mov(result, GREATER); 256 __ Mov(result, GREATER);
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 __ Sub(result, lhs, Operand::UntagSmi(rhs)); 508 __ Sub(result, lhs, Operand::UntagSmi(rhs));
525 __ Ret(); 509 __ Ret();
526 510
527 __ Bind(&not_two_smis); 511 __ Bind(&not_two_smis);
528 512
529 // NOTICE! This code is only reached after a smi-fast-case check, so it is 513 // NOTICE! This code is only reached after a smi-fast-case check, so it is
530 // certain that at least one operand isn't a smi. 514 // certain that at least one operand isn't a smi.
531 515
532 // Handle the case where the objects are identical. Either returns the answer 516 // Handle the case where the objects are identical. Either returns the answer
533 // or goes to slow. Only falls through if the objects were not identical. 517 // or goes to slow. Only falls through if the objects were not identical.
534 EmitIdenticalObjectComparison(masm, lhs, rhs, x10, d0, &slow, cond, 518 EmitIdenticalObjectComparison(masm, lhs, rhs, x10, d0, &slow, cond);
535 strength());
536 519
537 // If either is a smi (we know that at least one is not a smi), then they can 520 // If either is a smi (we know that at least one is not a smi), then they can
538 // only be strictly equal if the other is a HeapNumber. 521 // only be strictly equal if the other is a HeapNumber.
539 __ JumpIfBothNotSmi(lhs, rhs, &not_smis); 522 __ JumpIfBothNotSmi(lhs, rhs, &not_smis);
540 523
541 // Exactly one operand is a smi. EmitSmiNonsmiComparison generates code that 524 // Exactly one operand is a smi. EmitSmiNonsmiComparison generates code that
542 // can: 525 // can:
543 // 1) Return the answer. 526 // 1) Return the answer.
544 // 2) Branch to the slow case. 527 // 2) Branch to the slow case.
545 // 3) Fall through to both_loaded_as_doubles. 528 // 3) Fall through to both_loaded_as_doubles.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 ncr = GREATER; 638 ncr = GREATER;
656 } else { 639 } else {
657 DCHECK((cond == gt) || (cond == ge)); // remaining cases 640 DCHECK((cond == gt) || (cond == ge)); // remaining cases
658 ncr = LESS; 641 ncr = LESS;
659 } 642 }
660 __ Mov(x10, Smi::FromInt(ncr)); 643 __ Mov(x10, Smi::FromInt(ncr));
661 __ Push(x10); 644 __ Push(x10);
662 645
663 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 646 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
664 // tagged as a small integer. 647 // tagged as a small integer.
665 __ TailCallRuntime(is_strong(strength()) ? Runtime::kCompare_Strong 648 __ TailCallRuntime(Runtime::kCompare);
666 : Runtime::kCompare);
667 } 649 }
668 650
669 __ Bind(&miss); 651 __ Bind(&miss);
670 GenerateMiss(masm); 652 GenerateMiss(masm);
671 } 653 }
672 654
673 655
674 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { 656 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
675 CPURegList saved_regs = kCallerSaved; 657 CPURegList saved_regs = kCallerSaved;
676 CPURegList saved_fp_regs = kCallerSavedFP; 658 CPURegList saved_fp_regs = kCallerSavedFP;
(...skipping 1945 matching lines...) Expand 10 before | Expand all | Expand 10 after
2622 2604
2623 2605
2624 void CompareICStub::GenerateBooleans(MacroAssembler* masm) { 2606 void CompareICStub::GenerateBooleans(MacroAssembler* masm) {
2625 // Inputs are in x0 (lhs) and x1 (rhs). 2607 // Inputs are in x0 (lhs) and x1 (rhs).
2626 DCHECK_EQ(CompareICState::BOOLEAN, state()); 2608 DCHECK_EQ(CompareICState::BOOLEAN, state());
2627 ASM_LOCATION("CompareICStub[Booleans]"); 2609 ASM_LOCATION("CompareICStub[Booleans]");
2628 Label miss; 2610 Label miss;
2629 2611
2630 __ CheckMap(x1, x2, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK); 2612 __ CheckMap(x1, x2, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK);
2631 __ CheckMap(x0, x3, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK); 2613 __ CheckMap(x0, x3, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK);
2632 if (op() != Token::EQ_STRICT && is_strong(strength())) { 2614 if (!Token::IsEqualityOp(op())) {
2633 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion); 2615 __ Ldr(x1, FieldMemOperand(x1, Oddball::kToNumberOffset));
2634 } else { 2616 __ AssertSmi(x1);
2635 if (!Token::IsEqualityOp(op())) { 2617 __ Ldr(x0, FieldMemOperand(x0, Oddball::kToNumberOffset));
2636 __ Ldr(x1, FieldMemOperand(x1, Oddball::kToNumberOffset)); 2618 __ AssertSmi(x0);
2637 __ AssertSmi(x1);
2638 __ Ldr(x0, FieldMemOperand(x0, Oddball::kToNumberOffset));
2639 __ AssertSmi(x0);
2640 }
2641 __ Sub(x0, x1, x0);
2642 __ Ret();
2643 } 2619 }
2620 __ Sub(x0, x1, x0);
2621 __ Ret();
2644 2622
2645 __ Bind(&miss); 2623 __ Bind(&miss);
2646 GenerateMiss(masm); 2624 GenerateMiss(masm);
2647 } 2625 }
2648 2626
2649 2627
2650 void CompareICStub::GenerateSmis(MacroAssembler* masm) { 2628 void CompareICStub::GenerateSmis(MacroAssembler* masm) {
2651 // Inputs are in x0 (lhs) and x1 (rhs). 2629 // Inputs are in x0 (lhs) and x1 (rhs).
2652 DCHECK(state() == CompareICState::SMI); 2630 DCHECK(state() == CompareICState::SMI);
2653 ASM_LOCATION("CompareICStub[Smis]"); 2631 ASM_LOCATION("CompareICStub[Smis]");
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2707 2685
2708 __ Bind(&values_in_d_regs); 2686 __ Bind(&values_in_d_regs);
2709 __ Fcmp(lhs_d, rhs_d); 2687 __ Fcmp(lhs_d, rhs_d);
2710 __ B(vs, &unordered); // Overflow flag set if either is NaN. 2688 __ B(vs, &unordered); // Overflow flag set if either is NaN.
2711 STATIC_ASSERT((LESS == -1) && (EQUAL == 0) && (GREATER == 1)); 2689 STATIC_ASSERT((LESS == -1) && (EQUAL == 0) && (GREATER == 1));
2712 __ Cset(result, gt); // gt => 1, otherwise (lt, eq) => 0 (EQUAL). 2690 __ Cset(result, gt); // gt => 1, otherwise (lt, eq) => 0 (EQUAL).
2713 __ Csinv(result, result, xzr, ge); // lt => -1, gt => 1, eq => 0. 2691 __ Csinv(result, result, xzr, ge); // lt => -1, gt => 1, eq => 0.
2714 __ Ret(); 2692 __ Ret();
2715 2693
2716 __ Bind(&unordered); 2694 __ Bind(&unordered);
2717 CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC, 2695 CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
2718 CompareICState::GENERIC, CompareICState::GENERIC); 2696 CompareICState::GENERIC, CompareICState::GENERIC);
2719 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 2697 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
2720 2698
2721 __ Bind(&maybe_undefined1); 2699 __ Bind(&maybe_undefined1);
2722 if (Token::IsOrderedRelationalCompareOp(op())) { 2700 if (Token::IsOrderedRelationalCompareOp(op())) {
2723 __ JumpIfNotRoot(rhs, Heap::kUndefinedValueRootIndex, &miss); 2701 __ JumpIfNotRoot(rhs, Heap::kUndefinedValueRootIndex, &miss);
2724 __ JumpIfSmi(lhs, &unordered); 2702 __ JumpIfSmi(lhs, &unordered);
2725 __ JumpIfNotHeapNumber(lhs, &maybe_undefined2); 2703 __ JumpIfNotHeapNumber(lhs, &maybe_undefined2);
2726 __ B(&unordered); 2704 __ B(&unordered);
2727 } 2705 }
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2938 __ Ldr(rhs_map, FieldMemOperand(rhs, HeapObject::kMapOffset)); 2916 __ Ldr(rhs_map, FieldMemOperand(rhs, HeapObject::kMapOffset));
2939 __ Ldr(lhs_map, FieldMemOperand(lhs, HeapObject::kMapOffset)); 2917 __ Ldr(lhs_map, FieldMemOperand(lhs, HeapObject::kMapOffset));
2940 __ Cmp(rhs_map, map); 2918 __ Cmp(rhs_map, map);
2941 __ B(ne, &miss); 2919 __ B(ne, &miss);
2942 __ Cmp(lhs_map, map); 2920 __ Cmp(lhs_map, map);
2943 __ B(ne, &miss); 2921 __ B(ne, &miss);
2944 2922
2945 if (Token::IsEqualityOp(op())) { 2923 if (Token::IsEqualityOp(op())) {
2946 __ Sub(result, rhs, lhs); 2924 __ Sub(result, rhs, lhs);
2947 __ Ret(); 2925 __ Ret();
2948 } else if (is_strong(strength())) {
2949 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion);
2950 } else { 2926 } else {
2951 Register ncr = x2; 2927 Register ncr = x2;
2952 if (op() == Token::LT || op() == Token::LTE) { 2928 if (op() == Token::LT || op() == Token::LTE) {
2953 __ Mov(ncr, Smi::FromInt(GREATER)); 2929 __ Mov(ncr, Smi::FromInt(GREATER));
2954 } else { 2930 } else {
2955 __ Mov(ncr, Smi::FromInt(LESS)); 2931 __ Mov(ncr, Smi::FromInt(LESS));
2956 } 2932 }
2957 __ Push(lhs, rhs, ncr); 2933 __ Push(lhs, rhs, ncr);
2958 __ TailCallRuntime(Runtime::kCompare); 2934 __ TailCallRuntime(Runtime::kCompare);
2959 } 2935 }
(...skipping 2932 matching lines...) Expand 10 before | Expand all | Expand 10 after
5892 return_value_operand, NULL); 5868 return_value_operand, NULL);
5893 } 5869 }
5894 5870
5895 5871
5896 #undef __ 5872 #undef __
5897 5873
5898 } // namespace internal 5874 } // namespace internal
5899 } // namespace v8 5875 } // namespace v8
5900 5876
5901 #endif // V8_TARGET_ARCH_ARM64 5877 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698