OLD | NEW |
1 | 1 |
2 // Copyright 2012 the V8 project authors. All rights reserved. | 2 // Copyright 2012 the V8 project authors. All rights reserved. |
3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
5 | 5 |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 2356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2367 BranchDelaySlot bdslot) { | 2367 BranchDelaySlot bdslot) { |
2368 DCHECK(L == nullptr || offset == 0); | 2368 DCHECK(L == nullptr || offset == 0); |
2369 if (!is_near(L, OffsetSize::kOffset16)) return false; | 2369 if (!is_near(L, OffsetSize::kOffset16)) return false; |
2370 | 2370 |
2371 Register scratch = at; | 2371 Register scratch = at; |
2372 int32_t offset32; | 2372 int32_t offset32; |
2373 | 2373 |
2374 // Be careful to always use shifted_branch_offset only just before the | 2374 // Be careful to always use shifted_branch_offset only just before the |
2375 // branch instruction, as the location will be remember for patching the | 2375 // branch instruction, as the location will be remember for patching the |
2376 // target. | 2376 // target. |
2377 BlockTrampolinePoolScope block_trampoline_pool(this); | 2377 { |
2378 switch (cond) { | 2378 BlockTrampolinePoolScope block_trampoline_pool(this); |
2379 case cc_always: | 2379 switch (cond) { |
2380 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | 2380 case cc_always: |
2381 b(offset32); | |
2382 break; | |
2383 case eq: | |
2384 if (IsZero(rt)) { | |
2385 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2386 beq(rs, zero_reg, offset32); | |
2387 } else { | |
2388 // We don't want any other register but scratch clobbered. | |
2389 scratch = GetRtAsRegisterHelper(rt, scratch); | |
2390 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2391 beq(rs, scratch, offset32); | |
2392 } | |
2393 break; | |
2394 case ne: | |
2395 if (IsZero(rt)) { | |
2396 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2397 bne(rs, zero_reg, offset32); | |
2398 } else { | |
2399 // We don't want any other register but scratch clobbered. | |
2400 scratch = GetRtAsRegisterHelper(rt, scratch); | |
2401 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2402 bne(rs, scratch, offset32); | |
2403 } | |
2404 break; | |
2405 | |
2406 // Signed comparison. | |
2407 case greater: | |
2408 if (IsZero(rt)) { | |
2409 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2410 bgtz(rs, offset32); | |
2411 } else { | |
2412 Slt(scratch, GetRtAsRegisterHelper(rt, scratch), rs); | |
2413 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2414 bne(scratch, zero_reg, offset32); | |
2415 } | |
2416 break; | |
2417 case greater_equal: | |
2418 if (IsZero(rt)) { | |
2419 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2420 bgez(rs, offset32); | |
2421 } else { | |
2422 Slt(scratch, rs, rt); | |
2423 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2424 beq(scratch, zero_reg, offset32); | |
2425 } | |
2426 break; | |
2427 case less: | |
2428 if (IsZero(rt)) { | |
2429 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2430 bltz(rs, offset32); | |
2431 } else { | |
2432 Slt(scratch, rs, rt); | |
2433 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2434 bne(scratch, zero_reg, offset32); | |
2435 } | |
2436 break; | |
2437 case less_equal: | |
2438 if (IsZero(rt)) { | |
2439 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2440 blez(rs, offset32); | |
2441 } else { | |
2442 Slt(scratch, GetRtAsRegisterHelper(rt, scratch), rs); | |
2443 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2444 beq(scratch, zero_reg, offset32); | |
2445 } | |
2446 break; | |
2447 | |
2448 // Unsigned comparison. | |
2449 case Ugreater: | |
2450 if (IsZero(rt)) { | |
2451 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2452 bne(rs, zero_reg, offset32); | |
2453 } else { | |
2454 Sltu(scratch, GetRtAsRegisterHelper(rt, scratch), rs); | |
2455 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | |
2456 bne(scratch, zero_reg, offset32); | |
2457 } | |
2458 break; | |
2459 case Ugreater_equal: | |
2460 if (IsZero(rt)) { | |
2461 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | 2381 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
2462 b(offset32); | 2382 b(offset32); |
2463 } else { | 2383 break; |
2464 Sltu(scratch, rs, rt); | 2384 case eq: |
2465 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | 2385 if (IsZero(rt)) { |
2466 beq(scratch, zero_reg, offset32); | 2386 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
2467 } | 2387 beq(rs, zero_reg, offset32); |
2468 break; | 2388 } else { |
2469 case Uless: | 2389 // We don't want any other register but scratch clobbered. |
2470 if (IsZero(rt)) { | 2390 scratch = GetRtAsRegisterHelper(rt, scratch); |
2471 return true; // No code needs to be emitted. | 2391 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
2472 } else { | 2392 beq(rs, scratch, offset32); |
2473 Sltu(scratch, rs, rt); | 2393 } |
2474 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | 2394 break; |
2475 bne(scratch, zero_reg, offset32); | 2395 case ne: |
2476 } | 2396 if (IsZero(rt)) { |
2477 break; | 2397 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
2478 case Uless_equal: | 2398 bne(rs, zero_reg, offset32); |
2479 if (IsZero(rt)) { | 2399 } else { |
2480 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | 2400 // We don't want any other register but scratch clobbered. |
2481 beq(rs, zero_reg, offset32); | 2401 scratch = GetRtAsRegisterHelper(rt, scratch); |
2482 } else { | 2402 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
2483 Sltu(scratch, GetRtAsRegisterHelper(rt, scratch), rs); | 2403 bne(rs, scratch, offset32); |
2484 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); | 2404 } |
2485 beq(scratch, zero_reg, offset32); | 2405 break; |
2486 } | 2406 |
2487 break; | 2407 // Signed comparison. |
2488 default: | 2408 case greater: |
2489 UNREACHABLE(); | 2409 if (IsZero(rt)) { |
| 2410 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2411 bgtz(rs, offset32); |
| 2412 } else { |
| 2413 Slt(scratch, GetRtAsRegisterHelper(rt, scratch), rs); |
| 2414 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2415 bne(scratch, zero_reg, offset32); |
| 2416 } |
| 2417 break; |
| 2418 case greater_equal: |
| 2419 if (IsZero(rt)) { |
| 2420 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2421 bgez(rs, offset32); |
| 2422 } else { |
| 2423 Slt(scratch, rs, rt); |
| 2424 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2425 beq(scratch, zero_reg, offset32); |
| 2426 } |
| 2427 break; |
| 2428 case less: |
| 2429 if (IsZero(rt)) { |
| 2430 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2431 bltz(rs, offset32); |
| 2432 } else { |
| 2433 Slt(scratch, rs, rt); |
| 2434 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2435 bne(scratch, zero_reg, offset32); |
| 2436 } |
| 2437 break; |
| 2438 case less_equal: |
| 2439 if (IsZero(rt)) { |
| 2440 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2441 blez(rs, offset32); |
| 2442 } else { |
| 2443 Slt(scratch, GetRtAsRegisterHelper(rt, scratch), rs); |
| 2444 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2445 beq(scratch, zero_reg, offset32); |
| 2446 } |
| 2447 break; |
| 2448 |
| 2449 // Unsigned comparison. |
| 2450 case Ugreater: |
| 2451 if (IsZero(rt)) { |
| 2452 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2453 bne(rs, zero_reg, offset32); |
| 2454 } else { |
| 2455 Sltu(scratch, GetRtAsRegisterHelper(rt, scratch), rs); |
| 2456 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2457 bne(scratch, zero_reg, offset32); |
| 2458 } |
| 2459 break; |
| 2460 case Ugreater_equal: |
| 2461 if (IsZero(rt)) { |
| 2462 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2463 b(offset32); |
| 2464 } else { |
| 2465 Sltu(scratch, rs, rt); |
| 2466 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2467 beq(scratch, zero_reg, offset32); |
| 2468 } |
| 2469 break; |
| 2470 case Uless: |
| 2471 if (IsZero(rt)) { |
| 2472 return true; // No code needs to be emitted. |
| 2473 } else { |
| 2474 Sltu(scratch, rs, rt); |
| 2475 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2476 bne(scratch, zero_reg, offset32); |
| 2477 } |
| 2478 break; |
| 2479 case Uless_equal: |
| 2480 if (IsZero(rt)) { |
| 2481 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2482 beq(rs, zero_reg, offset32); |
| 2483 } else { |
| 2484 Sltu(scratch, GetRtAsRegisterHelper(rt, scratch), rs); |
| 2485 offset32 = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2486 beq(scratch, zero_reg, offset32); |
| 2487 } |
| 2488 break; |
| 2489 default: |
| 2490 UNREACHABLE(); |
| 2491 } |
2490 } | 2492 } |
2491 | |
2492 // Emit a nop in the branch delay slot if required. | 2493 // Emit a nop in the branch delay slot if required. |
2493 if (bdslot == PROTECT) | 2494 if (bdslot == PROTECT) |
2494 nop(); | 2495 nop(); |
2495 | 2496 |
2496 return true; | 2497 return true; |
2497 } | 2498 } |
2498 | 2499 |
2499 | 2500 |
2500 bool MacroAssembler::BranchShortCheck(int32_t offset, Label* L, Condition cond, | 2501 bool MacroAssembler::BranchShortCheck(int32_t offset, Label* L, Condition cond, |
2501 Register rs, const Operand& rt, | 2502 Register rs, const Operand& rt, |
(...skipping 3351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5853 if (mag.shift > 0) sra(result, result, mag.shift); | 5854 if (mag.shift > 0) sra(result, result, mag.shift); |
5854 srl(at, dividend, 31); | 5855 srl(at, dividend, 31); |
5855 Addu(result, result, Operand(at)); | 5856 Addu(result, result, Operand(at)); |
5856 } | 5857 } |
5857 | 5858 |
5858 | 5859 |
5859 } // namespace internal | 5860 } // namespace internal |
5860 } // namespace v8 | 5861 } // namespace v8 |
5861 | 5862 |
5862 #endif // V8_TARGET_ARCH_MIPS | 5863 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |