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
24source_hpp %{
25#include "gc/shenandoah/shenandoahBarrierSet.hpp"
26#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
27%}
28
29encode %{
30  enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{
31    MacroAssembler _masm(&cbuf);
32    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
33    Register tmp = $tmp$$Register;
34    __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
35    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
36                                                   /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register);
37  %}
38
39  enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{
40    MacroAssembler _masm(&cbuf);
41    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
42    Register tmp = $tmp$$Register;
43    __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
44    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
45                                                   /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register);
46  %}
47%}
48
49instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
50
51  match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
52  ins_cost(2 * VOLATILE_REF_COST);
53
54  effect(TEMP tmp, KILL cr);
55
56  format %{
57    "cmpxchg_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
58  %}
59
60  ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, res));
61
62  ins_pipe(pipe_slow);
63%}
64
65instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
66
67  match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
68  ins_cost(2 * VOLATILE_REF_COST);
69
70  effect(TEMP tmp, KILL cr);
71
72  format %{
73    "cmpxchgw_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
74  %}
75
76  ins_encode %{
77    Register tmp = $tmp$$Register;
78    __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
79    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register);
80  %}
81
82  ins_pipe(pipe_slow);
83%}
84
85instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
86
87  predicate(needs_acquiring_load_exclusive(n));
88  match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
89  ins_cost(VOLATILE_REF_COST);
90
91  effect(TEMP tmp, KILL cr);
92
93  format %{
94    "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
95  %}
96
97  ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, res));
98
99  ins_pipe(pipe_slow);
100%}
101
102instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
103
104  predicate(needs_acquiring_load_exclusive(n));
105  match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
106  ins_cost(VOLATILE_REF_COST);
107
108  effect(TEMP tmp, KILL cr);
109
110 format %{
111    "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
112 %}
113
114  ins_encode %{
115    Register tmp = $tmp$$Register;
116    __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
117    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register);
118  %}
119
120  ins_pipe(pipe_slow);
121%}
122
123instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
124  match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
125  ins_cost(3 * VOLATILE_REF_COST);
126  effect(TEMP_DEF res, TEMP tmp, KILL cr);
127  format %{
128    "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
129  %}
130  ins_encode %{
131    Register tmp = $tmp$$Register;
132    __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
133    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
134                                                   /*acquire*/ false, /*release*/ true, /*is_cae*/ true, $res$$Register);
135  %}
136  ins_pipe(pipe_slow);
137%}
138
139instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
140  match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
141  ins_cost(3 * VOLATILE_REF_COST);
142  effect(TEMP_DEF res, TEMP tmp, KILL cr);
143  format %{
144    "cmpxchg_oop_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
145  %}
146  ins_encode %{
147    Register tmp = $tmp$$Register;
148    __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
149    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
150                                                   /*acquire*/ false, /*release*/ true, /*is_cae*/ true, $res$$Register);
151  %}
152  ins_pipe(pipe_slow);
153%}
154
155instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
156  match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
157  ins_cost(3 * VOLATILE_REF_COST);
158  effect(TEMP tmp, KILL cr);
159  format %{
160    "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
161  %}
162  ins_encode %{
163    Register tmp = $tmp$$Register;
164    __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
165    // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop
166    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
167                                                   /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register);
168  %}
169  ins_pipe(pipe_slow);
170%}
171
172instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
173  match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval)));
174  ins_cost(3 * VOLATILE_REF_COST);
175  effect(TEMP tmp, KILL cr);
176  format %{
177    "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
178  %}
179  ins_encode %{
180    Register tmp = $tmp$$Register;
181    __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
182    // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop
183    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
184                                                   /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register);
185  %}
186  ins_pipe(pipe_slow);
187%}
188
189
190