< prev index next >

src/hotspot/cpu/aarch64/aarch64.ad

Print this page

        

*** 1,8 **** // // Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. ! // Copyright (c) 2014, Red Hat Inc. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License version 2 only, as // published by the Free Software Foundation. --- 1,8 ---- // // Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. ! // Copyright (c) 2014, 2018, Red Hat, Inc. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License version 2 only, as // published by the Free Software Foundation.
*** 998,1007 **** --- 998,1010 ---- #include "asm/macroAssembler.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/collectedHeap.hpp" #include "opto/addnode.hpp" + #if INCLUDE_SHENANDOAHGC + #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" + #endif class CallStubImpl { //-------------------------------------------------------------- //---< Used for optimization in Compile::shorten_branches >---
*** 1270,1279 **** --- 1273,1284 ---- // We handle these case Op_CompareAndSwapI: case Op_CompareAndSwapL: case Op_CompareAndSwapP: case Op_CompareAndSwapN: + case Op_ShenandoahCompareAndSwapP: + case Op_ShenandoahCompareAndSwapN: case Op_CompareAndSwapB: case Op_CompareAndSwapS: case Op_GetAndSetI: case Op_GetAndSetL: case Op_GetAndSetP:
*** 1291,1300 **** --- 1296,1309 ---- case Op_WeakCompareAndSwapS: case Op_WeakCompareAndSwapI: case Op_WeakCompareAndSwapL: case Op_WeakCompareAndSwapP: case Op_WeakCompareAndSwapN: + case Op_ShenandoahWeakCompareAndSwapP: + case Op_ShenandoahWeakCompareAndSwapN: + case Op_ShenandoahCompareAndExchangeP: + case Op_ShenandoahCompareAndExchangeN: return maybe_volatile; default: return false; } }
*** 2930,2939 **** --- 2939,2961 ---- Assembler::byte, /*acquire*/ false, /*release*/ true, /*weak*/ false, noreg); %} + enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{ + MacroAssembler _masm(&cbuf); + guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); + #else + ShouldNotReachHere(); + #endif + %} + // The only difference between aarch64_enc_cmpxchg and // aarch64_enc_cmpxchg_acq is that we use load-acquire in the // CompareAndSwap sequence to serve as a barrier on acquiring a // lock. enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
*** 2966,2975 **** --- 2988,3010 ---- __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, Assembler::byte, /*acquire*/ true, /*release*/ true, /*weak*/ false, noreg); %} + enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{ + MacroAssembler _masm(&cbuf); + guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); + #else + ShouldNotReachHere(); + #endif + %} + // auxiliary used for CompareAndSwapX to set result register enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ MacroAssembler _masm(&cbuf); Register res_reg = as_Register($res$$reg); __ cset(res_reg, Assembler::EQ);
*** 7916,7925 **** --- 7951,7975 ---- %} ins_pipe(ialu_reg); %} + instruct shenandoahRB(iRegPNoSp dst, iRegP src, rFlagsReg cr) %{ + match(Set dst (ShenandoahReadBarrier src)); + format %{ "shenandoah_rb $dst,$src" %} + ins_encode %{ + #if INCLUDE_SHENANDOAHGC + Register s = $src$$Register; + Register d = $dst$$Register; + __ ldr(d, Address(s, ShenandoahBrooksPointer::byte_offset())); + #else + ShouldNotReachHere(); + #endif + %} + ins_pipe(pipe_class_memory); + %} + // Convert oop pointer into compressed form instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); match(Set dst (EncodeP src));
*** 8242,8251 **** --- 8292,8319 ---- aarch64_enc_cset_eq(res)); ins_pipe(pipe_slow); %} + instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + + match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); + ins_cost(2 * VOLATILE_REF_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + + ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp), + aarch64_enc_cset_eq(res)); + + ins_pipe(pipe_slow); + %} + instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ match(Set res (CompareAndSwapN mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST);
*** 8260,8269 **** --- 8328,8363 ---- aarch64_enc_cset_eq(res)); ins_pipe(pipe_slow); %} + instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + + match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); + ins_cost(2 * VOLATILE_REF_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); + __ cset($res$$Register, Assembler::EQ); + #else + ShouldNotReachHere(); + #endif + %} + + ins_pipe(pipe_slow); + %} + // alternative CompareAndSwapX when we are eliding barriers instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ predicate(needs_acquiring_load_exclusive(n));
*** 8357,8366 **** --- 8451,8479 ---- aarch64_enc_cset_eq(res)); ins_pipe(pipe_slow); %} + instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + + predicate(needs_acquiring_load_exclusive(n)); + match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); + ins_cost(VOLATILE_REF_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + + ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp), + aarch64_enc_cset_eq(res)); + + ins_pipe(pipe_slow); + %} + instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ predicate(needs_acquiring_load_exclusive(n)); match(Set res (CompareAndSwapN mem (Binary oldval newval))); ins_cost(VOLATILE_REF_COST);
*** 8376,8385 **** --- 8489,8524 ---- aarch64_enc_cset_eq(res)); ins_pipe(pipe_slow); %} + instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + + predicate(needs_acquiring_load_exclusive(n)); + match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); + ins_cost(VOLATILE_REF_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); + __ cset($res$$Register, Assembler::EQ); + #else + ShouldNotReachHere(); + #endif + %} + + ins_pipe(pipe_slow); + %} // --------------------------------------------------------------------- // BEGIN This section of the file is automatically generated. Do not edit --------------
*** 8470,8479 **** --- 8609,8638 ---- /*weak*/ false, $res$$Register); %} ins_pipe(pipe_slow); %} + instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); + ins_cost(2 * VOLATILE_REF_COST); + effect(TEMP_DEF res, TEMP tmp, KILL cr); + format %{ + "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" + %} + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ false, /* encode*/ false, noreg, noreg, rscratch2, $res$$Register); + #else + ShouldNotReachHere(); + #endif + %} + ins_pipe(pipe_slow); + %} + instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ match(Set res (CompareAndExchangeP mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr); format %{
*** 8485,8494 **** --- 8644,8673 ---- /*weak*/ false, $res$$Register); %} ins_pipe(pipe_slow); %} + instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); + ins_cost(2 * VOLATILE_REF_COST); + effect(TEMP_DEF res, TEMP tmp, KILL cr); + format %{ + "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + %} + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg, rscratch2, $res$$Register); + #else + ShouldNotReachHere(); + #endif + %} + ins_pipe(pipe_slow); + %} + instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ predicate(needs_acquiring_load_exclusive(n)); match(Set res (CompareAndExchangeB mem (Binary oldval newval))); ins_cost(VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr);
*** 8569,8578 **** --- 8748,8778 ---- /*weak*/ false, $res$$Register); %} ins_pipe(pipe_slow); %} + instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); + ins_cost(VOLATILE_REF_COST); + effect(TEMP_DEF res, TEMP tmp, KILL cr); + format %{ + "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" + %} + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ true, /*release*/ true, /*weak*/ false, /* encode*/ false, noreg, noreg, rscratch2, $res$$Register); + #else + ShouldNotReachHere(); + #endif + %} + ins_pipe(pipe_slow); + %} + instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ predicate(needs_acquiring_load_exclusive(n)); match(Set res (CompareAndExchangeP mem (Binary oldval newval))); ins_cost(VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr);
*** 8585,8594 **** --- 8785,8815 ---- /*weak*/ false, $res$$Register); %} ins_pipe(pipe_slow); %} + instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); + ins_cost(VOLATILE_REF_COST); + effect(TEMP_DEF res, TEMP tmp, KILL cr); + format %{ + "cmpxchg_acq_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + %} + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg, rscratch2, $res$$Register); + #else + ShouldNotReachHere(); + #endif + %} + ins_pipe(pipe_slow); + %} + instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); effect(KILL cr); format %{
*** 8670,8679 **** --- 8891,8922 ---- __ csetw($res$$Register, Assembler::EQ); %} ins_pipe(pipe_slow); %} + instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); + ins_cost(2 * VOLATILE_REF_COST); + effect(TEMP tmp, KILL cr); + format %{ + "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" + "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); + #else + ShouldNotReachHere(); + #endif + __ csetw($res$$Register, Assembler::EQ); + %} + ins_pipe(pipe_slow); + %} + instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); effect(KILL cr); format %{
*** 8687,8696 **** --- 8930,8961 ---- __ csetw($res$$Register, Assembler::EQ); %} ins_pipe(pipe_slow); %} + instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); + ins_cost(2 * VOLATILE_REF_COST); + effect(TEMP tmp, KILL cr); + format %{ + "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" + "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); + #else + ShouldNotReachHere(); + #endif + __ csetw($res$$Register, Assembler::EQ); + %} + ins_pipe(pipe_slow); + %} + instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ predicate(needs_acquiring_load_exclusive(n)); match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); ins_cost(VOLATILE_REF_COST); effect(KILL cr);
*** 8777,8786 **** --- 9042,9074 ---- __ csetw($res$$Register, Assembler::EQ); %} ins_pipe(pipe_slow); %} + instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); + ins_cost(VOLATILE_REF_COST); + effect(TEMP tmp, KILL cr); + format %{ + "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" + "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ true, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); + #else + ShouldNotReachHere(); + #endif + __ csetw($res$$Register, Assembler::EQ); + %} + ins_pipe(pipe_slow); + %} + instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ predicate(needs_acquiring_load_exclusive(n)); match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); ins_cost(VOLATILE_REF_COST); effect(KILL cr);
*** 8795,8804 **** --- 9083,9115 ---- __ csetw($res$$Register, Assembler::EQ); %} ins_pipe(pipe_slow); %} + instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + predicate(needs_acquiring_load_exclusive(n)); + match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); + ins_cost(VOLATILE_REF_COST); + effect(TEMP tmp, KILL cr); + format %{ + "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" + "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + #if INCLUDE_SHENANDOAHGC + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ true, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); + #else + ShouldNotReachHere(); + #endif + __ csetw($res$$Register, Assembler::EQ); + %} + ins_pipe(pipe_slow); + %} + // END This section of the file is automatically generated. Do not edit -------------- // --------------------------------------------------------------------- instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ match(Set prev (GetAndSetI mem newv));
< prev index next >