src/hotspot/cpu/aarch64/gc/shenandoah/shenandoah_aarch64.ad
changeset 52925 9c18c9d839d3
child 53519 74a5ef4c81cc
equal deleted inserted replaced
52924:420ff459906f 52925:9c18c9d839d3
       
     1 //
       
     2 // Copyright (c) 2018, Red Hat, Inc. All rights reserved.
       
     3 //
       
     4 // This code is free software; you can redistribute it and/or modify it
       
     5 // under the terms of the GNU General Public License version 2 only, as
       
     6 // published by the Free Software Foundation.
       
     7 //
       
     8 // This code is distributed in the hope that it will be useful, but WITHOUT
       
     9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    10 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    11 // version 2 for more details (a copy is included in the LICENSE file that
       
    12 // accompanied this code).
       
    13 //
       
    14 // You should have received a copy of the GNU General Public License version
       
    15 // 2 along with this work; if not, write to the Free Software Foundation,
       
    16 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    17 //
       
    18 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    19 // or visit www.oracle.com if you need additional information or have any
       
    20 // questions.
       
    21 //
       
    22 //
       
    23 
       
    24 source_hpp %{
       
    25 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
       
    26 %}
       
    27 
       
    28 encode %{
       
    29   enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
       
    30     MacroAssembler _masm(&cbuf);
       
    31     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
       
    32     Register tmp = $tmp$$Register;
       
    33     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
    34     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
    35                                                    /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg);
       
    36   %}
       
    37 
       
    38   enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
       
    39     MacroAssembler _masm(&cbuf);
       
    40     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
       
    41     Register tmp = $tmp$$Register;
       
    42     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
    43     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
    44                                                    /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg);
       
    45   %}
       
    46 %}
       
    47 
       
    48 instruct shenandoahRB(iRegPNoSp dst, iRegP src, rFlagsReg cr) %{
       
    49   match(Set dst (ShenandoahReadBarrier src));
       
    50   format %{ "shenandoah_rb $dst,$src" %}
       
    51   ins_encode %{
       
    52     Register s = $src$$Register;
       
    53     Register d = $dst$$Register;
       
    54     __ ldr(d, Address(s, ShenandoahBrooksPointer::byte_offset()));
       
    55   %}
       
    56   ins_pipe(pipe_class_memory);
       
    57 %}
       
    58 
       
    59 
       
    60 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
       
    61 
       
    62   match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
       
    63   ins_cost(2 * VOLATILE_REF_COST);
       
    64 
       
    65   effect(TEMP tmp, KILL cr);
       
    66 
       
    67   format %{
       
    68     "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
       
    69     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
       
    70   %}
       
    71 
       
    72   ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp),
       
    73              aarch64_enc_cset_eq(res));
       
    74 
       
    75   ins_pipe(pipe_slow);
       
    76 %}
       
    77 
       
    78 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
       
    79 
       
    80   match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
       
    81   ins_cost(2 * VOLATILE_REF_COST);
       
    82 
       
    83   effect(TEMP tmp, KILL cr);
       
    84 
       
    85   format %{
       
    86     "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
       
    87     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
       
    88   %}
       
    89 
       
    90   ins_encode %{
       
    91     Register tmp = $tmp$$Register;
       
    92     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
    93     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg);
       
    94     __ cset($res$$Register, Assembler::EQ);
       
    95   %}
       
    96 
       
    97   ins_pipe(pipe_slow);
       
    98 %}
       
    99 
       
   100 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
       
   101 
       
   102   predicate(needs_acquiring_load_exclusive(n));
       
   103   match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
       
   104   ins_cost(VOLATILE_REF_COST);
       
   105 
       
   106   effect(TEMP tmp, KILL cr);
       
   107 
       
   108   format %{
       
   109     "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
       
   110     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
       
   111   %}
       
   112 
       
   113   ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp),
       
   114              aarch64_enc_cset_eq(res));
       
   115 
       
   116   ins_pipe(pipe_slow);
       
   117 %}
       
   118 
       
   119 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
       
   120 
       
   121   predicate(needs_acquiring_load_exclusive(n));
       
   122   match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
       
   123   ins_cost(VOLATILE_REF_COST);
       
   124 
       
   125   effect(TEMP tmp, KILL cr);
       
   126 
       
   127  format %{
       
   128     "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
       
   129     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
       
   130  %}
       
   131 
       
   132   ins_encode %{
       
   133     Register tmp = $tmp$$Register;
       
   134     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
   135     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg);
       
   136     __ cset($res$$Register, Assembler::EQ);
       
   137   %}
       
   138 
       
   139   ins_pipe(pipe_slow);
       
   140 %}
       
   141 
       
   142 instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
       
   143   match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
       
   144   ins_cost(2 * VOLATILE_REF_COST);
       
   145   effect(TEMP_DEF res, TEMP tmp, KILL cr);
       
   146   format %{
       
   147     "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
       
   148   %}
       
   149   ins_encode %{
       
   150     Register tmp = $tmp$$Register;
       
   151     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
   152     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
   153                                                    /*acquire*/ false, /*release*/ true, /*weak*/ false, /* encode*/ false, noreg, noreg, rscratch2, $res$$Register);
       
   154   %}
       
   155   ins_pipe(pipe_slow);
       
   156 %}
       
   157 
       
   158 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
       
   159   match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
       
   160   ins_cost(2 * VOLATILE_REF_COST);
       
   161   effect(TEMP_DEF res, TEMP tmp, KILL cr);
       
   162   format %{
       
   163     "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
       
   164   %}
       
   165   ins_encode %{
       
   166     Register tmp = $tmp$$Register;
       
   167     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
   168     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
   169                                                    /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg, rscratch2, $res$$Register);
       
   170   %}
       
   171   ins_pipe(pipe_slow);
       
   172 %}
       
   173 
       
   174 instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
       
   175   predicate(needs_acquiring_load_exclusive(n));
       
   176   match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
       
   177   ins_cost(VOLATILE_REF_COST);
       
   178   effect(TEMP_DEF res, TEMP tmp, KILL cr);
       
   179   format %{
       
   180     "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
       
   181   %}
       
   182   ins_encode %{
       
   183     Register tmp = $tmp$$Register;
       
   184     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
   185     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
   186                                                    /*acquire*/ true, /*release*/ true, /*weak*/ false, /* encode*/ false, noreg, noreg, rscratch2, $res$$Register);
       
   187   %}
       
   188   ins_pipe(pipe_slow);
       
   189 %}
       
   190 
       
   191 instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
       
   192   predicate(needs_acquiring_load_exclusive(n));
       
   193   match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
       
   194   ins_cost(VOLATILE_REF_COST);
       
   195   effect(TEMP_DEF res, TEMP tmp, KILL cr);
       
   196   format %{
       
   197     "cmpxchg_acq_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
       
   198   %}
       
   199   ins_encode %{
       
   200     Register tmp = $tmp$$Register;
       
   201     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
   202     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
   203                                                    /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg, rscratch2, $res$$Register);
       
   204   %}
       
   205   ins_pipe(pipe_slow);
       
   206 %}
       
   207 
       
   208 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
       
   209   match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
       
   210   ins_cost(2 * VOLATILE_REF_COST);
       
   211   effect(TEMP tmp, KILL cr);
       
   212   format %{
       
   213     "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
       
   214     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
       
   215   %}
       
   216   ins_encode %{
       
   217     Register tmp = $tmp$$Register;
       
   218     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
   219     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
   220                                                    /*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg);
       
   221     __ csetw($res$$Register, Assembler::EQ);
       
   222   %}
       
   223   ins_pipe(pipe_slow);
       
   224 %}
       
   225 
       
   226 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
       
   227   match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval)));
       
   228   ins_cost(2 * VOLATILE_REF_COST);
       
   229   effect(TEMP tmp, KILL cr);
       
   230   format %{
       
   231     "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
       
   232     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
       
   233   %}
       
   234   ins_encode %{
       
   235     Register tmp = $tmp$$Register;
       
   236     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
   237     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
   238                                                    /*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg);
       
   239     __ csetw($res$$Register, Assembler::EQ);
       
   240   %}
       
   241   ins_pipe(pipe_slow);
       
   242 %}
       
   243 
       
   244 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
       
   245   predicate(needs_acquiring_load_exclusive(n));
       
   246   match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
       
   247   ins_cost(VOLATILE_REF_COST);
       
   248   effect(TEMP tmp, KILL cr);
       
   249   format %{
       
   250     "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
       
   251     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
       
   252   %}
       
   253   ins_encode %{
       
   254     Register tmp = $tmp$$Register;
       
   255     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
   256     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
   257                                                    /*acquire*/ true, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg);
       
   258     __ csetw($res$$Register, Assembler::EQ);
       
   259   %}
       
   260   ins_pipe(pipe_slow);
       
   261 %}
       
   262 
       
   263 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
       
   264   predicate(needs_acquiring_load_exclusive(n));
       
   265   match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval)));
       
   266   ins_cost(VOLATILE_REF_COST);
       
   267   effect(TEMP tmp, KILL cr);
       
   268   format %{
       
   269     "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
       
   270     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
       
   271   %}
       
   272   ins_encode %{
       
   273     Register tmp = $tmp$$Register;
       
   274     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
       
   275     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
       
   276                                                    /*acquire*/ true, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg);
       
   277     __ csetw($res$$Register, Assembler::EQ);
       
   278   %}
       
   279   ins_pipe(pipe_slow);
       
   280 %}
       
   281