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

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

Issue 2622643005: ARM64: Add NEON support (Closed)
Patch Set: Created 3 years, 11 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/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 __ Pop(double_scratch); 135 __ Pop(double_scratch);
136 } 136 }
137 __ Pop(scratch2, scratch1); 137 __ Pop(scratch2, scratch1);
138 __ Ret(); 138 __ Ret();
139 } 139 }
140 140
141 141
142 // See call site for description. 142 // See call site for description.
143 static void EmitIdenticalObjectComparison(MacroAssembler* masm, Register left, 143 static void EmitIdenticalObjectComparison(MacroAssembler* masm, Register left,
144 Register right, Register scratch, 144 Register right, Register scratch,
145 FPRegister double_scratch, 145 VRegister double_scratch, Label* slow,
146 Label* slow, Condition cond) { 146 Condition cond) {
147 DCHECK(!AreAliased(left, right, scratch)); 147 DCHECK(!AreAliased(left, right, scratch));
148 Label not_identical, return_equal, heap_number; 148 Label not_identical, return_equal, heap_number;
149 Register result = x0; 149 Register result = x0;
150 150
151 __ Cmp(right, left); 151 __ Cmp(right, left);
152 __ B(ne, &not_identical); 152 __ B(ne, &not_identical);
153 153
154 // Test for NaN. Sadly, we can't just compare to factory::nan_value(), 154 // Test for NaN. Sadly, we can't just compare to factory::nan_value(),
155 // so we do the second best thing - test it ourselves. 155 // so we do the second best thing - test it ourselves.
156 // They are both equal and they are not both Smis so both of them are not 156 // They are both equal and they are not both Smis so both of them are not
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 // same object. We have already tested that case, so if left and right are 286 // same object. We have already tested that case, so if left and right are
287 // both internalized strings, they cannot be equal. 287 // both internalized strings, they cannot be equal.
288 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); 288 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0));
289 __ Orr(scratch, left_type, right_type); 289 __ Orr(scratch, left_type, right_type);
290 __ TestAndBranchIfAllClear( 290 __ TestAndBranchIfAllClear(
291 scratch, kIsNotStringMask | kIsNotInternalizedMask, &return_not_equal); 291 scratch, kIsNotStringMask | kIsNotInternalizedMask, &return_not_equal);
292 } 292 }
293 293
294 294
295 // See call site for description. 295 // See call site for description.
296 static void EmitSmiNonsmiComparison(MacroAssembler* masm, 296 static void EmitSmiNonsmiComparison(MacroAssembler* masm, Register left,
297 Register left, 297 Register right, VRegister left_d,
298 Register right, 298 VRegister right_d, Label* slow,
299 FPRegister left_d,
300 FPRegister right_d,
301 Label* slow,
302 bool strict) { 299 bool strict) {
303 DCHECK(!AreAliased(left_d, right_d)); 300 DCHECK(!AreAliased(left_d, right_d));
304 DCHECK((left.is(x0) && right.is(x1)) || 301 DCHECK((left.is(x0) && right.is(x1)) ||
305 (right.is(x0) && left.is(x1))); 302 (right.is(x0) && left.is(x1)));
306 Register result = x0; 303 Register result = x0;
307 304
308 Label right_is_smi, done; 305 Label right_is_smi, done;
309 __ JumpIfSmi(right, &right_is_smi); 306 __ JumpIfSmi(right, &right_is_smi);
310 307
311 // Left is the smi. Check whether right is a heap number. 308 // Left is the smi. Check whether right is a heap number.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 __ JumpIfBothNotSmi(lhs, rhs, &not_smis); 467 __ JumpIfBothNotSmi(lhs, rhs, &not_smis);
471 468
472 // Exactly one operand is a smi. EmitSmiNonsmiComparison generates code that 469 // Exactly one operand is a smi. EmitSmiNonsmiComparison generates code that
473 // can: 470 // can:
474 // 1) Return the answer. 471 // 1) Return the answer.
475 // 2) Branch to the slow case. 472 // 2) Branch to the slow case.
476 // 3) Fall through to both_loaded_as_doubles. 473 // 3) Fall through to both_loaded_as_doubles.
477 // In case 3, we have found out that we were dealing with a number-number 474 // In case 3, we have found out that we were dealing with a number-number
478 // comparison. The double values of the numbers have been loaded, right into 475 // comparison. The double values of the numbers have been loaded, right into
479 // rhs_d, left into lhs_d. 476 // rhs_d, left into lhs_d.
480 FPRegister rhs_d = d0; 477 VRegister rhs_d = d0;
481 FPRegister lhs_d = d1; 478 VRegister lhs_d = d1;
482 EmitSmiNonsmiComparison(masm, lhs, rhs, lhs_d, rhs_d, &slow, strict()); 479 EmitSmiNonsmiComparison(masm, lhs, rhs, lhs_d, rhs_d, &slow, strict());
483 480
484 __ Bind(&both_loaded_as_doubles); 481 __ Bind(&both_loaded_as_doubles);
485 // The arguments have been converted to doubles and stored in rhs_d and 482 // The arguments have been converted to doubles and stored in rhs_d and
486 // lhs_d. 483 // lhs_d.
487 Label nan; 484 Label nan;
488 __ Fcmp(lhs_d, rhs_d); 485 __ Fcmp(lhs_d, rhs_d);
489 __ B(vs, &nan); // Overflow flag set if either is NaN. 486 __ B(vs, &nan); // Overflow flag set if either is NaN.
490 STATIC_ASSERT((LESS == -1) && (EQUAL == 0) && (GREATER == 1)); 487 STATIC_ASSERT((LESS == -1) && (EQUAL == 0) && (GREATER == 1));
491 __ Cset(result, gt); // gt => 1, otherwise (lt, eq) => 0 (EQUAL). 488 __ Cset(result, gt); // gt => 1, otherwise (lt, eq) => 0 (EQUAL).
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 __ TailCallRuntime(Runtime::kCompare); 604 __ TailCallRuntime(Runtime::kCompare);
608 } 605 }
609 606
610 __ Bind(&miss); 607 __ Bind(&miss);
611 GenerateMiss(masm); 608 GenerateMiss(masm);
612 } 609 }
613 610
614 611
615 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { 612 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
616 CPURegList saved_regs = kCallerSaved; 613 CPURegList saved_regs = kCallerSaved;
617 CPURegList saved_fp_regs = kCallerSavedFP; 614 CPURegList saved_fp_regs = kCallerSavedV;
618 615
619 // We don't allow a GC during a store buffer overflow so there is no need to 616 // We don't allow a GC during a store buffer overflow so there is no need to
620 // store the registers in any particular way, but we do have to store and 617 // store the registers in any particular way, but we do have to store and
621 // restore them. 618 // restore them.
622 619
623 // We don't care if MacroAssembler scratch registers are corrupted. 620 // We don't care if MacroAssembler scratch registers are corrupted.
624 saved_regs.Remove(*(masm->TmpList())); 621 saved_regs.Remove(*(masm->TmpList()));
625 saved_fp_regs.Remove(*(masm->FPTmpList())); 622 saved_fp_regs.Remove(*(masm->FPTmpList()));
626 623
627 __ PushCPURegList(saved_regs); 624 __ PushCPURegList(saved_regs);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 // jssp[0]: Exponent (as a tagged value). 677 // jssp[0]: Exponent (as a tagged value).
681 // jssp[1]: Base (as a tagged value). 678 // jssp[1]: Base (as a tagged value).
682 // 679 //
683 // The (tagged) result will be returned in x0, as a heap number. 680 // The (tagged) result will be returned in x0, as a heap number.
684 681
685 Register exponent_tagged = MathPowTaggedDescriptor::exponent(); 682 Register exponent_tagged = MathPowTaggedDescriptor::exponent();
686 DCHECK(exponent_tagged.is(x11)); 683 DCHECK(exponent_tagged.is(x11));
687 Register exponent_integer = MathPowIntegerDescriptor::exponent(); 684 Register exponent_integer = MathPowIntegerDescriptor::exponent();
688 DCHECK(exponent_integer.is(x12)); 685 DCHECK(exponent_integer.is(x12));
689 Register saved_lr = x19; 686 Register saved_lr = x19;
690 FPRegister result_double = d0; 687 VRegister result_double = d0;
691 FPRegister base_double = d0; 688 VRegister base_double = d0;
692 FPRegister exponent_double = d1; 689 VRegister exponent_double = d1;
693 FPRegister base_double_copy = d2; 690 VRegister base_double_copy = d2;
694 FPRegister scratch1_double = d6; 691 VRegister scratch1_double = d6;
695 FPRegister scratch0_double = d7; 692 VRegister scratch0_double = d7;
696 693
697 // A fast-path for integer exponents. 694 // A fast-path for integer exponents.
698 Label exponent_is_smi, exponent_is_integer; 695 Label exponent_is_smi, exponent_is_integer;
699 // Allocate a heap number for the result, and return it. 696 // Allocate a heap number for the result, and return it.
700 Label done; 697 Label done;
701 698
702 // Unpack the inputs. 699 // Unpack the inputs.
703 if (exponent_type() == TAGGED) { 700 if (exponent_type() == TAGGED) {
704 __ JumpIfSmi(exponent_tagged, &exponent_is_smi); 701 __ JumpIfSmi(exponent_tagged, &exponent_is_smi);
705 __ Ldr(exponent_double, 702 __ Ldr(exponent_double,
(...skipping 1629 matching lines...) Expand 10 before | Expand all | Expand 10 after
2335 DCHECK(state() == CompareICState::NUMBER); 2332 DCHECK(state() == CompareICState::NUMBER);
2336 ASM_LOCATION("CompareICStub[HeapNumbers]"); 2333 ASM_LOCATION("CompareICStub[HeapNumbers]");
2337 2334
2338 Label unordered, maybe_undefined1, maybe_undefined2; 2335 Label unordered, maybe_undefined1, maybe_undefined2;
2339 Label miss, handle_lhs, values_in_d_regs; 2336 Label miss, handle_lhs, values_in_d_regs;
2340 Label untag_rhs, untag_lhs; 2337 Label untag_rhs, untag_lhs;
2341 2338
2342 Register result = x0; 2339 Register result = x0;
2343 Register rhs = x0; 2340 Register rhs = x0;
2344 Register lhs = x1; 2341 Register lhs = x1;
2345 FPRegister rhs_d = d0; 2342 VRegister rhs_d = d0;
2346 FPRegister lhs_d = d1; 2343 VRegister lhs_d = d1;
2347 2344
2348 if (left() == CompareICState::SMI) { 2345 if (left() == CompareICState::SMI) {
2349 __ JumpIfNotSmi(lhs, &miss); 2346 __ JumpIfNotSmi(lhs, &miss);
2350 } 2347 }
2351 if (right() == CompareICState::SMI) { 2348 if (right() == CompareICState::SMI) {
2352 __ JumpIfNotSmi(rhs, &miss); 2349 __ JumpIfNotSmi(rhs, &miss);
2353 } 2350 }
2354 2351
2355 __ SmiUntagToDouble(rhs_d, rhs, kSpeculativeUntag); 2352 __ SmiUntagToDouble(rhs_d, rhs, kSpeculativeUntag);
2356 __ SmiUntagToDouble(lhs_d, lhs, kSpeculativeUntag); 2353 __ SmiUntagToDouble(lhs_d, lhs, kSpeculativeUntag);
(...skipping 2198 matching lines...) Expand 10 before | Expand all | Expand 10 after
4555 kStackUnwindSpace, NULL, spill_offset, 4552 kStackUnwindSpace, NULL, spill_offset,
4556 return_value_operand, NULL); 4553 return_value_operand, NULL);
4557 } 4554 }
4558 4555
4559 #undef __ 4556 #undef __
4560 4557
4561 } // namespace internal 4558 } // namespace internal
4562 } // namespace v8 4559 } // namespace v8
4563 4560
4564 #endif // V8_TARGET_ARCH_ARM64 4561 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698