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/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"
50 #include "runtime/javaThread.hpp"
4634 __ fmovd(temp1, vs2acc);
4635 __ add(s1, s1, temp0);
4636 __ add(s2, s2, temp1);
4637 }
4638
4639 /**
4640 * Arguments:
4641 *
4642 * Input:
4643 * c_rarg0 - x address
4644 * c_rarg1 - x length
4645 * c_rarg2 - y address
4646 * c_rarg3 - y length
4647 * c_rarg4 - z address
4648 */
4649 address generate_multiplyToLen() {
4650 __ align(CodeEntryAlignment);
4651 StubCodeMark mark(this, "StubRoutines", "multiplyToLen");
4652
4653 address start = __ pc();
4654 const Register x = r0;
4655 const Register xlen = r1;
4656 const Register y = r2;
4657 const Register ylen = r3;
4658 const Register z = r4;
4659
4660 const Register tmp0 = r5;
4661 const Register tmp1 = r10;
4662 const Register tmp2 = r11;
4663 const Register tmp3 = r12;
4664 const Register tmp4 = r13;
4665 const Register tmp5 = r14;
4666 const Register tmp6 = r15;
4667 const Register tmp7 = r16;
4668
4669 BLOCK_COMMENT("Entry:");
4670 __ enter(); // required for proper stackwalking of RuntimeStub frame
4671 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4672 __ leave(); // required for proper stackwalking of RuntimeStub frame
4673 __ ret(lr);
4674
4675 return start;
4676 }
4677
4678 address generate_squareToLen() {
4679 // squareToLen algorithm for sizes 1..127 described in java code works
4680 // faster than multiply_to_len on some CPUs and slower on others, but
4681 // multiply_to_len shows a bit better overall results
4682 __ align(CodeEntryAlignment);
4683 StubCodeMark mark(this, "StubRoutines", "squareToLen");
4684 address start = __ pc();
4685
4686 const Register x = r0;
4687 const Register xlen = r1;
4688 const Register z = r2;
4689 const Register y = r4; // == x
4690 const Register ylen = r5; // == xlen
4691
4692 const Register tmp0 = r3;
4693 const Register tmp1 = r10;
4694 const Register tmp2 = r11;
4695 const Register tmp3 = r12;
4696 const Register tmp4 = r13;
4697 const Register tmp5 = r14;
4698 const Register tmp6 = r15;
4699 const Register tmp7 = r16;
4700
4701 RegSet spilled_regs = RegSet::of(y, ylen);
4702 BLOCK_COMMENT("Entry:");
4703 __ enter();
4704 __ push(spilled_regs, sp);
4705 __ mov(y, x);
4706 __ mov(ylen, xlen);
4707 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4708 __ pop(spilled_regs, sp);
4709 __ leave();
4710 __ ret(lr);
4711 return start;
4712 }
4713
4714 address generate_mulAdd() {
4715 __ align(CodeEntryAlignment);
4716 StubCodeMark mark(this, "StubRoutines", "mulAdd");
4717
4718 address start = __ pc();
4719
4720 const Register out = r0;
4721 const Register in = r1;
4722 const Register offset = r2;
4723 const Register len = r3;
4724 const Register k = r4;
4725
4726 BLOCK_COMMENT("Entry:");
4727 __ enter();
4728 __ mul_add(out, in, offset, len, k);
4729 __ leave();
4730 __ ret(lr);
4731
4732 return start;
4733 }
4734
4735 // Arguments:
4736 //
4737 // Input:
4738 // c_rarg0 - newArr address
4739 // c_rarg1 - oldArr address
4740 // c_rarg2 - newIdx
4741 // c_rarg3 - shiftCount
4742 // c_rarg4 - numIter
4743 //
4744 address generate_bigIntegerRightShift() {
4745 __ align(CodeEntryAlignment);
4746 StubCodeMark mark(this, "StubRoutines", "bigIntegerRightShiftWorker");
4747 address start = __ pc();
4748
4749 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
4750
4751 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/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"
51 #include "runtime/javaThread.hpp"
4635 __ fmovd(temp1, vs2acc);
4636 __ add(s1, s1, temp0);
4637 __ add(s2, s2, temp1);
4638 }
4639
4640 /**
4641 * Arguments:
4642 *
4643 * Input:
4644 * c_rarg0 - x address
4645 * c_rarg1 - x length
4646 * c_rarg2 - y address
4647 * c_rarg3 - y length
4648 * c_rarg4 - z address
4649 */
4650 address generate_multiplyToLen() {
4651 __ align(CodeEntryAlignment);
4652 StubCodeMark mark(this, "StubRoutines", "multiplyToLen");
4653
4654 address start = __ pc();
4655
4656 if (SCCache::load_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start)) {
4657 return start;
4658 }
4659 const Register x = r0;
4660 const Register xlen = r1;
4661 const Register y = r2;
4662 const Register ylen = r3;
4663 const Register z = r4;
4664
4665 const Register tmp0 = r5;
4666 const Register tmp1 = r10;
4667 const Register tmp2 = r11;
4668 const Register tmp3 = r12;
4669 const Register tmp4 = r13;
4670 const Register tmp5 = r14;
4671 const Register tmp6 = r15;
4672 const Register tmp7 = r16;
4673
4674 BLOCK_COMMENT("Entry:");
4675 __ enter(); // required for proper stackwalking of RuntimeStub frame
4676 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4677 __ leave(); // required for proper stackwalking of RuntimeStub frame
4678 __ ret(lr);
4679
4680 SCCache::store_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start);
4681 return start;
4682 }
4683
4684 address generate_squareToLen() {
4685 // squareToLen algorithm for sizes 1..127 described in java code works
4686 // faster than multiply_to_len on some CPUs and slower on others, but
4687 // multiply_to_len shows a bit better overall results
4688 __ align(CodeEntryAlignment);
4689 StubCodeMark mark(this, "StubRoutines", "squareToLen");
4690 address start = __ pc();
4691
4692 if (SCCache::load_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start)) {
4693 return start;
4694 }
4695 const Register x = r0;
4696 const Register xlen = r1;
4697 const Register z = r2;
4698 const Register y = r4; // == x
4699 const Register ylen = r5; // == xlen
4700
4701 const Register tmp0 = r3;
4702 const Register tmp1 = r10;
4703 const Register tmp2 = r11;
4704 const Register tmp3 = r12;
4705 const Register tmp4 = r13;
4706 const Register tmp5 = r14;
4707 const Register tmp6 = r15;
4708 const Register tmp7 = r16;
4709
4710 RegSet spilled_regs = RegSet::of(y, ylen);
4711 BLOCK_COMMENT("Entry:");
4712 __ enter();
4713 __ push(spilled_regs, sp);
4714 __ mov(y, x);
4715 __ mov(ylen, xlen);
4716 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
4717 __ pop(spilled_regs, sp);
4718 __ leave();
4719 __ ret(lr);
4720
4721 SCCache::store_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start);
4722 return start;
4723 }
4724
4725 address generate_mulAdd() {
4726 __ align(CodeEntryAlignment);
4727 StubCodeMark mark(this, "StubRoutines", "mulAdd");
4728
4729 address start = __ pc();
4730
4731 if (SCCache::load_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start)) {
4732 return start;
4733 }
4734 const Register out = r0;
4735 const Register in = r1;
4736 const Register offset = r2;
4737 const Register len = r3;
4738 const Register k = r4;
4739
4740 BLOCK_COMMENT("Entry:");
4741 __ enter();
4742 __ mul_add(out, in, offset, len, k);
4743 __ leave();
4744 __ ret(lr);
4745
4746 SCCache::store_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start);
4747 return start;
4748 }
4749
4750 // Arguments:
4751 //
4752 // Input:
4753 // c_rarg0 - newArr address
4754 // c_rarg1 - oldArr address
4755 // c_rarg2 - newIdx
4756 // c_rarg3 - shiftCount
4757 // c_rarg4 - numIter
4758 //
4759 address generate_bigIntegerRightShift() {
4760 __ align(CodeEntryAlignment);
4761 StubCodeMark mark(this, "StubRoutines", "bigIntegerRightShiftWorker");
4762 address start = __ pc();
4763
4764 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
4765
4766 Register newArr = c_rarg0;
|