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

Side by Side Diff: src/arm64/lithium-codegen-arm64.cc

Issue 272183003: ARM64: Small optimisations (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « src/arm64/lithium-arm64.cc ('k') | src/arm64/macro-assembler-arm64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "v8.h" 5 #include "v8.h"
6 6
7 #include "arm64/lithium-codegen-arm64.h" 7 #include "arm64/lithium-codegen-arm64.h"
8 #include "arm64/lithium-gap-resolver-arm64.h" 8 #include "arm64/lithium-gap-resolver-arm64.h"
9 #include "code-stubs.h" 9 #include "code-stubs.h"
10 #include "stub-cache.h" 10 #include "stub-cache.h"
(...skipping 2272 matching lines...) Expand 10 before | Expand all | Expand 10 after
2283 2283
2284 __ Bind(&done); 2284 __ Bind(&done);
2285 } 2285 }
2286 2286
2287 2287
2288 void LCodeGen::DoDoubleBits(LDoubleBits* instr) { 2288 void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
2289 DoubleRegister value_reg = ToDoubleRegister(instr->value()); 2289 DoubleRegister value_reg = ToDoubleRegister(instr->value());
2290 Register result_reg = ToRegister(instr->result()); 2290 Register result_reg = ToRegister(instr->result());
2291 if (instr->hydrogen()->bits() == HDoubleBits::HIGH) { 2291 if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
2292 __ Fmov(result_reg, value_reg); 2292 __ Fmov(result_reg, value_reg);
2293 __ Mov(result_reg, Operand(result_reg, LSR, 32)); 2293 __ Lsr(result_reg, result_reg, 32);
2294 } else { 2294 } else {
2295 __ Fmov(result_reg.W(), value_reg.S()); 2295 __ Fmov(result_reg.W(), value_reg.S());
2296 } 2296 }
2297 } 2297 }
2298 2298
2299 2299
2300 void LCodeGen::DoConstructDouble(LConstructDouble* instr) { 2300 void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
2301 Register hi_reg = ToRegister(instr->hi()); 2301 Register hi_reg = ToRegister(instr->hi());
2302 Register lo_reg = ToRegister(instr->lo()); 2302 Register lo_reg = ToRegister(instr->lo());
2303 Register temp = ToRegister(instr->temp());
2304 DoubleRegister result_reg = ToDoubleRegister(instr->result()); 2303 DoubleRegister result_reg = ToDoubleRegister(instr->result());
2305 2304
2306 __ And(temp, lo_reg, Operand(0xffffffff)); 2305 // Insert the least significant 32 bits of hi_reg into the most significant
2307 __ Orr(temp, temp, Operand(hi_reg, LSL, 32)); 2306 // 32 bits of lo_reg, and move to a floating point register.
2308 __ Fmov(result_reg, temp); 2307 __ Bfi(lo_reg, hi_reg, 32, 32);
2308 __ Fmov(result_reg, lo_reg);
2309 } 2309 }
2310 2310
2311 2311
2312 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2312 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
2313 Handle<String> class_name = instr->hydrogen()->class_name(); 2313 Handle<String> class_name = instr->hydrogen()->class_name();
2314 Label* true_label = instr->TrueLabel(chunk_); 2314 Label* true_label = instr->TrueLabel(chunk_);
2315 Label* false_label = instr->FalseLabel(chunk_); 2315 Label* false_label = instr->FalseLabel(chunk_);
2316 Register input = ToRegister(instr->value()); 2316 Register input = ToRegister(instr->value());
2317 Register scratch1 = ToRegister(instr->temp1()); 2317 Register scratch1 = ToRegister(instr->temp1());
2318 Register scratch2 = ToRegister(instr->temp2()); 2318 Register scratch2 = ToRegister(instr->temp2());
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2408 ASSERT(!rep.IsInteger32()); 2408 ASSERT(!rep.IsInteger32());
2409 Register scratch = ToRegister(instr->temp()); 2409 Register scratch = ToRegister(instr->temp());
2410 2410
2411 if (rep.IsDouble()) { 2411 if (rep.IsDouble()) {
2412 __ JumpIfMinusZero(ToDoubleRegister(instr->value()), 2412 __ JumpIfMinusZero(ToDoubleRegister(instr->value()),
2413 instr->TrueLabel(chunk())); 2413 instr->TrueLabel(chunk()));
2414 } else { 2414 } else {
2415 Register value = ToRegister(instr->value()); 2415 Register value = ToRegister(instr->value());
2416 __ CheckMap(value, scratch, Heap::kHeapNumberMapRootIndex, 2416 __ CheckMap(value, scratch, Heap::kHeapNumberMapRootIndex,
2417 instr->FalseLabel(chunk()), DO_SMI_CHECK); 2417 instr->FalseLabel(chunk()), DO_SMI_CHECK);
2418 __ Ldr(double_scratch(), FieldMemOperand(value, HeapNumber::kValueOffset)); 2418 __ Ldr(scratch, FieldMemOperand(value, HeapNumber::kValueOffset));
2419 __ JumpIfMinusZero(double_scratch(), instr->TrueLabel(chunk())); 2419 __ JumpIfMinusZero(scratch, instr->TrueLabel(chunk()));
2420 } 2420 }
2421 EmitGoto(instr->FalseDestination(chunk())); 2421 EmitGoto(instr->FalseDestination(chunk()));
2422 } 2422 }
2423 2423
2424 2424
2425 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { 2425 void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
2426 LOperand* left = instr->left(); 2426 LOperand* left = instr->left();
2427 LOperand* right = instr->right(); 2427 LOperand* right = instr->right();
2428 Condition cond = TokenToCondition(instr->op(), false); 2428 Condition cond = TokenToCondition(instr->op(), false);
2429 2429
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2517 ASSERT(instr->IsMarkedAsCall()); 2517 ASSERT(instr->IsMarkedAsCall());
2518 __ LoadTrueFalseRoots(x1, x2); 2518 __ LoadTrueFalseRoots(x1, x2);
2519 __ Cmp(x0, 0); 2519 __ Cmp(x0, 0);
2520 __ Csel(ToRegister(instr->result()), x1, x2, cond); 2520 __ Csel(ToRegister(instr->result()), x1, x2, cond);
2521 } 2521 }
2522 2522
2523 2523
2524 void LCodeGen::DoConstantD(LConstantD* instr) { 2524 void LCodeGen::DoConstantD(LConstantD* instr) {
2525 ASSERT(instr->result()->IsDoubleRegister()); 2525 ASSERT(instr->result()->IsDoubleRegister());
2526 DoubleRegister result = ToDoubleRegister(instr->result()); 2526 DoubleRegister result = ToDoubleRegister(instr->result());
2527 __ Fmov(result, instr->value()); 2527 if (instr->value() == 0) {
2528 if (copysign(1.0, instr->value()) == 1.0) {
2529 __ Fmov(result, fp_zero);
2530 } else {
2531 __ Fneg(result, fp_zero);
2532 }
2533 } else {
2534 __ Fmov(result, instr->value());
2535 }
2528 } 2536 }
2529 2537
2530 2538
2531 void LCodeGen::DoConstantE(LConstantE* instr) { 2539 void LCodeGen::DoConstantE(LConstantE* instr) {
2532 __ Mov(ToRegister(instr->result()), Operand(instr->value())); 2540 __ Mov(ToRegister(instr->result()), Operand(instr->value()));
2533 } 2541 }
2534 2542
2535 2543
2536 void LCodeGen::DoConstantI(LConstantI* instr) { 2544 void LCodeGen::DoConstantI(LConstantI* instr) {
2537 ASSERT(is_int32(instr->value())); 2545 ASSERT(is_int32(instr->value()));
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2656 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 2664 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
2657 Register dividend = ToRegister32(instr->dividend()); 2665 Register dividend = ToRegister32(instr->dividend());
2658 int32_t divisor = instr->divisor(); 2666 int32_t divisor = instr->divisor();
2659 Register result = ToRegister32(instr->result()); 2667 Register result = ToRegister32(instr->result());
2660 ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor))); 2668 ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
2661 ASSERT(!result.is(dividend)); 2669 ASSERT(!result.is(dividend));
2662 2670
2663 // Check for (0 / -x) that will produce negative zero. 2671 // Check for (0 / -x) that will produce negative zero.
2664 HDiv* hdiv = instr->hydrogen(); 2672 HDiv* hdiv = instr->hydrogen();
2665 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 2673 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
2666 __ Cmp(dividend, 0); 2674 DeoptimizeIfZero(dividend, instr->environment());
2667 DeoptimizeIf(eq, instr->environment());
2668 } 2675 }
2669 // Check for (kMinInt / -1). 2676 // Check for (kMinInt / -1).
2670 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { 2677 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
2671 __ Cmp(dividend, kMinInt); 2678 // Test dividend for kMinInt by subtracting one (cmp) and checking for
2672 DeoptimizeIf(eq, instr->environment()); 2679 // overflow.
2680 __ Cmp(dividend, 1);
2681 DeoptimizeIf(vs, instr->environment());
2673 } 2682 }
2674 // Deoptimize if remainder will not be 0. 2683 // Deoptimize if remainder will not be 0.
2675 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 2684 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
2676 divisor != 1 && divisor != -1) { 2685 divisor != 1 && divisor != -1) {
2677 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 2686 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
2678 __ Tst(dividend, mask); 2687 __ Tst(dividend, mask);
2679 DeoptimizeIf(ne, instr->environment()); 2688 DeoptimizeIf(ne, instr->environment());
2680 } 2689 }
2681 2690
2682 if (divisor == -1) { // Nice shortcut, not needed for correctness. 2691 if (divisor == -1) { // Nice shortcut, not needed for correctness.
(...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3915 ASSERT(!AreAliased(dividend, result)); 3924 ASSERT(!AreAliased(dividend, result));
3916 3925
3917 if (divisor == 0) { 3926 if (divisor == 0) {
3918 Deoptimize(instr->environment()); 3927 Deoptimize(instr->environment());
3919 return; 3928 return;
3920 } 3929 }
3921 3930
3922 // Check for (0 / -x) that will produce negative zero. 3931 // Check for (0 / -x) that will produce negative zero.
3923 HMathFloorOfDiv* hdiv = instr->hydrogen(); 3932 HMathFloorOfDiv* hdiv = instr->hydrogen();
3924 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 3933 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
3925 __ Cmp(dividend, 0); 3934 DeoptimizeIfZero(dividend, instr->environment());
3926 DeoptimizeIf(eq, instr->environment());
3927 } 3935 }
3928 3936
3929 // Easy case: We need no dynamic check for the dividend and the flooring 3937 // Easy case: We need no dynamic check for the dividend and the flooring
3930 // division is the same as the truncating division. 3938 // division is the same as the truncating division.
3931 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || 3939 if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
3932 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { 3940 (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
3933 __ TruncatingDiv(result, dividend, Abs(divisor)); 3941 __ TruncatingDiv(result, dividend, Abs(divisor));
3934 if (divisor < 0) __ Neg(result, result); 3942 if (divisor < 0) __ Neg(result, result);
3935 return; 3943 return;
3936 } 3944 }
3937 3945
3938 // In the general case we may need to adjust before and after the truncating 3946 // In the general case we may need to adjust before and after the truncating
3939 // division to get a flooring division. 3947 // division to get a flooring division.
3940 Register temp = ToRegister32(instr->temp()); 3948 Register temp = ToRegister32(instr->temp());
3941 ASSERT(!AreAliased(temp, dividend, result)); 3949 ASSERT(!AreAliased(temp, dividend, result));
3942 Label needs_adjustment, done; 3950 Label needs_adjustment, done;
3943 __ Cmp(dividend, 0); 3951 __ Cmp(dividend, 0);
3944 __ B(divisor > 0 ? lt : gt, &needs_adjustment); 3952 __ B(divisor > 0 ? lt : gt, &needs_adjustment);
3945 __ TruncatingDiv(result, dividend, Abs(divisor)); 3953 __ TruncatingDiv(result, dividend, Abs(divisor));
3946 if (divisor < 0) __ Neg(result, result); 3954 if (divisor < 0) __ Neg(result, result);
3947 __ B(&done); 3955 __ B(&done);
3948 __ bind(&needs_adjustment); 3956 __ Bind(&needs_adjustment);
3949 __ Add(temp, dividend, Operand(divisor > 0 ? 1 : -1)); 3957 __ Add(temp, dividend, Operand(divisor > 0 ? 1 : -1));
3950 __ TruncatingDiv(result, temp, Abs(divisor)); 3958 __ TruncatingDiv(result, temp, Abs(divisor));
3951 if (divisor < 0) __ Neg(result, result); 3959 if (divisor < 0) __ Neg(result, result);
3952 __ Sub(result, result, Operand(1)); 3960 __ Sub(result, result, Operand(1));
3953 __ bind(&done); 3961 __ Bind(&done);
3954 } 3962 }
3955 3963
3956 3964
3957 // TODO(svenpanne) Refactor this to avoid code duplication with DoDivI. 3965 // TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
3958 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { 3966 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
3959 Register dividend = ToRegister32(instr->dividend()); 3967 Register dividend = ToRegister32(instr->dividend());
3960 Register divisor = ToRegister32(instr->divisor()); 3968 Register divisor = ToRegister32(instr->divisor());
3961 Register remainder = ToRegister32(instr->temp()); 3969 Register remainder = ToRegister32(instr->temp());
3962 Register result = ToRegister32(instr->result()); 3970 Register result = ToRegister32(instr->result());
3963 3971
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
4210 // Theoretically, a variation of the branch-free code for integer division by 4218 // Theoretically, a variation of the branch-free code for integer division by
4211 // a power of 2 (calculating the remainder via an additional multiplication 4219 // a power of 2 (calculating the remainder via an additional multiplication
4212 // (which gets simplified to an 'and') and subtraction) should be faster, and 4220 // (which gets simplified to an 'and') and subtraction) should be faster, and
4213 // this is exactly what GCC and clang emit. Nevertheless, benchmarks seem to 4221 // this is exactly what GCC and clang emit. Nevertheless, benchmarks seem to
4214 // indicate that positive dividends are heavily favored, so the branching 4222 // indicate that positive dividends are heavily favored, so the branching
4215 // version performs better. 4223 // version performs better.
4216 HMod* hmod = instr->hydrogen(); 4224 HMod* hmod = instr->hydrogen();
4217 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 4225 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
4218 Label dividend_is_not_negative, done; 4226 Label dividend_is_not_negative, done;
4219 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { 4227 if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) {
4220 __ Cmp(dividend, 0); 4228 __ Tbz(dividend, kWSignBit, &dividend_is_not_negative);
4221 __ B(pl, &dividend_is_not_negative);
4222 // Note that this is correct even for kMinInt operands. 4229 // Note that this is correct even for kMinInt operands.
4223 __ Neg(dividend, dividend); 4230 __ Neg(dividend, dividend);
4224 __ And(dividend, dividend, mask); 4231 __ And(dividend, dividend, mask);
4225 __ Negs(dividend, dividend); 4232 __ Negs(dividend, dividend);
4226 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 4233 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
4227 DeoptimizeIf(eq, instr->environment()); 4234 DeoptimizeIf(eq, instr->environment());
4228 } 4235 }
4229 __ B(&done); 4236 __ B(&done);
4230 } 4237 }
4231 4238
(...skipping 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after
6001 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 6008 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
6002 // Index is equal to negated out of object property index plus 1. 6009 // Index is equal to negated out of object property index plus 1.
6003 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 6010 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2));
6004 __ Ldr(result, FieldMemOperand(result, 6011 __ Ldr(result, FieldMemOperand(result,
6005 FixedArray::kHeaderSize - kPointerSize)); 6012 FixedArray::kHeaderSize - kPointerSize));
6006 __ Bind(deferred->exit()); 6013 __ Bind(deferred->exit());
6007 __ Bind(&done); 6014 __ Bind(&done);
6008 } 6015 }
6009 6016
6010 } } // namespace v8::internal 6017 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm64/lithium-arm64.cc ('k') | src/arm64/macro-assembler-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698