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"
7805 __ add(s1, s1, temp0);
7806 __ add(s2, s2, temp1);
7807 }
7808
7809 /**
7810 * Arguments:
7811 *
7812 * Input:
7813 * c_rarg0 - x address
7814 * c_rarg1 - x length
7815 * c_rarg2 - y address
7816 * c_rarg3 - y length
7817 * c_rarg4 - z address
7818 */
7819 address generate_multiplyToLen() {
7820 __ align(CodeEntryAlignment);
7821 StubId stub_id = StubId::stubgen_multiplyToLen_id;
7822 StubCodeMark mark(this, stub_id);
7823
7824 address start = __ pc();
7825 const Register x = r0;
7826 const Register xlen = r1;
7827 const Register y = r2;
7828 const Register ylen = r3;
7829 const Register z = r4;
7830
7831 const Register tmp0 = r5;
7832 const Register tmp1 = r10;
7833 const Register tmp2 = r11;
7834 const Register tmp3 = r12;
7835 const Register tmp4 = r13;
7836 const Register tmp5 = r14;
7837 const Register tmp6 = r15;
7838 const Register tmp7 = r16;
7839
7840 BLOCK_COMMENT("Entry:");
7841 __ enter(); // required for proper stackwalking of RuntimeStub frame
7842 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7843 __ leave(); // required for proper stackwalking of RuntimeStub frame
7844 __ ret(lr);
7845
7846 return start;
7847 }
7848
7849 address generate_squareToLen() {
7850 // squareToLen algorithm for sizes 1..127 described in java code works
7851 // faster than multiply_to_len on some CPUs and slower on others, but
7852 // multiply_to_len shows a bit better overall results
7853 __ align(CodeEntryAlignment);
7854 StubId stub_id = StubId::stubgen_squareToLen_id;
7855 StubCodeMark mark(this, stub_id);
7856 address start = __ pc();
7857
7858 const Register x = r0;
7859 const Register xlen = r1;
7860 const Register z = r2;
7861 const Register y = r4; // == x
7862 const Register ylen = r5; // == xlen
7863
7864 const Register tmp0 = r3;
7865 const Register tmp1 = r10;
7866 const Register tmp2 = r11;
7867 const Register tmp3 = r12;
7868 const Register tmp4 = r13;
7869 const Register tmp5 = r14;
7870 const Register tmp6 = r15;
7871 const Register tmp7 = r16;
7872
7873 RegSet spilled_regs = RegSet::of(y, ylen);
7874 BLOCK_COMMENT("Entry:");
7875 __ enter();
7876 __ push(spilled_regs, sp);
7877 __ mov(y, x);
7878 __ mov(ylen, xlen);
7879 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7880 __ pop(spilled_regs, sp);
7881 __ leave();
7882 __ ret(lr);
7883 return start;
7884 }
7885
7886 address generate_mulAdd() {
7887 __ align(CodeEntryAlignment);
7888 StubId stub_id = StubId::stubgen_mulAdd_id;
7889 StubCodeMark mark(this, stub_id);
7890
7891 address start = __ pc();
7892
7893 const Register out = r0;
7894 const Register in = r1;
7895 const Register offset = r2;
7896 const Register len = r3;
7897 const Register k = r4;
7898
7899 BLOCK_COMMENT("Entry:");
7900 __ enter();
7901 __ mul_add(out, in, offset, len, k);
7902 __ leave();
7903 __ ret(lr);
7904
7905 return start;
7906 }
7907
7908 // Arguments:
7909 //
7910 // Input:
7911 // c_rarg0 - newArr address
7912 // c_rarg1 - oldArr address
7913 // c_rarg2 - newIdx
7914 // c_rarg3 - shiftCount
7915 // c_rarg4 - numIter
7916 //
7917 address generate_bigIntegerRightShift() {
7918 __ align(CodeEntryAlignment);
7919 StubId stub_id = StubId::stubgen_bigIntegerRightShiftWorker_id;
7920 StubCodeMark mark(this, stub_id);
7921 address start = __ pc();
7922
7923 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7924
|
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"
7806 __ add(s1, s1, temp0);
7807 __ add(s2, s2, temp1);
7808 }
7809
7810 /**
7811 * Arguments:
7812 *
7813 * Input:
7814 * c_rarg0 - x address
7815 * c_rarg1 - x length
7816 * c_rarg2 - y address
7817 * c_rarg3 - y length
7818 * c_rarg4 - z address
7819 */
7820 address generate_multiplyToLen() {
7821 __ align(CodeEntryAlignment);
7822 StubId stub_id = StubId::stubgen_multiplyToLen_id;
7823 StubCodeMark mark(this, stub_id);
7824
7825 address start = __ pc();
7826
7827 if (AOTCodeCache::load_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start)) {
7828 return start;
7829 }
7830 const Register x = r0;
7831 const Register xlen = r1;
7832 const Register y = r2;
7833 const Register ylen = r3;
7834 const Register z = r4;
7835
7836 const Register tmp0 = r5;
7837 const Register tmp1 = r10;
7838 const Register tmp2 = r11;
7839 const Register tmp3 = r12;
7840 const Register tmp4 = r13;
7841 const Register tmp5 = r14;
7842 const Register tmp6 = r15;
7843 const Register tmp7 = r16;
7844
7845 BLOCK_COMMENT("Entry:");
7846 __ enter(); // required for proper stackwalking of RuntimeStub frame
7847 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7848 __ leave(); // required for proper stackwalking of RuntimeStub frame
7849 __ ret(lr);
7850
7851 AOTCodeCache::store_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start);
7852 return start;
7853 }
7854
7855 address generate_squareToLen() {
7856 // squareToLen algorithm for sizes 1..127 described in java code works
7857 // faster than multiply_to_len on some CPUs and slower on others, but
7858 // multiply_to_len shows a bit better overall results
7859 __ align(CodeEntryAlignment);
7860 StubId stub_id = StubId::stubgen_squareToLen_id;
7861 StubCodeMark mark(this, stub_id);
7862 address start = __ pc();
7863
7864 if (AOTCodeCache::load_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start)) {
7865 return start;
7866 }
7867 const Register x = r0;
7868 const Register xlen = r1;
7869 const Register z = r2;
7870 const Register y = r4; // == x
7871 const Register ylen = r5; // == xlen
7872
7873 const Register tmp0 = r3;
7874 const Register tmp1 = r10;
7875 const Register tmp2 = r11;
7876 const Register tmp3 = r12;
7877 const Register tmp4 = r13;
7878 const Register tmp5 = r14;
7879 const Register tmp6 = r15;
7880 const Register tmp7 = r16;
7881
7882 RegSet spilled_regs = RegSet::of(y, ylen);
7883 BLOCK_COMMENT("Entry:");
7884 __ enter();
7885 __ push(spilled_regs, sp);
7886 __ mov(y, x);
7887 __ mov(ylen, xlen);
7888 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7889 __ pop(spilled_regs, sp);
7890 __ leave();
7891 __ ret(lr);
7892
7893 AOTCodeCache::store_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start);
7894 return start;
7895 }
7896
7897 address generate_mulAdd() {
7898 __ align(CodeEntryAlignment);
7899 StubId stub_id = StubId::stubgen_mulAdd_id;
7900 StubCodeMark mark(this, stub_id);
7901
7902 address start = __ pc();
7903
7904 if (AOTCodeCache::load_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start)) {
7905 return start;
7906 }
7907 const Register out = r0;
7908 const Register in = r1;
7909 const Register offset = r2;
7910 const Register len = r3;
7911 const Register k = r4;
7912
7913 BLOCK_COMMENT("Entry:");
7914 __ enter();
7915 __ mul_add(out, in, offset, len, k);
7916 __ leave();
7917 __ ret(lr);
7918
7919 AOTCodeCache::store_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start);
7920 return start;
7921 }
7922
7923 // Arguments:
7924 //
7925 // Input:
7926 // c_rarg0 - newArr address
7927 // c_rarg1 - oldArr address
7928 // c_rarg2 - newIdx
7929 // c_rarg3 - shiftCount
7930 // c_rarg4 - numIter
7931 //
7932 address generate_bigIntegerRightShift() {
7933 __ align(CodeEntryAlignment);
7934 StubId stub_id = StubId::stubgen_bigIntegerRightShiftWorker_id;
7935 StubCodeMark mark(this, stub_id);
7936 address start = __ pc();
7937
7938 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7939
|