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 |