10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include "asm/macroAssembler.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "asm/register.hpp"
29 #include "atomic_aarch64.hpp"
30 #include "compiler/oopMap.hpp"
31 #include "gc/shared/barrierSet.hpp"
32 #include "gc/shared/barrierSetAssembler.hpp"
33 #include "gc/shared/gc_globals.hpp"
34 #include "gc/shared/tlab_globals.hpp"
35 #include "interpreter/interpreter.hpp"
36 #include "memory/universe.hpp"
37 #include "nativeInst_aarch64.hpp"
38 #include "oops/instanceOop.hpp"
39 #include "oops/method.hpp"
40 #include "oops/objArrayKlass.hpp"
41 #include "oops/oop.inline.hpp"
42 #include "prims/methodHandles.hpp"
43 #include "prims/upcallLinker.hpp"
44 #include "runtime/arguments.hpp"
45 #include "runtime/atomicAccess.hpp"
46 #include "runtime/continuation.hpp"
47 #include "runtime/continuationEntry.inline.hpp"
48 #include "runtime/frame.inline.hpp"
49 #include "runtime/handles.inline.hpp"
7741 __ add(s1, s1, temp0);
7742 __ add(s2, s2, temp1);
7743 }
7744
7745 /**
7746 * Arguments:
7747 *
7748 * Input:
7749 * c_rarg0 - x address
7750 * c_rarg1 - x length
7751 * c_rarg2 - y address
7752 * c_rarg3 - y length
7753 * c_rarg4 - z address
7754 */
7755 address generate_multiplyToLen() {
7756 __ align(CodeEntryAlignment);
7757 StubId stub_id = StubId::stubgen_multiplyToLen_id;
7758 StubCodeMark mark(this, stub_id);
7759
7760 address start = __ pc();
7761 const Register x = r0;
7762 const Register xlen = r1;
7763 const Register y = r2;
7764 const Register ylen = r3;
7765 const Register z = r4;
7766
7767 const Register tmp0 = r5;
7768 const Register tmp1 = r10;
7769 const Register tmp2 = r11;
7770 const Register tmp3 = r12;
7771 const Register tmp4 = r13;
7772 const Register tmp5 = r14;
7773 const Register tmp6 = r15;
7774 const Register tmp7 = r16;
7775
7776 BLOCK_COMMENT("Entry:");
7777 __ enter(); // required for proper stackwalking of RuntimeStub frame
7778 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7779 __ leave(); // required for proper stackwalking of RuntimeStub frame
7780 __ ret(lr);
7781
7782 return start;
7783 }
7784
7785 address generate_squareToLen() {
7786 // squareToLen algorithm for sizes 1..127 described in java code works
7787 // faster than multiply_to_len on some CPUs and slower on others, but
7788 // multiply_to_len shows a bit better overall results
7789 __ align(CodeEntryAlignment);
7790 StubId stub_id = StubId::stubgen_squareToLen_id;
7791 StubCodeMark mark(this, stub_id);
7792 address start = __ pc();
7793
7794 const Register x = r0;
7795 const Register xlen = r1;
7796 const Register z = r2;
7797 const Register y = r4; // == x
7798 const Register ylen = r5; // == xlen
7799
7800 const Register tmp0 = r3;
7801 const Register tmp1 = r10;
7802 const Register tmp2 = r11;
7803 const Register tmp3 = r12;
7804 const Register tmp4 = r13;
7805 const Register tmp5 = r14;
7806 const Register tmp6 = r15;
7807 const Register tmp7 = r16;
7808
7809 RegSet spilled_regs = RegSet::of(y, ylen);
7810 BLOCK_COMMENT("Entry:");
7811 __ enter();
7812 __ push(spilled_regs, sp);
7813 __ mov(y, x);
7814 __ mov(ylen, xlen);
7815 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7816 __ pop(spilled_regs, sp);
7817 __ leave();
7818 __ ret(lr);
7819 return start;
7820 }
7821
7822 address generate_mulAdd() {
7823 __ align(CodeEntryAlignment);
7824 StubId stub_id = StubId::stubgen_mulAdd_id;
7825 StubCodeMark mark(this, stub_id);
7826
7827 address start = __ pc();
7828
7829 const Register out = r0;
7830 const Register in = r1;
7831 const Register offset = r2;
7832 const Register len = r3;
7833 const Register k = r4;
7834
7835 BLOCK_COMMENT("Entry:");
7836 __ enter();
7837 __ mul_add(out, in, offset, len, k);
7838 __ leave();
7839 __ ret(lr);
7840
7841 return start;
7842 }
7843
7844 // Arguments:
7845 //
7846 // Input:
7847 // c_rarg0 - newArr address
7848 // c_rarg1 - oldArr address
7849 // c_rarg2 - newIdx
7850 // c_rarg3 - shiftCount
7851 // c_rarg4 - numIter
7852 //
7853 address generate_bigIntegerRightShift() {
7854 __ align(CodeEntryAlignment);
7855 StubId stub_id = StubId::stubgen_bigIntegerRightShiftWorker_id;
7856 StubCodeMark mark(this, stub_id);
7857 address start = __ pc();
7858
7859 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7860
|
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include "asm/macroAssembler.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "asm/register.hpp"
29 #include "atomic_aarch64.hpp"
30 #include "code/aotCodeCache.hpp"
31 #include "compiler/oopMap.hpp"
32 #include "gc/shared/barrierSet.hpp"
33 #include "gc/shared/barrierSetAssembler.hpp"
34 #include "gc/shared/gc_globals.hpp"
35 #include "gc/shared/tlab_globals.hpp"
36 #include "interpreter/interpreter.hpp"
37 #include "memory/universe.hpp"
38 #include "nativeInst_aarch64.hpp"
39 #include "oops/instanceOop.hpp"
40 #include "oops/method.hpp"
41 #include "oops/objArrayKlass.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "prims/methodHandles.hpp"
44 #include "prims/upcallLinker.hpp"
45 #include "runtime/arguments.hpp"
46 #include "runtime/atomicAccess.hpp"
47 #include "runtime/continuation.hpp"
48 #include "runtime/continuationEntry.inline.hpp"
49 #include "runtime/frame.inline.hpp"
50 #include "runtime/handles.inline.hpp"
7742 __ add(s1, s1, temp0);
7743 __ add(s2, s2, temp1);
7744 }
7745
7746 /**
7747 * Arguments:
7748 *
7749 * Input:
7750 * c_rarg0 - x address
7751 * c_rarg1 - x length
7752 * c_rarg2 - y address
7753 * c_rarg3 - y length
7754 * c_rarg4 - z address
7755 */
7756 address generate_multiplyToLen() {
7757 __ align(CodeEntryAlignment);
7758 StubId stub_id = StubId::stubgen_multiplyToLen_id;
7759 StubCodeMark mark(this, stub_id);
7760
7761 address start = __ pc();
7762
7763 if (AOTCodeCache::load_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start)) {
7764 return start;
7765 }
7766 const Register x = r0;
7767 const Register xlen = r1;
7768 const Register y = r2;
7769 const Register ylen = r3;
7770 const Register z = r4;
7771
7772 const Register tmp0 = r5;
7773 const Register tmp1 = r10;
7774 const Register tmp2 = r11;
7775 const Register tmp3 = r12;
7776 const Register tmp4 = r13;
7777 const Register tmp5 = r14;
7778 const Register tmp6 = r15;
7779 const Register tmp7 = r16;
7780
7781 BLOCK_COMMENT("Entry:");
7782 __ enter(); // required for proper stackwalking of RuntimeStub frame
7783 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7784 __ leave(); // required for proper stackwalking of RuntimeStub frame
7785 __ ret(lr);
7786
7787 AOTCodeCache::store_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start);
7788 return start;
7789 }
7790
7791 address generate_squareToLen() {
7792 // squareToLen algorithm for sizes 1..127 described in java code works
7793 // faster than multiply_to_len on some CPUs and slower on others, but
7794 // multiply_to_len shows a bit better overall results
7795 __ align(CodeEntryAlignment);
7796 StubId stub_id = StubId::stubgen_squareToLen_id;
7797 StubCodeMark mark(this, stub_id);
7798 address start = __ pc();
7799
7800 if (AOTCodeCache::load_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start)) {
7801 return start;
7802 }
7803 const Register x = r0;
7804 const Register xlen = r1;
7805 const Register z = r2;
7806 const Register y = r4; // == x
7807 const Register ylen = r5; // == xlen
7808
7809 const Register tmp0 = r3;
7810 const Register tmp1 = r10;
7811 const Register tmp2 = r11;
7812 const Register tmp3 = r12;
7813 const Register tmp4 = r13;
7814 const Register tmp5 = r14;
7815 const Register tmp6 = r15;
7816 const Register tmp7 = r16;
7817
7818 RegSet spilled_regs = RegSet::of(y, ylen);
7819 BLOCK_COMMENT("Entry:");
7820 __ enter();
7821 __ push(spilled_regs, sp);
7822 __ mov(y, x);
7823 __ mov(ylen, xlen);
7824 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7825 __ pop(spilled_regs, sp);
7826 __ leave();
7827 __ ret(lr);
7828
7829 AOTCodeCache::store_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start);
7830 return start;
7831 }
7832
7833 address generate_mulAdd() {
7834 __ align(CodeEntryAlignment);
7835 StubId stub_id = StubId::stubgen_mulAdd_id;
7836 StubCodeMark mark(this, stub_id);
7837
7838 address start = __ pc();
7839
7840 if (AOTCodeCache::load_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start)) {
7841 return start;
7842 }
7843 const Register out = r0;
7844 const Register in = r1;
7845 const Register offset = r2;
7846 const Register len = r3;
7847 const Register k = r4;
7848
7849 BLOCK_COMMENT("Entry:");
7850 __ enter();
7851 __ mul_add(out, in, offset, len, k);
7852 __ leave();
7853 __ ret(lr);
7854
7855 AOTCodeCache::store_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start);
7856 return start;
7857 }
7858
7859 // Arguments:
7860 //
7861 // Input:
7862 // c_rarg0 - newArr address
7863 // c_rarg1 - oldArr address
7864 // c_rarg2 - newIdx
7865 // c_rarg3 - shiftCount
7866 // c_rarg4 - numIter
7867 //
7868 address generate_bigIntegerRightShift() {
7869 __ align(CodeEntryAlignment);
7870 StubId stub_id = StubId::stubgen_bigIntegerRightShiftWorker_id;
7871 StubCodeMark mark(this, stub_id);
7872 address start = __ pc();
7873
7874 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7875
|