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"
4802 __ add(s1, s1, temp0);
4803 __ add(s2, s2, temp1);
4804 }
4805
4806 /**
4807 * Arguments:
4808 *
4809 * Input:
4810 * c_rarg0 - x address
4811 * c_rarg1 - x length
4812 * c_rarg2 - y address
4813 * c_rarg3 - y length
4814 * c_rarg4 - z address
4815 */
4816 address generate_multiplyToLen() {
4817 __ align(CodeEntryAlignment);
4818 StubGenStubId stub_id = StubGenStubId::multiplyToLen_id;
4819 StubCodeMark mark(this, stub_id);
4820
4821 address start = __ pc();
4822 const Register x = r0;
4823 const Register xlen = r1;
4824 const Register y = r2;
4825 const Register ylen = r3;
4826 const Register z = r4;
4827
4828 const Register tmp0 = r5;
4829 const Register tmp1 = r10;
4830 const Register tmp2 = r11;
4831 const Register tmp3 = r12;
4832 const Register tmp4 = r13;
4833 const Register tmp5 = r14;
4834 const Register tmp6 = r15;
4835 const Register tmp7 = r16;
4836
4837 BLOCK_COMMENT("Entry:");
4838 __ enter(); // required for proper stackwalking of RuntimeStub frame
4839 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4840 __ leave(); // required for proper stackwalking of RuntimeStub frame
4841 __ ret(lr);
4842
4843 return start;
4844 }
4845
4846 address generate_squareToLen() {
4847 // squareToLen algorithm for sizes 1..127 described in java code works
4848 // faster than multiply_to_len on some CPUs and slower on others, but
4849 // multiply_to_len shows a bit better overall results
4850 __ align(CodeEntryAlignment);
4851 StubGenStubId stub_id = StubGenStubId::squareToLen_id;
4852 StubCodeMark mark(this, stub_id);
4853 address start = __ pc();
4854
4855 const Register x = r0;
4856 const Register xlen = r1;
4857 const Register z = r2;
4858 const Register y = r4; // == x
4859 const Register ylen = r5; // == xlen
4860
4861 const Register tmp0 = r3;
4862 const Register tmp1 = r10;
4863 const Register tmp2 = r11;
4864 const Register tmp3 = r12;
4865 const Register tmp4 = r13;
4866 const Register tmp5 = r14;
4867 const Register tmp6 = r15;
4868 const Register tmp7 = r16;
4869
4870 RegSet spilled_regs = RegSet::of(y, ylen);
4871 BLOCK_COMMENT("Entry:");
4872 __ enter();
4873 __ push(spilled_regs, sp);
4874 __ mov(y, x);
4875 __ mov(ylen, xlen);
4876 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4877 __ pop(spilled_regs, sp);
4878 __ leave();
4879 __ ret(lr);
4880 return start;
4881 }
4882
4883 address generate_mulAdd() {
4884 __ align(CodeEntryAlignment);
4885 StubGenStubId stub_id = StubGenStubId::mulAdd_id;
4886 StubCodeMark mark(this, stub_id);
4887
4888 address start = __ pc();
4889
4890 const Register out = r0;
4891 const Register in = r1;
4892 const Register offset = r2;
4893 const Register len = r3;
4894 const Register k = r4;
4895
4896 BLOCK_COMMENT("Entry:");
4897 __ enter();
4898 __ mul_add(out, in, offset, len, k);
4899 __ leave();
4900 __ ret(lr);
4901
4902 return start;
4903 }
4904
4905 // Arguments:
4906 //
4907 // Input:
4908 // c_rarg0 - newArr address
4909 // c_rarg1 - oldArr address
4910 // c_rarg2 - newIdx
4911 // c_rarg3 - shiftCount
4912 // c_rarg4 - numIter
4913 //
4914 address generate_bigIntegerRightShift() {
4915 __ align(CodeEntryAlignment);
4916 StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id;
4917 StubCodeMark mark(this, stub_id);
4918 address start = __ pc();
4919
4920 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
4921
|
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/SCCache.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"
4803 __ add(s1, s1, temp0);
4804 __ add(s2, s2, temp1);
4805 }
4806
4807 /**
4808 * Arguments:
4809 *
4810 * Input:
4811 * c_rarg0 - x address
4812 * c_rarg1 - x length
4813 * c_rarg2 - y address
4814 * c_rarg3 - y length
4815 * c_rarg4 - z address
4816 */
4817 address generate_multiplyToLen() {
4818 __ align(CodeEntryAlignment);
4819 StubGenStubId stub_id = StubGenStubId::multiplyToLen_id;
4820 StubCodeMark mark(this, stub_id);
4821
4822 address start = __ pc();
4823
4824 if (SCCache::load_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start)) {
4825 return start;
4826 }
4827 const Register x = r0;
4828 const Register xlen = r1;
4829 const Register y = r2;
4830 const Register ylen = r3;
4831 const Register z = r4;
4832
4833 const Register tmp0 = r5;
4834 const Register tmp1 = r10;
4835 const Register tmp2 = r11;
4836 const Register tmp3 = r12;
4837 const Register tmp4 = r13;
4838 const Register tmp5 = r14;
4839 const Register tmp6 = r15;
4840 const Register tmp7 = r16;
4841
4842 BLOCK_COMMENT("Entry:");
4843 __ enter(); // required for proper stackwalking of RuntimeStub frame
4844 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4845 __ leave(); // required for proper stackwalking of RuntimeStub frame
4846 __ ret(lr);
4847
4848 SCCache::store_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start);
4849 return start;
4850 }
4851
4852 address generate_squareToLen() {
4853 // squareToLen algorithm for sizes 1..127 described in java code works
4854 // faster than multiply_to_len on some CPUs and slower on others, but
4855 // multiply_to_len shows a bit better overall results
4856 __ align(CodeEntryAlignment);
4857 StubGenStubId stub_id = StubGenStubId::squareToLen_id;
4858 StubCodeMark mark(this, stub_id);
4859 address start = __ pc();
4860
4861 if (SCCache::load_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start)) {
4862 return start;
4863 }
4864 const Register x = r0;
4865 const Register xlen = r1;
4866 const Register z = r2;
4867 const Register y = r4; // == x
4868 const Register ylen = r5; // == xlen
4869
4870 const Register tmp0 = r3;
4871 const Register tmp1 = r10;
4872 const Register tmp2 = r11;
4873 const Register tmp3 = r12;
4874 const Register tmp4 = r13;
4875 const Register tmp5 = r14;
4876 const Register tmp6 = r15;
4877 const Register tmp7 = r16;
4878
4879 RegSet spilled_regs = RegSet::of(y, ylen);
4880 BLOCK_COMMENT("Entry:");
4881 __ enter();
4882 __ push(spilled_regs, sp);
4883 __ mov(y, x);
4884 __ mov(ylen, xlen);
4885 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4886 __ pop(spilled_regs, sp);
4887 __ leave();
4888 __ ret(lr);
4889
4890 SCCache::store_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start);
4891 return start;
4892 }
4893
4894 address generate_mulAdd() {
4895 __ align(CodeEntryAlignment);
4896 StubGenStubId stub_id = StubGenStubId::mulAdd_id;
4897 StubCodeMark mark(this, stub_id);
4898
4899 address start = __ pc();
4900
4901 if (SCCache::load_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start)) {
4902 return start;
4903 }
4904 const Register out = r0;
4905 const Register in = r1;
4906 const Register offset = r2;
4907 const Register len = r3;
4908 const Register k = r4;
4909
4910 BLOCK_COMMENT("Entry:");
4911 __ enter();
4912 __ mul_add(out, in, offset, len, k);
4913 __ leave();
4914 __ ret(lr);
4915
4916 SCCache::store_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start);
4917 return start;
4918 }
4919
4920 // Arguments:
4921 //
4922 // Input:
4923 // c_rarg0 - newArr address
4924 // c_rarg1 - oldArr address
4925 // c_rarg2 - newIdx
4926 // c_rarg3 - shiftCount
4927 // c_rarg4 - numIter
4928 //
4929 address generate_bigIntegerRightShift() {
4930 __ align(CodeEntryAlignment);
4931 StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id;
4932 StubCodeMark mark(this, stub_id);
4933 address start = __ pc();
4934
4935 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
4936
|