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 "precompiled.hpp"
27 #include "asm/macroAssembler.hpp"
28 #include "asm/macroAssembler.inline.hpp"
29 #include "asm/register.hpp"
30 #include "atomic_aarch64.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"
4659 __ fmovd(temp1, vs2acc);
4660 __ add(s1, s1, temp0);
4661 __ add(s2, s2, temp1);
4662 }
4663
4664 /**
4665 * Arguments:
4666 *
4667 * Input:
4668 * c_rarg0 - x address
4669 * c_rarg1 - x length
4670 * c_rarg2 - y address
4671 * c_rarg3 - y length
4672 * c_rarg4 - z address
4673 */
4674 address generate_multiplyToLen() {
4675 __ align(CodeEntryAlignment);
4676 StubCodeMark mark(this, "StubRoutines", "multiplyToLen");
4677
4678 address start = __ pc();
4679 const Register x = r0;
4680 const Register xlen = r1;
4681 const Register y = r2;
4682 const Register ylen = r3;
4683 const Register z = r4;
4684
4685 const Register tmp0 = r5;
4686 const Register tmp1 = r10;
4687 const Register tmp2 = r11;
4688 const Register tmp3 = r12;
4689 const Register tmp4 = r13;
4690 const Register tmp5 = r14;
4691 const Register tmp6 = r15;
4692 const Register tmp7 = r16;
4693
4694 BLOCK_COMMENT("Entry:");
4695 __ enter(); // required for proper stackwalking of RuntimeStub frame
4696 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4697 __ leave(); // required for proper stackwalking of RuntimeStub frame
4698 __ ret(lr);
4699
4700 return start;
4701 }
4702
4703 address generate_squareToLen() {
4704 // squareToLen algorithm for sizes 1..127 described in java code works
4705 // faster than multiply_to_len on some CPUs and slower on others, but
4706 // multiply_to_len shows a bit better overall results
4707 __ align(CodeEntryAlignment);
4708 StubCodeMark mark(this, "StubRoutines", "squareToLen");
4709 address start = __ pc();
4710
4711 const Register x = r0;
4712 const Register xlen = r1;
4713 const Register z = r2;
4714 const Register y = r4; // == x
4715 const Register ylen = r5; // == xlen
4716
4717 const Register tmp0 = r3;
4718 const Register tmp1 = r10;
4719 const Register tmp2 = r11;
4720 const Register tmp3 = r12;
4721 const Register tmp4 = r13;
4722 const Register tmp5 = r14;
4723 const Register tmp6 = r15;
4724 const Register tmp7 = r16;
4725
4726 RegSet spilled_regs = RegSet::of(y, ylen);
4727 BLOCK_COMMENT("Entry:");
4728 __ enter();
4729 __ push(spilled_regs, sp);
4730 __ mov(y, x);
4731 __ mov(ylen, xlen);
4732 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4733 __ pop(spilled_regs, sp);
4734 __ leave();
4735 __ ret(lr);
4736 return start;
4737 }
4738
4739 address generate_mulAdd() {
4740 __ align(CodeEntryAlignment);
4741 StubCodeMark mark(this, "StubRoutines", "mulAdd");
4742
4743 address start = __ pc();
4744
4745 const Register out = r0;
4746 const Register in = r1;
4747 const Register offset = r2;
4748 const Register len = r3;
4749 const Register k = r4;
4750
4751 BLOCK_COMMENT("Entry:");
4752 __ enter();
4753 __ mul_add(out, in, offset, len, k);
4754 __ leave();
4755 __ ret(lr);
4756
4757 return start;
4758 }
4759
4760 // Arguments:
4761 //
4762 // Input:
4763 // c_rarg0 - newArr address
4764 // c_rarg1 - oldArr address
4765 // c_rarg2 - newIdx
4766 // c_rarg3 - shiftCount
4767 // c_rarg4 - numIter
4768 //
4769 address generate_bigIntegerRightShift() {
4770 __ align(CodeEntryAlignment);
4771 StubCodeMark mark(this, "StubRoutines", "bigIntegerRightShiftWorker");
4772 address start = __ pc();
4773
4774 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
4775
4776 Register newArr = c_rarg0;
|
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 "precompiled.hpp"
27 #include "asm/macroAssembler.hpp"
28 #include "asm/macroAssembler.inline.hpp"
29 #include "asm/register.hpp"
30 #include "atomic_aarch64.hpp"
31 #include "code/SCCache.hpp"
32 #include "compiler/oopMap.hpp"
33 #include "gc/shared/barrierSet.hpp"
34 #include "gc/shared/barrierSetAssembler.hpp"
35 #include "gc/shared/gc_globals.hpp"
36 #include "gc/shared/tlab_globals.hpp"
37 #include "interpreter/interpreter.hpp"
38 #include "memory/universe.hpp"
39 #include "nativeInst_aarch64.hpp"
40 #include "oops/instanceOop.hpp"
41 #include "oops/method.hpp"
42 #include "oops/objArrayKlass.hpp"
43 #include "oops/oop.inline.hpp"
44 #include "prims/methodHandles.hpp"
45 #include "prims/upcallLinker.hpp"
46 #include "runtime/arguments.hpp"
47 #include "runtime/atomic.hpp"
48 #include "runtime/continuation.hpp"
49 #include "runtime/continuationEntry.inline.hpp"
50 #include "runtime/frame.inline.hpp"
51 #include "runtime/handles.inline.hpp"
4660 __ fmovd(temp1, vs2acc);
4661 __ add(s1, s1, temp0);
4662 __ add(s2, s2, temp1);
4663 }
4664
4665 /**
4666 * Arguments:
4667 *
4668 * Input:
4669 * c_rarg0 - x address
4670 * c_rarg1 - x length
4671 * c_rarg2 - y address
4672 * c_rarg3 - y length
4673 * c_rarg4 - z address
4674 */
4675 address generate_multiplyToLen() {
4676 __ align(CodeEntryAlignment);
4677 StubCodeMark mark(this, "StubRoutines", "multiplyToLen");
4678
4679 address start = __ pc();
4680
4681 if (SCCache::load_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start)) {
4682 return start;
4683 }
4684 const Register x = r0;
4685 const Register xlen = r1;
4686 const Register y = r2;
4687 const Register ylen = r3;
4688 const Register z = r4;
4689
4690 const Register tmp0 = r5;
4691 const Register tmp1 = r10;
4692 const Register tmp2 = r11;
4693 const Register tmp3 = r12;
4694 const Register tmp4 = r13;
4695 const Register tmp5 = r14;
4696 const Register tmp6 = r15;
4697 const Register tmp7 = r16;
4698
4699 BLOCK_COMMENT("Entry:");
4700 __ enter(); // required for proper stackwalking of RuntimeStub frame
4701 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4702 __ leave(); // required for proper stackwalking of RuntimeStub frame
4703 __ ret(lr);
4704
4705 SCCache::store_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start);
4706 return start;
4707 }
4708
4709 address generate_squareToLen() {
4710 // squareToLen algorithm for sizes 1..127 described in java code works
4711 // faster than multiply_to_len on some CPUs and slower on others, but
4712 // multiply_to_len shows a bit better overall results
4713 __ align(CodeEntryAlignment);
4714 StubCodeMark mark(this, "StubRoutines", "squareToLen");
4715 address start = __ pc();
4716
4717 if (SCCache::load_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start)) {
4718 return start;
4719 }
4720 const Register x = r0;
4721 const Register xlen = r1;
4722 const Register z = r2;
4723 const Register y = r4; // == x
4724 const Register ylen = r5; // == xlen
4725
4726 const Register tmp0 = r3;
4727 const Register tmp1 = r10;
4728 const Register tmp2 = r11;
4729 const Register tmp3 = r12;
4730 const Register tmp4 = r13;
4731 const Register tmp5 = r14;
4732 const Register tmp6 = r15;
4733 const Register tmp7 = r16;
4734
4735 RegSet spilled_regs = RegSet::of(y, ylen);
4736 BLOCK_COMMENT("Entry:");
4737 __ enter();
4738 __ push(spilled_regs, sp);
4739 __ mov(y, x);
4740 __ mov(ylen, xlen);
4741 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4742 __ pop(spilled_regs, sp);
4743 __ leave();
4744 __ ret(lr);
4745
4746 SCCache::store_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start);
4747 return start;
4748 }
4749
4750 address generate_mulAdd() {
4751 __ align(CodeEntryAlignment);
4752 StubCodeMark mark(this, "StubRoutines", "mulAdd");
4753
4754 address start = __ pc();
4755
4756 if (SCCache::load_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start)) {
4757 return start;
4758 }
4759 const Register out = r0;
4760 const Register in = r1;
4761 const Register offset = r2;
4762 const Register len = r3;
4763 const Register k = r4;
4764
4765 BLOCK_COMMENT("Entry:");
4766 __ enter();
4767 __ mul_add(out, in, offset, len, k);
4768 __ leave();
4769 __ ret(lr);
4770
4771 SCCache::store_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start);
4772 return start;
4773 }
4774
4775 // Arguments:
4776 //
4777 // Input:
4778 // c_rarg0 - newArr address
4779 // c_rarg1 - oldArr address
4780 // c_rarg2 - newIdx
4781 // c_rarg3 - shiftCount
4782 // c_rarg4 - numIter
4783 //
4784 address generate_bigIntegerRightShift() {
4785 __ align(CodeEntryAlignment);
4786 StubCodeMark mark(this, "StubRoutines", "bigIntegerRightShiftWorker");
4787 address start = __ pc();
4788
4789 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
4790
4791 Register newArr = c_rarg0;
|