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 |