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"
7266 __ add(s1, s1, temp0);
7267 __ add(s2, s2, temp1);
7268 }
7269
7270 /**
7271 * Arguments:
7272 *
7273 * Input:
7274 * c_rarg0 - x address
7275 * c_rarg1 - x length
7276 * c_rarg2 - y address
7277 * c_rarg3 - y length
7278 * c_rarg4 - z address
7279 */
7280 address generate_multiplyToLen() {
7281 __ align(CodeEntryAlignment);
7282 StubGenStubId stub_id = StubGenStubId::multiplyToLen_id;
7283 StubCodeMark mark(this, stub_id);
7284
7285 address start = __ pc();
7286 const Register x = r0;
7287 const Register xlen = r1;
7288 const Register y = r2;
7289 const Register ylen = r3;
7290 const Register z = r4;
7291
7292 const Register tmp0 = r5;
7293 const Register tmp1 = r10;
7294 const Register tmp2 = r11;
7295 const Register tmp3 = r12;
7296 const Register tmp4 = r13;
7297 const Register tmp5 = r14;
7298 const Register tmp6 = r15;
7299 const Register tmp7 = r16;
7300
7301 BLOCK_COMMENT("Entry:");
7302 __ enter(); // required for proper stackwalking of RuntimeStub frame
7303 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7304 __ leave(); // required for proper stackwalking of RuntimeStub frame
7305 __ ret(lr);
7306
7307 return start;
7308 }
7309
7310 address generate_squareToLen() {
7311 // squareToLen algorithm for sizes 1..127 described in java code works
7312 // faster than multiply_to_len on some CPUs and slower on others, but
7313 // multiply_to_len shows a bit better overall results
7314 __ align(CodeEntryAlignment);
7315 StubGenStubId stub_id = StubGenStubId::squareToLen_id;
7316 StubCodeMark mark(this, stub_id);
7317 address start = __ pc();
7318
7319 const Register x = r0;
7320 const Register xlen = r1;
7321 const Register z = r2;
7322 const Register y = r4; // == x
7323 const Register ylen = r5; // == xlen
7324
7325 const Register tmp0 = r3;
7326 const Register tmp1 = r10;
7327 const Register tmp2 = r11;
7328 const Register tmp3 = r12;
7329 const Register tmp4 = r13;
7330 const Register tmp5 = r14;
7331 const Register tmp6 = r15;
7332 const Register tmp7 = r16;
7333
7334 RegSet spilled_regs = RegSet::of(y, ylen);
7335 BLOCK_COMMENT("Entry:");
7336 __ enter();
7337 __ push(spilled_regs, sp);
7338 __ mov(y, x);
7339 __ mov(ylen, xlen);
7340 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7341 __ pop(spilled_regs, sp);
7342 __ leave();
7343 __ ret(lr);
7344 return start;
7345 }
7346
7347 address generate_mulAdd() {
7348 __ align(CodeEntryAlignment);
7349 StubGenStubId stub_id = StubGenStubId::mulAdd_id;
7350 StubCodeMark mark(this, stub_id);
7351
7352 address start = __ pc();
7353
7354 const Register out = r0;
7355 const Register in = r1;
7356 const Register offset = r2;
7357 const Register len = r3;
7358 const Register k = r4;
7359
7360 BLOCK_COMMENT("Entry:");
7361 __ enter();
7362 __ mul_add(out, in, offset, len, k);
7363 __ leave();
7364 __ ret(lr);
7365
7366 return start;
7367 }
7368
7369 // Arguments:
7370 //
7371 // Input:
7372 // c_rarg0 - newArr address
7373 // c_rarg1 - oldArr address
7374 // c_rarg2 - newIdx
7375 // c_rarg3 - shiftCount
7376 // c_rarg4 - numIter
7377 //
7378 address generate_bigIntegerRightShift() {
7379 __ align(CodeEntryAlignment);
7380 StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id;
7381 StubCodeMark mark(this, stub_id);
7382 address start = __ pc();
7383
7384 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7385
|
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"
7267 __ add(s1, s1, temp0);
7268 __ add(s2, s2, temp1);
7269 }
7270
7271 /**
7272 * Arguments:
7273 *
7274 * Input:
7275 * c_rarg0 - x address
7276 * c_rarg1 - x length
7277 * c_rarg2 - y address
7278 * c_rarg3 - y length
7279 * c_rarg4 - z address
7280 */
7281 address generate_multiplyToLen() {
7282 __ align(CodeEntryAlignment);
7283 StubGenStubId stub_id = StubGenStubId::multiplyToLen_id;
7284 StubCodeMark mark(this, stub_id);
7285
7286 address start = __ pc();
7287
7288 if (AOTCodeCache::load_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start)) {
7289 return start;
7290 }
7291 const Register x = r0;
7292 const Register xlen = r1;
7293 const Register y = r2;
7294 const Register ylen = r3;
7295 const Register z = r4;
7296
7297 const Register tmp0 = r5;
7298 const Register tmp1 = r10;
7299 const Register tmp2 = r11;
7300 const Register tmp3 = r12;
7301 const Register tmp4 = r13;
7302 const Register tmp5 = r14;
7303 const Register tmp6 = r15;
7304 const Register tmp7 = r16;
7305
7306 BLOCK_COMMENT("Entry:");
7307 __ enter(); // required for proper stackwalking of RuntimeStub frame
7308 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7309 __ leave(); // required for proper stackwalking of RuntimeStub frame
7310 __ ret(lr);
7311
7312 AOTCodeCache::store_stub(this, vmIntrinsics::_multiplyToLen, "multiplyToLen", start);
7313 return start;
7314 }
7315
7316 address generate_squareToLen() {
7317 // squareToLen algorithm for sizes 1..127 described in java code works
7318 // faster than multiply_to_len on some CPUs and slower on others, but
7319 // multiply_to_len shows a bit better overall results
7320 __ align(CodeEntryAlignment);
7321 StubGenStubId stub_id = StubGenStubId::squareToLen_id;
7322 StubCodeMark mark(this, stub_id);
7323 address start = __ pc();
7324
7325 if (AOTCodeCache::load_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start)) {
7326 return start;
7327 }
7328 const Register x = r0;
7329 const Register xlen = r1;
7330 const Register z = r2;
7331 const Register y = r4; // == x
7332 const Register ylen = r5; // == xlen
7333
7334 const Register tmp0 = r3;
7335 const Register tmp1 = r10;
7336 const Register tmp2 = r11;
7337 const Register tmp3 = r12;
7338 const Register tmp4 = r13;
7339 const Register tmp5 = r14;
7340 const Register tmp6 = r15;
7341 const Register tmp7 = r16;
7342
7343 RegSet spilled_regs = RegSet::of(y, ylen);
7344 BLOCK_COMMENT("Entry:");
7345 __ enter();
7346 __ push(spilled_regs, sp);
7347 __ mov(y, x);
7348 __ mov(ylen, xlen);
7349 __ multiply_to_len(x, xlen, y, ylen, z, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
7350 __ pop(spilled_regs, sp);
7351 __ leave();
7352 __ ret(lr);
7353
7354 AOTCodeCache::store_stub(this, vmIntrinsics::_squareToLen, "squareToLen", start);
7355 return start;
7356 }
7357
7358 address generate_mulAdd() {
7359 __ align(CodeEntryAlignment);
7360 StubGenStubId stub_id = StubGenStubId::mulAdd_id;
7361 StubCodeMark mark(this, stub_id);
7362
7363 address start = __ pc();
7364
7365 if (AOTCodeCache::load_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start)) {
7366 return start;
7367 }
7368 const Register out = r0;
7369 const Register in = r1;
7370 const Register offset = r2;
7371 const Register len = r3;
7372 const Register k = r4;
7373
7374 BLOCK_COMMENT("Entry:");
7375 __ enter();
7376 __ mul_add(out, in, offset, len, k);
7377 __ leave();
7378 __ ret(lr);
7379
7380 AOTCodeCache::store_stub(this, vmIntrinsics::_mulAdd, "mulAdd", start);
7381 return start;
7382 }
7383
7384 // Arguments:
7385 //
7386 // Input:
7387 // c_rarg0 - newArr address
7388 // c_rarg1 - oldArr address
7389 // c_rarg2 - newIdx
7390 // c_rarg3 - shiftCount
7391 // c_rarg4 - numIter
7392 //
7393 address generate_bigIntegerRightShift() {
7394 __ align(CodeEntryAlignment);
7395 StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id;
7396 StubCodeMark mark(this, stub_id);
7397 address start = __ pc();
7398
7399 Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit;
7400
|