9 *
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/assembler.hpp"
27 #include "asm/assembler.inline.hpp"
28 #include "ci/ciEnv.hpp"
29 #include "code/compiledIC.hpp"
30 #include "compiler/compileTask.hpp"
31 #include "compiler/disassembler.hpp"
32 #include "compiler/oopMap.hpp"
33 #include "gc/shared/barrierSet.hpp"
34 #include "gc/shared/barrierSetAssembler.hpp"
35 #include "gc/shared/cardTableBarrierSet.hpp"
36 #include "gc/shared/cardTable.hpp"
37 #include "gc/shared/collectedHeap.hpp"
38 #include "gc/shared/tlab_globals.hpp"
39 #include "interpreter/bytecodeHistogram.hpp"
40 #include "interpreter/interpreter.hpp"
41 #include "interpreter/interpreterRuntime.hpp"
42 #include "jvm.h"
43 #include "memory/resourceArea.hpp"
44 #include "memory/universe.hpp"
45 #include "nativeInst_aarch64.hpp"
46 #include "oops/accessDecorators.hpp"
47 #include "oops/compressedKlass.inline.hpp"
48 #include "oops/compressedOops.inline.hpp"
331 uint32_t insn2 = insn_at(insn_addr, 1);
332 uint32_t size = Instruction_aarch64::extract(insn2, 31, 30);
333 Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo >> size);
334 guarantee(((dest >> size) << size) == dest, "misaligned target");
335 return 2;
336 }
337 static int adrpAdd_impl(address insn_addr, address &target) {
338 uintptr_t dest = (uintptr_t)target;
339 int offset_lo = dest & 0xfff;
340 Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo);
341 return 2;
342 }
343 static int adrpMovk_impl(address insn_addr, address &target) {
344 uintptr_t dest = uintptr_t(target);
345 Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 20, 5, (uintptr_t)target >> 32);
346 dest = (dest & 0xffffffffULL) | (uintptr_t(insn_addr) & 0xffff00000000ULL);
347 target = address(dest);
348 return 2;
349 }
350 virtual int immediate(address insn_addr, address &target) {
351 assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
352 uint64_t dest = (uint64_t)target;
353 // Move wide constant
354 assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
355 assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
356 Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
357 Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
358 Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
359 return 3;
360 }
361 virtual void verify(address insn_addr, address &target) {
362 #ifdef ASSERT
363 address address_is = MacroAssembler::target_addr_for_insn(insn_addr);
364 if (!(address_is == target)) {
365 tty->print_cr("%p at %p should be %p", address_is, insn_addr, target);
366 disnm((intptr_t)insn_addr);
367 assert(address_is == target, "should be");
368 }
369 #endif
370 }
461 uint32_t insn2 = insn_at(insn_addr, 1);
462 uint64_t dest = uint64_t(target);
463 dest = (dest & 0xffff0000ffffffff) |
464 ((uint64_t)Instruction_aarch64::extract(insn2, 20, 5) << 32);
465 target = address(dest);
466
467 // We know the destination 4k page. Maybe we have a third
468 // instruction.
469 uint32_t insn = insn_at(insn_addr, 0);
470 uint32_t insn3 = insn_at(insn_addr, 2);
471 ptrdiff_t byte_offset;
472 if (offset_for(insn, insn3, byte_offset)) {
473 target += byte_offset;
474 return 3;
475 } else {
476 return 2;
477 }
478 }
479 virtual int immediate(address insn_addr, address &target) {
480 uint32_t *insns = (uint32_t *)insn_addr;
481 assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
482 // Move wide constant: movz, movk, movk. See movptr().
483 assert(nativeInstruction_at(insns+1)->is_movk(), "wrong insns in patch");
484 assert(nativeInstruction_at(insns+2)->is_movk(), "wrong insns in patch");
485 target = address(uint64_t(Instruction_aarch64::extract(_insn, 20, 5))
486 + (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16)
487 + (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32));
488 assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
489 assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
490 return 3;
491 }
492 virtual void verify(address insn_addr, address &target) {
493 }
494 };
495
496 address MacroAssembler::target_addr_for_insn(address insn_addr, uint32_t insn) {
497 AArch64Decoder decoder(insn_addr, insn);
498 address target;
499 decoder.run(insn_addr, target);
500 return target;
3324
3325 void MacroAssembler::sub(Register Rd, Register Rn, RegisterOrConstant decrement) {
3326 if (decrement.is_register()) {
3327 sub(Rd, Rn, decrement.as_register());
3328 } else {
3329 sub(Rd, Rn, decrement.as_constant());
3330 }
3331 }
3332
3333 void MacroAssembler::subw(Register Rd, Register Rn, RegisterOrConstant decrement) {
3334 if (decrement.is_register()) {
3335 subw(Rd, Rn, decrement.as_register());
3336 } else {
3337 subw(Rd, Rn, decrement.as_constant());
3338 }
3339 }
3340
3341 void MacroAssembler::reinit_heapbase()
3342 {
3343 if (UseCompressedOops) {
3344 if (Universe::is_fully_initialized()) {
3345 mov(rheapbase, CompressedOops::base());
3346 } else {
3347 lea(rheapbase, ExternalAddress(CompressedOops::base_addr()));
3348 ldr(rheapbase, Address(rheapbase));
3349 }
3350 }
3351 }
3352
3353 // this simulates the behaviour of the x86 cmpxchg instruction using a
3354 // load linked/store conditional pair. we use the acquire/release
3355 // versions of these instructions so that we flush pending writes as
3356 // per Java semantics.
3357
3358 // n.b the x86 version assumes the old value to be compared against is
3359 // in rax and updates rax with the value located in memory if the
3360 // cmpxchg fails. we supply a register for the old value explicitly
3361
3362 // the aarch64 load linked/store conditional instructions do not
3363 // accept an offset. so, unlike x86, we must provide a plain register
3364 // to identify the memory word to be compared/exchanged rather than a
5692 // the code cache so that if it is relocated we know it will still reach
5693 if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
5694 _adrp(reg1, dest.target());
5695 } else {
5696 uint64_t target = (uint64_t)dest.target();
5697 uint64_t adrp_target
5698 = (target & 0xffffffffULL) | ((uint64_t)pc() & 0xffff00000000ULL);
5699
5700 _adrp(reg1, (address)adrp_target);
5701 movk(reg1, target >> 32, 32);
5702 }
5703 byte_offset = (uint64_t)dest.target() & 0xfff;
5704 }
5705
5706 void MacroAssembler::load_byte_map_base(Register reg) {
5707 CardTable::CardValue* byte_map_base =
5708 ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
5709
5710 // Strictly speaking the byte_map_base isn't an address at all, and it might
5711 // even be negative. It is thus materialised as a constant.
5712 mov(reg, (uint64_t)byte_map_base);
5713 }
5714
5715 void MacroAssembler::build_frame(int framesize) {
5716 assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
5717 assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
5718 protect_return_address();
5719 if (framesize < ((1 << 9) + 2 * wordSize)) {
5720 sub(sp, sp, framesize);
5721 stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
5722 if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
5723 } else {
5724 stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
5725 if (PreserveFramePointer) mov(rfp, sp);
5726 if (framesize < ((1 << 12) + 2 * wordSize))
5727 sub(sp, sp, framesize - 2 * wordSize);
5728 else {
5729 mov(rscratch1, framesize - 2 * wordSize);
5730 sub(sp, sp, rscratch1);
5731 }
5732 }
|
9 *
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/assembler.hpp"
27 #include "asm/assembler.inline.hpp"
28 #include "ci/ciEnv.hpp"
29 #include "ci/ciUtilities.hpp"
30 #include "code/compiledIC.hpp"
31 #include "compiler/compileTask.hpp"
32 #include "compiler/disassembler.hpp"
33 #include "compiler/oopMap.hpp"
34 #include "gc/shared/barrierSet.hpp"
35 #include "gc/shared/barrierSetAssembler.hpp"
36 #include "gc/shared/cardTableBarrierSet.hpp"
37 #include "gc/shared/cardTable.hpp"
38 #include "gc/shared/collectedHeap.hpp"
39 #include "gc/shared/tlab_globals.hpp"
40 #include "interpreter/bytecodeHistogram.hpp"
41 #include "interpreter/interpreter.hpp"
42 #include "interpreter/interpreterRuntime.hpp"
43 #include "jvm.h"
44 #include "memory/resourceArea.hpp"
45 #include "memory/universe.hpp"
46 #include "nativeInst_aarch64.hpp"
47 #include "oops/accessDecorators.hpp"
48 #include "oops/compressedKlass.inline.hpp"
49 #include "oops/compressedOops.inline.hpp"
332 uint32_t insn2 = insn_at(insn_addr, 1);
333 uint32_t size = Instruction_aarch64::extract(insn2, 31, 30);
334 Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo >> size);
335 guarantee(((dest >> size) << size) == dest, "misaligned target");
336 return 2;
337 }
338 static int adrpAdd_impl(address insn_addr, address &target) {
339 uintptr_t dest = (uintptr_t)target;
340 int offset_lo = dest & 0xfff;
341 Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo);
342 return 2;
343 }
344 static int adrpMovk_impl(address insn_addr, address &target) {
345 uintptr_t dest = uintptr_t(target);
346 Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 20, 5, (uintptr_t)target >> 32);
347 dest = (dest & 0xffffffffULL) | (uintptr_t(insn_addr) & 0xffff00000000ULL);
348 target = address(dest);
349 return 2;
350 }
351 virtual int immediate(address insn_addr, address &target) {
352 // Metadata pointers are either narrow (32 bits) or wide (48 bits).
353 // We encode narrow ones by setting the upper 16 bits in the first
354 // instruction.
355 if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
356 assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
357 narrowKlass nk = CompressedKlassPointers::encode((Klass*)target);
358 Instruction_aarch64::patch(insn_addr, 20, 5, nk >> 16);
359 Instruction_aarch64::patch(insn_addr+4, 20, 5, nk & 0xffff);
360 return 2;
361 }
362 assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
363 uint64_t dest = (uint64_t)target;
364 // Move wide constant
365 assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
366 assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
367 Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
368 Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
369 Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
370 return 3;
371 }
372 virtual void verify(address insn_addr, address &target) {
373 #ifdef ASSERT
374 address address_is = MacroAssembler::target_addr_for_insn(insn_addr);
375 if (!(address_is == target)) {
376 tty->print_cr("%p at %p should be %p", address_is, insn_addr, target);
377 disnm((intptr_t)insn_addr);
378 assert(address_is == target, "should be");
379 }
380 #endif
381 }
472 uint32_t insn2 = insn_at(insn_addr, 1);
473 uint64_t dest = uint64_t(target);
474 dest = (dest & 0xffff0000ffffffff) |
475 ((uint64_t)Instruction_aarch64::extract(insn2, 20, 5) << 32);
476 target = address(dest);
477
478 // We know the destination 4k page. Maybe we have a third
479 // instruction.
480 uint32_t insn = insn_at(insn_addr, 0);
481 uint32_t insn3 = insn_at(insn_addr, 2);
482 ptrdiff_t byte_offset;
483 if (offset_for(insn, insn3, byte_offset)) {
484 target += byte_offset;
485 return 3;
486 } else {
487 return 2;
488 }
489 }
490 virtual int immediate(address insn_addr, address &target) {
491 uint32_t *insns = (uint32_t *)insn_addr;
492 // Metadata pointers are either narrow (32 bits) or wide (48 bits).
493 // We encode narrow ones by setting the upper 16 bits in the first
494 // instruction.
495 if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
496 assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
497 narrowKlass nk = (narrowKlass)((uint32_t(Instruction_aarch64::extract(_insn, 20, 5)) << 16)
498 + uint32_t(Instruction_aarch64::extract(insns[1], 20, 5)));
499 target = (address)CompressedKlassPointers::decode(nk);
500 return 2;
501 }
502 assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
503 // Move wide constant: movz, movk, movk. See movptr().
504 assert(nativeInstruction_at(insns+1)->is_movk(), "wrong insns in patch");
505 assert(nativeInstruction_at(insns+2)->is_movk(), "wrong insns in patch");
506 target = address(uint64_t(Instruction_aarch64::extract(_insn, 20, 5))
507 + (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16)
508 + (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32));
509 assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
510 assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
511 return 3;
512 }
513 virtual void verify(address insn_addr, address &target) {
514 }
515 };
516
517 address MacroAssembler::target_addr_for_insn(address insn_addr, uint32_t insn) {
518 AArch64Decoder decoder(insn_addr, insn);
519 address target;
520 decoder.run(insn_addr, target);
521 return target;
3345
3346 void MacroAssembler::sub(Register Rd, Register Rn, RegisterOrConstant decrement) {
3347 if (decrement.is_register()) {
3348 sub(Rd, Rn, decrement.as_register());
3349 } else {
3350 sub(Rd, Rn, decrement.as_constant());
3351 }
3352 }
3353
3354 void MacroAssembler::subw(Register Rd, Register Rn, RegisterOrConstant decrement) {
3355 if (decrement.is_register()) {
3356 subw(Rd, Rn, decrement.as_register());
3357 } else {
3358 subw(Rd, Rn, decrement.as_constant());
3359 }
3360 }
3361
3362 void MacroAssembler::reinit_heapbase()
3363 {
3364 if (UseCompressedOops) {
3365 if (Universe::is_fully_initialized() && !AOTCodeCache::is_on_for_dump()) {
3366 mov(rheapbase, CompressedOops::base());
3367 } else {
3368 lea(rheapbase, ExternalAddress(CompressedOops::base_addr()));
3369 ldr(rheapbase, Address(rheapbase));
3370 }
3371 }
3372 }
3373
3374 // this simulates the behaviour of the x86 cmpxchg instruction using a
3375 // load linked/store conditional pair. we use the acquire/release
3376 // versions of these instructions so that we flush pending writes as
3377 // per Java semantics.
3378
3379 // n.b the x86 version assumes the old value to be compared against is
3380 // in rax and updates rax with the value located in memory if the
3381 // cmpxchg fails. we supply a register for the old value explicitly
3382
3383 // the aarch64 load linked/store conditional instructions do not
3384 // accept an offset. so, unlike x86, we must provide a plain register
3385 // to identify the memory word to be compared/exchanged rather than a
5713 // the code cache so that if it is relocated we know it will still reach
5714 if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
5715 _adrp(reg1, dest.target());
5716 } else {
5717 uint64_t target = (uint64_t)dest.target();
5718 uint64_t adrp_target
5719 = (target & 0xffffffffULL) | ((uint64_t)pc() & 0xffff00000000ULL);
5720
5721 _adrp(reg1, (address)adrp_target);
5722 movk(reg1, target >> 32, 32);
5723 }
5724 byte_offset = (uint64_t)dest.target() & 0xfff;
5725 }
5726
5727 void MacroAssembler::load_byte_map_base(Register reg) {
5728 CardTable::CardValue* byte_map_base =
5729 ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
5730
5731 // Strictly speaking the byte_map_base isn't an address at all, and it might
5732 // even be negative. It is thus materialised as a constant.
5733 #if INCLUDE_CDS
5734 if (AOTCodeCache::is_on_for_dump()) {
5735 // AOT code needs relocation info for card table base
5736 lea(reg, ExternalAddress(reinterpret_cast<address>(byte_map_base)));
5737 } else {
5738 #endif
5739 mov(reg, (uint64_t)byte_map_base);
5740 #if INCLUDE_CDS
5741 }
5742 #endif
5743 }
5744
5745 void MacroAssembler::load_aotrc_address(Register reg, address a) {
5746 #if INCLUDE_CDS
5747 assert(AOTRuntimeConstants::contains(a), "address out of range for data area");
5748 if (AOTCodeCache::is_on_for_dump()) {
5749 // all aotrc field addresses should be registered in the AOTCodeCache address table
5750 lea(reg, ExternalAddress(a));
5751 } else {
5752 mov(reg, (uint64_t)a);
5753 }
5754 #else
5755 ShouldNotReachHere();
5756 #endif
5757 }
5758
5759 void MacroAssembler::build_frame(int framesize) {
5760 assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
5761 assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
5762 protect_return_address();
5763 if (framesize < ((1 << 9) + 2 * wordSize)) {
5764 sub(sp, sp, framesize);
5765 stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
5766 if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
5767 } else {
5768 stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
5769 if (PreserveFramePointer) mov(rfp, sp);
5770 if (framesize < ((1 << 12) + 2 * wordSize))
5771 sub(sp, sp, framesize - 2 * wordSize);
5772 else {
5773 mov(rscratch1, framesize - 2 * wordSize);
5774 sub(sp, sp, rscratch1);
5775 }
5776 }
|