| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
| 6 #include "src/compilation-info.h" | 6 #include "src/compilation-info.h" |
| 7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
| 8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
| 9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 FloatRegister InputSingleRegister(size_t index) { | 46 FloatRegister InputSingleRegister(size_t index) { |
| 47 return ToSingleRegister(instr_->InputAt(index)); | 47 return ToSingleRegister(instr_->InputAt(index)); |
| 48 } | 48 } |
| 49 | 49 |
| 50 FloatRegister ToSingleRegister(InstructionOperand* op) { | 50 FloatRegister ToSingleRegister(InstructionOperand* op) { |
| 51 // Single (Float) and Double register namespace is same on MIPS, | 51 // Single (Float) and Double register namespace is same on MIPS, |
| 52 // both are typedefs of FPURegister. | 52 // both are typedefs of FPURegister. |
| 53 return ToDoubleRegister(op); | 53 return ToDoubleRegister(op); |
| 54 } | 54 } |
| 55 | 55 |
| 56 Register InputOrZeroRegister(size_t index) { |
| 57 if (instr_->InputAt(index)->IsImmediate()) { |
| 58 DCHECK((InputInt32(index) == 0)); |
| 59 return zero_reg; |
| 60 } |
| 61 return InputRegister(index); |
| 62 } |
| 63 |
| 56 DoubleRegister InputOrZeroDoubleRegister(size_t index) { | 64 DoubleRegister InputOrZeroDoubleRegister(size_t index) { |
| 57 if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; | 65 if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; |
| 58 | 66 |
| 59 return InputDoubleRegister(index); | 67 return InputDoubleRegister(index); |
| 60 } | 68 } |
| 61 | 69 |
| 62 DoubleRegister InputOrZeroSingleRegister(size_t index) { | 70 DoubleRegister InputOrZeroSingleRegister(size_t index) { |
| 63 if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; | 71 if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; |
| 64 | 72 |
| 65 return InputSingleRegister(index); | 73 return InputSingleRegister(index); |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ | 401 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ |
| 394 } \ | 402 } \ |
| 395 __ bind(ool->exit()); \ | 403 __ bind(ool->exit()); \ |
| 396 } while (0) | 404 } while (0) |
| 397 | 405 |
| 398 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ | 406 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ |
| 399 do { \ | 407 do { \ |
| 400 Label done; \ | 408 Label done; \ |
| 401 if (instr->InputAt(0)->IsRegister()) { \ | 409 if (instr->InputAt(0)->IsRegister()) { \ |
| 402 auto offset = i.InputRegister(0); \ | 410 auto offset = i.InputRegister(0); \ |
| 403 auto value = i.Input##width##Register(2); \ | 411 auto value = i.InputOrZero##width##Register(2); \ |
| 412 if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \ |
| 413 __ Move(kDoubleRegZero, 0.0); \ |
| 414 } \ |
| 404 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ | 415 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ |
| 405 __ And(kScratchReg, offset, Operand(0xffffffff)); \ | 416 __ And(kScratchReg, offset, Operand(0xffffffff)); \ |
| 406 __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \ | 417 __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \ |
| 407 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ | 418 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ |
| 408 } else { \ | 419 } else { \ |
| 409 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 420 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
| 410 auto value = i.Input##width##Register(2); \ | 421 auto value = i.InputOrZero##width##Register(2); \ |
| 422 if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \ |
| 423 __ Move(kDoubleRegZero, 0.0); \ |
| 424 } \ |
| 411 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 425 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
| 412 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 426 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
| 413 } \ | 427 } \ |
| 414 __ bind(&done); \ | 428 __ bind(&done); \ |
| 415 } while (0) | 429 } while (0) |
| 416 | 430 |
| 417 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 431 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
| 418 do { \ | 432 do { \ |
| 419 Label done; \ | 433 Label done; \ |
| 420 if (instr->InputAt(0)->IsRegister()) { \ | 434 if (instr->InputAt(0)->IsRegister()) { \ |
| 421 auto offset = i.InputRegister(0); \ | 435 auto offset = i.InputRegister(0); \ |
| 422 auto value = i.InputRegister(2); \ | 436 auto value = i.InputOrZeroRegister(2); \ |
| 423 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ | 437 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ |
| 424 __ And(kScratchReg, offset, Operand(0xffffffff)); \ | 438 __ And(kScratchReg, offset, Operand(0xffffffff)); \ |
| 425 __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \ | 439 __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \ |
| 426 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ | 440 __ asm_instr(value, MemOperand(kScratchReg, 0)); \ |
| 427 } else { \ | 441 } else { \ |
| 428 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ | 442 int offset = static_cast<int>(i.InputOperand(0).immediate()); \ |
| 429 auto value = i.InputRegister(2); \ | 443 auto value = i.InputOrZeroRegister(2); \ |
| 430 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ | 444 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ |
| 431 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ | 445 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ |
| 432 } \ | 446 } \ |
| 433 __ bind(&done); \ | 447 __ bind(&done); \ |
| 434 } while (0) | 448 } while (0) |
| 435 | 449 |
| 436 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode) \ | 450 #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode) \ |
| 437 if (kArchVariant == kMips64r6) { \ | 451 if (kArchVariant == kMips64r6) { \ |
| 438 __ cfc1(kScratchReg, FCSR); \ | 452 __ cfc1(kScratchReg, FCSR); \ |
| 439 __ li(at, Operand(mode_##mode)); \ | 453 __ li(at, Operand(mode_##mode)); \ |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 __ bind(ool->exit()); \ | 496 __ bind(ool->exit()); \ |
| 483 __ bind(&done); \ | 497 __ bind(&done); \ |
| 484 } | 498 } |
| 485 | 499 |
| 486 #define ASSEMBLE_ATOMIC_LOAD_INTEGER(asm_instr) \ | 500 #define ASSEMBLE_ATOMIC_LOAD_INTEGER(asm_instr) \ |
| 487 do { \ | 501 do { \ |
| 488 __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \ | 502 __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \ |
| 489 __ sync(); \ | 503 __ sync(); \ |
| 490 } while (0) | 504 } while (0) |
| 491 | 505 |
| 492 #define ASSEMBLE_ATOMIC_STORE_INTEGER(asm_instr) \ | 506 #define ASSEMBLE_ATOMIC_STORE_INTEGER(asm_instr) \ |
| 493 do { \ | 507 do { \ |
| 494 __ sync(); \ | 508 __ sync(); \ |
| 495 __ asm_instr(i.InputRegister(2), i.MemoryOperand()); \ | 509 __ asm_instr(i.InputOrZeroRegister(2), i.MemoryOperand()); \ |
| 496 __ sync(); \ | 510 __ sync(); \ |
| 497 } while (0) | 511 } while (0) |
| 498 | 512 |
| 499 #define ASSEMBLE_IEEE754_BINOP(name) \ | 513 #define ASSEMBLE_IEEE754_BINOP(name) \ |
| 500 do { \ | 514 do { \ |
| 501 FrameScope scope(masm(), StackFrame::MANUAL); \ | 515 FrameScope scope(masm(), StackFrame::MANUAL); \ |
| 502 __ PrepareCallCFunction(0, 2, kScratchReg); \ | 516 __ PrepareCallCFunction(0, 2, kScratchReg); \ |
| 503 __ MovToFloatParameters(i.InputDoubleRegister(0), \ | 517 __ MovToFloatParameters(i.InputDoubleRegister(0), \ |
| 504 i.InputDoubleRegister(1)); \ | 518 i.InputDoubleRegister(1)); \ |
| 505 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ | 519 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ |
| 506 0, 2); \ | 520 0, 2); \ |
| (...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1676 case kMips64Seh: | 1690 case kMips64Seh: |
| 1677 __ seh(i.OutputRegister(), i.InputRegister(0)); | 1691 __ seh(i.OutputRegister(), i.InputRegister(0)); |
| 1678 break; | 1692 break; |
| 1679 case kMips64Lbu: | 1693 case kMips64Lbu: |
| 1680 __ lbu(i.OutputRegister(), i.MemoryOperand()); | 1694 __ lbu(i.OutputRegister(), i.MemoryOperand()); |
| 1681 break; | 1695 break; |
| 1682 case kMips64Lb: | 1696 case kMips64Lb: |
| 1683 __ lb(i.OutputRegister(), i.MemoryOperand()); | 1697 __ lb(i.OutputRegister(), i.MemoryOperand()); |
| 1684 break; | 1698 break; |
| 1685 case kMips64Sb: | 1699 case kMips64Sb: |
| 1686 __ sb(i.InputRegister(2), i.MemoryOperand()); | 1700 __ sb(i.InputOrZeroRegister(2), i.MemoryOperand()); |
| 1687 break; | 1701 break; |
| 1688 case kMips64Lhu: | 1702 case kMips64Lhu: |
| 1689 __ lhu(i.OutputRegister(), i.MemoryOperand()); | 1703 __ lhu(i.OutputRegister(), i.MemoryOperand()); |
| 1690 break; | 1704 break; |
| 1691 case kMips64Ulhu: | 1705 case kMips64Ulhu: |
| 1692 __ Ulhu(i.OutputRegister(), i.MemoryOperand()); | 1706 __ Ulhu(i.OutputRegister(), i.MemoryOperand()); |
| 1693 break; | 1707 break; |
| 1694 case kMips64Lh: | 1708 case kMips64Lh: |
| 1695 __ lh(i.OutputRegister(), i.MemoryOperand()); | 1709 __ lh(i.OutputRegister(), i.MemoryOperand()); |
| 1696 break; | 1710 break; |
| 1697 case kMips64Ulh: | 1711 case kMips64Ulh: |
| 1698 __ Ulh(i.OutputRegister(), i.MemoryOperand()); | 1712 __ Ulh(i.OutputRegister(), i.MemoryOperand()); |
| 1699 break; | 1713 break; |
| 1700 case kMips64Sh: | 1714 case kMips64Sh: |
| 1701 __ sh(i.InputRegister(2), i.MemoryOperand()); | 1715 __ sh(i.InputOrZeroRegister(2), i.MemoryOperand()); |
| 1702 break; | 1716 break; |
| 1703 case kMips64Ush: | 1717 case kMips64Ush: |
| 1704 __ Ush(i.InputRegister(2), i.MemoryOperand(), kScratchReg); | 1718 __ Ush(i.InputOrZeroRegister(2), i.MemoryOperand(), kScratchReg); |
| 1705 break; | 1719 break; |
| 1706 case kMips64Lw: | 1720 case kMips64Lw: |
| 1707 __ lw(i.OutputRegister(), i.MemoryOperand()); | 1721 __ lw(i.OutputRegister(), i.MemoryOperand()); |
| 1708 break; | 1722 break; |
| 1709 case kMips64Ulw: | 1723 case kMips64Ulw: |
| 1710 __ Ulw(i.OutputRegister(), i.MemoryOperand()); | 1724 __ Ulw(i.OutputRegister(), i.MemoryOperand()); |
| 1711 break; | 1725 break; |
| 1712 case kMips64Lwu: | 1726 case kMips64Lwu: |
| 1713 __ lwu(i.OutputRegister(), i.MemoryOperand()); | 1727 __ lwu(i.OutputRegister(), i.MemoryOperand()); |
| 1714 break; | 1728 break; |
| 1715 case kMips64Ulwu: | 1729 case kMips64Ulwu: |
| 1716 __ Ulwu(i.OutputRegister(), i.MemoryOperand()); | 1730 __ Ulwu(i.OutputRegister(), i.MemoryOperand()); |
| 1717 break; | 1731 break; |
| 1718 case kMips64Ld: | 1732 case kMips64Ld: |
| 1719 __ ld(i.OutputRegister(), i.MemoryOperand()); | 1733 __ ld(i.OutputRegister(), i.MemoryOperand()); |
| 1720 break; | 1734 break; |
| 1721 case kMips64Uld: | 1735 case kMips64Uld: |
| 1722 __ Uld(i.OutputRegister(), i.MemoryOperand()); | 1736 __ Uld(i.OutputRegister(), i.MemoryOperand()); |
| 1723 break; | 1737 break; |
| 1724 case kMips64Sw: | 1738 case kMips64Sw: |
| 1725 __ sw(i.InputRegister(2), i.MemoryOperand()); | 1739 __ sw(i.InputOrZeroRegister(2), i.MemoryOperand()); |
| 1726 break; | 1740 break; |
| 1727 case kMips64Usw: | 1741 case kMips64Usw: |
| 1728 __ Usw(i.InputRegister(2), i.MemoryOperand()); | 1742 __ Usw(i.InputOrZeroRegister(2), i.MemoryOperand()); |
| 1729 break; | 1743 break; |
| 1730 case kMips64Sd: | 1744 case kMips64Sd: |
| 1731 __ sd(i.InputRegister(2), i.MemoryOperand()); | 1745 __ sd(i.InputOrZeroRegister(2), i.MemoryOperand()); |
| 1732 break; | 1746 break; |
| 1733 case kMips64Usd: | 1747 case kMips64Usd: |
| 1734 __ Usd(i.InputRegister(2), i.MemoryOperand()); | 1748 __ Usd(i.InputOrZeroRegister(2), i.MemoryOperand()); |
| 1735 break; | 1749 break; |
| 1736 case kMips64Lwc1: { | 1750 case kMips64Lwc1: { |
| 1737 __ lwc1(i.OutputSingleRegister(), i.MemoryOperand()); | 1751 __ lwc1(i.OutputSingleRegister(), i.MemoryOperand()); |
| 1738 break; | 1752 break; |
| 1739 } | 1753 } |
| 1740 case kMips64Ulwc1: { | 1754 case kMips64Ulwc1: { |
| 1741 __ Ulwc1(i.OutputSingleRegister(), i.MemoryOperand(), kScratchReg); | 1755 __ Ulwc1(i.OutputSingleRegister(), i.MemoryOperand(), kScratchReg); |
| 1742 break; | 1756 break; |
| 1743 } | 1757 } |
| 1744 case kMips64Swc1: { | 1758 case kMips64Swc1: { |
| 1745 size_t index = 0; | 1759 size_t index = 0; |
| 1746 MemOperand operand = i.MemoryOperand(&index); | 1760 MemOperand operand = i.MemoryOperand(&index); |
| 1747 __ swc1(i.InputSingleRegister(index), operand); | 1761 FPURegister ft = i.InputOrZeroSingleRegister(index); |
| 1762 if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { |
| 1763 __ Move(kDoubleRegZero, 0.0); |
| 1764 } |
| 1765 __ swc1(ft, operand); |
| 1748 break; | 1766 break; |
| 1749 } | 1767 } |
| 1750 case kMips64Uswc1: { | 1768 case kMips64Uswc1: { |
| 1751 size_t index = 0; | 1769 size_t index = 0; |
| 1752 MemOperand operand = i.MemoryOperand(&index); | 1770 MemOperand operand = i.MemoryOperand(&index); |
| 1753 __ Uswc1(i.InputSingleRegister(index), operand, kScratchReg); | 1771 FPURegister ft = i.InputOrZeroSingleRegister(index); |
| 1772 if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { |
| 1773 __ Move(kDoubleRegZero, 0.0); |
| 1774 } |
| 1775 __ Uswc1(ft, operand, kScratchReg); |
| 1754 break; | 1776 break; |
| 1755 } | 1777 } |
| 1756 case kMips64Ldc1: | 1778 case kMips64Ldc1: |
| 1757 __ ldc1(i.OutputDoubleRegister(), i.MemoryOperand()); | 1779 __ ldc1(i.OutputDoubleRegister(), i.MemoryOperand()); |
| 1758 break; | 1780 break; |
| 1759 case kMips64Uldc1: | 1781 case kMips64Uldc1: |
| 1760 __ Uldc1(i.OutputDoubleRegister(), i.MemoryOperand(), kScratchReg); | 1782 __ Uldc1(i.OutputDoubleRegister(), i.MemoryOperand(), kScratchReg); |
| 1761 break; | 1783 break; |
| 1762 case kMips64Sdc1: | 1784 case kMips64Sdc1: { |
| 1763 __ sdc1(i.InputDoubleRegister(2), i.MemoryOperand()); | 1785 FPURegister ft = i.InputOrZeroDoubleRegister(2); |
| 1786 if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { |
| 1787 __ Move(kDoubleRegZero, 0.0); |
| 1788 } |
| 1789 __ sdc1(ft, i.MemoryOperand()); |
| 1764 break; | 1790 break; |
| 1765 case kMips64Usdc1: | 1791 } |
| 1766 __ Usdc1(i.InputDoubleRegister(2), i.MemoryOperand(), kScratchReg); | 1792 case kMips64Usdc1: { |
| 1793 FPURegister ft = i.InputOrZeroDoubleRegister(2); |
| 1794 if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { |
| 1795 __ Move(kDoubleRegZero, 0.0); |
| 1796 } |
| 1797 __ Usdc1(ft, i.MemoryOperand(), kScratchReg); |
| 1767 break; | 1798 break; |
| 1799 } |
| 1768 case kMips64Push: | 1800 case kMips64Push: |
| 1769 if (instr->InputAt(0)->IsFPRegister()) { | 1801 if (instr->InputAt(0)->IsFPRegister()) { |
| 1770 __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize)); | 1802 __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize)); |
| 1771 __ Subu(sp, sp, Operand(kDoubleSize)); | 1803 __ Subu(sp, sp, Operand(kDoubleSize)); |
| 1772 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); | 1804 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
| 1773 } else { | 1805 } else { |
| 1774 __ Push(i.InputRegister(0)); | 1806 __ Push(i.InputRegister(0)); |
| 1775 frame_access_state()->IncreaseSPDelta(1); | 1807 frame_access_state()->IncreaseSPDelta(1); |
| 1776 } | 1808 } |
| 1777 break; | 1809 break; |
| (...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2540 padding_size -= v8::internal::Assembler::kInstrSize; | 2572 padding_size -= v8::internal::Assembler::kInstrSize; |
| 2541 } | 2573 } |
| 2542 } | 2574 } |
| 2543 } | 2575 } |
| 2544 | 2576 |
| 2545 #undef __ | 2577 #undef __ |
| 2546 | 2578 |
| 2547 } // namespace compiler | 2579 } // namespace compiler |
| 2548 } // namespace internal | 2580 } // namespace internal |
| 2549 } // namespace v8 | 2581 } // namespace v8 |
| OLD | NEW |