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/atomic.hpp"
46 #include "runtime/continuation.hpp"
47 #include "runtime/continuationEntry.inline.hpp"
48 #include "runtime/frame.inline.hpp"
49 #include "runtime/handles.inline.hpp"
7749 __ add(s1, s1, temp0);
7750 __ add(s2, s2, temp1);
7751 }
7752
7753 /**
7754 * Arguments:
7755 *
7756 * Input:
7757 * c_rarg0 - x address
7758 * c_rarg1 - x length
7759 * c_rarg2 - y address
7760 * c_rarg3 - y length
7761 * c_rarg4 - z address
7762 */
7763 address generate_multiplyToLen() {
7764 __ align(CodeEntryAlignment);
7765 StubId stub_id = StubId::stubgen_multiplyToLen_id;
7766 StubCodeMark mark(this, stub_id);
7767
7768 address start = __ pc();
7769 const Register x = r0;
7770 const Register xlen = r1;
7771 const Register y = r2;
7772 const Register ylen = r3;
7773 const Register z = r4;
7774
7775 const Register tmp0 = r5;
7776 const Register tmp1 = r10;
7777 const Register tmp2 = r11;
7778 const Register tmp3 = r12;
7779 const Register tmp4 = r13;
7780 const Register tmp5 = r14;
7781 const Register tmp6 = r15;
7782 const Register tmp7 = r16;
7783
7784 BLOCK_COMMENT("Entry:");
7785 __ enter(); // required for proper stackwalking of RuntimeStub frame
7786 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7787 __ leave(); // required for proper stackwalking of RuntimeStub frame
7788 __ ret(lr);
7789
7790 return start;
7791 }
7792
7793 address generate_squareToLen() {
7794 // squareToLen algorithm for sizes 1..127 described in java code works
7795 // faster than multiply_to_len on some CPUs and slower on others, but
7796 // multiply_to_len shows a bit better overall results
7797 __ align(CodeEntryAlignment);
7798 StubId stub_id = StubId::stubgen_squareToLen_id;
7799 StubCodeMark mark(this, stub_id);
7800 address start = __ pc();
7801
7802 const Register x = r0;
7803 const Register xlen = r1;
7804 const Register z = r2;
7805 const Register y = r4; // == x
7806 const Register ylen = r5; // == xlen
7807
7808 const Register tmp0 = r3;
7809 const Register tmp1 = r10;
7810 const Register tmp2 = r11;
7811 const Register tmp3 = r12;
7812 const Register tmp4 = r13;
7813 const Register tmp5 = r14;
7814 const Register tmp6 = r15;
7815 const Register tmp7 = r16;
7816
7817 RegSet spilled_regs = RegSet::of(y, ylen);
7818 BLOCK_COMMENT("Entry:");
7819 __ enter();
7820 __ push(spilled_regs, sp);
7821 __ mov(y, x);
7822 __ mov(ylen, xlen);
7823 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7824 __ pop(spilled_regs, sp);
7825 __ leave();
7826 __ ret(lr);
7827 return start;
7828 }
7829
7830 address generate_mulAdd() {
7831 __ align(CodeEntryAlignment);
7832 StubId stub_id = StubId::stubgen_mulAdd_id;
7833 StubCodeMark mark(this, stub_id);
7834
7835 address start = __ pc();
7836
7837 const Register out = r0;
7838 const Register in = r1;
7839 const Register offset = r2;
7840 const Register len = r3;
7841 const Register k = r4;
7842
7843 BLOCK_COMMENT("Entry:");
7844 __ enter();
7845 __ mul_add(out, in, offset, len, k);
7846 __ leave();
7847 __ ret(lr);
7848
7849 return start;
7850 }
7851
7852 // Arguments:
7853 //
7854 // Input:
7855 // c_rarg0 - newArr address
7856 // c_rarg1 - oldArr address
7857 // c_rarg2 - newIdx
7858 // c_rarg3 - shiftCount
7859 // c_rarg4 - numIter
7860 //
7861 address generate_bigIntegerRightShift() {
7862 __ align(CodeEntryAlignment);
7863 StubId stub_id = StubId::stubgen_bigIntegerRightShiftWorker_id;
7864 StubCodeMark mark(this, stub_id);
7865 address start = __ pc();
7866
7867 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7868
|
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/atomic.hpp"
47 #include "runtime/continuation.hpp"
48 #include "runtime/continuationEntry.inline.hpp"
49 #include "runtime/frame.inline.hpp"
50 #include "runtime/handles.inline.hpp"
7750 __ add(s1, s1, temp0);
7751 __ add(s2, s2, temp1);
7752 }
7753
7754 /**
7755 * Arguments:
7756 *
7757 * Input:
7758 * c_rarg0 - x address
7759 * c_rarg1 - x length
7760 * c_rarg2 - y address
7761 * c_rarg3 - y length
7762 * c_rarg4 - z address
7763 */
7764 address generate_multiplyToLen() {
7765 __ align(CodeEntryAlignment);
7766 StubId stub_id = StubId::stubgen_multiplyToLen_id;
7767 StubCodeMark mark(this, stub_id);
7768
7769 address start = __ pc();
7770
7771 if (AOTCodeCache::load_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start)) {
7772 return start;
7773 }
7774 const Register x = r0;
7775 const Register xlen = r1;
7776 const Register y = r2;
7777 const Register ylen = r3;
7778 const Register z = r4;
7779
7780 const Register tmp0 = r5;
7781 const Register tmp1 = r10;
7782 const Register tmp2 = r11;
7783 const Register tmp3 = r12;
7784 const Register tmp4 = r13;
7785 const Register tmp5 = r14;
7786 const Register tmp6 = r15;
7787 const Register tmp7 = r16;
7788
7789 BLOCK_COMMENT("Entry:");
7790 __ enter(); // required for proper stackwalking of RuntimeStub frame
7791 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7792 __ leave(); // required for proper stackwalking of RuntimeStub frame
7793 __ ret(lr);
7794
7795 AOTCodeCache::store_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start);
7796 return start;
7797 }
7798
7799 address generate_squareToLen() {
7800 // squareToLen algorithm for sizes 1..127 described in java code works
7801 // faster than multiply_to_len on some CPUs and slower on others, but
7802 // multiply_to_len shows a bit better overall results
7803 __ align(CodeEntryAlignment);
7804 StubId stub_id = StubId::stubgen_squareToLen_id;
7805 StubCodeMark mark(this, stub_id);
7806 address start = __ pc();
7807
7808 if (AOTCodeCache::load_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start)) {
7809 return start;
7810 }
7811 const Register x = r0;
7812 const Register xlen = r1;
7813 const Register z = r2;
7814 const Register y = r4; // == x
7815 const Register ylen = r5; // == xlen
7816
7817 const Register tmp0 = r3;
7818 const Register tmp1 = r10;
7819 const Register tmp2 = r11;
7820 const Register tmp3 = r12;
7821 const Register tmp4 = r13;
7822 const Register tmp5 = r14;
7823 const Register tmp6 = r15;
7824 const Register tmp7 = r16;
7825
7826 RegSet spilled_regs = RegSet::of(y, ylen);
7827 BLOCK_COMMENT("Entry:");
7828 __ enter();
7829 __ push(spilled_regs, sp);
7830 __ mov(y, x);
7831 __ mov(ylen, xlen);
7832 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7833 __ pop(spilled_regs, sp);
7834 __ leave();
7835 __ ret(lr);
7836
7837 AOTCodeCache::store_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start);
7838 return start;
7839 }
7840
7841 address generate_mulAdd() {
7842 __ align(CodeEntryAlignment);
7843 StubId stub_id = StubId::stubgen_mulAdd_id;
7844 StubCodeMark mark(this, stub_id);
7845
7846 address start = __ pc();
7847
7848 if (AOTCodeCache::load_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start)) {
7849 return start;
7850 }
7851 const Register out = r0;
7852 const Register in = r1;
7853 const Register offset = r2;
7854 const Register len = r3;
7855 const Register k = r4;
7856
7857 BLOCK_COMMENT("Entry:");
7858 __ enter();
7859 __ mul_add(out, in, offset, len, k);
7860 __ leave();
7861 __ ret(lr);
7862
7863 AOTCodeCache::store_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start);
7864 return start;
7865 }
7866
7867 // Arguments:
7868 //
7869 // Input:
7870 // c_rarg0 - newArr address
7871 // c_rarg1 - oldArr address
7872 // c_rarg2 - newIdx
7873 // c_rarg3 - shiftCount
7874 // c_rarg4 - numIter
7875 //
7876 address generate_bigIntegerRightShift() {
7877 __ align(CodeEntryAlignment);
7878 StubId stub_id = StubId::stubgen_bigIntegerRightShiftWorker_id;
7879 StubCodeMark mark(this, stub_id);
7880 address start = __ pc();
7881
7882 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7883
|