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"
5869 __ add(s1, s1, temp0);
5870 __ add(s2, s2, temp1);
5871 }
5872
5873 /**
5874 * Arguments:
5875 *
5876 * Input:
5877 * c_rarg0 - x address
5878 * c_rarg1 - x length
5879 * c_rarg2 - y address
5880 * c_rarg3 - y length
5881 * c_rarg4 - z address
5882 */
5883 address generate_multiplyToLen() {
5884 __ align(CodeEntryAlignment);
5885 StubGenStubId stub_id = StubGenStubId::multiplyToLen_id;
5886 StubCodeMark mark(this, stub_id);
5887
5888 address start = __ pc();
5889 const Register x = r0;
5890 const Register xlen = r1;
5891 const Register y = r2;
5892 const Register ylen = r3;
5893 const Register z = r4;
5894
5895 const Register tmp0 = r5;
5896 const Register tmp1 = r10;
5897 const Register tmp2 = r11;
5898 const Register tmp3 = r12;
5899 const Register tmp4 = r13;
5900 const Register tmp5 = r14;
5901 const Register tmp6 = r15;
5902 const Register tmp7 = r16;
5903
5904 BLOCK_COMMENT("Entry:");
5905 __ enter(); // required for proper stackwalking of RuntimeStub frame
5906 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
5907 __ leave(); // required for proper stackwalking of RuntimeStub frame
5908 __ ret(lr);
5909
5910 return start;
5911 }
5912
5913 address generate_squareToLen() {
5914 // squareToLen algorithm for sizes 1..127 described in java code works
5915 // faster than multiply_to_len on some CPUs and slower on others, but
5916 // multiply_to_len shows a bit better overall results
5917 __ align(CodeEntryAlignment);
5918 StubGenStubId stub_id = StubGenStubId::squareToLen_id;
5919 StubCodeMark mark(this, stub_id);
5920 address start = __ pc();
5921
5922 const Register x = r0;
5923 const Register xlen = r1;
5924 const Register z = r2;
5925 const Register y = r4; // == x
5926 const Register ylen = r5; // == xlen
5927
5928 const Register tmp0 = r3;
5929 const Register tmp1 = r10;
5930 const Register tmp2 = r11;
5931 const Register tmp3 = r12;
5932 const Register tmp4 = r13;
5933 const Register tmp5 = r14;
5934 const Register tmp6 = r15;
5935 const Register tmp7 = r16;
5936
5937 RegSet spilled_regs = RegSet::of(y, ylen);
5938 BLOCK_COMMENT("Entry:");
5939 __ enter();
5940 __ push(spilled_regs, sp);
5941 __ mov(y, x);
5942 __ mov(ylen, xlen);
5943 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
5944 __ pop(spilled_regs, sp);
5945 __ leave();
5946 __ ret(lr);
5947 return start;
5948 }
5949
5950 address generate_mulAdd() {
5951 __ align(CodeEntryAlignment);
5952 StubGenStubId stub_id = StubGenStubId::mulAdd_id;
5953 StubCodeMark mark(this, stub_id);
5954
5955 address start = __ pc();
5956
5957 const Register out = r0;
5958 const Register in = r1;
5959 const Register offset = r2;
5960 const Register len = r3;
5961 const Register k = r4;
5962
5963 BLOCK_COMMENT("Entry:");
5964 __ enter();
5965 __ mul_add(out, in, offset, len, k);
5966 __ leave();
5967 __ ret(lr);
5968
5969 return start;
5970 }
5971
5972 // Arguments:
5973 //
5974 // Input:
5975 // c_rarg0 - newArr address
5976 // c_rarg1 - oldArr address
5977 // c_rarg2 - newIdx
5978 // c_rarg3 - shiftCount
5979 // c_rarg4 - numIter
5980 //
5981 address generate_bigIntegerRightShift() {
5982 __ align(CodeEntryAlignment);
5983 StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id;
5984 StubCodeMark mark(this, stub_id);
5985 address start = __ pc();
5986
5987 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
5988
|
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"
5870 __ add(s1, s1, temp0);
5871 __ add(s2, s2, temp1);
5872 }
5873
5874 /**
5875 * Arguments:
5876 *
5877 * Input:
5878 * c_rarg0 - x address
5879 * c_rarg1 - x length
5880 * c_rarg2 - y address
5881 * c_rarg3 - y length
5882 * c_rarg4 - z address
5883 */
5884 address generate_multiplyToLen() {
5885 __ align(CodeEntryAlignment);
5886 StubGenStubId stub_id = StubGenStubId::multiplyToLen_id;
5887 StubCodeMark mark(this, stub_id);
5888
5889 address start = __ pc();
5890
5891 if (SCCache::load_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start)) {
5892 return start;
5893 }
5894 const Register x = r0;
5895 const Register xlen = r1;
5896 const Register y = r2;
5897 const Register ylen = r3;
5898 const Register z = r4;
5899
5900 const Register tmp0 = r5;
5901 const Register tmp1 = r10;
5902 const Register tmp2 = r11;
5903 const Register tmp3 = r12;
5904 const Register tmp4 = r13;
5905 const Register tmp5 = r14;
5906 const Register tmp6 = r15;
5907 const Register tmp7 = r16;
5908
5909 BLOCK_COMMENT("Entry:");
5910 __ enter(); // required for proper stackwalking of RuntimeStub frame
5911 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
5912 __ leave(); // required for proper stackwalking of RuntimeStub frame
5913 __ ret(lr);
5914
5915 SCCache::store_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start);
5916 return start;
5917 }
5918
5919 address generate_squareToLen() {
5920 // squareToLen algorithm for sizes 1..127 described in java code works
5921 // faster than multiply_to_len on some CPUs and slower on others, but
5922 // multiply_to_len shows a bit better overall results
5923 __ align(CodeEntryAlignment);
5924 StubGenStubId stub_id = StubGenStubId::squareToLen_id;
5925 StubCodeMark mark(this, stub_id);
5926 address start = __ pc();
5927
5928 if (SCCache::load_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start)) {
5929 return start;
5930 }
5931 const Register x = r0;
5932 const Register xlen = r1;
5933 const Register z = r2;
5934 const Register y = r4; // == x
5935 const Register ylen = r5; // == xlen
5936
5937 const Register tmp0 = r3;
5938 const Register tmp1 = r10;
5939 const Register tmp2 = r11;
5940 const Register tmp3 = r12;
5941 const Register tmp4 = r13;
5942 const Register tmp5 = r14;
5943 const Register tmp6 = r15;
5944 const Register tmp7 = r16;
5945
5946 RegSet spilled_regs = RegSet::of(y, ylen);
5947 BLOCK_COMMENT("Entry:");
5948 __ enter();
5949 __ push(spilled_regs, sp);
5950 __ mov(y, x);
5951 __ mov(ylen, xlen);
5952 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
5953 __ pop(spilled_regs, sp);
5954 __ leave();
5955 __ ret(lr);
5956
5957 SCCache::store_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start);
5958 return start;
5959 }
5960
5961 address generate_mulAdd() {
5962 __ align(CodeEntryAlignment);
5963 StubGenStubId stub_id = StubGenStubId::mulAdd_id;
5964 StubCodeMark mark(this, stub_id);
5965
5966 address start = __ pc();
5967
5968 if (SCCache::load_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start)) {
5969 return start;
5970 }
5971 const Register out = r0;
5972 const Register in = r1;
5973 const Register offset = r2;
5974 const Register len = r3;
5975 const Register k = r4;
5976
5977 BLOCK_COMMENT("Entry:");
5978 __ enter();
5979 __ mul_add(out, in, offset, len, k);
5980 __ leave();
5981 __ ret(lr);
5982
5983 SCCache::store_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start);
5984 return start;
5985 }
5986
5987 // Arguments:
5988 //
5989 // Input:
5990 // c_rarg0 - newArr address
5991 // c_rarg1 - oldArr address
5992 // c_rarg2 - newIdx
5993 // c_rarg3 - shiftCount
5994 // c_rarg4 - numIter
5995 //
5996 address generate_bigIntegerRightShift() {
5997 __ align(CodeEntryAlignment);
5998 StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id;
5999 StubCodeMark mark(this, stub_id);
6000 address start = __ pc();
6001
6002 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
6003
|