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 instruct shenandoahRB(rRegP dst, rRegP src, rFlagsReg cr) %{
  29   match(Set dst (ShenandoahReadBarrier src));
  30   effect(DEF dst, USE src);
  31   ins_cost(125); // XXX
  32   format %{ "shenandoah_rb $dst, $src" %}
  33   ins_encode %{
  34     Register d = $dst$$Register;
  35     Register s = $src$$Register;
  36     __ movptr(d, Address(s, ShenandoahBrooksPointer::byte_offset()));
  37   %}
  38   ins_pipe(ialu_reg_mem);
  39 %}
  40 
  41 instruct shenandoahRBNarrow(rRegP dst, rRegN src) %{
  42   predicate(UseCompressedOops && (Universe::narrow_oop_shift() == 0));
  43   match(Set dst (ShenandoahReadBarrier (DecodeN src)));
  44   effect(DEF dst, USE src);
  45   ins_cost(125); // XXX
  46   format %{ "shenandoah_rb $dst, $src" %}
  47   ins_encode %{
  48     Register d = $dst$$Register;
  49     Register s = $src$$Register;
  50     __ movptr(d, Address(r12, s, Address::times_1, ShenandoahBrooksPointer::byte_offset()));
  51   %}
  52   ins_pipe(ialu_reg_mem);
  53 %}
  54 
  55 instruct shenandoahRBNarrowShift(rRegP dst, rRegN src) %{
  56   predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
  57   match(Set dst (ShenandoahReadBarrier (DecodeN src)));
  58   effect(DEF dst, USE src);
  59   ins_cost(125); // XXX
  60   format %{ "shenandoah_rb $dst, $src" %}
  61   ins_encode %{
  62     Register d = $dst$$Register;
  63     Register s = $src$$Register;
  64     __ movptr(d, Address(r12, s, Address::times_8, ShenandoahBrooksPointer::byte_offset()));
  65   %}
  66   ins_pipe(ialu_reg_mem);
  67 %}
  68 
  69 instruct compareAndSwapP_shenandoah(rRegI res,
  70                                     memory mem_ptr,
  71                                     rRegP tmp1, rRegP tmp2,
  72                                     rax_RegP oldval, rRegP newval,
  73                                     rFlagsReg cr)
  74 %{
  75   predicate(VM_Version::supports_cx8());
  76   match(Set res (ShenandoahCompareAndSwapP mem_ptr (Binary oldval newval)));
  77   match(Set res (ShenandoahWeakCompareAndSwapP mem_ptr (Binary oldval newval)));
  78   effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
  79 
  80   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
  81 
  82   ins_encode %{
  83     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm,
  84                                                    $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
  85                                                    false, // swap
  86                                                    false, $tmp1$$Register, $tmp2$$Register
  87                                                    );
  88   %}
  89   ins_pipe( pipe_cmpxchg );
  90 %}
  91 
  92 instruct compareAndSwapN_shenandoah(rRegI res,
  93                                     memory mem_ptr,
  94                                     rRegP tmp1, rRegP tmp2,
  95                                     rax_RegN oldval, rRegN newval,
  96                                     rFlagsReg cr) %{
  97   match(Set res (ShenandoahCompareAndSwapN mem_ptr (Binary oldval newval)));
  98   match(Set res (ShenandoahWeakCompareAndSwapN mem_ptr (Binary oldval newval)));
  99   effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
 100 
 101   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
 102 
 103   ins_encode %{
 104     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm,
 105                                                    $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
 106                                                    false, // swap
 107                                                    false, $tmp1$$Register, $tmp2$$Register
 108                                                    );
 109   %}
 110   ins_pipe( pipe_cmpxchg );
 111 %}
 112 
 113 instruct compareAndExchangeN_shenandoah(memory mem_ptr,
 114                                         rax_RegN oldval, rRegN newval,
 115                                         rRegP tmp1, rRegP tmp2,
 116                                         rFlagsReg cr) %{
 117   match(Set oldval (ShenandoahCompareAndExchangeN mem_ptr (Binary oldval newval)));
 118   effect(TEMP tmp1, TEMP tmp2, KILL cr);
 119 
 120   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
 121 
 122   ins_encode %{
 123     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm,
 124                                                    NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
 125                                                    true, // exchange
 126                                                    false, $tmp1$$Register, $tmp2$$Register
 127                                                    );
 128   %}
 129   ins_pipe( pipe_cmpxchg );
 130 %}
 131 
 132 instruct compareAndExchangeP_shenandoah(memory mem_ptr,
 133                                         rax_RegP oldval, rRegP newval,
 134                                         rRegP tmp1, rRegP tmp2,
 135                                         rFlagsReg cr)
 136 %{
 137   predicate(VM_Version::supports_cx8());
 138   match(Set oldval (ShenandoahCompareAndExchangeP mem_ptr (Binary oldval newval)));
 139   effect(KILL cr, TEMP tmp1, TEMP tmp2);
 140   ins_cost(1000);
 141 
 142   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
 143 
 144   ins_encode %{
 145     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm,
 146                                                    NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
 147                                                    true,  // exchange
 148                                                    false, $tmp1$$Register, $tmp2$$Register
 149                                                    );
 150   %}
 151   ins_pipe( pipe_cmpxchg );
 152 %}