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

Side by Side Diff: src/mips/macro-assembler-mips.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/mips/macro-assembler-mips.h ('k') | src/mips64/macro-assembler-mips64.h » ('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_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
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
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
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
OLDNEW
« no previous file with comments | « src/mips/macro-assembler-mips.h ('k') | src/mips64/macro-assembler-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698