| 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 1423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1434 // Check for unordered (NaN) cases. | 1434 // Check for unordered (NaN) cases. |
| 1435 if (nan) { | 1435 if (nan) { |
| 1436 bool long_branch = | 1436 bool long_branch = |
| 1437 nan->is_bound() ? is_near(nan) : is_trampoline_emitted(); | 1437 nan->is_bound() ? is_near(nan) : is_trampoline_emitted(); |
| 1438 if (!IsMipsArchVariant(kMips32r6)) { | 1438 if (!IsMipsArchVariant(kMips32r6)) { |
| 1439 if (long_branch) { | 1439 if (long_branch) { |
| 1440 Label skip; | 1440 Label skip; |
| 1441 c(UN, D, cmp1, cmp2); | 1441 c(UN, D, cmp1, cmp2); |
| 1442 bc1f(&skip); | 1442 bc1f(&skip); |
| 1443 nop(); | 1443 nop(); |
| 1444 Jr(nan, bd); | 1444 BranchLong(nan, bd); |
| 1445 bind(&skip); | 1445 bind(&skip); |
| 1446 } else { | 1446 } else { |
| 1447 c(UN, D, cmp1, cmp2); | 1447 c(UN, D, cmp1, cmp2); |
| 1448 bc1t(nan); | 1448 bc1t(nan); |
| 1449 if (bd == PROTECT) { | 1449 if (bd == PROTECT) { |
| 1450 nop(); | 1450 nop(); |
| 1451 } | 1451 } |
| 1452 } | 1452 } |
| 1453 } else { | 1453 } else { |
| 1454 // Use kDoubleCompareReg for comparison result. It has to be unavailable | 1454 // Use kDoubleCompareReg for comparison result. It has to be unavailable |
| 1455 // to lithium register allocator. | 1455 // to lithium register allocator. |
| 1456 DCHECK(!cmp1.is(kDoubleCompareReg) && !cmp2.is(kDoubleCompareReg)); | 1456 DCHECK(!cmp1.is(kDoubleCompareReg) && !cmp2.is(kDoubleCompareReg)); |
| 1457 if (long_branch) { | 1457 if (long_branch) { |
| 1458 Label skip; | 1458 Label skip; |
| 1459 cmp(UN, L, kDoubleCompareReg, cmp1, cmp2); | 1459 cmp(UN, L, kDoubleCompareReg, cmp1, cmp2); |
| 1460 bc1eqz(&skip, kDoubleCompareReg); | 1460 bc1eqz(&skip, kDoubleCompareReg); |
| 1461 nop(); | 1461 nop(); |
| 1462 Jr(nan, bd); | 1462 BranchLong(nan, bd); |
| 1463 bind(&skip); | 1463 bind(&skip); |
| 1464 } else { | 1464 } else { |
| 1465 cmp(UN, L, kDoubleCompareReg, cmp1, cmp2); | 1465 cmp(UN, L, kDoubleCompareReg, cmp1, cmp2); |
| 1466 bc1nez(nan, kDoubleCompareReg); | 1466 bc1nez(nan, kDoubleCompareReg); |
| 1467 if (bd == PROTECT) { | 1467 if (bd == PROTECT) { |
| 1468 nop(); | 1468 nop(); |
| 1469 } | 1469 } |
| 1470 } | 1470 } |
| 1471 } | 1471 } |
| 1472 } | 1472 } |
| 1473 | 1473 |
| 1474 if (target) { | 1474 if (target) { |
| 1475 bool long_branch = | 1475 bool long_branch = |
| 1476 target->is_bound() ? is_near(target) : is_trampoline_emitted(); | 1476 target->is_bound() ? is_near(target) : is_trampoline_emitted(); |
| 1477 if (long_branch) { | 1477 if (long_branch) { |
| 1478 Label skip; | 1478 Label skip; |
| 1479 Condition neg_cond = NegateFpuCondition(cond); | 1479 Condition neg_cond = NegateFpuCondition(cond); |
| 1480 BranchShortF(sizeField, &skip, neg_cond, cmp1, cmp2, bd); | 1480 BranchShortF(sizeField, &skip, neg_cond, cmp1, cmp2, bd); |
| 1481 Jr(target, bd); | 1481 BranchLong(target, bd); |
| 1482 bind(&skip); | 1482 bind(&skip); |
| 1483 } else { | 1483 } else { |
| 1484 BranchShortF(sizeField, target, cond, cmp1, cmp2, bd); | 1484 BranchShortF(sizeField, target, cond, cmp1, cmp2, bd); |
| 1485 } | 1485 } |
| 1486 } | 1486 } |
| 1487 } | 1487 } |
| 1488 } | 1488 } |
| 1489 | 1489 |
| 1490 void MacroAssembler::BranchShortF(SecondaryField sizeField, Label* target, | 1490 void MacroAssembler::BranchShortF(SecondaryField sizeField, Label* target, |
| 1491 Condition cc, FPURegister cmp1, | 1491 Condition cc, FPURegister cmp1, |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1950 DCHECK(is_near); | 1950 DCHECK(is_near); |
| 1951 USE(is_near); | 1951 USE(is_near); |
| 1952 } | 1952 } |
| 1953 | 1953 |
| 1954 | 1954 |
| 1955 void MacroAssembler::Branch(Label* L, BranchDelaySlot bdslot) { | 1955 void MacroAssembler::Branch(Label* L, BranchDelaySlot bdslot) { |
| 1956 if (L->is_bound()) { | 1956 if (L->is_bound()) { |
| 1957 if (is_near_branch(L)) { | 1957 if (is_near_branch(L)) { |
| 1958 BranchShort(L, bdslot); | 1958 BranchShort(L, bdslot); |
| 1959 } else { | 1959 } else { |
| 1960 Jr(L, bdslot); | 1960 BranchLong(L, bdslot); |
| 1961 } | 1961 } |
| 1962 } else { | 1962 } else { |
| 1963 if (is_trampoline_emitted()) { | 1963 if (is_trampoline_emitted()) { |
| 1964 Jr(L, bdslot); | 1964 BranchLong(L, bdslot); |
| 1965 } else { | 1965 } else { |
| 1966 BranchShort(L, bdslot); | 1966 BranchShort(L, bdslot); |
| 1967 } | 1967 } |
| 1968 } | 1968 } |
| 1969 } | 1969 } |
| 1970 | 1970 |
| 1971 | 1971 |
| 1972 void MacroAssembler::Branch(Label* L, Condition cond, Register rs, | 1972 void MacroAssembler::Branch(Label* L, Condition cond, Register rs, |
| 1973 const Operand& rt, | 1973 const Operand& rt, |
| 1974 BranchDelaySlot bdslot) { | 1974 BranchDelaySlot bdslot) { |
| 1975 if (L->is_bound()) { | 1975 if (L->is_bound()) { |
| 1976 if (!BranchShortCheck(0, L, cond, rs, rt, bdslot)) { | 1976 if (!BranchShortCheck(0, L, cond, rs, rt, bdslot)) { |
| 1977 if (cond != cc_always) { | 1977 if (cond != cc_always) { |
| 1978 Label skip; | 1978 Label skip; |
| 1979 Condition neg_cond = NegateCondition(cond); | 1979 Condition neg_cond = NegateCondition(cond); |
| 1980 BranchShort(&skip, neg_cond, rs, rt); | 1980 BranchShort(&skip, neg_cond, rs, rt); |
| 1981 Jr(L, bdslot); | 1981 BranchLong(L, bdslot); |
| 1982 bind(&skip); | 1982 bind(&skip); |
| 1983 } else { | 1983 } else { |
| 1984 Jr(L, bdslot); | 1984 BranchLong(L, bdslot); |
| 1985 } | 1985 } |
| 1986 } | 1986 } |
| 1987 } else { | 1987 } else { |
| 1988 if (is_trampoline_emitted()) { | 1988 if (is_trampoline_emitted()) { |
| 1989 if (cond != cc_always) { | 1989 if (cond != cc_always) { |
| 1990 Label skip; | 1990 Label skip; |
| 1991 Condition neg_cond = NegateCondition(cond); | 1991 Condition neg_cond = NegateCondition(cond); |
| 1992 BranchShort(&skip, neg_cond, rs, rt); | 1992 BranchShort(&skip, neg_cond, rs, rt); |
| 1993 Jr(L, bdslot); | 1993 BranchLong(L, bdslot); |
| 1994 bind(&skip); | 1994 bind(&skip); |
| 1995 } else { | 1995 } else { |
| 1996 Jr(L, bdslot); | 1996 BranchLong(L, bdslot); |
| 1997 } | 1997 } |
| 1998 } else { | 1998 } else { |
| 1999 BranchShort(L, cond, rs, rt, bdslot); | 1999 BranchShort(L, cond, rs, rt, bdslot); |
| 2000 } | 2000 } |
| 2001 } | 2001 } |
| 2002 } | 2002 } |
| 2003 | 2003 |
| 2004 | 2004 |
| 2005 void MacroAssembler::Branch(Label* L, | 2005 void MacroAssembler::Branch(Label* L, |
| 2006 Condition cond, | 2006 Condition cond, |
| 2007 Register rs, | 2007 Register rs, |
| 2008 Heap::RootListIndex index, | 2008 Heap::RootListIndex index, |
| 2009 BranchDelaySlot bdslot) { | 2009 BranchDelaySlot bdslot) { |
| 2010 LoadRoot(at, index); | 2010 LoadRoot(at, index); |
| 2011 Branch(L, cond, rs, Operand(at), bdslot); | 2011 Branch(L, cond, rs, Operand(at), bdslot); |
| 2012 } | 2012 } |
| 2013 | 2013 |
| 2014 | 2014 |
| 2015 void MacroAssembler::BranchShortHelper(int16_t offset, Label* L, | 2015 void MacroAssembler::BranchShortHelper(int16_t offset, Label* L, |
| 2016 BranchDelaySlot bdslot) { | 2016 BranchDelaySlot bdslot) { |
| 2017 DCHECK(L == nullptr || offset == 0); |
| 2017 offset = GetOffset(offset, L, OffsetSize::kOffset16); | 2018 offset = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2018 b(offset); | 2019 b(offset); |
| 2019 | 2020 |
| 2020 // Emit a nop in the branch delay slot if required. | 2021 // Emit a nop in the branch delay slot if required. |
| 2021 if (bdslot == PROTECT) | 2022 if (bdslot == PROTECT) |
| 2022 nop(); | 2023 nop(); |
| 2023 } | 2024 } |
| 2024 | 2025 |
| 2025 | 2026 |
| 2026 void MacroAssembler::BranchShortHelperR6(int32_t offset, Label* L) { | 2027 void MacroAssembler::BranchShortHelperR6(int32_t offset, Label* L) { |
| 2028 DCHECK(L == nullptr || offset == 0); |
| 2027 offset = GetOffset(offset, L, OffsetSize::kOffset26); | 2029 offset = GetOffset(offset, L, OffsetSize::kOffset26); |
| 2028 bc(offset); | 2030 bc(offset); |
| 2029 } | 2031 } |
| 2030 | 2032 |
| 2031 | 2033 |
| 2032 void MacroAssembler::BranchShort(int32_t offset, BranchDelaySlot bdslot) { | 2034 void MacroAssembler::BranchShort(int32_t offset, BranchDelaySlot bdslot) { |
| 2033 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) { | 2035 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) { |
| 2034 DCHECK(is_int26(offset)); | 2036 DCHECK(is_int26(offset)); |
| 2035 BranchShortHelperR6(offset, nullptr); | 2037 BranchShortHelperR6(offset, nullptr); |
| 2036 } else { | 2038 } else { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2078 li(r2, rt); | 2080 li(r2, rt); |
| 2079 } | 2081 } |
| 2080 | 2082 |
| 2081 return r2; | 2083 return r2; |
| 2082 } | 2084 } |
| 2083 | 2085 |
| 2084 | 2086 |
| 2085 bool MacroAssembler::BranchShortHelperR6(int32_t offset, Label* L, | 2087 bool MacroAssembler::BranchShortHelperR6(int32_t offset, Label* L, |
| 2086 Condition cond, Register rs, | 2088 Condition cond, Register rs, |
| 2087 const Operand& rt) { | 2089 const Operand& rt) { |
| 2090 DCHECK(L == nullptr || offset == 0); |
| 2088 Register scratch = rs.is(at) ? t8 : at; | 2091 Register scratch = rs.is(at) ? t8 : at; |
| 2089 OffsetSize bits = OffsetSize::kOffset16; | 2092 OffsetSize bits = OffsetSize::kOffset16; |
| 2090 | 2093 |
| 2091 // Be careful to always use shifted_branch_offset only just before the | 2094 // Be careful to always use shifted_branch_offset only just before the |
| 2092 // branch instruction, as the location will be remember for patching the | 2095 // branch instruction, as the location will be remember for patching the |
| 2093 // target. | 2096 // target. |
| 2094 BlockTrampolinePoolScope block_trampoline_pool(this); | 2097 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 2095 switch (cond) { | 2098 switch (cond) { |
| 2096 case cc_always: | 2099 case cc_always: |
| 2097 bits = OffsetSize::kOffset26; | 2100 bits = OffsetSize::kOffset26; |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2355 default: | 2358 default: |
| 2356 UNREACHABLE(); | 2359 UNREACHABLE(); |
| 2357 } | 2360 } |
| 2358 return true; | 2361 return true; |
| 2359 } | 2362 } |
| 2360 | 2363 |
| 2361 | 2364 |
| 2362 bool MacroAssembler::BranchShortHelper(int16_t offset, Label* L, Condition cond, | 2365 bool MacroAssembler::BranchShortHelper(int16_t offset, Label* L, Condition cond, |
| 2363 Register rs, const Operand& rt, | 2366 Register rs, const Operand& rt, |
| 2364 BranchDelaySlot bdslot) { | 2367 BranchDelaySlot bdslot) { |
| 2368 DCHECK(L == nullptr || offset == 0); |
| 2365 if (!is_near(L, OffsetSize::kOffset16)) return false; | 2369 if (!is_near(L, OffsetSize::kOffset16)) return false; |
| 2366 | 2370 |
| 2367 Register scratch = at; | 2371 Register scratch = at; |
| 2368 int32_t offset32; | 2372 int32_t offset32; |
| 2369 | 2373 |
| 2370 // 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 |
| 2371 // branch instruction, as the location will be remember for patching the | 2375 // branch instruction, as the location will be remember for patching the |
| 2372 // target. | 2376 // target. |
| 2373 BlockTrampolinePoolScope block_trampoline_pool(this); | 2377 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 2374 switch (cond) { | 2378 switch (cond) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2541 DCHECK(is_near); | 2545 DCHECK(is_near); |
| 2542 USE(is_near); | 2546 USE(is_near); |
| 2543 } | 2547 } |
| 2544 | 2548 |
| 2545 | 2549 |
| 2546 void MacroAssembler::BranchAndLink(Label* L, BranchDelaySlot bdslot) { | 2550 void MacroAssembler::BranchAndLink(Label* L, BranchDelaySlot bdslot) { |
| 2547 if (L->is_bound()) { | 2551 if (L->is_bound()) { |
| 2548 if (is_near_branch(L)) { | 2552 if (is_near_branch(L)) { |
| 2549 BranchAndLinkShort(L, bdslot); | 2553 BranchAndLinkShort(L, bdslot); |
| 2550 } else { | 2554 } else { |
| 2551 Jalr(L, bdslot); | 2555 BranchAndLinkLong(L, bdslot); |
| 2552 } | 2556 } |
| 2553 } else { | 2557 } else { |
| 2554 if (is_trampoline_emitted()) { | 2558 if (is_trampoline_emitted()) { |
| 2555 Jalr(L, bdslot); | 2559 BranchAndLinkLong(L, bdslot); |
| 2556 } else { | 2560 } else { |
| 2557 BranchAndLinkShort(L, bdslot); | 2561 BranchAndLinkShort(L, bdslot); |
| 2558 } | 2562 } |
| 2559 } | 2563 } |
| 2560 } | 2564 } |
| 2561 | 2565 |
| 2562 | 2566 |
| 2563 void MacroAssembler::BranchAndLink(Label* L, Condition cond, Register rs, | 2567 void MacroAssembler::BranchAndLink(Label* L, Condition cond, Register rs, |
| 2564 const Operand& rt, | 2568 const Operand& rt, |
| 2565 BranchDelaySlot bdslot) { | 2569 BranchDelaySlot bdslot) { |
| 2566 if (L->is_bound()) { | 2570 if (L->is_bound()) { |
| 2567 if (!BranchAndLinkShortCheck(0, L, cond, rs, rt, bdslot)) { | 2571 if (!BranchAndLinkShortCheck(0, L, cond, rs, rt, bdslot)) { |
| 2568 Label skip; | 2572 Label skip; |
| 2569 Condition neg_cond = NegateCondition(cond); | 2573 Condition neg_cond = NegateCondition(cond); |
| 2570 BranchShort(&skip, neg_cond, rs, rt); | 2574 BranchShort(&skip, neg_cond, rs, rt); |
| 2571 Jalr(L, bdslot); | 2575 BranchAndLinkLong(L, bdslot); |
| 2572 bind(&skip); | 2576 bind(&skip); |
| 2573 } | 2577 } |
| 2574 } else { | 2578 } else { |
| 2575 if (is_trampoline_emitted()) { | 2579 if (is_trampoline_emitted()) { |
| 2576 Label skip; | 2580 Label skip; |
| 2577 Condition neg_cond = NegateCondition(cond); | 2581 Condition neg_cond = NegateCondition(cond); |
| 2578 BranchShort(&skip, neg_cond, rs, rt); | 2582 BranchShort(&skip, neg_cond, rs, rt); |
| 2579 Jalr(L, bdslot); | 2583 BranchAndLinkLong(L, bdslot); |
| 2580 bind(&skip); | 2584 bind(&skip); |
| 2581 } else { | 2585 } else { |
| 2582 BranchAndLinkShortCheck(0, L, cond, rs, rt, bdslot); | 2586 BranchAndLinkShortCheck(0, L, cond, rs, rt, bdslot); |
| 2583 } | 2587 } |
| 2584 } | 2588 } |
| 2585 } | 2589 } |
| 2586 | 2590 |
| 2587 | 2591 |
| 2588 void MacroAssembler::BranchAndLinkShortHelper(int16_t offset, Label* L, | 2592 void MacroAssembler::BranchAndLinkShortHelper(int16_t offset, Label* L, |
| 2589 BranchDelaySlot bdslot) { | 2593 BranchDelaySlot bdslot) { |
| 2594 DCHECK(L == nullptr || offset == 0); |
| 2590 offset = GetOffset(offset, L, OffsetSize::kOffset16); | 2595 offset = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2591 bal(offset); | 2596 bal(offset); |
| 2592 | 2597 |
| 2593 // Emit a nop in the branch delay slot if required. | 2598 // Emit a nop in the branch delay slot if required. |
| 2594 if (bdslot == PROTECT) | 2599 if (bdslot == PROTECT) |
| 2595 nop(); | 2600 nop(); |
| 2596 } | 2601 } |
| 2597 | 2602 |
| 2598 | 2603 |
| 2599 void MacroAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L) { | 2604 void MacroAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L) { |
| 2605 DCHECK(L == nullptr || offset == 0); |
| 2600 offset = GetOffset(offset, L, OffsetSize::kOffset26); | 2606 offset = GetOffset(offset, L, OffsetSize::kOffset26); |
| 2601 balc(offset); | 2607 balc(offset); |
| 2602 } | 2608 } |
| 2603 | 2609 |
| 2604 | 2610 |
| 2605 void MacroAssembler::BranchAndLinkShort(int32_t offset, | 2611 void MacroAssembler::BranchAndLinkShort(int32_t offset, |
| 2606 BranchDelaySlot bdslot) { | 2612 BranchDelaySlot bdslot) { |
| 2607 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) { | 2613 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) { |
| 2608 DCHECK(is_int26(offset)); | 2614 DCHECK(is_int26(offset)); |
| 2609 BranchAndLinkShortHelperR6(offset, nullptr); | 2615 BranchAndLinkShortHelperR6(offset, nullptr); |
| 2610 } else { | 2616 } else { |
| 2611 DCHECK(is_int16(offset)); | 2617 DCHECK(is_int16(offset)); |
| 2612 BranchAndLinkShortHelper(offset, nullptr, bdslot); | 2618 BranchAndLinkShortHelper(offset, nullptr, bdslot); |
| 2613 } | 2619 } |
| 2614 } | 2620 } |
| 2615 | 2621 |
| 2616 | 2622 |
| 2617 void MacroAssembler::BranchAndLinkShort(Label* L, BranchDelaySlot bdslot) { | 2623 void MacroAssembler::BranchAndLinkShort(Label* L, BranchDelaySlot bdslot) { |
| 2618 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) { | 2624 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) { |
| 2619 BranchAndLinkShortHelperR6(0, L); | 2625 BranchAndLinkShortHelperR6(0, L); |
| 2620 } else { | 2626 } else { |
| 2621 BranchAndLinkShortHelper(0, L, bdslot); | 2627 BranchAndLinkShortHelper(0, L, bdslot); |
| 2622 } | 2628 } |
| 2623 } | 2629 } |
| 2624 | 2630 |
| 2625 | 2631 |
| 2626 bool MacroAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, | 2632 bool MacroAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, |
| 2627 Condition cond, Register rs, | 2633 Condition cond, Register rs, |
| 2628 const Operand& rt) { | 2634 const Operand& rt) { |
| 2635 DCHECK(L == nullptr || offset == 0); |
| 2629 Register scratch = rs.is(at) ? t8 : at; | 2636 Register scratch = rs.is(at) ? t8 : at; |
| 2630 OffsetSize bits = OffsetSize::kOffset16; | 2637 OffsetSize bits = OffsetSize::kOffset16; |
| 2631 | 2638 |
| 2632 BlockTrampolinePoolScope block_trampoline_pool(this); | 2639 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 2633 DCHECK((cond == cc_always && is_int26(offset)) || is_int16(offset)); | 2640 DCHECK((cond == cc_always && is_int26(offset)) || is_int16(offset)); |
| 2634 switch (cond) { | 2641 switch (cond) { |
| 2635 case cc_always: | 2642 case cc_always: |
| 2636 bits = OffsetSize::kOffset26; | 2643 bits = OffsetSize::kOffset26; |
| 2637 if (!is_near(L, bits)) return false; | 2644 if (!is_near(L, bits)) return false; |
| 2638 offset = GetOffset(offset, L, bits); | 2645 offset = GetOffset(offset, L, bits); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2776 } | 2783 } |
| 2777 | 2784 |
| 2778 | 2785 |
| 2779 // Pre r6 we need to use a bgezal or bltzal, but they can't be used directly | 2786 // Pre r6 we need to use a bgezal or bltzal, but they can't be used directly |
| 2780 // with the slt instructions. We could use sub or add instead but we would miss | 2787 // with the slt instructions. We could use sub or add instead but we would miss |
| 2781 // overflow cases, so we keep slt and add an intermediate third instruction. | 2788 // overflow cases, so we keep slt and add an intermediate third instruction. |
| 2782 bool MacroAssembler::BranchAndLinkShortHelper(int16_t offset, Label* L, | 2789 bool MacroAssembler::BranchAndLinkShortHelper(int16_t offset, Label* L, |
| 2783 Condition cond, Register rs, | 2790 Condition cond, Register rs, |
| 2784 const Operand& rt, | 2791 const Operand& rt, |
| 2785 BranchDelaySlot bdslot) { | 2792 BranchDelaySlot bdslot) { |
| 2793 DCHECK(L == nullptr || offset == 0); |
| 2786 if (!is_near(L, OffsetSize::kOffset16)) return false; | 2794 if (!is_near(L, OffsetSize::kOffset16)) return false; |
| 2787 | 2795 |
| 2788 Register scratch = t8; | 2796 Register scratch = t8; |
| 2789 BlockTrampolinePoolScope block_trampoline_pool(this); | 2797 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 2790 | 2798 |
| 2791 switch (cond) { | 2799 switch (cond) { |
| 2792 case cc_always: | 2800 case cc_always: |
| 2793 offset = GetOffset(offset, L, OffsetSize::kOffset16); | 2801 offset = GetOffset(offset, L, OffsetSize::kOffset16); |
| 2794 bal(offset); | 2802 bal(offset); |
| 2795 break; | 2803 break; |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3074 | 3082 |
| 3075 | 3083 |
| 3076 void MacroAssembler::Ret(Condition cond, | 3084 void MacroAssembler::Ret(Condition cond, |
| 3077 Register rs, | 3085 Register rs, |
| 3078 const Operand& rt, | 3086 const Operand& rt, |
| 3079 BranchDelaySlot bd) { | 3087 BranchDelaySlot bd) { |
| 3080 Jump(ra, cond, rs, rt, bd); | 3088 Jump(ra, cond, rs, rt, bd); |
| 3081 } | 3089 } |
| 3082 | 3090 |
| 3083 | 3091 |
| 3084 void MacroAssembler::Jr(Label* L, BranchDelaySlot bdslot) { | 3092 void MacroAssembler::BranchLong(Label* L, BranchDelaySlot bdslot) { |
| 3085 BlockTrampolinePoolScope block_trampoline_pool(this); | 3093 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT && |
| 3094 (!L->is_bound() || is_near_r6(L))) { |
| 3095 BranchShortHelperR6(0, L); |
| 3096 } else { |
| 3097 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 3098 uint32_t imm32; |
| 3099 imm32 = jump_address(L); |
| 3100 { |
| 3101 BlockGrowBufferScope block_buf_growth(this); |
| 3102 // Buffer growth (and relocation) must be blocked for internal references |
| 3103 // until associated instructions are emitted and available to be patched. |
| 3104 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED); |
| 3105 lui(at, (imm32 & kHiMask) >> kLuiShift); |
| 3106 ori(at, at, (imm32 & kImm16Mask)); |
| 3107 } |
| 3108 jr(at); |
| 3086 | 3109 |
| 3087 uint32_t imm32; | 3110 // Emit a nop in the branch delay slot if required. |
| 3088 imm32 = jump_address(L); | 3111 if (bdslot == PROTECT) nop(); |
| 3089 { BlockGrowBufferScope block_buf_growth(this); | |
| 3090 // Buffer growth (and relocation) must be blocked for internal references | |
| 3091 // until associated instructions are emitted and available to be patched. | |
| 3092 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED); | |
| 3093 lui(at, (imm32 & kHiMask) >> kLuiShift); | |
| 3094 ori(at, at, (imm32 & kImm16Mask)); | |
| 3095 } | 3112 } |
| 3096 jr(at); | |
| 3097 | |
| 3098 // Emit a nop in the branch delay slot if required. | |
| 3099 if (bdslot == PROTECT) | |
| 3100 nop(); | |
| 3101 } | 3113 } |
| 3102 | 3114 |
| 3103 | 3115 |
| 3104 void MacroAssembler::Jalr(Label* L, BranchDelaySlot bdslot) { | 3116 void MacroAssembler::BranchAndLinkLong(Label* L, BranchDelaySlot bdslot) { |
| 3105 BlockTrampolinePoolScope block_trampoline_pool(this); | 3117 if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT && |
| 3118 (!L->is_bound() || is_near_r6(L))) { |
| 3119 BranchAndLinkShortHelperR6(0, L); |
| 3120 } else { |
| 3121 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 3122 uint32_t imm32; |
| 3123 imm32 = jump_address(L); |
| 3124 { |
| 3125 BlockGrowBufferScope block_buf_growth(this); |
| 3126 // Buffer growth (and relocation) must be blocked for internal references |
| 3127 // until associated instructions are emitted and available to be patched. |
| 3128 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED); |
| 3129 lui(at, (imm32 & kHiMask) >> kLuiShift); |
| 3130 ori(at, at, (imm32 & kImm16Mask)); |
| 3131 } |
| 3132 jalr(at); |
| 3106 | 3133 |
| 3107 uint32_t imm32; | 3134 // Emit a nop in the branch delay slot if required. |
| 3108 imm32 = jump_address(L); | 3135 if (bdslot == PROTECT) nop(); |
| 3109 { BlockGrowBufferScope block_buf_growth(this); | |
| 3110 // Buffer growth (and relocation) must be blocked for internal references | |
| 3111 // until associated instructions are emitted and available to be patched. | |
| 3112 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED); | |
| 3113 lui(at, (imm32 & kHiMask) >> kLuiShift); | |
| 3114 ori(at, at, (imm32 & kImm16Mask)); | |
| 3115 } | 3136 } |
| 3116 jalr(at); | |
| 3117 | |
| 3118 // Emit a nop in the branch delay slot if required. | |
| 3119 if (bdslot == PROTECT) | |
| 3120 nop(); | |
| 3121 } | 3137 } |
| 3122 | 3138 |
| 3123 | 3139 |
| 3124 void MacroAssembler::DropAndRet(int drop) { | 3140 void MacroAssembler::DropAndRet(int drop) { |
| 3125 DCHECK(is_int16(drop * kPointerSize)); | 3141 DCHECK(is_int16(drop * kPointerSize)); |
| 3126 Ret(USE_DELAY_SLOT); | 3142 Ret(USE_DELAY_SLOT); |
| 3127 addiu(sp, sp, drop * kPointerSize); | 3143 addiu(sp, sp, drop * kPointerSize); |
| 3128 } | 3144 } |
| 3129 | 3145 |
| 3130 void MacroAssembler::DropAndRet(int drop, | 3146 void MacroAssembler::DropAndRet(int drop, |
| (...skipping 2706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5837 if (mag.shift > 0) sra(result, result, mag.shift); | 5853 if (mag.shift > 0) sra(result, result, mag.shift); |
| 5838 srl(at, dividend, 31); | 5854 srl(at, dividend, 31); |
| 5839 Addu(result, result, Operand(at)); | 5855 Addu(result, result, Operand(at)); |
| 5840 } | 5856 } |
| 5841 | 5857 |
| 5842 | 5858 |
| 5843 } // namespace internal | 5859 } // namespace internal |
| 5844 } // namespace v8 | 5860 } // namespace v8 |
| 5845 | 5861 |
| 5846 #endif // V8_TARGET_ARCH_MIPS | 5862 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |