Mercurial > hg > truffle
comparison src/cpu/sparc/vm/stubGenerator_sparc.cpp @ 1794:065dd1ca3ab6
6982370: SIGBUS in jbyte_fill
Reviewed-by: kvn
author | never |
---|---|
date | Tue, 14 Sep 2010 14:09:24 -0700 |
parents | f353275af40e |
children | 75588558f1bf |
comparison
equal
deleted
inserted
replaced
1793:d257356e35f0 | 1794:065dd1ca3ab6 |
---|---|
1607 // O3 is used as a temp register | 1607 // O3 is used as a temp register |
1608 | 1608 |
1609 assert_clean_int(count, O3); // Make sure 'count' is clean int. | 1609 assert_clean_int(count, O3); // Make sure 'count' is clean int. |
1610 | 1610 |
1611 Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte; | 1611 Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte; |
1612 Label L_fill_2_bytes, L_fill_4_bytes, L_fill_32_bytes; | 1612 Label L_fill_2_bytes, L_fill_elements, L_fill_32_bytes; |
1613 | 1613 |
1614 int shift = -1; | 1614 int shift = -1; |
1615 switch (t) { | 1615 switch (t) { |
1616 case T_BYTE: | 1616 case T_BYTE: |
1617 shift = 2; | 1617 shift = 2; |
1633 __ sllx(value, 8, O3); | 1633 __ sllx(value, 8, O3); |
1634 __ or3(value, O3, value); | 1634 __ or3(value, O3, value); |
1635 } | 1635 } |
1636 if (t == T_SHORT) { | 1636 if (t == T_SHORT) { |
1637 // Zero extend value | 1637 // Zero extend value |
1638 __ sethi(0xffff0000, O3); | 1638 __ sllx(value, 48, value); |
1639 __ andn(value, O3, value); | 1639 __ srlx(value, 48, value); |
1640 } | 1640 } |
1641 if (t == T_BYTE || t == T_SHORT) { | 1641 if (t == T_BYTE || t == T_SHORT) { |
1642 __ sllx(value, 16, O3); | 1642 __ sllx(value, 16, O3); |
1643 __ or3(value, O3, value); | 1643 __ or3(value, O3, value); |
1644 } | 1644 } |
1645 | 1645 |
1646 __ cmp(count, 2<<shift); // Short arrays (< 8 bytes) fill by element | 1646 __ cmp(count, 2<<shift); // Short arrays (< 8 bytes) fill by element |
1647 __ brx(Assembler::lessUnsigned, false, Assembler::pn, L_fill_4_bytes); // use unsigned cmp | 1647 __ brx(Assembler::lessUnsigned, false, Assembler::pn, L_fill_elements); // use unsigned cmp |
1648 __ delayed()->andcc(count, 1<<shift, G0); | 1648 __ delayed()->andcc(count, 1, G0); |
1649 | 1649 |
1650 if (!aligned && (t == T_BYTE || t == T_SHORT)) { | 1650 if (!aligned && (t == T_BYTE || t == T_SHORT)) { |
1651 // align source address at 4 bytes address boundary | 1651 // align source address at 4 bytes address boundary |
1652 if (t == T_BYTE) { | 1652 if (t == T_BYTE) { |
1653 // One byte misalignment happens only for byte arrays | 1653 // One byte misalignment happens only for byte arrays |
1696 // Fill 32-byte chunks | 1696 // Fill 32-byte chunks |
1697 __ subcc(count, 8 << shift, count); | 1697 __ subcc(count, 8 << shift, count); |
1698 __ brx(Assembler::less, false, Assembler::pt, L_check_fill_8_bytes); | 1698 __ brx(Assembler::less, false, Assembler::pt, L_check_fill_8_bytes); |
1699 __ delayed()->nop(); | 1699 __ delayed()->nop(); |
1700 | 1700 |
1701 Label L_fill_32_bytes_loop; | 1701 Label L_fill_32_bytes_loop, L_fill_4_bytes; |
1702 __ align(16); | 1702 __ align(16); |
1703 __ BIND(L_fill_32_bytes_loop); | 1703 __ BIND(L_fill_32_bytes_loop); |
1704 | 1704 |
1705 __ stx(value, to, 0); | 1705 __ stx(value, to, 0); |
1706 __ stx(value, to, 8); | 1706 __ stx(value, to, 8); |
1728 __ brx(Assembler::greaterEqual, false, Assembler::pn, L_fill_8_bytes_loop); | 1728 __ brx(Assembler::greaterEqual, false, Assembler::pn, L_fill_8_bytes_loop); |
1729 __ delayed()->add(to, 8, to); | 1729 __ delayed()->add(to, 8, to); |
1730 | 1730 |
1731 // fill trailing 4 bytes | 1731 // fill trailing 4 bytes |
1732 __ andcc(count, 1<<shift, G0); // in delay slot of branches | 1732 __ andcc(count, 1<<shift, G0); // in delay slot of branches |
1733 if (t == T_INT) { | |
1734 __ BIND(L_fill_elements); | |
1735 } | |
1733 __ BIND(L_fill_4_bytes); | 1736 __ BIND(L_fill_4_bytes); |
1734 __ brx(Assembler::zero, false, Assembler::pt, L_fill_2_bytes); | 1737 __ brx(Assembler::zero, false, Assembler::pt, L_fill_2_bytes); |
1735 if (t == T_BYTE || t == T_SHORT) { | 1738 if (t == T_BYTE || t == T_SHORT) { |
1736 __ delayed()->andcc(count, 1<<(shift-1), G0); | 1739 __ delayed()->andcc(count, 1<<(shift-1), G0); |
1737 } else { | 1740 } else { |
1760 } else { | 1763 } else { |
1761 __ BIND(L_fill_2_bytes); | 1764 __ BIND(L_fill_2_bytes); |
1762 } | 1765 } |
1763 __ BIND(L_exit); | 1766 __ BIND(L_exit); |
1764 __ retl(); | 1767 __ retl(); |
1765 __ delayed()->mov(G0, O0); // return 0 | 1768 __ delayed()->nop(); |
1769 | |
1770 // Handle copies less than 8 bytes. Int is handled elsewhere. | |
1771 if (t == T_BYTE) { | |
1772 __ BIND(L_fill_elements); | |
1773 Label L_fill_2, L_fill_4; | |
1774 // in delay slot __ andcc(count, 1, G0); | |
1775 __ brx(Assembler::zero, false, Assembler::pt, L_fill_2); | |
1776 __ delayed()->andcc(count, 2, G0); | |
1777 __ stb(value, to, 0); | |
1778 __ inc(to, 1); | |
1779 __ BIND(L_fill_2); | |
1780 __ brx(Assembler::zero, false, Assembler::pt, L_fill_4); | |
1781 __ delayed()->andcc(count, 4, G0); | |
1782 __ stb(value, to, 0); | |
1783 __ stb(value, to, 1); | |
1784 __ inc(to, 2); | |
1785 __ BIND(L_fill_4); | |
1786 __ brx(Assembler::zero, false, Assembler::pt, L_exit); | |
1787 __ delayed()->nop(); | |
1788 __ stb(value, to, 0); | |
1789 __ stb(value, to, 1); | |
1790 __ stb(value, to, 2); | |
1791 __ retl(); | |
1792 __ delayed()->stb(value, to, 3); | |
1793 } | |
1794 | |
1795 if (t == T_SHORT) { | |
1796 Label L_fill_2; | |
1797 __ BIND(L_fill_elements); | |
1798 // in delay slot __ andcc(count, 1, G0); | |
1799 __ brx(Assembler::zero, false, Assembler::pt, L_fill_2); | |
1800 __ delayed()->andcc(count, 2, G0); | |
1801 __ sth(value, to, 0); | |
1802 __ inc(to, 2); | |
1803 __ BIND(L_fill_2); | |
1804 __ brx(Assembler::zero, false, Assembler::pt, L_exit); | |
1805 __ delayed()->nop(); | |
1806 __ sth(value, to, 0); | |
1807 __ retl(); | |
1808 __ delayed()->sth(value, to, 2); | |
1809 } | |
1766 return start; | 1810 return start; |
1767 } | 1811 } |
1768 | 1812 |
1769 // | 1813 // |
1770 // Generate stub for conjoint short copy. If "aligned" is true, the | 1814 // Generate stub for conjoint short copy. If "aligned" is true, the |