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

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

Issue 2534413002: MIPS: Improve Float(32|64)(Max|Min). (Closed)
Patch Set: MIPS: Improve Float(32|64)(Max|Min). Created 4 years 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/mips64/macro-assembler-mips64.h ('k') | test/cctest/compiler/test-run-machops.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_MIPS64 7 #if V8_TARGET_ARCH_MIPS64
8 8
9 #include "src/base/division-by-constant.h" 9 #include "src/base/division-by-constant.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 2506 matching lines...) Expand 10 before | Expand all | Expand 10 after
2517 2517
2518 void MacroAssembler::Movt(Register rd, Register rs, uint16_t cc) { 2518 void MacroAssembler::Movt(Register rd, Register rs, uint16_t cc) {
2519 movt(rd, rs, cc); 2519 movt(rd, rs, cc);
2520 } 2520 }
2521 2521
2522 2522
2523 void MacroAssembler::Movf(Register rd, Register rs, uint16_t cc) { 2523 void MacroAssembler::Movf(Register rd, Register rs, uint16_t cc) {
2524 movf(rd, rs, cc); 2524 movf(rd, rs, cc);
2525 } 2525 }
2526 2526
2527 #define __ masm->
2528
2529 static bool ZeroHelper_d(MacroAssembler* masm, MaxMinKind kind, FPURegister dst,
2530 FPURegister src1, FPURegister src2, Label* equal) {
2531 if (src1.is(src2)) {
2532 __ Move(dst, src1);
2533 return true;
2534 }
2535
2536 Label other, compare_not_equal;
2537 FPURegister left, right;
2538 if (kind == MaxMinKind::kMin) {
2539 left = src1;
2540 right = src2;
2541 } else {
2542 left = src2;
2543 right = src1;
2544 }
2545
2546 __ BranchF64(&compare_not_equal, nullptr, ne, src1, src2);
2547 // Left and right hand side are equal, check for -0 vs. +0.
2548 __ dmfc1(t8, src1);
2549 __ Branch(&other, eq, t8, Operand(0x8000000000000000));
2550 __ Move_d(dst, right);
2551 __ Branch(equal);
2552 __ bind(&other);
2553 __ Move_d(dst, left);
2554 __ Branch(equal);
2555 __ bind(&compare_not_equal);
2556 return false;
2557 }
2558
2559 static bool ZeroHelper_s(MacroAssembler* masm, MaxMinKind kind, FPURegister dst,
2560 FPURegister src1, FPURegister src2, Label* equal) {
2561 if (src1.is(src2)) {
2562 __ Move(dst, src1);
2563 return true;
2564 }
2565
2566 Label other, compare_not_equal;
2567 FPURegister left, right;
2568 if (kind == MaxMinKind::kMin) {
2569 left = src1;
2570 right = src2;
2571 } else {
2572 left = src2;
2573 right = src1;
2574 }
2575
2576 __ BranchF32(&compare_not_equal, nullptr, ne, src1, src2);
2577 // Left and right hand side are equal, check for -0 vs. +0.
2578 __ FmoveLow(t8, src1);
2579 __ dsll32(t8, t8, 0);
2580 __ Branch(&other, eq, t8, Operand(0x8000000000000000));
2581 __ Move_s(dst, right);
2582 __ Branch(equal);
2583 __ bind(&other);
2584 __ Move_s(dst, left);
2585 __ Branch(equal);
2586 __ bind(&compare_not_equal);
2587 return false;
2588 }
2589
2590 #undef __
2591
2592 void MacroAssembler::MinNaNCheck_d(FPURegister dst, FPURegister src1,
2593 FPURegister src2, Label* nan) {
2594 if (nan) {
2595 BranchF64(nullptr, nan, eq, src1, src2);
2596 }
2597 if (kArchVariant >= kMips64r6) {
2598 min_d(dst, src1, src2);
2599 } else {
2600 Label skip;
2601 if (!ZeroHelper_d(this, MaxMinKind::kMin, dst, src1, src2, &skip)) {
2602 if (dst.is(src1)) {
2603 BranchF64(&skip, nullptr, le, src1, src2);
2604 Move_d(dst, src2);
2605 } else if (dst.is(src2)) {
2606 BranchF64(&skip, nullptr, ge, src1, src2);
2607 Move_d(dst, src1);
2608 } else {
2609 Label right;
2610 BranchF64(&right, nullptr, gt, src1, src2);
2611 Move_d(dst, src1);
2612 Branch(&skip);
2613 bind(&right);
2614 Move_d(dst, src2);
2615 }
2616 }
2617 bind(&skip);
2618 }
2619 }
2620
2621 void MacroAssembler::MaxNaNCheck_d(FPURegister dst, FPURegister src1,
2622 FPURegister src2, Label* nan) {
2623 if (nan) {
2624 BranchF64(nullptr, nan, eq, src1, src2);
2625 }
2626 if (kArchVariant >= kMips64r6) {
2627 max_d(dst, src1, src2);
2628 } else {
2629 Label skip;
2630 if (!ZeroHelper_d(this, MaxMinKind::kMax, dst, src1, src2, &skip)) {
2631 if (dst.is(src1)) {
2632 BranchF64(&skip, nullptr, ge, src1, src2);
2633 Move_d(dst, src2);
2634 } else if (dst.is(src2)) {
2635 BranchF64(&skip, nullptr, le, src1, src2);
2636 Move_d(dst, src1);
2637 } else {
2638 Label right;
2639 BranchF64(&right, nullptr, lt, src1, src2);
2640 Move_d(dst, src1);
2641 Branch(&skip);
2642 bind(&right);
2643 Move_d(dst, src2);
2644 }
2645 }
2646 bind(&skip);
2647 }
2648 }
2649
2650 void MacroAssembler::MinNaNCheck_s(FPURegister dst, FPURegister src1,
2651 FPURegister src2, Label* nan) {
2652 if (nan) {
2653 BranchF32(nullptr, nan, eq, src1, src2);
2654 }
2655 if (kArchVariant >= kMips64r6) {
2656 min_s(dst, src1, src2);
2657 } else {
2658 Label skip;
2659 if (!ZeroHelper_s(this, MaxMinKind::kMin, dst, src1, src2, &skip)) {
2660 if (dst.is(src1)) {
2661 BranchF32(&skip, nullptr, le, src1, src2);
2662 Move_s(dst, src2);
2663 } else if (dst.is(src2)) {
2664 BranchF32(&skip, nullptr, ge, src1, src2);
2665 Move_s(dst, src1);
2666 } else {
2667 Label right;
2668 BranchF32(&right, nullptr, gt, src1, src2);
2669 Move_s(dst, src1);
2670 Branch(&skip);
2671 bind(&right);
2672 Move_s(dst, src2);
2673 }
2674 }
2675 bind(&skip);
2676 }
2677 }
2678
2679 void MacroAssembler::MaxNaNCheck_s(FPURegister dst, FPURegister src1,
2680 FPURegister src2, Label* nan) {
2681 if (nan) {
2682 BranchF32(nullptr, nan, eq, src1, src2);
2683 }
2684 if (kArchVariant >= kMips64r6) {
2685 max_s(dst, src1, src2);
2686 } else {
2687 Label skip;
2688 if (!ZeroHelper_s(this, MaxMinKind::kMax, dst, src1, src2, &skip)) {
2689 if (dst.is(src1)) {
2690 BranchF32(&skip, nullptr, ge, src1, src2);
2691 Move_s(dst, src2);
2692 } else if (dst.is(src2)) {
2693 BranchF32(&skip, nullptr, le, src1, src2);
2694 Move_s(dst, src1);
2695 } else {
2696 Label right;
2697 BranchF32(&right, nullptr, lt, src1, src2);
2698 Move_s(dst, src1);
2699 Branch(&skip);
2700 bind(&right);
2701 Move_s(dst, src2);
2702 }
2703 }
2704 bind(&skip);
2705 }
2706 }
2707 2527
2708 void MacroAssembler::Clz(Register rd, Register rs) { 2528 void MacroAssembler::Clz(Register rd, Register rs) {
2709 clz(rd, rs); 2529 clz(rd, rs);
2710 } 2530 }
2711 2531
2712 2532
2713 void MacroAssembler::EmitFPUTruncate(FPURoundingMode rounding_mode, 2533 void MacroAssembler::EmitFPUTruncate(FPURoundingMode rounding_mode,
2714 Register result, 2534 Register result,
2715 DoubleRegister double_input, 2535 DoubleRegister double_input,
2716 Register scratch, 2536 Register scratch,
(...skipping 3756 matching lines...) Expand 10 before | Expand all | Expand 10 after
6473 Register scratch2, 6293 Register scratch2,
6474 Label* failure) { 6294 Label* failure) {
6475 // Check that neither is a smi. 6295 // Check that neither is a smi.
6476 STATIC_ASSERT(kSmiTag == 0); 6296 STATIC_ASSERT(kSmiTag == 0);
6477 And(scratch1, first, Operand(second)); 6297 And(scratch1, first, Operand(second));
6478 JumpIfSmi(scratch1, failure); 6298 JumpIfSmi(scratch1, failure);
6479 JumpIfNonSmisNotBothSequentialOneByteStrings(first, second, scratch1, 6299 JumpIfNonSmisNotBothSequentialOneByteStrings(first, second, scratch1,
6480 scratch2, failure); 6300 scratch2, failure);
6481 } 6301 }
6482 6302
6303 void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1,
6304 FPURegister src2, Label* out_of_line) {
6305 DCHECK(!src1.is(src2));
6306
6307 // Check if one of operands is NaN.
6308 BranchF32(nullptr, out_of_line, eq, src1, src2);
6309
6310 if (kArchVariant >= kMips64r6) {
6311 max_s(dst, src1, src2);
6312 } else {
6313 Label return_left, return_right, done;
6314
6315 c(OLT, S, src1, src2);
6316 bc1t(&return_right);
6317 nop();
6318
6319 c(OLT, S, src2, src1);
6320 bc1t(&return_left);
6321 nop();
6322
6323 // Operands are equal, but check for +/-0.
6324 mfc1(t8, src1);
6325 dsll32(t8, t8, 0);
6326 beq(t8, zero_reg, &return_left);
6327 nop();
6328 b(&return_right);
6329 nop();
6330
6331 bind(&return_right);
6332 if (!src2.is(dst)) {
6333 Move_s(dst, src2);
6334 }
6335 b(&done);
6336 nop();
6337
6338 bind(&return_left);
6339 if (!src1.is(dst)) {
6340 Move_s(dst, src1);
6341 }
6342
6343 bind(&done);
6344 }
6345 }
6346
6347 void MacroAssembler::Float32MaxOutOfLine(FPURegister dst, FPURegister src1,
6348 FPURegister src2) {
6349 DCHECK(!src1.is(src2));
6350 add_s(dst, src1, src2);
6351 }
6352
6353 void MacroAssembler::Float32Min(FPURegister dst, FPURegister src1,
6354 FPURegister src2, Label* out_of_line) {
6355 DCHECK(!src1.is(src2));
6356
6357 // Check if one of operands is NaN.
6358 BranchF32(nullptr, out_of_line, eq, src1, src2);
6359
6360 if (kArchVariant >= kMips64r6) {
6361 min_s(dst, src1, src2);
6362 } else {
6363 Label return_left, return_right, done;
6364
6365 c(OLT, S, src1, src2);
6366 bc1t(&return_left);
6367 nop();
6368
6369 c(OLT, S, src2, src1);
6370 bc1t(&return_right);
6371 nop();
6372
6373 // Left equals right => check for -0.
6374 mfc1(t8, src1);
6375 dsll32(t8, t8, 0);
6376 beq(t8, zero_reg, &return_right);
6377 nop();
6378 b(&return_left);
6379 nop();
6380
6381 bind(&return_right);
6382 if (!src2.is(dst)) {
6383 Move_s(dst, src2);
6384 }
6385 b(&done);
6386 nop();
6387
6388 bind(&return_left);
6389 if (!src1.is(dst)) {
6390 Move_s(dst, src1);
6391 }
6392
6393 bind(&done);
6394 }
6395 }
6396
6397 void MacroAssembler::Float32MinOutOfLine(FPURegister dst, FPURegister src1,
6398 FPURegister src2) {
6399 DCHECK(!src1.is(src2));
6400 add_s(dst, src1, src2);
6401 }
6402
6403 void MacroAssembler::Float64Max(FPURegister dst, FPURegister src1,
6404 FPURegister src2, Label* out_of_line) {
6405 DCHECK(!src1.is(src2));
6406
6407 // Check if one of operands is NaN.
6408 BranchF64(nullptr, out_of_line, eq, src1, src2);
6409
6410 if (kArchVariant >= kMips64r6) {
6411 max_d(dst, src1, src2);
6412 } else {
6413 Label return_left, return_right, done;
6414
6415 c(OLT, D, src1, src2);
6416 bc1t(&return_right);
6417 nop();
6418
6419 c(OLT, D, src2, src1);
6420 bc1t(&return_left);
6421 nop();
6422
6423 // Left equals right => check for -0.
6424 dmfc1(t8, src1);
6425 beq(t8, zero_reg, &return_left);
6426 nop();
6427 b(&return_right);
6428 nop();
6429
6430 bind(&return_right);
6431 if (!src2.is(dst)) {
6432 Move_d(dst, src2);
6433 }
6434 b(&done);
6435 nop();
6436
6437 bind(&return_left);
6438 if (!src1.is(dst)) {
6439 Move_d(dst, src1);
6440 }
6441
6442 bind(&done);
6443 }
6444 }
6445
6446 void MacroAssembler::Float64MaxOutOfLine(FPURegister dst, FPURegister src1,
6447 FPURegister src2) {
6448 DCHECK(!src1.is(src2));
6449 add_d(dst, src1, src2);
6450 }
6451
6452 void MacroAssembler::Float64Min(FPURegister dst, FPURegister src1,
6453 FPURegister src2, Label* out_of_line) {
6454 DCHECK(!src1.is(src2));
6455
6456 // Check if one of operands is NaN.
6457 BranchF64(nullptr, out_of_line, eq, src1, src2);
6458
6459 if (kArchVariant >= kMips64r6) {
6460 min_d(dst, src1, src2);
6461 } else {
6462 Label return_left, return_right, done;
6463
6464 c(OLT, D, src1, src2);
6465 bc1t(&return_left);
6466 nop();
6467
6468 c(OLT, D, src2, src1);
6469 bc1t(&return_right);
6470 nop();
6471
6472 // Left equals right => check for -0.
6473 dmfc1(t8, src1);
6474 beq(t8, zero_reg, &return_right);
6475 nop();
6476 b(&return_left);
6477 nop();
6478
6479 bind(&return_right);
6480 if (!src2.is(dst)) {
6481 Move_d(dst, src2);
6482 }
6483 b(&done);
6484 nop();
6485
6486 bind(&return_left);
6487 if (!src1.is(dst)) {
6488 Move_d(dst, src1);
6489 }
6490
6491 bind(&done);
6492 }
6493 }
6494
6495 void MacroAssembler::Float64MinOutOfLine(FPURegister dst, FPURegister src1,
6496 FPURegister src2) {
6497 DCHECK(!src1.is(src2));
6498 add_d(dst, src1, src2);
6499 }
6483 6500
6484 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( 6501 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte(
6485 Register first, Register second, Register scratch1, Register scratch2, 6502 Register first, Register second, Register scratch1, Register scratch2,
6486 Label* failure) { 6503 Label* failure) {
6487 const int kFlatOneByteStringMask = 6504 const int kFlatOneByteStringMask =
6488 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; 6505 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
6489 const int kFlatOneByteStringTag = 6506 const int kFlatOneByteStringTag =
6490 kStringTag | kOneByteStringTag | kSeqStringTag; 6507 kStringTag | kOneByteStringTag | kSeqStringTag;
6491 DCHECK(kFlatOneByteStringTag <= 0xffff); // Ensure this fits 16-bit immed. 6508 DCHECK(kFlatOneByteStringTag <= 0xffff); // Ensure this fits 16-bit immed.
6492 andi(scratch1, first, kFlatOneByteStringMask); 6509 andi(scratch1, first, kFlatOneByteStringMask);
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
7028 if (mag.shift > 0) sra(result, result, mag.shift); 7045 if (mag.shift > 0) sra(result, result, mag.shift);
7029 srl(at, dividend, 31); 7046 srl(at, dividend, 31);
7030 Addu(result, result, Operand(at)); 7047 Addu(result, result, Operand(at));
7031 } 7048 }
7032 7049
7033 7050
7034 } // namespace internal 7051 } // namespace internal
7035 } // namespace v8 7052 } // namespace v8
7036 7053
7037 #endif // V8_TARGET_ARCH_MIPS64 7054 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/macro-assembler-mips64.h ('k') | test/cctest/compiler/test-run-machops.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698