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"
7386 __ add(s1, s1, temp0);
7387 __ add(s2, s2, temp1);
7388 }
7389
7390 /**
7391 * Arguments:
7392 *
7393 * Input:
7394 * c_rarg0 - x address
7395 * c_rarg1 - x length
7396 * c_rarg2 - y address
7397 * c_rarg3 - y length
7398 * c_rarg4 - z address
7399 */
7400 address generate_multiplyToLen() {
7401 __ align(CodeEntryAlignment);
7402 StubGenStubId stub_id = StubGenStubId::multiplyToLen_id;
7403 StubCodeMark mark(this, stub_id);
7404
7405 address start = __ pc();
7406 const Register x = r0;
7407 const Register xlen = r1;
7408 const Register y = r2;
7409 const Register ylen = r3;
7410 const Register z = r4;
7411
7412 const Register tmp0 = r5;
7413 const Register tmp1 = r10;
7414 const Register tmp2 = r11;
7415 const Register tmp3 = r12;
7416 const Register tmp4 = r13;
7417 const Register tmp5 = r14;
7418 const Register tmp6 = r15;
7419 const Register tmp7 = r16;
7420
7421 BLOCK_COMMENT("Entry:");
7422 __ enter(); // required for proper stackwalking of RuntimeStub frame
7423 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7424 __ leave(); // required for proper stackwalking of RuntimeStub frame
7425 __ ret(lr);
7426
7427 return start;
7428 }
7429
7430 address generate_squareToLen() {
7431 // squareToLen algorithm for sizes 1..127 described in java code works
7432 // faster than multiply_to_len on some CPUs and slower on others, but
7433 // multiply_to_len shows a bit better overall results
7434 __ align(CodeEntryAlignment);
7435 StubGenStubId stub_id = StubGenStubId::squareToLen_id;
7436 StubCodeMark mark(this, stub_id);
7437 address start = __ pc();
7438
7439 const Register x = r0;
7440 const Register xlen = r1;
7441 const Register z = r2;
7442 const Register y = r4; // == x
7443 const Register ylen = r5; // == xlen
7444
7445 const Register tmp0 = r3;
7446 const Register tmp1 = r10;
7447 const Register tmp2 = r11;
7448 const Register tmp3 = r12;
7449 const Register tmp4 = r13;
7450 const Register tmp5 = r14;
7451 const Register tmp6 = r15;
7452 const Register tmp7 = r16;
7453
7454 RegSet spilled_regs = RegSet::of(y, ylen);
7455 BLOCK_COMMENT("Entry:");
7456 __ enter();
7457 __ push(spilled_regs, sp);
7458 __ mov(y, x);
7459 __ mov(ylen, xlen);
7460 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7461 __ pop(spilled_regs, sp);
7462 __ leave();
7463 __ ret(lr);
7464 return start;
7465 }
7466
7467 address generate_mulAdd() {
7468 __ align(CodeEntryAlignment);
7469 StubGenStubId stub_id = StubGenStubId::mulAdd_id;
7470 StubCodeMark mark(this, stub_id);
7471
7472 address start = __ pc();
7473
7474 const Register out = r0;
7475 const Register in = r1;
7476 const Register offset = r2;
7477 const Register len = r3;
7478 const Register k = r4;
7479
7480 BLOCK_COMMENT("Entry:");
7481 __ enter();
7482 __ mul_add(out, in, offset, len, k);
7483 __ leave();
7484 __ ret(lr);
7485
7486 return start;
7487 }
7488
7489 // Arguments:
7490 //
7491 // Input:
7492 // c_rarg0 - newArr address
7493 // c_rarg1 - oldArr address
7494 // c_rarg2 - newIdx
7495 // c_rarg3 - shiftCount
7496 // c_rarg4 - numIter
7497 //
7498 address generate_bigIntegerRightShift() {
7499 __ align(CodeEntryAlignment);
7500 StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id;
7501 StubCodeMark mark(this, stub_id);
7502 address start = __ pc();
7503
7504 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7505
|
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/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"
7387 __ add(s1, s1, temp0);
7388 __ add(s2, s2, temp1);
7389 }
7390
7391 /**
7392 * Arguments:
7393 *
7394 * Input:
7395 * c_rarg0 - x address
7396 * c_rarg1 - x length
7397 * c_rarg2 - y address
7398 * c_rarg3 - y length
7399 * c_rarg4 - z address
7400 */
7401 address generate_multiplyToLen() {
7402 __ align(CodeEntryAlignment);
7403 StubGenStubId stub_id = StubGenStubId::multiplyToLen_id;
7404 StubCodeMark mark(this, stub_id);
7405
7406 address start = __ pc();
7407
7408 if (AOTCodeCache::load_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start)) {
7409 return start;
7410 }
7411 const Register x = r0;
7412 const Register xlen = r1;
7413 const Register y = r2;
7414 const Register ylen = r3;
7415 const Register z = r4;
7416
7417 const Register tmp0 = r5;
7418 const Register tmp1 = r10;
7419 const Register tmp2 = r11;
7420 const Register tmp3 = r12;
7421 const Register tmp4 = r13;
7422 const Register tmp5 = r14;
7423 const Register tmp6 = r15;
7424 const Register tmp7 = r16;
7425
7426 BLOCK_COMMENT("Entry:");
7427 __ enter(); // required for proper stackwalking of RuntimeStub frame
7428 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7429 __ leave(); // required for proper stackwalking of RuntimeStub frame
7430 __ ret(lr);
7431
7432 AOTCodeCache::store_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start);
7433 return start;
7434 }
7435
7436 address generate_squareToLen() {
7437 // squareToLen algorithm for sizes 1..127 described in java code works
7438 // faster than multiply_to_len on some CPUs and slower on others, but
7439 // multiply_to_len shows a bit better overall results
7440 __ align(CodeEntryAlignment);
7441 StubGenStubId stub_id = StubGenStubId::squareToLen_id;
7442 StubCodeMark mark(this, stub_id);
7443 address start = __ pc();
7444
7445 if (AOTCodeCache::load_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start)) {
7446 return start;
7447 }
7448 const Register x = r0;
7449 const Register xlen = r1;
7450 const Register z = r2;
7451 const Register y = r4; // == x
7452 const Register ylen = r5; // == xlen
7453
7454 const Register tmp0 = r3;
7455 const Register tmp1 = r10;
7456 const Register tmp2 = r11;
7457 const Register tmp3 = r12;
7458 const Register tmp4 = r13;
7459 const Register tmp5 = r14;
7460 const Register tmp6 = r15;
7461 const Register tmp7 = r16;
7462
7463 RegSet spilled_regs = RegSet::of(y, ylen);
7464 BLOCK_COMMENT("Entry:");
7465 __ enter();
7466 __ push(spilled_regs, sp);
7467 __ mov(y, x);
7468 __ mov(ylen, xlen);
7469 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7470 __ pop(spilled_regs, sp);
7471 __ leave();
7472 __ ret(lr);
7473
7474 AOTCodeCache::store_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start);
7475 return start;
7476 }
7477
7478 address generate_mulAdd() {
7479 __ align(CodeEntryAlignment);
7480 StubGenStubId stub_id = StubGenStubId::mulAdd_id;
7481 StubCodeMark mark(this, stub_id);
7482
7483 address start = __ pc();
7484
7485 if (AOTCodeCache::load_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start)) {
7486 return start;
7487 }
7488 const Register out = r0;
7489 const Register in = r1;
7490 const Register offset = r2;
7491 const Register len = r3;
7492 const Register k = r4;
7493
7494 BLOCK_COMMENT("Entry:");
7495 __ enter();
7496 __ mul_add(out, in, offset, len, k);
7497 __ leave();
7498 __ ret(lr);
7499
7500 AOTCodeCache::store_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start);
7501 return start;
7502 }
7503
7504 // Arguments:
7505 //
7506 // Input:
7507 // c_rarg0 - newArr address
7508 // c_rarg1 - oldArr address
7509 // c_rarg2 - newIdx
7510 // c_rarg3 - shiftCount
7511 // c_rarg4 - numIter
7512 //
7513 address generate_bigIntegerRightShift() {
7514 __ align(CodeEntryAlignment);
7515 StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id;
7516 StubCodeMark mark(this, stub_id);
7517 address start = __ pc();
7518
7519 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7520
|