OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |