| 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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
| 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 2307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2318 srl(scratch, scratch, 16); | 2318 srl(scratch, scratch, 16); |
| 2319 andi(scratch, scratch, 0x0080); | 2319 andi(scratch, scratch, 0x0080); |
| 2320 Branch(&done, ne, scratch, Operand(zero_reg)); | 2320 Branch(&done, ne, scratch, Operand(zero_reg)); |
| 2321 mov(rd, rs); | 2321 mov(rd, rs); |
| 2322 bind(&done); | 2322 bind(&done); |
| 2323 } else { | 2323 } else { |
| 2324 movf(rd, rs, cc); | 2324 movf(rd, rs, cc); |
| 2325 } | 2325 } |
| 2326 } | 2326 } |
| 2327 | 2327 |
| 2328 #define __ masm-> | |
| 2329 | |
| 2330 static bool ZeroHelper_d(MacroAssembler* masm, MaxMinKind kind, FPURegister dst, | |
| 2331 FPURegister src1, FPURegister src2, Label* equal) { | |
| 2332 if (src1.is(src2)) { | |
| 2333 __ Move(dst, src1); | |
| 2334 return true; | |
| 2335 } | |
| 2336 | |
| 2337 Label other, compare_not_equal; | |
| 2338 FPURegister left, right; | |
| 2339 if (kind == MaxMinKind::kMin) { | |
| 2340 left = src1; | |
| 2341 right = src2; | |
| 2342 } else { | |
| 2343 left = src2; | |
| 2344 right = src1; | |
| 2345 } | |
| 2346 | |
| 2347 __ BranchF64(&compare_not_equal, nullptr, ne, src1, src2); | |
| 2348 // Left and right hand side are equal, check for -0 vs. +0. | |
| 2349 __ FmoveHigh(t8, src1); | |
| 2350 __ Branch(&other, eq, t8, Operand(0x80000000)); | |
| 2351 __ Move_d(dst, right); | |
| 2352 __ Branch(equal); | |
| 2353 __ bind(&other); | |
| 2354 __ Move_d(dst, left); | |
| 2355 __ Branch(equal); | |
| 2356 __ bind(&compare_not_equal); | |
| 2357 return false; | |
| 2358 } | |
| 2359 | |
| 2360 static bool ZeroHelper_s(MacroAssembler* masm, MaxMinKind kind, FPURegister dst, | |
| 2361 FPURegister src1, FPURegister src2, Label* equal) { | |
| 2362 if (src1.is(src2)) { | |
| 2363 __ Move(dst, src1); | |
| 2364 return true; | |
| 2365 } | |
| 2366 | |
| 2367 Label other, compare_not_equal; | |
| 2368 FPURegister left, right; | |
| 2369 if (kind == MaxMinKind::kMin) { | |
| 2370 left = src1; | |
| 2371 right = src2; | |
| 2372 } else { | |
| 2373 left = src2; | |
| 2374 right = src1; | |
| 2375 } | |
| 2376 | |
| 2377 __ BranchF32(&compare_not_equal, nullptr, ne, src1, src2); | |
| 2378 // Left and right hand side are equal, check for -0 vs. +0. | |
| 2379 __ FmoveLow(t8, src1); | |
| 2380 __ Branch(&other, eq, t8, Operand(0x80000000)); | |
| 2381 __ Move_s(dst, right); | |
| 2382 __ Branch(equal); | |
| 2383 __ bind(&other); | |
| 2384 __ Move_s(dst, left); | |
| 2385 __ Branch(equal); | |
| 2386 __ bind(&compare_not_equal); | |
| 2387 return false; | |
| 2388 } | |
| 2389 | |
| 2390 #undef __ | |
| 2391 | |
| 2392 void MacroAssembler::MinNaNCheck_d(FPURegister dst, FPURegister src1, | |
| 2393 FPURegister src2, Label* nan) { | |
| 2394 if (nan) { | |
| 2395 BranchF64(nullptr, nan, eq, src1, src2); | |
| 2396 } | |
| 2397 if (IsMipsArchVariant(kMips32r6)) { | |
| 2398 min_d(dst, src1, src2); | |
| 2399 } else { | |
| 2400 Label skip; | |
| 2401 if (!ZeroHelper_d(this, MaxMinKind::kMin, dst, src1, src2, &skip)) { | |
| 2402 if (dst.is(src1)) { | |
| 2403 BranchF64(&skip, nullptr, le, src1, src2); | |
| 2404 Move_d(dst, src2); | |
| 2405 } else if (dst.is(src2)) { | |
| 2406 BranchF64(&skip, nullptr, ge, src1, src2); | |
| 2407 Move_d(dst, src1); | |
| 2408 } else { | |
| 2409 Label right; | |
| 2410 BranchF64(&right, nullptr, gt, src1, src2); | |
| 2411 Move_d(dst, src1); | |
| 2412 Branch(&skip); | |
| 2413 bind(&right); | |
| 2414 Move_d(dst, src2); | |
| 2415 } | |
| 2416 } | |
| 2417 bind(&skip); | |
| 2418 } | |
| 2419 } | |
| 2420 | |
| 2421 void MacroAssembler::MaxNaNCheck_d(FPURegister dst, FPURegister src1, | |
| 2422 FPURegister src2, Label* nan) { | |
| 2423 if (nan) { | |
| 2424 BranchF64(nullptr, nan, eq, src1, src2); | |
| 2425 } | |
| 2426 if (IsMipsArchVariant(kMips32r6)) { | |
| 2427 max_d(dst, src1, src2); | |
| 2428 } else { | |
| 2429 Label skip; | |
| 2430 if (!ZeroHelper_d(this, MaxMinKind::kMax, dst, src1, src2, &skip)) { | |
| 2431 if (dst.is(src1)) { | |
| 2432 BranchF64(&skip, nullptr, ge, src1, src2); | |
| 2433 Move_d(dst, src2); | |
| 2434 } else if (dst.is(src2)) { | |
| 2435 BranchF64(&skip, nullptr, le, src1, src2); | |
| 2436 Move_d(dst, src1); | |
| 2437 } else { | |
| 2438 Label right; | |
| 2439 BranchF64(&right, nullptr, lt, src1, src2); | |
| 2440 Move_d(dst, src1); | |
| 2441 Branch(&skip); | |
| 2442 bind(&right); | |
| 2443 Move_d(dst, src2); | |
| 2444 } | |
| 2445 } | |
| 2446 bind(&skip); | |
| 2447 } | |
| 2448 } | |
| 2449 | |
| 2450 void MacroAssembler::MinNaNCheck_s(FPURegister dst, FPURegister src1, | |
| 2451 FPURegister src2, Label* nan) { | |
| 2452 if (nan) { | |
| 2453 BranchF32(nullptr, nan, eq, src1, src2); | |
| 2454 } | |
| 2455 if (IsMipsArchVariant(kMips32r6)) { | |
| 2456 min_s(dst, src1, src2); | |
| 2457 } else { | |
| 2458 Label skip; | |
| 2459 if (!ZeroHelper_s(this, MaxMinKind::kMin, dst, src1, src2, &skip)) { | |
| 2460 if (dst.is(src1)) { | |
| 2461 BranchF32(&skip, nullptr, le, src1, src2); | |
| 2462 Move_s(dst, src2); | |
| 2463 } else if (dst.is(src2)) { | |
| 2464 BranchF32(&skip, nullptr, ge, src1, src2); | |
| 2465 Move_s(dst, src1); | |
| 2466 } else { | |
| 2467 Label right; | |
| 2468 BranchF32(&right, nullptr, gt, src1, src2); | |
| 2469 Move_s(dst, src1); | |
| 2470 Branch(&skip); | |
| 2471 bind(&right); | |
| 2472 Move_s(dst, src2); | |
| 2473 } | |
| 2474 } | |
| 2475 bind(&skip); | |
| 2476 } | |
| 2477 } | |
| 2478 | |
| 2479 void MacroAssembler::MaxNaNCheck_s(FPURegister dst, FPURegister src1, | |
| 2480 FPURegister src2, Label* nan) { | |
| 2481 if (nan) { | |
| 2482 BranchF32(nullptr, nan, eq, src1, src2); | |
| 2483 } | |
| 2484 if (IsMipsArchVariant(kMips32r6)) { | |
| 2485 max_s(dst, src1, src2); | |
| 2486 } else { | |
| 2487 Label skip; | |
| 2488 if (!ZeroHelper_s(this, MaxMinKind::kMax, dst, src1, src2, &skip)) { | |
| 2489 if (dst.is(src1)) { | |
| 2490 BranchF32(&skip, nullptr, ge, src1, src2); | |
| 2491 Move_s(dst, src2); | |
| 2492 } else if (dst.is(src2)) { | |
| 2493 BranchF32(&skip, nullptr, le, src1, src2); | |
| 2494 Move_s(dst, src1); | |
| 2495 } else { | |
| 2496 Label right; | |
| 2497 BranchF32(&right, nullptr, lt, src1, src2); | |
| 2498 Move_s(dst, src1); | |
| 2499 Branch(&skip); | |
| 2500 bind(&right); | |
| 2501 Move_s(dst, src2); | |
| 2502 } | |
| 2503 } | |
| 2504 bind(&skip); | |
| 2505 } | |
| 2506 } | |
| 2507 | |
| 2508 void MacroAssembler::Clz(Register rd, Register rs) { | 2328 void MacroAssembler::Clz(Register rd, Register rs) { |
| 2509 if (IsMipsArchVariant(kLoongson)) { | 2329 if (IsMipsArchVariant(kLoongson)) { |
| 2510 DCHECK(!(rd.is(t8) || rd.is(t9)) && !(rs.is(t8) || rs.is(t9))); | 2330 DCHECK(!(rd.is(t8) || rd.is(t9)) && !(rs.is(t8) || rs.is(t9))); |
| 2511 Register mask = t8; | 2331 Register mask = t8; |
| 2512 Register scratch = t9; | 2332 Register scratch = t9; |
| 2513 Label loop, end; | 2333 Label loop, end; |
| 2514 mov(at, rs); | 2334 mov(at, rs); |
| 2515 mov(rd, zero_reg); | 2335 mov(rd, zero_reg); |
| 2516 lui(mask, 0x8000); | 2336 lui(mask, 0x8000); |
| 2517 bind(&loop); | 2337 bind(&loop); |
| (...skipping 3532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6050 Register scratch2, | 5870 Register scratch2, |
| 6051 Label* failure) { | 5871 Label* failure) { |
| 6052 // Check that neither is a smi. | 5872 // Check that neither is a smi. |
| 6053 STATIC_ASSERT(kSmiTag == 0); | 5873 STATIC_ASSERT(kSmiTag == 0); |
| 6054 And(scratch1, first, Operand(second)); | 5874 And(scratch1, first, Operand(second)); |
| 6055 JumpIfSmi(scratch1, failure); | 5875 JumpIfSmi(scratch1, failure); |
| 6056 JumpIfNonSmisNotBothSequentialOneByteStrings(first, second, scratch1, | 5876 JumpIfNonSmisNotBothSequentialOneByteStrings(first, second, scratch1, |
| 6057 scratch2, failure); | 5877 scratch2, failure); |
| 6058 } | 5878 } |
| 6059 | 5879 |
| 5880 void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1, |
| 5881 FPURegister src2, Label* out_of_line) { |
| 5882 DCHECK(!src1.is(src2)); |
| 5883 |
| 5884 // Check if one of operands is NaN. |
| 5885 BranchF32(nullptr, out_of_line, eq, src1, src2); |
| 5886 |
| 5887 if (IsMipsArchVariant(kMips32r6)) { |
| 5888 max_s(dst, src1, src2); |
| 5889 } else { |
| 5890 Label return_left, return_right, done; |
| 5891 |
| 5892 c(OLT, S, src1, src2); |
| 5893 bc1t(&return_right); |
| 5894 nop(); |
| 5895 |
| 5896 c(OLT, S, src2, src1); |
| 5897 bc1t(&return_left); |
| 5898 nop(); |
| 5899 |
| 5900 // Operands are equal, but check for +/-0. |
| 5901 mfc1(t8, src1); |
| 5902 beq(t8, zero_reg, &return_left); |
| 5903 nop(); |
| 5904 b(&return_right); |
| 5905 nop(); |
| 5906 |
| 5907 bind(&return_right); |
| 5908 if (!src2.is(dst)) { |
| 5909 Move_s(dst, src2); |
| 5910 } |
| 5911 b(&done); |
| 5912 nop(); |
| 5913 |
| 5914 bind(&return_left); |
| 5915 if (!src1.is(dst)) { |
| 5916 Move_s(dst, src1); |
| 5917 } |
| 5918 |
| 5919 bind(&done); |
| 5920 } |
| 5921 } |
| 5922 |
| 5923 void MacroAssembler::Float32MaxOutOfLine(FPURegister dst, FPURegister src1, |
| 5924 FPURegister src2) { |
| 5925 DCHECK(!src1.is(src2)); |
| 5926 add_s(dst, src1, src2); |
| 5927 } |
| 5928 |
| 5929 void MacroAssembler::Float32Min(FPURegister dst, FPURegister src1, |
| 5930 FPURegister src2, Label* out_of_line) { |
| 5931 DCHECK(!src1.is(src2)); |
| 5932 |
| 5933 // Check if one of operands is NaN. |
| 5934 BranchF32(nullptr, out_of_line, eq, src1, src2); |
| 5935 |
| 5936 if (IsMipsArchVariant(kMips32r6)) { |
| 5937 min_s(dst, src1, src2); |
| 5938 } else { |
| 5939 Label return_left, return_right, done; |
| 5940 |
| 5941 c(OLT, S, src1, src2); |
| 5942 bc1t(&return_left); |
| 5943 nop(); |
| 5944 |
| 5945 c(OLT, S, src2, src1); |
| 5946 bc1t(&return_right); |
| 5947 nop(); |
| 5948 |
| 5949 // Left equals right => check for -0. |
| 5950 mfc1(t8, src1); |
| 5951 beq(t8, zero_reg, &return_right); |
| 5952 nop(); |
| 5953 b(&return_left); |
| 5954 nop(); |
| 5955 |
| 5956 bind(&return_right); |
| 5957 if (!src2.is(dst)) { |
| 5958 Move_s(dst, src2); |
| 5959 } |
| 5960 b(&done); |
| 5961 nop(); |
| 5962 |
| 5963 bind(&return_left); |
| 5964 if (!src1.is(dst)) { |
| 5965 Move_s(dst, src1); |
| 5966 } |
| 5967 |
| 5968 bind(&done); |
| 5969 } |
| 5970 } |
| 5971 |
| 5972 void MacroAssembler::Float32MinOutOfLine(FPURegister dst, FPURegister src1, |
| 5973 FPURegister src2) { |
| 5974 DCHECK(!src1.is(src2)); |
| 5975 add_s(dst, src1, src2); |
| 5976 } |
| 5977 |
| 5978 void MacroAssembler::Float64Max(DoubleRegister dst, DoubleRegister src1, |
| 5979 DoubleRegister src2, Label* out_of_line) { |
| 5980 DCHECK(!src1.is(src2)); |
| 5981 |
| 5982 // Check if one of operands is NaN. |
| 5983 BranchF64(nullptr, out_of_line, eq, src1, src2); |
| 5984 |
| 5985 if (IsMipsArchVariant(kMips32r6)) { |
| 5986 max_d(dst, src1, src2); |
| 5987 } else { |
| 5988 Label return_left, return_right, done; |
| 5989 |
| 5990 c(OLT, D, src1, src2); |
| 5991 bc1t(&return_right); |
| 5992 nop(); |
| 5993 |
| 5994 c(OLT, D, src2, src1); |
| 5995 bc1t(&return_left); |
| 5996 nop(); |
| 5997 |
| 5998 // Left equals right => check for -0. |
| 5999 Mfhc1(t8, src1); |
| 6000 beq(t8, zero_reg, &return_left); |
| 6001 nop(); |
| 6002 b(&return_right); |
| 6003 nop(); |
| 6004 |
| 6005 bind(&return_right); |
| 6006 if (!src2.is(dst)) { |
| 6007 Move_d(dst, src2); |
| 6008 } |
| 6009 b(&done); |
| 6010 nop(); |
| 6011 |
| 6012 bind(&return_left); |
| 6013 if (!src1.is(dst)) { |
| 6014 Move_d(dst, src1); |
| 6015 } |
| 6016 |
| 6017 bind(&done); |
| 6018 } |
| 6019 } |
| 6020 |
| 6021 void MacroAssembler::Float64MaxOutOfLine(DoubleRegister dst, |
| 6022 DoubleRegister src1, |
| 6023 DoubleRegister src2) { |
| 6024 DCHECK(!src1.is(src2)); |
| 6025 add_d(dst, src1, src2); |
| 6026 } |
| 6027 |
| 6028 void MacroAssembler::Float64Min(DoubleRegister dst, DoubleRegister src1, |
| 6029 DoubleRegister src2, Label* out_of_line) { |
| 6030 DCHECK(!src1.is(src2)); |
| 6031 |
| 6032 // Check if one of operands is NaN. |
| 6033 BranchF64(nullptr, out_of_line, eq, src1, src2); |
| 6034 |
| 6035 if (IsMipsArchVariant(kMips32r6)) { |
| 6036 min_d(dst, src1, src2); |
| 6037 } else { |
| 6038 Label return_left, return_right, done; |
| 6039 |
| 6040 c(OLT, D, src1, src2); |
| 6041 bc1t(&return_left); |
| 6042 nop(); |
| 6043 |
| 6044 c(OLT, D, src2, src1); |
| 6045 bc1t(&return_right); |
| 6046 nop(); |
| 6047 |
| 6048 // Left equals right => check for -0. |
| 6049 Mfhc1(t8, src1); |
| 6050 beq(t8, zero_reg, &return_right); |
| 6051 nop(); |
| 6052 b(&return_left); |
| 6053 nop(); |
| 6054 |
| 6055 bind(&return_right); |
| 6056 if (!src2.is(dst)) { |
| 6057 Move_d(dst, src2); |
| 6058 } |
| 6059 b(&done); |
| 6060 nop(); |
| 6061 |
| 6062 bind(&return_left); |
| 6063 if (!src1.is(dst)) { |
| 6064 Move_d(dst, src1); |
| 6065 } |
| 6066 |
| 6067 bind(&done); |
| 6068 } |
| 6069 } |
| 6070 |
| 6071 void MacroAssembler::Float64MinOutOfLine(DoubleRegister dst, |
| 6072 DoubleRegister src1, |
| 6073 DoubleRegister src2) { |
| 6074 DCHECK(!src1.is(src2)); |
| 6075 add_d(dst, src1, src2); |
| 6076 } |
| 6060 | 6077 |
| 6061 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( | 6078 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( |
| 6062 Register first, Register second, Register scratch1, Register scratch2, | 6079 Register first, Register second, Register scratch1, Register scratch2, |
| 6063 Label* failure) { | 6080 Label* failure) { |
| 6064 const int kFlatOneByteStringMask = | 6081 const int kFlatOneByteStringMask = |
| 6065 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 6082 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
| 6066 const int kFlatOneByteStringTag = | 6083 const int kFlatOneByteStringTag = |
| 6067 kStringTag | kOneByteStringTag | kSeqStringTag; | 6084 kStringTag | kOneByteStringTag | kSeqStringTag; |
| 6068 DCHECK(kFlatOneByteStringTag <= 0xffff); // Ensure this fits 16-bit immed. | 6085 DCHECK(kFlatOneByteStringTag <= 0xffff); // Ensure this fits 16-bit immed. |
| 6069 andi(scratch1, first, kFlatOneByteStringMask); | 6086 andi(scratch1, first, kFlatOneByteStringMask); |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6609 if (mag.shift > 0) sra(result, result, mag.shift); | 6626 if (mag.shift > 0) sra(result, result, mag.shift); |
| 6610 srl(at, dividend, 31); | 6627 srl(at, dividend, 31); |
| 6611 Addu(result, result, Operand(at)); | 6628 Addu(result, result, Operand(at)); |
| 6612 } | 6629 } |
| 6613 | 6630 |
| 6614 | 6631 |
| 6615 } // namespace internal | 6632 } // namespace internal |
| 6616 } // namespace v8 | 6633 } // namespace v8 |
| 6617 | 6634 |
| 6618 #endif // V8_TARGET_ARCH_MIPS | 6635 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |