< prev index next >

src/cpu/aarch64/vm/macroAssembler_aarch64.cpp

Print this page


   1 /*
   2 /*
   3  * Copyright (c) 2013, Red Hat Inc.
   4  * Copyright (c) 1997, 2012, Oracle and/or its affiliates.
   5  * All rights reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  23  * or visit www.oracle.com if you need additional information or have any
  24  * questions.
  25  *
  26  */
  27 
  28 #include <sys/types.h>
  29 
  30 #include "precompiled.hpp"
  31 #include "asm/assembler.hpp"
  32 #include "asm/assembler.inline.hpp"
  33 #include "interpreter/interpreter.hpp"
  34 
  35 #include "compiler/disassembler.hpp"

  36 #include "memory/resourceArea.hpp"
  37 #include "runtime/biasedLocking.hpp"
  38 #include "runtime/interfaceSupport.hpp"
  39 #include "runtime/sharedRuntime.hpp"
  40 
  41 // #include "gc_interface/collectedHeap.inline.hpp"
  42 // #include "interpreter/interpreter.hpp"
  43 // #include "memory/cardTableModRefBS.hpp"
  44 // #include "prims/methodHandles.hpp"
  45 // #include "runtime/biasedLocking.hpp"
  46 // #include "runtime/interfaceSupport.hpp"
  47 // #include "runtime/objectMonitor.hpp"
  48 // #include "runtime/os.hpp"
  49 // #include "runtime/sharedRuntime.hpp"
  50 // #include "runtime/stubRoutines.hpp"
  51 
  52 #if INCLUDE_ALL_GCS
  53 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  54 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  55 #include "gc_implementation/g1/heapRegion.hpp"

  56 #endif
  57 
  58 #ifdef COMPILER2
  59 #include "opto/node.hpp"
  60 #include "opto/compile.hpp"
  61 #endif
  62 
  63 #ifdef PRODUCT
  64 #define BLOCK_COMMENT(str) /* nothing */
  65 #define STOP(error) stop(error)
  66 #else
  67 #define BLOCK_COMMENT(str) block_comment(str)
  68 #define STOP(error) block_comment(error); stop(error)
  69 #endif
  70 
  71 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
  72 
  73 // Patch any kind of instruction; there may be several instructions.
  74 // Return the total length (in bytes) of the instructions.
  75 int MacroAssembler::pd_patch_instruction_size(address branch, address target) {


1627     // constant
1628     u_int32_t imm_h[2];
1629     imm_h[0] = imm32 & 0xffff;
1630     imm_h[1] = ((imm32 >> 16) & 0xffff);
1631     if (imm_h[0] == 0) {
1632       movzw(dst, imm_h[1], 16);
1633     } else if (imm_h[0] == 0xffff) {
1634       movnw(dst, imm_h[1] ^ 0xffff, 16);
1635     } else if (imm_h[1] == 0) {
1636       movzw(dst, imm_h[0], 0);
1637     } else if (imm_h[1] == 0xffff) {
1638       movnw(dst, imm_h[0] ^ 0xffff, 0);
1639     } else {
1640       // use a MOVZ and MOVK (makes it easier to debug)
1641       movzw(dst, imm_h[0], 0);
1642       movkw(dst, imm_h[1], 16);
1643     }
1644   }
1645 }
1646 






1647 // Form an address from base + offset in Rd.  Rd may or may
1648 // not actually be used: you must use the Address that is returned.
1649 // It is up to you to ensure that the shift provided matches the size
1650 // of your data.
1651 Address MacroAssembler::form_address(Register Rd, Register base, long byte_offset, int shift) {
1652   if (Address::offset_ok_for_immed(byte_offset, shift))
1653     // It fits; no need for any heroics
1654     return Address(base, byte_offset);
1655 
1656   // Don't do anything clever with negative or misaligned offsets
1657   unsigned mask = (1 << shift) - 1;
1658   if (byte_offset < 0 || byte_offset & mask) {
1659     mov(Rd, byte_offset);
1660     add(Rd, base, Rd);
1661     return Address(Rd);
1662   }
1663 
1664   // See if we can do this with two 12-bit offsets
1665   {
1666     unsigned long word_offset = byte_offset >> shift;


2350       tty->print_cr("r22 = 0x%016lx", regs[22]);
2351       tty->print_cr("r23 = 0x%016lx", regs[23]);
2352       tty->print_cr("r24 = 0x%016lx", regs[24]);
2353       tty->print_cr("r25 = 0x%016lx", regs[25]);
2354       tty->print_cr("r26 = 0x%016lx", regs[26]);
2355       tty->print_cr("r27 = 0x%016lx", regs[27]);
2356       tty->print_cr("r28 = 0x%016lx", regs[28]);
2357       tty->print_cr("r30 = 0x%016lx", regs[30]);
2358       tty->print_cr("r31 = 0x%016lx", regs[31]);
2359       BREAKPOINT;
2360     }
2361     ThreadStateTransition::transition(thread, _thread_in_vm, saved_state);
2362   } else {
2363     ttyLocker ttyl;
2364     ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n",
2365                     msg);
2366     assert(false, err_msg("DEBUG MESSAGE: %s", msg));
2367   }
2368 }
2369 
2370 void MacroAssembler::push_call_clobbered_registers() {
2371   push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
2372 
2373   // Push v0-v7, v16-v31.
2374   for (int i = 30; i >= 0; i -= 2) {
2375     if (i <= v7->encoding() || i >= v16->encoding()) {
2376         stpd(as_FloatRegister(i), as_FloatRegister(i+1),
2377              Address(pre(sp, -2 * wordSize)));
2378     }
2379   }
2380 }
2381 
2382 void MacroAssembler::pop_call_clobbered_registers() {
2383 
2384   for (int i = 0; i < 32; i += 2) {
2385     if (i <= v7->encoding() || i >= v16->encoding()) {
2386       ldpd(as_FloatRegister(i), as_FloatRegister(i+1),
2387            Address(post(sp, 2 * wordSize)));
2388     }
2389   }











2390 
2391   pop(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
2392 }
2393 
2394 void MacroAssembler::push_CPU_state(bool save_vectors) {
2395   push(0x3fffffff, sp);         // integer registers except lr & sp
2396 
2397   if (!save_vectors) {
2398     for (int i = 30; i >= 0; i -= 2)
2399       stpd(as_FloatRegister(i), as_FloatRegister(i+1),
2400            Address(pre(sp, -2 * wordSize)));
2401   } else {
2402     for (int i = 30; i >= 0; i -= 2)
2403       stpq(as_FloatRegister(i), as_FloatRegister(i+1),
2404            Address(pre(sp, -4 * wordSize)));
2405   }
2406 }
2407 
2408 void MacroAssembler::pop_CPU_state(bool restore_vectors) {
2409   if (!restore_vectors) {


3444   movz(dst, 0xDEAD, 16);
3445   movk(dst, 0xBEEF);
3446 }
3447 
3448 void  MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
3449   assert (UseCompressedClassPointers, "should only be used for compressed headers");
3450   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
3451   int index = oop_recorder()->find_index(k);
3452   assert(! Universe::heap()->is_in_reserved(k), "should not be an oop");
3453 
3454   InstructionMark im(this);
3455   RelocationHolder rspec = metadata_Relocation::spec(index);
3456   code_section()->relocate(inst_mark(), rspec);
3457   narrowKlass nk = Klass::encode_klass(k);
3458   movz(dst, (nk >> 16), 16);
3459   movk(dst, nk & 0xffff);
3460 }
3461 
3462 void MacroAssembler::load_heap_oop(Register dst, Address src)
3463 {







3464   if (UseCompressedOops) {
3465     ldrw(dst, src);
3466     decode_heap_oop(dst);
3467   } else {
3468     ldr(dst, src);
3469   }
3470 }
3471 
3472 void MacroAssembler::load_heap_oop_not_null(Register dst, Address src)
3473 {







3474   if (UseCompressedOops) {
3475     ldrw(dst, src);
3476     decode_heap_oop_not_null(dst);
3477   } else {
3478     ldr(dst, src);
3479   }
3480 }
3481 
3482 void MacroAssembler::store_heap_oop(Address dst, Register src) {
3483   if (UseCompressedOops) {
3484     assert(!dst.uses(src), "not enough registers");
3485     encode_heap_oop(src);
3486     strw(src, dst);
3487   } else
3488     str(src, dst);
3489 }
3490 
3491 // Used for storing NULLs.
3492 void MacroAssembler::store_heap_oop_null(Address dst) {
3493   if (UseCompressedOops) {


3596 }
3597 
3598 /*
3599  * g1_write_barrier_post -- G1GC post-write barrier for store of new_val at
3600  * store_addr
3601  *
3602  * Allocates rscratch1
3603  */
3604 void MacroAssembler::g1_write_barrier_post(Register store_addr,
3605                                            Register new_val,
3606                                            Register thread,
3607                                            Register tmp,
3608                                            Register tmp2) {
3609 #ifdef _LP64
3610   assert(thread == rthread, "must be");
3611 #endif // _LP64
3612   assert_different_registers(store_addr, new_val, thread, tmp, tmp2,
3613                              rscratch1);
3614   assert(store_addr != noreg && new_val != noreg && tmp != noreg
3615          && tmp2 != noreg, "expecting a register");







3616 
3617   Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3618                                        PtrQueue::byte_offset_of_index()));
3619   Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3620                                        PtrQueue::byte_offset_of_buf()));
3621 
3622   BarrierSet* bs = Universe::heap()->barrier_set();
3623   CardTableModRefBS* ct = (CardTableModRefBS*)bs;
3624   assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
3625 
3626   Label done;
3627   Label runtime;
3628 
3629   // Does store cross heap regions?
3630 
3631   eor(tmp, store_addr, new_val);
3632   lsr(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
3633   cbz(tmp, done);
3634 
3635   // crosses regions, storing NULL?


   1 /*

   2  * Copyright (c) 2013, Red Hat Inc.
   3  * Copyright (c) 1997, 2012, Oracle and/or its affiliates.
   4  * All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  *
  25  */
  26 
  27 #include <sys/types.h>
  28 
  29 #include "precompiled.hpp"
  30 #include "asm/assembler.hpp"
  31 #include "asm/assembler.inline.hpp"
  32 #include "interpreter/interpreter.hpp"
  33 
  34 #include "compiler/disassembler.hpp"
  35 #include "gc_interface/collectedHeap.inline.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "runtime/biasedLocking.hpp"
  38 #include "runtime/interfaceSupport.hpp"
  39 #include "runtime/sharedRuntime.hpp"
  40 
  41 // #include "gc_interface/collectedHeap.inline.hpp"
  42 // #include "interpreter/interpreter.hpp"
  43 // #include "memory/cardTableModRefBS.hpp"
  44 // #include "prims/methodHandles.hpp"
  45 // #include "runtime/biasedLocking.hpp"
  46 // #include "runtime/interfaceSupport.hpp"
  47 // #include "runtime/objectMonitor.hpp"
  48 // #include "runtime/os.hpp"
  49 // #include "runtime/sharedRuntime.hpp"
  50 // #include "runtime/stubRoutines.hpp"
  51 
  52 #if INCLUDE_ALL_GCS
  53 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  54 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  55 #include "gc_implementation/g1/heapRegion.hpp"
  56 #include "shenandoahBarrierSetAssembler_aarch64.hpp"
  57 #endif
  58 
  59 #ifdef COMPILER2
  60 #include "opto/node.hpp"
  61 #include "opto/compile.hpp"
  62 #endif
  63 
  64 #ifdef PRODUCT
  65 #define BLOCK_COMMENT(str) /* nothing */
  66 #define STOP(error) stop(error)
  67 #else
  68 #define BLOCK_COMMENT(str) block_comment(str)
  69 #define STOP(error) block_comment(error); stop(error)
  70 #endif
  71 
  72 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
  73 
  74 // Patch any kind of instruction; there may be several instructions.
  75 // Return the total length (in bytes) of the instructions.
  76 int MacroAssembler::pd_patch_instruction_size(address branch, address target) {


1628     // constant
1629     u_int32_t imm_h[2];
1630     imm_h[0] = imm32 & 0xffff;
1631     imm_h[1] = ((imm32 >> 16) & 0xffff);
1632     if (imm_h[0] == 0) {
1633       movzw(dst, imm_h[1], 16);
1634     } else if (imm_h[0] == 0xffff) {
1635       movnw(dst, imm_h[1] ^ 0xffff, 16);
1636     } else if (imm_h[1] == 0) {
1637       movzw(dst, imm_h[0], 0);
1638     } else if (imm_h[1] == 0xffff) {
1639       movnw(dst, imm_h[0] ^ 0xffff, 0);
1640     } else {
1641       // use a MOVZ and MOVK (makes it easier to debug)
1642       movzw(dst, imm_h[0], 0);
1643       movkw(dst, imm_h[1], 16);
1644     }
1645   }
1646 }
1647 
1648 void MacroAssembler::mov(Register dst, address addr) {
1649   assert(Universe::heap() == NULL
1650          || !Universe::heap()->is_in(addr), "use movptr for oop pointers");
1651     mov_immediate64(dst, (uintptr_t)addr);
1652 }
1653 
1654 // Form an address from base + offset in Rd.  Rd may or may
1655 // not actually be used: you must use the Address that is returned.
1656 // It is up to you to ensure that the shift provided matches the size
1657 // of your data.
1658 Address MacroAssembler::form_address(Register Rd, Register base, long byte_offset, int shift) {
1659   if (Address::offset_ok_for_immed(byte_offset, shift))
1660     // It fits; no need for any heroics
1661     return Address(base, byte_offset);
1662 
1663   // Don't do anything clever with negative or misaligned offsets
1664   unsigned mask = (1 << shift) - 1;
1665   if (byte_offset < 0 || byte_offset & mask) {
1666     mov(Rd, byte_offset);
1667     add(Rd, base, Rd);
1668     return Address(Rd);
1669   }
1670 
1671   // See if we can do this with two 12-bit offsets
1672   {
1673     unsigned long word_offset = byte_offset >> shift;


2357       tty->print_cr("r22 = 0x%016lx", regs[22]);
2358       tty->print_cr("r23 = 0x%016lx", regs[23]);
2359       tty->print_cr("r24 = 0x%016lx", regs[24]);
2360       tty->print_cr("r25 = 0x%016lx", regs[25]);
2361       tty->print_cr("r26 = 0x%016lx", regs[26]);
2362       tty->print_cr("r27 = 0x%016lx", regs[27]);
2363       tty->print_cr("r28 = 0x%016lx", regs[28]);
2364       tty->print_cr("r30 = 0x%016lx", regs[30]);
2365       tty->print_cr("r31 = 0x%016lx", regs[31]);
2366       BREAKPOINT;
2367     }
2368     ThreadStateTransition::transition(thread, _thread_in_vm, saved_state);
2369   } else {
2370     ttyLocker ttyl;
2371     ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n",
2372                     msg);
2373     assert(false, err_msg("DEBUG MESSAGE: %s", msg));
2374   }
2375 }
2376 
2377 void MacroAssembler::push_call_clobbered_fp_registers() {


2378   // Push v0-v7, v16-v31.
2379   for (int i = 30; i >= 0; i -= 2) {
2380     if (i <= v7->encoding() || i >= v16->encoding()) {
2381         stpd(as_FloatRegister(i), as_FloatRegister(i+1),
2382              Address(pre(sp, -2 * wordSize)));
2383     }
2384   }
2385 }
2386 
2387 void MacroAssembler::pop_call_clobbered_fp_registers() {
2388 
2389   for (int i = 0; i < 32; i += 2) {
2390     if (i <= v7->encoding() || i >= v16->encoding()) {
2391       ldpd(as_FloatRegister(i), as_FloatRegister(i+1),
2392            Address(post(sp, 2 * wordSize)));
2393     }
2394   }
2395 }
2396 
2397 void MacroAssembler::push_call_clobbered_registers() {
2398   push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
2399 
2400   push_call_clobbered_fp_registers();
2401 }
2402 
2403 void MacroAssembler::pop_call_clobbered_registers() {
2404 
2405   pop_call_clobbered_fp_registers();
2406 
2407   pop(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
2408 }
2409 
2410 void MacroAssembler::push_CPU_state(bool save_vectors) {
2411   push(0x3fffffff, sp);         // integer registers except lr & sp
2412 
2413   if (!save_vectors) {
2414     for (int i = 30; i >= 0; i -= 2)
2415       stpd(as_FloatRegister(i), as_FloatRegister(i+1),
2416            Address(pre(sp, -2 * wordSize)));
2417   } else {
2418     for (int i = 30; i >= 0; i -= 2)
2419       stpq(as_FloatRegister(i), as_FloatRegister(i+1),
2420            Address(pre(sp, -4 * wordSize)));
2421   }
2422 }
2423 
2424 void MacroAssembler::pop_CPU_state(bool restore_vectors) {
2425   if (!restore_vectors) {


3460   movz(dst, 0xDEAD, 16);
3461   movk(dst, 0xBEEF);
3462 }
3463 
3464 void  MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
3465   assert (UseCompressedClassPointers, "should only be used for compressed headers");
3466   assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
3467   int index = oop_recorder()->find_index(k);
3468   assert(! Universe::heap()->is_in_reserved(k), "should not be an oop");
3469 
3470   InstructionMark im(this);
3471   RelocationHolder rspec = metadata_Relocation::spec(index);
3472   code_section()->relocate(inst_mark(), rspec);
3473   narrowKlass nk = Klass::encode_klass(k);
3474   movz(dst, (nk >> 16), 16);
3475   movk(dst, nk & 0xffff);
3476 }
3477 
3478 void MacroAssembler::load_heap_oop(Register dst, Address src)
3479 {
3480 #if INCLUDE_ALL_GCS
3481   if (UseShenandoahGC) {
3482     ShenandoahBarrierSetAssembler::bsasm()->load_heap_oop(this, dst, src);
3483     return;
3484   }
3485 #endif
3486 
3487   if (UseCompressedOops) {
3488     ldrw(dst, src);
3489     decode_heap_oop(dst);
3490   } else {
3491     ldr(dst, src);
3492   }
3493 }
3494 
3495 void MacroAssembler::load_heap_oop_not_null(Register dst, Address src)
3496 {
3497 #if INCLUDE_ALL_GCS
3498   if (UseShenandoahGC) {
3499     ShenandoahBarrierSetAssembler::bsasm()->load_heap_oop(this, dst, src);
3500     return;
3501   }
3502 #endif
3503 
3504   if (UseCompressedOops) {
3505     ldrw(dst, src);
3506     decode_heap_oop_not_null(dst);
3507   } else {
3508     ldr(dst, src);
3509   }
3510 }
3511 
3512 void MacroAssembler::store_heap_oop(Address dst, Register src) {
3513   if (UseCompressedOops) {
3514     assert(!dst.uses(src), "not enough registers");
3515     encode_heap_oop(src);
3516     strw(src, dst);
3517   } else
3518     str(src, dst);
3519 }
3520 
3521 // Used for storing NULLs.
3522 void MacroAssembler::store_heap_oop_null(Address dst) {
3523   if (UseCompressedOops) {


3626 }
3627 
3628 /*
3629  * g1_write_barrier_post -- G1GC post-write barrier for store of new_val at
3630  * store_addr
3631  *
3632  * Allocates rscratch1
3633  */
3634 void MacroAssembler::g1_write_barrier_post(Register store_addr,
3635                                            Register new_val,
3636                                            Register thread,
3637                                            Register tmp,
3638                                            Register tmp2) {
3639 #ifdef _LP64
3640   assert(thread == rthread, "must be");
3641 #endif // _LP64
3642   assert_different_registers(store_addr, new_val, thread, tmp, tmp2,
3643                              rscratch1);
3644   assert(store_addr != noreg && new_val != noreg && tmp != noreg
3645          && tmp2 != noreg, "expecting a register");
3646 
3647   if (UseShenandoahGC) {
3648     // No need for this in Shenandoah.
3649     return;
3650   }
3651 
3652   assert(UseG1GC, "expect G1 GC");
3653 
3654   Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3655                                        PtrQueue::byte_offset_of_index()));
3656   Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3657                                        PtrQueue::byte_offset_of_buf()));
3658 
3659   BarrierSet* bs = Universe::heap()->barrier_set();
3660   CardTableModRefBS* ct = (CardTableModRefBS*)bs;
3661   assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
3662 
3663   Label done;
3664   Label runtime;
3665 
3666   // Does store cross heap regions?
3667 
3668   eor(tmp, store_addr, new_val);
3669   lsr(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
3670   cbz(tmp, done);
3671 
3672   // crosses regions, storing NULL?


< prev index next >