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

Side by Side Diff: src/arm/macro-assembler-arm.cc

Issue 2313863003: [arm] Improve Float(32|64)(Max|Min). (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/compiler/arm/code-generator-arm.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 <limits.h> // For LONG_MIN, LONG_MAX. 5 #include <limits.h> // For LONG_MIN, LONG_MAX.
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/base/division-by-constant.h" 10 #include "src/base/division-by-constant.h"
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 mov(dst, Operand(value)); 243 mov(dst, Operand(value));
244 } 244 }
245 245
246 246
247 void MacroAssembler::Move(Register dst, Register src, Condition cond) { 247 void MacroAssembler::Move(Register dst, Register src, Condition cond) {
248 if (!dst.is(src)) { 248 if (!dst.is(src)) {
249 mov(dst, src, LeaveCC, cond); 249 mov(dst, src, LeaveCC, cond);
250 } 250 }
251 } 251 }
252 252
253 void MacroAssembler::Move(SwVfpRegister dst, SwVfpRegister src) { 253 void MacroAssembler::Move(SwVfpRegister dst, SwVfpRegister src,
254 Condition cond) {
254 if (!dst.is(src)) { 255 if (!dst.is(src)) {
255 vmov(dst, src); 256 vmov(dst, src, cond);
256 } 257 }
257 } 258 }
258 259
259 void MacroAssembler::Move(DwVfpRegister dst, DwVfpRegister src) { 260 void MacroAssembler::Move(DwVfpRegister dst, DwVfpRegister src,
261 Condition cond) {
260 if (!dst.is(src)) { 262 if (!dst.is(src)) {
261 vmov(dst, src); 263 vmov(dst, src, cond);
262 } 264 }
263 } 265 }
264 266
265 void MacroAssembler::Mls(Register dst, Register src1, Register src2, 267 void MacroAssembler::Mls(Register dst, Register src1, Register src2,
266 Register srcA, Condition cond) { 268 Register srcA, Condition cond) {
267 if (CpuFeatures::IsSupported(ARMv7)) { 269 if (CpuFeatures::IsSupported(ARMv7)) {
268 CpuFeatureScope scope(this, ARMv7); 270 CpuFeatureScope scope(this, ARMv7);
269 mls(dst, src1, src2, srcA, cond); 271 mls(dst, src1, src2, srcA, cond);
270 } else { 272 } else {
271 DCHECK(!srcA.is(ip)); 273 DCHECK(!srcA.is(ip));
(...skipping 3149 matching lines...) Expand 10 before | Expand all | Expand 10 after
3421 } 3423 }
3422 3424
3423 3425
3424 void MacroAssembler::RestoreFPRegs(Register location, Register scratch) { 3426 void MacroAssembler::RestoreFPRegs(Register location, Register scratch) {
3425 CheckFor32DRegs(scratch); 3427 CheckFor32DRegs(scratch);
3426 vldm(ia_w, location, d0, d15); 3428 vldm(ia_w, location, d0, d15);
3427 vldm(ia_w, location, d16, d31, ne); 3429 vldm(ia_w, location, d16, d31, ne);
3428 add(location, location, Operand(16 * kDoubleSize), LeaveCC, eq); 3430 add(location, location, Operand(16 * kDoubleSize), LeaveCC, eq);
3429 } 3431 }
3430 3432
3433 template <typename T>
3434 void MacroAssembler::FloatMaxHelper(T result, T left, T right,
3435 Label* out_of_line) {
3436 // This trivial case is caught sooner, so that the out-of-line code can be
3437 // completely avoided.
3438 DCHECK(!left.is(right));
3439
3440 if (CpuFeatures::IsSupported(ARMv8)) {
3441 CpuFeatureScope scope(this, ARMv8);
3442 VFPCompareAndSetFlags(left, right);
3443 b(vs, out_of_line);
3444 vmaxnm(result, left, right);
3445 } else {
3446 Label done;
3447 VFPCompareAndSetFlags(left, right);
3448 b(vs, out_of_line);
3449 // Avoid a conditional instruction if the result register is unique.
3450 bool aliased_result_reg = result.is(left) || result.is(right);
3451 Move(result, right, aliased_result_reg ? mi : al);
3452 Move(result, left, gt);
3453 b(ne, &done);
3454 // Left and right are equal, but check for +/-0.
3455 VFPCompareAndSetFlags(left, 0.0);
3456 b(eq, out_of_line);
3457 // The arguments are equal and not zero, so it doesn't matter which input we
3458 // pick. We have already moved one input into the result (if it didn't
3459 // already alias) so there's nothing more to do.
3460 bind(&done);
3461 }
3462 }
3463
3464 template <typename T>
3465 void MacroAssembler::FloatMaxOutOfLineHelper(T result, T left, T right) {
3466 DCHECK(!left.is(right));
3467
3468 // ARMv8: At least one of left and right is a NaN.
3469 // Anything else: At least one of left and right is a NaN, or both left and
3470 // right are zeroes with unknown sign.
3471
3472 // If left and right are +/-0, select the one with the most positive sign.
3473 // If left or right are NaN, vadd propagates the appropriate one.
3474 vadd(result, left, right);
3475 }
3476
3477 template <typename T>
3478 void MacroAssembler::FloatMinHelper(T result, T left, T right,
3479 Label* out_of_line) {
3480 // This trivial case is caught sooner, so that the out-of-line code can be
3481 // completely avoided.
3482 DCHECK(!left.is(right));
3483
3484 if (CpuFeatures::IsSupported(ARMv8)) {
3485 CpuFeatureScope scope(this, ARMv8);
3486 VFPCompareAndSetFlags(left, right);
3487 b(vs, out_of_line);
3488 vminnm(result, left, right);
3489 } else {
3490 Label done;
3491 VFPCompareAndSetFlags(left, right);
3492 b(vs, out_of_line);
3493 // Avoid a conditional instruction if the result register is unique.
3494 bool aliased_result_reg = result.is(left) || result.is(right);
3495 Move(result, left, aliased_result_reg ? mi : al);
3496 Move(result, right, gt);
3497 b(ne, &done);
3498 // Left and right are equal, but check for +/-0.
3499 VFPCompareAndSetFlags(left, 0.0);
3500 // If the arguments are equal and not zero, it doesn't matter which input we
3501 // pick. We have already moved one input into the result (if it didn't
3502 // already alias) so there's nothing more to do.
3503 b(ne, &done);
3504 // At this point, both left and right are either 0 or -0.
3505 // We could use a single 'vorr' instruction here if we had NEON support.
3506 // The algorithm used is -((-L) + (-R)), which is most efficiently expressed
3507 // as -((-L) - R).
3508 if (left.is(result)) {
3509 DCHECK(!right.is(result));
3510 vneg(result, left);
3511 vsub(result, result, right);
3512 vneg(result, result);
3513 } else {
3514 DCHECK(!left.is(result));
3515 vneg(result, right);
3516 vsub(result, result, left);
3517 vneg(result, result);
3518 }
3519 bind(&done);
3520 }
3521 }
3522
3523 template <typename T>
3524 void MacroAssembler::FloatMinOutOfLineHelper(T result, T left, T right) {
3525 DCHECK(!left.is(right));
3526
3527 // At least one of left and right is a NaN. Use vadd to propagate the NaN
3528 // appropriately. +/-0 is handled inline.
3529 vadd(result, left, right);
3530 }
3531
3532 void MacroAssembler::FloatMax(SwVfpRegister result, SwVfpRegister left,
3533 SwVfpRegister right, Label* out_of_line) {
3534 FloatMaxHelper(result, left, right, out_of_line);
3535 }
3536
3537 void MacroAssembler::FloatMin(SwVfpRegister result, SwVfpRegister left,
3538 SwVfpRegister right, Label* out_of_line) {
3539 FloatMinHelper(result, left, right, out_of_line);
3540 }
3541
3542 void MacroAssembler::FloatMax(DwVfpRegister result, DwVfpRegister left,
3543 DwVfpRegister right, Label* out_of_line) {
3544 FloatMaxHelper(result, left, right, out_of_line);
3545 }
3546
3547 void MacroAssembler::FloatMin(DwVfpRegister result, DwVfpRegister left,
3548 DwVfpRegister right, Label* out_of_line) {
3549 FloatMinHelper(result, left, right, out_of_line);
3550 }
3551
3552 void MacroAssembler::FloatMaxOutOfLine(SwVfpRegister result, SwVfpRegister left,
3553 SwVfpRegister right) {
3554 FloatMaxOutOfLineHelper(result, left, right);
3555 }
3556
3557 void MacroAssembler::FloatMinOutOfLine(SwVfpRegister result, SwVfpRegister left,
3558 SwVfpRegister right) {
3559 FloatMinOutOfLineHelper(result, left, right);
3560 }
3561
3562 void MacroAssembler::FloatMaxOutOfLine(DwVfpRegister result, DwVfpRegister left,
3563 DwVfpRegister right) {
3564 FloatMaxOutOfLineHelper(result, left, right);
3565 }
3566
3567 void MacroAssembler::FloatMinOutOfLine(DwVfpRegister result, DwVfpRegister left,
3568 DwVfpRegister right) {
3569 FloatMinOutOfLineHelper(result, left, right);
3570 }
3431 3571
3432 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( 3572 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte(
3433 Register first, Register second, Register scratch1, Register scratch2, 3573 Register first, Register second, Register scratch1, Register scratch2,
3434 Label* failure) { 3574 Label* failure) {
3435 const int kFlatOneByteStringMask = 3575 const int kFlatOneByteStringMask =
3436 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; 3576 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
3437 const int kFlatOneByteStringTag = 3577 const int kFlatOneByteStringTag =
3438 kStringTag | kOneByteStringTag | kSeqStringTag; 3578 kStringTag | kOneByteStringTag | kSeqStringTag;
3439 and_(scratch1, first, Operand(kFlatOneByteStringMask)); 3579 and_(scratch1, first, Operand(kFlatOneByteStringMask));
3440 and_(scratch2, second, Operand(kFlatOneByteStringMask)); 3580 and_(scratch2, second, Operand(kFlatOneByteStringMask));
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
4026 } 4166 }
4027 } 4167 }
4028 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); 4168 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift));
4029 add(result, result, Operand(dividend, LSR, 31)); 4169 add(result, result, Operand(dividend, LSR, 31));
4030 } 4170 }
4031 4171
4032 } // namespace internal 4172 } // namespace internal
4033 } // namespace v8 4173 } // namespace v8
4034 4174
4035 #endif // V8_TARGET_ARCH_ARM 4175 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698