1 //
2 // Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2014, 2024, Red Hat, Inc. All rights reserved.
4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 //
6 // This code is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License version 2 only, as
8 // published by the Free Software Foundation.
9 //
10 // This code is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // version 2 for more details (a copy is included in the LICENSE file that
14 // accompanied this code).
15 //
16 // You should have received a copy of the GNU General Public License version
17 // 2 along with this work; if not, write to the Free Software Foundation,
18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 // or visit www.oracle.com if you need additional information or have any
22 // questions.
23 //
24 //
25
26 // AArch64 Architecture Description File
27
28 //----------REGISTER DEFINITION BLOCK------------------------------------------
29 // This information is used by the matcher and the register allocator to
30 // describe individual registers and classes of registers within the target
31 // architecture.
32
33 register %{
34 //----------Architecture Description Register Definitions----------------------
35 // General Registers
36 // "reg_def" name ( register save type, C convention save type,
37 // ideal register type, encoding );
38 // Register Save Types:
39 //
40 // NS = No-Save: The register allocator assumes that these registers
41 // can be used without saving upon entry to the method, &
42 // that they do not need to be saved at call sites.
43 //
44 // SOC = Save-On-Call: The register allocator assumes that these registers
45 // can be used without saving upon entry to the method,
46 // but that they must be saved at call sites.
47 //
48 // SOE = Save-On-Entry: The register allocator assumes that these registers
49 // must be saved before using them upon entry to the
50 // method, but they do not need to be saved at call
51 // sites.
52 //
53 // AS = Always-Save: The register allocator assumes that these registers
54 // must be saved before using them upon entry to the
55 // method, & that they must be saved at call sites.
56 //
57 // Ideal Register Type is used to determine how to save & restore a
58 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
59 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
60 //
61 // The encoding number is the actual bit-pattern placed into the opcodes.
62
63 // We must define the 64 bit int registers in two 32 bit halves, the
64 // real lower register and a virtual upper half register. upper halves
65 // are used by the register allocator but are not actually supplied as
66 // operands to memory ops.
67 //
68 // follow the C1 compiler in making registers
69 //
70 // r0-r7,r10-r26 volatile (caller save)
71 // r27-r32 system (no save, no allocate)
72 // r8-r9 non-allocatable (so we can use them as scratch regs)
73 //
74 // as regards Java usage. we don't use any callee save registers
75 // because this makes it difficult to de-optimise a frame (see comment
76 // in x86 implementation of Deoptimization::unwind_callee_save_values)
77 //
78
79 // General Registers
80
81 reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() );
82 reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() );
83 reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() );
84 reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() );
85 reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() );
86 reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() );
87 reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() );
88 reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() );
89 reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() );
90 reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() );
91 reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() );
92 reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() );
93 reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() );
94 reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() );
95 reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() );
96 reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() );
97 reg_def R8 ( NS, SOC, Op_RegI, 8, r8->as_VMReg() ); // rscratch1, non-allocatable
98 reg_def R8_H ( NS, SOC, Op_RegI, 8, r8->as_VMReg()->next() );
99 reg_def R9 ( NS, SOC, Op_RegI, 9, r9->as_VMReg() ); // rscratch2, non-allocatable
100 reg_def R9_H ( NS, SOC, Op_RegI, 9, r9->as_VMReg()->next() );
101 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() );
102 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
103 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() );
104 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
105 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() );
106 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next());
107 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() );
108 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next());
109 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() );
110 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next());
111 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() );
112 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next());
113 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() );
114 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next());
115 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() );
116 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next());
117 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg() );
118 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg()->next());
119 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() );
120 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next());
121 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp
122 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next());
123 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() );
124 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next());
125 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() );
126 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next());
127 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() );
128 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next());
129 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() );
130 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next());
131 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() );
132 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next());
133 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() );
134 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next());
135 reg_def R27 ( SOC, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase
136 reg_def R27_H ( SOC, SOE, Op_RegI, 27, r27->as_VMReg()->next());
137 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread
138 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next());
139 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp
140 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next());
141 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr
142 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next());
143 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp
144 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next());
145
146 // ----------------------------
147 // Float/Double/Vector Registers
148 // ----------------------------
149
150 // Double Registers
151
152 // The rules of ADL require that double registers be defined in pairs.
153 // Each pair must be two 32-bit values, but not necessarily a pair of
154 // single float registers. In each pair, ADLC-assigned register numbers
155 // must be adjacent, with the lower number even. Finally, when the
156 // CPU stores such a register pair to memory, the word associated with
157 // the lower ADLC-assigned number must be stored to the lower address.
158
159 // AArch64 has 32 floating-point registers. Each can store a vector of
160 // single or double precision floating-point values up to 8 * 32
161 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only
162 // use the first float or double element of the vector.
163
164 // for Java use float registers v0-v15 are always save on call whereas
165 // the platform ABI treats v8-v15 as callee save). float registers
166 // v16-v31 are SOC as per the platform spec
167
168 // For SVE vector registers, we simply extend vector register size to 8
169 // 'logical' slots. This is nominally 256 bits but it actually covers
170 // all possible 'physical' SVE vector register lengths from 128 ~ 2048
171 // bits. The 'physical' SVE vector register length is detected during
172 // startup, so the register allocator is able to identify the correct
173 // number of bytes needed for an SVE spill/unspill.
174 // Note that a vector register with 4 slots denotes a 128-bit NEON
175 // register allowing it to be distinguished from the corresponding SVE
176 // vector register when the SVE vector length is 128 bits.
177
178 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() );
179 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() );
180 reg_def V0_J ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(2) );
181 reg_def V0_K ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(3) );
182
183 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() );
184 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() );
185 reg_def V1_J ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(2) );
186 reg_def V1_K ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(3) );
187
188 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() );
189 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() );
190 reg_def V2_J ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(2) );
191 reg_def V2_K ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(3) );
192
193 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() );
194 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() );
195 reg_def V3_J ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(2) );
196 reg_def V3_K ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(3) );
197
198 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() );
199 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() );
200 reg_def V4_J ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(2) );
201 reg_def V4_K ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(3) );
202
203 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() );
204 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() );
205 reg_def V5_J ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(2) );
206 reg_def V5_K ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(3) );
207
208 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() );
209 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() );
210 reg_def V6_J ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(2) );
211 reg_def V6_K ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(3) );
212
213 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() );
214 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() );
215 reg_def V7_J ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(2) );
216 reg_def V7_K ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(3) );
217
218 reg_def V8 ( SOC, SOE, Op_RegF, 8, v8->as_VMReg() );
219 reg_def V8_H ( SOC, SOE, Op_RegF, 8, v8->as_VMReg()->next() );
220 reg_def V8_J ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(2) );
221 reg_def V8_K ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(3) );
222
223 reg_def V9 ( SOC, SOE, Op_RegF, 9, v9->as_VMReg() );
224 reg_def V9_H ( SOC, SOE, Op_RegF, 9, v9->as_VMReg()->next() );
225 reg_def V9_J ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(2) );
226 reg_def V9_K ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(3) );
227
228 reg_def V10 ( SOC, SOE, Op_RegF, 10, v10->as_VMReg() );
229 reg_def V10_H ( SOC, SOE, Op_RegF, 10, v10->as_VMReg()->next() );
230 reg_def V10_J ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2) );
231 reg_def V10_K ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3) );
232
233 reg_def V11 ( SOC, SOE, Op_RegF, 11, v11->as_VMReg() );
234 reg_def V11_H ( SOC, SOE, Op_RegF, 11, v11->as_VMReg()->next() );
235 reg_def V11_J ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2) );
236 reg_def V11_K ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3) );
237
238 reg_def V12 ( SOC, SOE, Op_RegF, 12, v12->as_VMReg() );
239 reg_def V12_H ( SOC, SOE, Op_RegF, 12, v12->as_VMReg()->next() );
240 reg_def V12_J ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2) );
241 reg_def V12_K ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3) );
242
243 reg_def V13 ( SOC, SOE, Op_RegF, 13, v13->as_VMReg() );
244 reg_def V13_H ( SOC, SOE, Op_RegF, 13, v13->as_VMReg()->next() );
245 reg_def V13_J ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2) );
246 reg_def V13_K ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3) );
247
248 reg_def V14 ( SOC, SOE, Op_RegF, 14, v14->as_VMReg() );
249 reg_def V14_H ( SOC, SOE, Op_RegF, 14, v14->as_VMReg()->next() );
250 reg_def V14_J ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2) );
251 reg_def V14_K ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3) );
252
253 reg_def V15 ( SOC, SOE, Op_RegF, 15, v15->as_VMReg() );
254 reg_def V15_H ( SOC, SOE, Op_RegF, 15, v15->as_VMReg()->next() );
255 reg_def V15_J ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2) );
256 reg_def V15_K ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3) );
257
258 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() );
259 reg_def V16_H ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() );
260 reg_def V16_J ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2) );
261 reg_def V16_K ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3) );
262
263 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() );
264 reg_def V17_H ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() );
265 reg_def V17_J ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2) );
266 reg_def V17_K ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3) );
267
268 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() );
269 reg_def V18_H ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() );
270 reg_def V18_J ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2) );
271 reg_def V18_K ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3) );
272
273 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() );
274 reg_def V19_H ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() );
275 reg_def V19_J ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2) );
276 reg_def V19_K ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3) );
277
278 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() );
279 reg_def V20_H ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() );
280 reg_def V20_J ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2) );
281 reg_def V20_K ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3) );
282
283 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() );
284 reg_def V21_H ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() );
285 reg_def V21_J ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2) );
286 reg_def V21_K ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3) );
287
288 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() );
289 reg_def V22_H ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() );
290 reg_def V22_J ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2) );
291 reg_def V22_K ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3) );
292
293 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() );
294 reg_def V23_H ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() );
295 reg_def V23_J ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2) );
296 reg_def V23_K ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3) );
297
298 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() );
299 reg_def V24_H ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() );
300 reg_def V24_J ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2) );
301 reg_def V24_K ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3) );
302
303 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() );
304 reg_def V25_H ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() );
305 reg_def V25_J ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2) );
306 reg_def V25_K ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3) );
307
308 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() );
309 reg_def V26_H ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() );
310 reg_def V26_J ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2) );
311 reg_def V26_K ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3) );
312
313 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() );
314 reg_def V27_H ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() );
315 reg_def V27_J ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2) );
316 reg_def V27_K ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3) );
317
318 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() );
319 reg_def V28_H ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() );
320 reg_def V28_J ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2) );
321 reg_def V28_K ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3) );
322
323 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() );
324 reg_def V29_H ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() );
325 reg_def V29_J ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2) );
326 reg_def V29_K ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3) );
327
328 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() );
329 reg_def V30_H ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() );
330 reg_def V30_J ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2) );
331 reg_def V30_K ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3) );
332
333 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() );
334 reg_def V31_H ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() );
335 reg_def V31_J ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2) );
336 reg_def V31_K ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3) );
337
338 // ----------------------------
339 // SVE Predicate Registers
340 // ----------------------------
341 reg_def P0 (SOC, SOC, Op_RegVectMask, 0, p0->as_VMReg());
342 reg_def P1 (SOC, SOC, Op_RegVectMask, 1, p1->as_VMReg());
343 reg_def P2 (SOC, SOC, Op_RegVectMask, 2, p2->as_VMReg());
344 reg_def P3 (SOC, SOC, Op_RegVectMask, 3, p3->as_VMReg());
345 reg_def P4 (SOC, SOC, Op_RegVectMask, 4, p4->as_VMReg());
346 reg_def P5 (SOC, SOC, Op_RegVectMask, 5, p5->as_VMReg());
347 reg_def P6 (SOC, SOC, Op_RegVectMask, 6, p6->as_VMReg());
348 reg_def P7 (SOC, SOC, Op_RegVectMask, 7, p7->as_VMReg());
349 reg_def P8 (SOC, SOC, Op_RegVectMask, 8, p8->as_VMReg());
350 reg_def P9 (SOC, SOC, Op_RegVectMask, 9, p9->as_VMReg());
351 reg_def P10 (SOC, SOC, Op_RegVectMask, 10, p10->as_VMReg());
352 reg_def P11 (SOC, SOC, Op_RegVectMask, 11, p11->as_VMReg());
353 reg_def P12 (SOC, SOC, Op_RegVectMask, 12, p12->as_VMReg());
354 reg_def P13 (SOC, SOC, Op_RegVectMask, 13, p13->as_VMReg());
355 reg_def P14 (SOC, SOC, Op_RegVectMask, 14, p14->as_VMReg());
356 reg_def P15 (SOC, SOC, Op_RegVectMask, 15, p15->as_VMReg());
357
358 // ----------------------------
359 // Special Registers
360 // ----------------------------
361
362 // the AArch64 CSPR status flag register is not directly accessible as
363 // instruction operand. the FPSR status flag register is a system
364 // register which can be written/read using MSR/MRS but again does not
365 // appear as an operand (a code identifying the FSPR occurs as an
366 // immediate value in the instruction).
367
368 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad());
369
370 // Specify priority of register selection within phases of register
371 // allocation. Highest priority is first. A useful heuristic is to
372 // give registers a low priority when they are required by machine
373 // instructions, like EAX and EDX on I486, and choose no-save registers
374 // before save-on-call, & save-on-call before save-on-entry. Registers
375 // which participate in fixed calling sequences should come last.
376 // Registers which are used as pairs must fall on an even boundary.
377
378 alloc_class chunk0(
379 // volatiles
380 R10, R10_H,
381 R11, R11_H,
382 R12, R12_H,
383 R13, R13_H,
384 R14, R14_H,
385 R15, R15_H,
386 R16, R16_H,
387 R17, R17_H,
388 R18, R18_H,
389
390 // arg registers
391 R0, R0_H,
392 R1, R1_H,
393 R2, R2_H,
394 R3, R3_H,
395 R4, R4_H,
396 R5, R5_H,
397 R6, R6_H,
398 R7, R7_H,
399
400 // non-volatiles
401 R19, R19_H,
402 R20, R20_H,
403 R21, R21_H,
404 R22, R22_H,
405 R23, R23_H,
406 R24, R24_H,
407 R25, R25_H,
408 R26, R26_H,
409
410 // non-allocatable registers
411
412 R27, R27_H, // heapbase
413 R28, R28_H, // thread
414 R29, R29_H, // fp
415 R30, R30_H, // lr
416 R31, R31_H, // sp
417 R8, R8_H, // rscratch1
418 R9, R9_H, // rscratch2
419 );
420
421 alloc_class chunk1(
422
423 // no save
424 V16, V16_H, V16_J, V16_K,
425 V17, V17_H, V17_J, V17_K,
426 V18, V18_H, V18_J, V18_K,
427 V19, V19_H, V19_J, V19_K,
428 V20, V20_H, V20_J, V20_K,
429 V21, V21_H, V21_J, V21_K,
430 V22, V22_H, V22_J, V22_K,
431 V23, V23_H, V23_J, V23_K,
432 V24, V24_H, V24_J, V24_K,
433 V25, V25_H, V25_J, V25_K,
434 V26, V26_H, V26_J, V26_K,
435 V27, V27_H, V27_J, V27_K,
436 V28, V28_H, V28_J, V28_K,
437 V29, V29_H, V29_J, V29_K,
438 V30, V30_H, V30_J, V30_K,
439 V31, V31_H, V31_J, V31_K,
440
441 // arg registers
442 V0, V0_H, V0_J, V0_K,
443 V1, V1_H, V1_J, V1_K,
444 V2, V2_H, V2_J, V2_K,
445 V3, V3_H, V3_J, V3_K,
446 V4, V4_H, V4_J, V4_K,
447 V5, V5_H, V5_J, V5_K,
448 V6, V6_H, V6_J, V6_K,
449 V7, V7_H, V7_J, V7_K,
450
451 // non-volatiles
452 V8, V8_H, V8_J, V8_K,
453 V9, V9_H, V9_J, V9_K,
454 V10, V10_H, V10_J, V10_K,
455 V11, V11_H, V11_J, V11_K,
456 V12, V12_H, V12_J, V12_K,
457 V13, V13_H, V13_J, V13_K,
458 V14, V14_H, V14_J, V14_K,
459 V15, V15_H, V15_J, V15_K,
460 );
461
462 alloc_class chunk2 (
463 // Governing predicates for load/store and arithmetic
464 P0,
465 P1,
466 P2,
467 P3,
468 P4,
469 P5,
470 P6,
471
472 // Extra predicates
473 P8,
474 P9,
475 P10,
476 P11,
477 P12,
478 P13,
479 P14,
480 P15,
481
482 // Preserved for all-true predicate
483 P7,
484 );
485
486 alloc_class chunk3(RFLAGS);
487
488 //----------Architecture Description Register Classes--------------------------
489 // Several register classes are automatically defined based upon information in
490 // this architecture description.
491 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ )
492 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
493 //
494
495 // Class for all 32 bit general purpose registers
496 reg_class all_reg32(
497 R0,
498 R1,
499 R2,
500 R3,
501 R4,
502 R5,
503 R6,
504 R7,
505 R10,
506 R11,
507 R12,
508 R13,
509 R14,
510 R15,
511 R16,
512 R17,
513 R18,
514 R19,
515 R20,
516 R21,
517 R22,
518 R23,
519 R24,
520 R25,
521 R26,
522 R27,
523 R28,
524 R29,
525 R30,
526 R31
527 );
528
529
530 // Class for all 32 bit integer registers (excluding SP which
531 // will never be used as an integer register)
532 reg_class any_reg32 %{
533 return _ANY_REG32_mask;
534 %}
535
536 // Singleton class for R0 int register
537 reg_class int_r0_reg(R0);
538
539 // Singleton class for R2 int register
540 reg_class int_r2_reg(R2);
541
542 // Singleton class for R3 int register
543 reg_class int_r3_reg(R3);
544
545 // Singleton class for R4 int register
546 reg_class int_r4_reg(R4);
547
548 // Singleton class for R31 int register
549 reg_class int_r31_reg(R31);
550
551 // Class for all 64 bit general purpose registers
552 reg_class all_reg(
553 R0, R0_H,
554 R1, R1_H,
555 R2, R2_H,
556 R3, R3_H,
557 R4, R4_H,
558 R5, R5_H,
559 R6, R6_H,
560 R7, R7_H,
561 R10, R10_H,
562 R11, R11_H,
563 R12, R12_H,
564 R13, R13_H,
565 R14, R14_H,
566 R15, R15_H,
567 R16, R16_H,
568 R17, R17_H,
569 R18, R18_H,
570 R19, R19_H,
571 R20, R20_H,
572 R21, R21_H,
573 R22, R22_H,
574 R23, R23_H,
575 R24, R24_H,
576 R25, R25_H,
577 R26, R26_H,
578 R27, R27_H,
579 R28, R28_H,
580 R29, R29_H,
581 R30, R30_H,
582 R31, R31_H
583 );
584
585 // Class for all long integer registers (including SP)
586 reg_class any_reg %{
587 return _ANY_REG_mask;
588 %}
589
590 // Class for non-allocatable 32 bit registers
591 reg_class non_allocatable_reg32(
592 #ifdef R18_RESERVED
593 // See comment in register_aarch64.hpp
594 R18, // tls on Windows
595 #endif
596 R28, // thread
597 R30, // lr
598 R31 // sp
599 );
600
601 // Class for non-allocatable 64 bit registers
602 reg_class non_allocatable_reg(
603 #ifdef R18_RESERVED
604 // See comment in register_aarch64.hpp
605 R18, R18_H, // tls on Windows, platform register on macOS
606 #endif
607 R28, R28_H, // thread
608 R30, R30_H, // lr
609 R31, R31_H // sp
610 );
611
612 // Class for all non-special integer registers
613 reg_class no_special_reg32 %{
614 return _NO_SPECIAL_REG32_mask;
615 %}
616
617 // Class for all non-special long integer registers
618 reg_class no_special_reg %{
619 return _NO_SPECIAL_REG_mask;
620 %}
621
622 // Class for 64 bit register r0
623 reg_class r0_reg(
624 R0, R0_H
625 );
626
627 // Class for 64 bit register r1
628 reg_class r1_reg(
629 R1, R1_H
630 );
631
632 // Class for 64 bit register r2
633 reg_class r2_reg(
634 R2, R2_H
635 );
636
637 // Class for 64 bit register r3
638 reg_class r3_reg(
639 R3, R3_H
640 );
641
642 // Class for 64 bit register r4
643 reg_class r4_reg(
644 R4, R4_H
645 );
646
647 // Class for 64 bit register r5
648 reg_class r5_reg(
649 R5, R5_H
650 );
651
652 // Class for 64 bit register r10
653 reg_class r10_reg(
654 R10, R10_H
655 );
656
657 // Class for 64 bit register r11
658 reg_class r11_reg(
659 R11, R11_H
660 );
661
662 // Class for method register
663 reg_class method_reg(
664 R12, R12_H
665 );
666
667 // Class for thread register
668 reg_class thread_reg(
669 R28, R28_H
670 );
671
672 // Class for frame pointer register
673 reg_class fp_reg(
674 R29, R29_H
675 );
676
677 // Class for link register
678 reg_class lr_reg(
679 R30, R30_H
680 );
681
682 // Class for long sp register
683 reg_class sp_reg(
684 R31, R31_H
685 );
686
687 // Class for all pointer registers
688 reg_class ptr_reg %{
689 return _PTR_REG_mask;
690 %}
691
692 // Class for all non_special pointer registers
693 reg_class no_special_ptr_reg %{
694 return _NO_SPECIAL_PTR_REG_mask;
695 %}
696
697 // Class for all non_special pointer registers (excluding rfp)
698 reg_class no_special_no_rfp_ptr_reg %{
699 return _NO_SPECIAL_NO_RFP_PTR_REG_mask;
700 %}
701
702 // Class for all float registers
703 reg_class float_reg(
704 V0,
705 V1,
706 V2,
707 V3,
708 V4,
709 V5,
710 V6,
711 V7,
712 V8,
713 V9,
714 V10,
715 V11,
716 V12,
717 V13,
718 V14,
719 V15,
720 V16,
721 V17,
722 V18,
723 V19,
724 V20,
725 V21,
726 V22,
727 V23,
728 V24,
729 V25,
730 V26,
731 V27,
732 V28,
733 V29,
734 V30,
735 V31
736 );
737
738 // Double precision float registers have virtual `high halves' that
739 // are needed by the allocator.
740 // Class for all double registers
741 reg_class double_reg(
742 V0, V0_H,
743 V1, V1_H,
744 V2, V2_H,
745 V3, V3_H,
746 V4, V4_H,
747 V5, V5_H,
748 V6, V6_H,
749 V7, V7_H,
750 V8, V8_H,
751 V9, V9_H,
752 V10, V10_H,
753 V11, V11_H,
754 V12, V12_H,
755 V13, V13_H,
756 V14, V14_H,
757 V15, V15_H,
758 V16, V16_H,
759 V17, V17_H,
760 V18, V18_H,
761 V19, V19_H,
762 V20, V20_H,
763 V21, V21_H,
764 V22, V22_H,
765 V23, V23_H,
766 V24, V24_H,
767 V25, V25_H,
768 V26, V26_H,
769 V27, V27_H,
770 V28, V28_H,
771 V29, V29_H,
772 V30, V30_H,
773 V31, V31_H
774 );
775
776 // Class for all SVE vector registers.
777 reg_class vectora_reg (
778 V0, V0_H, V0_J, V0_K,
779 V1, V1_H, V1_J, V1_K,
780 V2, V2_H, V2_J, V2_K,
781 V3, V3_H, V3_J, V3_K,
782 V4, V4_H, V4_J, V4_K,
783 V5, V5_H, V5_J, V5_K,
784 V6, V6_H, V6_J, V6_K,
785 V7, V7_H, V7_J, V7_K,
786 V8, V8_H, V8_J, V8_K,
787 V9, V9_H, V9_J, V9_K,
788 V10, V10_H, V10_J, V10_K,
789 V11, V11_H, V11_J, V11_K,
790 V12, V12_H, V12_J, V12_K,
791 V13, V13_H, V13_J, V13_K,
792 V14, V14_H, V14_J, V14_K,
793 V15, V15_H, V15_J, V15_K,
794 V16, V16_H, V16_J, V16_K,
795 V17, V17_H, V17_J, V17_K,
796 V18, V18_H, V18_J, V18_K,
797 V19, V19_H, V19_J, V19_K,
798 V20, V20_H, V20_J, V20_K,
799 V21, V21_H, V21_J, V21_K,
800 V22, V22_H, V22_J, V22_K,
801 V23, V23_H, V23_J, V23_K,
802 V24, V24_H, V24_J, V24_K,
803 V25, V25_H, V25_J, V25_K,
804 V26, V26_H, V26_J, V26_K,
805 V27, V27_H, V27_J, V27_K,
806 V28, V28_H, V28_J, V28_K,
807 V29, V29_H, V29_J, V29_K,
808 V30, V30_H, V30_J, V30_K,
809 V31, V31_H, V31_J, V31_K,
810 );
811
812 // Class for all 64bit vector registers
813 reg_class vectord_reg(
814 V0, V0_H,
815 V1, V1_H,
816 V2, V2_H,
817 V3, V3_H,
818 V4, V4_H,
819 V5, V5_H,
820 V6, V6_H,
821 V7, V7_H,
822 V8, V8_H,
823 V9, V9_H,
824 V10, V10_H,
825 V11, V11_H,
826 V12, V12_H,
827 V13, V13_H,
828 V14, V14_H,
829 V15, V15_H,
830 V16, V16_H,
831 V17, V17_H,
832 V18, V18_H,
833 V19, V19_H,
834 V20, V20_H,
835 V21, V21_H,
836 V22, V22_H,
837 V23, V23_H,
838 V24, V24_H,
839 V25, V25_H,
840 V26, V26_H,
841 V27, V27_H,
842 V28, V28_H,
843 V29, V29_H,
844 V30, V30_H,
845 V31, V31_H
846 );
847
848 // Class for all 128bit vector registers
849 reg_class vectorx_reg(
850 V0, V0_H, V0_J, V0_K,
851 V1, V1_H, V1_J, V1_K,
852 V2, V2_H, V2_J, V2_K,
853 V3, V3_H, V3_J, V3_K,
854 V4, V4_H, V4_J, V4_K,
855 V5, V5_H, V5_J, V5_K,
856 V6, V6_H, V6_J, V6_K,
857 V7, V7_H, V7_J, V7_K,
858 V8, V8_H, V8_J, V8_K,
859 V9, V9_H, V9_J, V9_K,
860 V10, V10_H, V10_J, V10_K,
861 V11, V11_H, V11_J, V11_K,
862 V12, V12_H, V12_J, V12_K,
863 V13, V13_H, V13_J, V13_K,
864 V14, V14_H, V14_J, V14_K,
865 V15, V15_H, V15_J, V15_K,
866 V16, V16_H, V16_J, V16_K,
867 V17, V17_H, V17_J, V17_K,
868 V18, V18_H, V18_J, V18_K,
869 V19, V19_H, V19_J, V19_K,
870 V20, V20_H, V20_J, V20_K,
871 V21, V21_H, V21_J, V21_K,
872 V22, V22_H, V22_J, V22_K,
873 V23, V23_H, V23_J, V23_K,
874 V24, V24_H, V24_J, V24_K,
875 V25, V25_H, V25_J, V25_K,
876 V26, V26_H, V26_J, V26_K,
877 V27, V27_H, V27_J, V27_K,
878 V28, V28_H, V28_J, V28_K,
879 V29, V29_H, V29_J, V29_K,
880 V30, V30_H, V30_J, V30_K,
881 V31, V31_H, V31_J, V31_K
882 );
883
884 // Class for vector register V10
885 reg_class v10_veca_reg(
886 V10, V10_H, V10_J, V10_K
887 );
888
889 // Class for vector register V11
890 reg_class v11_veca_reg(
891 V11, V11_H, V11_J, V11_K
892 );
893
894 // Class for vector register V12
895 reg_class v12_veca_reg(
896 V12, V12_H, V12_J, V12_K
897 );
898
899 // Class for vector register V13
900 reg_class v13_veca_reg(
901 V13, V13_H, V13_J, V13_K
902 );
903
904 // Class for vector register V17
905 reg_class v17_veca_reg(
906 V17, V17_H, V17_J, V17_K
907 );
908
909 // Class for vector register V18
910 reg_class v18_veca_reg(
911 V18, V18_H, V18_J, V18_K
912 );
913
914 // Class for vector register V23
915 reg_class v23_veca_reg(
916 V23, V23_H, V23_J, V23_K
917 );
918
919 // Class for vector register V24
920 reg_class v24_veca_reg(
921 V24, V24_H, V24_J, V24_K
922 );
923
924 // Class for 128 bit register v0
925 reg_class v0_reg(
926 V0, V0_H
927 );
928
929 // Class for 128 bit register v1
930 reg_class v1_reg(
931 V1, V1_H
932 );
933
934 // Class for 128 bit register v2
935 reg_class v2_reg(
936 V2, V2_H
937 );
938
939 // Class for 128 bit register v3
940 reg_class v3_reg(
941 V3, V3_H
942 );
943
944 // Class for 128 bit register v4
945 reg_class v4_reg(
946 V4, V4_H
947 );
948
949 // Class for 128 bit register v5
950 reg_class v5_reg(
951 V5, V5_H
952 );
953
954 // Class for 128 bit register v6
955 reg_class v6_reg(
956 V6, V6_H
957 );
958
959 // Class for 128 bit register v7
960 reg_class v7_reg(
961 V7, V7_H
962 );
963
964 // Class for 128 bit register v8
965 reg_class v8_reg(
966 V8, V8_H
967 );
968
969 // Class for 128 bit register v9
970 reg_class v9_reg(
971 V9, V9_H
972 );
973
974 // Class for 128 bit register v10
975 reg_class v10_reg(
976 V10, V10_H
977 );
978
979 // Class for 128 bit register v11
980 reg_class v11_reg(
981 V11, V11_H
982 );
983
984 // Class for 128 bit register v12
985 reg_class v12_reg(
986 V12, V12_H
987 );
988
989 // Class for 128 bit register v13
990 reg_class v13_reg(
991 V13, V13_H
992 );
993
994 // Class for 128 bit register v14
995 reg_class v14_reg(
996 V14, V14_H
997 );
998
999 // Class for 128 bit register v15
1000 reg_class v15_reg(
1001 V15, V15_H
1002 );
1003
1004 // Class for 128 bit register v16
1005 reg_class v16_reg(
1006 V16, V16_H
1007 );
1008
1009 // Class for 128 bit register v17
1010 reg_class v17_reg(
1011 V17, V17_H
1012 );
1013
1014 // Class for 128 bit register v18
1015 reg_class v18_reg(
1016 V18, V18_H
1017 );
1018
1019 // Class for 128 bit register v19
1020 reg_class v19_reg(
1021 V19, V19_H
1022 );
1023
1024 // Class for 128 bit register v20
1025 reg_class v20_reg(
1026 V20, V20_H
1027 );
1028
1029 // Class for 128 bit register v21
1030 reg_class v21_reg(
1031 V21, V21_H
1032 );
1033
1034 // Class for 128 bit register v22
1035 reg_class v22_reg(
1036 V22, V22_H
1037 );
1038
1039 // Class for 128 bit register v23
1040 reg_class v23_reg(
1041 V23, V23_H
1042 );
1043
1044 // Class for 128 bit register v24
1045 reg_class v24_reg(
1046 V24, V24_H
1047 );
1048
1049 // Class for 128 bit register v25
1050 reg_class v25_reg(
1051 V25, V25_H
1052 );
1053
1054 // Class for 128 bit register v26
1055 reg_class v26_reg(
1056 V26, V26_H
1057 );
1058
1059 // Class for 128 bit register v27
1060 reg_class v27_reg(
1061 V27, V27_H
1062 );
1063
1064 // Class for 128 bit register v28
1065 reg_class v28_reg(
1066 V28, V28_H
1067 );
1068
1069 // Class for 128 bit register v29
1070 reg_class v29_reg(
1071 V29, V29_H
1072 );
1073
1074 // Class for 128 bit register v30
1075 reg_class v30_reg(
1076 V30, V30_H
1077 );
1078
1079 // Class for 128 bit register v31
1080 reg_class v31_reg(
1081 V31, V31_H
1082 );
1083
1084 // Class for all SVE predicate registers.
1085 reg_class pr_reg (
1086 P0,
1087 P1,
1088 P2,
1089 P3,
1090 P4,
1091 P5,
1092 P6,
1093 // P7, non-allocatable, preserved with all elements preset to TRUE.
1094 P8,
1095 P9,
1096 P10,
1097 P11,
1098 P12,
1099 P13,
1100 P14,
1101 P15
1102 );
1103
1104 // Class for SVE governing predicate registers, which are used
1105 // to determine the active elements of a predicated instruction.
1106 reg_class gov_pr (
1107 P0,
1108 P1,
1109 P2,
1110 P3,
1111 P4,
1112 P5,
1113 P6,
1114 // P7, non-allocatable, preserved with all elements preset to TRUE.
1115 );
1116
1117 reg_class p0_reg(P0);
1118 reg_class p1_reg(P1);
1119
1120 // Singleton class for condition codes
1121 reg_class int_flags(RFLAGS);
1122
1123 %}
1124
1125 //----------DEFINITION BLOCK---------------------------------------------------
1126 // Define name --> value mappings to inform the ADLC of an integer valued name
1127 // Current support includes integer values in the range [0, 0x7FFFFFFF]
1128 // Format:
1129 // int_def <name> ( <int_value>, <expression>);
1130 // Generated Code in ad_<arch>.hpp
1131 // #define <name> (<expression>)
1132 // // value == <int_value>
1133 // Generated code in ad_<arch>.cpp adlc_verification()
1134 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
1135 //
1136
1137 // we follow the ppc-aix port in using a simple cost model which ranks
1138 // register operations as cheap, memory ops as more expensive and
1139 // branches as most expensive. the first two have a low as well as a
1140 // normal cost. huge cost appears to be a way of saying don't do
1141 // something
1142
1143 definitions %{
1144 // The default cost (of a register move instruction).
1145 int_def INSN_COST ( 100, 100);
1146 int_def BRANCH_COST ( 200, 2 * INSN_COST);
1147 int_def CALL_COST ( 200, 2 * INSN_COST);
1148 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST);
1149 %}
1150
1151
1152 //----------SOURCE BLOCK-------------------------------------------------------
1153 // This is a block of C++ code which provides values, functions, and
1154 // definitions necessary in the rest of the architecture description
1155
1156 source_hpp %{
1157
1158 #include "asm/macroAssembler.hpp"
1159 #include "gc/shared/barrierSetAssembler.hpp"
1160 #include "gc/shared/cardTable.hpp"
1161 #include "gc/shared/cardTableBarrierSet.hpp"
1162 #include "gc/shared/collectedHeap.hpp"
1163 #include "opto/addnode.hpp"
1164 #include "opto/convertnode.hpp"
1165 #include "runtime/objectMonitor.hpp"
1166
1167 extern RegMask _ANY_REG32_mask;
1168 extern RegMask _ANY_REG_mask;
1169 extern RegMask _PTR_REG_mask;
1170 extern RegMask _NO_SPECIAL_REG32_mask;
1171 extern RegMask _NO_SPECIAL_REG_mask;
1172 extern RegMask _NO_SPECIAL_PTR_REG_mask;
1173 extern RegMask _NO_SPECIAL_NO_RFP_PTR_REG_mask;
1174
1175 class CallStubImpl {
1176
1177 //--------------------------------------------------------------
1178 //---< Used for optimization in Compile::shorten_branches >---
1179 //--------------------------------------------------------------
1180
1181 public:
1182 // Size of call trampoline stub.
1183 static uint size_call_trampoline() {
1184 return 0; // no call trampolines on this platform
1185 }
1186
1187 // number of relocations needed by a call trampoline stub
1188 static uint reloc_call_trampoline() {
1189 return 0; // no call trampolines on this platform
1190 }
1191 };
1192
1193 class HandlerImpl {
1194
1195 public:
1196
1197 static int emit_exception_handler(C2_MacroAssembler *masm);
1198 static int emit_deopt_handler(C2_MacroAssembler* masm);
1199
1200 static uint size_exception_handler() {
1201 return MacroAssembler::far_codestub_branch_size();
1202 }
1203
1204 static uint size_deopt_handler() {
1205 // count one adr and one far branch instruction
1206 return NativeInstruction::instruction_size + MacroAssembler::far_codestub_branch_size();
1207 }
1208 };
1209
1210 class Node::PD {
1211 public:
1212 enum NodeFlags {
1213 _last_flag = Node::_last_flag
1214 };
1215 };
1216
1217 bool is_CAS(int opcode, bool maybe_volatile);
1218
1219 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
1220
1221 bool unnecessary_acquire(const Node *barrier);
1222 bool needs_acquiring_load(const Node *load);
1223
1224 // predicates controlling emit of str<x>/stlr<x> and associated dmbs
1225
1226 bool unnecessary_release(const Node *barrier);
1227 bool unnecessary_volatile(const Node *barrier);
1228 bool needs_releasing_store(const Node *store);
1229
1230 // predicate controlling translation of CompareAndSwapX
1231 bool needs_acquiring_load_exclusive(const Node *load);
1232
1233 // predicate controlling addressing modes
1234 bool size_fits_all_mem_uses(AddPNode* addp, int shift);
1235
1236 // Convert BootTest condition to Assembler condition.
1237 // Replicate the logic of cmpOpOper::ccode() and cmpOpUOper::ccode().
1238 Assembler::Condition to_assembler_cond(BoolTest::mask cond);
1239 %}
1240
1241 source %{
1242
1243 // Derived RegMask with conditionally allocatable registers
1244
1245 void PhaseOutput::pd_perform_mach_node_analysis() {
1246 }
1247
1248 int MachNode::pd_alignment_required() const {
1249 return 1;
1250 }
1251
1252 int MachNode::compute_padding(int current_offset) const {
1253 return 0;
1254 }
1255
1256 RegMask _ANY_REG32_mask;
1257 RegMask _ANY_REG_mask;
1258 RegMask _PTR_REG_mask;
1259 RegMask _NO_SPECIAL_REG32_mask;
1260 RegMask _NO_SPECIAL_REG_mask;
1261 RegMask _NO_SPECIAL_PTR_REG_mask;
1262 RegMask _NO_SPECIAL_NO_RFP_PTR_REG_mask;
1263
1264 void reg_mask_init() {
1265 // We derive below RegMask(s) from the ones which are auto-generated from
1266 // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29)
1267 // registers conditionally reserved.
1268
1269 _ANY_REG32_mask = _ALL_REG32_mask;
1270 _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg()));
1271
1272 _ANY_REG_mask = _ALL_REG_mask;
1273
1274 _PTR_REG_mask = _ALL_REG_mask;
1275
1276 _NO_SPECIAL_REG32_mask = _ALL_REG32_mask;
1277 _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask);
1278
1279 _NO_SPECIAL_REG_mask = _ALL_REG_mask;
1280 _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask);
1281
1282 _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask;
1283 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask);
1284
1285 // r27 is not allocatable when compressed oops is on and heapbase is not
1286 // zero, compressed klass pointers doesn't use r27 after JDK-8234794
1287 if (UseCompressedOops && (CompressedOops::base() != nullptr)) {
1288 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg()));
1289 _NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg()));
1290 _NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg()));
1291 }
1292
1293 // r29 is not allocatable when PreserveFramePointer is on
1294 if (PreserveFramePointer) {
1295 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
1296 _NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
1297 _NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
1298 }
1299
1300 _NO_SPECIAL_NO_RFP_PTR_REG_mask = _NO_SPECIAL_PTR_REG_mask;
1301 _NO_SPECIAL_NO_RFP_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
1302 }
1303
1304 // Optimizaton of volatile gets and puts
1305 // -------------------------------------
1306 //
1307 // AArch64 has ldar<x> and stlr<x> instructions which we can safely
1308 // use to implement volatile reads and writes. For a volatile read
1309 // we simply need
1310 //
1311 // ldar<x>
1312 //
1313 // and for a volatile write we need
1314 //
1315 // stlr<x>
1316 //
1317 // Alternatively, we can implement them by pairing a normal
1318 // load/store with a memory barrier. For a volatile read we need
1319 //
1320 // ldr<x>
1321 // dmb ishld
1322 //
1323 // for a volatile write
1324 //
1325 // dmb ish
1326 // str<x>
1327 // dmb ish
1328 //
1329 // We can also use ldaxr and stlxr to implement compare and swap CAS
1330 // sequences. These are normally translated to an instruction
1331 // sequence like the following
1332 //
1333 // dmb ish
1334 // retry:
1335 // ldxr<x> rval raddr
1336 // cmp rval rold
1337 // b.ne done
1338 // stlxr<x> rval, rnew, rold
1339 // cbnz rval retry
1340 // done:
1341 // cset r0, eq
1342 // dmb ishld
1343 //
1344 // Note that the exclusive store is already using an stlxr
1345 // instruction. That is required to ensure visibility to other
1346 // threads of the exclusive write (assuming it succeeds) before that
1347 // of any subsequent writes.
1348 //
1349 // The following instruction sequence is an improvement on the above
1350 //
1351 // retry:
1352 // ldaxr<x> rval raddr
1353 // cmp rval rold
1354 // b.ne done
1355 // stlxr<x> rval, rnew, rold
1356 // cbnz rval retry
1357 // done:
1358 // cset r0, eq
1359 //
1360 // We don't need the leading dmb ish since the stlxr guarantees
1361 // visibility of prior writes in the case that the swap is
1362 // successful. Crucially we don't have to worry about the case where
1363 // the swap is not successful since no valid program should be
1364 // relying on visibility of prior changes by the attempting thread
1365 // in the case where the CAS fails.
1366 //
1367 // Similarly, we don't need the trailing dmb ishld if we substitute
1368 // an ldaxr instruction since that will provide all the guarantees we
1369 // require regarding observation of changes made by other threads
1370 // before any change to the CAS address observed by the load.
1371 //
1372 // In order to generate the desired instruction sequence we need to
1373 // be able to identify specific 'signature' ideal graph node
1374 // sequences which i) occur as a translation of a volatile reads or
1375 // writes or CAS operations and ii) do not occur through any other
1376 // translation or graph transformation. We can then provide
1377 // alternative aldc matching rules which translate these node
1378 // sequences to the desired machine code sequences. Selection of the
1379 // alternative rules can be implemented by predicates which identify
1380 // the relevant node sequences.
1381 //
1382 // The ideal graph generator translates a volatile read to the node
1383 // sequence
1384 //
1385 // LoadX[mo_acquire]
1386 // MemBarAcquire
1387 //
1388 // As a special case when using the compressed oops optimization we
1389 // may also see this variant
1390 //
1391 // LoadN[mo_acquire]
1392 // DecodeN
1393 // MemBarAcquire
1394 //
1395 // A volatile write is translated to the node sequence
1396 //
1397 // MemBarRelease
1398 // StoreX[mo_release] {CardMark}-optional
1399 // MemBarVolatile
1400 //
1401 // n.b. the above node patterns are generated with a strict
1402 // 'signature' configuration of input and output dependencies (see
1403 // the predicates below for exact details). The card mark may be as
1404 // simple as a few extra nodes or, in a few GC configurations, may
1405 // include more complex control flow between the leading and
1406 // trailing memory barriers. However, whatever the card mark
1407 // configuration these signatures are unique to translated volatile
1408 // reads/stores -- they will not appear as a result of any other
1409 // bytecode translation or inlining nor as a consequence of
1410 // optimizing transforms.
1411 //
1412 // We also want to catch inlined unsafe volatile gets and puts and
1413 // be able to implement them using either ldar<x>/stlr<x> or some
1414 // combination of ldr<x>/stlr<x> and dmb instructions.
1415 //
1416 // Inlined unsafe volatiles puts manifest as a minor variant of the
1417 // normal volatile put node sequence containing an extra cpuorder
1418 // membar
1419 //
1420 // MemBarRelease
1421 // MemBarCPUOrder
1422 // StoreX[mo_release] {CardMark}-optional
1423 // MemBarCPUOrder
1424 // MemBarVolatile
1425 //
1426 // n.b. as an aside, a cpuorder membar is not itself subject to
1427 // matching and translation by adlc rules. However, the rule
1428 // predicates need to detect its presence in order to correctly
1429 // select the desired adlc rules.
1430 //
1431 // Inlined unsafe volatile gets manifest as a slightly different
1432 // node sequence to a normal volatile get because of the
1433 // introduction of some CPUOrder memory barriers to bracket the
1434 // Load. However, but the same basic skeleton of a LoadX feeding a
1435 // MemBarAcquire, possibly through an optional DecodeN, is still
1436 // present
1437 //
1438 // MemBarCPUOrder
1439 // || \\
1440 // MemBarCPUOrder LoadX[mo_acquire]
1441 // || |
1442 // || {DecodeN} optional
1443 // || /
1444 // MemBarAcquire
1445 //
1446 // In this case the acquire membar does not directly depend on the
1447 // load. However, we can be sure that the load is generated from an
1448 // inlined unsafe volatile get if we see it dependent on this unique
1449 // sequence of membar nodes. Similarly, given an acquire membar we
1450 // can know that it was added because of an inlined unsafe volatile
1451 // get if it is fed and feeds a cpuorder membar and if its feed
1452 // membar also feeds an acquiring load.
1453 //
1454 // Finally an inlined (Unsafe) CAS operation is translated to the
1455 // following ideal graph
1456 //
1457 // MemBarRelease
1458 // MemBarCPUOrder
1459 // CompareAndSwapX {CardMark}-optional
1460 // MemBarCPUOrder
1461 // MemBarAcquire
1462 //
1463 // So, where we can identify these volatile read and write
1464 // signatures we can choose to plant either of the above two code
1465 // sequences. For a volatile read we can simply plant a normal
1466 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can
1467 // also choose to inhibit translation of the MemBarAcquire and
1468 // inhibit planting of the ldr<x>, instead planting an ldar<x>.
1469 //
1470 // When we recognise a volatile store signature we can choose to
1471 // plant at a dmb ish as a translation for the MemBarRelease, a
1472 // normal str<x> and then a dmb ish for the MemBarVolatile.
1473 // Alternatively, we can inhibit translation of the MemBarRelease
1474 // and MemBarVolatile and instead plant a simple stlr<x>
1475 // instruction.
1476 //
1477 // when we recognise a CAS signature we can choose to plant a dmb
1478 // ish as a translation for the MemBarRelease, the conventional
1479 // macro-instruction sequence for the CompareAndSwap node (which
1480 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire.
1481 // Alternatively, we can elide generation of the dmb instructions
1482 // and plant the alternative CompareAndSwap macro-instruction
1483 // sequence (which uses ldaxr<x>).
1484 //
1485 // Of course, the above only applies when we see these signature
1486 // configurations. We still want to plant dmb instructions in any
1487 // other cases where we may see a MemBarAcquire, MemBarRelease or
1488 // MemBarVolatile. For example, at the end of a constructor which
1489 // writes final/volatile fields we will see a MemBarRelease
1490 // instruction and this needs a 'dmb ish' lest we risk the
1491 // constructed object being visible without making the
1492 // final/volatile field writes visible.
1493 //
1494 // n.b. the translation rules below which rely on detection of the
1495 // volatile signatures and insert ldar<x> or stlr<x> are failsafe.
1496 // If we see anything other than the signature configurations we
1497 // always just translate the loads and stores to ldr<x> and str<x>
1498 // and translate acquire, release and volatile membars to the
1499 // relevant dmb instructions.
1500 //
1501
1502 // is_CAS(int opcode, bool maybe_volatile)
1503 //
1504 // return true if opcode is one of the possible CompareAndSwapX
1505 // values otherwise false.
1506
1507 bool is_CAS(int opcode, bool maybe_volatile)
1508 {
1509 switch(opcode) {
1510 // We handle these
1511 case Op_CompareAndSwapI:
1512 case Op_CompareAndSwapL:
1513 case Op_CompareAndSwapP:
1514 case Op_CompareAndSwapN:
1515 case Op_ShenandoahCompareAndSwapP:
1516 case Op_ShenandoahCompareAndSwapN:
1517 case Op_CompareAndSwapB:
1518 case Op_CompareAndSwapS:
1519 case Op_GetAndSetI:
1520 case Op_GetAndSetL:
1521 case Op_GetAndSetP:
1522 case Op_GetAndSetN:
1523 case Op_GetAndAddI:
1524 case Op_GetAndAddL:
1525 return true;
1526 case Op_CompareAndExchangeI:
1527 case Op_CompareAndExchangeN:
1528 case Op_CompareAndExchangeB:
1529 case Op_CompareAndExchangeS:
1530 case Op_CompareAndExchangeL:
1531 case Op_CompareAndExchangeP:
1532 case Op_WeakCompareAndSwapB:
1533 case Op_WeakCompareAndSwapS:
1534 case Op_WeakCompareAndSwapI:
1535 case Op_WeakCompareAndSwapL:
1536 case Op_WeakCompareAndSwapP:
1537 case Op_WeakCompareAndSwapN:
1538 case Op_ShenandoahWeakCompareAndSwapP:
1539 case Op_ShenandoahWeakCompareAndSwapN:
1540 case Op_ShenandoahCompareAndExchangeP:
1541 case Op_ShenandoahCompareAndExchangeN:
1542 return maybe_volatile;
1543 default:
1544 return false;
1545 }
1546 }
1547
1548 // helper to determine the maximum number of Phi nodes we may need to
1549 // traverse when searching from a card mark membar for the merge mem
1550 // feeding a trailing membar or vice versa
1551
1552 // predicates controlling emit of ldr<x>/ldar<x>
1553
1554 bool unnecessary_acquire(const Node *barrier)
1555 {
1556 assert(barrier->is_MemBar(), "expecting a membar");
1557
1558 MemBarNode* mb = barrier->as_MemBar();
1559
1560 if (mb->trailing_load()) {
1561 return true;
1562 }
1563
1564 if (mb->trailing_load_store()) {
1565 Node* load_store = mb->in(MemBarNode::Precedent);
1566 assert(load_store->is_LoadStore(), "unexpected graph shape");
1567 return is_CAS(load_store->Opcode(), true);
1568 }
1569
1570 return false;
1571 }
1572
1573 bool needs_acquiring_load(const Node *n)
1574 {
1575 assert(n->is_Load(), "expecting a load");
1576 LoadNode *ld = n->as_Load();
1577 return ld->is_acquire();
1578 }
1579
1580 bool unnecessary_release(const Node *n)
1581 {
1582 assert((n->is_MemBar() &&
1583 n->Opcode() == Op_MemBarRelease),
1584 "expecting a release membar");
1585
1586 MemBarNode *barrier = n->as_MemBar();
1587 if (!barrier->leading()) {
1588 return false;
1589 } else {
1590 Node* trailing = barrier->trailing_membar();
1591 MemBarNode* trailing_mb = trailing->as_MemBar();
1592 assert(trailing_mb->trailing(), "Not a trailing membar?");
1593 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars");
1594
1595 Node* mem = trailing_mb->in(MemBarNode::Precedent);
1596 if (mem->is_Store()) {
1597 assert(mem->as_Store()->is_release(), "");
1598 assert(trailing_mb->Opcode() == Op_MemBarVolatile, "");
1599 return true;
1600 } else {
1601 assert(mem->is_LoadStore(), "");
1602 assert(trailing_mb->Opcode() == Op_MemBarAcquire, "");
1603 return is_CAS(mem->Opcode(), true);
1604 }
1605 }
1606 return false;
1607 }
1608
1609 bool unnecessary_volatile(const Node *n)
1610 {
1611 // assert n->is_MemBar();
1612 MemBarNode *mbvol = n->as_MemBar();
1613
1614 bool release = mbvol->trailing_store();
1615 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), "");
1616 #ifdef ASSERT
1617 if (release) {
1618 Node* leading = mbvol->leading_membar();
1619 assert(leading->Opcode() == Op_MemBarRelease, "");
1620 assert(leading->as_MemBar()->leading_store(), "");
1621 assert(leading->as_MemBar()->trailing_membar() == mbvol, "");
1622 }
1623 #endif
1624
1625 return release;
1626 }
1627
1628 // predicates controlling emit of str<x>/stlr<x>
1629
1630 bool needs_releasing_store(const Node *n)
1631 {
1632 // assert n->is_Store();
1633 StoreNode *st = n->as_Store();
1634 return st->trailing_membar() != nullptr;
1635 }
1636
1637 // predicate controlling translation of CAS
1638 //
1639 // returns true if CAS needs to use an acquiring load otherwise false
1640
1641 bool needs_acquiring_load_exclusive(const Node *n)
1642 {
1643 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap");
1644 LoadStoreNode* ldst = n->as_LoadStore();
1645 if (is_CAS(n->Opcode(), false)) {
1646 assert(ldst->trailing_membar() != nullptr, "expected trailing membar");
1647 } else {
1648 return ldst->trailing_membar() != nullptr;
1649 }
1650
1651 // so we can just return true here
1652 return true;
1653 }
1654
1655 #define __ masm->
1656
1657 // advance declarations for helper functions to convert register
1658 // indices to register objects
1659
1660 // the ad file has to provide implementations of certain methods
1661 // expected by the generic code
1662 //
1663 // REQUIRED FUNCTIONALITY
1664
1665 //=============================================================================
1666
1667 // !!!!! Special hack to get all types of calls to specify the byte offset
1668 // from the start of the call to the point where the return address
1669 // will point.
1670
1671 int MachCallStaticJavaNode::ret_addr_offset()
1672 {
1673 // call should be a simple bl
1674 int off = 4;
1675 return off;
1676 }
1677
1678 int MachCallDynamicJavaNode::ret_addr_offset()
1679 {
1680 return 16; // movz, movk, movk, bl
1681 }
1682
1683 int MachCallRuntimeNode::ret_addr_offset() {
1684 // for generated stubs the call will be
1685 // bl(addr)
1686 // or with far branches
1687 // bl(trampoline_stub)
1688 // for real runtime callouts it will be six instructions
1689 // see aarch64_enc_java_to_runtime
1690 // adr(rscratch2, retaddr)
1691 // str(rscratch2, Address(rthread, JavaThread::last_Java_pc_offset()));
1692 // lea(rscratch1, RuntimeAddress(addr)
1693 // blr(rscratch1)
1694 CodeBlob *cb = CodeCache::find_blob(_entry_point);
1695 if (cb) {
1696 return 1 * NativeInstruction::instruction_size;
1697 } else {
1698 return 6 * NativeInstruction::instruction_size;
1699 }
1700 }
1701
1702 //=============================================================================
1703
1704 #ifndef PRODUCT
1705 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1706 st->print("BREAKPOINT");
1707 }
1708 #endif
1709
1710 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1711 __ brk(0);
1712 }
1713
1714 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1715 return MachNode::size(ra_);
1716 }
1717
1718 //=============================================================================
1719
1720 #ifndef PRODUCT
1721 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
1722 st->print("nop \t# %d bytes pad for loops and calls", _count);
1723 }
1724 #endif
1725
1726 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc*) const {
1727 for (int i = 0; i < _count; i++) {
1728 __ nop();
1729 }
1730 }
1731
1732 uint MachNopNode::size(PhaseRegAlloc*) const {
1733 return _count * NativeInstruction::instruction_size;
1734 }
1735
1736 //=============================================================================
1737 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
1738
1739 int ConstantTable::calculate_table_base_offset() const {
1740 return 0; // absolute addressing, no offset
1741 }
1742
1743 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1744 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1745 ShouldNotReachHere();
1746 }
1747
1748 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const {
1749 // Empty encoding
1750 }
1751
1752 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1753 return 0;
1754 }
1755
1756 #ifndef PRODUCT
1757 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1758 st->print("-- \t// MachConstantBaseNode (empty encoding)");
1759 }
1760 #endif
1761
1762 #ifndef PRODUCT
1763 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1764 Compile* C = ra_->C;
1765
1766 int framesize = C->output()->frame_slots() << LogBytesPerInt;
1767
1768 if (C->output()->need_stack_bang(framesize))
1769 st->print("# stack bang size=%d\n\t", framesize);
1770
1771 if (VM_Version::use_rop_protection()) {
1772 st->print("ldr zr, [lr]\n\t");
1773 st->print("paciaz\n\t");
1774 }
1775 if (framesize < ((1 << 9) + 2 * wordSize)) {
1776 st->print("sub sp, sp, #%d\n\t", framesize);
1777 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize);
1778 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize);
1779 } else {
1780 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize));
1781 if (PreserveFramePointer) st->print("mov rfp, sp\n\t");
1782 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize);
1783 st->print("sub sp, sp, rscratch1");
1784 }
1785 if (C->stub_function() == nullptr) {
1786 st->print("\n\t");
1787 st->print("ldr rscratch1, [guard]\n\t");
1788 st->print("dmb ishld\n\t");
1789 st->print("ldr rscratch2, [rthread, #thread_disarmed_guard_value_offset]\n\t");
1790 st->print("cmp rscratch1, rscratch2\n\t");
1791 st->print("b.eq skip");
1792 st->print("\n\t");
1793 st->print("blr #nmethod_entry_barrier_stub\n\t");
1794 st->print("b skip\n\t");
1795 st->print("guard: int\n\t");
1796 st->print("\n\t");
1797 st->print("skip:\n\t");
1798 }
1799 }
1800 #endif
1801
1802 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1803 Compile* C = ra_->C;
1804
1805 // n.b. frame size includes space for return pc and rfp
1806 const int framesize = C->output()->frame_size_in_bytes();
1807
1808 if (C->clinit_barrier_on_entry()) {
1809 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
1810
1811 Label L_skip_barrier;
1812
1813 __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding());
1814 __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier);
1815 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
1816 __ bind(L_skip_barrier);
1817 }
1818
1819 if (C->max_vector_size() > 0) {
1820 __ reinitialize_ptrue();
1821 }
1822
1823 int bangsize = C->output()->bang_size_in_bytes();
1824 if (C->output()->need_stack_bang(bangsize))
1825 __ generate_stack_overflow_check(bangsize);
1826
1827 __ build_frame(framesize);
1828
1829 if (C->stub_function() == nullptr) {
1830 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
1831 // Dummy labels for just measuring the code size
1832 Label dummy_slow_path;
1833 Label dummy_continuation;
1834 Label dummy_guard;
1835 Label* slow_path = &dummy_slow_path;
1836 Label* continuation = &dummy_continuation;
1837 Label* guard = &dummy_guard;
1838 if (!Compile::current()->output()->in_scratch_emit_size()) {
1839 // Use real labels from actual stub when not emitting code for the purpose of measuring its size
1840 C2EntryBarrierStub* stub = new (Compile::current()->comp_arena()) C2EntryBarrierStub();
1841 Compile::current()->output()->add_stub(stub);
1842 slow_path = &stub->entry();
1843 continuation = &stub->continuation();
1844 guard = &stub->guard();
1845 }
1846 // In the C2 code, we move the non-hot part of nmethod entry barriers out-of-line to a stub.
1847 bs->nmethod_entry_barrier(masm, slow_path, continuation, guard);
1848 }
1849
1850 if (VerifyStackAtCalls) {
1851 Unimplemented();
1852 }
1853
1854 C->output()->set_frame_complete(__ offset());
1855
1856 if (C->has_mach_constant_base_node()) {
1857 // NOTE: We set the table base offset here because users might be
1858 // emitted before MachConstantBaseNode.
1859 ConstantTable& constant_table = C->output()->constant_table();
1860 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1861 }
1862 }
1863
1864 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
1865 {
1866 return MachNode::size(ra_); // too many variables; just compute it
1867 // the hard way
1868 }
1869
1870 int MachPrologNode::reloc() const
1871 {
1872 return 0;
1873 }
1874
1875 //=============================================================================
1876
1877 #ifndef PRODUCT
1878 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1879 Compile* C = ra_->C;
1880 int framesize = C->output()->frame_slots() << LogBytesPerInt;
1881
1882 st->print("# pop frame %d\n\t",framesize);
1883
1884 if (framesize == 0) {
1885 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1886 } else if (framesize < ((1 << 9) + 2 * wordSize)) {
1887 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize);
1888 st->print("add sp, sp, #%d\n\t", framesize);
1889 } else {
1890 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize);
1891 st->print("add sp, sp, rscratch1\n\t");
1892 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1893 }
1894 if (VM_Version::use_rop_protection()) {
1895 st->print("autiaz\n\t");
1896 st->print("ldr zr, [lr]\n\t");
1897 }
1898
1899 if (do_polling() && C->is_method_compilation()) {
1900 st->print("# test polling word\n\t");
1901 st->print("ldr rscratch1, [rthread],#%d\n\t", in_bytes(JavaThread::polling_word_offset()));
1902 st->print("cmp sp, rscratch1\n\t");
1903 st->print("bhi #slow_path");
1904 }
1905 }
1906 #endif
1907
1908 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1909 Compile* C = ra_->C;
1910 int framesize = C->output()->frame_slots() << LogBytesPerInt;
1911
1912 __ remove_frame(framesize);
1913
1914 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1915 __ reserved_stack_check();
1916 }
1917
1918 if (do_polling() && C->is_method_compilation()) {
1919 Label dummy_label;
1920 Label* code_stub = &dummy_label;
1921 if (!C->output()->in_scratch_emit_size()) {
1922 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1923 C->output()->add_stub(stub);
1924 code_stub = &stub->entry();
1925 }
1926 __ relocate(relocInfo::poll_return_type);
1927 __ safepoint_poll(*code_stub, true /* at_return */, true /* in_nmethod */);
1928 }
1929 }
1930
1931 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1932 // Variable size. Determine dynamically.
1933 return MachNode::size(ra_);
1934 }
1935
1936 int MachEpilogNode::reloc() const {
1937 // Return number of relocatable values contained in this instruction.
1938 return 1; // 1 for polling page.
1939 }
1940
1941 const Pipeline * MachEpilogNode::pipeline() const {
1942 return MachNode::pipeline_class();
1943 }
1944
1945 //=============================================================================
1946
1947 static enum RC rc_class(OptoReg::Name reg) {
1948
1949 if (reg == OptoReg::Bad) {
1950 return rc_bad;
1951 }
1952
1953 // we have 32 int registers * 2 halves
1954 int slots_of_int_registers = Register::number_of_registers * Register::max_slots_per_register;
1955
1956 if (reg < slots_of_int_registers) {
1957 return rc_int;
1958 }
1959
1960 // we have 32 float register * 8 halves
1961 int slots_of_float_registers = FloatRegister::number_of_registers * FloatRegister::max_slots_per_register;
1962 if (reg < slots_of_int_registers + slots_of_float_registers) {
1963 return rc_float;
1964 }
1965
1966 int slots_of_predicate_registers = PRegister::number_of_registers * PRegister::max_slots_per_register;
1967 if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_predicate_registers) {
1968 return rc_predicate;
1969 }
1970
1971 // Between predicate regs & stack is the flags.
1972 assert(OptoReg::is_stack(reg), "blow up if spilling flags");
1973
1974 return rc_stack;
1975 }
1976
1977 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1978 Compile* C = ra_->C;
1979
1980 // Get registers to move.
1981 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1982 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1983 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1984 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1985
1986 enum RC src_hi_rc = rc_class(src_hi);
1987 enum RC src_lo_rc = rc_class(src_lo);
1988 enum RC dst_hi_rc = rc_class(dst_hi);
1989 enum RC dst_lo_rc = rc_class(dst_lo);
1990
1991 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1992
1993 if (src_hi != OptoReg::Bad && !bottom_type()->isa_vectmask()) {
1994 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1995 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1996 "expected aligned-adjacent pairs");
1997 }
1998
1999 if (src_lo == dst_lo && src_hi == dst_hi) {
2000 return 0; // Self copy, no move.
2001 }
2002
2003 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi &&
2004 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi;
2005 int src_offset = ra_->reg2offset(src_lo);
2006 int dst_offset = ra_->reg2offset(dst_lo);
2007
2008 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) {
2009 uint ireg = ideal_reg();
2010 if (ireg == Op_VecA && masm) {
2011 int sve_vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE);
2012 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
2013 // stack->stack
2014 __ spill_copy_sve_vector_stack_to_stack(src_offset, dst_offset,
2015 sve_vector_reg_size_in_bytes);
2016 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
2017 __ spill_sve_vector(as_FloatRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo),
2018 sve_vector_reg_size_in_bytes);
2019 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
2020 __ unspill_sve_vector(as_FloatRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo),
2021 sve_vector_reg_size_in_bytes);
2022 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
2023 __ sve_orr(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2024 as_FloatRegister(Matcher::_regEncode[src_lo]),
2025 as_FloatRegister(Matcher::_regEncode[src_lo]));
2026 } else {
2027 ShouldNotReachHere();
2028 }
2029 } else if (masm) {
2030 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector");
2031 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity");
2032 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
2033 // stack->stack
2034 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset");
2035 if (ireg == Op_VecD) {
2036 __ unspill(rscratch1, true, src_offset);
2037 __ spill(rscratch1, true, dst_offset);
2038 } else {
2039 __ spill_copy128(src_offset, dst_offset);
2040 }
2041 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
2042 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2043 ireg == Op_VecD ? __ T8B : __ T16B,
2044 as_FloatRegister(Matcher::_regEncode[src_lo]));
2045 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
2046 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
2047 ireg == Op_VecD ? __ D : __ Q,
2048 ra_->reg2offset(dst_lo));
2049 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
2050 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2051 ireg == Op_VecD ? __ D : __ Q,
2052 ra_->reg2offset(src_lo));
2053 } else {
2054 ShouldNotReachHere();
2055 }
2056 }
2057 } else if (masm) {
2058 switch (src_lo_rc) {
2059 case rc_int:
2060 if (dst_lo_rc == rc_int) { // gpr --> gpr copy
2061 if (is64) {
2062 __ mov(as_Register(Matcher::_regEncode[dst_lo]),
2063 as_Register(Matcher::_regEncode[src_lo]));
2064 } else {
2065 __ movw(as_Register(Matcher::_regEncode[dst_lo]),
2066 as_Register(Matcher::_regEncode[src_lo]));
2067 }
2068 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
2069 if (is64) {
2070 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2071 as_Register(Matcher::_regEncode[src_lo]));
2072 } else {
2073 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2074 as_Register(Matcher::_regEncode[src_lo]));
2075 }
2076 } else { // gpr --> stack spill
2077 assert(dst_lo_rc == rc_stack, "spill to bad register class");
2078 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
2079 }
2080 break;
2081 case rc_float:
2082 if (dst_lo_rc == rc_int) { // fpr --> gpr copy
2083 if (is64) {
2084 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
2085 as_FloatRegister(Matcher::_regEncode[src_lo]));
2086 } else {
2087 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
2088 as_FloatRegister(Matcher::_regEncode[src_lo]));
2089 }
2090 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
2091 if (is64) {
2092 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2093 as_FloatRegister(Matcher::_regEncode[src_lo]));
2094 } else {
2095 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2096 as_FloatRegister(Matcher::_regEncode[src_lo]));
2097 }
2098 } else { // fpr --> stack spill
2099 assert(dst_lo_rc == rc_stack, "spill to bad register class");
2100 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
2101 is64 ? __ D : __ S, dst_offset);
2102 }
2103 break;
2104 case rc_stack:
2105 if (dst_lo_rc == rc_int) { // stack --> gpr load
2106 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
2107 } else if (dst_lo_rc == rc_float) { // stack --> fpr load
2108 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2109 is64 ? __ D : __ S, src_offset);
2110 } else if (dst_lo_rc == rc_predicate) {
2111 __ unspill_sve_predicate(as_PRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo),
2112 Matcher::scalable_vector_reg_size(T_BYTE) >> 3);
2113 } else { // stack --> stack copy
2114 assert(dst_lo_rc == rc_stack, "spill to bad register class");
2115 if (ideal_reg() == Op_RegVectMask) {
2116 __ spill_copy_sve_predicate_stack_to_stack(src_offset, dst_offset,
2117 Matcher::scalable_vector_reg_size(T_BYTE) >> 3);
2118 } else {
2119 __ unspill(rscratch1, is64, src_offset);
2120 __ spill(rscratch1, is64, dst_offset);
2121 }
2122 }
2123 break;
2124 case rc_predicate:
2125 if (dst_lo_rc == rc_predicate) {
2126 __ sve_mov(as_PRegister(Matcher::_regEncode[dst_lo]), as_PRegister(Matcher::_regEncode[src_lo]));
2127 } else if (dst_lo_rc == rc_stack) {
2128 __ spill_sve_predicate(as_PRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo),
2129 Matcher::scalable_vector_reg_size(T_BYTE) >> 3);
2130 } else {
2131 assert(false, "bad src and dst rc_class combination.");
2132 ShouldNotReachHere();
2133 }
2134 break;
2135 default:
2136 assert(false, "bad rc_class for spill");
2137 ShouldNotReachHere();
2138 }
2139 }
2140
2141 if (st) {
2142 st->print("spill ");
2143 if (src_lo_rc == rc_stack) {
2144 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
2145 } else {
2146 st->print("%s -> ", Matcher::regName[src_lo]);
2147 }
2148 if (dst_lo_rc == rc_stack) {
2149 st->print("[sp, #%d]", ra_->reg2offset(dst_lo));
2150 } else {
2151 st->print("%s", Matcher::regName[dst_lo]);
2152 }
2153 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) {
2154 int vsize = 0;
2155 switch (ideal_reg()) {
2156 case Op_VecD:
2157 vsize = 64;
2158 break;
2159 case Op_VecX:
2160 vsize = 128;
2161 break;
2162 case Op_VecA:
2163 vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8;
2164 break;
2165 default:
2166 assert(false, "bad register type for spill");
2167 ShouldNotReachHere();
2168 }
2169 st->print("\t# vector spill size = %d", vsize);
2170 } else if (ideal_reg() == Op_RegVectMask) {
2171 assert(Matcher::supports_scalable_vector(), "bad register type for spill");
2172 int vsize = Matcher::scalable_predicate_reg_slots() * 32;
2173 st->print("\t# predicate spill size = %d", vsize);
2174 } else {
2175 st->print("\t# spill size = %d", is64 ? 64 : 32);
2176 }
2177 }
2178
2179 return 0;
2180
2181 }
2182
2183 #ifndef PRODUCT
2184 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2185 if (!ra_)
2186 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
2187 else
2188 implementation(nullptr, ra_, false, st);
2189 }
2190 #endif
2191
2192 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
2193 implementation(masm, ra_, false, nullptr);
2194 }
2195
2196 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
2197 return MachNode::size(ra_);
2198 }
2199
2200 //=============================================================================
2201
2202 #ifndef PRODUCT
2203 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2204 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2205 int reg = ra_->get_reg_first(this);
2206 st->print("add %s, rsp, #%d]\t# box lock",
2207 Matcher::regName[reg], offset);
2208 }
2209 #endif
2210
2211 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
2212 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2213 int reg = ra_->get_encode(this);
2214
2215 // This add will handle any 24-bit signed offset. 24 bits allows an
2216 // 8 megabyte stack frame.
2217 __ add(as_Register(reg), sp, offset);
2218 }
2219
2220 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
2221 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
2222 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2223
2224 if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
2225 return NativeInstruction::instruction_size;
2226 } else {
2227 return 2 * NativeInstruction::instruction_size;
2228 }
2229 }
2230
2231 //=============================================================================
2232
2233 #ifndef PRODUCT
2234 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
2235 {
2236 st->print_cr("# MachUEPNode");
2237 if (UseCompressedClassPointers) {
2238 st->print_cr("\tldrw rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2239 st->print_cr("\tldrw r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass");
2240 st->print_cr("\tcmpw rscratch1, r10");
2241 } else {
2242 st->print_cr("\tldr rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2243 st->print_cr("\tldr r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass");
2244 st->print_cr("\tcmp rscratch1, r10");
2245 }
2246 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
2247 }
2248 #endif
2249
2250 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const
2251 {
2252 __ ic_check(InteriorEntryAlignment);
2253 }
2254
2255 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
2256 {
2257 return MachNode::size(ra_);
2258 }
2259
2260 // REQUIRED EMIT CODE
2261
2262 //=============================================================================
2263
2264 // Emit exception handler code.
2265 int HandlerImpl::emit_exception_handler(C2_MacroAssembler* masm)
2266 {
2267 // mov rscratch1 #exception_blob_entry_point
2268 // br rscratch1
2269 // Note that the code buffer's insts_mark is always relative to insts.
2270 // That's why we must use the macroassembler to generate a handler.
2271 address base = __ start_a_stub(size_exception_handler());
2272 if (base == nullptr) {
2273 ciEnv::current()->record_failure("CodeCache is full");
2274 return 0; // CodeBuffer::expand failed
2275 }
2276 int offset = __ offset();
2277 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
2278 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
2279 __ end_a_stub();
2280 return offset;
2281 }
2282
2283 // Emit deopt handler code.
2284 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm)
2285 {
2286 // Note that the code buffer's insts_mark is always relative to insts.
2287 // That's why we must use the macroassembler to generate a handler.
2288 address base = __ start_a_stub(size_deopt_handler());
2289 if (base == nullptr) {
2290 ciEnv::current()->record_failure("CodeCache is full");
2291 return 0; // CodeBuffer::expand failed
2292 }
2293 int offset = __ offset();
2294
2295 __ adr(lr, __ pc());
2296 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
2297
2298 assert(__ offset() - offset == (int) size_deopt_handler(), "overflow");
2299 __ end_a_stub();
2300 return offset;
2301 }
2302
2303 // REQUIRED MATCHER CODE
2304
2305 //=============================================================================
2306
2307 bool Matcher::match_rule_supported(int opcode) {
2308 if (!has_match_rule(opcode))
2309 return false;
2310
2311 switch (opcode) {
2312 case Op_OnSpinWait:
2313 return VM_Version::supports_on_spin_wait();
2314 case Op_CacheWB:
2315 case Op_CacheWBPreSync:
2316 case Op_CacheWBPostSync:
2317 if (!VM_Version::supports_data_cache_line_flush()) {
2318 return false;
2319 }
2320 break;
2321 case Op_ExpandBits:
2322 case Op_CompressBits:
2323 if (!VM_Version::supports_svebitperm()) {
2324 return false;
2325 }
2326 break;
2327 case Op_FmaF:
2328 case Op_FmaD:
2329 case Op_FmaVF:
2330 case Op_FmaVD:
2331 if (!UseFMA) {
2332 return false;
2333 }
2334 break;
2335 case Op_FmaHF:
2336 // UseFMA flag also needs to be checked along with FEAT_FP16
2337 if (!UseFMA || !is_feat_fp16_supported()) {
2338 return false;
2339 }
2340 break;
2341 case Op_AddHF:
2342 case Op_SubHF:
2343 case Op_MulHF:
2344 case Op_DivHF:
2345 case Op_MinHF:
2346 case Op_MaxHF:
2347 case Op_SqrtHF:
2348 // Half-precision floating point scalar operations require FEAT_FP16
2349 // to be available. FEAT_FP16 is enabled if both "fphp" and "asimdhp"
2350 // features are supported.
2351 if (!is_feat_fp16_supported()) {
2352 return false;
2353 }
2354 break;
2355 }
2356
2357 return true; // Per default match rules are supported.
2358 }
2359
2360 const RegMask* Matcher::predicate_reg_mask(void) {
2361 return &_PR_REG_mask;
2362 }
2363
2364 bool Matcher::supports_vector_calling_convention(void) {
2365 return EnableVectorSupport;
2366 }
2367
2368 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2369 assert(EnableVectorSupport, "sanity");
2370 int lo = V0_num;
2371 int hi = V0_H_num;
2372 if (ideal_reg == Op_VecX || ideal_reg == Op_VecA) {
2373 hi = V0_K_num;
2374 }
2375 return OptoRegPair(hi, lo);
2376 }
2377
2378 // Is this branch offset short enough that a short branch can be used?
2379 //
2380 // NOTE: If the platform does not provide any short branch variants, then
2381 // this method should return false for offset 0.
2382 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2383 // The passed offset is relative to address of the branch.
2384
2385 return (-32768 <= offset && offset < 32768);
2386 }
2387
2388 // Vector width in bytes.
2389 int Matcher::vector_width_in_bytes(BasicType bt) {
2390 // The MaxVectorSize should have been set by detecting SVE max vector register size.
2391 int size = MIN2((UseSVE > 0) ? (int)FloatRegister::sve_vl_max : (int)FloatRegister::neon_vl, (int)MaxVectorSize);
2392 // Minimum 2 values in vector
2393 if (size < 2*type2aelembytes(bt)) size = 0;
2394 // But never < 4
2395 if (size < 4) size = 0;
2396 return size;
2397 }
2398
2399 // Limits on vector size (number of elements) loaded into vector.
2400 int Matcher::max_vector_size(const BasicType bt) {
2401 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2402 }
2403
2404 int Matcher::min_vector_size(const BasicType bt) {
2405 // Usually, the shortest vector length supported by AArch64 ISA and
2406 // Vector API species is 64 bits. However, we allow 32-bit or 16-bit
2407 // vectors in a few special cases.
2408 int size;
2409 switch(bt) {
2410 case T_BOOLEAN:
2411 // Load/store a vector mask with only 2 elements for vector types
2412 // such as "2I/2F/2L/2D".
2413 size = 2;
2414 break;
2415 case T_BYTE:
2416 // Generate a "4B" vector, to support vector cast between "8B/16B"
2417 // and "4S/4I/4L/4F/4D".
2418 size = 4;
2419 break;
2420 case T_SHORT:
2421 // Generate a "2S" vector, to support vector cast between "4S/8S"
2422 // and "2I/2L/2F/2D".
2423 size = 2;
2424 break;
2425 default:
2426 // Limit the min vector length to 64-bit.
2427 size = 8 / type2aelembytes(bt);
2428 // The number of elements in a vector should be at least 2.
2429 size = MAX2(size, 2);
2430 }
2431
2432 int max_size = max_vector_size(bt);
2433 return MIN2(size, max_size);
2434 }
2435
2436 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
2437 return Matcher::max_vector_size(bt);
2438 }
2439
2440 // Actual max scalable vector register length.
2441 int Matcher::scalable_vector_reg_size(const BasicType bt) {
2442 return Matcher::max_vector_size(bt);
2443 }
2444
2445 // Vector ideal reg.
2446 uint Matcher::vector_ideal_reg(int len) {
2447 if (UseSVE > 0 && FloatRegister::neon_vl < len && len <= FloatRegister::sve_vl_max) {
2448 return Op_VecA;
2449 }
2450 switch(len) {
2451 // For 16-bit/32-bit mask vector, reuse VecD.
2452 case 2:
2453 case 4:
2454 case 8: return Op_VecD;
2455 case 16: return Op_VecX;
2456 }
2457 ShouldNotReachHere();
2458 return 0;
2459 }
2460
2461 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp) {
2462 assert(Matcher::is_generic_vector(generic_opnd), "not generic");
2463 switch (ideal_reg) {
2464 case Op_VecA: return new vecAOper();
2465 case Op_VecD: return new vecDOper();
2466 case Op_VecX: return new vecXOper();
2467 }
2468 ShouldNotReachHere();
2469 return nullptr;
2470 }
2471
2472 bool Matcher::is_reg2reg_move(MachNode* m) {
2473 return false;
2474 }
2475
2476 bool Matcher::is_generic_vector(MachOper* opnd) {
2477 return opnd->opcode() == VREG;
2478 }
2479
2480 // Return whether or not this register is ever used as an argument.
2481 // This function is used on startup to build the trampoline stubs in
2482 // generateOptoStub. Registers not mentioned will be killed by the VM
2483 // call in the trampoline, and arguments in those registers not be
2484 // available to the callee.
2485 bool Matcher::can_be_java_arg(int reg)
2486 {
2487 return
2488 reg == R0_num || reg == R0_H_num ||
2489 reg == R1_num || reg == R1_H_num ||
2490 reg == R2_num || reg == R2_H_num ||
2491 reg == R3_num || reg == R3_H_num ||
2492 reg == R4_num || reg == R4_H_num ||
2493 reg == R5_num || reg == R5_H_num ||
2494 reg == R6_num || reg == R6_H_num ||
2495 reg == R7_num || reg == R7_H_num ||
2496 reg == V0_num || reg == V0_H_num ||
2497 reg == V1_num || reg == V1_H_num ||
2498 reg == V2_num || reg == V2_H_num ||
2499 reg == V3_num || reg == V3_H_num ||
2500 reg == V4_num || reg == V4_H_num ||
2501 reg == V5_num || reg == V5_H_num ||
2502 reg == V6_num || reg == V6_H_num ||
2503 reg == V7_num || reg == V7_H_num;
2504 }
2505
2506 bool Matcher::is_spillable_arg(int reg)
2507 {
2508 return can_be_java_arg(reg);
2509 }
2510
2511 uint Matcher::int_pressure_limit()
2512 {
2513 // JDK-8183543: When taking the number of available registers as int
2514 // register pressure threshold, the jtreg test:
2515 // test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java
2516 // failed due to C2 compilation failure with
2517 // "COMPILE SKIPPED: failed spill-split-recycle sanity check".
2518 //
2519 // A derived pointer is live at CallNode and then is flagged by RA
2520 // as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip
2521 // derived pointers and lastly fail to spill after reaching maximum
2522 // number of iterations. Lowering the default pressure threshold to
2523 // (_NO_SPECIAL_REG32_mask.Size() minus 1) forces CallNode to become
2524 // a high register pressure area of the code so that split_DEF can
2525 // generate DefinitionSpillCopy for the derived pointer.
2526 uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.Size() - 1;
2527 if (!PreserveFramePointer) {
2528 // When PreserveFramePointer is off, frame pointer is allocatable,
2529 // but different from other SOC registers, it is excluded from
2530 // fatproj's mask because its save type is No-Save. Decrease 1 to
2531 // ensure high pressure at fatproj when PreserveFramePointer is off.
2532 // See check_pressure_at_fatproj().
2533 default_int_pressure_threshold--;
2534 }
2535 return (INTPRESSURE == -1) ? default_int_pressure_threshold : INTPRESSURE;
2536 }
2537
2538 uint Matcher::float_pressure_limit()
2539 {
2540 // _FLOAT_REG_mask is generated by adlc from the float_reg register class.
2541 return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.Size() : FLOATPRESSURE;
2542 }
2543
2544 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
2545 return false;
2546 }
2547
2548 RegMask Matcher::divI_proj_mask() {
2549 ShouldNotReachHere();
2550 return RegMask();
2551 }
2552
2553 // Register for MODI projection of divmodI.
2554 RegMask Matcher::modI_proj_mask() {
2555 ShouldNotReachHere();
2556 return RegMask();
2557 }
2558
2559 // Register for DIVL projection of divmodL.
2560 RegMask Matcher::divL_proj_mask() {
2561 ShouldNotReachHere();
2562 return RegMask();
2563 }
2564
2565 // Register for MODL projection of divmodL.
2566 RegMask Matcher::modL_proj_mask() {
2567 ShouldNotReachHere();
2568 return RegMask();
2569 }
2570
2571 bool size_fits_all_mem_uses(AddPNode* addp, int shift) {
2572 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
2573 Node* u = addp->fast_out(i);
2574 if (u->is_LoadStore()) {
2575 // On AArch64, LoadStoreNodes (i.e. compare and swap
2576 // instructions) only take register indirect as an operand, so
2577 // any attempt to use an AddPNode as an input to a LoadStoreNode
2578 // must fail.
2579 return false;
2580 }
2581 if (u->is_Mem()) {
2582 int opsize = u->as_Mem()->memory_size();
2583 assert(opsize > 0, "unexpected memory operand size");
2584 if (u->as_Mem()->memory_size() != (1<<shift)) {
2585 return false;
2586 }
2587 }
2588 }
2589 return true;
2590 }
2591
2592 // Convert BootTest condition to Assembler condition.
2593 // Replicate the logic of cmpOpOper::ccode() and cmpOpUOper::ccode().
2594 Assembler::Condition to_assembler_cond(BoolTest::mask cond) {
2595 Assembler::Condition result;
2596 switch(cond) {
2597 case BoolTest::eq:
2598 result = Assembler::EQ; break;
2599 case BoolTest::ne:
2600 result = Assembler::NE; break;
2601 case BoolTest::le:
2602 result = Assembler::LE; break;
2603 case BoolTest::ge:
2604 result = Assembler::GE; break;
2605 case BoolTest::lt:
2606 result = Assembler::LT; break;
2607 case BoolTest::gt:
2608 result = Assembler::GT; break;
2609 case BoolTest::ule:
2610 result = Assembler::LS; break;
2611 case BoolTest::uge:
2612 result = Assembler::HS; break;
2613 case BoolTest::ult:
2614 result = Assembler::LO; break;
2615 case BoolTest::ugt:
2616 result = Assembler::HI; break;
2617 case BoolTest::overflow:
2618 result = Assembler::VS; break;
2619 case BoolTest::no_overflow:
2620 result = Assembler::VC; break;
2621 default:
2622 ShouldNotReachHere();
2623 return Assembler::Condition(-1);
2624 }
2625
2626 // Check conversion
2627 if (cond & BoolTest::unsigned_compare) {
2628 assert(cmpOpUOper((BoolTest::mask)((int)cond & ~(BoolTest::unsigned_compare))).ccode() == result, "Invalid conversion");
2629 } else {
2630 assert(cmpOpOper(cond).ccode() == result, "Invalid conversion");
2631 }
2632
2633 return result;
2634 }
2635
2636 // Binary src (Replicate con)
2637 static bool is_valid_sve_arith_imm_pattern(Node* n, Node* m) {
2638 if (n == nullptr || m == nullptr) {
2639 return false;
2640 }
2641
2642 if (UseSVE == 0 || m->Opcode() != Op_Replicate) {
2643 return false;
2644 }
2645
2646 Node* imm_node = m->in(1);
2647 if (!imm_node->is_Con()) {
2648 return false;
2649 }
2650
2651 const Type* t = imm_node->bottom_type();
2652 if (!(t->isa_int() || t->isa_long())) {
2653 return false;
2654 }
2655
2656 switch (n->Opcode()) {
2657 case Op_AndV:
2658 case Op_OrV:
2659 case Op_XorV: {
2660 Assembler::SIMD_RegVariant T = Assembler::elemType_to_regVariant(Matcher::vector_element_basic_type(n));
2661 uint64_t value = t->isa_long() ? (uint64_t)imm_node->get_long() : (uint64_t)imm_node->get_int();
2662 return Assembler::operand_valid_for_sve_logical_immediate(Assembler::regVariant_to_elemBits(T), value);
2663 }
2664 case Op_AddVB:
2665 return (imm_node->get_int() <= 255 && imm_node->get_int() >= -255);
2666 case Op_AddVS:
2667 case Op_AddVI:
2668 return Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)imm_node->get_int());
2669 case Op_AddVL:
2670 return Assembler::operand_valid_for_sve_add_sub_immediate(imm_node->get_long());
2671 default:
2672 return false;
2673 }
2674 }
2675
2676 // (XorV src (Replicate m1))
2677 // (XorVMask src (MaskAll m1))
2678 static bool is_vector_bitwise_not_pattern(Node* n, Node* m) {
2679 if (n != nullptr && m != nullptr) {
2680 return (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) &&
2681 VectorNode::is_all_ones_vector(m);
2682 }
2683 return false;
2684 }
2685
2686 // Should the matcher clone input 'm' of node 'n'?
2687 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
2688 if (is_vshift_con_pattern(n, m) ||
2689 is_vector_bitwise_not_pattern(n, m) ||
2690 is_valid_sve_arith_imm_pattern(n, m) ||
2691 is_encode_and_store_pattern(n, m)) {
2692 mstack.push(m, Visit);
2693 return true;
2694 }
2695 return false;
2696 }
2697
2698 // Should the Matcher clone shifts on addressing modes, expecting them
2699 // to be subsumed into complex addressing expressions or compute them
2700 // into registers?
2701 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
2702
2703 // Loads and stores with indirect memory input (e.g., volatile loads and
2704 // stores) do not subsume the input into complex addressing expressions. If
2705 // the addressing expression is input to at least one such load or store, do
2706 // not clone the addressing expression. Query needs_acquiring_load and
2707 // needs_releasing_store as a proxy for indirect memory input, as it is not
2708 // possible to directly query for indirect memory input at this stage.
2709 for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) {
2710 Node* n = m->fast_out(i);
2711 if (n->is_Load() && needs_acquiring_load(n)) {
2712 return false;
2713 }
2714 if (n->is_Store() && needs_releasing_store(n)) {
2715 return false;
2716 }
2717 }
2718
2719 if (clone_base_plus_offset_address(m, mstack, address_visited)) {
2720 return true;
2721 }
2722
2723 Node *off = m->in(AddPNode::Offset);
2724 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() &&
2725 size_fits_all_mem_uses(m, off->in(2)->get_int()) &&
2726 // Are there other uses besides address expressions?
2727 !is_visited(off)) {
2728 address_visited.set(off->_idx); // Flag as address_visited
2729 mstack.push(off->in(2), Visit);
2730 Node *conv = off->in(1);
2731 if (conv->Opcode() == Op_ConvI2L &&
2732 // Are there other uses besides address expressions?
2733 !is_visited(conv)) {
2734 address_visited.set(conv->_idx); // Flag as address_visited
2735 mstack.push(conv->in(1), Pre_Visit);
2736 } else {
2737 mstack.push(conv, Pre_Visit);
2738 }
2739 address_visited.test_set(m->_idx); // Flag as address_visited
2740 mstack.push(m->in(AddPNode::Address), Pre_Visit);
2741 mstack.push(m->in(AddPNode::Base), Pre_Visit);
2742 return true;
2743 } else if (off->Opcode() == Op_ConvI2L &&
2744 // Are there other uses besides address expressions?
2745 !is_visited(off)) {
2746 address_visited.test_set(m->_idx); // Flag as address_visited
2747 address_visited.set(off->_idx); // Flag as address_visited
2748 mstack.push(off->in(1), Pre_Visit);
2749 mstack.push(m->in(AddPNode::Address), Pre_Visit);
2750 mstack.push(m->in(AddPNode::Base), Pre_Visit);
2751 return true;
2752 }
2753 return false;
2754 }
2755
2756 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \
2757 { \
2758 guarantee(INDEX == -1, "mode not permitted for volatile"); \
2759 guarantee(DISP == 0, "mode not permitted for volatile"); \
2760 guarantee(SCALE == 0, "mode not permitted for volatile"); \
2761 __ INSN(REG, as_Register(BASE)); \
2762 }
2763
2764
2765 static Address mem2address(int opcode, Register base, int index, int size, int disp)
2766 {
2767 Address::extend scale;
2768
2769 // Hooboy, this is fugly. We need a way to communicate to the
2770 // encoder that the index needs to be sign extended, so we have to
2771 // enumerate all the cases.
2772 switch (opcode) {
2773 case INDINDEXSCALEDI2L:
2774 case INDINDEXSCALEDI2LN:
2775 case INDINDEXI2L:
2776 case INDINDEXI2LN:
2777 scale = Address::sxtw(size);
2778 break;
2779 default:
2780 scale = Address::lsl(size);
2781 }
2782
2783 if (index == -1) {
2784 return Address(base, disp);
2785 } else {
2786 assert(disp == 0, "unsupported address mode: disp = %d", disp);
2787 return Address(base, as_Register(index), scale);
2788 }
2789 }
2790
2791
2792 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
2793 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr);
2794 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
2795 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
2796 MacroAssembler::SIMD_RegVariant T, const Address &adr);
2797
2798 // Used for all non-volatile memory accesses. The use of
2799 // $mem->opcode() to discover whether this pattern uses sign-extended
2800 // offsets is something of a kludge.
2801 static void loadStore(C2_MacroAssembler* masm, mem_insn insn,
2802 Register reg, int opcode,
2803 Register base, int index, int scale, int disp,
2804 int size_in_memory)
2805 {
2806 Address addr = mem2address(opcode, base, index, scale, disp);
2807 if (addr.getMode() == Address::base_plus_offset) {
2808 /* Fix up any out-of-range offsets. */
2809 assert_different_registers(rscratch1, base);
2810 assert_different_registers(rscratch1, reg);
2811 addr = __ legitimize_address(addr, size_in_memory, rscratch1);
2812 }
2813 (masm->*insn)(reg, addr);
2814 }
2815
2816 static void loadStore(C2_MacroAssembler* masm, mem_float_insn insn,
2817 FloatRegister reg, int opcode,
2818 Register base, int index, int size, int disp,
2819 int size_in_memory)
2820 {
2821 Address::extend scale;
2822
2823 switch (opcode) {
2824 case INDINDEXSCALEDI2L:
2825 case INDINDEXSCALEDI2LN:
2826 scale = Address::sxtw(size);
2827 break;
2828 default:
2829 scale = Address::lsl(size);
2830 }
2831
2832 if (index == -1) {
2833 // Fix up any out-of-range offsets.
2834 assert_different_registers(rscratch1, base);
2835 Address addr = Address(base, disp);
2836 addr = __ legitimize_address(addr, size_in_memory, rscratch1);
2837 (masm->*insn)(reg, addr);
2838 } else {
2839 assert(disp == 0, "unsupported address mode: disp = %d", disp);
2840 (masm->*insn)(reg, Address(base, as_Register(index), scale));
2841 }
2842 }
2843
2844 static void loadStore(C2_MacroAssembler* masm, mem_vector_insn insn,
2845 FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
2846 int opcode, Register base, int index, int size, int disp)
2847 {
2848 if (index == -1) {
2849 (masm->*insn)(reg, T, Address(base, disp));
2850 } else {
2851 assert(disp == 0, "unsupported address mode");
2852 (masm->*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size)));
2853 }
2854 }
2855
2856 %}
2857
2858
2859
2860 //----------ENCODING BLOCK-----------------------------------------------------
2861 // This block specifies the encoding classes used by the compiler to
2862 // output byte streams. Encoding classes are parameterized macros
2863 // used by Machine Instruction Nodes in order to generate the bit
2864 // encoding of the instruction. Operands specify their base encoding
2865 // interface with the interface keyword. There are currently
2866 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
2867 // COND_INTER. REG_INTER causes an operand to generate a function
2868 // which returns its register number when queried. CONST_INTER causes
2869 // an operand to generate a function which returns the value of the
2870 // constant when queried. MEMORY_INTER causes an operand to generate
2871 // four functions which return the Base Register, the Index Register,
2872 // the Scale Value, and the Offset Value of the operand when queried.
2873 // COND_INTER causes an operand to generate six functions which return
2874 // the encoding code (ie - encoding bits for the instruction)
2875 // associated with each basic boolean condition for a conditional
2876 // instruction.
2877 //
2878 // Instructions specify two basic values for encoding. Again, a
2879 // function is available to check if the constant displacement is an
2880 // oop. They use the ins_encode keyword to specify their encoding
2881 // classes (which must be a sequence of enc_class names, and their
2882 // parameters, specified in the encoding block), and they use the
2883 // opcode keyword to specify, in order, their primary, secondary, and
2884 // tertiary opcode. Only the opcode sections which a particular
2885 // instruction needs for encoding need to be specified.
2886 encode %{
2887 // Build emit functions for each basic byte or larger field in the
2888 // intel encoding scheme (opcode, rm, sib, immediate), and call them
2889 // from C++ code in the enc_class source block. Emit functions will
2890 // live in the main source block for now. In future, we can
2891 // generalize this by adding a syntax that specifies the sizes of
2892 // fields in an order, so that the adlc can build the emit functions
2893 // automagically
2894
2895 // catch all for unimplemented encodings
2896 enc_class enc_unimplemented %{
2897 __ unimplemented("C2 catch all");
2898 %}
2899
2900 // BEGIN Non-volatile memory access
2901
2902 // This encoding class is generated automatically from ad_encode.m4.
2903 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2904 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{
2905 Register dst_reg = as_Register($dst$$reg);
2906 loadStore(masm, &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(),
2907 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2908 %}
2909
2910 // This encoding class is generated automatically from ad_encode.m4.
2911 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2912 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{
2913 Register dst_reg = as_Register($dst$$reg);
2914 loadStore(masm, &MacroAssembler::ldrsb, dst_reg, $mem->opcode(),
2915 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2916 %}
2917
2918 // This encoding class is generated automatically from ad_encode.m4.
2919 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2920 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{
2921 Register dst_reg = as_Register($dst$$reg);
2922 loadStore(masm, &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2923 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2924 %}
2925
2926 // This encoding class is generated automatically from ad_encode.m4.
2927 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2928 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{
2929 Register dst_reg = as_Register($dst$$reg);
2930 loadStore(masm, &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2931 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2932 %}
2933
2934 // This encoding class is generated automatically from ad_encode.m4.
2935 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2936 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{
2937 Register dst_reg = as_Register($dst$$reg);
2938 loadStore(masm, &MacroAssembler::ldrshw, dst_reg, $mem->opcode(),
2939 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2940 %}
2941
2942 // This encoding class is generated automatically from ad_encode.m4.
2943 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2944 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{
2945 Register dst_reg = as_Register($dst$$reg);
2946 loadStore(masm, &MacroAssembler::ldrsh, dst_reg, $mem->opcode(),
2947 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2948 %}
2949
2950 // This encoding class is generated automatically from ad_encode.m4.
2951 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2952 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{
2953 Register dst_reg = as_Register($dst$$reg);
2954 loadStore(masm, &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2955 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2956 %}
2957
2958 // This encoding class is generated automatically from ad_encode.m4.
2959 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2960 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{
2961 Register dst_reg = as_Register($dst$$reg);
2962 loadStore(masm, &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2963 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2964 %}
2965
2966 // This encoding class is generated automatically from ad_encode.m4.
2967 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2968 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{
2969 Register dst_reg = as_Register($dst$$reg);
2970 loadStore(masm, &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2971 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2972 %}
2973
2974 // This encoding class is generated automatically from ad_encode.m4.
2975 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2976 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{
2977 Register dst_reg = as_Register($dst$$reg);
2978 loadStore(masm, &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2979 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2980 %}
2981
2982 // This encoding class is generated automatically from ad_encode.m4.
2983 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2984 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{
2985 Register dst_reg = as_Register($dst$$reg);
2986 loadStore(masm, &MacroAssembler::ldrsw, dst_reg, $mem->opcode(),
2987 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2988 %}
2989
2990 // This encoding class is generated automatically from ad_encode.m4.
2991 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2992 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{
2993 Register dst_reg = as_Register($dst$$reg);
2994 loadStore(masm, &MacroAssembler::ldr, dst_reg, $mem->opcode(),
2995 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
2996 %}
2997
2998 // This encoding class is generated automatically from ad_encode.m4.
2999 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3000 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{
3001 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3002 loadStore(masm, &MacroAssembler::ldrs, dst_reg, $mem->opcode(),
3003 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
3004 %}
3005
3006 // This encoding class is generated automatically from ad_encode.m4.
3007 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3008 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{
3009 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3010 loadStore(masm, &MacroAssembler::ldrd, dst_reg, $mem->opcode(),
3011 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3012 %}
3013
3014 // This encoding class is generated automatically from ad_encode.m4.
3015 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3016 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{
3017 Register src_reg = as_Register($src$$reg);
3018 loadStore(masm, &MacroAssembler::strb, src_reg, $mem->opcode(),
3019 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
3020 %}
3021
3022 // This encoding class is generated automatically from ad_encode.m4.
3023 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3024 enc_class aarch64_enc_strb0(memory1 mem) %{
3025 loadStore(masm, &MacroAssembler::strb, zr, $mem->opcode(),
3026 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
3027 %}
3028
3029 // This encoding class is generated automatically from ad_encode.m4.
3030 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3031 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{
3032 Register src_reg = as_Register($src$$reg);
3033 loadStore(masm, &MacroAssembler::strh, src_reg, $mem->opcode(),
3034 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
3035 %}
3036
3037 // This encoding class is generated automatically from ad_encode.m4.
3038 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3039 enc_class aarch64_enc_strh0(memory2 mem) %{
3040 loadStore(masm, &MacroAssembler::strh, zr, $mem->opcode(),
3041 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
3042 %}
3043
3044 // This encoding class is generated automatically from ad_encode.m4.
3045 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3046 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{
3047 Register src_reg = as_Register($src$$reg);
3048 loadStore(masm, &MacroAssembler::strw, src_reg, $mem->opcode(),
3049 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
3050 %}
3051
3052 // This encoding class is generated automatically from ad_encode.m4.
3053 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3054 enc_class aarch64_enc_strw0(memory4 mem) %{
3055 loadStore(masm, &MacroAssembler::strw, zr, $mem->opcode(),
3056 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
3057 %}
3058
3059 // This encoding class is generated automatically from ad_encode.m4.
3060 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3061 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{
3062 Register src_reg = as_Register($src$$reg);
3063 // we sometimes get asked to store the stack pointer into the
3064 // current thread -- we cannot do that directly on AArch64
3065 if (src_reg == r31_sp) {
3066 assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
3067 __ mov(rscratch2, sp);
3068 src_reg = rscratch2;
3069 }
3070 loadStore(masm, &MacroAssembler::str, src_reg, $mem->opcode(),
3071 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3072 %}
3073
3074 // This encoding class is generated automatically from ad_encode.m4.
3075 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3076 enc_class aarch64_enc_str0(memory8 mem) %{
3077 loadStore(masm, &MacroAssembler::str, zr, $mem->opcode(),
3078 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3079 %}
3080
3081 // This encoding class is generated automatically from ad_encode.m4.
3082 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3083 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{
3084 FloatRegister src_reg = as_FloatRegister($src$$reg);
3085 loadStore(masm, &MacroAssembler::strs, src_reg, $mem->opcode(),
3086 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
3087 %}
3088
3089 // This encoding class is generated automatically from ad_encode.m4.
3090 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3091 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{
3092 FloatRegister src_reg = as_FloatRegister($src$$reg);
3093 loadStore(masm, &MacroAssembler::strd, src_reg, $mem->opcode(),
3094 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3095 %}
3096
3097 // This encoding class is generated automatically from ad_encode.m4.
3098 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3099 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{
3100 __ membar(Assembler::StoreStore);
3101 loadStore(masm, &MacroAssembler::strb, zr, $mem->opcode(),
3102 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
3103 %}
3104
3105 // END Non-volatile memory access
3106
3107 // Vector loads and stores
3108 enc_class aarch64_enc_ldrvH(vReg dst, memory mem) %{
3109 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3110 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::H,
3111 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3112 %}
3113
3114 enc_class aarch64_enc_ldrvS(vReg dst, memory mem) %{
3115 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3116 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::S,
3117 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3118 %}
3119
3120 enc_class aarch64_enc_ldrvD(vReg dst, memory mem) %{
3121 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3122 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::D,
3123 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3124 %}
3125
3126 enc_class aarch64_enc_ldrvQ(vReg dst, memory mem) %{
3127 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3128 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::Q,
3129 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3130 %}
3131
3132 enc_class aarch64_enc_strvH(vReg src, memory mem) %{
3133 FloatRegister src_reg = as_FloatRegister($src$$reg);
3134 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::H,
3135 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3136 %}
3137
3138 enc_class aarch64_enc_strvS(vReg src, memory mem) %{
3139 FloatRegister src_reg = as_FloatRegister($src$$reg);
3140 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::S,
3141 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3142 %}
3143
3144 enc_class aarch64_enc_strvD(vReg src, memory mem) %{
3145 FloatRegister src_reg = as_FloatRegister($src$$reg);
3146 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::D,
3147 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3148 %}
3149
3150 enc_class aarch64_enc_strvQ(vReg src, memory mem) %{
3151 FloatRegister src_reg = as_FloatRegister($src$$reg);
3152 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::Q,
3153 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3154 %}
3155
3156 // volatile loads and stores
3157
3158 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{
3159 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3160 rscratch1, stlrb);
3161 %}
3162
3163 enc_class aarch64_enc_stlrb0(memory mem) %{
3164 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3165 rscratch1, stlrb);
3166 %}
3167
3168 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{
3169 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3170 rscratch1, stlrh);
3171 %}
3172
3173 enc_class aarch64_enc_stlrh0(memory mem) %{
3174 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3175 rscratch1, stlrh);
3176 %}
3177
3178 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{
3179 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3180 rscratch1, stlrw);
3181 %}
3182
3183 enc_class aarch64_enc_stlrw0(memory mem) %{
3184 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3185 rscratch1, stlrw);
3186 %}
3187
3188 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{
3189 Register dst_reg = as_Register($dst$$reg);
3190 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3191 rscratch1, ldarb);
3192 __ sxtbw(dst_reg, dst_reg);
3193 %}
3194
3195 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{
3196 Register dst_reg = as_Register($dst$$reg);
3197 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3198 rscratch1, ldarb);
3199 __ sxtb(dst_reg, dst_reg);
3200 %}
3201
3202 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{
3203 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3204 rscratch1, ldarb);
3205 %}
3206
3207 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{
3208 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3209 rscratch1, ldarb);
3210 %}
3211
3212 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{
3213 Register dst_reg = as_Register($dst$$reg);
3214 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3215 rscratch1, ldarh);
3216 __ sxthw(dst_reg, dst_reg);
3217 %}
3218
3219 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{
3220 Register dst_reg = as_Register($dst$$reg);
3221 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3222 rscratch1, ldarh);
3223 __ sxth(dst_reg, dst_reg);
3224 %}
3225
3226 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{
3227 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3228 rscratch1, ldarh);
3229 %}
3230
3231 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{
3232 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3233 rscratch1, ldarh);
3234 %}
3235
3236 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{
3237 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3238 rscratch1, ldarw);
3239 %}
3240
3241 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{
3242 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3243 rscratch1, ldarw);
3244 %}
3245
3246 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{
3247 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3248 rscratch1, ldar);
3249 %}
3250
3251 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{
3252 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3253 rscratch1, ldarw);
3254 __ fmovs(as_FloatRegister($dst$$reg), rscratch1);
3255 %}
3256
3257 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{
3258 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3259 rscratch1, ldar);
3260 __ fmovd(as_FloatRegister($dst$$reg), rscratch1);
3261 %}
3262
3263 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{
3264 Register src_reg = as_Register($src$$reg);
3265 // we sometimes get asked to store the stack pointer into the
3266 // current thread -- we cannot do that directly on AArch64
3267 if (src_reg == r31_sp) {
3268 assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
3269 __ mov(rscratch2, sp);
3270 src_reg = rscratch2;
3271 }
3272 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3273 rscratch1, stlr);
3274 %}
3275
3276 enc_class aarch64_enc_stlr0(memory mem) %{
3277 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3278 rscratch1, stlr);
3279 %}
3280
3281 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{
3282 {
3283 FloatRegister src_reg = as_FloatRegister($src$$reg);
3284 __ fmovs(rscratch2, src_reg);
3285 }
3286 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3287 rscratch1, stlrw);
3288 %}
3289
3290 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{
3291 {
3292 FloatRegister src_reg = as_FloatRegister($src$$reg);
3293 __ fmovd(rscratch2, src_reg);
3294 }
3295 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3296 rscratch1, stlr);
3297 %}
3298
3299 // synchronized read/update encodings
3300
3301 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{
3302 Register dst_reg = as_Register($dst$$reg);
3303 Register base = as_Register($mem$$base);
3304 int index = $mem$$index;
3305 int scale = $mem$$scale;
3306 int disp = $mem$$disp;
3307 if (index == -1) {
3308 if (disp != 0) {
3309 __ lea(rscratch1, Address(base, disp));
3310 __ ldaxr(dst_reg, rscratch1);
3311 } else {
3312 // TODO
3313 // should we ever get anything other than this case?
3314 __ ldaxr(dst_reg, base);
3315 }
3316 } else {
3317 Register index_reg = as_Register(index);
3318 if (disp == 0) {
3319 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale)));
3320 __ ldaxr(dst_reg, rscratch1);
3321 } else {
3322 __ lea(rscratch1, Address(base, disp));
3323 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale)));
3324 __ ldaxr(dst_reg, rscratch1);
3325 }
3326 }
3327 %}
3328
3329 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{
3330 Register src_reg = as_Register($src$$reg);
3331 Register base = as_Register($mem$$base);
3332 int index = $mem$$index;
3333 int scale = $mem$$scale;
3334 int disp = $mem$$disp;
3335 if (index == -1) {
3336 if (disp != 0) {
3337 __ lea(rscratch2, Address(base, disp));
3338 __ stlxr(rscratch1, src_reg, rscratch2);
3339 } else {
3340 // TODO
3341 // should we ever get anything other than this case?
3342 __ stlxr(rscratch1, src_reg, base);
3343 }
3344 } else {
3345 Register index_reg = as_Register(index);
3346 if (disp == 0) {
3347 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale)));
3348 __ stlxr(rscratch1, src_reg, rscratch2);
3349 } else {
3350 __ lea(rscratch2, Address(base, disp));
3351 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale)));
3352 __ stlxr(rscratch1, src_reg, rscratch2);
3353 }
3354 }
3355 __ cmpw(rscratch1, zr);
3356 %}
3357
3358 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
3359 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3360 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3361 Assembler::xword, /*acquire*/ false, /*release*/ true,
3362 /*weak*/ false, noreg);
3363 %}
3364
3365 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3366 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3367 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3368 Assembler::word, /*acquire*/ false, /*release*/ true,
3369 /*weak*/ false, noreg);
3370 %}
3371
3372 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3373 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3374 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3375 Assembler::halfword, /*acquire*/ false, /*release*/ true,
3376 /*weak*/ false, noreg);
3377 %}
3378
3379 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3380 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3381 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3382 Assembler::byte, /*acquire*/ false, /*release*/ true,
3383 /*weak*/ false, noreg);
3384 %}
3385
3386
3387 // The only difference between aarch64_enc_cmpxchg and
3388 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the
3389 // CompareAndSwap sequence to serve as a barrier on acquiring a
3390 // lock.
3391 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
3392 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3393 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3394 Assembler::xword, /*acquire*/ true, /*release*/ true,
3395 /*weak*/ false, noreg);
3396 %}
3397
3398 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3399 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3400 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3401 Assembler::word, /*acquire*/ true, /*release*/ true,
3402 /*weak*/ false, noreg);
3403 %}
3404
3405 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3406 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3407 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3408 Assembler::halfword, /*acquire*/ true, /*release*/ true,
3409 /*weak*/ false, noreg);
3410 %}
3411
3412 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3413 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3414 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3415 Assembler::byte, /*acquire*/ true, /*release*/ true,
3416 /*weak*/ false, noreg);
3417 %}
3418
3419 // auxiliary used for CompareAndSwapX to set result register
3420 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
3421 Register res_reg = as_Register($res$$reg);
3422 __ cset(res_reg, Assembler::EQ);
3423 %}
3424
3425 // prefetch encodings
3426
3427 enc_class aarch64_enc_prefetchw(memory mem) %{
3428 Register base = as_Register($mem$$base);
3429 int index = $mem$$index;
3430 int scale = $mem$$scale;
3431 int disp = $mem$$disp;
3432 if (index == -1) {
3433 // Fix up any out-of-range offsets.
3434 assert_different_registers(rscratch1, base);
3435 Address addr = Address(base, disp);
3436 addr = __ legitimize_address(addr, 8, rscratch1);
3437 __ prfm(addr, PSTL1KEEP);
3438 } else {
3439 Register index_reg = as_Register(index);
3440 if (disp == 0) {
3441 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP);
3442 } else {
3443 __ lea(rscratch1, Address(base, disp));
3444 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP);
3445 }
3446 }
3447 %}
3448
3449 // mov encodings
3450
3451 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{
3452 uint32_t con = (uint32_t)$src$$constant;
3453 Register dst_reg = as_Register($dst$$reg);
3454 if (con == 0) {
3455 __ movw(dst_reg, zr);
3456 } else {
3457 __ movw(dst_reg, con);
3458 }
3459 %}
3460
3461 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{
3462 Register dst_reg = as_Register($dst$$reg);
3463 uint64_t con = (uint64_t)$src$$constant;
3464 if (con == 0) {
3465 __ mov(dst_reg, zr);
3466 } else {
3467 __ mov(dst_reg, con);
3468 }
3469 %}
3470
3471 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
3472 Register dst_reg = as_Register($dst$$reg);
3473 address con = (address)$src$$constant;
3474 if (con == nullptr || con == (address)1) {
3475 ShouldNotReachHere();
3476 } else {
3477 relocInfo::relocType rtype = $src->constant_reloc();
3478 if (rtype == relocInfo::oop_type) {
3479 __ movoop(dst_reg, (jobject)con);
3480 } else if (rtype == relocInfo::metadata_type) {
3481 __ mov_metadata(dst_reg, (Metadata*)con);
3482 } else {
3483 assert(rtype == relocInfo::none, "unexpected reloc type");
3484 if (! __ is_valid_AArch64_address(con) ||
3485 con < (address)(uintptr_t)os::vm_page_size()) {
3486 __ mov(dst_reg, con);
3487 } else {
3488 uint64_t offset;
3489 __ adrp(dst_reg, con, offset);
3490 __ add(dst_reg, dst_reg, offset);
3491 }
3492 }
3493 }
3494 %}
3495
3496 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
3497 Register dst_reg = as_Register($dst$$reg);
3498 __ mov(dst_reg, zr);
3499 %}
3500
3501 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
3502 Register dst_reg = as_Register($dst$$reg);
3503 __ mov(dst_reg, (uint64_t)1);
3504 %}
3505
3506 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{
3507 Register dst_reg = as_Register($dst$$reg);
3508 address con = (address)$src$$constant;
3509 if (con == nullptr) {
3510 ShouldNotReachHere();
3511 } else {
3512 relocInfo::relocType rtype = $src->constant_reloc();
3513 assert(rtype == relocInfo::oop_type, "unexpected reloc type");
3514 __ set_narrow_oop(dst_reg, (jobject)con);
3515 }
3516 %}
3517
3518 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{
3519 Register dst_reg = as_Register($dst$$reg);
3520 __ mov(dst_reg, zr);
3521 %}
3522
3523 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{
3524 Register dst_reg = as_Register($dst$$reg);
3525 address con = (address)$src$$constant;
3526 if (con == nullptr) {
3527 ShouldNotReachHere();
3528 } else {
3529 relocInfo::relocType rtype = $src->constant_reloc();
3530 assert(rtype == relocInfo::metadata_type, "unexpected reloc type");
3531 __ set_narrow_klass(dst_reg, (Klass *)con);
3532 }
3533 %}
3534
3535 // arithmetic encodings
3536
3537 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{
3538 Register dst_reg = as_Register($dst$$reg);
3539 Register src_reg = as_Register($src1$$reg);
3540 int32_t con = (int32_t)$src2$$constant;
3541 // add has primary == 0, subtract has primary == 1
3542 if ($primary) { con = -con; }
3543 if (con < 0) {
3544 __ subw(dst_reg, src_reg, -con);
3545 } else {
3546 __ addw(dst_reg, src_reg, con);
3547 }
3548 %}
3549
3550 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{
3551 Register dst_reg = as_Register($dst$$reg);
3552 Register src_reg = as_Register($src1$$reg);
3553 int32_t con = (int32_t)$src2$$constant;
3554 // add has primary == 0, subtract has primary == 1
3555 if ($primary) { con = -con; }
3556 if (con < 0) {
3557 __ sub(dst_reg, src_reg, -con);
3558 } else {
3559 __ add(dst_reg, src_reg, con);
3560 }
3561 %}
3562
3563 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{
3564 Register dst_reg = as_Register($dst$$reg);
3565 Register src1_reg = as_Register($src1$$reg);
3566 Register src2_reg = as_Register($src2$$reg);
3567 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1);
3568 %}
3569
3570 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
3571 Register dst_reg = as_Register($dst$$reg);
3572 Register src1_reg = as_Register($src1$$reg);
3573 Register src2_reg = as_Register($src2$$reg);
3574 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1);
3575 %}
3576
3577 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
3578 Register dst_reg = as_Register($dst$$reg);
3579 Register src1_reg = as_Register($src1$$reg);
3580 Register src2_reg = as_Register($src2$$reg);
3581 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1);
3582 %}
3583
3584 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
3585 Register dst_reg = as_Register($dst$$reg);
3586 Register src1_reg = as_Register($src1$$reg);
3587 Register src2_reg = as_Register($src2$$reg);
3588 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1);
3589 %}
3590
3591 // compare instruction encodings
3592
3593 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{
3594 Register reg1 = as_Register($src1$$reg);
3595 Register reg2 = as_Register($src2$$reg);
3596 __ cmpw(reg1, reg2);
3597 %}
3598
3599 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{
3600 Register reg = as_Register($src1$$reg);
3601 int32_t val = $src2$$constant;
3602 if (val >= 0) {
3603 __ subsw(zr, reg, val);
3604 } else {
3605 __ addsw(zr, reg, -val);
3606 }
3607 %}
3608
3609 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{
3610 Register reg1 = as_Register($src1$$reg);
3611 uint32_t val = (uint32_t)$src2$$constant;
3612 __ movw(rscratch1, val);
3613 __ cmpw(reg1, rscratch1);
3614 %}
3615
3616 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{
3617 Register reg1 = as_Register($src1$$reg);
3618 Register reg2 = as_Register($src2$$reg);
3619 __ cmp(reg1, reg2);
3620 %}
3621
3622 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{
3623 Register reg = as_Register($src1$$reg);
3624 int64_t val = $src2$$constant;
3625 if (val >= 0) {
3626 __ subs(zr, reg, val);
3627 } else if (val != -val) {
3628 __ adds(zr, reg, -val);
3629 } else {
3630 // aargh, Long.MIN_VALUE is a special case
3631 __ orr(rscratch1, zr, (uint64_t)val);
3632 __ subs(zr, reg, rscratch1);
3633 }
3634 %}
3635
3636 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{
3637 Register reg1 = as_Register($src1$$reg);
3638 uint64_t val = (uint64_t)$src2$$constant;
3639 __ mov(rscratch1, val);
3640 __ cmp(reg1, rscratch1);
3641 %}
3642
3643 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{
3644 Register reg1 = as_Register($src1$$reg);
3645 Register reg2 = as_Register($src2$$reg);
3646 __ cmp(reg1, reg2);
3647 %}
3648
3649 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{
3650 Register reg1 = as_Register($src1$$reg);
3651 Register reg2 = as_Register($src2$$reg);
3652 __ cmpw(reg1, reg2);
3653 %}
3654
3655 enc_class aarch64_enc_testp(iRegP src) %{
3656 Register reg = as_Register($src$$reg);
3657 __ cmp(reg, zr);
3658 %}
3659
3660 enc_class aarch64_enc_testn(iRegN src) %{
3661 Register reg = as_Register($src$$reg);
3662 __ cmpw(reg, zr);
3663 %}
3664
3665 enc_class aarch64_enc_b(label lbl) %{
3666 Label *L = $lbl$$label;
3667 __ b(*L);
3668 %}
3669
3670 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{
3671 Label *L = $lbl$$label;
3672 __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3673 %}
3674
3675 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{
3676 Label *L = $lbl$$label;
3677 __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3678 %}
3679
3680 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result)
3681 %{
3682 Register sub_reg = as_Register($sub$$reg);
3683 Register super_reg = as_Register($super$$reg);
3684 Register temp_reg = as_Register($temp$$reg);
3685 Register result_reg = as_Register($result$$reg);
3686
3687 Label miss;
3688 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg,
3689 nullptr, &miss,
3690 /*set_cond_codes:*/ true);
3691 if ($primary) {
3692 __ mov(result_reg, zr);
3693 }
3694 __ bind(miss);
3695 %}
3696
3697 enc_class aarch64_enc_java_static_call(method meth) %{
3698 address addr = (address)$meth$$method;
3699 address call;
3700 if (!_method) {
3701 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3702 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type));
3703 if (call == nullptr) {
3704 ciEnv::current()->record_failure("CodeCache is full");
3705 return;
3706 }
3707 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) {
3708 // The NOP here is purely to ensure that eliding a call to
3709 // JVM_EnsureMaterializedForStackWalk doesn't change the code size.
3710 __ nop();
3711 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)");
3712 } else {
3713 int method_index = resolved_method_index(masm);
3714 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3715 : static_call_Relocation::spec(method_index);
3716 call = __ trampoline_call(Address(addr, rspec));
3717 if (call == nullptr) {
3718 ciEnv::current()->record_failure("CodeCache is full");
3719 return;
3720 }
3721 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) {
3722 // Calls of the same statically bound method can share
3723 // a stub to the interpreter.
3724 __ code()->shared_stub_to_interp_for(_method, call - __ begin());
3725 } else {
3726 // Emit stub for static call
3727 address stub = CompiledDirectCall::emit_to_interp_stub(masm, call);
3728 if (stub == nullptr) {
3729 ciEnv::current()->record_failure("CodeCache is full");
3730 return;
3731 }
3732 }
3733 }
3734
3735 __ post_call_nop();
3736
3737 // Only non uncommon_trap calls need to reinitialize ptrue.
3738 if (Compile::current()->max_vector_size() > 0 && uncommon_trap_request() == 0) {
3739 __ reinitialize_ptrue();
3740 }
3741 %}
3742
3743 enc_class aarch64_enc_java_dynamic_call(method meth) %{
3744 int method_index = resolved_method_index(masm);
3745 address call = __ ic_call((address)$meth$$method, method_index);
3746 if (call == nullptr) {
3747 ciEnv::current()->record_failure("CodeCache is full");
3748 return;
3749 }
3750 __ post_call_nop();
3751 if (Compile::current()->max_vector_size() > 0) {
3752 __ reinitialize_ptrue();
3753 }
3754 %}
3755
3756 enc_class aarch64_enc_call_epilog() %{
3757 if (VerifyStackAtCalls) {
3758 // Check that stack depth is unchanged: find majik cookie on stack
3759 __ call_Unimplemented();
3760 }
3761 %}
3762
3763 enc_class aarch64_enc_java_to_runtime(method meth) %{
3764 // some calls to generated routines (arraycopy code) are scheduled
3765 // by C2 as runtime calls. if so we can call them using a br (they
3766 // will be in a reachable segment) otherwise we have to use a blr
3767 // which loads the absolute address into a register.
3768 address entry = (address)$meth$$method;
3769 CodeBlob *cb = CodeCache::find_blob(entry);
3770 if (cb) {
3771 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type));
3772 if (call == nullptr) {
3773 ciEnv::current()->record_failure("CodeCache is full");
3774 return;
3775 }
3776 __ post_call_nop();
3777 } else {
3778 Label retaddr;
3779 // Make the anchor frame walkable
3780 __ adr(rscratch2, retaddr);
3781 __ str(rscratch2, Address(rthread, JavaThread::last_Java_pc_offset()));
3782 __ lea(rscratch1, RuntimeAddress(entry));
3783 __ blr(rscratch1);
3784 __ bind(retaddr);
3785 __ post_call_nop();
3786 }
3787 if (Compile::current()->max_vector_size() > 0) {
3788 __ reinitialize_ptrue();
3789 }
3790 %}
3791
3792 enc_class aarch64_enc_rethrow() %{
3793 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub()));
3794 %}
3795
3796 enc_class aarch64_enc_ret() %{
3797 #ifdef ASSERT
3798 if (Compile::current()->max_vector_size() > 0) {
3799 __ verify_ptrue();
3800 }
3801 #endif
3802 __ ret(lr);
3803 %}
3804
3805 enc_class aarch64_enc_tail_call(iRegP jump_target) %{
3806 Register target_reg = as_Register($jump_target$$reg);
3807 __ br(target_reg);
3808 %}
3809
3810 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{
3811 Register target_reg = as_Register($jump_target$$reg);
3812 // exception oop should be in r0
3813 // ret addr has been popped into lr
3814 // callee expects it in r3
3815 __ mov(r3, lr);
3816 __ br(target_reg);
3817 %}
3818
3819 %}
3820
3821 //----------FRAME--------------------------------------------------------------
3822 // Definition of frame structure and management information.
3823 //
3824 // S T A C K L A Y O U T Allocators stack-slot number
3825 // | (to get allocators register number
3826 // G Owned by | | v add OptoReg::stack0())
3827 // r CALLER | |
3828 // o | +--------+ pad to even-align allocators stack-slot
3829 // w V | pad0 | numbers; owned by CALLER
3830 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
3831 // h ^ | in | 5
3832 // | | args | 4 Holes in incoming args owned by SELF
3833 // | | | | 3
3834 // | | +--------+
3835 // V | | old out| Empty on Intel, window on Sparc
3836 // | old |preserve| Must be even aligned.
3837 // | SP-+--------+----> Matcher::_old_SP, even aligned
3838 // | | in | 3 area for Intel ret address
3839 // Owned by |preserve| Empty on Sparc.
3840 // SELF +--------+
3841 // | | pad2 | 2 pad to align old SP
3842 // | +--------+ 1
3843 // | | locks | 0
3844 // | +--------+----> OptoReg::stack0(), even aligned
3845 // | | pad1 | 11 pad to align new SP
3846 // | +--------+
3847 // | | | 10
3848 // | | spills | 9 spills
3849 // V | | 8 (pad0 slot for callee)
3850 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
3851 // ^ | out | 7
3852 // | | args | 6 Holes in outgoing args owned by CALLEE
3853 // Owned by +--------+
3854 // CALLEE | new out| 6 Empty on Intel, window on Sparc
3855 // | new |preserve| Must be even-aligned.
3856 // | SP-+--------+----> Matcher::_new_SP, even aligned
3857 // | | |
3858 //
3859 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
3860 // known from SELF's arguments and the Java calling convention.
3861 // Region 6-7 is determined per call site.
3862 // Note 2: If the calling convention leaves holes in the incoming argument
3863 // area, those holes are owned by SELF. Holes in the outgoing area
3864 // are owned by the CALLEE. Holes should not be necessary in the
3865 // incoming area, as the Java calling convention is completely under
3866 // the control of the AD file. Doubles can be sorted and packed to
3867 // avoid holes. Holes in the outgoing arguments may be necessary for
3868 // varargs C calling conventions.
3869 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
3870 // even aligned with pad0 as needed.
3871 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
3872 // (the latter is true on Intel but is it false on AArch64?)
3873 // region 6-11 is even aligned; it may be padded out more so that
3874 // the region from SP to FP meets the minimum stack alignment.
3875 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3876 // alignment. Region 11, pad1, may be dynamically extended so that
3877 // SP meets the minimum alignment.
3878
3879 frame %{
3880 // These three registers define part of the calling convention
3881 // between compiled code and the interpreter.
3882
3883 // Inline Cache Register or Method for I2C.
3884 inline_cache_reg(R12);
3885
3886 // Number of stack slots consumed by locking an object
3887 sync_stack_slots(2);
3888
3889 // Compiled code's Frame Pointer
3890 frame_pointer(R31);
3891
3892 // Interpreter stores its frame pointer in a register which is
3893 // stored to the stack by I2CAdaptors.
3894 // I2CAdaptors convert from interpreted java to compiled java.
3895 interpreter_frame_pointer(R29);
3896
3897 // Stack alignment requirement
3898 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
3899
3900 // Number of outgoing stack slots killed above the out_preserve_stack_slots
3901 // for calls to C. Supports the var-args backing area for register parms.
3902 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
3903
3904 // The after-PROLOG location of the return address. Location of
3905 // return address specifies a type (REG or STACK) and a number
3906 // representing the register number (i.e. - use a register name) or
3907 // stack slot.
3908 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3909 // Otherwise, it is above the locks and verification slot and alignment word
3910 // TODO this may well be correct but need to check why that - 2 is there
3911 // ppc port uses 0 but we definitely need to allow for fixed_slots
3912 // which folds in the space used for monitors
3913 return_addr(STACK - 2 +
3914 align_up((Compile::current()->in_preserve_stack_slots() +
3915 Compile::current()->fixed_slots()),
3916 stack_alignment_in_slots()));
3917
3918 // Location of compiled Java return values. Same as C for now.
3919 return_value
3920 %{
3921 // TODO do we allow ideal_reg == Op_RegN???
3922 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
3923 "only return normal values");
3924
3925 static const int lo[Op_RegL + 1] = { // enum name
3926 0, // Op_Node
3927 0, // Op_Set
3928 R0_num, // Op_RegN
3929 R0_num, // Op_RegI
3930 R0_num, // Op_RegP
3931 V0_num, // Op_RegF
3932 V0_num, // Op_RegD
3933 R0_num // Op_RegL
3934 };
3935
3936 static const int hi[Op_RegL + 1] = { // enum name
3937 0, // Op_Node
3938 0, // Op_Set
3939 OptoReg::Bad, // Op_RegN
3940 OptoReg::Bad, // Op_RegI
3941 R0_H_num, // Op_RegP
3942 OptoReg::Bad, // Op_RegF
3943 V0_H_num, // Op_RegD
3944 R0_H_num // Op_RegL
3945 };
3946
3947 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
3948 %}
3949 %}
3950
3951 //----------ATTRIBUTES---------------------------------------------------------
3952 //----------Operand Attributes-------------------------------------------------
3953 op_attrib op_cost(1); // Required cost attribute
3954
3955 //----------Instruction Attributes---------------------------------------------
3956 ins_attrib ins_cost(INSN_COST); // Required cost attribute
3957 ins_attrib ins_size(32); // Required size attribute (in bits)
3958 ins_attrib ins_short_branch(0); // Required flag: is this instruction
3959 // a non-matching short branch variant
3960 // of some long branch?
3961 ins_attrib ins_alignment(4); // Required alignment attribute (must
3962 // be a power of 2) specifies the
3963 // alignment that some part of the
3964 // instruction (not necessarily the
3965 // start) requires. If > 1, a
3966 // compute_padding() function must be
3967 // provided for the instruction
3968
3969 // Whether this node is expanded during code emission into a sequence of
3970 // instructions and the first instruction can perform an implicit null check.
3971 ins_attrib ins_is_late_expanded_null_check_candidate(false);
3972
3973 //----------OPERANDS-----------------------------------------------------------
3974 // Operand definitions must precede instruction definitions for correct parsing
3975 // in the ADLC because operands constitute user defined types which are used in
3976 // instruction definitions.
3977
3978 //----------Simple Operands----------------------------------------------------
3979
3980 // Integer operands 32 bit
3981 // 32 bit immediate
3982 operand immI()
3983 %{
3984 match(ConI);
3985
3986 op_cost(0);
3987 format %{ %}
3988 interface(CONST_INTER);
3989 %}
3990
3991 // 32 bit zero
3992 operand immI0()
3993 %{
3994 predicate(n->get_int() == 0);
3995 match(ConI);
3996
3997 op_cost(0);
3998 format %{ %}
3999 interface(CONST_INTER);
4000 %}
4001
4002 // 32 bit unit increment
4003 operand immI_1()
4004 %{
4005 predicate(n->get_int() == 1);
4006 match(ConI);
4007
4008 op_cost(0);
4009 format %{ %}
4010 interface(CONST_INTER);
4011 %}
4012
4013 // 32 bit unit decrement
4014 operand immI_M1()
4015 %{
4016 predicate(n->get_int() == -1);
4017 match(ConI);
4018
4019 op_cost(0);
4020 format %{ %}
4021 interface(CONST_INTER);
4022 %}
4023
4024 // Shift values for add/sub extension shift
4025 operand immIExt()
4026 %{
4027 predicate(0 <= n->get_int() && (n->get_int() <= 4));
4028 match(ConI);
4029
4030 op_cost(0);
4031 format %{ %}
4032 interface(CONST_INTER);
4033 %}
4034
4035 operand immI_gt_1()
4036 %{
4037 predicate(n->get_int() > 1);
4038 match(ConI);
4039
4040 op_cost(0);
4041 format %{ %}
4042 interface(CONST_INTER);
4043 %}
4044
4045 operand immI_le_4()
4046 %{
4047 predicate(n->get_int() <= 4);
4048 match(ConI);
4049
4050 op_cost(0);
4051 format %{ %}
4052 interface(CONST_INTER);
4053 %}
4054
4055 operand immI_16()
4056 %{
4057 predicate(n->get_int() == 16);
4058 match(ConI);
4059
4060 op_cost(0);
4061 format %{ %}
4062 interface(CONST_INTER);
4063 %}
4064
4065 operand immI_24()
4066 %{
4067 predicate(n->get_int() == 24);
4068 match(ConI);
4069
4070 op_cost(0);
4071 format %{ %}
4072 interface(CONST_INTER);
4073 %}
4074
4075 operand immI_32()
4076 %{
4077 predicate(n->get_int() == 32);
4078 match(ConI);
4079
4080 op_cost(0);
4081 format %{ %}
4082 interface(CONST_INTER);
4083 %}
4084
4085 operand immI_48()
4086 %{
4087 predicate(n->get_int() == 48);
4088 match(ConI);
4089
4090 op_cost(0);
4091 format %{ %}
4092 interface(CONST_INTER);
4093 %}
4094
4095 operand immI_56()
4096 %{
4097 predicate(n->get_int() == 56);
4098 match(ConI);
4099
4100 op_cost(0);
4101 format %{ %}
4102 interface(CONST_INTER);
4103 %}
4104
4105 operand immI_255()
4106 %{
4107 predicate(n->get_int() == 255);
4108 match(ConI);
4109
4110 op_cost(0);
4111 format %{ %}
4112 interface(CONST_INTER);
4113 %}
4114
4115 operand immI_65535()
4116 %{
4117 predicate(n->get_int() == 65535);
4118 match(ConI);
4119
4120 op_cost(0);
4121 format %{ %}
4122 interface(CONST_INTER);
4123 %}
4124
4125 operand immI_positive()
4126 %{
4127 predicate(n->get_int() > 0);
4128 match(ConI);
4129
4130 op_cost(0);
4131 format %{ %}
4132 interface(CONST_INTER);
4133 %}
4134
4135 // BoolTest condition for signed compare
4136 operand immI_cmp_cond()
4137 %{
4138 predicate(!Matcher::is_unsigned_booltest_pred(n->get_int()));
4139 match(ConI);
4140
4141 op_cost(0);
4142 format %{ %}
4143 interface(CONST_INTER);
4144 %}
4145
4146 // BoolTest condition for unsigned compare
4147 operand immI_cmpU_cond()
4148 %{
4149 predicate(Matcher::is_unsigned_booltest_pred(n->get_int()));
4150 match(ConI);
4151
4152 op_cost(0);
4153 format %{ %}
4154 interface(CONST_INTER);
4155 %}
4156
4157 operand immL_255()
4158 %{
4159 predicate(n->get_long() == 255L);
4160 match(ConL);
4161
4162 op_cost(0);
4163 format %{ %}
4164 interface(CONST_INTER);
4165 %}
4166
4167 operand immL_65535()
4168 %{
4169 predicate(n->get_long() == 65535L);
4170 match(ConL);
4171
4172 op_cost(0);
4173 format %{ %}
4174 interface(CONST_INTER);
4175 %}
4176
4177 operand immL_4294967295()
4178 %{
4179 predicate(n->get_long() == 4294967295L);
4180 match(ConL);
4181
4182 op_cost(0);
4183 format %{ %}
4184 interface(CONST_INTER);
4185 %}
4186
4187 operand immL_bitmask()
4188 %{
4189 predicate((n->get_long() != 0)
4190 && ((n->get_long() & 0xc000000000000000l) == 0)
4191 && is_power_of_2(n->get_long() + 1));
4192 match(ConL);
4193
4194 op_cost(0);
4195 format %{ %}
4196 interface(CONST_INTER);
4197 %}
4198
4199 operand immI_bitmask()
4200 %{
4201 predicate((n->get_int() != 0)
4202 && ((n->get_int() & 0xc0000000) == 0)
4203 && is_power_of_2(n->get_int() + 1));
4204 match(ConI);
4205
4206 op_cost(0);
4207 format %{ %}
4208 interface(CONST_INTER);
4209 %}
4210
4211 operand immL_positive_bitmaskI()
4212 %{
4213 predicate((n->get_long() != 0)
4214 && ((julong)n->get_long() < 0x80000000ULL)
4215 && is_power_of_2(n->get_long() + 1));
4216 match(ConL);
4217
4218 op_cost(0);
4219 format %{ %}
4220 interface(CONST_INTER);
4221 %}
4222
4223 // Scale values for scaled offset addressing modes (up to long but not quad)
4224 operand immIScale()
4225 %{
4226 predicate(0 <= n->get_int() && (n->get_int() <= 3));
4227 match(ConI);
4228
4229 op_cost(0);
4230 format %{ %}
4231 interface(CONST_INTER);
4232 %}
4233
4234 // 5 bit signed integer
4235 operand immI5()
4236 %{
4237 predicate(Assembler::is_simm(n->get_int(), 5));
4238 match(ConI);
4239
4240 op_cost(0);
4241 format %{ %}
4242 interface(CONST_INTER);
4243 %}
4244
4245 // 7 bit unsigned integer
4246 operand immIU7()
4247 %{
4248 predicate(Assembler::is_uimm(n->get_int(), 7));
4249 match(ConI);
4250
4251 op_cost(0);
4252 format %{ %}
4253 interface(CONST_INTER);
4254 %}
4255
4256 // Offset for scaled or unscaled immediate loads and stores
4257 operand immIOffset()
4258 %{
4259 predicate(Address::offset_ok_for_immed(n->get_int(), 0));
4260 match(ConI);
4261
4262 op_cost(0);
4263 format %{ %}
4264 interface(CONST_INTER);
4265 %}
4266
4267 operand immIOffset1()
4268 %{
4269 predicate(Address::offset_ok_for_immed(n->get_int(), 0));
4270 match(ConI);
4271
4272 op_cost(0);
4273 format %{ %}
4274 interface(CONST_INTER);
4275 %}
4276
4277 operand immIOffset2()
4278 %{
4279 predicate(Address::offset_ok_for_immed(n->get_int(), 1));
4280 match(ConI);
4281
4282 op_cost(0);
4283 format %{ %}
4284 interface(CONST_INTER);
4285 %}
4286
4287 operand immIOffset4()
4288 %{
4289 predicate(Address::offset_ok_for_immed(n->get_int(), 2));
4290 match(ConI);
4291
4292 op_cost(0);
4293 format %{ %}
4294 interface(CONST_INTER);
4295 %}
4296
4297 operand immIOffset8()
4298 %{
4299 predicate(Address::offset_ok_for_immed(n->get_int(), 3));
4300 match(ConI);
4301
4302 op_cost(0);
4303 format %{ %}
4304 interface(CONST_INTER);
4305 %}
4306
4307 operand immIOffset16()
4308 %{
4309 predicate(Address::offset_ok_for_immed(n->get_int(), 4));
4310 match(ConI);
4311
4312 op_cost(0);
4313 format %{ %}
4314 interface(CONST_INTER);
4315 %}
4316
4317 operand immLOffset()
4318 %{
4319 predicate(n->get_long() >= -256 && n->get_long() <= 65520);
4320 match(ConL);
4321
4322 op_cost(0);
4323 format %{ %}
4324 interface(CONST_INTER);
4325 %}
4326
4327 operand immLoffset1()
4328 %{
4329 predicate(Address::offset_ok_for_immed(n->get_long(), 0));
4330 match(ConL);
4331
4332 op_cost(0);
4333 format %{ %}
4334 interface(CONST_INTER);
4335 %}
4336
4337 operand immLoffset2()
4338 %{
4339 predicate(Address::offset_ok_for_immed(n->get_long(), 1));
4340 match(ConL);
4341
4342 op_cost(0);
4343 format %{ %}
4344 interface(CONST_INTER);
4345 %}
4346
4347 operand immLoffset4()
4348 %{
4349 predicate(Address::offset_ok_for_immed(n->get_long(), 2));
4350 match(ConL);
4351
4352 op_cost(0);
4353 format %{ %}
4354 interface(CONST_INTER);
4355 %}
4356
4357 operand immLoffset8()
4358 %{
4359 predicate(Address::offset_ok_for_immed(n->get_long(), 3));
4360 match(ConL);
4361
4362 op_cost(0);
4363 format %{ %}
4364 interface(CONST_INTER);
4365 %}
4366
4367 operand immLoffset16()
4368 %{
4369 predicate(Address::offset_ok_for_immed(n->get_long(), 4));
4370 match(ConL);
4371
4372 op_cost(0);
4373 format %{ %}
4374 interface(CONST_INTER);
4375 %}
4376
4377 // 5 bit signed long integer
4378 operand immL5()
4379 %{
4380 predicate(Assembler::is_simm(n->get_long(), 5));
4381 match(ConL);
4382
4383 op_cost(0);
4384 format %{ %}
4385 interface(CONST_INTER);
4386 %}
4387
4388 // 7 bit unsigned long integer
4389 operand immLU7()
4390 %{
4391 predicate(Assembler::is_uimm(n->get_long(), 7));
4392 match(ConL);
4393
4394 op_cost(0);
4395 format %{ %}
4396 interface(CONST_INTER);
4397 %}
4398
4399 // 8 bit signed value.
4400 operand immI8()
4401 %{
4402 predicate(n->get_int() <= 127 && n->get_int() >= -128);
4403 match(ConI);
4404
4405 op_cost(0);
4406 format %{ %}
4407 interface(CONST_INTER);
4408 %}
4409
4410 // 8 bit signed value (simm8), or #simm8 LSL 8.
4411 operand immIDupV()
4412 %{
4413 predicate(Assembler::operand_valid_for_sve_dup_immediate((int64_t)n->get_int()));
4414 match(ConI);
4415
4416 op_cost(0);
4417 format %{ %}
4418 interface(CONST_INTER);
4419 %}
4420
4421 // 8 bit signed value (simm8), or #simm8 LSL 8.
4422 operand immLDupV()
4423 %{
4424 predicate(Assembler::operand_valid_for_sve_dup_immediate(n->get_long()));
4425 match(ConL);
4426
4427 op_cost(0);
4428 format %{ %}
4429 interface(CONST_INTER);
4430 %}
4431
4432 // 8 bit signed value (simm8), or #simm8 LSL 8.
4433 operand immHDupV()
4434 %{
4435 predicate(Assembler::operand_valid_for_sve_dup_immediate((int64_t)n->geth()));
4436 match(ConH);
4437
4438 op_cost(0);
4439 format %{ %}
4440 interface(CONST_INTER);
4441 %}
4442
4443 // 8 bit integer valid for vector add sub immediate
4444 operand immBAddSubV()
4445 %{
4446 predicate(n->get_int() <= 255 && n->get_int() >= -255);
4447 match(ConI);
4448
4449 op_cost(0);
4450 format %{ %}
4451 interface(CONST_INTER);
4452 %}
4453
4454 // 32 bit integer valid for add sub immediate
4455 operand immIAddSub()
4456 %{
4457 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int()));
4458 match(ConI);
4459 op_cost(0);
4460 format %{ %}
4461 interface(CONST_INTER);
4462 %}
4463
4464 // 32 bit integer valid for vector add sub immediate
4465 operand immIAddSubV()
4466 %{
4467 predicate(Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)n->get_int()));
4468 match(ConI);
4469
4470 op_cost(0);
4471 format %{ %}
4472 interface(CONST_INTER);
4473 %}
4474
4475 // 32 bit unsigned integer valid for logical immediate
4476
4477 operand immBLog()
4478 %{
4479 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerByte, (uint64_t)n->get_int()));
4480 match(ConI);
4481
4482 op_cost(0);
4483 format %{ %}
4484 interface(CONST_INTER);
4485 %}
4486
4487 operand immSLog()
4488 %{
4489 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerShort, (uint64_t)n->get_int()));
4490 match(ConI);
4491
4492 op_cost(0);
4493 format %{ %}
4494 interface(CONST_INTER);
4495 %}
4496
4497 operand immILog()
4498 %{
4499 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int()));
4500 match(ConI);
4501
4502 op_cost(0);
4503 format %{ %}
4504 interface(CONST_INTER);
4505 %}
4506
4507 // Integer operands 64 bit
4508 // 64 bit immediate
4509 operand immL()
4510 %{
4511 match(ConL);
4512
4513 op_cost(0);
4514 format %{ %}
4515 interface(CONST_INTER);
4516 %}
4517
4518 // 64 bit zero
4519 operand immL0()
4520 %{
4521 predicate(n->get_long() == 0);
4522 match(ConL);
4523
4524 op_cost(0);
4525 format %{ %}
4526 interface(CONST_INTER);
4527 %}
4528
4529 // 64 bit unit decrement
4530 operand immL_M1()
4531 %{
4532 predicate(n->get_long() == -1);
4533 match(ConL);
4534
4535 op_cost(0);
4536 format %{ %}
4537 interface(CONST_INTER);
4538 %}
4539
4540 // 64 bit integer valid for add sub immediate
4541 operand immLAddSub()
4542 %{
4543 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long()));
4544 match(ConL);
4545 op_cost(0);
4546 format %{ %}
4547 interface(CONST_INTER);
4548 %}
4549
4550 // 64 bit integer valid for addv subv immediate
4551 operand immLAddSubV()
4552 %{
4553 predicate(Assembler::operand_valid_for_sve_add_sub_immediate(n->get_long()));
4554 match(ConL);
4555
4556 op_cost(0);
4557 format %{ %}
4558 interface(CONST_INTER);
4559 %}
4560
4561 // 64 bit integer valid for logical immediate
4562 operand immLLog()
4563 %{
4564 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long()));
4565 match(ConL);
4566 op_cost(0);
4567 format %{ %}
4568 interface(CONST_INTER);
4569 %}
4570
4571 // Long Immediate: low 32-bit mask
4572 operand immL_32bits()
4573 %{
4574 predicate(n->get_long() == 0xFFFFFFFFL);
4575 match(ConL);
4576 op_cost(0);
4577 format %{ %}
4578 interface(CONST_INTER);
4579 %}
4580
4581 // Pointer operands
4582 // Pointer Immediate
4583 operand immP()
4584 %{
4585 match(ConP);
4586
4587 op_cost(0);
4588 format %{ %}
4589 interface(CONST_INTER);
4590 %}
4591
4592 // nullptr Pointer Immediate
4593 operand immP0()
4594 %{
4595 predicate(n->get_ptr() == 0);
4596 match(ConP);
4597
4598 op_cost(0);
4599 format %{ %}
4600 interface(CONST_INTER);
4601 %}
4602
4603 // Pointer Immediate One
4604 // this is used in object initialization (initial object header)
4605 operand immP_1()
4606 %{
4607 predicate(n->get_ptr() == 1);
4608 match(ConP);
4609
4610 op_cost(0);
4611 format %{ %}
4612 interface(CONST_INTER);
4613 %}
4614
4615 // Float and Double operands
4616 // Double Immediate
4617 operand immD()
4618 %{
4619 match(ConD);
4620 op_cost(0);
4621 format %{ %}
4622 interface(CONST_INTER);
4623 %}
4624
4625 // Double Immediate: +0.0d
4626 operand immD0()
4627 %{
4628 predicate(jlong_cast(n->getd()) == 0);
4629 match(ConD);
4630
4631 op_cost(0);
4632 format %{ %}
4633 interface(CONST_INTER);
4634 %}
4635
4636 // constant 'double +0.0'.
4637 operand immDPacked()
4638 %{
4639 predicate(Assembler::operand_valid_for_float_immediate(n->getd()));
4640 match(ConD);
4641 op_cost(0);
4642 format %{ %}
4643 interface(CONST_INTER);
4644 %}
4645
4646 // Float Immediate
4647 operand immF()
4648 %{
4649 match(ConF);
4650 op_cost(0);
4651 format %{ %}
4652 interface(CONST_INTER);
4653 %}
4654
4655 // Float Immediate: +0.0f.
4656 operand immF0()
4657 %{
4658 predicate(jint_cast(n->getf()) == 0);
4659 match(ConF);
4660
4661 op_cost(0);
4662 format %{ %}
4663 interface(CONST_INTER);
4664 %}
4665
4666 // Half Float (FP16) Immediate
4667 operand immH()
4668 %{
4669 match(ConH);
4670 op_cost(0);
4671 format %{ %}
4672 interface(CONST_INTER);
4673 %}
4674
4675 //
4676 operand immFPacked()
4677 %{
4678 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf()));
4679 match(ConF);
4680 op_cost(0);
4681 format %{ %}
4682 interface(CONST_INTER);
4683 %}
4684
4685 // Narrow pointer operands
4686 // Narrow Pointer Immediate
4687 operand immN()
4688 %{
4689 match(ConN);
4690
4691 op_cost(0);
4692 format %{ %}
4693 interface(CONST_INTER);
4694 %}
4695
4696 // Narrow nullptr Pointer Immediate
4697 operand immN0()
4698 %{
4699 predicate(n->get_narrowcon() == 0);
4700 match(ConN);
4701
4702 op_cost(0);
4703 format %{ %}
4704 interface(CONST_INTER);
4705 %}
4706
4707 operand immNKlass()
4708 %{
4709 match(ConNKlass);
4710
4711 op_cost(0);
4712 format %{ %}
4713 interface(CONST_INTER);
4714 %}
4715
4716 // Integer 32 bit Register Operands
4717 // Integer 32 bitRegister (excludes SP)
4718 operand iRegI()
4719 %{
4720 constraint(ALLOC_IN_RC(any_reg32));
4721 match(RegI);
4722 match(iRegINoSp);
4723 op_cost(0);
4724 format %{ %}
4725 interface(REG_INTER);
4726 %}
4727
4728 // Integer 32 bit Register not Special
4729 operand iRegINoSp()
4730 %{
4731 constraint(ALLOC_IN_RC(no_special_reg32));
4732 match(RegI);
4733 op_cost(0);
4734 format %{ %}
4735 interface(REG_INTER);
4736 %}
4737
4738 // Integer 64 bit Register Operands
4739 // Integer 64 bit Register (includes SP)
4740 operand iRegL()
4741 %{
4742 constraint(ALLOC_IN_RC(any_reg));
4743 match(RegL);
4744 match(iRegLNoSp);
4745 op_cost(0);
4746 format %{ %}
4747 interface(REG_INTER);
4748 %}
4749
4750 // Integer 64 bit Register not Special
4751 operand iRegLNoSp()
4752 %{
4753 constraint(ALLOC_IN_RC(no_special_reg));
4754 match(RegL);
4755 match(iRegL_R0);
4756 format %{ %}
4757 interface(REG_INTER);
4758 %}
4759
4760 // Pointer Register Operands
4761 // Pointer Register
4762 operand iRegP()
4763 %{
4764 constraint(ALLOC_IN_RC(ptr_reg));
4765 match(RegP);
4766 match(iRegPNoSp);
4767 match(iRegP_R0);
4768 //match(iRegP_R2);
4769 //match(iRegP_R4);
4770 match(iRegP_R5);
4771 match(thread_RegP);
4772 op_cost(0);
4773 format %{ %}
4774 interface(REG_INTER);
4775 %}
4776
4777 // Pointer 64 bit Register not Special
4778 operand iRegPNoSp()
4779 %{
4780 constraint(ALLOC_IN_RC(no_special_ptr_reg));
4781 match(RegP);
4782 // match(iRegP);
4783 // match(iRegP_R0);
4784 // match(iRegP_R2);
4785 // match(iRegP_R4);
4786 // match(iRegP_R5);
4787 // match(thread_RegP);
4788 op_cost(0);
4789 format %{ %}
4790 interface(REG_INTER);
4791 %}
4792
4793 // This operand is not allowed to use rfp even if
4794 // rfp is not used to hold the frame pointer.
4795 operand iRegPNoSpNoRfp()
4796 %{
4797 constraint(ALLOC_IN_RC(no_special_no_rfp_ptr_reg));
4798 match(RegP);
4799 match(iRegPNoSp);
4800 op_cost(0);
4801 format %{ %}
4802 interface(REG_INTER);
4803 %}
4804
4805 // Pointer 64 bit Register R0 only
4806 operand iRegP_R0()
4807 %{
4808 constraint(ALLOC_IN_RC(r0_reg));
4809 match(RegP);
4810 // match(iRegP);
4811 match(iRegPNoSp);
4812 op_cost(0);
4813 format %{ %}
4814 interface(REG_INTER);
4815 %}
4816
4817 // Pointer 64 bit Register R1 only
4818 operand iRegP_R1()
4819 %{
4820 constraint(ALLOC_IN_RC(r1_reg));
4821 match(RegP);
4822 // match(iRegP);
4823 match(iRegPNoSp);
4824 op_cost(0);
4825 format %{ %}
4826 interface(REG_INTER);
4827 %}
4828
4829 // Pointer 64 bit Register R2 only
4830 operand iRegP_R2()
4831 %{
4832 constraint(ALLOC_IN_RC(r2_reg));
4833 match(RegP);
4834 // match(iRegP);
4835 match(iRegPNoSp);
4836 op_cost(0);
4837 format %{ %}
4838 interface(REG_INTER);
4839 %}
4840
4841 // Pointer 64 bit Register R3 only
4842 operand iRegP_R3()
4843 %{
4844 constraint(ALLOC_IN_RC(r3_reg));
4845 match(RegP);
4846 // match(iRegP);
4847 match(iRegPNoSp);
4848 op_cost(0);
4849 format %{ %}
4850 interface(REG_INTER);
4851 %}
4852
4853 // Pointer 64 bit Register R4 only
4854 operand iRegP_R4()
4855 %{
4856 constraint(ALLOC_IN_RC(r4_reg));
4857 match(RegP);
4858 // match(iRegP);
4859 match(iRegPNoSp);
4860 op_cost(0);
4861 format %{ %}
4862 interface(REG_INTER);
4863 %}
4864
4865 // Pointer 64 bit Register R5 only
4866 operand iRegP_R5()
4867 %{
4868 constraint(ALLOC_IN_RC(r5_reg));
4869 match(RegP);
4870 // match(iRegP);
4871 match(iRegPNoSp);
4872 op_cost(0);
4873 format %{ %}
4874 interface(REG_INTER);
4875 %}
4876
4877 // Pointer 64 bit Register R10 only
4878 operand iRegP_R10()
4879 %{
4880 constraint(ALLOC_IN_RC(r10_reg));
4881 match(RegP);
4882 // match(iRegP);
4883 match(iRegPNoSp);
4884 op_cost(0);
4885 format %{ %}
4886 interface(REG_INTER);
4887 %}
4888
4889 // Long 64 bit Register R0 only
4890 operand iRegL_R0()
4891 %{
4892 constraint(ALLOC_IN_RC(r0_reg));
4893 match(RegL);
4894 match(iRegLNoSp);
4895 op_cost(0);
4896 format %{ %}
4897 interface(REG_INTER);
4898 %}
4899
4900 // Long 64 bit Register R11 only
4901 operand iRegL_R11()
4902 %{
4903 constraint(ALLOC_IN_RC(r11_reg));
4904 match(RegL);
4905 match(iRegLNoSp);
4906 op_cost(0);
4907 format %{ %}
4908 interface(REG_INTER);
4909 %}
4910
4911 // Register R0 only
4912 operand iRegI_R0()
4913 %{
4914 constraint(ALLOC_IN_RC(int_r0_reg));
4915 match(RegI);
4916 match(iRegINoSp);
4917 op_cost(0);
4918 format %{ %}
4919 interface(REG_INTER);
4920 %}
4921
4922 // Register R2 only
4923 operand iRegI_R2()
4924 %{
4925 constraint(ALLOC_IN_RC(int_r2_reg));
4926 match(RegI);
4927 match(iRegINoSp);
4928 op_cost(0);
4929 format %{ %}
4930 interface(REG_INTER);
4931 %}
4932
4933 // Register R3 only
4934 operand iRegI_R3()
4935 %{
4936 constraint(ALLOC_IN_RC(int_r3_reg));
4937 match(RegI);
4938 match(iRegINoSp);
4939 op_cost(0);
4940 format %{ %}
4941 interface(REG_INTER);
4942 %}
4943
4944
4945 // Register R4 only
4946 operand iRegI_R4()
4947 %{
4948 constraint(ALLOC_IN_RC(int_r4_reg));
4949 match(RegI);
4950 match(iRegINoSp);
4951 op_cost(0);
4952 format %{ %}
4953 interface(REG_INTER);
4954 %}
4955
4956
4957 // Pointer Register Operands
4958 // Narrow Pointer Register
4959 operand iRegN()
4960 %{
4961 constraint(ALLOC_IN_RC(any_reg32));
4962 match(RegN);
4963 match(iRegNNoSp);
4964 op_cost(0);
4965 format %{ %}
4966 interface(REG_INTER);
4967 %}
4968
4969 // Integer 64 bit Register not Special
4970 operand iRegNNoSp()
4971 %{
4972 constraint(ALLOC_IN_RC(no_special_reg32));
4973 match(RegN);
4974 op_cost(0);
4975 format %{ %}
4976 interface(REG_INTER);
4977 %}
4978
4979 // Float Register
4980 // Float register operands
4981 operand vRegF()
4982 %{
4983 constraint(ALLOC_IN_RC(float_reg));
4984 match(RegF);
4985
4986 op_cost(0);
4987 format %{ %}
4988 interface(REG_INTER);
4989 %}
4990
4991 // Double Register
4992 // Double register operands
4993 operand vRegD()
4994 %{
4995 constraint(ALLOC_IN_RC(double_reg));
4996 match(RegD);
4997
4998 op_cost(0);
4999 format %{ %}
5000 interface(REG_INTER);
5001 %}
5002
5003 // Generic vector class. This will be used for
5004 // all vector operands, including NEON and SVE.
5005 operand vReg()
5006 %{
5007 constraint(ALLOC_IN_RC(dynamic));
5008 match(VecA);
5009 match(VecD);
5010 match(VecX);
5011
5012 op_cost(0);
5013 format %{ %}
5014 interface(REG_INTER);
5015 %}
5016
5017 operand vReg_V10()
5018 %{
5019 constraint(ALLOC_IN_RC(v10_veca_reg));
5020 match(vReg);
5021
5022 op_cost(0);
5023 format %{ %}
5024 interface(REG_INTER);
5025 %}
5026
5027 operand vReg_V11()
5028 %{
5029 constraint(ALLOC_IN_RC(v11_veca_reg));
5030 match(vReg);
5031
5032 op_cost(0);
5033 format %{ %}
5034 interface(REG_INTER);
5035 %}
5036
5037 operand vReg_V12()
5038 %{
5039 constraint(ALLOC_IN_RC(v12_veca_reg));
5040 match(vReg);
5041
5042 op_cost(0);
5043 format %{ %}
5044 interface(REG_INTER);
5045 %}
5046
5047 operand vReg_V13()
5048 %{
5049 constraint(ALLOC_IN_RC(v13_veca_reg));
5050 match(vReg);
5051
5052 op_cost(0);
5053 format %{ %}
5054 interface(REG_INTER);
5055 %}
5056
5057 operand vReg_V17()
5058 %{
5059 constraint(ALLOC_IN_RC(v17_veca_reg));
5060 match(vReg);
5061
5062 op_cost(0);
5063 format %{ %}
5064 interface(REG_INTER);
5065 %}
5066
5067 operand vReg_V18()
5068 %{
5069 constraint(ALLOC_IN_RC(v18_veca_reg));
5070 match(vReg);
5071
5072 op_cost(0);
5073 format %{ %}
5074 interface(REG_INTER);
5075 %}
5076
5077 operand vReg_V23()
5078 %{
5079 constraint(ALLOC_IN_RC(v23_veca_reg));
5080 match(vReg);
5081
5082 op_cost(0);
5083 format %{ %}
5084 interface(REG_INTER);
5085 %}
5086
5087 operand vReg_V24()
5088 %{
5089 constraint(ALLOC_IN_RC(v24_veca_reg));
5090 match(vReg);
5091
5092 op_cost(0);
5093 format %{ %}
5094 interface(REG_INTER);
5095 %}
5096
5097 operand vecA()
5098 %{
5099 constraint(ALLOC_IN_RC(vectora_reg));
5100 match(VecA);
5101
5102 op_cost(0);
5103 format %{ %}
5104 interface(REG_INTER);
5105 %}
5106
5107 operand vecD()
5108 %{
5109 constraint(ALLOC_IN_RC(vectord_reg));
5110 match(VecD);
5111
5112 op_cost(0);
5113 format %{ %}
5114 interface(REG_INTER);
5115 %}
5116
5117 operand vecX()
5118 %{
5119 constraint(ALLOC_IN_RC(vectorx_reg));
5120 match(VecX);
5121
5122 op_cost(0);
5123 format %{ %}
5124 interface(REG_INTER);
5125 %}
5126
5127 operand vRegD_V0()
5128 %{
5129 constraint(ALLOC_IN_RC(v0_reg));
5130 match(RegD);
5131 op_cost(0);
5132 format %{ %}
5133 interface(REG_INTER);
5134 %}
5135
5136 operand vRegD_V1()
5137 %{
5138 constraint(ALLOC_IN_RC(v1_reg));
5139 match(RegD);
5140 op_cost(0);
5141 format %{ %}
5142 interface(REG_INTER);
5143 %}
5144
5145 operand vRegD_V2()
5146 %{
5147 constraint(ALLOC_IN_RC(v2_reg));
5148 match(RegD);
5149 op_cost(0);
5150 format %{ %}
5151 interface(REG_INTER);
5152 %}
5153
5154 operand vRegD_V3()
5155 %{
5156 constraint(ALLOC_IN_RC(v3_reg));
5157 match(RegD);
5158 op_cost(0);
5159 format %{ %}
5160 interface(REG_INTER);
5161 %}
5162
5163 operand vRegD_V4()
5164 %{
5165 constraint(ALLOC_IN_RC(v4_reg));
5166 match(RegD);
5167 op_cost(0);
5168 format %{ %}
5169 interface(REG_INTER);
5170 %}
5171
5172 operand vRegD_V5()
5173 %{
5174 constraint(ALLOC_IN_RC(v5_reg));
5175 match(RegD);
5176 op_cost(0);
5177 format %{ %}
5178 interface(REG_INTER);
5179 %}
5180
5181 operand vRegD_V6()
5182 %{
5183 constraint(ALLOC_IN_RC(v6_reg));
5184 match(RegD);
5185 op_cost(0);
5186 format %{ %}
5187 interface(REG_INTER);
5188 %}
5189
5190 operand vRegD_V7()
5191 %{
5192 constraint(ALLOC_IN_RC(v7_reg));
5193 match(RegD);
5194 op_cost(0);
5195 format %{ %}
5196 interface(REG_INTER);
5197 %}
5198
5199 operand vRegD_V12()
5200 %{
5201 constraint(ALLOC_IN_RC(v12_reg));
5202 match(RegD);
5203 op_cost(0);
5204 format %{ %}
5205 interface(REG_INTER);
5206 %}
5207
5208 operand vRegD_V13()
5209 %{
5210 constraint(ALLOC_IN_RC(v13_reg));
5211 match(RegD);
5212 op_cost(0);
5213 format %{ %}
5214 interface(REG_INTER);
5215 %}
5216
5217 operand pReg()
5218 %{
5219 constraint(ALLOC_IN_RC(pr_reg));
5220 match(RegVectMask);
5221 match(pRegGov);
5222 op_cost(0);
5223 format %{ %}
5224 interface(REG_INTER);
5225 %}
5226
5227 operand pRegGov()
5228 %{
5229 constraint(ALLOC_IN_RC(gov_pr));
5230 match(RegVectMask);
5231 match(pReg);
5232 op_cost(0);
5233 format %{ %}
5234 interface(REG_INTER);
5235 %}
5236
5237 operand pRegGov_P0()
5238 %{
5239 constraint(ALLOC_IN_RC(p0_reg));
5240 match(RegVectMask);
5241 op_cost(0);
5242 format %{ %}
5243 interface(REG_INTER);
5244 %}
5245
5246 operand pRegGov_P1()
5247 %{
5248 constraint(ALLOC_IN_RC(p1_reg));
5249 match(RegVectMask);
5250 op_cost(0);
5251 format %{ %}
5252 interface(REG_INTER);
5253 %}
5254
5255 // Flags register, used as output of signed compare instructions
5256
5257 // note that on AArch64 we also use this register as the output for
5258 // for floating point compare instructions (CmpF CmpD). this ensures
5259 // that ordered inequality tests use GT, GE, LT or LE none of which
5260 // pass through cases where the result is unordered i.e. one or both
5261 // inputs to the compare is a NaN. this means that the ideal code can
5262 // replace e.g. a GT with an LE and not end up capturing the NaN case
5263 // (where the comparison should always fail). EQ and NE tests are
5264 // always generated in ideal code so that unordered folds into the NE
5265 // case, matching the behaviour of AArch64 NE.
5266 //
5267 // This differs from x86 where the outputs of FP compares use a
5268 // special FP flags registers and where compares based on this
5269 // register are distinguished into ordered inequalities (cmpOpUCF) and
5270 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests
5271 // to explicitly handle the unordered case in branches. x86 also has
5272 // to include extra CMoveX rules to accept a cmpOpUCF input.
5273
5274 operand rFlagsReg()
5275 %{
5276 constraint(ALLOC_IN_RC(int_flags));
5277 match(RegFlags);
5278
5279 op_cost(0);
5280 format %{ "RFLAGS" %}
5281 interface(REG_INTER);
5282 %}
5283
5284 // Flags register, used as output of unsigned compare instructions
5285 operand rFlagsRegU()
5286 %{
5287 constraint(ALLOC_IN_RC(int_flags));
5288 match(RegFlags);
5289
5290 op_cost(0);
5291 format %{ "RFLAGSU" %}
5292 interface(REG_INTER);
5293 %}
5294
5295 // Special Registers
5296
5297 // Method Register
5298 operand inline_cache_RegP(iRegP reg)
5299 %{
5300 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg
5301 match(reg);
5302 match(iRegPNoSp);
5303 op_cost(0);
5304 format %{ %}
5305 interface(REG_INTER);
5306 %}
5307
5308 // Thread Register
5309 operand thread_RegP(iRegP reg)
5310 %{
5311 constraint(ALLOC_IN_RC(thread_reg)); // link_reg
5312 match(reg);
5313 op_cost(0);
5314 format %{ %}
5315 interface(REG_INTER);
5316 %}
5317
5318 //----------Memory Operands----------------------------------------------------
5319
5320 operand indirect(iRegP reg)
5321 %{
5322 constraint(ALLOC_IN_RC(ptr_reg));
5323 match(reg);
5324 op_cost(0);
5325 format %{ "[$reg]" %}
5326 interface(MEMORY_INTER) %{
5327 base($reg);
5328 index(0xffffffff);
5329 scale(0x0);
5330 disp(0x0);
5331 %}
5332 %}
5333
5334 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale)
5335 %{
5336 constraint(ALLOC_IN_RC(ptr_reg));
5337 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5338 match(AddP reg (LShiftL (ConvI2L ireg) scale));
5339 op_cost(0);
5340 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %}
5341 interface(MEMORY_INTER) %{
5342 base($reg);
5343 index($ireg);
5344 scale($scale);
5345 disp(0x0);
5346 %}
5347 %}
5348
5349 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale)
5350 %{
5351 constraint(ALLOC_IN_RC(ptr_reg));
5352 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5353 match(AddP reg (LShiftL lreg scale));
5354 op_cost(0);
5355 format %{ "$reg, $lreg lsl($scale)" %}
5356 interface(MEMORY_INTER) %{
5357 base($reg);
5358 index($lreg);
5359 scale($scale);
5360 disp(0x0);
5361 %}
5362 %}
5363
5364 operand indIndexI2L(iRegP reg, iRegI ireg)
5365 %{
5366 constraint(ALLOC_IN_RC(ptr_reg));
5367 match(AddP reg (ConvI2L ireg));
5368 op_cost(0);
5369 format %{ "$reg, $ireg, 0, I2L" %}
5370 interface(MEMORY_INTER) %{
5371 base($reg);
5372 index($ireg);
5373 scale(0x0);
5374 disp(0x0);
5375 %}
5376 %}
5377
5378 operand indIndex(iRegP reg, iRegL lreg)
5379 %{
5380 constraint(ALLOC_IN_RC(ptr_reg));
5381 match(AddP reg lreg);
5382 op_cost(0);
5383 format %{ "$reg, $lreg" %}
5384 interface(MEMORY_INTER) %{
5385 base($reg);
5386 index($lreg);
5387 scale(0x0);
5388 disp(0x0);
5389 %}
5390 %}
5391
5392 operand indOffI1(iRegP reg, immIOffset1 off)
5393 %{
5394 constraint(ALLOC_IN_RC(ptr_reg));
5395 match(AddP reg off);
5396 op_cost(0);
5397 format %{ "[$reg, $off]" %}
5398 interface(MEMORY_INTER) %{
5399 base($reg);
5400 index(0xffffffff);
5401 scale(0x0);
5402 disp($off);
5403 %}
5404 %}
5405
5406 operand indOffI2(iRegP reg, immIOffset2 off)
5407 %{
5408 constraint(ALLOC_IN_RC(ptr_reg));
5409 match(AddP reg off);
5410 op_cost(0);
5411 format %{ "[$reg, $off]" %}
5412 interface(MEMORY_INTER) %{
5413 base($reg);
5414 index(0xffffffff);
5415 scale(0x0);
5416 disp($off);
5417 %}
5418 %}
5419
5420 operand indOffI4(iRegP reg, immIOffset4 off)
5421 %{
5422 constraint(ALLOC_IN_RC(ptr_reg));
5423 match(AddP reg off);
5424 op_cost(0);
5425 format %{ "[$reg, $off]" %}
5426 interface(MEMORY_INTER) %{
5427 base($reg);
5428 index(0xffffffff);
5429 scale(0x0);
5430 disp($off);
5431 %}
5432 %}
5433
5434 operand indOffI8(iRegP reg, immIOffset8 off)
5435 %{
5436 constraint(ALLOC_IN_RC(ptr_reg));
5437 match(AddP reg off);
5438 op_cost(0);
5439 format %{ "[$reg, $off]" %}
5440 interface(MEMORY_INTER) %{
5441 base($reg);
5442 index(0xffffffff);
5443 scale(0x0);
5444 disp($off);
5445 %}
5446 %}
5447
5448 operand indOffI16(iRegP reg, immIOffset16 off)
5449 %{
5450 constraint(ALLOC_IN_RC(ptr_reg));
5451 match(AddP reg off);
5452 op_cost(0);
5453 format %{ "[$reg, $off]" %}
5454 interface(MEMORY_INTER) %{
5455 base($reg);
5456 index(0xffffffff);
5457 scale(0x0);
5458 disp($off);
5459 %}
5460 %}
5461
5462 operand indOffL1(iRegP reg, immLoffset1 off)
5463 %{
5464 constraint(ALLOC_IN_RC(ptr_reg));
5465 match(AddP reg off);
5466 op_cost(0);
5467 format %{ "[$reg, $off]" %}
5468 interface(MEMORY_INTER) %{
5469 base($reg);
5470 index(0xffffffff);
5471 scale(0x0);
5472 disp($off);
5473 %}
5474 %}
5475
5476 operand indOffL2(iRegP reg, immLoffset2 off)
5477 %{
5478 constraint(ALLOC_IN_RC(ptr_reg));
5479 match(AddP reg off);
5480 op_cost(0);
5481 format %{ "[$reg, $off]" %}
5482 interface(MEMORY_INTER) %{
5483 base($reg);
5484 index(0xffffffff);
5485 scale(0x0);
5486 disp($off);
5487 %}
5488 %}
5489
5490 operand indOffL4(iRegP reg, immLoffset4 off)
5491 %{
5492 constraint(ALLOC_IN_RC(ptr_reg));
5493 match(AddP reg off);
5494 op_cost(0);
5495 format %{ "[$reg, $off]" %}
5496 interface(MEMORY_INTER) %{
5497 base($reg);
5498 index(0xffffffff);
5499 scale(0x0);
5500 disp($off);
5501 %}
5502 %}
5503
5504 operand indOffL8(iRegP reg, immLoffset8 off)
5505 %{
5506 constraint(ALLOC_IN_RC(ptr_reg));
5507 match(AddP reg off);
5508 op_cost(0);
5509 format %{ "[$reg, $off]" %}
5510 interface(MEMORY_INTER) %{
5511 base($reg);
5512 index(0xffffffff);
5513 scale(0x0);
5514 disp($off);
5515 %}
5516 %}
5517
5518 operand indOffL16(iRegP reg, immLoffset16 off)
5519 %{
5520 constraint(ALLOC_IN_RC(ptr_reg));
5521 match(AddP reg off);
5522 op_cost(0);
5523 format %{ "[$reg, $off]" %}
5524 interface(MEMORY_INTER) %{
5525 base($reg);
5526 index(0xffffffff);
5527 scale(0x0);
5528 disp($off);
5529 %}
5530 %}
5531
5532 operand indirectX2P(iRegL reg)
5533 %{
5534 constraint(ALLOC_IN_RC(ptr_reg));
5535 match(CastX2P reg);
5536 op_cost(0);
5537 format %{ "[$reg]\t# long -> ptr" %}
5538 interface(MEMORY_INTER) %{
5539 base($reg);
5540 index(0xffffffff);
5541 scale(0x0);
5542 disp(0x0);
5543 %}
5544 %}
5545
5546 operand indOffX2P(iRegL reg, immLOffset off)
5547 %{
5548 constraint(ALLOC_IN_RC(ptr_reg));
5549 match(AddP (CastX2P reg) off);
5550 op_cost(0);
5551 format %{ "[$reg, $off]\t# long -> ptr" %}
5552 interface(MEMORY_INTER) %{
5553 base($reg);
5554 index(0xffffffff);
5555 scale(0x0);
5556 disp($off);
5557 %}
5558 %}
5559
5560 operand indirectN(iRegN reg)
5561 %{
5562 predicate(CompressedOops::shift() == 0);
5563 constraint(ALLOC_IN_RC(ptr_reg));
5564 match(DecodeN reg);
5565 op_cost(0);
5566 format %{ "[$reg]\t# narrow" %}
5567 interface(MEMORY_INTER) %{
5568 base($reg);
5569 index(0xffffffff);
5570 scale(0x0);
5571 disp(0x0);
5572 %}
5573 %}
5574
5575 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale)
5576 %{
5577 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5578 constraint(ALLOC_IN_RC(ptr_reg));
5579 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale));
5580 op_cost(0);
5581 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %}
5582 interface(MEMORY_INTER) %{
5583 base($reg);
5584 index($ireg);
5585 scale($scale);
5586 disp(0x0);
5587 %}
5588 %}
5589
5590 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale)
5591 %{
5592 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5593 constraint(ALLOC_IN_RC(ptr_reg));
5594 match(AddP (DecodeN reg) (LShiftL lreg scale));
5595 op_cost(0);
5596 format %{ "$reg, $lreg lsl($scale)\t# narrow" %}
5597 interface(MEMORY_INTER) %{
5598 base($reg);
5599 index($lreg);
5600 scale($scale);
5601 disp(0x0);
5602 %}
5603 %}
5604
5605 operand indIndexI2LN(iRegN reg, iRegI ireg)
5606 %{
5607 predicate(CompressedOops::shift() == 0);
5608 constraint(ALLOC_IN_RC(ptr_reg));
5609 match(AddP (DecodeN reg) (ConvI2L ireg));
5610 op_cost(0);
5611 format %{ "$reg, $ireg, 0, I2L\t# narrow" %}
5612 interface(MEMORY_INTER) %{
5613 base($reg);
5614 index($ireg);
5615 scale(0x0);
5616 disp(0x0);
5617 %}
5618 %}
5619
5620 operand indIndexN(iRegN reg, iRegL lreg)
5621 %{
5622 predicate(CompressedOops::shift() == 0);
5623 constraint(ALLOC_IN_RC(ptr_reg));
5624 match(AddP (DecodeN reg) lreg);
5625 op_cost(0);
5626 format %{ "$reg, $lreg\t# narrow" %}
5627 interface(MEMORY_INTER) %{
5628 base($reg);
5629 index($lreg);
5630 scale(0x0);
5631 disp(0x0);
5632 %}
5633 %}
5634
5635 operand indOffIN(iRegN reg, immIOffset off)
5636 %{
5637 predicate(CompressedOops::shift() == 0);
5638 constraint(ALLOC_IN_RC(ptr_reg));
5639 match(AddP (DecodeN reg) off);
5640 op_cost(0);
5641 format %{ "[$reg, $off]\t# narrow" %}
5642 interface(MEMORY_INTER) %{
5643 base($reg);
5644 index(0xffffffff);
5645 scale(0x0);
5646 disp($off);
5647 %}
5648 %}
5649
5650 operand indOffLN(iRegN reg, immLOffset off)
5651 %{
5652 predicate(CompressedOops::shift() == 0);
5653 constraint(ALLOC_IN_RC(ptr_reg));
5654 match(AddP (DecodeN reg) off);
5655 op_cost(0);
5656 format %{ "[$reg, $off]\t# narrow" %}
5657 interface(MEMORY_INTER) %{
5658 base($reg);
5659 index(0xffffffff);
5660 scale(0x0);
5661 disp($off);
5662 %}
5663 %}
5664
5665
5666 //----------Special Memory Operands--------------------------------------------
5667 // Stack Slot Operand - This operand is used for loading and storing temporary
5668 // values on the stack where a match requires a value to
5669 // flow through memory.
5670 operand stackSlotP(sRegP reg)
5671 %{
5672 constraint(ALLOC_IN_RC(stack_slots));
5673 op_cost(100);
5674 // No match rule because this operand is only generated in matching
5675 // match(RegP);
5676 format %{ "[$reg]" %}
5677 interface(MEMORY_INTER) %{
5678 base(0x1e); // RSP
5679 index(0x0); // No Index
5680 scale(0x0); // No Scale
5681 disp($reg); // Stack Offset
5682 %}
5683 %}
5684
5685 operand stackSlotI(sRegI reg)
5686 %{
5687 constraint(ALLOC_IN_RC(stack_slots));
5688 // No match rule because this operand is only generated in matching
5689 // match(RegI);
5690 format %{ "[$reg]" %}
5691 interface(MEMORY_INTER) %{
5692 base(0x1e); // RSP
5693 index(0x0); // No Index
5694 scale(0x0); // No Scale
5695 disp($reg); // Stack Offset
5696 %}
5697 %}
5698
5699 operand stackSlotF(sRegF reg)
5700 %{
5701 constraint(ALLOC_IN_RC(stack_slots));
5702 // No match rule because this operand is only generated in matching
5703 // match(RegF);
5704 format %{ "[$reg]" %}
5705 interface(MEMORY_INTER) %{
5706 base(0x1e); // RSP
5707 index(0x0); // No Index
5708 scale(0x0); // No Scale
5709 disp($reg); // Stack Offset
5710 %}
5711 %}
5712
5713 operand stackSlotD(sRegD reg)
5714 %{
5715 constraint(ALLOC_IN_RC(stack_slots));
5716 // No match rule because this operand is only generated in matching
5717 // match(RegD);
5718 format %{ "[$reg]" %}
5719 interface(MEMORY_INTER) %{
5720 base(0x1e); // RSP
5721 index(0x0); // No Index
5722 scale(0x0); // No Scale
5723 disp($reg); // Stack Offset
5724 %}
5725 %}
5726
5727 operand stackSlotL(sRegL reg)
5728 %{
5729 constraint(ALLOC_IN_RC(stack_slots));
5730 // No match rule because this operand is only generated in matching
5731 // match(RegL);
5732 format %{ "[$reg]" %}
5733 interface(MEMORY_INTER) %{
5734 base(0x1e); // RSP
5735 index(0x0); // No Index
5736 scale(0x0); // No Scale
5737 disp($reg); // Stack Offset
5738 %}
5739 %}
5740
5741 // Operands for expressing Control Flow
5742 // NOTE: Label is a predefined operand which should not be redefined in
5743 // the AD file. It is generically handled within the ADLC.
5744
5745 //----------Conditional Branch Operands----------------------------------------
5746 // Comparison Op - This is the operation of the comparison, and is limited to
5747 // the following set of codes:
5748 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5749 //
5750 // Other attributes of the comparison, such as unsignedness, are specified
5751 // by the comparison instruction that sets a condition code flags register.
5752 // That result is represented by a flags operand whose subtype is appropriate
5753 // to the unsignedness (etc.) of the comparison.
5754 //
5755 // Later, the instruction which matches both the Comparison Op (a Bool) and
5756 // the flags (produced by the Cmp) specifies the coding of the comparison op
5757 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5758
5759 // used for signed integral comparisons and fp comparisons
5760
5761 operand cmpOp()
5762 %{
5763 match(Bool);
5764
5765 format %{ "" %}
5766 interface(COND_INTER) %{
5767 equal(0x0, "eq");
5768 not_equal(0x1, "ne");
5769 less(0xb, "lt");
5770 greater_equal(0xa, "ge");
5771 less_equal(0xd, "le");
5772 greater(0xc, "gt");
5773 overflow(0x6, "vs");
5774 no_overflow(0x7, "vc");
5775 %}
5776 %}
5777
5778 // used for unsigned integral comparisons
5779
5780 operand cmpOpU()
5781 %{
5782 match(Bool);
5783
5784 format %{ "" %}
5785 interface(COND_INTER) %{
5786 equal(0x0, "eq");
5787 not_equal(0x1, "ne");
5788 less(0x3, "lo");
5789 greater_equal(0x2, "hs");
5790 less_equal(0x9, "ls");
5791 greater(0x8, "hi");
5792 overflow(0x6, "vs");
5793 no_overflow(0x7, "vc");
5794 %}
5795 %}
5796
5797 // used for certain integral comparisons which can be
5798 // converted to cbxx or tbxx instructions
5799
5800 operand cmpOpEqNe()
5801 %{
5802 match(Bool);
5803 op_cost(0);
5804 predicate(n->as_Bool()->_test._test == BoolTest::ne
5805 || n->as_Bool()->_test._test == BoolTest::eq);
5806
5807 format %{ "" %}
5808 interface(COND_INTER) %{
5809 equal(0x0, "eq");
5810 not_equal(0x1, "ne");
5811 less(0xb, "lt");
5812 greater_equal(0xa, "ge");
5813 less_equal(0xd, "le");
5814 greater(0xc, "gt");
5815 overflow(0x6, "vs");
5816 no_overflow(0x7, "vc");
5817 %}
5818 %}
5819
5820 // used for certain integral comparisons which can be
5821 // converted to cbxx or tbxx instructions
5822
5823 operand cmpOpLtGe()
5824 %{
5825 match(Bool);
5826 op_cost(0);
5827
5828 predicate(n->as_Bool()->_test._test == BoolTest::lt
5829 || n->as_Bool()->_test._test == BoolTest::ge);
5830
5831 format %{ "" %}
5832 interface(COND_INTER) %{
5833 equal(0x0, "eq");
5834 not_equal(0x1, "ne");
5835 less(0xb, "lt");
5836 greater_equal(0xa, "ge");
5837 less_equal(0xd, "le");
5838 greater(0xc, "gt");
5839 overflow(0x6, "vs");
5840 no_overflow(0x7, "vc");
5841 %}
5842 %}
5843
5844 // used for certain unsigned integral comparisons which can be
5845 // converted to cbxx or tbxx instructions
5846
5847 operand cmpOpUEqNeLeGt()
5848 %{
5849 match(Bool);
5850 op_cost(0);
5851
5852 predicate(n->as_Bool()->_test._test == BoolTest::eq ||
5853 n->as_Bool()->_test._test == BoolTest::ne ||
5854 n->as_Bool()->_test._test == BoolTest::le ||
5855 n->as_Bool()->_test._test == BoolTest::gt);
5856
5857 format %{ "" %}
5858 interface(COND_INTER) %{
5859 equal(0x0, "eq");
5860 not_equal(0x1, "ne");
5861 less(0x3, "lo");
5862 greater_equal(0x2, "hs");
5863 less_equal(0x9, "ls");
5864 greater(0x8, "hi");
5865 overflow(0x6, "vs");
5866 no_overflow(0x7, "vc");
5867 %}
5868 %}
5869
5870 // Special operand allowing long args to int ops to be truncated for free
5871
5872 operand iRegL2I(iRegL reg) %{
5873
5874 op_cost(0);
5875
5876 match(ConvL2I reg);
5877
5878 format %{ "l2i($reg)" %}
5879
5880 interface(REG_INTER)
5881 %}
5882
5883 operand iRegL2P(iRegL reg) %{
5884
5885 op_cost(0);
5886
5887 match(CastX2P reg);
5888
5889 format %{ "l2p($reg)" %}
5890
5891 interface(REG_INTER)
5892 %}
5893
5894 opclass vmem2(indirect, indIndex, indOffI2, indOffL2);
5895 opclass vmem4(indirect, indIndex, indOffI4, indOffL4);
5896 opclass vmem8(indirect, indIndex, indOffI8, indOffL8);
5897 opclass vmem16(indirect, indIndex, indOffI16, indOffL16);
5898
5899 //----------OPERAND CLASSES----------------------------------------------------
5900 // Operand Classes are groups of operands that are used as to simplify
5901 // instruction definitions by not requiring the AD writer to specify
5902 // separate instructions for every form of operand when the
5903 // instruction accepts multiple operand types with the same basic
5904 // encoding and format. The classic case of this is memory operands.
5905
5906 // memory is used to define read/write location for load/store
5907 // instruction defs. we can turn a memory op into an Address
5908
5909 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5910 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5911
5912 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5913 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5914
5915 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5916 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5917
5918 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5919 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5920
5921 // All of the memory operands. For the pipeline description.
5922 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5923 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5924 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5925
5926
5927 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5928 // operations. it allows the src to be either an iRegI or a (ConvL2I
5929 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5930 // can be elided because the 32-bit instruction will just employ the
5931 // lower 32 bits anyway.
5932 //
5933 // n.b. this does not elide all L2I conversions. if the truncated
5934 // value is consumed by more than one operation then the ConvL2I
5935 // cannot be bundled into the consuming nodes so an l2i gets planted
5936 // (actually a movw $dst $src) and the downstream instructions consume
5937 // the result of the l2i as an iRegI input. That's a shame since the
5938 // movw is actually redundant but its not too costly.
5939
5940 opclass iRegIorL2I(iRegI, iRegL2I);
5941 opclass iRegPorL2P(iRegP, iRegL2P);
5942
5943 //----------PIPELINE-----------------------------------------------------------
5944 // Rules which define the behavior of the target architectures pipeline.
5945
5946 // For specific pipelines, eg A53, define the stages of that pipeline
5947 //pipe_desc(ISS, EX1, EX2, WR);
5948 #define ISS S0
5949 #define EX1 S1
5950 #define EX2 S2
5951 #define WR S3
5952
5953 // Integer ALU reg operation
5954 pipeline %{
5955
5956 attributes %{
5957 // ARM instructions are of fixed length
5958 fixed_size_instructions; // Fixed size instructions TODO does
5959 max_instructions_per_bundle = 4; // A53 = 2, A57 = 4
5960 // ARM instructions come in 32-bit word units
5961 instruction_unit_size = 4; // An instruction is 4 bytes long
5962 instruction_fetch_unit_size = 64; // The processor fetches one line
5963 instruction_fetch_units = 1; // of 64 bytes
5964 %}
5965
5966 // We don't use an actual pipeline model so don't care about resources
5967 // or description. we do use pipeline classes to introduce fixed
5968 // latencies
5969
5970 //----------RESOURCES----------------------------------------------------------
5971 // Resources are the functional units available to the machine
5972
5973 resources( INS0, INS1, INS01 = INS0 | INS1,
5974 ALU0, ALU1, ALU = ALU0 | ALU1,
5975 MAC,
5976 DIV,
5977 BRANCH,
5978 LDST,
5979 NEON_FP);
5980
5981 //----------PIPELINE DESCRIPTION-----------------------------------------------
5982 // Pipeline Description specifies the stages in the machine's pipeline
5983
5984 // Define the pipeline as a generic 6 stage pipeline
5985 pipe_desc(S0, S1, S2, S3, S4, S5);
5986
5987 //----------PIPELINE CLASSES---------------------------------------------------
5988 // Pipeline Classes describe the stages in which input and output are
5989 // referenced by the hardware pipeline.
5990
5991 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2)
5992 %{
5993 single_instruction;
5994 src1 : S1(read);
5995 src2 : S2(read);
5996 dst : S5(write);
5997 INS01 : ISS;
5998 NEON_FP : S5;
5999 %}
6000
6001 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2)
6002 %{
6003 single_instruction;
6004 src1 : S1(read);
6005 src2 : S2(read);
6006 dst : S5(write);
6007 INS01 : ISS;
6008 NEON_FP : S5;
6009 %}
6010
6011 pipe_class fp_uop_s(vRegF dst, vRegF src)
6012 %{
6013 single_instruction;
6014 src : S1(read);
6015 dst : S5(write);
6016 INS01 : ISS;
6017 NEON_FP : S5;
6018 %}
6019
6020 pipe_class fp_uop_d(vRegD dst, vRegD src)
6021 %{
6022 single_instruction;
6023 src : S1(read);
6024 dst : S5(write);
6025 INS01 : ISS;
6026 NEON_FP : S5;
6027 %}
6028
6029 pipe_class fp_d2f(vRegF dst, vRegD src)
6030 %{
6031 single_instruction;
6032 src : S1(read);
6033 dst : S5(write);
6034 INS01 : ISS;
6035 NEON_FP : S5;
6036 %}
6037
6038 pipe_class fp_f2d(vRegD dst, vRegF src)
6039 %{
6040 single_instruction;
6041 src : S1(read);
6042 dst : S5(write);
6043 INS01 : ISS;
6044 NEON_FP : S5;
6045 %}
6046
6047 pipe_class fp_f2i(iRegINoSp dst, vRegF src)
6048 %{
6049 single_instruction;
6050 src : S1(read);
6051 dst : S5(write);
6052 INS01 : ISS;
6053 NEON_FP : S5;
6054 %}
6055
6056 pipe_class fp_f2l(iRegLNoSp dst, vRegF src)
6057 %{
6058 single_instruction;
6059 src : S1(read);
6060 dst : S5(write);
6061 INS01 : ISS;
6062 NEON_FP : S5;
6063 %}
6064
6065 pipe_class fp_i2f(vRegF dst, iRegIorL2I src)
6066 %{
6067 single_instruction;
6068 src : S1(read);
6069 dst : S5(write);
6070 INS01 : ISS;
6071 NEON_FP : S5;
6072 %}
6073
6074 pipe_class fp_l2f(vRegF dst, iRegL src)
6075 %{
6076 single_instruction;
6077 src : S1(read);
6078 dst : S5(write);
6079 INS01 : ISS;
6080 NEON_FP : S5;
6081 %}
6082
6083 pipe_class fp_d2i(iRegINoSp dst, vRegD src)
6084 %{
6085 single_instruction;
6086 src : S1(read);
6087 dst : S5(write);
6088 INS01 : ISS;
6089 NEON_FP : S5;
6090 %}
6091
6092 pipe_class fp_d2l(iRegLNoSp dst, vRegD src)
6093 %{
6094 single_instruction;
6095 src : S1(read);
6096 dst : S5(write);
6097 INS01 : ISS;
6098 NEON_FP : S5;
6099 %}
6100
6101 pipe_class fp_i2d(vRegD dst, iRegIorL2I src)
6102 %{
6103 single_instruction;
6104 src : S1(read);
6105 dst : S5(write);
6106 INS01 : ISS;
6107 NEON_FP : S5;
6108 %}
6109
6110 pipe_class fp_l2d(vRegD dst, iRegIorL2I src)
6111 %{
6112 single_instruction;
6113 src : S1(read);
6114 dst : S5(write);
6115 INS01 : ISS;
6116 NEON_FP : S5;
6117 %}
6118
6119 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2)
6120 %{
6121 single_instruction;
6122 src1 : S1(read);
6123 src2 : S2(read);
6124 dst : S5(write);
6125 INS0 : ISS;
6126 NEON_FP : S5;
6127 %}
6128
6129 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2)
6130 %{
6131 single_instruction;
6132 src1 : S1(read);
6133 src2 : S2(read);
6134 dst : S5(write);
6135 INS0 : ISS;
6136 NEON_FP : S5;
6137 %}
6138
6139 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr)
6140 %{
6141 single_instruction;
6142 cr : S1(read);
6143 src1 : S1(read);
6144 src2 : S1(read);
6145 dst : S3(write);
6146 INS01 : ISS;
6147 NEON_FP : S3;
6148 %}
6149
6150 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr)
6151 %{
6152 single_instruction;
6153 cr : S1(read);
6154 src1 : S1(read);
6155 src2 : S1(read);
6156 dst : S3(write);
6157 INS01 : ISS;
6158 NEON_FP : S3;
6159 %}
6160
6161 pipe_class fp_imm_s(vRegF dst)
6162 %{
6163 single_instruction;
6164 dst : S3(write);
6165 INS01 : ISS;
6166 NEON_FP : S3;
6167 %}
6168
6169 pipe_class fp_imm_d(vRegD dst)
6170 %{
6171 single_instruction;
6172 dst : S3(write);
6173 INS01 : ISS;
6174 NEON_FP : S3;
6175 %}
6176
6177 pipe_class fp_load_constant_s(vRegF dst)
6178 %{
6179 single_instruction;
6180 dst : S4(write);
6181 INS01 : ISS;
6182 NEON_FP : S4;
6183 %}
6184
6185 pipe_class fp_load_constant_d(vRegD dst)
6186 %{
6187 single_instruction;
6188 dst : S4(write);
6189 INS01 : ISS;
6190 NEON_FP : S4;
6191 %}
6192
6193 //------- Integer ALU operations --------------------------
6194
6195 // Integer ALU reg-reg operation
6196 // Operands needed in EX1, result generated in EX2
6197 // Eg. ADD x0, x1, x2
6198 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6199 %{
6200 single_instruction;
6201 dst : EX2(write);
6202 src1 : EX1(read);
6203 src2 : EX1(read);
6204 INS01 : ISS; // Dual issue as instruction 0 or 1
6205 ALU : EX2;
6206 %}
6207
6208 // Integer ALU reg-reg operation with constant shift
6209 // Shifted register must be available in LATE_ISS instead of EX1
6210 // Eg. ADD x0, x1, x2, LSL #2
6211 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift)
6212 %{
6213 single_instruction;
6214 dst : EX2(write);
6215 src1 : EX1(read);
6216 src2 : ISS(read);
6217 INS01 : ISS;
6218 ALU : EX2;
6219 %}
6220
6221 // Integer ALU reg operation with constant shift
6222 // Eg. LSL x0, x1, #shift
6223 pipe_class ialu_reg_shift(iRegI dst, iRegI src1)
6224 %{
6225 single_instruction;
6226 dst : EX2(write);
6227 src1 : ISS(read);
6228 INS01 : ISS;
6229 ALU : EX2;
6230 %}
6231
6232 // Integer ALU reg-reg operation with variable shift
6233 // Both operands must be available in LATE_ISS instead of EX1
6234 // Result is available in EX1 instead of EX2
6235 // Eg. LSLV x0, x1, x2
6236 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2)
6237 %{
6238 single_instruction;
6239 dst : EX1(write);
6240 src1 : ISS(read);
6241 src2 : ISS(read);
6242 INS01 : ISS;
6243 ALU : EX1;
6244 %}
6245
6246 // Integer ALU reg-reg operation with extract
6247 // As for _vshift above, but result generated in EX2
6248 // Eg. EXTR x0, x1, x2, #N
6249 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2)
6250 %{
6251 single_instruction;
6252 dst : EX2(write);
6253 src1 : ISS(read);
6254 src2 : ISS(read);
6255 INS1 : ISS; // Can only dual issue as Instruction 1
6256 ALU : EX1;
6257 %}
6258
6259 // Integer ALU reg operation
6260 // Eg. NEG x0, x1
6261 pipe_class ialu_reg(iRegI dst, iRegI src)
6262 %{
6263 single_instruction;
6264 dst : EX2(write);
6265 src : EX1(read);
6266 INS01 : ISS;
6267 ALU : EX2;
6268 %}
6269
6270 // Integer ALU reg mmediate operation
6271 // Eg. ADD x0, x1, #N
6272 pipe_class ialu_reg_imm(iRegI dst, iRegI src1)
6273 %{
6274 single_instruction;
6275 dst : EX2(write);
6276 src1 : EX1(read);
6277 INS01 : ISS;
6278 ALU : EX2;
6279 %}
6280
6281 // Integer ALU immediate operation (no source operands)
6282 // Eg. MOV x0, #N
6283 pipe_class ialu_imm(iRegI dst)
6284 %{
6285 single_instruction;
6286 dst : EX1(write);
6287 INS01 : ISS;
6288 ALU : EX1;
6289 %}
6290
6291 //------- Compare operation -------------------------------
6292
6293 // Compare reg-reg
6294 // Eg. CMP x0, x1
6295 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
6296 %{
6297 single_instruction;
6298 // fixed_latency(16);
6299 cr : EX2(write);
6300 op1 : EX1(read);
6301 op2 : EX1(read);
6302 INS01 : ISS;
6303 ALU : EX2;
6304 %}
6305
6306 // Compare reg-reg
6307 // Eg. CMP x0, #N
6308 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1)
6309 %{
6310 single_instruction;
6311 // fixed_latency(16);
6312 cr : EX2(write);
6313 op1 : EX1(read);
6314 INS01 : ISS;
6315 ALU : EX2;
6316 %}
6317
6318 //------- Conditional instructions ------------------------
6319
6320 // Conditional no operands
6321 // Eg. CSINC x0, zr, zr, <cond>
6322 pipe_class icond_none(iRegI dst, rFlagsReg cr)
6323 %{
6324 single_instruction;
6325 cr : EX1(read);
6326 dst : EX2(write);
6327 INS01 : ISS;
6328 ALU : EX2;
6329 %}
6330
6331 // Conditional 2 operand
6332 // EG. CSEL X0, X1, X2, <cond>
6333 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr)
6334 %{
6335 single_instruction;
6336 cr : EX1(read);
6337 src1 : EX1(read);
6338 src2 : EX1(read);
6339 dst : EX2(write);
6340 INS01 : ISS;
6341 ALU : EX2;
6342 %}
6343
6344 // Conditional 2 operand
6345 // EG. CSEL X0, X1, X2, <cond>
6346 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr)
6347 %{
6348 single_instruction;
6349 cr : EX1(read);
6350 src : EX1(read);
6351 dst : EX2(write);
6352 INS01 : ISS;
6353 ALU : EX2;
6354 %}
6355
6356 //------- Multiply pipeline operations --------------------
6357
6358 // Multiply reg-reg
6359 // Eg. MUL w0, w1, w2
6360 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6361 %{
6362 single_instruction;
6363 dst : WR(write);
6364 src1 : ISS(read);
6365 src2 : ISS(read);
6366 INS01 : ISS;
6367 MAC : WR;
6368 %}
6369
6370 // Multiply accumulate
6371 // Eg. MADD w0, w1, w2, w3
6372 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6373 %{
6374 single_instruction;
6375 dst : WR(write);
6376 src1 : ISS(read);
6377 src2 : ISS(read);
6378 src3 : ISS(read);
6379 INS01 : ISS;
6380 MAC : WR;
6381 %}
6382
6383 // Eg. MUL w0, w1, w2
6384 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6385 %{
6386 single_instruction;
6387 fixed_latency(3); // Maximum latency for 64 bit mul
6388 dst : WR(write);
6389 src1 : ISS(read);
6390 src2 : ISS(read);
6391 INS01 : ISS;
6392 MAC : WR;
6393 %}
6394
6395 // Multiply accumulate
6396 // Eg. MADD w0, w1, w2, w3
6397 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6398 %{
6399 single_instruction;
6400 fixed_latency(3); // Maximum latency for 64 bit mul
6401 dst : WR(write);
6402 src1 : ISS(read);
6403 src2 : ISS(read);
6404 src3 : ISS(read);
6405 INS01 : ISS;
6406 MAC : WR;
6407 %}
6408
6409 //------- Divide pipeline operations --------------------
6410
6411 // Eg. SDIV w0, w1, w2
6412 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6413 %{
6414 single_instruction;
6415 fixed_latency(8); // Maximum latency for 32 bit divide
6416 dst : WR(write);
6417 src1 : ISS(read);
6418 src2 : ISS(read);
6419 INS0 : ISS; // Can only dual issue as instruction 0
6420 DIV : WR;
6421 %}
6422
6423 // Eg. SDIV x0, x1, x2
6424 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6425 %{
6426 single_instruction;
6427 fixed_latency(16); // Maximum latency for 64 bit divide
6428 dst : WR(write);
6429 src1 : ISS(read);
6430 src2 : ISS(read);
6431 INS0 : ISS; // Can only dual issue as instruction 0
6432 DIV : WR;
6433 %}
6434
6435 //------- Load pipeline operations ------------------------
6436
6437 // Load - prefetch
6438 // Eg. PFRM <mem>
6439 pipe_class iload_prefetch(memory mem)
6440 %{
6441 single_instruction;
6442 mem : ISS(read);
6443 INS01 : ISS;
6444 LDST : WR;
6445 %}
6446
6447 // Load - reg, mem
6448 // Eg. LDR x0, <mem>
6449 pipe_class iload_reg_mem(iRegI dst, memory mem)
6450 %{
6451 single_instruction;
6452 dst : WR(write);
6453 mem : ISS(read);
6454 INS01 : ISS;
6455 LDST : WR;
6456 %}
6457
6458 // Load - reg, reg
6459 // Eg. LDR x0, [sp, x1]
6460 pipe_class iload_reg_reg(iRegI dst, iRegI src)
6461 %{
6462 single_instruction;
6463 dst : WR(write);
6464 src : ISS(read);
6465 INS01 : ISS;
6466 LDST : WR;
6467 %}
6468
6469 //------- Store pipeline operations -----------------------
6470
6471 // Store - zr, mem
6472 // Eg. STR zr, <mem>
6473 pipe_class istore_mem(memory mem)
6474 %{
6475 single_instruction;
6476 mem : ISS(read);
6477 INS01 : ISS;
6478 LDST : WR;
6479 %}
6480
6481 // Store - reg, mem
6482 // Eg. STR x0, <mem>
6483 pipe_class istore_reg_mem(iRegI src, memory mem)
6484 %{
6485 single_instruction;
6486 mem : ISS(read);
6487 src : EX2(read);
6488 INS01 : ISS;
6489 LDST : WR;
6490 %}
6491
6492 // Store - reg, reg
6493 // Eg. STR x0, [sp, x1]
6494 pipe_class istore_reg_reg(iRegI dst, iRegI src)
6495 %{
6496 single_instruction;
6497 dst : ISS(read);
6498 src : EX2(read);
6499 INS01 : ISS;
6500 LDST : WR;
6501 %}
6502
6503 //------- Store pipeline operations -----------------------
6504
6505 // Branch
6506 pipe_class pipe_branch()
6507 %{
6508 single_instruction;
6509 INS01 : ISS;
6510 BRANCH : EX1;
6511 %}
6512
6513 // Conditional branch
6514 pipe_class pipe_branch_cond(rFlagsReg cr)
6515 %{
6516 single_instruction;
6517 cr : EX1(read);
6518 INS01 : ISS;
6519 BRANCH : EX1;
6520 %}
6521
6522 // Compare & Branch
6523 // EG. CBZ/CBNZ
6524 pipe_class pipe_cmp_branch(iRegI op1)
6525 %{
6526 single_instruction;
6527 op1 : EX1(read);
6528 INS01 : ISS;
6529 BRANCH : EX1;
6530 %}
6531
6532 //------- Synchronisation operations ----------------------
6533
6534 // Any operation requiring serialization.
6535 // EG. DMB/Atomic Ops/Load Acquire/Str Release
6536 pipe_class pipe_serial()
6537 %{
6538 single_instruction;
6539 force_serialization;
6540 fixed_latency(16);
6541 INS01 : ISS(2); // Cannot dual issue with any other instruction
6542 LDST : WR;
6543 %}
6544
6545 // Generic big/slow expanded idiom - also serialized
6546 pipe_class pipe_slow()
6547 %{
6548 instruction_count(10);
6549 multiple_bundles;
6550 force_serialization;
6551 fixed_latency(16);
6552 INS01 : ISS(2); // Cannot dual issue with any other instruction
6553 LDST : WR;
6554 %}
6555
6556 // Empty pipeline class
6557 pipe_class pipe_class_empty()
6558 %{
6559 single_instruction;
6560 fixed_latency(0);
6561 %}
6562
6563 // Default pipeline class.
6564 pipe_class pipe_class_default()
6565 %{
6566 single_instruction;
6567 fixed_latency(2);
6568 %}
6569
6570 // Pipeline class for compares.
6571 pipe_class pipe_class_compare()
6572 %{
6573 single_instruction;
6574 fixed_latency(16);
6575 %}
6576
6577 // Pipeline class for memory operations.
6578 pipe_class pipe_class_memory()
6579 %{
6580 single_instruction;
6581 fixed_latency(16);
6582 %}
6583
6584 // Pipeline class for call.
6585 pipe_class pipe_class_call()
6586 %{
6587 single_instruction;
6588 fixed_latency(100);
6589 %}
6590
6591 // Define the class for the Nop node.
6592 define %{
6593 MachNop = pipe_class_empty;
6594 %}
6595
6596 %}
6597 //----------INSTRUCTIONS-------------------------------------------------------
6598 //
6599 // match -- States which machine-independent subtree may be replaced
6600 // by this instruction.
6601 // ins_cost -- The estimated cost of this instruction is used by instruction
6602 // selection to identify a minimum cost tree of machine
6603 // instructions that matches a tree of machine-independent
6604 // instructions.
6605 // format -- A string providing the disassembly for this instruction.
6606 // The value of an instruction's operand may be inserted
6607 // by referring to it with a '$' prefix.
6608 // opcode -- Three instruction opcodes may be provided. These are referred
6609 // to within an encode class as $primary, $secondary, and $tertiary
6610 // rrspectively. The primary opcode is commonly used to
6611 // indicate the type of machine instruction, while secondary
6612 // and tertiary are often used for prefix options or addressing
6613 // modes.
6614 // ins_encode -- A list of encode classes with parameters. The encode class
6615 // name must have been defined in an 'enc_class' specification
6616 // in the encode section of the architecture description.
6617
6618 // ============================================================================
6619 // Memory (Load/Store) Instructions
6620
6621 // Load Instructions
6622
6623 // Load Byte (8 bit signed)
6624 instruct loadB(iRegINoSp dst, memory1 mem)
6625 %{
6626 match(Set dst (LoadB mem));
6627 predicate(!needs_acquiring_load(n));
6628
6629 ins_cost(4 * INSN_COST);
6630 format %{ "ldrsbw $dst, $mem\t# byte" %}
6631
6632 ins_encode(aarch64_enc_ldrsbw(dst, mem));
6633
6634 ins_pipe(iload_reg_mem);
6635 %}
6636
6637 // Load Byte (8 bit signed) into long
6638 instruct loadB2L(iRegLNoSp dst, memory1 mem)
6639 %{
6640 match(Set dst (ConvI2L (LoadB mem)));
6641 predicate(!needs_acquiring_load(n->in(1)));
6642
6643 ins_cost(4 * INSN_COST);
6644 format %{ "ldrsb $dst, $mem\t# byte" %}
6645
6646 ins_encode(aarch64_enc_ldrsb(dst, mem));
6647
6648 ins_pipe(iload_reg_mem);
6649 %}
6650
6651 // Load Byte (8 bit unsigned)
6652 instruct loadUB(iRegINoSp dst, memory1 mem)
6653 %{
6654 match(Set dst (LoadUB mem));
6655 predicate(!needs_acquiring_load(n));
6656
6657 ins_cost(4 * INSN_COST);
6658 format %{ "ldrbw $dst, $mem\t# byte" %}
6659
6660 ins_encode(aarch64_enc_ldrb(dst, mem));
6661
6662 ins_pipe(iload_reg_mem);
6663 %}
6664
6665 // Load Byte (8 bit unsigned) into long
6666 instruct loadUB2L(iRegLNoSp dst, memory1 mem)
6667 %{
6668 match(Set dst (ConvI2L (LoadUB mem)));
6669 predicate(!needs_acquiring_load(n->in(1)));
6670
6671 ins_cost(4 * INSN_COST);
6672 format %{ "ldrb $dst, $mem\t# byte" %}
6673
6674 ins_encode(aarch64_enc_ldrb(dst, mem));
6675
6676 ins_pipe(iload_reg_mem);
6677 %}
6678
6679 // Load Short (16 bit signed)
6680 instruct loadS(iRegINoSp dst, memory2 mem)
6681 %{
6682 match(Set dst (LoadS mem));
6683 predicate(!needs_acquiring_load(n));
6684
6685 ins_cost(4 * INSN_COST);
6686 format %{ "ldrshw $dst, $mem\t# short" %}
6687
6688 ins_encode(aarch64_enc_ldrshw(dst, mem));
6689
6690 ins_pipe(iload_reg_mem);
6691 %}
6692
6693 // Load Short (16 bit signed) into long
6694 instruct loadS2L(iRegLNoSp dst, memory2 mem)
6695 %{
6696 match(Set dst (ConvI2L (LoadS mem)));
6697 predicate(!needs_acquiring_load(n->in(1)));
6698
6699 ins_cost(4 * INSN_COST);
6700 format %{ "ldrsh $dst, $mem\t# short" %}
6701
6702 ins_encode(aarch64_enc_ldrsh(dst, mem));
6703
6704 ins_pipe(iload_reg_mem);
6705 %}
6706
6707 // Load Char (16 bit unsigned)
6708 instruct loadUS(iRegINoSp dst, memory2 mem)
6709 %{
6710 match(Set dst (LoadUS mem));
6711 predicate(!needs_acquiring_load(n));
6712
6713 ins_cost(4 * INSN_COST);
6714 format %{ "ldrh $dst, $mem\t# short" %}
6715
6716 ins_encode(aarch64_enc_ldrh(dst, mem));
6717
6718 ins_pipe(iload_reg_mem);
6719 %}
6720
6721 // Load Short/Char (16 bit unsigned) into long
6722 instruct loadUS2L(iRegLNoSp dst, memory2 mem)
6723 %{
6724 match(Set dst (ConvI2L (LoadUS mem)));
6725 predicate(!needs_acquiring_load(n->in(1)));
6726
6727 ins_cost(4 * INSN_COST);
6728 format %{ "ldrh $dst, $mem\t# short" %}
6729
6730 ins_encode(aarch64_enc_ldrh(dst, mem));
6731
6732 ins_pipe(iload_reg_mem);
6733 %}
6734
6735 // Load Integer (32 bit signed)
6736 instruct loadI(iRegINoSp dst, memory4 mem)
6737 %{
6738 match(Set dst (LoadI mem));
6739 predicate(!needs_acquiring_load(n));
6740
6741 ins_cost(4 * INSN_COST);
6742 format %{ "ldrw $dst, $mem\t# int" %}
6743
6744 ins_encode(aarch64_enc_ldrw(dst, mem));
6745
6746 ins_pipe(iload_reg_mem);
6747 %}
6748
6749 // Load Integer (32 bit signed) into long
6750 instruct loadI2L(iRegLNoSp dst, memory4 mem)
6751 %{
6752 match(Set dst (ConvI2L (LoadI mem)));
6753 predicate(!needs_acquiring_load(n->in(1)));
6754
6755 ins_cost(4 * INSN_COST);
6756 format %{ "ldrsw $dst, $mem\t# int" %}
6757
6758 ins_encode(aarch64_enc_ldrsw(dst, mem));
6759
6760 ins_pipe(iload_reg_mem);
6761 %}
6762
6763 // Load Integer (32 bit unsigned) into long
6764 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask)
6765 %{
6766 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
6767 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load()));
6768
6769 ins_cost(4 * INSN_COST);
6770 format %{ "ldrw $dst, $mem\t# int" %}
6771
6772 ins_encode(aarch64_enc_ldrw(dst, mem));
6773
6774 ins_pipe(iload_reg_mem);
6775 %}
6776
6777 // Load Long (64 bit signed)
6778 instruct loadL(iRegLNoSp dst, memory8 mem)
6779 %{
6780 match(Set dst (LoadL mem));
6781 predicate(!needs_acquiring_load(n));
6782
6783 ins_cost(4 * INSN_COST);
6784 format %{ "ldr $dst, $mem\t# int" %}
6785
6786 ins_encode(aarch64_enc_ldr(dst, mem));
6787
6788 ins_pipe(iload_reg_mem);
6789 %}
6790
6791 // Load Range
6792 instruct loadRange(iRegINoSp dst, memory4 mem)
6793 %{
6794 match(Set dst (LoadRange mem));
6795
6796 ins_cost(4 * INSN_COST);
6797 format %{ "ldrw $dst, $mem\t# range" %}
6798
6799 ins_encode(aarch64_enc_ldrw(dst, mem));
6800
6801 ins_pipe(iload_reg_mem);
6802 %}
6803
6804 // Load Pointer
6805 instruct loadP(iRegPNoSp dst, memory8 mem)
6806 %{
6807 match(Set dst (LoadP mem));
6808 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0));
6809
6810 ins_cost(4 * INSN_COST);
6811 format %{ "ldr $dst, $mem\t# ptr" %}
6812
6813 ins_encode(aarch64_enc_ldr(dst, mem));
6814
6815 ins_pipe(iload_reg_mem);
6816 %}
6817
6818 // Load Compressed Pointer
6819 instruct loadN(iRegNNoSp dst, memory4 mem)
6820 %{
6821 match(Set dst (LoadN mem));
6822 predicate(!needs_acquiring_load(n) && n->as_Load()->barrier_data() == 0);
6823
6824 ins_cost(4 * INSN_COST);
6825 format %{ "ldrw $dst, $mem\t# compressed ptr" %}
6826
6827 ins_encode(aarch64_enc_ldrw(dst, mem));
6828
6829 ins_pipe(iload_reg_mem);
6830 %}
6831
6832 // Load Klass Pointer
6833 instruct loadKlass(iRegPNoSp dst, memory8 mem)
6834 %{
6835 match(Set dst (LoadKlass mem));
6836 predicate(!needs_acquiring_load(n));
6837
6838 ins_cost(4 * INSN_COST);
6839 format %{ "ldr $dst, $mem\t# class" %}
6840
6841 ins_encode(aarch64_enc_ldr(dst, mem));
6842
6843 ins_pipe(iload_reg_mem);
6844 %}
6845
6846 // Load Narrow Klass Pointer
6847 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6848 %{
6849 match(Set dst (LoadNKlass mem));
6850 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6851
6852 ins_cost(4 * INSN_COST);
6853 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6854
6855 ins_encode(aarch64_enc_ldrw(dst, mem));
6856
6857 ins_pipe(iload_reg_mem);
6858 %}
6859
6860 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory4 mem)
6861 %{
6862 match(Set dst (LoadNKlass mem));
6863 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6864
6865 ins_cost(4 * INSN_COST);
6866 format %{
6867 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6868 "lsrw $dst, $dst, markWord::klass_shift_at_offset"
6869 %}
6870 ins_encode %{
6871 // inlined aarch64_enc_ldrw
6872 loadStore(masm, &MacroAssembler::ldrw, $dst$$Register, $mem->opcode(),
6873 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
6874 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift_at_offset);
6875 %}
6876 ins_pipe(iload_reg_mem);
6877 %}
6878
6879 // Load Float
6880 instruct loadF(vRegF dst, memory4 mem)
6881 %{
6882 match(Set dst (LoadF mem));
6883 predicate(!needs_acquiring_load(n));
6884
6885 ins_cost(4 * INSN_COST);
6886 format %{ "ldrs $dst, $mem\t# float" %}
6887
6888 ins_encode( aarch64_enc_ldrs(dst, mem) );
6889
6890 ins_pipe(pipe_class_memory);
6891 %}
6892
6893 // Load Double
6894 instruct loadD(vRegD dst, memory8 mem)
6895 %{
6896 match(Set dst (LoadD mem));
6897 predicate(!needs_acquiring_load(n));
6898
6899 ins_cost(4 * INSN_COST);
6900 format %{ "ldrd $dst, $mem\t# double" %}
6901
6902 ins_encode( aarch64_enc_ldrd(dst, mem) );
6903
6904 ins_pipe(pipe_class_memory);
6905 %}
6906
6907
6908 // Load Int Constant
6909 instruct loadConI(iRegINoSp dst, immI src)
6910 %{
6911 match(Set dst src);
6912
6913 ins_cost(INSN_COST);
6914 format %{ "mov $dst, $src\t# int" %}
6915
6916 ins_encode( aarch64_enc_movw_imm(dst, src) );
6917
6918 ins_pipe(ialu_imm);
6919 %}
6920
6921 // Load Long Constant
6922 instruct loadConL(iRegLNoSp dst, immL src)
6923 %{
6924 match(Set dst src);
6925
6926 ins_cost(INSN_COST);
6927 format %{ "mov $dst, $src\t# long" %}
6928
6929 ins_encode( aarch64_enc_mov_imm(dst, src) );
6930
6931 ins_pipe(ialu_imm);
6932 %}
6933
6934 // Load Pointer Constant
6935
6936 instruct loadConP(iRegPNoSp dst, immP con)
6937 %{
6938 match(Set dst con);
6939
6940 ins_cost(INSN_COST * 4);
6941 format %{
6942 "mov $dst, $con\t# ptr\n\t"
6943 %}
6944
6945 ins_encode(aarch64_enc_mov_p(dst, con));
6946
6947 ins_pipe(ialu_imm);
6948 %}
6949
6950 // Load Null Pointer Constant
6951
6952 instruct loadConP0(iRegPNoSp dst, immP0 con)
6953 %{
6954 match(Set dst con);
6955
6956 ins_cost(INSN_COST);
6957 format %{ "mov $dst, $con\t# nullptr ptr" %}
6958
6959 ins_encode(aarch64_enc_mov_p0(dst, con));
6960
6961 ins_pipe(ialu_imm);
6962 %}
6963
6964 // Load Pointer Constant One
6965
6966 instruct loadConP1(iRegPNoSp dst, immP_1 con)
6967 %{
6968 match(Set dst con);
6969
6970 ins_cost(INSN_COST);
6971 format %{ "mov $dst, $con\t# nullptr ptr" %}
6972
6973 ins_encode(aarch64_enc_mov_p1(dst, con));
6974
6975 ins_pipe(ialu_imm);
6976 %}
6977
6978 // Load Narrow Pointer Constant
6979
6980 instruct loadConN(iRegNNoSp dst, immN con)
6981 %{
6982 match(Set dst con);
6983
6984 ins_cost(INSN_COST * 4);
6985 format %{ "mov $dst, $con\t# compressed ptr" %}
6986
6987 ins_encode(aarch64_enc_mov_n(dst, con));
6988
6989 ins_pipe(ialu_imm);
6990 %}
6991
6992 // Load Narrow Null Pointer Constant
6993
6994 instruct loadConN0(iRegNNoSp dst, immN0 con)
6995 %{
6996 match(Set dst con);
6997
6998 ins_cost(INSN_COST);
6999 format %{ "mov $dst, $con\t# compressed nullptr ptr" %}
7000
7001 ins_encode(aarch64_enc_mov_n0(dst, con));
7002
7003 ins_pipe(ialu_imm);
7004 %}
7005
7006 // Load Narrow Klass Constant
7007
7008 instruct loadConNKlass(iRegNNoSp dst, immNKlass con)
7009 %{
7010 match(Set dst con);
7011
7012 ins_cost(INSN_COST);
7013 format %{ "mov $dst, $con\t# compressed klass ptr" %}
7014
7015 ins_encode(aarch64_enc_mov_nk(dst, con));
7016
7017 ins_pipe(ialu_imm);
7018 %}
7019
7020 // Load Packed Float Constant
7021
7022 instruct loadConF_packed(vRegF dst, immFPacked con) %{
7023 match(Set dst con);
7024 ins_cost(INSN_COST * 4);
7025 format %{ "fmovs $dst, $con"%}
7026 ins_encode %{
7027 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant);
7028 %}
7029
7030 ins_pipe(fp_imm_s);
7031 %}
7032
7033 // Load Float Constant
7034
7035 instruct loadConF(vRegF dst, immF con) %{
7036 match(Set dst con);
7037
7038 ins_cost(INSN_COST * 4);
7039
7040 format %{
7041 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
7042 %}
7043
7044 ins_encode %{
7045 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con));
7046 %}
7047
7048 ins_pipe(fp_load_constant_s);
7049 %}
7050
7051 // Load Packed Double Constant
7052
7053 instruct loadConD_packed(vRegD dst, immDPacked con) %{
7054 match(Set dst con);
7055 ins_cost(INSN_COST);
7056 format %{ "fmovd $dst, $con"%}
7057 ins_encode %{
7058 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant);
7059 %}
7060
7061 ins_pipe(fp_imm_d);
7062 %}
7063
7064 // Load Double Constant
7065
7066 instruct loadConD(vRegD dst, immD con) %{
7067 match(Set dst con);
7068
7069 ins_cost(INSN_COST * 5);
7070 format %{
7071 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
7072 %}
7073
7074 ins_encode %{
7075 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con));
7076 %}
7077
7078 ins_pipe(fp_load_constant_d);
7079 %}
7080
7081 // Load Half Float Constant
7082 instruct loadConH(vRegF dst, immH con) %{
7083 match(Set dst con);
7084 format %{ "mov rscratch1, $con\n\t"
7085 "fmov $dst, rscratch1"
7086 %}
7087 ins_encode %{
7088 __ movw(rscratch1, (uint32_t)$con$$constant);
7089 __ fmovs($dst$$FloatRegister, rscratch1);
7090 %}
7091 ins_pipe(pipe_class_default);
7092 %}
7093
7094 // Store Instructions
7095
7096 // Store Byte
7097 instruct storeB(iRegIorL2I src, memory1 mem)
7098 %{
7099 match(Set mem (StoreB mem src));
7100 predicate(!needs_releasing_store(n));
7101
7102 ins_cost(INSN_COST);
7103 format %{ "strb $src, $mem\t# byte" %}
7104
7105 ins_encode(aarch64_enc_strb(src, mem));
7106
7107 ins_pipe(istore_reg_mem);
7108 %}
7109
7110
7111 instruct storeimmB0(immI0 zero, memory1 mem)
7112 %{
7113 match(Set mem (StoreB mem zero));
7114 predicate(!needs_releasing_store(n));
7115
7116 ins_cost(INSN_COST);
7117 format %{ "strb rscractch2, $mem\t# byte" %}
7118
7119 ins_encode(aarch64_enc_strb0(mem));
7120
7121 ins_pipe(istore_mem);
7122 %}
7123
7124 // Store Char/Short
7125 instruct storeC(iRegIorL2I src, memory2 mem)
7126 %{
7127 match(Set mem (StoreC mem src));
7128 predicate(!needs_releasing_store(n));
7129
7130 ins_cost(INSN_COST);
7131 format %{ "strh $src, $mem\t# short" %}
7132
7133 ins_encode(aarch64_enc_strh(src, mem));
7134
7135 ins_pipe(istore_reg_mem);
7136 %}
7137
7138 instruct storeimmC0(immI0 zero, memory2 mem)
7139 %{
7140 match(Set mem (StoreC mem zero));
7141 predicate(!needs_releasing_store(n));
7142
7143 ins_cost(INSN_COST);
7144 format %{ "strh zr, $mem\t# short" %}
7145
7146 ins_encode(aarch64_enc_strh0(mem));
7147
7148 ins_pipe(istore_mem);
7149 %}
7150
7151 // Store Integer
7152
7153 instruct storeI(iRegIorL2I src, memory4 mem)
7154 %{
7155 match(Set mem(StoreI mem src));
7156 predicate(!needs_releasing_store(n));
7157
7158 ins_cost(INSN_COST);
7159 format %{ "strw $src, $mem\t# int" %}
7160
7161 ins_encode(aarch64_enc_strw(src, mem));
7162
7163 ins_pipe(istore_reg_mem);
7164 %}
7165
7166 instruct storeimmI0(immI0 zero, memory4 mem)
7167 %{
7168 match(Set mem(StoreI mem zero));
7169 predicate(!needs_releasing_store(n));
7170
7171 ins_cost(INSN_COST);
7172 format %{ "strw zr, $mem\t# int" %}
7173
7174 ins_encode(aarch64_enc_strw0(mem));
7175
7176 ins_pipe(istore_mem);
7177 %}
7178
7179 // Store Long (64 bit signed)
7180 instruct storeL(iRegL src, memory8 mem)
7181 %{
7182 match(Set mem (StoreL mem src));
7183 predicate(!needs_releasing_store(n));
7184
7185 ins_cost(INSN_COST);
7186 format %{ "str $src, $mem\t# int" %}
7187
7188 ins_encode(aarch64_enc_str(src, mem));
7189
7190 ins_pipe(istore_reg_mem);
7191 %}
7192
7193 // Store Long (64 bit signed)
7194 instruct storeimmL0(immL0 zero, memory8 mem)
7195 %{
7196 match(Set mem (StoreL mem zero));
7197 predicate(!needs_releasing_store(n));
7198
7199 ins_cost(INSN_COST);
7200 format %{ "str zr, $mem\t# int" %}
7201
7202 ins_encode(aarch64_enc_str0(mem));
7203
7204 ins_pipe(istore_mem);
7205 %}
7206
7207 // Store Pointer
7208 instruct storeP(iRegP src, memory8 mem)
7209 %{
7210 match(Set mem (StoreP mem src));
7211 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0);
7212
7213 ins_cost(INSN_COST);
7214 format %{ "str $src, $mem\t# ptr" %}
7215
7216 ins_encode(aarch64_enc_str(src, mem));
7217
7218 ins_pipe(istore_reg_mem);
7219 %}
7220
7221 // Store Pointer
7222 instruct storeimmP0(immP0 zero, memory8 mem)
7223 %{
7224 match(Set mem (StoreP mem zero));
7225 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0);
7226
7227 ins_cost(INSN_COST);
7228 format %{ "str zr, $mem\t# ptr" %}
7229
7230 ins_encode(aarch64_enc_str0(mem));
7231
7232 ins_pipe(istore_mem);
7233 %}
7234
7235 // Store Compressed Pointer
7236 instruct storeN(iRegN src, memory4 mem)
7237 %{
7238 match(Set mem (StoreN mem src));
7239 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0);
7240
7241 ins_cost(INSN_COST);
7242 format %{ "strw $src, $mem\t# compressed ptr" %}
7243
7244 ins_encode(aarch64_enc_strw(src, mem));
7245
7246 ins_pipe(istore_reg_mem);
7247 %}
7248
7249 instruct storeImmN0(immN0 zero, memory4 mem)
7250 %{
7251 match(Set mem (StoreN mem zero));
7252 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0);
7253
7254 ins_cost(INSN_COST);
7255 format %{ "strw zr, $mem\t# compressed ptr" %}
7256
7257 ins_encode(aarch64_enc_strw0(mem));
7258
7259 ins_pipe(istore_mem);
7260 %}
7261
7262 // Store Float
7263 instruct storeF(vRegF src, memory4 mem)
7264 %{
7265 match(Set mem (StoreF mem src));
7266 predicate(!needs_releasing_store(n));
7267
7268 ins_cost(INSN_COST);
7269 format %{ "strs $src, $mem\t# float" %}
7270
7271 ins_encode( aarch64_enc_strs(src, mem) );
7272
7273 ins_pipe(pipe_class_memory);
7274 %}
7275
7276 // TODO
7277 // implement storeImmF0 and storeFImmPacked
7278
7279 // Store Double
7280 instruct storeD(vRegD src, memory8 mem)
7281 %{
7282 match(Set mem (StoreD mem src));
7283 predicate(!needs_releasing_store(n));
7284
7285 ins_cost(INSN_COST);
7286 format %{ "strd $src, $mem\t# double" %}
7287
7288 ins_encode( aarch64_enc_strd(src, mem) );
7289
7290 ins_pipe(pipe_class_memory);
7291 %}
7292
7293 // Store Compressed Klass Pointer
7294 instruct storeNKlass(iRegN src, memory4 mem)
7295 %{
7296 predicate(!needs_releasing_store(n));
7297 match(Set mem (StoreNKlass mem src));
7298
7299 ins_cost(INSN_COST);
7300 format %{ "strw $src, $mem\t# compressed klass ptr" %}
7301
7302 ins_encode(aarch64_enc_strw(src, mem));
7303
7304 ins_pipe(istore_reg_mem);
7305 %}
7306
7307 // TODO
7308 // implement storeImmD0 and storeDImmPacked
7309
7310 // prefetch instructions
7311 // Must be safe to execute with invalid address (cannot fault).
7312
7313 instruct prefetchalloc( memory8 mem ) %{
7314 match(PrefetchAllocation mem);
7315
7316 ins_cost(INSN_COST);
7317 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %}
7318
7319 ins_encode( aarch64_enc_prefetchw(mem) );
7320
7321 ins_pipe(iload_prefetch);
7322 %}
7323
7324 // ---------------- volatile loads and stores ----------------
7325
7326 // Load Byte (8 bit signed)
7327 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7328 %{
7329 match(Set dst (LoadB mem));
7330
7331 ins_cost(VOLATILE_REF_COST);
7332 format %{ "ldarsb $dst, $mem\t# byte" %}
7333
7334 ins_encode(aarch64_enc_ldarsb(dst, mem));
7335
7336 ins_pipe(pipe_serial);
7337 %}
7338
7339 // Load Byte (8 bit signed) into long
7340 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7341 %{
7342 match(Set dst (ConvI2L (LoadB mem)));
7343
7344 ins_cost(VOLATILE_REF_COST);
7345 format %{ "ldarsb $dst, $mem\t# byte" %}
7346
7347 ins_encode(aarch64_enc_ldarsb(dst, mem));
7348
7349 ins_pipe(pipe_serial);
7350 %}
7351
7352 // Load Byte (8 bit unsigned)
7353 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7354 %{
7355 match(Set dst (LoadUB mem));
7356
7357 ins_cost(VOLATILE_REF_COST);
7358 format %{ "ldarb $dst, $mem\t# byte" %}
7359
7360 ins_encode(aarch64_enc_ldarb(dst, mem));
7361
7362 ins_pipe(pipe_serial);
7363 %}
7364
7365 // Load Byte (8 bit unsigned) into long
7366 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7367 %{
7368 match(Set dst (ConvI2L (LoadUB mem)));
7369
7370 ins_cost(VOLATILE_REF_COST);
7371 format %{ "ldarb $dst, $mem\t# byte" %}
7372
7373 ins_encode(aarch64_enc_ldarb(dst, mem));
7374
7375 ins_pipe(pipe_serial);
7376 %}
7377
7378 // Load Short (16 bit signed)
7379 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7380 %{
7381 match(Set dst (LoadS mem));
7382
7383 ins_cost(VOLATILE_REF_COST);
7384 format %{ "ldarshw $dst, $mem\t# short" %}
7385
7386 ins_encode(aarch64_enc_ldarshw(dst, mem));
7387
7388 ins_pipe(pipe_serial);
7389 %}
7390
7391 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7392 %{
7393 match(Set dst (LoadUS mem));
7394
7395 ins_cost(VOLATILE_REF_COST);
7396 format %{ "ldarhw $dst, $mem\t# short" %}
7397
7398 ins_encode(aarch64_enc_ldarhw(dst, mem));
7399
7400 ins_pipe(pipe_serial);
7401 %}
7402
7403 // Load Short/Char (16 bit unsigned) into long
7404 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7405 %{
7406 match(Set dst (ConvI2L (LoadUS mem)));
7407
7408 ins_cost(VOLATILE_REF_COST);
7409 format %{ "ldarh $dst, $mem\t# short" %}
7410
7411 ins_encode(aarch64_enc_ldarh(dst, mem));
7412
7413 ins_pipe(pipe_serial);
7414 %}
7415
7416 // Load Short/Char (16 bit signed) into long
7417 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7418 %{
7419 match(Set dst (ConvI2L (LoadS mem)));
7420
7421 ins_cost(VOLATILE_REF_COST);
7422 format %{ "ldarh $dst, $mem\t# short" %}
7423
7424 ins_encode(aarch64_enc_ldarsh(dst, mem));
7425
7426 ins_pipe(pipe_serial);
7427 %}
7428
7429 // Load Integer (32 bit signed)
7430 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7431 %{
7432 match(Set dst (LoadI mem));
7433
7434 ins_cost(VOLATILE_REF_COST);
7435 format %{ "ldarw $dst, $mem\t# int" %}
7436
7437 ins_encode(aarch64_enc_ldarw(dst, mem));
7438
7439 ins_pipe(pipe_serial);
7440 %}
7441
7442 // Load Integer (32 bit unsigned) into long
7443 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask)
7444 %{
7445 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
7446
7447 ins_cost(VOLATILE_REF_COST);
7448 format %{ "ldarw $dst, $mem\t# int" %}
7449
7450 ins_encode(aarch64_enc_ldarw(dst, mem));
7451
7452 ins_pipe(pipe_serial);
7453 %}
7454
7455 // Load Long (64 bit signed)
7456 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7457 %{
7458 match(Set dst (LoadL mem));
7459
7460 ins_cost(VOLATILE_REF_COST);
7461 format %{ "ldar $dst, $mem\t# int" %}
7462
7463 ins_encode(aarch64_enc_ldar(dst, mem));
7464
7465 ins_pipe(pipe_serial);
7466 %}
7467
7468 // Load Pointer
7469 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem)
7470 %{
7471 match(Set dst (LoadP mem));
7472 predicate(n->as_Load()->barrier_data() == 0);
7473
7474 ins_cost(VOLATILE_REF_COST);
7475 format %{ "ldar $dst, $mem\t# ptr" %}
7476
7477 ins_encode(aarch64_enc_ldar(dst, mem));
7478
7479 ins_pipe(pipe_serial);
7480 %}
7481
7482 // Load Compressed Pointer
7483 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem)
7484 %{
7485 match(Set dst (LoadN mem));
7486 predicate(n->as_Load()->barrier_data() == 0);
7487
7488 ins_cost(VOLATILE_REF_COST);
7489 format %{ "ldarw $dst, $mem\t# compressed ptr" %}
7490
7491 ins_encode(aarch64_enc_ldarw(dst, mem));
7492
7493 ins_pipe(pipe_serial);
7494 %}
7495
7496 // Load Float
7497 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem)
7498 %{
7499 match(Set dst (LoadF mem));
7500
7501 ins_cost(VOLATILE_REF_COST);
7502 format %{ "ldars $dst, $mem\t# float" %}
7503
7504 ins_encode( aarch64_enc_fldars(dst, mem) );
7505
7506 ins_pipe(pipe_serial);
7507 %}
7508
7509 // Load Double
7510 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem)
7511 %{
7512 match(Set dst (LoadD mem));
7513
7514 ins_cost(VOLATILE_REF_COST);
7515 format %{ "ldard $dst, $mem\t# double" %}
7516
7517 ins_encode( aarch64_enc_fldard(dst, mem) );
7518
7519 ins_pipe(pipe_serial);
7520 %}
7521
7522 // Store Byte
7523 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7524 %{
7525 match(Set mem (StoreB mem src));
7526
7527 ins_cost(VOLATILE_REF_COST);
7528 format %{ "stlrb $src, $mem\t# byte" %}
7529
7530 ins_encode(aarch64_enc_stlrb(src, mem));
7531
7532 ins_pipe(pipe_class_memory);
7533 %}
7534
7535 instruct storeimmB0_volatile(immI0 zero, /* sync_memory*/indirect mem)
7536 %{
7537 match(Set mem (StoreB mem zero));
7538
7539 ins_cost(VOLATILE_REF_COST);
7540 format %{ "stlrb zr, $mem\t# byte" %}
7541
7542 ins_encode(aarch64_enc_stlrb0(mem));
7543
7544 ins_pipe(pipe_class_memory);
7545 %}
7546
7547 // Store Char/Short
7548 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7549 %{
7550 match(Set mem (StoreC mem src));
7551
7552 ins_cost(VOLATILE_REF_COST);
7553 format %{ "stlrh $src, $mem\t# short" %}
7554
7555 ins_encode(aarch64_enc_stlrh(src, mem));
7556
7557 ins_pipe(pipe_class_memory);
7558 %}
7559
7560 instruct storeimmC0_volatile(immI0 zero, /* sync_memory*/indirect mem)
7561 %{
7562 match(Set mem (StoreC mem zero));
7563
7564 ins_cost(VOLATILE_REF_COST);
7565 format %{ "stlrh zr, $mem\t# short" %}
7566
7567 ins_encode(aarch64_enc_stlrh0(mem));
7568
7569 ins_pipe(pipe_class_memory);
7570 %}
7571
7572 // Store Integer
7573
7574 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7575 %{
7576 match(Set mem(StoreI mem src));
7577
7578 ins_cost(VOLATILE_REF_COST);
7579 format %{ "stlrw $src, $mem\t# int" %}
7580
7581 ins_encode(aarch64_enc_stlrw(src, mem));
7582
7583 ins_pipe(pipe_class_memory);
7584 %}
7585
7586 instruct storeimmI0_volatile(immI0 zero, /* sync_memory*/indirect mem)
7587 %{
7588 match(Set mem(StoreI mem zero));
7589
7590 ins_cost(VOLATILE_REF_COST);
7591 format %{ "stlrw zr, $mem\t# int" %}
7592
7593 ins_encode(aarch64_enc_stlrw0(mem));
7594
7595 ins_pipe(pipe_class_memory);
7596 %}
7597
7598 // Store Long (64 bit signed)
7599 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem)
7600 %{
7601 match(Set mem (StoreL mem src));
7602
7603 ins_cost(VOLATILE_REF_COST);
7604 format %{ "stlr $src, $mem\t# int" %}
7605
7606 ins_encode(aarch64_enc_stlr(src, mem));
7607
7608 ins_pipe(pipe_class_memory);
7609 %}
7610
7611 instruct storeimmL0_volatile(immL0 zero, /* sync_memory*/indirect mem)
7612 %{
7613 match(Set mem (StoreL mem zero));
7614
7615 ins_cost(VOLATILE_REF_COST);
7616 format %{ "stlr zr, $mem\t# int" %}
7617
7618 ins_encode(aarch64_enc_stlr0(mem));
7619
7620 ins_pipe(pipe_class_memory);
7621 %}
7622
7623 // Store Pointer
7624 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem)
7625 %{
7626 match(Set mem (StoreP mem src));
7627 predicate(n->as_Store()->barrier_data() == 0);
7628
7629 ins_cost(VOLATILE_REF_COST);
7630 format %{ "stlr $src, $mem\t# ptr" %}
7631
7632 ins_encode(aarch64_enc_stlr(src, mem));
7633
7634 ins_pipe(pipe_class_memory);
7635 %}
7636
7637 instruct storeimmP0_volatile(immP0 zero, /* sync_memory*/indirect mem)
7638 %{
7639 match(Set mem (StoreP mem zero));
7640 predicate(n->as_Store()->barrier_data() == 0);
7641
7642 ins_cost(VOLATILE_REF_COST);
7643 format %{ "stlr zr, $mem\t# ptr" %}
7644
7645 ins_encode(aarch64_enc_stlr0(mem));
7646
7647 ins_pipe(pipe_class_memory);
7648 %}
7649
7650 // Store Compressed Pointer
7651 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem)
7652 %{
7653 match(Set mem (StoreN mem src));
7654 predicate(n->as_Store()->barrier_data() == 0);
7655
7656 ins_cost(VOLATILE_REF_COST);
7657 format %{ "stlrw $src, $mem\t# compressed ptr" %}
7658
7659 ins_encode(aarch64_enc_stlrw(src, mem));
7660
7661 ins_pipe(pipe_class_memory);
7662 %}
7663
7664 instruct storeimmN0_volatile(immN0 zero, /* sync_memory*/indirect mem)
7665 %{
7666 match(Set mem (StoreN mem zero));
7667 predicate(n->as_Store()->barrier_data() == 0);
7668
7669 ins_cost(VOLATILE_REF_COST);
7670 format %{ "stlrw zr, $mem\t# compressed ptr" %}
7671
7672 ins_encode(aarch64_enc_stlrw0(mem));
7673
7674 ins_pipe(pipe_class_memory);
7675 %}
7676
7677 // Store Float
7678 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem)
7679 %{
7680 match(Set mem (StoreF mem src));
7681
7682 ins_cost(VOLATILE_REF_COST);
7683 format %{ "stlrs $src, $mem\t# float" %}
7684
7685 ins_encode( aarch64_enc_fstlrs(src, mem) );
7686
7687 ins_pipe(pipe_class_memory);
7688 %}
7689
7690 // TODO
7691 // implement storeImmF0 and storeFImmPacked
7692
7693 // Store Double
7694 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem)
7695 %{
7696 match(Set mem (StoreD mem src));
7697
7698 ins_cost(VOLATILE_REF_COST);
7699 format %{ "stlrd $src, $mem\t# double" %}
7700
7701 ins_encode( aarch64_enc_fstlrd(src, mem) );
7702
7703 ins_pipe(pipe_class_memory);
7704 %}
7705
7706 // ---------------- end of volatile loads and stores ----------------
7707
7708 instruct cacheWB(indirect addr)
7709 %{
7710 predicate(VM_Version::supports_data_cache_line_flush());
7711 match(CacheWB addr);
7712
7713 ins_cost(100);
7714 format %{"cache wb $addr" %}
7715 ins_encode %{
7716 assert($addr->index_position() < 0, "should be");
7717 assert($addr$$disp == 0, "should be");
7718 __ cache_wb(Address($addr$$base$$Register, 0));
7719 %}
7720 ins_pipe(pipe_slow); // XXX
7721 %}
7722
7723 instruct cacheWBPreSync()
7724 %{
7725 predicate(VM_Version::supports_data_cache_line_flush());
7726 match(CacheWBPreSync);
7727
7728 ins_cost(100);
7729 format %{"cache wb presync" %}
7730 ins_encode %{
7731 __ cache_wbsync(true);
7732 %}
7733 ins_pipe(pipe_slow); // XXX
7734 %}
7735
7736 instruct cacheWBPostSync()
7737 %{
7738 predicate(VM_Version::supports_data_cache_line_flush());
7739 match(CacheWBPostSync);
7740
7741 ins_cost(100);
7742 format %{"cache wb postsync" %}
7743 ins_encode %{
7744 __ cache_wbsync(false);
7745 %}
7746 ins_pipe(pipe_slow); // XXX
7747 %}
7748
7749 // ============================================================================
7750 // BSWAP Instructions
7751
7752 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{
7753 match(Set dst (ReverseBytesI src));
7754
7755 ins_cost(INSN_COST);
7756 format %{ "revw $dst, $src" %}
7757
7758 ins_encode %{
7759 __ revw(as_Register($dst$$reg), as_Register($src$$reg));
7760 %}
7761
7762 ins_pipe(ialu_reg);
7763 %}
7764
7765 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{
7766 match(Set dst (ReverseBytesL src));
7767
7768 ins_cost(INSN_COST);
7769 format %{ "rev $dst, $src" %}
7770
7771 ins_encode %{
7772 __ rev(as_Register($dst$$reg), as_Register($src$$reg));
7773 %}
7774
7775 ins_pipe(ialu_reg);
7776 %}
7777
7778 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{
7779 match(Set dst (ReverseBytesUS src));
7780
7781 ins_cost(INSN_COST);
7782 format %{ "rev16w $dst, $src" %}
7783
7784 ins_encode %{
7785 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7786 %}
7787
7788 ins_pipe(ialu_reg);
7789 %}
7790
7791 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{
7792 match(Set dst (ReverseBytesS src));
7793
7794 ins_cost(INSN_COST);
7795 format %{ "rev16w $dst, $src\n\t"
7796 "sbfmw $dst, $dst, #0, #15" %}
7797
7798 ins_encode %{
7799 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7800 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U);
7801 %}
7802
7803 ins_pipe(ialu_reg);
7804 %}
7805
7806 // ============================================================================
7807 // Zero Count Instructions
7808
7809 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7810 match(Set dst (CountLeadingZerosI src));
7811
7812 ins_cost(INSN_COST);
7813 format %{ "clzw $dst, $src" %}
7814 ins_encode %{
7815 __ clzw(as_Register($dst$$reg), as_Register($src$$reg));
7816 %}
7817
7818 ins_pipe(ialu_reg);
7819 %}
7820
7821 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{
7822 match(Set dst (CountLeadingZerosL src));
7823
7824 ins_cost(INSN_COST);
7825 format %{ "clz $dst, $src" %}
7826 ins_encode %{
7827 __ clz(as_Register($dst$$reg), as_Register($src$$reg));
7828 %}
7829
7830 ins_pipe(ialu_reg);
7831 %}
7832
7833 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7834 match(Set dst (CountTrailingZerosI src));
7835
7836 ins_cost(INSN_COST * 2);
7837 format %{ "rbitw $dst, $src\n\t"
7838 "clzw $dst, $dst" %}
7839 ins_encode %{
7840 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg));
7841 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg));
7842 %}
7843
7844 ins_pipe(ialu_reg);
7845 %}
7846
7847 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{
7848 match(Set dst (CountTrailingZerosL src));
7849
7850 ins_cost(INSN_COST * 2);
7851 format %{ "rbit $dst, $src\n\t"
7852 "clz $dst, $dst" %}
7853 ins_encode %{
7854 __ rbit(as_Register($dst$$reg), as_Register($src$$reg));
7855 __ clz(as_Register($dst$$reg), as_Register($dst$$reg));
7856 %}
7857
7858 ins_pipe(ialu_reg);
7859 %}
7860
7861 //---------- Population Count Instructions -------------------------------------
7862 //
7863
7864 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{
7865 match(Set dst (PopCountI src));
7866 effect(TEMP tmp);
7867 ins_cost(INSN_COST * 13);
7868
7869 format %{ "fmovs $tmp, $src\t# vector (1S)\n\t"
7870 "cnt $tmp, $tmp\t# vector (8B)\n\t"
7871 "addv $tmp, $tmp\t# vector (8B)\n\t"
7872 "mov $dst, $tmp\t# vector (1D)" %}
7873 ins_encode %{
7874 __ fmovs($tmp$$FloatRegister, $src$$Register);
7875 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7876 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7877 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0);
7878 %}
7879
7880 ins_pipe(pipe_class_default);
7881 %}
7882
7883 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{
7884 match(Set dst (PopCountI (LoadI mem)));
7885 effect(TEMP tmp);
7886 ins_cost(INSN_COST * 13);
7887
7888 format %{ "ldrs $tmp, $mem\n\t"
7889 "cnt $tmp, $tmp\t# vector (8B)\n\t"
7890 "addv $tmp, $tmp\t# vector (8B)\n\t"
7891 "mov $dst, $tmp\t# vector (1D)" %}
7892 ins_encode %{
7893 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7894 loadStore(masm, &MacroAssembler::ldrs, tmp_reg, $mem->opcode(),
7895 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
7896 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7897 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7898 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0);
7899 %}
7900
7901 ins_pipe(pipe_class_default);
7902 %}
7903
7904 // Note: Long.bitCount(long) returns an int.
7905 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{
7906 match(Set dst (PopCountL src));
7907 effect(TEMP tmp);
7908 ins_cost(INSN_COST * 13);
7909
7910 format %{ "mov $tmp, $src\t# vector (1D)\n\t"
7911 "cnt $tmp, $tmp\t# vector (8B)\n\t"
7912 "addv $tmp, $tmp\t# vector (8B)\n\t"
7913 "mov $dst, $tmp\t# vector (1D)" %}
7914 ins_encode %{
7915 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register);
7916 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7917 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7918 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0);
7919 %}
7920
7921 ins_pipe(pipe_class_default);
7922 %}
7923
7924 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{
7925 match(Set dst (PopCountL (LoadL mem)));
7926 effect(TEMP tmp);
7927 ins_cost(INSN_COST * 13);
7928
7929 format %{ "ldrd $tmp, $mem\n\t"
7930 "cnt $tmp, $tmp\t# vector (8B)\n\t"
7931 "addv $tmp, $tmp\t# vector (8B)\n\t"
7932 "mov $dst, $tmp\t# vector (1D)" %}
7933 ins_encode %{
7934 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7935 loadStore(masm, &MacroAssembler::ldrd, tmp_reg, $mem->opcode(),
7936 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
7937 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7938 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7939 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0);
7940 %}
7941
7942 ins_pipe(pipe_class_default);
7943 %}
7944
7945 // ============================================================================
7946 // VerifyVectorAlignment Instruction
7947
7948 instruct verify_vector_alignment(iRegP addr, immL_positive_bitmaskI mask, rFlagsReg cr) %{
7949 match(Set addr (VerifyVectorAlignment addr mask));
7950 effect(KILL cr);
7951 format %{ "verify_vector_alignment $addr $mask \t! verify alignment" %}
7952 ins_encode %{
7953 Label Lskip;
7954 // check if masked bits of addr are zero
7955 __ tst($addr$$Register, $mask$$constant);
7956 __ br(Assembler::EQ, Lskip);
7957 __ stop("verify_vector_alignment found a misaligned vector memory access");
7958 __ bind(Lskip);
7959 %}
7960 ins_pipe(pipe_slow);
7961 %}
7962
7963 // ============================================================================
7964 // MemBar Instruction
7965
7966 instruct load_fence() %{
7967 match(LoadFence);
7968 ins_cost(VOLATILE_REF_COST);
7969
7970 format %{ "load_fence" %}
7971
7972 ins_encode %{
7973 __ membar(Assembler::LoadLoad|Assembler::LoadStore);
7974 %}
7975 ins_pipe(pipe_serial);
7976 %}
7977
7978 instruct unnecessary_membar_acquire() %{
7979 predicate(unnecessary_acquire(n));
7980 match(MemBarAcquire);
7981 ins_cost(0);
7982
7983 format %{ "membar_acquire (elided)" %}
7984
7985 ins_encode %{
7986 __ block_comment("membar_acquire (elided)");
7987 %}
7988
7989 ins_pipe(pipe_class_empty);
7990 %}
7991
7992 instruct membar_acquire() %{
7993 match(MemBarAcquire);
7994 ins_cost(VOLATILE_REF_COST);
7995
7996 format %{ "membar_acquire\n\t"
7997 "dmb ishld" %}
7998
7999 ins_encode %{
8000 __ block_comment("membar_acquire");
8001 __ membar(Assembler::LoadLoad|Assembler::LoadStore);
8002 %}
8003
8004 ins_pipe(pipe_serial);
8005 %}
8006
8007
8008 instruct membar_acquire_lock() %{
8009 match(MemBarAcquireLock);
8010 ins_cost(VOLATILE_REF_COST);
8011
8012 format %{ "membar_acquire_lock (elided)" %}
8013
8014 ins_encode %{
8015 __ block_comment("membar_acquire_lock (elided)");
8016 %}
8017
8018 ins_pipe(pipe_serial);
8019 %}
8020
8021 instruct store_fence() %{
8022 match(StoreFence);
8023 ins_cost(VOLATILE_REF_COST);
8024
8025 format %{ "store_fence" %}
8026
8027 ins_encode %{
8028 __ membar(Assembler::LoadStore|Assembler::StoreStore);
8029 %}
8030 ins_pipe(pipe_serial);
8031 %}
8032
8033 instruct unnecessary_membar_release() %{
8034 predicate(unnecessary_release(n));
8035 match(MemBarRelease);
8036 ins_cost(0);
8037
8038 format %{ "membar_release (elided)" %}
8039
8040 ins_encode %{
8041 __ block_comment("membar_release (elided)");
8042 %}
8043 ins_pipe(pipe_serial);
8044 %}
8045
8046 instruct membar_release() %{
8047 match(MemBarRelease);
8048 ins_cost(VOLATILE_REF_COST);
8049
8050 format %{ "membar_release\n\t"
8051 "dmb ishst\n\tdmb ishld" %}
8052
8053 ins_encode %{
8054 __ block_comment("membar_release");
8055 // These will be merged if AlwaysMergeDMB is enabled.
8056 __ membar(Assembler::StoreStore);
8057 __ membar(Assembler::LoadStore);
8058 %}
8059 ins_pipe(pipe_serial);
8060 %}
8061
8062 instruct membar_storestore() %{
8063 match(MemBarStoreStore);
8064 match(StoreStoreFence);
8065 ins_cost(VOLATILE_REF_COST);
8066
8067 format %{ "MEMBAR-store-store" %}
8068
8069 ins_encode %{
8070 __ membar(Assembler::StoreStore);
8071 %}
8072 ins_pipe(pipe_serial);
8073 %}
8074
8075 instruct membar_release_lock() %{
8076 match(MemBarReleaseLock);
8077 ins_cost(VOLATILE_REF_COST);
8078
8079 format %{ "membar_release_lock (elided)" %}
8080
8081 ins_encode %{
8082 __ block_comment("membar_release_lock (elided)");
8083 %}
8084
8085 ins_pipe(pipe_serial);
8086 %}
8087
8088 instruct unnecessary_membar_volatile() %{
8089 predicate(unnecessary_volatile(n));
8090 match(MemBarVolatile);
8091 ins_cost(0);
8092
8093 format %{ "membar_volatile (elided)" %}
8094
8095 ins_encode %{
8096 __ block_comment("membar_volatile (elided)");
8097 %}
8098
8099 ins_pipe(pipe_serial);
8100 %}
8101
8102 instruct membar_volatile() %{
8103 match(MemBarVolatile);
8104 ins_cost(VOLATILE_REF_COST*100);
8105
8106 format %{ "membar_volatile\n\t"
8107 "dmb ish"%}
8108
8109 ins_encode %{
8110 __ block_comment("membar_volatile");
8111 __ membar(Assembler::StoreLoad);
8112 %}
8113
8114 ins_pipe(pipe_serial);
8115 %}
8116
8117 // ============================================================================
8118 // Cast/Convert Instructions
8119
8120 instruct castX2P(iRegPNoSp dst, iRegL src) %{
8121 match(Set dst (CastX2P src));
8122
8123 ins_cost(INSN_COST);
8124 format %{ "mov $dst, $src\t# long -> ptr" %}
8125
8126 ins_encode %{
8127 if ($dst$$reg != $src$$reg) {
8128 __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8129 }
8130 %}
8131
8132 ins_pipe(ialu_reg);
8133 %}
8134
8135 instruct castP2X(iRegLNoSp dst, iRegP src) %{
8136 match(Set dst (CastP2X src));
8137
8138 ins_cost(INSN_COST);
8139 format %{ "mov $dst, $src\t# ptr -> long" %}
8140
8141 ins_encode %{
8142 if ($dst$$reg != $src$$reg) {
8143 __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8144 }
8145 %}
8146
8147 ins_pipe(ialu_reg);
8148 %}
8149
8150 // Convert oop into int for vectors alignment masking
8151 instruct convP2I(iRegINoSp dst, iRegP src) %{
8152 match(Set dst (ConvL2I (CastP2X src)));
8153
8154 ins_cost(INSN_COST);
8155 format %{ "movw $dst, $src\t# ptr -> int" %}
8156 ins_encode %{
8157 __ movw($dst$$Register, $src$$Register);
8158 %}
8159
8160 ins_pipe(ialu_reg);
8161 %}
8162
8163 // Convert compressed oop into int for vectors alignment masking
8164 // in case of 32bit oops (heap < 4Gb).
8165 instruct convN2I(iRegINoSp dst, iRegN src)
8166 %{
8167 predicate(CompressedOops::shift() == 0);
8168 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
8169
8170 ins_cost(INSN_COST);
8171 format %{ "mov dst, $src\t# compressed ptr -> int" %}
8172 ins_encode %{
8173 __ movw($dst$$Register, $src$$Register);
8174 %}
8175
8176 ins_pipe(ialu_reg);
8177 %}
8178
8179
8180 // Convert oop pointer into compressed form
8181 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
8182 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
8183 match(Set dst (EncodeP src));
8184 effect(KILL cr);
8185 ins_cost(INSN_COST * 3);
8186 format %{ "encode_heap_oop $dst, $src" %}
8187 ins_encode %{
8188 Register s = $src$$Register;
8189 Register d = $dst$$Register;
8190 __ encode_heap_oop(d, s);
8191 %}
8192 ins_pipe(ialu_reg);
8193 %}
8194
8195 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
8196 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
8197 match(Set dst (EncodeP src));
8198 ins_cost(INSN_COST * 3);
8199 format %{ "encode_heap_oop_not_null $dst, $src" %}
8200 ins_encode %{
8201 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
8202 %}
8203 ins_pipe(ialu_reg);
8204 %}
8205
8206 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
8207 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
8208 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
8209 match(Set dst (DecodeN src));
8210 ins_cost(INSN_COST * 3);
8211 format %{ "decode_heap_oop $dst, $src" %}
8212 ins_encode %{
8213 Register s = $src$$Register;
8214 Register d = $dst$$Register;
8215 __ decode_heap_oop(d, s);
8216 %}
8217 ins_pipe(ialu_reg);
8218 %}
8219
8220 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
8221 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
8222 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
8223 match(Set dst (DecodeN src));
8224 ins_cost(INSN_COST * 3);
8225 format %{ "decode_heap_oop_not_null $dst, $src" %}
8226 ins_encode %{
8227 Register s = $src$$Register;
8228 Register d = $dst$$Register;
8229 __ decode_heap_oop_not_null(d, s);
8230 %}
8231 ins_pipe(ialu_reg);
8232 %}
8233
8234 // n.b. AArch64 implementations of encode_klass_not_null and
8235 // decode_klass_not_null do not modify the flags register so, unlike
8236 // Intel, we don't kill CR as a side effect here
8237
8238 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{
8239 match(Set dst (EncodePKlass src));
8240
8241 ins_cost(INSN_COST * 3);
8242 format %{ "encode_klass_not_null $dst,$src" %}
8243
8244 ins_encode %{
8245 Register src_reg = as_Register($src$$reg);
8246 Register dst_reg = as_Register($dst$$reg);
8247 __ encode_klass_not_null(dst_reg, src_reg);
8248 %}
8249
8250 ins_pipe(ialu_reg);
8251 %}
8252
8253 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{
8254 match(Set dst (DecodeNKlass src));
8255
8256 ins_cost(INSN_COST * 3);
8257 format %{ "decode_klass_not_null $dst,$src" %}
8258
8259 ins_encode %{
8260 Register src_reg = as_Register($src$$reg);
8261 Register dst_reg = as_Register($dst$$reg);
8262 if (dst_reg != src_reg) {
8263 __ decode_klass_not_null(dst_reg, src_reg);
8264 } else {
8265 __ decode_klass_not_null(dst_reg);
8266 }
8267 %}
8268
8269 ins_pipe(ialu_reg);
8270 %}
8271
8272 instruct checkCastPP(iRegPNoSp dst)
8273 %{
8274 match(Set dst (CheckCastPP dst));
8275
8276 size(0);
8277 format %{ "# checkcastPP of $dst" %}
8278 ins_encode(/* empty encoding */);
8279 ins_pipe(pipe_class_empty);
8280 %}
8281
8282 instruct castPP(iRegPNoSp dst)
8283 %{
8284 match(Set dst (CastPP dst));
8285
8286 size(0);
8287 format %{ "# castPP of $dst" %}
8288 ins_encode(/* empty encoding */);
8289 ins_pipe(pipe_class_empty);
8290 %}
8291
8292 instruct castII(iRegI dst)
8293 %{
8294 predicate(VerifyConstraintCasts == 0);
8295 match(Set dst (CastII dst));
8296
8297 size(0);
8298 format %{ "# castII of $dst" %}
8299 ins_encode(/* empty encoding */);
8300 ins_cost(0);
8301 ins_pipe(pipe_class_empty);
8302 %}
8303
8304 instruct castII_checked(iRegI dst, rFlagsReg cr)
8305 %{
8306 predicate(VerifyConstraintCasts > 0);
8307 match(Set dst (CastII dst));
8308 effect(KILL cr);
8309
8310 format %{ "# castII_checked of $dst" %}
8311 ins_encode %{
8312 __ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register, rscratch1);
8313 %}
8314 ins_pipe(pipe_slow);
8315 %}
8316
8317 instruct castLL(iRegL dst)
8318 %{
8319 predicate(VerifyConstraintCasts == 0);
8320 match(Set dst (CastLL dst));
8321
8322 size(0);
8323 format %{ "# castLL of $dst" %}
8324 ins_encode(/* empty encoding */);
8325 ins_cost(0);
8326 ins_pipe(pipe_class_empty);
8327 %}
8328
8329 instruct castLL_checked(iRegL dst, rFlagsReg cr)
8330 %{
8331 predicate(VerifyConstraintCasts > 0);
8332 match(Set dst (CastLL dst));
8333 effect(KILL cr);
8334
8335 format %{ "# castLL_checked of $dst" %}
8336 ins_encode %{
8337 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, rscratch1);
8338 %}
8339 ins_pipe(pipe_slow);
8340 %}
8341
8342 instruct castHH(vRegF dst)
8343 %{
8344 match(Set dst (CastHH dst));
8345 size(0);
8346 format %{ "# castHH of $dst" %}
8347 ins_encode(/* empty encoding */);
8348 ins_cost(0);
8349 ins_pipe(pipe_class_empty);
8350 %}
8351
8352 instruct castFF(vRegF dst)
8353 %{
8354 match(Set dst (CastFF dst));
8355
8356 size(0);
8357 format %{ "# castFF of $dst" %}
8358 ins_encode(/* empty encoding */);
8359 ins_cost(0);
8360 ins_pipe(pipe_class_empty);
8361 %}
8362
8363 instruct castDD(vRegD dst)
8364 %{
8365 match(Set dst (CastDD dst));
8366
8367 size(0);
8368 format %{ "# castDD of $dst" %}
8369 ins_encode(/* empty encoding */);
8370 ins_cost(0);
8371 ins_pipe(pipe_class_empty);
8372 %}
8373
8374 instruct castVV(vReg dst)
8375 %{
8376 match(Set dst (CastVV dst));
8377
8378 size(0);
8379 format %{ "# castVV of $dst" %}
8380 ins_encode(/* empty encoding */);
8381 ins_cost(0);
8382 ins_pipe(pipe_class_empty);
8383 %}
8384
8385 instruct castVVMask(pRegGov dst)
8386 %{
8387 match(Set dst (CastVV dst));
8388
8389 size(0);
8390 format %{ "# castVV of $dst" %}
8391 ins_encode(/* empty encoding */);
8392 ins_cost(0);
8393 ins_pipe(pipe_class_empty);
8394 %}
8395
8396 // ============================================================================
8397 // Atomic operation instructions
8398 //
8399
8400 // standard CompareAndSwapX when we are using barriers
8401 // these have higher priority than the rules selected by a predicate
8402
8403 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher
8404 // can't match them
8405
8406 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8407
8408 match(Set res (CompareAndSwapB mem (Binary oldval newval)));
8409 ins_cost(2 * VOLATILE_REF_COST);
8410
8411 effect(KILL cr);
8412
8413 format %{
8414 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8415 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8416 %}
8417
8418 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval),
8419 aarch64_enc_cset_eq(res));
8420
8421 ins_pipe(pipe_slow);
8422 %}
8423
8424 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8425
8426 match(Set res (CompareAndSwapS mem (Binary oldval newval)));
8427 ins_cost(2 * VOLATILE_REF_COST);
8428
8429 effect(KILL cr);
8430
8431 format %{
8432 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8433 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8434 %}
8435
8436 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval),
8437 aarch64_enc_cset_eq(res));
8438
8439 ins_pipe(pipe_slow);
8440 %}
8441
8442 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8443
8444 match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8445 ins_cost(2 * VOLATILE_REF_COST);
8446
8447 effect(KILL cr);
8448
8449 format %{
8450 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8451 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8452 %}
8453
8454 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8455 aarch64_enc_cset_eq(res));
8456
8457 ins_pipe(pipe_slow);
8458 %}
8459
8460 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8461
8462 match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8463 ins_cost(2 * VOLATILE_REF_COST);
8464
8465 effect(KILL cr);
8466
8467 format %{
8468 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8469 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8470 %}
8471
8472 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8473 aarch64_enc_cset_eq(res));
8474
8475 ins_pipe(pipe_slow);
8476 %}
8477
8478 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8479
8480 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8481 predicate(n->as_LoadStore()->barrier_data() == 0);
8482 ins_cost(2 * VOLATILE_REF_COST);
8483
8484 effect(KILL cr);
8485
8486 format %{
8487 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8488 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8489 %}
8490
8491 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8492 aarch64_enc_cset_eq(res));
8493
8494 ins_pipe(pipe_slow);
8495 %}
8496
8497 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8498
8499 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8500 predicate(n->as_LoadStore()->barrier_data() == 0);
8501 ins_cost(2 * VOLATILE_REF_COST);
8502
8503 effect(KILL cr);
8504
8505 format %{
8506 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8507 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8508 %}
8509
8510 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8511 aarch64_enc_cset_eq(res));
8512
8513 ins_pipe(pipe_slow);
8514 %}
8515
8516 // alternative CompareAndSwapX when we are eliding barriers
8517
8518 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8519
8520 predicate(needs_acquiring_load_exclusive(n));
8521 match(Set res (CompareAndSwapB mem (Binary oldval newval)));
8522 ins_cost(VOLATILE_REF_COST);
8523
8524 effect(KILL cr);
8525
8526 format %{
8527 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8528 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8529 %}
8530
8531 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval),
8532 aarch64_enc_cset_eq(res));
8533
8534 ins_pipe(pipe_slow);
8535 %}
8536
8537 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8538
8539 predicate(needs_acquiring_load_exclusive(n));
8540 match(Set res (CompareAndSwapS mem (Binary oldval newval)));
8541 ins_cost(VOLATILE_REF_COST);
8542
8543 effect(KILL cr);
8544
8545 format %{
8546 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8547 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8548 %}
8549
8550 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval),
8551 aarch64_enc_cset_eq(res));
8552
8553 ins_pipe(pipe_slow);
8554 %}
8555
8556 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8557
8558 predicate(needs_acquiring_load_exclusive(n));
8559 match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8560 ins_cost(VOLATILE_REF_COST);
8561
8562 effect(KILL cr);
8563
8564 format %{
8565 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8566 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8567 %}
8568
8569 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8570 aarch64_enc_cset_eq(res));
8571
8572 ins_pipe(pipe_slow);
8573 %}
8574
8575 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8576
8577 predicate(needs_acquiring_load_exclusive(n));
8578 match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8579 ins_cost(VOLATILE_REF_COST);
8580
8581 effect(KILL cr);
8582
8583 format %{
8584 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8585 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8586 %}
8587
8588 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8589 aarch64_enc_cset_eq(res));
8590
8591 ins_pipe(pipe_slow);
8592 %}
8593
8594 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8595
8596 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
8597 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8598 ins_cost(VOLATILE_REF_COST);
8599
8600 effect(KILL cr);
8601
8602 format %{
8603 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8604 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8605 %}
8606
8607 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8608 aarch64_enc_cset_eq(res));
8609
8610 ins_pipe(pipe_slow);
8611 %}
8612
8613 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8614
8615 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
8616 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8617 ins_cost(VOLATILE_REF_COST);
8618
8619 effect(KILL cr);
8620
8621 format %{
8622 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8623 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8624 %}
8625
8626 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8627 aarch64_enc_cset_eq(res));
8628
8629 ins_pipe(pipe_slow);
8630 %}
8631
8632
8633 // ---------------------------------------------------------------------
8634
8635 // BEGIN This section of the file is automatically generated. Do not edit --------------
8636
8637 // Sundry CAS operations. Note that release is always true,
8638 // regardless of the memory ordering of the CAS. This is because we
8639 // need the volatile case to be sequentially consistent but there is
8640 // no trailing StoreLoad barrier emitted by C2. Unfortunately we
8641 // can't check the type of memory ordering here, so we always emit a
8642 // STLXR.
8643
8644 // This section is generated from cas.m4
8645
8646
8647 // This pattern is generated automatically from cas.m4.
8648 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8649 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8650 match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
8651 ins_cost(2 * VOLATILE_REF_COST);
8652 effect(TEMP_DEF res, KILL cr);
8653 format %{
8654 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8655 %}
8656 ins_encode %{
8657 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8658 Assembler::byte, /*acquire*/ false, /*release*/ true,
8659 /*weak*/ false, $res$$Register);
8660 __ sxtbw($res$$Register, $res$$Register);
8661 %}
8662 ins_pipe(pipe_slow);
8663 %}
8664
8665 // This pattern is generated automatically from cas.m4.
8666 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8667 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8668 match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
8669 ins_cost(2 * VOLATILE_REF_COST);
8670 effect(TEMP_DEF res, KILL cr);
8671 format %{
8672 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8673 %}
8674 ins_encode %{
8675 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8676 Assembler::halfword, /*acquire*/ false, /*release*/ true,
8677 /*weak*/ false, $res$$Register);
8678 __ sxthw($res$$Register, $res$$Register);
8679 %}
8680 ins_pipe(pipe_slow);
8681 %}
8682
8683 // This pattern is generated automatically from cas.m4.
8684 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8685 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8686 match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
8687 ins_cost(2 * VOLATILE_REF_COST);
8688 effect(TEMP_DEF res, KILL cr);
8689 format %{
8690 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8691 %}
8692 ins_encode %{
8693 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8694 Assembler::word, /*acquire*/ false, /*release*/ true,
8695 /*weak*/ false, $res$$Register);
8696 %}
8697 ins_pipe(pipe_slow);
8698 %}
8699
8700 // This pattern is generated automatically from cas.m4.
8701 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8702 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8703 match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
8704 ins_cost(2 * VOLATILE_REF_COST);
8705 effect(TEMP_DEF res, KILL cr);
8706 format %{
8707 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8708 %}
8709 ins_encode %{
8710 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8711 Assembler::xword, /*acquire*/ false, /*release*/ true,
8712 /*weak*/ false, $res$$Register);
8713 %}
8714 ins_pipe(pipe_slow);
8715 %}
8716
8717 // This pattern is generated automatically from cas.m4.
8718 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8719 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8720 predicate(n->as_LoadStore()->barrier_data() == 0);
8721 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
8722 ins_cost(2 * VOLATILE_REF_COST);
8723 effect(TEMP_DEF res, KILL cr);
8724 format %{
8725 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8726 %}
8727 ins_encode %{
8728 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8729 Assembler::word, /*acquire*/ false, /*release*/ true,
8730 /*weak*/ false, $res$$Register);
8731 %}
8732 ins_pipe(pipe_slow);
8733 %}
8734
8735 // This pattern is generated automatically from cas.m4.
8736 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8737 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8738 predicate(n->as_LoadStore()->barrier_data() == 0);
8739 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
8740 ins_cost(2 * VOLATILE_REF_COST);
8741 effect(TEMP_DEF res, KILL cr);
8742 format %{
8743 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8744 %}
8745 ins_encode %{
8746 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8747 Assembler::xword, /*acquire*/ false, /*release*/ true,
8748 /*weak*/ false, $res$$Register);
8749 %}
8750 ins_pipe(pipe_slow);
8751 %}
8752
8753 // This pattern is generated automatically from cas.m4.
8754 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8755 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8756 predicate(needs_acquiring_load_exclusive(n));
8757 match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
8758 ins_cost(VOLATILE_REF_COST);
8759 effect(TEMP_DEF res, KILL cr);
8760 format %{
8761 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8762 %}
8763 ins_encode %{
8764 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8765 Assembler::byte, /*acquire*/ true, /*release*/ true,
8766 /*weak*/ false, $res$$Register);
8767 __ sxtbw($res$$Register, $res$$Register);
8768 %}
8769 ins_pipe(pipe_slow);
8770 %}
8771
8772 // This pattern is generated automatically from cas.m4.
8773 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8774 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8775 predicate(needs_acquiring_load_exclusive(n));
8776 match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
8777 ins_cost(VOLATILE_REF_COST);
8778 effect(TEMP_DEF res, KILL cr);
8779 format %{
8780 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8781 %}
8782 ins_encode %{
8783 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8784 Assembler::halfword, /*acquire*/ true, /*release*/ true,
8785 /*weak*/ false, $res$$Register);
8786 __ sxthw($res$$Register, $res$$Register);
8787 %}
8788 ins_pipe(pipe_slow);
8789 %}
8790
8791 // This pattern is generated automatically from cas.m4.
8792 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8793 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8794 predicate(needs_acquiring_load_exclusive(n));
8795 match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
8796 ins_cost(VOLATILE_REF_COST);
8797 effect(TEMP_DEF res, KILL cr);
8798 format %{
8799 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8800 %}
8801 ins_encode %{
8802 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8803 Assembler::word, /*acquire*/ true, /*release*/ true,
8804 /*weak*/ false, $res$$Register);
8805 %}
8806 ins_pipe(pipe_slow);
8807 %}
8808
8809 // This pattern is generated automatically from cas.m4.
8810 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8811 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8812 predicate(needs_acquiring_load_exclusive(n));
8813 match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
8814 ins_cost(VOLATILE_REF_COST);
8815 effect(TEMP_DEF res, KILL cr);
8816 format %{
8817 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8818 %}
8819 ins_encode %{
8820 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8821 Assembler::xword, /*acquire*/ true, /*release*/ true,
8822 /*weak*/ false, $res$$Register);
8823 %}
8824 ins_pipe(pipe_slow);
8825 %}
8826
8827 // This pattern is generated automatically from cas.m4.
8828 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8829 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8830 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
8831 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
8832 ins_cost(VOLATILE_REF_COST);
8833 effect(TEMP_DEF res, KILL cr);
8834 format %{
8835 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8836 %}
8837 ins_encode %{
8838 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8839 Assembler::word, /*acquire*/ true, /*release*/ true,
8840 /*weak*/ false, $res$$Register);
8841 %}
8842 ins_pipe(pipe_slow);
8843 %}
8844
8845 // This pattern is generated automatically from cas.m4.
8846 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8847 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8848 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
8849 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
8850 ins_cost(VOLATILE_REF_COST);
8851 effect(TEMP_DEF res, KILL cr);
8852 format %{
8853 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8854 %}
8855 ins_encode %{
8856 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8857 Assembler::xword, /*acquire*/ true, /*release*/ true,
8858 /*weak*/ false, $res$$Register);
8859 %}
8860 ins_pipe(pipe_slow);
8861 %}
8862
8863 // This pattern is generated automatically from cas.m4.
8864 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8865 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8866 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
8867 ins_cost(2 * VOLATILE_REF_COST);
8868 effect(KILL cr);
8869 format %{
8870 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8871 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8872 %}
8873 ins_encode %{
8874 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8875 Assembler::byte, /*acquire*/ false, /*release*/ true,
8876 /*weak*/ true, noreg);
8877 __ csetw($res$$Register, Assembler::EQ);
8878 %}
8879 ins_pipe(pipe_slow);
8880 %}
8881
8882 // This pattern is generated automatically from cas.m4.
8883 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8884 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8885 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
8886 ins_cost(2 * VOLATILE_REF_COST);
8887 effect(KILL cr);
8888 format %{
8889 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8890 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8891 %}
8892 ins_encode %{
8893 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8894 Assembler::halfword, /*acquire*/ false, /*release*/ true,
8895 /*weak*/ true, noreg);
8896 __ csetw($res$$Register, Assembler::EQ);
8897 %}
8898 ins_pipe(pipe_slow);
8899 %}
8900
8901 // This pattern is generated automatically from cas.m4.
8902 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8903 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8904 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
8905 ins_cost(2 * VOLATILE_REF_COST);
8906 effect(KILL cr);
8907 format %{
8908 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8909 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8910 %}
8911 ins_encode %{
8912 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8913 Assembler::word, /*acquire*/ false, /*release*/ true,
8914 /*weak*/ true, noreg);
8915 __ csetw($res$$Register, Assembler::EQ);
8916 %}
8917 ins_pipe(pipe_slow);
8918 %}
8919
8920 // This pattern is generated automatically from cas.m4.
8921 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8922 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8923 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
8924 ins_cost(2 * VOLATILE_REF_COST);
8925 effect(KILL cr);
8926 format %{
8927 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8928 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8929 %}
8930 ins_encode %{
8931 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8932 Assembler::xword, /*acquire*/ false, /*release*/ true,
8933 /*weak*/ true, noreg);
8934 __ csetw($res$$Register, Assembler::EQ);
8935 %}
8936 ins_pipe(pipe_slow);
8937 %}
8938
8939 // This pattern is generated automatically from cas.m4.
8940 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8941 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8942 predicate(n->as_LoadStore()->barrier_data() == 0);
8943 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
8944 ins_cost(2 * VOLATILE_REF_COST);
8945 effect(KILL cr);
8946 format %{
8947 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8948 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8949 %}
8950 ins_encode %{
8951 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8952 Assembler::word, /*acquire*/ false, /*release*/ true,
8953 /*weak*/ true, noreg);
8954 __ csetw($res$$Register, Assembler::EQ);
8955 %}
8956 ins_pipe(pipe_slow);
8957 %}
8958
8959 // This pattern is generated automatically from cas.m4.
8960 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8961 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8962 predicate(n->as_LoadStore()->barrier_data() == 0);
8963 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
8964 ins_cost(2 * VOLATILE_REF_COST);
8965 effect(KILL cr);
8966 format %{
8967 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8968 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8969 %}
8970 ins_encode %{
8971 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8972 Assembler::xword, /*acquire*/ false, /*release*/ true,
8973 /*weak*/ true, noreg);
8974 __ csetw($res$$Register, Assembler::EQ);
8975 %}
8976 ins_pipe(pipe_slow);
8977 %}
8978
8979 // This pattern is generated automatically from cas.m4.
8980 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8981 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8982 predicate(needs_acquiring_load_exclusive(n));
8983 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
8984 ins_cost(VOLATILE_REF_COST);
8985 effect(KILL cr);
8986 format %{
8987 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8988 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8989 %}
8990 ins_encode %{
8991 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8992 Assembler::byte, /*acquire*/ true, /*release*/ true,
8993 /*weak*/ true, noreg);
8994 __ csetw($res$$Register, Assembler::EQ);
8995 %}
8996 ins_pipe(pipe_slow);
8997 %}
8998
8999 // This pattern is generated automatically from cas.m4.
9000 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9001 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9002 predicate(needs_acquiring_load_exclusive(n));
9003 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
9004 ins_cost(VOLATILE_REF_COST);
9005 effect(KILL cr);
9006 format %{
9007 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
9008 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9009 %}
9010 ins_encode %{
9011 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9012 Assembler::halfword, /*acquire*/ true, /*release*/ true,
9013 /*weak*/ true, noreg);
9014 __ csetw($res$$Register, Assembler::EQ);
9015 %}
9016 ins_pipe(pipe_slow);
9017 %}
9018
9019 // This pattern is generated automatically from cas.m4.
9020 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9021 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9022 predicate(needs_acquiring_load_exclusive(n));
9023 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
9024 ins_cost(VOLATILE_REF_COST);
9025 effect(KILL cr);
9026 format %{
9027 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
9028 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9029 %}
9030 ins_encode %{
9031 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9032 Assembler::word, /*acquire*/ true, /*release*/ true,
9033 /*weak*/ true, noreg);
9034 __ csetw($res$$Register, Assembler::EQ);
9035 %}
9036 ins_pipe(pipe_slow);
9037 %}
9038
9039 // This pattern is generated automatically from cas.m4.
9040 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9041 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
9042 predicate(needs_acquiring_load_exclusive(n));
9043 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
9044 ins_cost(VOLATILE_REF_COST);
9045 effect(KILL cr);
9046 format %{
9047 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
9048 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9049 %}
9050 ins_encode %{
9051 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9052 Assembler::xword, /*acquire*/ true, /*release*/ true,
9053 /*weak*/ true, noreg);
9054 __ csetw($res$$Register, Assembler::EQ);
9055 %}
9056 ins_pipe(pipe_slow);
9057 %}
9058
9059 // This pattern is generated automatically from cas.m4.
9060 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9061 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
9062 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
9063 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
9064 ins_cost(VOLATILE_REF_COST);
9065 effect(KILL cr);
9066 format %{
9067 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9068 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9069 %}
9070 ins_encode %{
9071 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9072 Assembler::word, /*acquire*/ true, /*release*/ true,
9073 /*weak*/ true, noreg);
9074 __ csetw($res$$Register, Assembler::EQ);
9075 %}
9076 ins_pipe(pipe_slow);
9077 %}
9078
9079 // This pattern is generated automatically from cas.m4.
9080 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9081 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9082 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
9083 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
9084 ins_cost(VOLATILE_REF_COST);
9085 effect(KILL cr);
9086 format %{
9087 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
9088 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9089 %}
9090 ins_encode %{
9091 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9092 Assembler::xword, /*acquire*/ true, /*release*/ true,
9093 /*weak*/ true, noreg);
9094 __ csetw($res$$Register, Assembler::EQ);
9095 %}
9096 ins_pipe(pipe_slow);
9097 %}
9098
9099 // END This section of the file is automatically generated. Do not edit --------------
9100 // ---------------------------------------------------------------------
9101
9102 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
9103 match(Set prev (GetAndSetI mem newv));
9104 ins_cost(2 * VOLATILE_REF_COST);
9105 format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
9106 ins_encode %{
9107 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9108 %}
9109 ins_pipe(pipe_serial);
9110 %}
9111
9112 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
9113 match(Set prev (GetAndSetL mem newv));
9114 ins_cost(2 * VOLATILE_REF_COST);
9115 format %{ "atomic_xchg $prev, $newv, [$mem]" %}
9116 ins_encode %{
9117 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
9118 %}
9119 ins_pipe(pipe_serial);
9120 %}
9121
9122 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
9123 predicate(n->as_LoadStore()->barrier_data() == 0);
9124 match(Set prev (GetAndSetN mem newv));
9125 ins_cost(2 * VOLATILE_REF_COST);
9126 format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
9127 ins_encode %{
9128 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9129 %}
9130 ins_pipe(pipe_serial);
9131 %}
9132
9133 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
9134 predicate(n->as_LoadStore()->barrier_data() == 0);
9135 match(Set prev (GetAndSetP mem newv));
9136 ins_cost(2 * VOLATILE_REF_COST);
9137 format %{ "atomic_xchg $prev, $newv, [$mem]" %}
9138 ins_encode %{
9139 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
9140 %}
9141 ins_pipe(pipe_serial);
9142 %}
9143
9144 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{
9145 predicate(needs_acquiring_load_exclusive(n));
9146 match(Set prev (GetAndSetI mem newv));
9147 ins_cost(VOLATILE_REF_COST);
9148 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %}
9149 ins_encode %{
9150 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9151 %}
9152 ins_pipe(pipe_serial);
9153 %}
9154
9155 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{
9156 predicate(needs_acquiring_load_exclusive(n));
9157 match(Set prev (GetAndSetL mem newv));
9158 ins_cost(VOLATILE_REF_COST);
9159 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %}
9160 ins_encode %{
9161 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
9162 %}
9163 ins_pipe(pipe_serial);
9164 %}
9165
9166 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{
9167 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
9168 match(Set prev (GetAndSetN mem newv));
9169 ins_cost(VOLATILE_REF_COST);
9170 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %}
9171 ins_encode %{
9172 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9173 %}
9174 ins_pipe(pipe_serial);
9175 %}
9176
9177 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{
9178 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
9179 match(Set prev (GetAndSetP mem newv));
9180 ins_cost(VOLATILE_REF_COST);
9181 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %}
9182 ins_encode %{
9183 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
9184 %}
9185 ins_pipe(pipe_serial);
9186 %}
9187
9188
9189 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{
9190 match(Set newval (GetAndAddL mem incr));
9191 ins_cost(2 * VOLATILE_REF_COST + 1);
9192 format %{ "get_and_addL $newval, [$mem], $incr" %}
9193 ins_encode %{
9194 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base));
9195 %}
9196 ins_pipe(pipe_serial);
9197 %}
9198
9199 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{
9200 predicate(n->as_LoadStore()->result_not_used());
9201 match(Set dummy (GetAndAddL mem incr));
9202 ins_cost(2 * VOLATILE_REF_COST);
9203 format %{ "get_and_addL [$mem], $incr" %}
9204 ins_encode %{
9205 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base));
9206 %}
9207 ins_pipe(pipe_serial);
9208 %}
9209
9210 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
9211 match(Set newval (GetAndAddL mem incr));
9212 ins_cost(2 * VOLATILE_REF_COST + 1);
9213 format %{ "get_and_addL $newval, [$mem], $incr" %}
9214 ins_encode %{
9215 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base));
9216 %}
9217 ins_pipe(pipe_serial);
9218 %}
9219
9220 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{
9221 predicate(n->as_LoadStore()->result_not_used());
9222 match(Set dummy (GetAndAddL mem incr));
9223 ins_cost(2 * VOLATILE_REF_COST);
9224 format %{ "get_and_addL [$mem], $incr" %}
9225 ins_encode %{
9226 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base));
9227 %}
9228 ins_pipe(pipe_serial);
9229 %}
9230
9231 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
9232 match(Set newval (GetAndAddI mem incr));
9233 ins_cost(2 * VOLATILE_REF_COST + 1);
9234 format %{ "get_and_addI $newval, [$mem], $incr" %}
9235 ins_encode %{
9236 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base));
9237 %}
9238 ins_pipe(pipe_serial);
9239 %}
9240
9241 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{
9242 predicate(n->as_LoadStore()->result_not_used());
9243 match(Set dummy (GetAndAddI mem incr));
9244 ins_cost(2 * VOLATILE_REF_COST);
9245 format %{ "get_and_addI [$mem], $incr" %}
9246 ins_encode %{
9247 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base));
9248 %}
9249 ins_pipe(pipe_serial);
9250 %}
9251
9252 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{
9253 match(Set newval (GetAndAddI mem incr));
9254 ins_cost(2 * VOLATILE_REF_COST + 1);
9255 format %{ "get_and_addI $newval, [$mem], $incr" %}
9256 ins_encode %{
9257 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base));
9258 %}
9259 ins_pipe(pipe_serial);
9260 %}
9261
9262 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{
9263 predicate(n->as_LoadStore()->result_not_used());
9264 match(Set dummy (GetAndAddI mem incr));
9265 ins_cost(2 * VOLATILE_REF_COST);
9266 format %{ "get_and_addI [$mem], $incr" %}
9267 ins_encode %{
9268 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base));
9269 %}
9270 ins_pipe(pipe_serial);
9271 %}
9272
9273 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{
9274 predicate(needs_acquiring_load_exclusive(n));
9275 match(Set newval (GetAndAddL mem incr));
9276 ins_cost(VOLATILE_REF_COST + 1);
9277 format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
9278 ins_encode %{
9279 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base));
9280 %}
9281 ins_pipe(pipe_serial);
9282 %}
9283
9284 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{
9285 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9286 match(Set dummy (GetAndAddL mem incr));
9287 ins_cost(VOLATILE_REF_COST);
9288 format %{ "get_and_addL_acq [$mem], $incr" %}
9289 ins_encode %{
9290 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base));
9291 %}
9292 ins_pipe(pipe_serial);
9293 %}
9294
9295 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
9296 predicate(needs_acquiring_load_exclusive(n));
9297 match(Set newval (GetAndAddL mem incr));
9298 ins_cost(VOLATILE_REF_COST + 1);
9299 format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
9300 ins_encode %{
9301 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base));
9302 %}
9303 ins_pipe(pipe_serial);
9304 %}
9305
9306 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{
9307 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9308 match(Set dummy (GetAndAddL mem incr));
9309 ins_cost(VOLATILE_REF_COST);
9310 format %{ "get_and_addL_acq [$mem], $incr" %}
9311 ins_encode %{
9312 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base));
9313 %}
9314 ins_pipe(pipe_serial);
9315 %}
9316
9317 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
9318 predicate(needs_acquiring_load_exclusive(n));
9319 match(Set newval (GetAndAddI mem incr));
9320 ins_cost(VOLATILE_REF_COST + 1);
9321 format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
9322 ins_encode %{
9323 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base));
9324 %}
9325 ins_pipe(pipe_serial);
9326 %}
9327
9328 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{
9329 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9330 match(Set dummy (GetAndAddI mem incr));
9331 ins_cost(VOLATILE_REF_COST);
9332 format %{ "get_and_addI_acq [$mem], $incr" %}
9333 ins_encode %{
9334 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base));
9335 %}
9336 ins_pipe(pipe_serial);
9337 %}
9338
9339 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{
9340 predicate(needs_acquiring_load_exclusive(n));
9341 match(Set newval (GetAndAddI mem incr));
9342 ins_cost(VOLATILE_REF_COST + 1);
9343 format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
9344 ins_encode %{
9345 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base));
9346 %}
9347 ins_pipe(pipe_serial);
9348 %}
9349
9350 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{
9351 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9352 match(Set dummy (GetAndAddI mem incr));
9353 ins_cost(VOLATILE_REF_COST);
9354 format %{ "get_and_addI_acq [$mem], $incr" %}
9355 ins_encode %{
9356 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base));
9357 %}
9358 ins_pipe(pipe_serial);
9359 %}
9360
9361 // Manifest a CmpU result in an integer register.
9362 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
9363 instruct cmpU3_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg flags)
9364 %{
9365 match(Set dst (CmpU3 src1 src2));
9366 effect(KILL flags);
9367
9368 ins_cost(INSN_COST * 3);
9369 format %{
9370 "cmpw $src1, $src2\n\t"
9371 "csetw $dst, ne\n\t"
9372 "cnegw $dst, lo\t# CmpU3(reg)"
9373 %}
9374 ins_encode %{
9375 __ cmpw($src1$$Register, $src2$$Register);
9376 __ csetw($dst$$Register, Assembler::NE);
9377 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
9378 %}
9379
9380 ins_pipe(pipe_class_default);
9381 %}
9382
9383 instruct cmpU3_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2, rFlagsReg flags)
9384 %{
9385 match(Set dst (CmpU3 src1 src2));
9386 effect(KILL flags);
9387
9388 ins_cost(INSN_COST * 3);
9389 format %{
9390 "subsw zr, $src1, $src2\n\t"
9391 "csetw $dst, ne\n\t"
9392 "cnegw $dst, lo\t# CmpU3(imm)"
9393 %}
9394 ins_encode %{
9395 __ subsw(zr, $src1$$Register, (int32_t)$src2$$constant);
9396 __ csetw($dst$$Register, Assembler::NE);
9397 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
9398 %}
9399
9400 ins_pipe(pipe_class_default);
9401 %}
9402
9403 // Manifest a CmpUL result in an integer register.
9404 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
9405 instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
9406 %{
9407 match(Set dst (CmpUL3 src1 src2));
9408 effect(KILL flags);
9409
9410 ins_cost(INSN_COST * 3);
9411 format %{
9412 "cmp $src1, $src2\n\t"
9413 "csetw $dst, ne\n\t"
9414 "cnegw $dst, lo\t# CmpUL3(reg)"
9415 %}
9416 ins_encode %{
9417 __ cmp($src1$$Register, $src2$$Register);
9418 __ csetw($dst$$Register, Assembler::NE);
9419 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
9420 %}
9421
9422 ins_pipe(pipe_class_default);
9423 %}
9424
9425 instruct cmpUL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags)
9426 %{
9427 match(Set dst (CmpUL3 src1 src2));
9428 effect(KILL flags);
9429
9430 ins_cost(INSN_COST * 3);
9431 format %{
9432 "subs zr, $src1, $src2\n\t"
9433 "csetw $dst, ne\n\t"
9434 "cnegw $dst, lo\t# CmpUL3(imm)"
9435 %}
9436 ins_encode %{
9437 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant);
9438 __ csetw($dst$$Register, Assembler::NE);
9439 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
9440 %}
9441
9442 ins_pipe(pipe_class_default);
9443 %}
9444
9445 // Manifest a CmpL result in an integer register.
9446 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
9447 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
9448 %{
9449 match(Set dst (CmpL3 src1 src2));
9450 effect(KILL flags);
9451
9452 ins_cost(INSN_COST * 3);
9453 format %{
9454 "cmp $src1, $src2\n\t"
9455 "csetw $dst, ne\n\t"
9456 "cnegw $dst, lt\t# CmpL3(reg)"
9457 %}
9458 ins_encode %{
9459 __ cmp($src1$$Register, $src2$$Register);
9460 __ csetw($dst$$Register, Assembler::NE);
9461 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
9462 %}
9463
9464 ins_pipe(pipe_class_default);
9465 %}
9466
9467 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags)
9468 %{
9469 match(Set dst (CmpL3 src1 src2));
9470 effect(KILL flags);
9471
9472 ins_cost(INSN_COST * 3);
9473 format %{
9474 "subs zr, $src1, $src2\n\t"
9475 "csetw $dst, ne\n\t"
9476 "cnegw $dst, lt\t# CmpL3(imm)"
9477 %}
9478 ins_encode %{
9479 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant);
9480 __ csetw($dst$$Register, Assembler::NE);
9481 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
9482 %}
9483
9484 ins_pipe(pipe_class_default);
9485 %}
9486
9487 // ============================================================================
9488 // Conditional Move Instructions
9489
9490 // n.b. we have identical rules for both a signed compare op (cmpOp)
9491 // and an unsigned compare op (cmpOpU). it would be nice if we could
9492 // define an op class which merged both inputs and use it to type the
9493 // argument to a single rule. unfortunatelyt his fails because the
9494 // opclass does not live up to the COND_INTER interface of its
9495 // component operands. When the generic code tries to negate the
9496 // operand it ends up running the generci Machoper::negate method
9497 // which throws a ShouldNotHappen. So, we have to provide two flavours
9498 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh).
9499
9500 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9501 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9502
9503 ins_cost(INSN_COST * 2);
9504 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %}
9505
9506 ins_encode %{
9507 __ cselw(as_Register($dst$$reg),
9508 as_Register($src2$$reg),
9509 as_Register($src1$$reg),
9510 (Assembler::Condition)$cmp$$cmpcode);
9511 %}
9512
9513 ins_pipe(icond_reg_reg);
9514 %}
9515
9516 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9517 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9518
9519 ins_cost(INSN_COST * 2);
9520 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %}
9521
9522 ins_encode %{
9523 __ cselw(as_Register($dst$$reg),
9524 as_Register($src2$$reg),
9525 as_Register($src1$$reg),
9526 (Assembler::Condition)$cmp$$cmpcode);
9527 %}
9528
9529 ins_pipe(icond_reg_reg);
9530 %}
9531
9532 // special cases where one arg is zero
9533
9534 // n.b. this is selected in preference to the rule above because it
9535 // avoids loading constant 0 into a source register
9536
9537 // TODO
9538 // we ought only to be able to cull one of these variants as the ideal
9539 // transforms ought always to order the zero consistently (to left/right?)
9540
9541 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
9542 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
9543
9544 ins_cost(INSN_COST * 2);
9545 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %}
9546
9547 ins_encode %{
9548 __ cselw(as_Register($dst$$reg),
9549 as_Register($src$$reg),
9550 zr,
9551 (Assembler::Condition)$cmp$$cmpcode);
9552 %}
9553
9554 ins_pipe(icond_reg);
9555 %}
9556
9557 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
9558 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
9559
9560 ins_cost(INSN_COST * 2);
9561 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %}
9562
9563 ins_encode %{
9564 __ cselw(as_Register($dst$$reg),
9565 as_Register($src$$reg),
9566 zr,
9567 (Assembler::Condition)$cmp$$cmpcode);
9568 %}
9569
9570 ins_pipe(icond_reg);
9571 %}
9572
9573 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
9574 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
9575
9576 ins_cost(INSN_COST * 2);
9577 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %}
9578
9579 ins_encode %{
9580 __ cselw(as_Register($dst$$reg),
9581 zr,
9582 as_Register($src$$reg),
9583 (Assembler::Condition)$cmp$$cmpcode);
9584 %}
9585
9586 ins_pipe(icond_reg);
9587 %}
9588
9589 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
9590 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
9591
9592 ins_cost(INSN_COST * 2);
9593 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %}
9594
9595 ins_encode %{
9596 __ cselw(as_Register($dst$$reg),
9597 zr,
9598 as_Register($src$$reg),
9599 (Assembler::Condition)$cmp$$cmpcode);
9600 %}
9601
9602 ins_pipe(icond_reg);
9603 %}
9604
9605 // special case for creating a boolean 0 or 1
9606
9607 // n.b. this is selected in preference to the rule above because it
9608 // avoids loading constants 0 and 1 into a source register
9609
9610 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
9611 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
9612
9613 ins_cost(INSN_COST * 2);
9614 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %}
9615
9616 ins_encode %{
9617 // equivalently
9618 // cset(as_Register($dst$$reg),
9619 // negate_condition((Assembler::Condition)$cmp$$cmpcode));
9620 __ csincw(as_Register($dst$$reg),
9621 zr,
9622 zr,
9623 (Assembler::Condition)$cmp$$cmpcode);
9624 %}
9625
9626 ins_pipe(icond_none);
9627 %}
9628
9629 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
9630 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
9631
9632 ins_cost(INSN_COST * 2);
9633 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %}
9634
9635 ins_encode %{
9636 // equivalently
9637 // cset(as_Register($dst$$reg),
9638 // negate_condition((Assembler::Condition)$cmp$$cmpcode));
9639 __ csincw(as_Register($dst$$reg),
9640 zr,
9641 zr,
9642 (Assembler::Condition)$cmp$$cmpcode);
9643 %}
9644
9645 ins_pipe(icond_none);
9646 %}
9647
9648 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
9649 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
9650
9651 ins_cost(INSN_COST * 2);
9652 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %}
9653
9654 ins_encode %{
9655 __ csel(as_Register($dst$$reg),
9656 as_Register($src2$$reg),
9657 as_Register($src1$$reg),
9658 (Assembler::Condition)$cmp$$cmpcode);
9659 %}
9660
9661 ins_pipe(icond_reg_reg);
9662 %}
9663
9664 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
9665 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
9666
9667 ins_cost(INSN_COST * 2);
9668 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %}
9669
9670 ins_encode %{
9671 __ csel(as_Register($dst$$reg),
9672 as_Register($src2$$reg),
9673 as_Register($src1$$reg),
9674 (Assembler::Condition)$cmp$$cmpcode);
9675 %}
9676
9677 ins_pipe(icond_reg_reg);
9678 %}
9679
9680 // special cases where one arg is zero
9681
9682 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
9683 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
9684
9685 ins_cost(INSN_COST * 2);
9686 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %}
9687
9688 ins_encode %{
9689 __ csel(as_Register($dst$$reg),
9690 zr,
9691 as_Register($src$$reg),
9692 (Assembler::Condition)$cmp$$cmpcode);
9693 %}
9694
9695 ins_pipe(icond_reg);
9696 %}
9697
9698 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
9699 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
9700
9701 ins_cost(INSN_COST * 2);
9702 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %}
9703
9704 ins_encode %{
9705 __ csel(as_Register($dst$$reg),
9706 zr,
9707 as_Register($src$$reg),
9708 (Assembler::Condition)$cmp$$cmpcode);
9709 %}
9710
9711 ins_pipe(icond_reg);
9712 %}
9713
9714 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
9715 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
9716
9717 ins_cost(INSN_COST * 2);
9718 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %}
9719
9720 ins_encode %{
9721 __ csel(as_Register($dst$$reg),
9722 as_Register($src$$reg),
9723 zr,
9724 (Assembler::Condition)$cmp$$cmpcode);
9725 %}
9726
9727 ins_pipe(icond_reg);
9728 %}
9729
9730 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
9731 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
9732
9733 ins_cost(INSN_COST * 2);
9734 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %}
9735
9736 ins_encode %{
9737 __ csel(as_Register($dst$$reg),
9738 as_Register($src$$reg),
9739 zr,
9740 (Assembler::Condition)$cmp$$cmpcode);
9741 %}
9742
9743 ins_pipe(icond_reg);
9744 %}
9745
9746 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
9747 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
9748
9749 ins_cost(INSN_COST * 2);
9750 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %}
9751
9752 ins_encode %{
9753 __ csel(as_Register($dst$$reg),
9754 as_Register($src2$$reg),
9755 as_Register($src1$$reg),
9756 (Assembler::Condition)$cmp$$cmpcode);
9757 %}
9758
9759 ins_pipe(icond_reg_reg);
9760 %}
9761
9762 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
9763 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
9764
9765 ins_cost(INSN_COST * 2);
9766 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %}
9767
9768 ins_encode %{
9769 __ csel(as_Register($dst$$reg),
9770 as_Register($src2$$reg),
9771 as_Register($src1$$reg),
9772 (Assembler::Condition)$cmp$$cmpcode);
9773 %}
9774
9775 ins_pipe(icond_reg_reg);
9776 %}
9777
9778 // special cases where one arg is zero
9779
9780 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
9781 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
9782
9783 ins_cost(INSN_COST * 2);
9784 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %}
9785
9786 ins_encode %{
9787 __ csel(as_Register($dst$$reg),
9788 zr,
9789 as_Register($src$$reg),
9790 (Assembler::Condition)$cmp$$cmpcode);
9791 %}
9792
9793 ins_pipe(icond_reg);
9794 %}
9795
9796 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
9797 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
9798
9799 ins_cost(INSN_COST * 2);
9800 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %}
9801
9802 ins_encode %{
9803 __ csel(as_Register($dst$$reg),
9804 zr,
9805 as_Register($src$$reg),
9806 (Assembler::Condition)$cmp$$cmpcode);
9807 %}
9808
9809 ins_pipe(icond_reg);
9810 %}
9811
9812 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
9813 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
9814
9815 ins_cost(INSN_COST * 2);
9816 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %}
9817
9818 ins_encode %{
9819 __ csel(as_Register($dst$$reg),
9820 as_Register($src$$reg),
9821 zr,
9822 (Assembler::Condition)$cmp$$cmpcode);
9823 %}
9824
9825 ins_pipe(icond_reg);
9826 %}
9827
9828 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
9829 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
9830
9831 ins_cost(INSN_COST * 2);
9832 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %}
9833
9834 ins_encode %{
9835 __ csel(as_Register($dst$$reg),
9836 as_Register($src$$reg),
9837 zr,
9838 (Assembler::Condition)$cmp$$cmpcode);
9839 %}
9840
9841 ins_pipe(icond_reg);
9842 %}
9843
9844 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
9845 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
9846
9847 ins_cost(INSN_COST * 2);
9848 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %}
9849
9850 ins_encode %{
9851 __ cselw(as_Register($dst$$reg),
9852 as_Register($src2$$reg),
9853 as_Register($src1$$reg),
9854 (Assembler::Condition)$cmp$$cmpcode);
9855 %}
9856
9857 ins_pipe(icond_reg_reg);
9858 %}
9859
9860 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
9861 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
9862
9863 ins_cost(INSN_COST * 2);
9864 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %}
9865
9866 ins_encode %{
9867 __ cselw(as_Register($dst$$reg),
9868 as_Register($src2$$reg),
9869 as_Register($src1$$reg),
9870 (Assembler::Condition)$cmp$$cmpcode);
9871 %}
9872
9873 ins_pipe(icond_reg_reg);
9874 %}
9875
9876 // special cases where one arg is zero
9877
9878 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
9879 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
9880
9881 ins_cost(INSN_COST * 2);
9882 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %}
9883
9884 ins_encode %{
9885 __ cselw(as_Register($dst$$reg),
9886 zr,
9887 as_Register($src$$reg),
9888 (Assembler::Condition)$cmp$$cmpcode);
9889 %}
9890
9891 ins_pipe(icond_reg);
9892 %}
9893
9894 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
9895 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
9896
9897 ins_cost(INSN_COST * 2);
9898 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %}
9899
9900 ins_encode %{
9901 __ cselw(as_Register($dst$$reg),
9902 zr,
9903 as_Register($src$$reg),
9904 (Assembler::Condition)$cmp$$cmpcode);
9905 %}
9906
9907 ins_pipe(icond_reg);
9908 %}
9909
9910 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
9911 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
9912
9913 ins_cost(INSN_COST * 2);
9914 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %}
9915
9916 ins_encode %{
9917 __ cselw(as_Register($dst$$reg),
9918 as_Register($src$$reg),
9919 zr,
9920 (Assembler::Condition)$cmp$$cmpcode);
9921 %}
9922
9923 ins_pipe(icond_reg);
9924 %}
9925
9926 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
9927 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
9928
9929 ins_cost(INSN_COST * 2);
9930 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %}
9931
9932 ins_encode %{
9933 __ cselw(as_Register($dst$$reg),
9934 as_Register($src$$reg),
9935 zr,
9936 (Assembler::Condition)$cmp$$cmpcode);
9937 %}
9938
9939 ins_pipe(icond_reg);
9940 %}
9941
9942 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2)
9943 %{
9944 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
9945
9946 ins_cost(INSN_COST * 3);
9947
9948 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
9949 ins_encode %{
9950 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9951 __ fcsels(as_FloatRegister($dst$$reg),
9952 as_FloatRegister($src2$$reg),
9953 as_FloatRegister($src1$$reg),
9954 cond);
9955 %}
9956
9957 ins_pipe(fp_cond_reg_reg_s);
9958 %}
9959
9960 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2)
9961 %{
9962 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
9963
9964 ins_cost(INSN_COST * 3);
9965
9966 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
9967 ins_encode %{
9968 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9969 __ fcsels(as_FloatRegister($dst$$reg),
9970 as_FloatRegister($src2$$reg),
9971 as_FloatRegister($src1$$reg),
9972 cond);
9973 %}
9974
9975 ins_pipe(fp_cond_reg_reg_s);
9976 %}
9977
9978 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2)
9979 %{
9980 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
9981
9982 ins_cost(INSN_COST * 3);
9983
9984 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
9985 ins_encode %{
9986 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
9987 __ fcseld(as_FloatRegister($dst$$reg),
9988 as_FloatRegister($src2$$reg),
9989 as_FloatRegister($src1$$reg),
9990 cond);
9991 %}
9992
9993 ins_pipe(fp_cond_reg_reg_d);
9994 %}
9995
9996 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2)
9997 %{
9998 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
9999
10000 ins_cost(INSN_COST * 3);
10001
10002 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
10003 ins_encode %{
10004 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
10005 __ fcseld(as_FloatRegister($dst$$reg),
10006 as_FloatRegister($src2$$reg),
10007 as_FloatRegister($src1$$reg),
10008 cond);
10009 %}
10010
10011 ins_pipe(fp_cond_reg_reg_d);
10012 %}
10013
10014 // ============================================================================
10015 // Arithmetic Instructions
10016 //
10017
10018 // Integer Addition
10019
10020 // TODO
10021 // these currently employ operations which do not set CR and hence are
10022 // not flagged as killing CR but we would like to isolate the cases
10023 // where we want to set flags from those where we don't. need to work
10024 // out how to do that.
10025
10026 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10027 match(Set dst (AddI src1 src2));
10028
10029 ins_cost(INSN_COST);
10030 format %{ "addw $dst, $src1, $src2" %}
10031
10032 ins_encode %{
10033 __ addw(as_Register($dst$$reg),
10034 as_Register($src1$$reg),
10035 as_Register($src2$$reg));
10036 %}
10037
10038 ins_pipe(ialu_reg_reg);
10039 %}
10040
10041 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
10042 match(Set dst (AddI src1 src2));
10043
10044 ins_cost(INSN_COST);
10045 format %{ "addw $dst, $src1, $src2" %}
10046
10047 // use opcode to indicate that this is an add not a sub
10048 opcode(0x0);
10049
10050 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
10051
10052 ins_pipe(ialu_reg_imm);
10053 %}
10054
10055 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{
10056 match(Set dst (AddI (ConvL2I src1) src2));
10057
10058 ins_cost(INSN_COST);
10059 format %{ "addw $dst, $src1, $src2" %}
10060
10061 // use opcode to indicate that this is an add not a sub
10062 opcode(0x0);
10063
10064 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
10065
10066 ins_pipe(ialu_reg_imm);
10067 %}
10068
10069 // Pointer Addition
10070 instruct addP_reg_reg(iRegPNoSp dst, iRegPorL2P src1, iRegL src2) %{
10071 match(Set dst (AddP src1 src2));
10072
10073 ins_cost(INSN_COST);
10074 format %{ "add $dst, $src1, $src2\t# ptr" %}
10075
10076 ins_encode %{
10077 __ add(as_Register($dst$$reg),
10078 as_Register($src1$$reg),
10079 as_Register($src2$$reg));
10080 %}
10081
10082 ins_pipe(ialu_reg_reg);
10083 %}
10084
10085 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegPorL2P src1, iRegIorL2I src2) %{
10086 match(Set dst (AddP src1 (ConvI2L src2)));
10087
10088 ins_cost(1.9 * INSN_COST);
10089 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %}
10090
10091 ins_encode %{
10092 __ add(as_Register($dst$$reg),
10093 as_Register($src1$$reg),
10094 as_Register($src2$$reg), ext::sxtw);
10095 %}
10096
10097 ins_pipe(ialu_reg_reg);
10098 %}
10099
10100 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegPorL2P src1, iRegL src2, immIScale scale) %{
10101 match(Set dst (AddP src1 (LShiftL src2 scale)));
10102
10103 ins_cost(1.9 * INSN_COST);
10104 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %}
10105
10106 ins_encode %{
10107 __ lea(as_Register($dst$$reg),
10108 Address(as_Register($src1$$reg), as_Register($src2$$reg),
10109 Address::lsl($scale$$constant)));
10110 %}
10111
10112 ins_pipe(ialu_reg_reg_shift);
10113 %}
10114
10115 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegPorL2P src1, iRegIorL2I src2, immIScale scale) %{
10116 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale)));
10117
10118 ins_cost(1.9 * INSN_COST);
10119 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %}
10120
10121 ins_encode %{
10122 __ lea(as_Register($dst$$reg),
10123 Address(as_Register($src1$$reg), as_Register($src2$$reg),
10124 Address::sxtw($scale$$constant)));
10125 %}
10126
10127 ins_pipe(ialu_reg_reg_shift);
10128 %}
10129
10130 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{
10131 match(Set dst (LShiftL (ConvI2L src) scale));
10132
10133 ins_cost(INSN_COST);
10134 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %}
10135
10136 ins_encode %{
10137 __ sbfiz(as_Register($dst$$reg),
10138 as_Register($src$$reg),
10139 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63)));
10140 %}
10141
10142 ins_pipe(ialu_reg_shift);
10143 %}
10144
10145 // Pointer Immediate Addition
10146 // n.b. this needs to be more expensive than using an indirect memory
10147 // operand
10148 instruct addP_reg_imm(iRegPNoSp dst, iRegPorL2P src1, immLAddSub src2) %{
10149 match(Set dst (AddP src1 src2));
10150
10151 ins_cost(INSN_COST);
10152 format %{ "add $dst, $src1, $src2\t# ptr" %}
10153
10154 // use opcode to indicate that this is an add not a sub
10155 opcode(0x0);
10156
10157 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
10158
10159 ins_pipe(ialu_reg_imm);
10160 %}
10161
10162 // Long Addition
10163 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10164
10165 match(Set dst (AddL src1 src2));
10166
10167 ins_cost(INSN_COST);
10168 format %{ "add $dst, $src1, $src2" %}
10169
10170 ins_encode %{
10171 __ add(as_Register($dst$$reg),
10172 as_Register($src1$$reg),
10173 as_Register($src2$$reg));
10174 %}
10175
10176 ins_pipe(ialu_reg_reg);
10177 %}
10178
10179 // No constant pool entries requiredLong Immediate Addition.
10180 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
10181 match(Set dst (AddL src1 src2));
10182
10183 ins_cost(INSN_COST);
10184 format %{ "add $dst, $src1, $src2" %}
10185
10186 // use opcode to indicate that this is an add not a sub
10187 opcode(0x0);
10188
10189 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
10190
10191 ins_pipe(ialu_reg_imm);
10192 %}
10193
10194 // Integer Subtraction
10195 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10196 match(Set dst (SubI src1 src2));
10197
10198 ins_cost(INSN_COST);
10199 format %{ "subw $dst, $src1, $src2" %}
10200
10201 ins_encode %{
10202 __ subw(as_Register($dst$$reg),
10203 as_Register($src1$$reg),
10204 as_Register($src2$$reg));
10205 %}
10206
10207 ins_pipe(ialu_reg_reg);
10208 %}
10209
10210 // Immediate Subtraction
10211 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
10212 match(Set dst (SubI src1 src2));
10213
10214 ins_cost(INSN_COST);
10215 format %{ "subw $dst, $src1, $src2" %}
10216
10217 // use opcode to indicate that this is a sub not an add
10218 opcode(0x1);
10219
10220 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
10221
10222 ins_pipe(ialu_reg_imm);
10223 %}
10224
10225 // Long Subtraction
10226 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10227
10228 match(Set dst (SubL src1 src2));
10229
10230 ins_cost(INSN_COST);
10231 format %{ "sub $dst, $src1, $src2" %}
10232
10233 ins_encode %{
10234 __ sub(as_Register($dst$$reg),
10235 as_Register($src1$$reg),
10236 as_Register($src2$$reg));
10237 %}
10238
10239 ins_pipe(ialu_reg_reg);
10240 %}
10241
10242 // No constant pool entries requiredLong Immediate Subtraction.
10243 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
10244 match(Set dst (SubL src1 src2));
10245
10246 ins_cost(INSN_COST);
10247 format %{ "sub$dst, $src1, $src2" %}
10248
10249 // use opcode to indicate that this is a sub not an add
10250 opcode(0x1);
10251
10252 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
10253
10254 ins_pipe(ialu_reg_imm);
10255 %}
10256
10257 // Integer Negation (special case for sub)
10258
10259 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{
10260 match(Set dst (SubI zero src));
10261
10262 ins_cost(INSN_COST);
10263 format %{ "negw $dst, $src\t# int" %}
10264
10265 ins_encode %{
10266 __ negw(as_Register($dst$$reg),
10267 as_Register($src$$reg));
10268 %}
10269
10270 ins_pipe(ialu_reg);
10271 %}
10272
10273 // Long Negation
10274
10275 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{
10276 match(Set dst (SubL zero src));
10277
10278 ins_cost(INSN_COST);
10279 format %{ "neg $dst, $src\t# long" %}
10280
10281 ins_encode %{
10282 __ neg(as_Register($dst$$reg),
10283 as_Register($src$$reg));
10284 %}
10285
10286 ins_pipe(ialu_reg);
10287 %}
10288
10289 // Integer Multiply
10290
10291 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10292 match(Set dst (MulI src1 src2));
10293
10294 ins_cost(INSN_COST * 3);
10295 format %{ "mulw $dst, $src1, $src2" %}
10296
10297 ins_encode %{
10298 __ mulw(as_Register($dst$$reg),
10299 as_Register($src1$$reg),
10300 as_Register($src2$$reg));
10301 %}
10302
10303 ins_pipe(imul_reg_reg);
10304 %}
10305
10306 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10307 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2)));
10308
10309 ins_cost(INSN_COST * 3);
10310 format %{ "smull $dst, $src1, $src2" %}
10311
10312 ins_encode %{
10313 __ smull(as_Register($dst$$reg),
10314 as_Register($src1$$reg),
10315 as_Register($src2$$reg));
10316 %}
10317
10318 ins_pipe(imul_reg_reg);
10319 %}
10320
10321 // Long Multiply
10322
10323 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10324 match(Set dst (MulL src1 src2));
10325
10326 ins_cost(INSN_COST * 5);
10327 format %{ "mul $dst, $src1, $src2" %}
10328
10329 ins_encode %{
10330 __ mul(as_Register($dst$$reg),
10331 as_Register($src1$$reg),
10332 as_Register($src2$$reg));
10333 %}
10334
10335 ins_pipe(lmul_reg_reg);
10336 %}
10337
10338 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr)
10339 %{
10340 match(Set dst (MulHiL src1 src2));
10341
10342 ins_cost(INSN_COST * 7);
10343 format %{ "smulh $dst, $src1, $src2\t# mulhi" %}
10344
10345 ins_encode %{
10346 __ smulh(as_Register($dst$$reg),
10347 as_Register($src1$$reg),
10348 as_Register($src2$$reg));
10349 %}
10350
10351 ins_pipe(lmul_reg_reg);
10352 %}
10353
10354 instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr)
10355 %{
10356 match(Set dst (UMulHiL src1 src2));
10357
10358 ins_cost(INSN_COST * 7);
10359 format %{ "umulh $dst, $src1, $src2\t# umulhi" %}
10360
10361 ins_encode %{
10362 __ umulh(as_Register($dst$$reg),
10363 as_Register($src1$$reg),
10364 as_Register($src2$$reg));
10365 %}
10366
10367 ins_pipe(lmul_reg_reg);
10368 %}
10369
10370 // Combined Integer Multiply & Add/Sub
10371
10372 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
10373 match(Set dst (AddI src3 (MulI src1 src2)));
10374
10375 ins_cost(INSN_COST * 3);
10376 format %{ "madd $dst, $src1, $src2, $src3" %}
10377
10378 ins_encode %{
10379 __ maddw(as_Register($dst$$reg),
10380 as_Register($src1$$reg),
10381 as_Register($src2$$reg),
10382 as_Register($src3$$reg));
10383 %}
10384
10385 ins_pipe(imac_reg_reg);
10386 %}
10387
10388 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
10389 match(Set dst (SubI src3 (MulI src1 src2)));
10390
10391 ins_cost(INSN_COST * 3);
10392 format %{ "msub $dst, $src1, $src2, $src3" %}
10393
10394 ins_encode %{
10395 __ msubw(as_Register($dst$$reg),
10396 as_Register($src1$$reg),
10397 as_Register($src2$$reg),
10398 as_Register($src3$$reg));
10399 %}
10400
10401 ins_pipe(imac_reg_reg);
10402 %}
10403
10404 // Combined Integer Multiply & Neg
10405
10406 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{
10407 match(Set dst (MulI (SubI zero src1) src2));
10408
10409 ins_cost(INSN_COST * 3);
10410 format %{ "mneg $dst, $src1, $src2" %}
10411
10412 ins_encode %{
10413 __ mnegw(as_Register($dst$$reg),
10414 as_Register($src1$$reg),
10415 as_Register($src2$$reg));
10416 %}
10417
10418 ins_pipe(imac_reg_reg);
10419 %}
10420
10421 // Combined Long Multiply & Add/Sub
10422
10423 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
10424 match(Set dst (AddL src3 (MulL src1 src2)));
10425
10426 ins_cost(INSN_COST * 5);
10427 format %{ "madd $dst, $src1, $src2, $src3" %}
10428
10429 ins_encode %{
10430 __ madd(as_Register($dst$$reg),
10431 as_Register($src1$$reg),
10432 as_Register($src2$$reg),
10433 as_Register($src3$$reg));
10434 %}
10435
10436 ins_pipe(lmac_reg_reg);
10437 %}
10438
10439 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
10440 match(Set dst (SubL src3 (MulL src1 src2)));
10441
10442 ins_cost(INSN_COST * 5);
10443 format %{ "msub $dst, $src1, $src2, $src3" %}
10444
10445 ins_encode %{
10446 __ msub(as_Register($dst$$reg),
10447 as_Register($src1$$reg),
10448 as_Register($src2$$reg),
10449 as_Register($src3$$reg));
10450 %}
10451
10452 ins_pipe(lmac_reg_reg);
10453 %}
10454
10455 // Combined Long Multiply & Neg
10456
10457 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{
10458 match(Set dst (MulL (SubL zero src1) src2));
10459
10460 ins_cost(INSN_COST * 5);
10461 format %{ "mneg $dst, $src1, $src2" %}
10462
10463 ins_encode %{
10464 __ mneg(as_Register($dst$$reg),
10465 as_Register($src1$$reg),
10466 as_Register($src2$$reg));
10467 %}
10468
10469 ins_pipe(lmac_reg_reg);
10470 %}
10471
10472 // Combine Integer Signed Multiply & Add/Sub/Neg Long
10473
10474 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{
10475 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2))));
10476
10477 ins_cost(INSN_COST * 3);
10478 format %{ "smaddl $dst, $src1, $src2, $src3" %}
10479
10480 ins_encode %{
10481 __ smaddl(as_Register($dst$$reg),
10482 as_Register($src1$$reg),
10483 as_Register($src2$$reg),
10484 as_Register($src3$$reg));
10485 %}
10486
10487 ins_pipe(imac_reg_reg);
10488 %}
10489
10490 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{
10491 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2))));
10492
10493 ins_cost(INSN_COST * 3);
10494 format %{ "smsubl $dst, $src1, $src2, $src3" %}
10495
10496 ins_encode %{
10497 __ smsubl(as_Register($dst$$reg),
10498 as_Register($src1$$reg),
10499 as_Register($src2$$reg),
10500 as_Register($src3$$reg));
10501 %}
10502
10503 ins_pipe(imac_reg_reg);
10504 %}
10505
10506 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{
10507 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2)));
10508
10509 ins_cost(INSN_COST * 3);
10510 format %{ "smnegl $dst, $src1, $src2" %}
10511
10512 ins_encode %{
10513 __ smnegl(as_Register($dst$$reg),
10514 as_Register($src1$$reg),
10515 as_Register($src2$$reg));
10516 %}
10517
10518 ins_pipe(imac_reg_reg);
10519 %}
10520
10521 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4)
10522
10523 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{
10524 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4)));
10525
10526 ins_cost(INSN_COST * 5);
10527 format %{ "mulw rscratch1, $src1, $src2\n\t"
10528 "maddw $dst, $src3, $src4, rscratch1" %}
10529
10530 ins_encode %{
10531 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg));
10532 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %}
10533
10534 ins_pipe(imac_reg_reg);
10535 %}
10536
10537 // Integer Divide
10538
10539 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10540 match(Set dst (DivI src1 src2));
10541
10542 ins_cost(INSN_COST * 19);
10543 format %{ "sdivw $dst, $src1, $src2" %}
10544
10545 ins_encode(aarch64_enc_divw(dst, src1, src2));
10546 ins_pipe(idiv_reg_reg);
10547 %}
10548
10549 // Long Divide
10550
10551 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10552 match(Set dst (DivL src1 src2));
10553
10554 ins_cost(INSN_COST * 35);
10555 format %{ "sdiv $dst, $src1, $src2" %}
10556
10557 ins_encode(aarch64_enc_div(dst, src1, src2));
10558 ins_pipe(ldiv_reg_reg);
10559 %}
10560
10561 // Integer Remainder
10562
10563 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10564 match(Set dst (ModI src1 src2));
10565
10566 ins_cost(INSN_COST * 22);
10567 format %{ "sdivw rscratch1, $src1, $src2\n\t"
10568 "msubw $dst, rscratch1, $src2, $src1" %}
10569
10570 ins_encode(aarch64_enc_modw(dst, src1, src2));
10571 ins_pipe(idiv_reg_reg);
10572 %}
10573
10574 // Long Remainder
10575
10576 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10577 match(Set dst (ModL src1 src2));
10578
10579 ins_cost(INSN_COST * 38);
10580 format %{ "sdiv rscratch1, $src1, $src2\n"
10581 "msub $dst, rscratch1, $src2, $src1" %}
10582
10583 ins_encode(aarch64_enc_mod(dst, src1, src2));
10584 ins_pipe(ldiv_reg_reg);
10585 %}
10586
10587 // Unsigned Integer Divide
10588
10589 instruct UdivI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10590 match(Set dst (UDivI src1 src2));
10591
10592 ins_cost(INSN_COST * 19);
10593 format %{ "udivw $dst, $src1, $src2" %}
10594
10595 ins_encode %{
10596 __ udivw($dst$$Register, $src1$$Register, $src2$$Register);
10597 %}
10598
10599 ins_pipe(idiv_reg_reg);
10600 %}
10601
10602 // Unsigned Long Divide
10603
10604 instruct UdivL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10605 match(Set dst (UDivL src1 src2));
10606
10607 ins_cost(INSN_COST * 35);
10608 format %{ "udiv $dst, $src1, $src2" %}
10609
10610 ins_encode %{
10611 __ udiv($dst$$Register, $src1$$Register, $src2$$Register);
10612 %}
10613
10614 ins_pipe(ldiv_reg_reg);
10615 %}
10616
10617 // Unsigned Integer Remainder
10618
10619 instruct UmodI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10620 match(Set dst (UModI src1 src2));
10621
10622 ins_cost(INSN_COST * 22);
10623 format %{ "udivw rscratch1, $src1, $src2\n\t"
10624 "msubw $dst, rscratch1, $src2, $src1" %}
10625
10626 ins_encode %{
10627 __ udivw(rscratch1, $src1$$Register, $src2$$Register);
10628 __ msubw($dst$$Register, rscratch1, $src2$$Register, $src1$$Register);
10629 %}
10630
10631 ins_pipe(idiv_reg_reg);
10632 %}
10633
10634 // Unsigned Long Remainder
10635
10636 instruct UModL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10637 match(Set dst (UModL src1 src2));
10638
10639 ins_cost(INSN_COST * 38);
10640 format %{ "udiv rscratch1, $src1, $src2\n"
10641 "msub $dst, rscratch1, $src2, $src1" %}
10642
10643 ins_encode %{
10644 __ udiv(rscratch1, $src1$$Register, $src2$$Register);
10645 __ msub($dst$$Register, rscratch1, $src2$$Register, $src1$$Register);
10646 %}
10647
10648 ins_pipe(ldiv_reg_reg);
10649 %}
10650
10651 // Integer Shifts
10652
10653 // Shift Left Register
10654 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10655 match(Set dst (LShiftI src1 src2));
10656
10657 ins_cost(INSN_COST * 2);
10658 format %{ "lslvw $dst, $src1, $src2" %}
10659
10660 ins_encode %{
10661 __ lslvw(as_Register($dst$$reg),
10662 as_Register($src1$$reg),
10663 as_Register($src2$$reg));
10664 %}
10665
10666 ins_pipe(ialu_reg_reg_vshift);
10667 %}
10668
10669 // Shift Left Immediate
10670 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10671 match(Set dst (LShiftI src1 src2));
10672
10673 ins_cost(INSN_COST);
10674 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %}
10675
10676 ins_encode %{
10677 __ lslw(as_Register($dst$$reg),
10678 as_Register($src1$$reg),
10679 $src2$$constant & 0x1f);
10680 %}
10681
10682 ins_pipe(ialu_reg_shift);
10683 %}
10684
10685 // Shift Right Logical Register
10686 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10687 match(Set dst (URShiftI src1 src2));
10688
10689 ins_cost(INSN_COST * 2);
10690 format %{ "lsrvw $dst, $src1, $src2" %}
10691
10692 ins_encode %{
10693 __ lsrvw(as_Register($dst$$reg),
10694 as_Register($src1$$reg),
10695 as_Register($src2$$reg));
10696 %}
10697
10698 ins_pipe(ialu_reg_reg_vshift);
10699 %}
10700
10701 // Shift Right Logical Immediate
10702 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10703 match(Set dst (URShiftI src1 src2));
10704
10705 ins_cost(INSN_COST);
10706 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %}
10707
10708 ins_encode %{
10709 __ lsrw(as_Register($dst$$reg),
10710 as_Register($src1$$reg),
10711 $src2$$constant & 0x1f);
10712 %}
10713
10714 ins_pipe(ialu_reg_shift);
10715 %}
10716
10717 // Shift Right Arithmetic Register
10718 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10719 match(Set dst (RShiftI src1 src2));
10720
10721 ins_cost(INSN_COST * 2);
10722 format %{ "asrvw $dst, $src1, $src2" %}
10723
10724 ins_encode %{
10725 __ asrvw(as_Register($dst$$reg),
10726 as_Register($src1$$reg),
10727 as_Register($src2$$reg));
10728 %}
10729
10730 ins_pipe(ialu_reg_reg_vshift);
10731 %}
10732
10733 // Shift Right Arithmetic Immediate
10734 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10735 match(Set dst (RShiftI src1 src2));
10736
10737 ins_cost(INSN_COST);
10738 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %}
10739
10740 ins_encode %{
10741 __ asrw(as_Register($dst$$reg),
10742 as_Register($src1$$reg),
10743 $src2$$constant & 0x1f);
10744 %}
10745
10746 ins_pipe(ialu_reg_shift);
10747 %}
10748
10749 // Combined Int Mask and Right Shift (using UBFM)
10750 // TODO
10751
10752 // Long Shifts
10753
10754 // Shift Left Register
10755 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10756 match(Set dst (LShiftL src1 src2));
10757
10758 ins_cost(INSN_COST * 2);
10759 format %{ "lslv $dst, $src1, $src2" %}
10760
10761 ins_encode %{
10762 __ lslv(as_Register($dst$$reg),
10763 as_Register($src1$$reg),
10764 as_Register($src2$$reg));
10765 %}
10766
10767 ins_pipe(ialu_reg_reg_vshift);
10768 %}
10769
10770 // Shift Left Immediate
10771 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10772 match(Set dst (LShiftL src1 src2));
10773
10774 ins_cost(INSN_COST);
10775 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %}
10776
10777 ins_encode %{
10778 __ lsl(as_Register($dst$$reg),
10779 as_Register($src1$$reg),
10780 $src2$$constant & 0x3f);
10781 %}
10782
10783 ins_pipe(ialu_reg_shift);
10784 %}
10785
10786 // Shift Right Logical Register
10787 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10788 match(Set dst (URShiftL src1 src2));
10789
10790 ins_cost(INSN_COST * 2);
10791 format %{ "lsrv $dst, $src1, $src2" %}
10792
10793 ins_encode %{
10794 __ lsrv(as_Register($dst$$reg),
10795 as_Register($src1$$reg),
10796 as_Register($src2$$reg));
10797 %}
10798
10799 ins_pipe(ialu_reg_reg_vshift);
10800 %}
10801
10802 // Shift Right Logical Immediate
10803 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10804 match(Set dst (URShiftL src1 src2));
10805
10806 ins_cost(INSN_COST);
10807 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %}
10808
10809 ins_encode %{
10810 __ lsr(as_Register($dst$$reg),
10811 as_Register($src1$$reg),
10812 $src2$$constant & 0x3f);
10813 %}
10814
10815 ins_pipe(ialu_reg_shift);
10816 %}
10817
10818 // A special-case pattern for card table stores.
10819 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{
10820 match(Set dst (URShiftL (CastP2X src1) src2));
10821
10822 ins_cost(INSN_COST);
10823 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %}
10824
10825 ins_encode %{
10826 __ lsr(as_Register($dst$$reg),
10827 as_Register($src1$$reg),
10828 $src2$$constant & 0x3f);
10829 %}
10830
10831 ins_pipe(ialu_reg_shift);
10832 %}
10833
10834 // Shift Right Arithmetic Register
10835 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10836 match(Set dst (RShiftL src1 src2));
10837
10838 ins_cost(INSN_COST * 2);
10839 format %{ "asrv $dst, $src1, $src2" %}
10840
10841 ins_encode %{
10842 __ asrv(as_Register($dst$$reg),
10843 as_Register($src1$$reg),
10844 as_Register($src2$$reg));
10845 %}
10846
10847 ins_pipe(ialu_reg_reg_vshift);
10848 %}
10849
10850 // Shift Right Arithmetic Immediate
10851 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10852 match(Set dst (RShiftL src1 src2));
10853
10854 ins_cost(INSN_COST);
10855 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %}
10856
10857 ins_encode %{
10858 __ asr(as_Register($dst$$reg),
10859 as_Register($src1$$reg),
10860 $src2$$constant & 0x3f);
10861 %}
10862
10863 ins_pipe(ialu_reg_shift);
10864 %}
10865
10866 // BEGIN This section of the file is automatically generated. Do not edit --------------
10867 // This section is generated from aarch64_ad.m4
10868
10869 // This pattern is automatically generated from aarch64_ad.m4
10870 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10871 instruct regL_not_reg(iRegLNoSp dst,
10872 iRegL src1, immL_M1 m1,
10873 rFlagsReg cr) %{
10874 match(Set dst (XorL src1 m1));
10875 ins_cost(INSN_COST);
10876 format %{ "eon $dst, $src1, zr" %}
10877
10878 ins_encode %{
10879 __ eon(as_Register($dst$$reg),
10880 as_Register($src1$$reg),
10881 zr,
10882 Assembler::LSL, 0);
10883 %}
10884
10885 ins_pipe(ialu_reg);
10886 %}
10887
10888 // This pattern is automatically generated from aarch64_ad.m4
10889 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10890 instruct regI_not_reg(iRegINoSp dst,
10891 iRegIorL2I src1, immI_M1 m1,
10892 rFlagsReg cr) %{
10893 match(Set dst (XorI src1 m1));
10894 ins_cost(INSN_COST);
10895 format %{ "eonw $dst, $src1, zr" %}
10896
10897 ins_encode %{
10898 __ eonw(as_Register($dst$$reg),
10899 as_Register($src1$$reg),
10900 zr,
10901 Assembler::LSL, 0);
10902 %}
10903
10904 ins_pipe(ialu_reg);
10905 %}
10906
10907 // This pattern is automatically generated from aarch64_ad.m4
10908 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10909 instruct NegI_reg_URShift_reg(iRegINoSp dst,
10910 immI0 zero, iRegIorL2I src1, immI src2) %{
10911 match(Set dst (SubI zero (URShiftI src1 src2)));
10912
10913 ins_cost(1.9 * INSN_COST);
10914 format %{ "negw $dst, $src1, LSR $src2" %}
10915
10916 ins_encode %{
10917 __ negw(as_Register($dst$$reg), as_Register($src1$$reg),
10918 Assembler::LSR, $src2$$constant & 0x1f);
10919 %}
10920
10921 ins_pipe(ialu_reg_shift);
10922 %}
10923
10924 // This pattern is automatically generated from aarch64_ad.m4
10925 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10926 instruct NegI_reg_RShift_reg(iRegINoSp dst,
10927 immI0 zero, iRegIorL2I src1, immI src2) %{
10928 match(Set dst (SubI zero (RShiftI src1 src2)));
10929
10930 ins_cost(1.9 * INSN_COST);
10931 format %{ "negw $dst, $src1, ASR $src2" %}
10932
10933 ins_encode %{
10934 __ negw(as_Register($dst$$reg), as_Register($src1$$reg),
10935 Assembler::ASR, $src2$$constant & 0x1f);
10936 %}
10937
10938 ins_pipe(ialu_reg_shift);
10939 %}
10940
10941 // This pattern is automatically generated from aarch64_ad.m4
10942 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10943 instruct NegI_reg_LShift_reg(iRegINoSp dst,
10944 immI0 zero, iRegIorL2I src1, immI src2) %{
10945 match(Set dst (SubI zero (LShiftI src1 src2)));
10946
10947 ins_cost(1.9 * INSN_COST);
10948 format %{ "negw $dst, $src1, LSL $src2" %}
10949
10950 ins_encode %{
10951 __ negw(as_Register($dst$$reg), as_Register($src1$$reg),
10952 Assembler::LSL, $src2$$constant & 0x1f);
10953 %}
10954
10955 ins_pipe(ialu_reg_shift);
10956 %}
10957
10958 // This pattern is automatically generated from aarch64_ad.m4
10959 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10960 instruct NegL_reg_URShift_reg(iRegLNoSp dst,
10961 immL0 zero, iRegL src1, immI src2) %{
10962 match(Set dst (SubL zero (URShiftL src1 src2)));
10963
10964 ins_cost(1.9 * INSN_COST);
10965 format %{ "neg $dst, $src1, LSR $src2" %}
10966
10967 ins_encode %{
10968 __ neg(as_Register($dst$$reg), as_Register($src1$$reg),
10969 Assembler::LSR, $src2$$constant & 0x3f);
10970 %}
10971
10972 ins_pipe(ialu_reg_shift);
10973 %}
10974
10975 // This pattern is automatically generated from aarch64_ad.m4
10976 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10977 instruct NegL_reg_RShift_reg(iRegLNoSp dst,
10978 immL0 zero, iRegL src1, immI src2) %{
10979 match(Set dst (SubL zero (RShiftL src1 src2)));
10980
10981 ins_cost(1.9 * INSN_COST);
10982 format %{ "neg $dst, $src1, ASR $src2" %}
10983
10984 ins_encode %{
10985 __ neg(as_Register($dst$$reg), as_Register($src1$$reg),
10986 Assembler::ASR, $src2$$constant & 0x3f);
10987 %}
10988
10989 ins_pipe(ialu_reg_shift);
10990 %}
10991
10992 // This pattern is automatically generated from aarch64_ad.m4
10993 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10994 instruct NegL_reg_LShift_reg(iRegLNoSp dst,
10995 immL0 zero, iRegL src1, immI src2) %{
10996 match(Set dst (SubL zero (LShiftL src1 src2)));
10997
10998 ins_cost(1.9 * INSN_COST);
10999 format %{ "neg $dst, $src1, LSL $src2" %}
11000
11001 ins_encode %{
11002 __ neg(as_Register($dst$$reg), as_Register($src1$$reg),
11003 Assembler::LSL, $src2$$constant & 0x3f);
11004 %}
11005
11006 ins_pipe(ialu_reg_shift);
11007 %}
11008
11009 // This pattern is automatically generated from aarch64_ad.m4
11010 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11011 instruct AndI_reg_not_reg(iRegINoSp dst,
11012 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{
11013 match(Set dst (AndI src1 (XorI src2 m1)));
11014 ins_cost(INSN_COST);
11015 format %{ "bicw $dst, $src1, $src2" %}
11016
11017 ins_encode %{
11018 __ bicw(as_Register($dst$$reg),
11019 as_Register($src1$$reg),
11020 as_Register($src2$$reg),
11021 Assembler::LSL, 0);
11022 %}
11023
11024 ins_pipe(ialu_reg_reg);
11025 %}
11026
11027 // This pattern is automatically generated from aarch64_ad.m4
11028 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11029 instruct AndL_reg_not_reg(iRegLNoSp dst,
11030 iRegL src1, iRegL src2, immL_M1 m1) %{
11031 match(Set dst (AndL src1 (XorL src2 m1)));
11032 ins_cost(INSN_COST);
11033 format %{ "bic $dst, $src1, $src2" %}
11034
11035 ins_encode %{
11036 __ bic(as_Register($dst$$reg),
11037 as_Register($src1$$reg),
11038 as_Register($src2$$reg),
11039 Assembler::LSL, 0);
11040 %}
11041
11042 ins_pipe(ialu_reg_reg);
11043 %}
11044
11045 // This pattern is automatically generated from aarch64_ad.m4
11046 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11047 instruct OrI_reg_not_reg(iRegINoSp dst,
11048 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{
11049 match(Set dst (OrI src1 (XorI src2 m1)));
11050 ins_cost(INSN_COST);
11051 format %{ "ornw $dst, $src1, $src2" %}
11052
11053 ins_encode %{
11054 __ ornw(as_Register($dst$$reg),
11055 as_Register($src1$$reg),
11056 as_Register($src2$$reg),
11057 Assembler::LSL, 0);
11058 %}
11059
11060 ins_pipe(ialu_reg_reg);
11061 %}
11062
11063 // This pattern is automatically generated from aarch64_ad.m4
11064 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11065 instruct OrL_reg_not_reg(iRegLNoSp dst,
11066 iRegL src1, iRegL src2, immL_M1 m1) %{
11067 match(Set dst (OrL src1 (XorL src2 m1)));
11068 ins_cost(INSN_COST);
11069 format %{ "orn $dst, $src1, $src2" %}
11070
11071 ins_encode %{
11072 __ orn(as_Register($dst$$reg),
11073 as_Register($src1$$reg),
11074 as_Register($src2$$reg),
11075 Assembler::LSL, 0);
11076 %}
11077
11078 ins_pipe(ialu_reg_reg);
11079 %}
11080
11081 // This pattern is automatically generated from aarch64_ad.m4
11082 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11083 instruct XorI_reg_not_reg(iRegINoSp dst,
11084 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{
11085 match(Set dst (XorI m1 (XorI src2 src1)));
11086 ins_cost(INSN_COST);
11087 format %{ "eonw $dst, $src1, $src2" %}
11088
11089 ins_encode %{
11090 __ eonw(as_Register($dst$$reg),
11091 as_Register($src1$$reg),
11092 as_Register($src2$$reg),
11093 Assembler::LSL, 0);
11094 %}
11095
11096 ins_pipe(ialu_reg_reg);
11097 %}
11098
11099 // This pattern is automatically generated from aarch64_ad.m4
11100 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11101 instruct XorL_reg_not_reg(iRegLNoSp dst,
11102 iRegL src1, iRegL src2, immL_M1 m1) %{
11103 match(Set dst (XorL m1 (XorL src2 src1)));
11104 ins_cost(INSN_COST);
11105 format %{ "eon $dst, $src1, $src2" %}
11106
11107 ins_encode %{
11108 __ eon(as_Register($dst$$reg),
11109 as_Register($src1$$reg),
11110 as_Register($src2$$reg),
11111 Assembler::LSL, 0);
11112 %}
11113
11114 ins_pipe(ialu_reg_reg);
11115 %}
11116
11117 // This pattern is automatically generated from aarch64_ad.m4
11118 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11119 // val & (-1 ^ (val >>> shift)) ==> bicw
11120 instruct AndI_reg_URShift_not_reg(iRegINoSp dst,
11121 iRegIorL2I src1, iRegIorL2I src2,
11122 immI src3, immI_M1 src4) %{
11123 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4)));
11124 ins_cost(1.9 * INSN_COST);
11125 format %{ "bicw $dst, $src1, $src2, LSR $src3" %}
11126
11127 ins_encode %{
11128 __ bicw(as_Register($dst$$reg),
11129 as_Register($src1$$reg),
11130 as_Register($src2$$reg),
11131 Assembler::LSR,
11132 $src3$$constant & 0x1f);
11133 %}
11134
11135 ins_pipe(ialu_reg_reg_shift);
11136 %}
11137
11138 // This pattern is automatically generated from aarch64_ad.m4
11139 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11140 // val & (-1 ^ (val >>> shift)) ==> bic
11141 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst,
11142 iRegL src1, iRegL src2,
11143 immI src3, immL_M1 src4) %{
11144 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4)));
11145 ins_cost(1.9 * INSN_COST);
11146 format %{ "bic $dst, $src1, $src2, LSR $src3" %}
11147
11148 ins_encode %{
11149 __ bic(as_Register($dst$$reg),
11150 as_Register($src1$$reg),
11151 as_Register($src2$$reg),
11152 Assembler::LSR,
11153 $src3$$constant & 0x3f);
11154 %}
11155
11156 ins_pipe(ialu_reg_reg_shift);
11157 %}
11158
11159 // This pattern is automatically generated from aarch64_ad.m4
11160 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11161 // val & (-1 ^ (val >> shift)) ==> bicw
11162 instruct AndI_reg_RShift_not_reg(iRegINoSp dst,
11163 iRegIorL2I src1, iRegIorL2I src2,
11164 immI src3, immI_M1 src4) %{
11165 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4)));
11166 ins_cost(1.9 * INSN_COST);
11167 format %{ "bicw $dst, $src1, $src2, ASR $src3" %}
11168
11169 ins_encode %{
11170 __ bicw(as_Register($dst$$reg),
11171 as_Register($src1$$reg),
11172 as_Register($src2$$reg),
11173 Assembler::ASR,
11174 $src3$$constant & 0x1f);
11175 %}
11176
11177 ins_pipe(ialu_reg_reg_shift);
11178 %}
11179
11180 // This pattern is automatically generated from aarch64_ad.m4
11181 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11182 // val & (-1 ^ (val >> shift)) ==> bic
11183 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst,
11184 iRegL src1, iRegL src2,
11185 immI src3, immL_M1 src4) %{
11186 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4)));
11187 ins_cost(1.9 * INSN_COST);
11188 format %{ "bic $dst, $src1, $src2, ASR $src3" %}
11189
11190 ins_encode %{
11191 __ bic(as_Register($dst$$reg),
11192 as_Register($src1$$reg),
11193 as_Register($src2$$reg),
11194 Assembler::ASR,
11195 $src3$$constant & 0x3f);
11196 %}
11197
11198 ins_pipe(ialu_reg_reg_shift);
11199 %}
11200
11201 // This pattern is automatically generated from aarch64_ad.m4
11202 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11203 // val & (-1 ^ (val ror shift)) ==> bicw
11204 instruct AndI_reg_RotateRight_not_reg(iRegINoSp dst,
11205 iRegIorL2I src1, iRegIorL2I src2,
11206 immI src3, immI_M1 src4) %{
11207 match(Set dst (AndI src1 (XorI(RotateRight src2 src3) src4)));
11208 ins_cost(1.9 * INSN_COST);
11209 format %{ "bicw $dst, $src1, $src2, ROR $src3" %}
11210
11211 ins_encode %{
11212 __ bicw(as_Register($dst$$reg),
11213 as_Register($src1$$reg),
11214 as_Register($src2$$reg),
11215 Assembler::ROR,
11216 $src3$$constant & 0x1f);
11217 %}
11218
11219 ins_pipe(ialu_reg_reg_shift);
11220 %}
11221
11222 // This pattern is automatically generated from aarch64_ad.m4
11223 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11224 // val & (-1 ^ (val ror shift)) ==> bic
11225 instruct AndL_reg_RotateRight_not_reg(iRegLNoSp dst,
11226 iRegL src1, iRegL src2,
11227 immI src3, immL_M1 src4) %{
11228 match(Set dst (AndL src1 (XorL(RotateRight src2 src3) src4)));
11229 ins_cost(1.9 * INSN_COST);
11230 format %{ "bic $dst, $src1, $src2, ROR $src3" %}
11231
11232 ins_encode %{
11233 __ bic(as_Register($dst$$reg),
11234 as_Register($src1$$reg),
11235 as_Register($src2$$reg),
11236 Assembler::ROR,
11237 $src3$$constant & 0x3f);
11238 %}
11239
11240 ins_pipe(ialu_reg_reg_shift);
11241 %}
11242
11243 // This pattern is automatically generated from aarch64_ad.m4
11244 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11245 // val & (-1 ^ (val << shift)) ==> bicw
11246 instruct AndI_reg_LShift_not_reg(iRegINoSp dst,
11247 iRegIorL2I src1, iRegIorL2I src2,
11248 immI src3, immI_M1 src4) %{
11249 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4)));
11250 ins_cost(1.9 * INSN_COST);
11251 format %{ "bicw $dst, $src1, $src2, LSL $src3" %}
11252
11253 ins_encode %{
11254 __ bicw(as_Register($dst$$reg),
11255 as_Register($src1$$reg),
11256 as_Register($src2$$reg),
11257 Assembler::LSL,
11258 $src3$$constant & 0x1f);
11259 %}
11260
11261 ins_pipe(ialu_reg_reg_shift);
11262 %}
11263
11264 // This pattern is automatically generated from aarch64_ad.m4
11265 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11266 // val & (-1 ^ (val << shift)) ==> bic
11267 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst,
11268 iRegL src1, iRegL src2,
11269 immI src3, immL_M1 src4) %{
11270 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4)));
11271 ins_cost(1.9 * INSN_COST);
11272 format %{ "bic $dst, $src1, $src2, LSL $src3" %}
11273
11274 ins_encode %{
11275 __ bic(as_Register($dst$$reg),
11276 as_Register($src1$$reg),
11277 as_Register($src2$$reg),
11278 Assembler::LSL,
11279 $src3$$constant & 0x3f);
11280 %}
11281
11282 ins_pipe(ialu_reg_reg_shift);
11283 %}
11284
11285 // This pattern is automatically generated from aarch64_ad.m4
11286 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11287 // val ^ (-1 ^ (val >>> shift)) ==> eonw
11288 instruct XorI_reg_URShift_not_reg(iRegINoSp dst,
11289 iRegIorL2I src1, iRegIorL2I src2,
11290 immI src3, immI_M1 src4) %{
11291 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1)));
11292 ins_cost(1.9 * INSN_COST);
11293 format %{ "eonw $dst, $src1, $src2, LSR $src3" %}
11294
11295 ins_encode %{
11296 __ eonw(as_Register($dst$$reg),
11297 as_Register($src1$$reg),
11298 as_Register($src2$$reg),
11299 Assembler::LSR,
11300 $src3$$constant & 0x1f);
11301 %}
11302
11303 ins_pipe(ialu_reg_reg_shift);
11304 %}
11305
11306 // This pattern is automatically generated from aarch64_ad.m4
11307 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11308 // val ^ (-1 ^ (val >>> shift)) ==> eon
11309 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst,
11310 iRegL src1, iRegL src2,
11311 immI src3, immL_M1 src4) %{
11312 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1)));
11313 ins_cost(1.9 * INSN_COST);
11314 format %{ "eon $dst, $src1, $src2, LSR $src3" %}
11315
11316 ins_encode %{
11317 __ eon(as_Register($dst$$reg),
11318 as_Register($src1$$reg),
11319 as_Register($src2$$reg),
11320 Assembler::LSR,
11321 $src3$$constant & 0x3f);
11322 %}
11323
11324 ins_pipe(ialu_reg_reg_shift);
11325 %}
11326
11327 // This pattern is automatically generated from aarch64_ad.m4
11328 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11329 // val ^ (-1 ^ (val >> shift)) ==> eonw
11330 instruct XorI_reg_RShift_not_reg(iRegINoSp dst,
11331 iRegIorL2I src1, iRegIorL2I src2,
11332 immI src3, immI_M1 src4) %{
11333 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1)));
11334 ins_cost(1.9 * INSN_COST);
11335 format %{ "eonw $dst, $src1, $src2, ASR $src3" %}
11336
11337 ins_encode %{
11338 __ eonw(as_Register($dst$$reg),
11339 as_Register($src1$$reg),
11340 as_Register($src2$$reg),
11341 Assembler::ASR,
11342 $src3$$constant & 0x1f);
11343 %}
11344
11345 ins_pipe(ialu_reg_reg_shift);
11346 %}
11347
11348 // This pattern is automatically generated from aarch64_ad.m4
11349 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11350 // val ^ (-1 ^ (val >> shift)) ==> eon
11351 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst,
11352 iRegL src1, iRegL src2,
11353 immI src3, immL_M1 src4) %{
11354 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1)));
11355 ins_cost(1.9 * INSN_COST);
11356 format %{ "eon $dst, $src1, $src2, ASR $src3" %}
11357
11358 ins_encode %{
11359 __ eon(as_Register($dst$$reg),
11360 as_Register($src1$$reg),
11361 as_Register($src2$$reg),
11362 Assembler::ASR,
11363 $src3$$constant & 0x3f);
11364 %}
11365
11366 ins_pipe(ialu_reg_reg_shift);
11367 %}
11368
11369 // This pattern is automatically generated from aarch64_ad.m4
11370 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11371 // val ^ (-1 ^ (val ror shift)) ==> eonw
11372 instruct XorI_reg_RotateRight_not_reg(iRegINoSp dst,
11373 iRegIorL2I src1, iRegIorL2I src2,
11374 immI src3, immI_M1 src4) %{
11375 match(Set dst (XorI src4 (XorI(RotateRight src2 src3) src1)));
11376 ins_cost(1.9 * INSN_COST);
11377 format %{ "eonw $dst, $src1, $src2, ROR $src3" %}
11378
11379 ins_encode %{
11380 __ eonw(as_Register($dst$$reg),
11381 as_Register($src1$$reg),
11382 as_Register($src2$$reg),
11383 Assembler::ROR,
11384 $src3$$constant & 0x1f);
11385 %}
11386
11387 ins_pipe(ialu_reg_reg_shift);
11388 %}
11389
11390 // This pattern is automatically generated from aarch64_ad.m4
11391 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11392 // val ^ (-1 ^ (val ror shift)) ==> eon
11393 instruct XorL_reg_RotateRight_not_reg(iRegLNoSp dst,
11394 iRegL src1, iRegL src2,
11395 immI src3, immL_M1 src4) %{
11396 match(Set dst (XorL src4 (XorL(RotateRight src2 src3) src1)));
11397 ins_cost(1.9 * INSN_COST);
11398 format %{ "eon $dst, $src1, $src2, ROR $src3" %}
11399
11400 ins_encode %{
11401 __ eon(as_Register($dst$$reg),
11402 as_Register($src1$$reg),
11403 as_Register($src2$$reg),
11404 Assembler::ROR,
11405 $src3$$constant & 0x3f);
11406 %}
11407
11408 ins_pipe(ialu_reg_reg_shift);
11409 %}
11410
11411 // This pattern is automatically generated from aarch64_ad.m4
11412 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11413 // val ^ (-1 ^ (val << shift)) ==> eonw
11414 instruct XorI_reg_LShift_not_reg(iRegINoSp dst,
11415 iRegIorL2I src1, iRegIorL2I src2,
11416 immI src3, immI_M1 src4) %{
11417 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1)));
11418 ins_cost(1.9 * INSN_COST);
11419 format %{ "eonw $dst, $src1, $src2, LSL $src3" %}
11420
11421 ins_encode %{
11422 __ eonw(as_Register($dst$$reg),
11423 as_Register($src1$$reg),
11424 as_Register($src2$$reg),
11425 Assembler::LSL,
11426 $src3$$constant & 0x1f);
11427 %}
11428
11429 ins_pipe(ialu_reg_reg_shift);
11430 %}
11431
11432 // This pattern is automatically generated from aarch64_ad.m4
11433 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11434 // val ^ (-1 ^ (val << shift)) ==> eon
11435 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst,
11436 iRegL src1, iRegL src2,
11437 immI src3, immL_M1 src4) %{
11438 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1)));
11439 ins_cost(1.9 * INSN_COST);
11440 format %{ "eon $dst, $src1, $src2, LSL $src3" %}
11441
11442 ins_encode %{
11443 __ eon(as_Register($dst$$reg),
11444 as_Register($src1$$reg),
11445 as_Register($src2$$reg),
11446 Assembler::LSL,
11447 $src3$$constant & 0x3f);
11448 %}
11449
11450 ins_pipe(ialu_reg_reg_shift);
11451 %}
11452
11453 // This pattern is automatically generated from aarch64_ad.m4
11454 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11455 // val | (-1 ^ (val >>> shift)) ==> ornw
11456 instruct OrI_reg_URShift_not_reg(iRegINoSp dst,
11457 iRegIorL2I src1, iRegIorL2I src2,
11458 immI src3, immI_M1 src4) %{
11459 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4)));
11460 ins_cost(1.9 * INSN_COST);
11461 format %{ "ornw $dst, $src1, $src2, LSR $src3" %}
11462
11463 ins_encode %{
11464 __ ornw(as_Register($dst$$reg),
11465 as_Register($src1$$reg),
11466 as_Register($src2$$reg),
11467 Assembler::LSR,
11468 $src3$$constant & 0x1f);
11469 %}
11470
11471 ins_pipe(ialu_reg_reg_shift);
11472 %}
11473
11474 // This pattern is automatically generated from aarch64_ad.m4
11475 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11476 // val | (-1 ^ (val >>> shift)) ==> orn
11477 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst,
11478 iRegL src1, iRegL src2,
11479 immI src3, immL_M1 src4) %{
11480 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4)));
11481 ins_cost(1.9 * INSN_COST);
11482 format %{ "orn $dst, $src1, $src2, LSR $src3" %}
11483
11484 ins_encode %{
11485 __ orn(as_Register($dst$$reg),
11486 as_Register($src1$$reg),
11487 as_Register($src2$$reg),
11488 Assembler::LSR,
11489 $src3$$constant & 0x3f);
11490 %}
11491
11492 ins_pipe(ialu_reg_reg_shift);
11493 %}
11494
11495 // This pattern is automatically generated from aarch64_ad.m4
11496 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11497 // val | (-1 ^ (val >> shift)) ==> ornw
11498 instruct OrI_reg_RShift_not_reg(iRegINoSp dst,
11499 iRegIorL2I src1, iRegIorL2I src2,
11500 immI src3, immI_M1 src4) %{
11501 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4)));
11502 ins_cost(1.9 * INSN_COST);
11503 format %{ "ornw $dst, $src1, $src2, ASR $src3" %}
11504
11505 ins_encode %{
11506 __ ornw(as_Register($dst$$reg),
11507 as_Register($src1$$reg),
11508 as_Register($src2$$reg),
11509 Assembler::ASR,
11510 $src3$$constant & 0x1f);
11511 %}
11512
11513 ins_pipe(ialu_reg_reg_shift);
11514 %}
11515
11516 // This pattern is automatically generated from aarch64_ad.m4
11517 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11518 // val | (-1 ^ (val >> shift)) ==> orn
11519 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst,
11520 iRegL src1, iRegL src2,
11521 immI src3, immL_M1 src4) %{
11522 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4)));
11523 ins_cost(1.9 * INSN_COST);
11524 format %{ "orn $dst, $src1, $src2, ASR $src3" %}
11525
11526 ins_encode %{
11527 __ orn(as_Register($dst$$reg),
11528 as_Register($src1$$reg),
11529 as_Register($src2$$reg),
11530 Assembler::ASR,
11531 $src3$$constant & 0x3f);
11532 %}
11533
11534 ins_pipe(ialu_reg_reg_shift);
11535 %}
11536
11537 // This pattern is automatically generated from aarch64_ad.m4
11538 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11539 // val | (-1 ^ (val ror shift)) ==> ornw
11540 instruct OrI_reg_RotateRight_not_reg(iRegINoSp dst,
11541 iRegIorL2I src1, iRegIorL2I src2,
11542 immI src3, immI_M1 src4) %{
11543 match(Set dst (OrI src1 (XorI(RotateRight src2 src3) src4)));
11544 ins_cost(1.9 * INSN_COST);
11545 format %{ "ornw $dst, $src1, $src2, ROR $src3" %}
11546
11547 ins_encode %{
11548 __ ornw(as_Register($dst$$reg),
11549 as_Register($src1$$reg),
11550 as_Register($src2$$reg),
11551 Assembler::ROR,
11552 $src3$$constant & 0x1f);
11553 %}
11554
11555 ins_pipe(ialu_reg_reg_shift);
11556 %}
11557
11558 // This pattern is automatically generated from aarch64_ad.m4
11559 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11560 // val | (-1 ^ (val ror shift)) ==> orn
11561 instruct OrL_reg_RotateRight_not_reg(iRegLNoSp dst,
11562 iRegL src1, iRegL src2,
11563 immI src3, immL_M1 src4) %{
11564 match(Set dst (OrL src1 (XorL(RotateRight src2 src3) src4)));
11565 ins_cost(1.9 * INSN_COST);
11566 format %{ "orn $dst, $src1, $src2, ROR $src3" %}
11567
11568 ins_encode %{
11569 __ orn(as_Register($dst$$reg),
11570 as_Register($src1$$reg),
11571 as_Register($src2$$reg),
11572 Assembler::ROR,
11573 $src3$$constant & 0x3f);
11574 %}
11575
11576 ins_pipe(ialu_reg_reg_shift);
11577 %}
11578
11579 // This pattern is automatically generated from aarch64_ad.m4
11580 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11581 // val | (-1 ^ (val << shift)) ==> ornw
11582 instruct OrI_reg_LShift_not_reg(iRegINoSp dst,
11583 iRegIorL2I src1, iRegIorL2I src2,
11584 immI src3, immI_M1 src4) %{
11585 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4)));
11586 ins_cost(1.9 * INSN_COST);
11587 format %{ "ornw $dst, $src1, $src2, LSL $src3" %}
11588
11589 ins_encode %{
11590 __ ornw(as_Register($dst$$reg),
11591 as_Register($src1$$reg),
11592 as_Register($src2$$reg),
11593 Assembler::LSL,
11594 $src3$$constant & 0x1f);
11595 %}
11596
11597 ins_pipe(ialu_reg_reg_shift);
11598 %}
11599
11600 // This pattern is automatically generated from aarch64_ad.m4
11601 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11602 // val | (-1 ^ (val << shift)) ==> orn
11603 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst,
11604 iRegL src1, iRegL src2,
11605 immI src3, immL_M1 src4) %{
11606 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4)));
11607 ins_cost(1.9 * INSN_COST);
11608 format %{ "orn $dst, $src1, $src2, LSL $src3" %}
11609
11610 ins_encode %{
11611 __ orn(as_Register($dst$$reg),
11612 as_Register($src1$$reg),
11613 as_Register($src2$$reg),
11614 Assembler::LSL,
11615 $src3$$constant & 0x3f);
11616 %}
11617
11618 ins_pipe(ialu_reg_reg_shift);
11619 %}
11620
11621 // This pattern is automatically generated from aarch64_ad.m4
11622 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11623 instruct AndI_reg_URShift_reg(iRegINoSp dst,
11624 iRegIorL2I src1, iRegIorL2I src2,
11625 immI src3) %{
11626 match(Set dst (AndI src1 (URShiftI src2 src3)));
11627
11628 ins_cost(1.9 * INSN_COST);
11629 format %{ "andw $dst, $src1, $src2, LSR $src3" %}
11630
11631 ins_encode %{
11632 __ andw(as_Register($dst$$reg),
11633 as_Register($src1$$reg),
11634 as_Register($src2$$reg),
11635 Assembler::LSR,
11636 $src3$$constant & 0x1f);
11637 %}
11638
11639 ins_pipe(ialu_reg_reg_shift);
11640 %}
11641
11642 // This pattern is automatically generated from aarch64_ad.m4
11643 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11644 instruct AndL_reg_URShift_reg(iRegLNoSp dst,
11645 iRegL src1, iRegL src2,
11646 immI src3) %{
11647 match(Set dst (AndL src1 (URShiftL src2 src3)));
11648
11649 ins_cost(1.9 * INSN_COST);
11650 format %{ "andr $dst, $src1, $src2, LSR $src3" %}
11651
11652 ins_encode %{
11653 __ andr(as_Register($dst$$reg),
11654 as_Register($src1$$reg),
11655 as_Register($src2$$reg),
11656 Assembler::LSR,
11657 $src3$$constant & 0x3f);
11658 %}
11659
11660 ins_pipe(ialu_reg_reg_shift);
11661 %}
11662
11663 // This pattern is automatically generated from aarch64_ad.m4
11664 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11665 instruct AndI_reg_RShift_reg(iRegINoSp dst,
11666 iRegIorL2I src1, iRegIorL2I src2,
11667 immI src3) %{
11668 match(Set dst (AndI src1 (RShiftI src2 src3)));
11669
11670 ins_cost(1.9 * INSN_COST);
11671 format %{ "andw $dst, $src1, $src2, ASR $src3" %}
11672
11673 ins_encode %{
11674 __ andw(as_Register($dst$$reg),
11675 as_Register($src1$$reg),
11676 as_Register($src2$$reg),
11677 Assembler::ASR,
11678 $src3$$constant & 0x1f);
11679 %}
11680
11681 ins_pipe(ialu_reg_reg_shift);
11682 %}
11683
11684 // This pattern is automatically generated from aarch64_ad.m4
11685 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11686 instruct AndL_reg_RShift_reg(iRegLNoSp dst,
11687 iRegL src1, iRegL src2,
11688 immI src3) %{
11689 match(Set dst (AndL src1 (RShiftL src2 src3)));
11690
11691 ins_cost(1.9 * INSN_COST);
11692 format %{ "andr $dst, $src1, $src2, ASR $src3" %}
11693
11694 ins_encode %{
11695 __ andr(as_Register($dst$$reg),
11696 as_Register($src1$$reg),
11697 as_Register($src2$$reg),
11698 Assembler::ASR,
11699 $src3$$constant & 0x3f);
11700 %}
11701
11702 ins_pipe(ialu_reg_reg_shift);
11703 %}
11704
11705 // This pattern is automatically generated from aarch64_ad.m4
11706 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11707 instruct AndI_reg_LShift_reg(iRegINoSp dst,
11708 iRegIorL2I src1, iRegIorL2I src2,
11709 immI src3) %{
11710 match(Set dst (AndI src1 (LShiftI src2 src3)));
11711
11712 ins_cost(1.9 * INSN_COST);
11713 format %{ "andw $dst, $src1, $src2, LSL $src3" %}
11714
11715 ins_encode %{
11716 __ andw(as_Register($dst$$reg),
11717 as_Register($src1$$reg),
11718 as_Register($src2$$reg),
11719 Assembler::LSL,
11720 $src3$$constant & 0x1f);
11721 %}
11722
11723 ins_pipe(ialu_reg_reg_shift);
11724 %}
11725
11726 // This pattern is automatically generated from aarch64_ad.m4
11727 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11728 instruct AndL_reg_LShift_reg(iRegLNoSp dst,
11729 iRegL src1, iRegL src2,
11730 immI src3) %{
11731 match(Set dst (AndL src1 (LShiftL src2 src3)));
11732
11733 ins_cost(1.9 * INSN_COST);
11734 format %{ "andr $dst, $src1, $src2, LSL $src3" %}
11735
11736 ins_encode %{
11737 __ andr(as_Register($dst$$reg),
11738 as_Register($src1$$reg),
11739 as_Register($src2$$reg),
11740 Assembler::LSL,
11741 $src3$$constant & 0x3f);
11742 %}
11743
11744 ins_pipe(ialu_reg_reg_shift);
11745 %}
11746
11747 // This pattern is automatically generated from aarch64_ad.m4
11748 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11749 instruct AndI_reg_RotateRight_reg(iRegINoSp dst,
11750 iRegIorL2I src1, iRegIorL2I src2,
11751 immI src3) %{
11752 match(Set dst (AndI src1 (RotateRight src2 src3)));
11753
11754 ins_cost(1.9 * INSN_COST);
11755 format %{ "andw $dst, $src1, $src2, ROR $src3" %}
11756
11757 ins_encode %{
11758 __ andw(as_Register($dst$$reg),
11759 as_Register($src1$$reg),
11760 as_Register($src2$$reg),
11761 Assembler::ROR,
11762 $src3$$constant & 0x1f);
11763 %}
11764
11765 ins_pipe(ialu_reg_reg_shift);
11766 %}
11767
11768 // This pattern is automatically generated from aarch64_ad.m4
11769 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11770 instruct AndL_reg_RotateRight_reg(iRegLNoSp dst,
11771 iRegL src1, iRegL src2,
11772 immI src3) %{
11773 match(Set dst (AndL src1 (RotateRight src2 src3)));
11774
11775 ins_cost(1.9 * INSN_COST);
11776 format %{ "andr $dst, $src1, $src2, ROR $src3" %}
11777
11778 ins_encode %{
11779 __ andr(as_Register($dst$$reg),
11780 as_Register($src1$$reg),
11781 as_Register($src2$$reg),
11782 Assembler::ROR,
11783 $src3$$constant & 0x3f);
11784 %}
11785
11786 ins_pipe(ialu_reg_reg_shift);
11787 %}
11788
11789 // This pattern is automatically generated from aarch64_ad.m4
11790 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11791 instruct XorI_reg_URShift_reg(iRegINoSp dst,
11792 iRegIorL2I src1, iRegIorL2I src2,
11793 immI src3) %{
11794 match(Set dst (XorI src1 (URShiftI src2 src3)));
11795
11796 ins_cost(1.9 * INSN_COST);
11797 format %{ "eorw $dst, $src1, $src2, LSR $src3" %}
11798
11799 ins_encode %{
11800 __ eorw(as_Register($dst$$reg),
11801 as_Register($src1$$reg),
11802 as_Register($src2$$reg),
11803 Assembler::LSR,
11804 $src3$$constant & 0x1f);
11805 %}
11806
11807 ins_pipe(ialu_reg_reg_shift);
11808 %}
11809
11810 // This pattern is automatically generated from aarch64_ad.m4
11811 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11812 instruct XorL_reg_URShift_reg(iRegLNoSp dst,
11813 iRegL src1, iRegL src2,
11814 immI src3) %{
11815 match(Set dst (XorL src1 (URShiftL src2 src3)));
11816
11817 ins_cost(1.9 * INSN_COST);
11818 format %{ "eor $dst, $src1, $src2, LSR $src3" %}
11819
11820 ins_encode %{
11821 __ eor(as_Register($dst$$reg),
11822 as_Register($src1$$reg),
11823 as_Register($src2$$reg),
11824 Assembler::LSR,
11825 $src3$$constant & 0x3f);
11826 %}
11827
11828 ins_pipe(ialu_reg_reg_shift);
11829 %}
11830
11831 // This pattern is automatically generated from aarch64_ad.m4
11832 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11833 instruct XorI_reg_RShift_reg(iRegINoSp dst,
11834 iRegIorL2I src1, iRegIorL2I src2,
11835 immI src3) %{
11836 match(Set dst (XorI src1 (RShiftI src2 src3)));
11837
11838 ins_cost(1.9 * INSN_COST);
11839 format %{ "eorw $dst, $src1, $src2, ASR $src3" %}
11840
11841 ins_encode %{
11842 __ eorw(as_Register($dst$$reg),
11843 as_Register($src1$$reg),
11844 as_Register($src2$$reg),
11845 Assembler::ASR,
11846 $src3$$constant & 0x1f);
11847 %}
11848
11849 ins_pipe(ialu_reg_reg_shift);
11850 %}
11851
11852 // This pattern is automatically generated from aarch64_ad.m4
11853 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11854 instruct XorL_reg_RShift_reg(iRegLNoSp dst,
11855 iRegL src1, iRegL src2,
11856 immI src3) %{
11857 match(Set dst (XorL src1 (RShiftL src2 src3)));
11858
11859 ins_cost(1.9 * INSN_COST);
11860 format %{ "eor $dst, $src1, $src2, ASR $src3" %}
11861
11862 ins_encode %{
11863 __ eor(as_Register($dst$$reg),
11864 as_Register($src1$$reg),
11865 as_Register($src2$$reg),
11866 Assembler::ASR,
11867 $src3$$constant & 0x3f);
11868 %}
11869
11870 ins_pipe(ialu_reg_reg_shift);
11871 %}
11872
11873 // This pattern is automatically generated from aarch64_ad.m4
11874 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11875 instruct XorI_reg_LShift_reg(iRegINoSp dst,
11876 iRegIorL2I src1, iRegIorL2I src2,
11877 immI src3) %{
11878 match(Set dst (XorI src1 (LShiftI src2 src3)));
11879
11880 ins_cost(1.9 * INSN_COST);
11881 format %{ "eorw $dst, $src1, $src2, LSL $src3" %}
11882
11883 ins_encode %{
11884 __ eorw(as_Register($dst$$reg),
11885 as_Register($src1$$reg),
11886 as_Register($src2$$reg),
11887 Assembler::LSL,
11888 $src3$$constant & 0x1f);
11889 %}
11890
11891 ins_pipe(ialu_reg_reg_shift);
11892 %}
11893
11894 // This pattern is automatically generated from aarch64_ad.m4
11895 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11896 instruct XorL_reg_LShift_reg(iRegLNoSp dst,
11897 iRegL src1, iRegL src2,
11898 immI src3) %{
11899 match(Set dst (XorL src1 (LShiftL src2 src3)));
11900
11901 ins_cost(1.9 * INSN_COST);
11902 format %{ "eor $dst, $src1, $src2, LSL $src3" %}
11903
11904 ins_encode %{
11905 __ eor(as_Register($dst$$reg),
11906 as_Register($src1$$reg),
11907 as_Register($src2$$reg),
11908 Assembler::LSL,
11909 $src3$$constant & 0x3f);
11910 %}
11911
11912 ins_pipe(ialu_reg_reg_shift);
11913 %}
11914
11915 // This pattern is automatically generated from aarch64_ad.m4
11916 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11917 instruct XorI_reg_RotateRight_reg(iRegINoSp dst,
11918 iRegIorL2I src1, iRegIorL2I src2,
11919 immI src3) %{
11920 match(Set dst (XorI src1 (RotateRight src2 src3)));
11921
11922 ins_cost(1.9 * INSN_COST);
11923 format %{ "eorw $dst, $src1, $src2, ROR $src3" %}
11924
11925 ins_encode %{
11926 __ eorw(as_Register($dst$$reg),
11927 as_Register($src1$$reg),
11928 as_Register($src2$$reg),
11929 Assembler::ROR,
11930 $src3$$constant & 0x1f);
11931 %}
11932
11933 ins_pipe(ialu_reg_reg_shift);
11934 %}
11935
11936 // This pattern is automatically generated from aarch64_ad.m4
11937 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11938 instruct XorL_reg_RotateRight_reg(iRegLNoSp dst,
11939 iRegL src1, iRegL src2,
11940 immI src3) %{
11941 match(Set dst (XorL src1 (RotateRight src2 src3)));
11942
11943 ins_cost(1.9 * INSN_COST);
11944 format %{ "eor $dst, $src1, $src2, ROR $src3" %}
11945
11946 ins_encode %{
11947 __ eor(as_Register($dst$$reg),
11948 as_Register($src1$$reg),
11949 as_Register($src2$$reg),
11950 Assembler::ROR,
11951 $src3$$constant & 0x3f);
11952 %}
11953
11954 ins_pipe(ialu_reg_reg_shift);
11955 %}
11956
11957 // This pattern is automatically generated from aarch64_ad.m4
11958 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11959 instruct OrI_reg_URShift_reg(iRegINoSp dst,
11960 iRegIorL2I src1, iRegIorL2I src2,
11961 immI src3) %{
11962 match(Set dst (OrI src1 (URShiftI src2 src3)));
11963
11964 ins_cost(1.9 * INSN_COST);
11965 format %{ "orrw $dst, $src1, $src2, LSR $src3" %}
11966
11967 ins_encode %{
11968 __ orrw(as_Register($dst$$reg),
11969 as_Register($src1$$reg),
11970 as_Register($src2$$reg),
11971 Assembler::LSR,
11972 $src3$$constant & 0x1f);
11973 %}
11974
11975 ins_pipe(ialu_reg_reg_shift);
11976 %}
11977
11978 // This pattern is automatically generated from aarch64_ad.m4
11979 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11980 instruct OrL_reg_URShift_reg(iRegLNoSp dst,
11981 iRegL src1, iRegL src2,
11982 immI src3) %{
11983 match(Set dst (OrL src1 (URShiftL src2 src3)));
11984
11985 ins_cost(1.9 * INSN_COST);
11986 format %{ "orr $dst, $src1, $src2, LSR $src3" %}
11987
11988 ins_encode %{
11989 __ orr(as_Register($dst$$reg),
11990 as_Register($src1$$reg),
11991 as_Register($src2$$reg),
11992 Assembler::LSR,
11993 $src3$$constant & 0x3f);
11994 %}
11995
11996 ins_pipe(ialu_reg_reg_shift);
11997 %}
11998
11999 // This pattern is automatically generated from aarch64_ad.m4
12000 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12001 instruct OrI_reg_RShift_reg(iRegINoSp dst,
12002 iRegIorL2I src1, iRegIorL2I src2,
12003 immI src3) %{
12004 match(Set dst (OrI src1 (RShiftI src2 src3)));
12005
12006 ins_cost(1.9 * INSN_COST);
12007 format %{ "orrw $dst, $src1, $src2, ASR $src3" %}
12008
12009 ins_encode %{
12010 __ orrw(as_Register($dst$$reg),
12011 as_Register($src1$$reg),
12012 as_Register($src2$$reg),
12013 Assembler::ASR,
12014 $src3$$constant & 0x1f);
12015 %}
12016
12017 ins_pipe(ialu_reg_reg_shift);
12018 %}
12019
12020 // This pattern is automatically generated from aarch64_ad.m4
12021 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12022 instruct OrL_reg_RShift_reg(iRegLNoSp dst,
12023 iRegL src1, iRegL src2,
12024 immI src3) %{
12025 match(Set dst (OrL src1 (RShiftL src2 src3)));
12026
12027 ins_cost(1.9 * INSN_COST);
12028 format %{ "orr $dst, $src1, $src2, ASR $src3" %}
12029
12030 ins_encode %{
12031 __ orr(as_Register($dst$$reg),
12032 as_Register($src1$$reg),
12033 as_Register($src2$$reg),
12034 Assembler::ASR,
12035 $src3$$constant & 0x3f);
12036 %}
12037
12038 ins_pipe(ialu_reg_reg_shift);
12039 %}
12040
12041 // This pattern is automatically generated from aarch64_ad.m4
12042 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12043 instruct OrI_reg_LShift_reg(iRegINoSp dst,
12044 iRegIorL2I src1, iRegIorL2I src2,
12045 immI src3) %{
12046 match(Set dst (OrI src1 (LShiftI src2 src3)));
12047
12048 ins_cost(1.9 * INSN_COST);
12049 format %{ "orrw $dst, $src1, $src2, LSL $src3" %}
12050
12051 ins_encode %{
12052 __ orrw(as_Register($dst$$reg),
12053 as_Register($src1$$reg),
12054 as_Register($src2$$reg),
12055 Assembler::LSL,
12056 $src3$$constant & 0x1f);
12057 %}
12058
12059 ins_pipe(ialu_reg_reg_shift);
12060 %}
12061
12062 // This pattern is automatically generated from aarch64_ad.m4
12063 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12064 instruct OrL_reg_LShift_reg(iRegLNoSp dst,
12065 iRegL src1, iRegL src2,
12066 immI src3) %{
12067 match(Set dst (OrL src1 (LShiftL src2 src3)));
12068
12069 ins_cost(1.9 * INSN_COST);
12070 format %{ "orr $dst, $src1, $src2, LSL $src3" %}
12071
12072 ins_encode %{
12073 __ orr(as_Register($dst$$reg),
12074 as_Register($src1$$reg),
12075 as_Register($src2$$reg),
12076 Assembler::LSL,
12077 $src3$$constant & 0x3f);
12078 %}
12079
12080 ins_pipe(ialu_reg_reg_shift);
12081 %}
12082
12083 // This pattern is automatically generated from aarch64_ad.m4
12084 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12085 instruct OrI_reg_RotateRight_reg(iRegINoSp dst,
12086 iRegIorL2I src1, iRegIorL2I src2,
12087 immI src3) %{
12088 match(Set dst (OrI src1 (RotateRight src2 src3)));
12089
12090 ins_cost(1.9 * INSN_COST);
12091 format %{ "orrw $dst, $src1, $src2, ROR $src3" %}
12092
12093 ins_encode %{
12094 __ orrw(as_Register($dst$$reg),
12095 as_Register($src1$$reg),
12096 as_Register($src2$$reg),
12097 Assembler::ROR,
12098 $src3$$constant & 0x1f);
12099 %}
12100
12101 ins_pipe(ialu_reg_reg_shift);
12102 %}
12103
12104 // This pattern is automatically generated from aarch64_ad.m4
12105 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12106 instruct OrL_reg_RotateRight_reg(iRegLNoSp dst,
12107 iRegL src1, iRegL src2,
12108 immI src3) %{
12109 match(Set dst (OrL src1 (RotateRight src2 src3)));
12110
12111 ins_cost(1.9 * INSN_COST);
12112 format %{ "orr $dst, $src1, $src2, ROR $src3" %}
12113
12114 ins_encode %{
12115 __ orr(as_Register($dst$$reg),
12116 as_Register($src1$$reg),
12117 as_Register($src2$$reg),
12118 Assembler::ROR,
12119 $src3$$constant & 0x3f);
12120 %}
12121
12122 ins_pipe(ialu_reg_reg_shift);
12123 %}
12124
12125 // This pattern is automatically generated from aarch64_ad.m4
12126 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12127 instruct AddI_reg_URShift_reg(iRegINoSp dst,
12128 iRegIorL2I src1, iRegIorL2I src2,
12129 immI src3) %{
12130 match(Set dst (AddI src1 (URShiftI src2 src3)));
12131
12132 ins_cost(1.9 * INSN_COST);
12133 format %{ "addw $dst, $src1, $src2, LSR $src3" %}
12134
12135 ins_encode %{
12136 __ addw(as_Register($dst$$reg),
12137 as_Register($src1$$reg),
12138 as_Register($src2$$reg),
12139 Assembler::LSR,
12140 $src3$$constant & 0x1f);
12141 %}
12142
12143 ins_pipe(ialu_reg_reg_shift);
12144 %}
12145
12146 // This pattern is automatically generated from aarch64_ad.m4
12147 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12148 instruct AddL_reg_URShift_reg(iRegLNoSp dst,
12149 iRegL src1, iRegL src2,
12150 immI src3) %{
12151 match(Set dst (AddL src1 (URShiftL src2 src3)));
12152
12153 ins_cost(1.9 * INSN_COST);
12154 format %{ "add $dst, $src1, $src2, LSR $src3" %}
12155
12156 ins_encode %{
12157 __ add(as_Register($dst$$reg),
12158 as_Register($src1$$reg),
12159 as_Register($src2$$reg),
12160 Assembler::LSR,
12161 $src3$$constant & 0x3f);
12162 %}
12163
12164 ins_pipe(ialu_reg_reg_shift);
12165 %}
12166
12167 // This pattern is automatically generated from aarch64_ad.m4
12168 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12169 instruct AddI_reg_RShift_reg(iRegINoSp dst,
12170 iRegIorL2I src1, iRegIorL2I src2,
12171 immI src3) %{
12172 match(Set dst (AddI src1 (RShiftI src2 src3)));
12173
12174 ins_cost(1.9 * INSN_COST);
12175 format %{ "addw $dst, $src1, $src2, ASR $src3" %}
12176
12177 ins_encode %{
12178 __ addw(as_Register($dst$$reg),
12179 as_Register($src1$$reg),
12180 as_Register($src2$$reg),
12181 Assembler::ASR,
12182 $src3$$constant & 0x1f);
12183 %}
12184
12185 ins_pipe(ialu_reg_reg_shift);
12186 %}
12187
12188 // This pattern is automatically generated from aarch64_ad.m4
12189 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12190 instruct AddL_reg_RShift_reg(iRegLNoSp dst,
12191 iRegL src1, iRegL src2,
12192 immI src3) %{
12193 match(Set dst (AddL src1 (RShiftL src2 src3)));
12194
12195 ins_cost(1.9 * INSN_COST);
12196 format %{ "add $dst, $src1, $src2, ASR $src3" %}
12197
12198 ins_encode %{
12199 __ add(as_Register($dst$$reg),
12200 as_Register($src1$$reg),
12201 as_Register($src2$$reg),
12202 Assembler::ASR,
12203 $src3$$constant & 0x3f);
12204 %}
12205
12206 ins_pipe(ialu_reg_reg_shift);
12207 %}
12208
12209 // This pattern is automatically generated from aarch64_ad.m4
12210 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12211 instruct AddI_reg_LShift_reg(iRegINoSp dst,
12212 iRegIorL2I src1, iRegIorL2I src2,
12213 immI src3) %{
12214 match(Set dst (AddI src1 (LShiftI src2 src3)));
12215
12216 ins_cost(1.9 * INSN_COST);
12217 format %{ "addw $dst, $src1, $src2, LSL $src3" %}
12218
12219 ins_encode %{
12220 __ addw(as_Register($dst$$reg),
12221 as_Register($src1$$reg),
12222 as_Register($src2$$reg),
12223 Assembler::LSL,
12224 $src3$$constant & 0x1f);
12225 %}
12226
12227 ins_pipe(ialu_reg_reg_shift);
12228 %}
12229
12230 // This pattern is automatically generated from aarch64_ad.m4
12231 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12232 instruct AddL_reg_LShift_reg(iRegLNoSp dst,
12233 iRegL src1, iRegL src2,
12234 immI src3) %{
12235 match(Set dst (AddL src1 (LShiftL src2 src3)));
12236
12237 ins_cost(1.9 * INSN_COST);
12238 format %{ "add $dst, $src1, $src2, LSL $src3" %}
12239
12240 ins_encode %{
12241 __ add(as_Register($dst$$reg),
12242 as_Register($src1$$reg),
12243 as_Register($src2$$reg),
12244 Assembler::LSL,
12245 $src3$$constant & 0x3f);
12246 %}
12247
12248 ins_pipe(ialu_reg_reg_shift);
12249 %}
12250
12251 // This pattern is automatically generated from aarch64_ad.m4
12252 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12253 instruct SubI_reg_URShift_reg(iRegINoSp dst,
12254 iRegIorL2I src1, iRegIorL2I src2,
12255 immI src3) %{
12256 match(Set dst (SubI src1 (URShiftI src2 src3)));
12257
12258 ins_cost(1.9 * INSN_COST);
12259 format %{ "subw $dst, $src1, $src2, LSR $src3" %}
12260
12261 ins_encode %{
12262 __ subw(as_Register($dst$$reg),
12263 as_Register($src1$$reg),
12264 as_Register($src2$$reg),
12265 Assembler::LSR,
12266 $src3$$constant & 0x1f);
12267 %}
12268
12269 ins_pipe(ialu_reg_reg_shift);
12270 %}
12271
12272 // This pattern is automatically generated from aarch64_ad.m4
12273 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12274 instruct SubL_reg_URShift_reg(iRegLNoSp dst,
12275 iRegL src1, iRegL src2,
12276 immI src3) %{
12277 match(Set dst (SubL src1 (URShiftL src2 src3)));
12278
12279 ins_cost(1.9 * INSN_COST);
12280 format %{ "sub $dst, $src1, $src2, LSR $src3" %}
12281
12282 ins_encode %{
12283 __ sub(as_Register($dst$$reg),
12284 as_Register($src1$$reg),
12285 as_Register($src2$$reg),
12286 Assembler::LSR,
12287 $src3$$constant & 0x3f);
12288 %}
12289
12290 ins_pipe(ialu_reg_reg_shift);
12291 %}
12292
12293 // This pattern is automatically generated from aarch64_ad.m4
12294 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12295 instruct SubI_reg_RShift_reg(iRegINoSp dst,
12296 iRegIorL2I src1, iRegIorL2I src2,
12297 immI src3) %{
12298 match(Set dst (SubI src1 (RShiftI src2 src3)));
12299
12300 ins_cost(1.9 * INSN_COST);
12301 format %{ "subw $dst, $src1, $src2, ASR $src3" %}
12302
12303 ins_encode %{
12304 __ subw(as_Register($dst$$reg),
12305 as_Register($src1$$reg),
12306 as_Register($src2$$reg),
12307 Assembler::ASR,
12308 $src3$$constant & 0x1f);
12309 %}
12310
12311 ins_pipe(ialu_reg_reg_shift);
12312 %}
12313
12314 // This pattern is automatically generated from aarch64_ad.m4
12315 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12316 instruct SubL_reg_RShift_reg(iRegLNoSp dst,
12317 iRegL src1, iRegL src2,
12318 immI src3) %{
12319 match(Set dst (SubL src1 (RShiftL src2 src3)));
12320
12321 ins_cost(1.9 * INSN_COST);
12322 format %{ "sub $dst, $src1, $src2, ASR $src3" %}
12323
12324 ins_encode %{
12325 __ sub(as_Register($dst$$reg),
12326 as_Register($src1$$reg),
12327 as_Register($src2$$reg),
12328 Assembler::ASR,
12329 $src3$$constant & 0x3f);
12330 %}
12331
12332 ins_pipe(ialu_reg_reg_shift);
12333 %}
12334
12335 // This pattern is automatically generated from aarch64_ad.m4
12336 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12337 instruct SubI_reg_LShift_reg(iRegINoSp dst,
12338 iRegIorL2I src1, iRegIorL2I src2,
12339 immI src3) %{
12340 match(Set dst (SubI src1 (LShiftI src2 src3)));
12341
12342 ins_cost(1.9 * INSN_COST);
12343 format %{ "subw $dst, $src1, $src2, LSL $src3" %}
12344
12345 ins_encode %{
12346 __ subw(as_Register($dst$$reg),
12347 as_Register($src1$$reg),
12348 as_Register($src2$$reg),
12349 Assembler::LSL,
12350 $src3$$constant & 0x1f);
12351 %}
12352
12353 ins_pipe(ialu_reg_reg_shift);
12354 %}
12355
12356 // This pattern is automatically generated from aarch64_ad.m4
12357 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12358 instruct SubL_reg_LShift_reg(iRegLNoSp dst,
12359 iRegL src1, iRegL src2,
12360 immI src3) %{
12361 match(Set dst (SubL src1 (LShiftL src2 src3)));
12362
12363 ins_cost(1.9 * INSN_COST);
12364 format %{ "sub $dst, $src1, $src2, LSL $src3" %}
12365
12366 ins_encode %{
12367 __ sub(as_Register($dst$$reg),
12368 as_Register($src1$$reg),
12369 as_Register($src2$$reg),
12370 Assembler::LSL,
12371 $src3$$constant & 0x3f);
12372 %}
12373
12374 ins_pipe(ialu_reg_reg_shift);
12375 %}
12376
12377 // This pattern is automatically generated from aarch64_ad.m4
12378 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12379
12380 // Shift Left followed by Shift Right.
12381 // This idiom is used by the compiler for the i2b bytecode etc.
12382 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
12383 %{
12384 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count));
12385 ins_cost(INSN_COST * 2);
12386 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
12387 ins_encode %{
12388 int lshift = $lshift_count$$constant & 63;
12389 int rshift = $rshift_count$$constant & 63;
12390 int s = 63 - lshift;
12391 int r = (rshift - lshift) & 63;
12392 __ sbfm(as_Register($dst$$reg),
12393 as_Register($src$$reg),
12394 r, s);
12395 %}
12396
12397 ins_pipe(ialu_reg_shift);
12398 %}
12399
12400 // This pattern is automatically generated from aarch64_ad.m4
12401 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12402
12403 // Shift Left followed by Shift Right.
12404 // This idiom is used by the compiler for the i2b bytecode etc.
12405 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
12406 %{
12407 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count));
12408 ins_cost(INSN_COST * 2);
12409 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
12410 ins_encode %{
12411 int lshift = $lshift_count$$constant & 31;
12412 int rshift = $rshift_count$$constant & 31;
12413 int s = 31 - lshift;
12414 int r = (rshift - lshift) & 31;
12415 __ sbfmw(as_Register($dst$$reg),
12416 as_Register($src$$reg),
12417 r, s);
12418 %}
12419
12420 ins_pipe(ialu_reg_shift);
12421 %}
12422
12423 // This pattern is automatically generated from aarch64_ad.m4
12424 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12425
12426 // Shift Left followed by Shift Right.
12427 // This idiom is used by the compiler for the i2b bytecode etc.
12428 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
12429 %{
12430 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count));
12431 ins_cost(INSN_COST * 2);
12432 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
12433 ins_encode %{
12434 int lshift = $lshift_count$$constant & 63;
12435 int rshift = $rshift_count$$constant & 63;
12436 int s = 63 - lshift;
12437 int r = (rshift - lshift) & 63;
12438 __ ubfm(as_Register($dst$$reg),
12439 as_Register($src$$reg),
12440 r, s);
12441 %}
12442
12443 ins_pipe(ialu_reg_shift);
12444 %}
12445
12446 // This pattern is automatically generated from aarch64_ad.m4
12447 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12448
12449 // Shift Left followed by Shift Right.
12450 // This idiom is used by the compiler for the i2b bytecode etc.
12451 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
12452 %{
12453 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count));
12454 ins_cost(INSN_COST * 2);
12455 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
12456 ins_encode %{
12457 int lshift = $lshift_count$$constant & 31;
12458 int rshift = $rshift_count$$constant & 31;
12459 int s = 31 - lshift;
12460 int r = (rshift - lshift) & 31;
12461 __ ubfmw(as_Register($dst$$reg),
12462 as_Register($src$$reg),
12463 r, s);
12464 %}
12465
12466 ins_pipe(ialu_reg_shift);
12467 %}
12468
12469 // Bitfield extract with shift & mask
12470
12471 // This pattern is automatically generated from aarch64_ad.m4
12472 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12473 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
12474 %{
12475 match(Set dst (AndI (URShiftI src rshift) mask));
12476 // Make sure we are not going to exceed what ubfxw can do.
12477 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
12478
12479 ins_cost(INSN_COST);
12480 format %{ "ubfxw $dst, $src, $rshift, $mask" %}
12481 ins_encode %{
12482 int rshift = $rshift$$constant & 31;
12483 intptr_t mask = $mask$$constant;
12484 int width = exact_log2(mask+1);
12485 __ ubfxw(as_Register($dst$$reg),
12486 as_Register($src$$reg), rshift, width);
12487 %}
12488 ins_pipe(ialu_reg_shift);
12489 %}
12490
12491 // This pattern is automatically generated from aarch64_ad.m4
12492 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12493 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask)
12494 %{
12495 match(Set dst (AndL (URShiftL src rshift) mask));
12496 // Make sure we are not going to exceed what ubfx can do.
12497 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1));
12498
12499 ins_cost(INSN_COST);
12500 format %{ "ubfx $dst, $src, $rshift, $mask" %}
12501 ins_encode %{
12502 int rshift = $rshift$$constant & 63;
12503 intptr_t mask = $mask$$constant;
12504 int width = exact_log2_long(mask+1);
12505 __ ubfx(as_Register($dst$$reg),
12506 as_Register($src$$reg), rshift, width);
12507 %}
12508 ins_pipe(ialu_reg_shift);
12509 %}
12510
12511
12512 // This pattern is automatically generated from aarch64_ad.m4
12513 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12514
12515 // We can use ubfx when extending an And with a mask when we know mask
12516 // is positive. We know that because immI_bitmask guarantees it.
12517 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
12518 %{
12519 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
12520 // Make sure we are not going to exceed what ubfxw can do.
12521 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
12522
12523 ins_cost(INSN_COST * 2);
12524 format %{ "ubfx $dst, $src, $rshift, $mask" %}
12525 ins_encode %{
12526 int rshift = $rshift$$constant & 31;
12527 intptr_t mask = $mask$$constant;
12528 int width = exact_log2(mask+1);
12529 __ ubfx(as_Register($dst$$reg),
12530 as_Register($src$$reg), rshift, width);
12531 %}
12532 ins_pipe(ialu_reg_shift);
12533 %}
12534
12535
12536 // This pattern is automatically generated from aarch64_ad.m4
12537 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12538
12539 // We can use ubfiz when masking by a positive number and then left shifting the result.
12540 // We know that the mask is positive because immI_bitmask guarantees it.
12541 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
12542 %{
12543 match(Set dst (LShiftI (AndI src mask) lshift));
12544 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1));
12545
12546 ins_cost(INSN_COST);
12547 format %{ "ubfizw $dst, $src, $lshift, $mask" %}
12548 ins_encode %{
12549 int lshift = $lshift$$constant & 31;
12550 intptr_t mask = $mask$$constant;
12551 int width = exact_log2(mask+1);
12552 __ ubfizw(as_Register($dst$$reg),
12553 as_Register($src$$reg), lshift, width);
12554 %}
12555 ins_pipe(ialu_reg_shift);
12556 %}
12557
12558 // This pattern is automatically generated from aarch64_ad.m4
12559 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12560
12561 // We can use ubfiz when masking by a positive number and then left shifting the result.
12562 // We know that the mask is positive because immL_bitmask guarantees it.
12563 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
12564 %{
12565 match(Set dst (LShiftL (AndL src mask) lshift));
12566 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
12567
12568 ins_cost(INSN_COST);
12569 format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12570 ins_encode %{
12571 int lshift = $lshift$$constant & 63;
12572 intptr_t mask = $mask$$constant;
12573 int width = exact_log2_long(mask+1);
12574 __ ubfiz(as_Register($dst$$reg),
12575 as_Register($src$$reg), lshift, width);
12576 %}
12577 ins_pipe(ialu_reg_shift);
12578 %}
12579
12580 // This pattern is automatically generated from aarch64_ad.m4
12581 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12582
12583 // We can use ubfiz when masking by a positive number and then left shifting the result.
12584 // We know that the mask is positive because immI_bitmask guarantees it.
12585 instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
12586 %{
12587 match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift)));
12588 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31);
12589
12590 ins_cost(INSN_COST);
12591 format %{ "ubfizw $dst, $src, $lshift, $mask" %}
12592 ins_encode %{
12593 int lshift = $lshift$$constant & 31;
12594 intptr_t mask = $mask$$constant;
12595 int width = exact_log2(mask+1);
12596 __ ubfizw(as_Register($dst$$reg),
12597 as_Register($src$$reg), lshift, width);
12598 %}
12599 ins_pipe(ialu_reg_shift);
12600 %}
12601
12602 // This pattern is automatically generated from aarch64_ad.m4
12603 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12604
12605 // We can use ubfiz when masking by a positive number and then left shifting the result.
12606 // We know that the mask is positive because immL_bitmask guarantees it.
12607 instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
12608 %{
12609 match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift)));
12610 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31);
12611
12612 ins_cost(INSN_COST);
12613 format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12614 ins_encode %{
12615 int lshift = $lshift$$constant & 63;
12616 intptr_t mask = $mask$$constant;
12617 int width = exact_log2_long(mask+1);
12618 __ ubfiz(as_Register($dst$$reg),
12619 as_Register($src$$reg), lshift, width);
12620 %}
12621 ins_pipe(ialu_reg_shift);
12622 %}
12623
12624
12625 // This pattern is automatically generated from aarch64_ad.m4
12626 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12627
12628 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
12629 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
12630 %{
12631 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift));
12632 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
12633
12634 ins_cost(INSN_COST);
12635 format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12636 ins_encode %{
12637 int lshift = $lshift$$constant & 63;
12638 intptr_t mask = $mask$$constant;
12639 int width = exact_log2(mask+1);
12640 __ ubfiz(as_Register($dst$$reg),
12641 as_Register($src$$reg), lshift, width);
12642 %}
12643 ins_pipe(ialu_reg_shift);
12644 %}
12645
12646 // This pattern is automatically generated from aarch64_ad.m4
12647 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12648
12649 // If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz
12650 instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
12651 %{
12652 match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift));
12653 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31);
12654
12655 ins_cost(INSN_COST);
12656 format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12657 ins_encode %{
12658 int lshift = $lshift$$constant & 31;
12659 intptr_t mask = $mask$$constant;
12660 int width = exact_log2(mask+1);
12661 __ ubfiz(as_Register($dst$$reg),
12662 as_Register($src$$reg), lshift, width);
12663 %}
12664 ins_pipe(ialu_reg_shift);
12665 %}
12666
12667 // This pattern is automatically generated from aarch64_ad.m4
12668 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12669
12670 // Can skip int2long conversions after AND with small bitmask
12671 instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk)
12672 %{
12673 match(Set dst (ConvI2L (AndI src msk)));
12674 ins_cost(INSN_COST);
12675 format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %}
12676 ins_encode %{
12677 __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1));
12678 %}
12679 ins_pipe(ialu_reg_shift);
12680 %}
12681
12682
12683 // Rotations
12684
12685 // This pattern is automatically generated from aarch64_ad.m4
12686 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12687 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
12688 %{
12689 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift)));
12690 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
12691
12692 ins_cost(INSN_COST);
12693 format %{ "extr $dst, $src1, $src2, #$rshift" %}
12694
12695 ins_encode %{
12696 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12697 $rshift$$constant & 63);
12698 %}
12699 ins_pipe(ialu_reg_reg_extr);
12700 %}
12701
12702
12703 // This pattern is automatically generated from aarch64_ad.m4
12704 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12705 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
12706 %{
12707 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift)));
12708 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
12709
12710 ins_cost(INSN_COST);
12711 format %{ "extr $dst, $src1, $src2, #$rshift" %}
12712
12713 ins_encode %{
12714 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12715 $rshift$$constant & 31);
12716 %}
12717 ins_pipe(ialu_reg_reg_extr);
12718 %}
12719
12720
12721 // This pattern is automatically generated from aarch64_ad.m4
12722 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12723 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
12724 %{
12725 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift)));
12726 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
12727
12728 ins_cost(INSN_COST);
12729 format %{ "extr $dst, $src1, $src2, #$rshift" %}
12730
12731 ins_encode %{
12732 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12733 $rshift$$constant & 63);
12734 %}
12735 ins_pipe(ialu_reg_reg_extr);
12736 %}
12737
12738
12739 // This pattern is automatically generated from aarch64_ad.m4
12740 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12741 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
12742 %{
12743 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift)));
12744 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
12745
12746 ins_cost(INSN_COST);
12747 format %{ "extr $dst, $src1, $src2, #$rshift" %}
12748
12749 ins_encode %{
12750 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12751 $rshift$$constant & 31);
12752 %}
12753 ins_pipe(ialu_reg_reg_extr);
12754 %}
12755
12756 // This pattern is automatically generated from aarch64_ad.m4
12757 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12758 instruct rorI_imm(iRegINoSp dst, iRegI src, immI shift)
12759 %{
12760 match(Set dst (RotateRight src shift));
12761
12762 ins_cost(INSN_COST);
12763 format %{ "ror $dst, $src, $shift" %}
12764
12765 ins_encode %{
12766 __ extrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg),
12767 $shift$$constant & 0x1f);
12768 %}
12769 ins_pipe(ialu_reg_reg_vshift);
12770 %}
12771
12772 // This pattern is automatically generated from aarch64_ad.m4
12773 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12774 instruct rorL_imm(iRegLNoSp dst, iRegL src, immI shift)
12775 %{
12776 match(Set dst (RotateRight src shift));
12777
12778 ins_cost(INSN_COST);
12779 format %{ "ror $dst, $src, $shift" %}
12780
12781 ins_encode %{
12782 __ extr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg),
12783 $shift$$constant & 0x3f);
12784 %}
12785 ins_pipe(ialu_reg_reg_vshift);
12786 %}
12787
12788 // This pattern is automatically generated from aarch64_ad.m4
12789 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12790 instruct rorI_reg(iRegINoSp dst, iRegI src, iRegI shift)
12791 %{
12792 match(Set dst (RotateRight src shift));
12793
12794 ins_cost(INSN_COST);
12795 format %{ "ror $dst, $src, $shift" %}
12796
12797 ins_encode %{
12798 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg));
12799 %}
12800 ins_pipe(ialu_reg_reg_vshift);
12801 %}
12802
12803 // This pattern is automatically generated from aarch64_ad.m4
12804 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12805 instruct rorL_reg(iRegLNoSp dst, iRegL src, iRegI shift)
12806 %{
12807 match(Set dst (RotateRight src shift));
12808
12809 ins_cost(INSN_COST);
12810 format %{ "ror $dst, $src, $shift" %}
12811
12812 ins_encode %{
12813 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg));
12814 %}
12815 ins_pipe(ialu_reg_reg_vshift);
12816 %}
12817
12818 // This pattern is automatically generated from aarch64_ad.m4
12819 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12820 instruct rolI_reg(iRegINoSp dst, iRegI src, iRegI shift)
12821 %{
12822 match(Set dst (RotateLeft src shift));
12823
12824 ins_cost(INSN_COST);
12825 format %{ "rol $dst, $src, $shift" %}
12826
12827 ins_encode %{
12828 __ subw(rscratch1, zr, as_Register($shift$$reg));
12829 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), rscratch1);
12830 %}
12831 ins_pipe(ialu_reg_reg_vshift);
12832 %}
12833
12834 // This pattern is automatically generated from aarch64_ad.m4
12835 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12836 instruct rolL_reg(iRegLNoSp dst, iRegL src, iRegI shift)
12837 %{
12838 match(Set dst (RotateLeft src shift));
12839
12840 ins_cost(INSN_COST);
12841 format %{ "rol $dst, $src, $shift" %}
12842
12843 ins_encode %{
12844 __ subw(rscratch1, zr, as_Register($shift$$reg));
12845 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), rscratch1);
12846 %}
12847 ins_pipe(ialu_reg_reg_vshift);
12848 %}
12849
12850
12851 // Add/subtract (extended)
12852
12853 // This pattern is automatically generated from aarch64_ad.m4
12854 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12855 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
12856 %{
12857 match(Set dst (AddL src1 (ConvI2L src2)));
12858 ins_cost(INSN_COST);
12859 format %{ "add $dst, $src1, $src2, sxtw" %}
12860
12861 ins_encode %{
12862 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12863 as_Register($src2$$reg), ext::sxtw);
12864 %}
12865 ins_pipe(ialu_reg_reg);
12866 %}
12867
12868 // This pattern is automatically generated from aarch64_ad.m4
12869 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12870 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
12871 %{
12872 match(Set dst (SubL src1 (ConvI2L src2)));
12873 ins_cost(INSN_COST);
12874 format %{ "sub $dst, $src1, $src2, sxtw" %}
12875
12876 ins_encode %{
12877 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12878 as_Register($src2$$reg), ext::sxtw);
12879 %}
12880 ins_pipe(ialu_reg_reg);
12881 %}
12882
12883 // This pattern is automatically generated from aarch64_ad.m4
12884 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12885 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr)
12886 %{
12887 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
12888 ins_cost(INSN_COST);
12889 format %{ "add $dst, $src1, $src2, sxth" %}
12890
12891 ins_encode %{
12892 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12893 as_Register($src2$$reg), ext::sxth);
12894 %}
12895 ins_pipe(ialu_reg_reg);
12896 %}
12897
12898 // This pattern is automatically generated from aarch64_ad.m4
12899 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12900 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
12901 %{
12902 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
12903 ins_cost(INSN_COST);
12904 format %{ "add $dst, $src1, $src2, sxtb" %}
12905
12906 ins_encode %{
12907 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12908 as_Register($src2$$reg), ext::sxtb);
12909 %}
12910 ins_pipe(ialu_reg_reg);
12911 %}
12912
12913 // This pattern is automatically generated from aarch64_ad.m4
12914 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12915 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
12916 %{
12917 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift)));
12918 ins_cost(INSN_COST);
12919 format %{ "add $dst, $src1, $src2, uxtb" %}
12920
12921 ins_encode %{
12922 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12923 as_Register($src2$$reg), ext::uxtb);
12924 %}
12925 ins_pipe(ialu_reg_reg);
12926 %}
12927
12928 // This pattern is automatically generated from aarch64_ad.m4
12929 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12930 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr)
12931 %{
12932 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
12933 ins_cost(INSN_COST);
12934 format %{ "add $dst, $src1, $src2, sxth" %}
12935
12936 ins_encode %{
12937 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12938 as_Register($src2$$reg), ext::sxth);
12939 %}
12940 ins_pipe(ialu_reg_reg);
12941 %}
12942
12943 // This pattern is automatically generated from aarch64_ad.m4
12944 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12945 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr)
12946 %{
12947 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
12948 ins_cost(INSN_COST);
12949 format %{ "add $dst, $src1, $src2, sxtw" %}
12950
12951 ins_encode %{
12952 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12953 as_Register($src2$$reg), ext::sxtw);
12954 %}
12955 ins_pipe(ialu_reg_reg);
12956 %}
12957
12958 // This pattern is automatically generated from aarch64_ad.m4
12959 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12960 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
12961 %{
12962 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
12963 ins_cost(INSN_COST);
12964 format %{ "add $dst, $src1, $src2, sxtb" %}
12965
12966 ins_encode %{
12967 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12968 as_Register($src2$$reg), ext::sxtb);
12969 %}
12970 ins_pipe(ialu_reg_reg);
12971 %}
12972
12973 // This pattern is automatically generated from aarch64_ad.m4
12974 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12975 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
12976 %{
12977 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift)));
12978 ins_cost(INSN_COST);
12979 format %{ "add $dst, $src1, $src2, uxtb" %}
12980
12981 ins_encode %{
12982 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12983 as_Register($src2$$reg), ext::uxtb);
12984 %}
12985 ins_pipe(ialu_reg_reg);
12986 %}
12987
12988 // This pattern is automatically generated from aarch64_ad.m4
12989 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12990 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
12991 %{
12992 match(Set dst (AddI src1 (AndI src2 mask)));
12993 ins_cost(INSN_COST);
12994 format %{ "addw $dst, $src1, $src2, uxtb" %}
12995
12996 ins_encode %{
12997 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
12998 as_Register($src2$$reg), ext::uxtb);
12999 %}
13000 ins_pipe(ialu_reg_reg);
13001 %}
13002
13003 // This pattern is automatically generated from aarch64_ad.m4
13004 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13005 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
13006 %{
13007 match(Set dst (AddI src1 (AndI src2 mask)));
13008 ins_cost(INSN_COST);
13009 format %{ "addw $dst, $src1, $src2, uxth" %}
13010
13011 ins_encode %{
13012 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13013 as_Register($src2$$reg), ext::uxth);
13014 %}
13015 ins_pipe(ialu_reg_reg);
13016 %}
13017
13018 // This pattern is automatically generated from aarch64_ad.m4
13019 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13020 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
13021 %{
13022 match(Set dst (AddL src1 (AndL src2 mask)));
13023 ins_cost(INSN_COST);
13024 format %{ "add $dst, $src1, $src2, uxtb" %}
13025
13026 ins_encode %{
13027 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13028 as_Register($src2$$reg), ext::uxtb);
13029 %}
13030 ins_pipe(ialu_reg_reg);
13031 %}
13032
13033 // This pattern is automatically generated from aarch64_ad.m4
13034 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13035 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
13036 %{
13037 match(Set dst (AddL src1 (AndL src2 mask)));
13038 ins_cost(INSN_COST);
13039 format %{ "add $dst, $src1, $src2, uxth" %}
13040
13041 ins_encode %{
13042 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13043 as_Register($src2$$reg), ext::uxth);
13044 %}
13045 ins_pipe(ialu_reg_reg);
13046 %}
13047
13048 // This pattern is automatically generated from aarch64_ad.m4
13049 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13050 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
13051 %{
13052 match(Set dst (AddL src1 (AndL src2 mask)));
13053 ins_cost(INSN_COST);
13054 format %{ "add $dst, $src1, $src2, uxtw" %}
13055
13056 ins_encode %{
13057 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13058 as_Register($src2$$reg), ext::uxtw);
13059 %}
13060 ins_pipe(ialu_reg_reg);
13061 %}
13062
13063 // This pattern is automatically generated from aarch64_ad.m4
13064 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13065 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
13066 %{
13067 match(Set dst (SubI src1 (AndI src2 mask)));
13068 ins_cost(INSN_COST);
13069 format %{ "subw $dst, $src1, $src2, uxtb" %}
13070
13071 ins_encode %{
13072 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13073 as_Register($src2$$reg), ext::uxtb);
13074 %}
13075 ins_pipe(ialu_reg_reg);
13076 %}
13077
13078 // This pattern is automatically generated from aarch64_ad.m4
13079 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13080 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
13081 %{
13082 match(Set dst (SubI src1 (AndI src2 mask)));
13083 ins_cost(INSN_COST);
13084 format %{ "subw $dst, $src1, $src2, uxth" %}
13085
13086 ins_encode %{
13087 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13088 as_Register($src2$$reg), ext::uxth);
13089 %}
13090 ins_pipe(ialu_reg_reg);
13091 %}
13092
13093 // This pattern is automatically generated from aarch64_ad.m4
13094 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13095 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
13096 %{
13097 match(Set dst (SubL src1 (AndL src2 mask)));
13098 ins_cost(INSN_COST);
13099 format %{ "sub $dst, $src1, $src2, uxtb" %}
13100
13101 ins_encode %{
13102 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13103 as_Register($src2$$reg), ext::uxtb);
13104 %}
13105 ins_pipe(ialu_reg_reg);
13106 %}
13107
13108 // This pattern is automatically generated from aarch64_ad.m4
13109 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13110 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
13111 %{
13112 match(Set dst (SubL src1 (AndL src2 mask)));
13113 ins_cost(INSN_COST);
13114 format %{ "sub $dst, $src1, $src2, uxth" %}
13115
13116 ins_encode %{
13117 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13118 as_Register($src2$$reg), ext::uxth);
13119 %}
13120 ins_pipe(ialu_reg_reg);
13121 %}
13122
13123 // This pattern is automatically generated from aarch64_ad.m4
13124 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13125 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
13126 %{
13127 match(Set dst (SubL src1 (AndL src2 mask)));
13128 ins_cost(INSN_COST);
13129 format %{ "sub $dst, $src1, $src2, uxtw" %}
13130
13131 ins_encode %{
13132 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13133 as_Register($src2$$reg), ext::uxtw);
13134 %}
13135 ins_pipe(ialu_reg_reg);
13136 %}
13137
13138
13139 // This pattern is automatically generated from aarch64_ad.m4
13140 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13141 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
13142 %{
13143 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13144 ins_cost(1.9 * INSN_COST);
13145 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %}
13146
13147 ins_encode %{
13148 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13149 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13150 %}
13151 ins_pipe(ialu_reg_reg_shift);
13152 %}
13153
13154 // This pattern is automatically generated from aarch64_ad.m4
13155 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13156 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
13157 %{
13158 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13159 ins_cost(1.9 * INSN_COST);
13160 format %{ "add $dst, $src1, $src2, sxth #lshift2" %}
13161
13162 ins_encode %{
13163 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13164 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13165 %}
13166 ins_pipe(ialu_reg_reg_shift);
13167 %}
13168
13169 // This pattern is automatically generated from aarch64_ad.m4
13170 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13171 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
13172 %{
13173 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13174 ins_cost(1.9 * INSN_COST);
13175 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %}
13176
13177 ins_encode %{
13178 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13179 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
13180 %}
13181 ins_pipe(ialu_reg_reg_shift);
13182 %}
13183
13184 // This pattern is automatically generated from aarch64_ad.m4
13185 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13186 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
13187 %{
13188 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13189 ins_cost(1.9 * INSN_COST);
13190 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %}
13191
13192 ins_encode %{
13193 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13194 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13195 %}
13196 ins_pipe(ialu_reg_reg_shift);
13197 %}
13198
13199 // This pattern is automatically generated from aarch64_ad.m4
13200 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13201 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
13202 %{
13203 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13204 ins_cost(1.9 * INSN_COST);
13205 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %}
13206
13207 ins_encode %{
13208 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13209 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13210 %}
13211 ins_pipe(ialu_reg_reg_shift);
13212 %}
13213
13214 // This pattern is automatically generated from aarch64_ad.m4
13215 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13216 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
13217 %{
13218 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13219 ins_cost(1.9 * INSN_COST);
13220 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %}
13221
13222 ins_encode %{
13223 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13224 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
13225 %}
13226 ins_pipe(ialu_reg_reg_shift);
13227 %}
13228
13229 // This pattern is automatically generated from aarch64_ad.m4
13230 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13231 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
13232 %{
13233 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13234 ins_cost(1.9 * INSN_COST);
13235 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %}
13236
13237 ins_encode %{
13238 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13239 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13240 %}
13241 ins_pipe(ialu_reg_reg_shift);
13242 %}
13243
13244 // This pattern is automatically generated from aarch64_ad.m4
13245 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13246 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
13247 %{
13248 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13249 ins_cost(1.9 * INSN_COST);
13250 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %}
13251
13252 ins_encode %{
13253 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13254 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13255 %}
13256 ins_pipe(ialu_reg_reg_shift);
13257 %}
13258
13259 // This pattern is automatically generated from aarch64_ad.m4
13260 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13261 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
13262 %{
13263 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13264 ins_cost(1.9 * INSN_COST);
13265 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %}
13266
13267 ins_encode %{
13268 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13269 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13270 %}
13271 ins_pipe(ialu_reg_reg_shift);
13272 %}
13273
13274 // This pattern is automatically generated from aarch64_ad.m4
13275 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13276 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
13277 %{
13278 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13279 ins_cost(1.9 * INSN_COST);
13280 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %}
13281
13282 ins_encode %{
13283 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13284 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13285 %}
13286 ins_pipe(ialu_reg_reg_shift);
13287 %}
13288
13289 // This pattern is automatically generated from aarch64_ad.m4
13290 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13291 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
13292 %{
13293 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift)));
13294 ins_cost(1.9 * INSN_COST);
13295 format %{ "add $dst, $src1, $src2, sxtw #lshift" %}
13296
13297 ins_encode %{
13298 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13299 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
13300 %}
13301 ins_pipe(ialu_reg_reg_shift);
13302 %}
13303
13304 // This pattern is automatically generated from aarch64_ad.m4
13305 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13306 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
13307 %{
13308 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift)));
13309 ins_cost(1.9 * INSN_COST);
13310 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %}
13311
13312 ins_encode %{
13313 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13314 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
13315 %}
13316 ins_pipe(ialu_reg_reg_shift);
13317 %}
13318
13319 // This pattern is automatically generated from aarch64_ad.m4
13320 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13321 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
13322 %{
13323 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
13324 ins_cost(1.9 * INSN_COST);
13325 format %{ "add $dst, $src1, $src2, uxtb #lshift" %}
13326
13327 ins_encode %{
13328 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13329 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13330 %}
13331 ins_pipe(ialu_reg_reg_shift);
13332 %}
13333
13334 // This pattern is automatically generated from aarch64_ad.m4
13335 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13336 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
13337 %{
13338 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
13339 ins_cost(1.9 * INSN_COST);
13340 format %{ "add $dst, $src1, $src2, uxth #lshift" %}
13341
13342 ins_encode %{
13343 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13344 as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13345 %}
13346 ins_pipe(ialu_reg_reg_shift);
13347 %}
13348
13349 // This pattern is automatically generated from aarch64_ad.m4
13350 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13351 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
13352 %{
13353 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
13354 ins_cost(1.9 * INSN_COST);
13355 format %{ "add $dst, $src1, $src2, uxtw #lshift" %}
13356
13357 ins_encode %{
13358 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13359 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
13360 %}
13361 ins_pipe(ialu_reg_reg_shift);
13362 %}
13363
13364 // This pattern is automatically generated from aarch64_ad.m4
13365 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13366 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
13367 %{
13368 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
13369 ins_cost(1.9 * INSN_COST);
13370 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %}
13371
13372 ins_encode %{
13373 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13374 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13375 %}
13376 ins_pipe(ialu_reg_reg_shift);
13377 %}
13378
13379 // This pattern is automatically generated from aarch64_ad.m4
13380 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13381 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
13382 %{
13383 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
13384 ins_cost(1.9 * INSN_COST);
13385 format %{ "sub $dst, $src1, $src2, uxth #lshift" %}
13386
13387 ins_encode %{
13388 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13389 as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13390 %}
13391 ins_pipe(ialu_reg_reg_shift);
13392 %}
13393
13394 // This pattern is automatically generated from aarch64_ad.m4
13395 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13396 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
13397 %{
13398 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
13399 ins_cost(1.9 * INSN_COST);
13400 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %}
13401
13402 ins_encode %{
13403 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13404 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
13405 %}
13406 ins_pipe(ialu_reg_reg_shift);
13407 %}
13408
13409 // This pattern is automatically generated from aarch64_ad.m4
13410 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13411 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
13412 %{
13413 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
13414 ins_cost(1.9 * INSN_COST);
13415 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %}
13416
13417 ins_encode %{
13418 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13419 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13420 %}
13421 ins_pipe(ialu_reg_reg_shift);
13422 %}
13423
13424 // This pattern is automatically generated from aarch64_ad.m4
13425 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13426 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
13427 %{
13428 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
13429 ins_cost(1.9 * INSN_COST);
13430 format %{ "addw $dst, $src1, $src2, uxth #lshift" %}
13431
13432 ins_encode %{
13433 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13434 as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13435 %}
13436 ins_pipe(ialu_reg_reg_shift);
13437 %}
13438
13439 // This pattern is automatically generated from aarch64_ad.m4
13440 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13441 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
13442 %{
13443 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
13444 ins_cost(1.9 * INSN_COST);
13445 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %}
13446
13447 ins_encode %{
13448 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13449 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13450 %}
13451 ins_pipe(ialu_reg_reg_shift);
13452 %}
13453
13454 // This pattern is automatically generated from aarch64_ad.m4
13455 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13456 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
13457 %{
13458 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
13459 ins_cost(1.9 * INSN_COST);
13460 format %{ "subw $dst, $src1, $src2, uxth #lshift" %}
13461
13462 ins_encode %{
13463 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13464 as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13465 %}
13466 ins_pipe(ialu_reg_reg_shift);
13467 %}
13468
13469 // This pattern is automatically generated from aarch64_ad.m4
13470 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13471 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
13472 %{
13473 effect(DEF dst, USE src1, USE src2, USE cr);
13474 ins_cost(INSN_COST * 2);
13475 format %{ "cselw $dst, $src1, $src2 lt\t" %}
13476
13477 ins_encode %{
13478 __ cselw($dst$$Register,
13479 $src1$$Register,
13480 $src2$$Register,
13481 Assembler::LT);
13482 %}
13483 ins_pipe(icond_reg_reg);
13484 %}
13485
13486 // This pattern is automatically generated from aarch64_ad.m4
13487 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13488 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
13489 %{
13490 effect(DEF dst, USE src1, USE src2, USE cr);
13491 ins_cost(INSN_COST * 2);
13492 format %{ "cselw $dst, $src1, $src2 gt\t" %}
13493
13494 ins_encode %{
13495 __ cselw($dst$$Register,
13496 $src1$$Register,
13497 $src2$$Register,
13498 Assembler::GT);
13499 %}
13500 ins_pipe(icond_reg_reg);
13501 %}
13502
13503 // This pattern is automatically generated from aarch64_ad.m4
13504 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13505 instruct cmovI_reg_imm0_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13506 %{
13507 effect(DEF dst, USE src1, USE cr);
13508 ins_cost(INSN_COST * 2);
13509 format %{ "cselw $dst, $src1, zr lt\t" %}
13510
13511 ins_encode %{
13512 __ cselw($dst$$Register,
13513 $src1$$Register,
13514 zr,
13515 Assembler::LT);
13516 %}
13517 ins_pipe(icond_reg);
13518 %}
13519
13520 // This pattern is automatically generated from aarch64_ad.m4
13521 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13522 instruct cmovI_reg_imm0_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13523 %{
13524 effect(DEF dst, USE src1, USE cr);
13525 ins_cost(INSN_COST * 2);
13526 format %{ "cselw $dst, $src1, zr gt\t" %}
13527
13528 ins_encode %{
13529 __ cselw($dst$$Register,
13530 $src1$$Register,
13531 zr,
13532 Assembler::GT);
13533 %}
13534 ins_pipe(icond_reg);
13535 %}
13536
13537 // This pattern is automatically generated from aarch64_ad.m4
13538 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13539 instruct cmovI_reg_imm1_le(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13540 %{
13541 effect(DEF dst, USE src1, USE cr);
13542 ins_cost(INSN_COST * 2);
13543 format %{ "csincw $dst, $src1, zr le\t" %}
13544
13545 ins_encode %{
13546 __ csincw($dst$$Register,
13547 $src1$$Register,
13548 zr,
13549 Assembler::LE);
13550 %}
13551 ins_pipe(icond_reg);
13552 %}
13553
13554 // This pattern is automatically generated from aarch64_ad.m4
13555 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13556 instruct cmovI_reg_imm1_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13557 %{
13558 effect(DEF dst, USE src1, USE cr);
13559 ins_cost(INSN_COST * 2);
13560 format %{ "csincw $dst, $src1, zr gt\t" %}
13561
13562 ins_encode %{
13563 __ csincw($dst$$Register,
13564 $src1$$Register,
13565 zr,
13566 Assembler::GT);
13567 %}
13568 ins_pipe(icond_reg);
13569 %}
13570
13571 // This pattern is automatically generated from aarch64_ad.m4
13572 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13573 instruct cmovI_reg_immM1_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13574 %{
13575 effect(DEF dst, USE src1, USE cr);
13576 ins_cost(INSN_COST * 2);
13577 format %{ "csinvw $dst, $src1, zr lt\t" %}
13578
13579 ins_encode %{
13580 __ csinvw($dst$$Register,
13581 $src1$$Register,
13582 zr,
13583 Assembler::LT);
13584 %}
13585 ins_pipe(icond_reg);
13586 %}
13587
13588 // This pattern is automatically generated from aarch64_ad.m4
13589 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13590 instruct cmovI_reg_immM1_ge(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13591 %{
13592 effect(DEF dst, USE src1, USE cr);
13593 ins_cost(INSN_COST * 2);
13594 format %{ "csinvw $dst, $src1, zr ge\t" %}
13595
13596 ins_encode %{
13597 __ csinvw($dst$$Register,
13598 $src1$$Register,
13599 zr,
13600 Assembler::GE);
13601 %}
13602 ins_pipe(icond_reg);
13603 %}
13604
13605 // This pattern is automatically generated from aarch64_ad.m4
13606 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13607 instruct minI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm)
13608 %{
13609 match(Set dst (MinI src imm));
13610 ins_cost(INSN_COST * 3);
13611 expand %{
13612 rFlagsReg cr;
13613 compI_reg_imm0(cr, src);
13614 cmovI_reg_imm0_lt(dst, src, cr);
13615 %}
13616 %}
13617
13618 // This pattern is automatically generated from aarch64_ad.m4
13619 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13620 instruct minI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src)
13621 %{
13622 match(Set dst (MinI imm src));
13623 ins_cost(INSN_COST * 3);
13624 expand %{
13625 rFlagsReg cr;
13626 compI_reg_imm0(cr, src);
13627 cmovI_reg_imm0_lt(dst, src, cr);
13628 %}
13629 %}
13630
13631 // This pattern is automatically generated from aarch64_ad.m4
13632 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13633 instruct minI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm)
13634 %{
13635 match(Set dst (MinI src imm));
13636 ins_cost(INSN_COST * 3);
13637 expand %{
13638 rFlagsReg cr;
13639 compI_reg_imm0(cr, src);
13640 cmovI_reg_imm1_le(dst, src, cr);
13641 %}
13642 %}
13643
13644 // This pattern is automatically generated from aarch64_ad.m4
13645 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13646 instruct minI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src)
13647 %{
13648 match(Set dst (MinI imm src));
13649 ins_cost(INSN_COST * 3);
13650 expand %{
13651 rFlagsReg cr;
13652 compI_reg_imm0(cr, src);
13653 cmovI_reg_imm1_le(dst, src, cr);
13654 %}
13655 %}
13656
13657 // This pattern is automatically generated from aarch64_ad.m4
13658 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13659 instruct minI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm)
13660 %{
13661 match(Set dst (MinI src imm));
13662 ins_cost(INSN_COST * 3);
13663 expand %{
13664 rFlagsReg cr;
13665 compI_reg_imm0(cr, src);
13666 cmovI_reg_immM1_lt(dst, src, cr);
13667 %}
13668 %}
13669
13670 // This pattern is automatically generated from aarch64_ad.m4
13671 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13672 instruct minI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src)
13673 %{
13674 match(Set dst (MinI imm src));
13675 ins_cost(INSN_COST * 3);
13676 expand %{
13677 rFlagsReg cr;
13678 compI_reg_imm0(cr, src);
13679 cmovI_reg_immM1_lt(dst, src, cr);
13680 %}
13681 %}
13682
13683 // This pattern is automatically generated from aarch64_ad.m4
13684 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13685 instruct maxI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm)
13686 %{
13687 match(Set dst (MaxI src imm));
13688 ins_cost(INSN_COST * 3);
13689 expand %{
13690 rFlagsReg cr;
13691 compI_reg_imm0(cr, src);
13692 cmovI_reg_imm0_gt(dst, src, cr);
13693 %}
13694 %}
13695
13696 // This pattern is automatically generated from aarch64_ad.m4
13697 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13698 instruct maxI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src)
13699 %{
13700 match(Set dst (MaxI imm src));
13701 ins_cost(INSN_COST * 3);
13702 expand %{
13703 rFlagsReg cr;
13704 compI_reg_imm0(cr, src);
13705 cmovI_reg_imm0_gt(dst, src, cr);
13706 %}
13707 %}
13708
13709 // This pattern is automatically generated from aarch64_ad.m4
13710 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13711 instruct maxI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm)
13712 %{
13713 match(Set dst (MaxI src imm));
13714 ins_cost(INSN_COST * 3);
13715 expand %{
13716 rFlagsReg cr;
13717 compI_reg_imm0(cr, src);
13718 cmovI_reg_imm1_gt(dst, src, cr);
13719 %}
13720 %}
13721
13722 // This pattern is automatically generated from aarch64_ad.m4
13723 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13724 instruct maxI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src)
13725 %{
13726 match(Set dst (MaxI imm src));
13727 ins_cost(INSN_COST * 3);
13728 expand %{
13729 rFlagsReg cr;
13730 compI_reg_imm0(cr, src);
13731 cmovI_reg_imm1_gt(dst, src, cr);
13732 %}
13733 %}
13734
13735 // This pattern is automatically generated from aarch64_ad.m4
13736 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13737 instruct maxI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm)
13738 %{
13739 match(Set dst (MaxI src imm));
13740 ins_cost(INSN_COST * 3);
13741 expand %{
13742 rFlagsReg cr;
13743 compI_reg_imm0(cr, src);
13744 cmovI_reg_immM1_ge(dst, src, cr);
13745 %}
13746 %}
13747
13748 // This pattern is automatically generated from aarch64_ad.m4
13749 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13750 instruct maxI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src)
13751 %{
13752 match(Set dst (MaxI imm src));
13753 ins_cost(INSN_COST * 3);
13754 expand %{
13755 rFlagsReg cr;
13756 compI_reg_imm0(cr, src);
13757 cmovI_reg_immM1_ge(dst, src, cr);
13758 %}
13759 %}
13760
13761 // This pattern is automatically generated from aarch64_ad.m4
13762 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13763 instruct bits_reverse_I(iRegINoSp dst, iRegIorL2I src)
13764 %{
13765 match(Set dst (ReverseI src));
13766 ins_cost(INSN_COST);
13767 format %{ "rbitw $dst, $src" %}
13768 ins_encode %{
13769 __ rbitw($dst$$Register, $src$$Register);
13770 %}
13771 ins_pipe(ialu_reg);
13772 %}
13773
13774 // This pattern is automatically generated from aarch64_ad.m4
13775 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13776 instruct bits_reverse_L(iRegLNoSp dst, iRegL src)
13777 %{
13778 match(Set dst (ReverseL src));
13779 ins_cost(INSN_COST);
13780 format %{ "rbit $dst, $src" %}
13781 ins_encode %{
13782 __ rbit($dst$$Register, $src$$Register);
13783 %}
13784 ins_pipe(ialu_reg);
13785 %}
13786
13787
13788 // END This section of the file is automatically generated. Do not edit --------------
13789
13790
13791 // ============================================================================
13792 // Floating Point Arithmetic Instructions
13793
13794 instruct addHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13795 match(Set dst (AddHF src1 src2));
13796 format %{ "faddh $dst, $src1, $src2" %}
13797 ins_encode %{
13798 __ faddh($dst$$FloatRegister,
13799 $src1$$FloatRegister,
13800 $src2$$FloatRegister);
13801 %}
13802 ins_pipe(fp_dop_reg_reg_s);
13803 %}
13804
13805 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13806 match(Set dst (AddF src1 src2));
13807
13808 ins_cost(INSN_COST * 5);
13809 format %{ "fadds $dst, $src1, $src2" %}
13810
13811 ins_encode %{
13812 __ fadds(as_FloatRegister($dst$$reg),
13813 as_FloatRegister($src1$$reg),
13814 as_FloatRegister($src2$$reg));
13815 %}
13816
13817 ins_pipe(fp_dop_reg_reg_s);
13818 %}
13819
13820 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
13821 match(Set dst (AddD src1 src2));
13822
13823 ins_cost(INSN_COST * 5);
13824 format %{ "faddd $dst, $src1, $src2" %}
13825
13826 ins_encode %{
13827 __ faddd(as_FloatRegister($dst$$reg),
13828 as_FloatRegister($src1$$reg),
13829 as_FloatRegister($src2$$reg));
13830 %}
13831
13832 ins_pipe(fp_dop_reg_reg_d);
13833 %}
13834
13835 instruct subHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13836 match(Set dst (SubHF src1 src2));
13837 format %{ "fsubh $dst, $src1, $src2" %}
13838 ins_encode %{
13839 __ fsubh($dst$$FloatRegister,
13840 $src1$$FloatRegister,
13841 $src2$$FloatRegister);
13842 %}
13843 ins_pipe(fp_dop_reg_reg_s);
13844 %}
13845
13846 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13847 match(Set dst (SubF src1 src2));
13848
13849 ins_cost(INSN_COST * 5);
13850 format %{ "fsubs $dst, $src1, $src2" %}
13851
13852 ins_encode %{
13853 __ fsubs(as_FloatRegister($dst$$reg),
13854 as_FloatRegister($src1$$reg),
13855 as_FloatRegister($src2$$reg));
13856 %}
13857
13858 ins_pipe(fp_dop_reg_reg_s);
13859 %}
13860
13861 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
13862 match(Set dst (SubD src1 src2));
13863
13864 ins_cost(INSN_COST * 5);
13865 format %{ "fsubd $dst, $src1, $src2" %}
13866
13867 ins_encode %{
13868 __ fsubd(as_FloatRegister($dst$$reg),
13869 as_FloatRegister($src1$$reg),
13870 as_FloatRegister($src2$$reg));
13871 %}
13872
13873 ins_pipe(fp_dop_reg_reg_d);
13874 %}
13875
13876 instruct mulHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13877 match(Set dst (MulHF src1 src2));
13878 format %{ "fmulh $dst, $src1, $src2" %}
13879 ins_encode %{
13880 __ fmulh($dst$$FloatRegister,
13881 $src1$$FloatRegister,
13882 $src2$$FloatRegister);
13883 %}
13884 ins_pipe(fp_dop_reg_reg_s);
13885 %}
13886
13887 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13888 match(Set dst (MulF src1 src2));
13889
13890 ins_cost(INSN_COST * 6);
13891 format %{ "fmuls $dst, $src1, $src2" %}
13892
13893 ins_encode %{
13894 __ fmuls(as_FloatRegister($dst$$reg),
13895 as_FloatRegister($src1$$reg),
13896 as_FloatRegister($src2$$reg));
13897 %}
13898
13899 ins_pipe(fp_dop_reg_reg_s);
13900 %}
13901
13902 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
13903 match(Set dst (MulD src1 src2));
13904
13905 ins_cost(INSN_COST * 6);
13906 format %{ "fmuld $dst, $src1, $src2" %}
13907
13908 ins_encode %{
13909 __ fmuld(as_FloatRegister($dst$$reg),
13910 as_FloatRegister($src1$$reg),
13911 as_FloatRegister($src2$$reg));
13912 %}
13913
13914 ins_pipe(fp_dop_reg_reg_d);
13915 %}
13916
13917 // src1 * src2 + src3 (half-precision float)
13918 instruct maddHF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
13919 match(Set dst (FmaHF src3 (Binary src1 src2)));
13920 format %{ "fmaddh $dst, $src1, $src2, $src3" %}
13921 ins_encode %{
13922 assert(UseFMA, "Needs FMA instructions support.");
13923 __ fmaddh($dst$$FloatRegister,
13924 $src1$$FloatRegister,
13925 $src2$$FloatRegister,
13926 $src3$$FloatRegister);
13927 %}
13928 ins_pipe(pipe_class_default);
13929 %}
13930
13931 // src1 * src2 + src3
13932 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
13933 match(Set dst (FmaF src3 (Binary src1 src2)));
13934
13935 format %{ "fmadds $dst, $src1, $src2, $src3" %}
13936
13937 ins_encode %{
13938 assert(UseFMA, "Needs FMA instructions support.");
13939 __ fmadds(as_FloatRegister($dst$$reg),
13940 as_FloatRegister($src1$$reg),
13941 as_FloatRegister($src2$$reg),
13942 as_FloatRegister($src3$$reg));
13943 %}
13944
13945 ins_pipe(pipe_class_default);
13946 %}
13947
13948 // src1 * src2 + src3
13949 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
13950 match(Set dst (FmaD src3 (Binary src1 src2)));
13951
13952 format %{ "fmaddd $dst, $src1, $src2, $src3" %}
13953
13954 ins_encode %{
13955 assert(UseFMA, "Needs FMA instructions support.");
13956 __ fmaddd(as_FloatRegister($dst$$reg),
13957 as_FloatRegister($src1$$reg),
13958 as_FloatRegister($src2$$reg),
13959 as_FloatRegister($src3$$reg));
13960 %}
13961
13962 ins_pipe(pipe_class_default);
13963 %}
13964
13965 // src1 * (-src2) + src3
13966 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
13967 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
13968 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
13969
13970 format %{ "fmsubs $dst, $src1, $src2, $src3" %}
13971
13972 ins_encode %{
13973 assert(UseFMA, "Needs FMA instructions support.");
13974 __ fmsubs(as_FloatRegister($dst$$reg),
13975 as_FloatRegister($src1$$reg),
13976 as_FloatRegister($src2$$reg),
13977 as_FloatRegister($src3$$reg));
13978 %}
13979
13980 ins_pipe(pipe_class_default);
13981 %}
13982
13983 // src1 * (-src2) + src3
13984 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
13985 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
13986 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
13987
13988 format %{ "fmsubd $dst, $src1, $src2, $src3" %}
13989
13990 ins_encode %{
13991 assert(UseFMA, "Needs FMA instructions support.");
13992 __ fmsubd(as_FloatRegister($dst$$reg),
13993 as_FloatRegister($src1$$reg),
13994 as_FloatRegister($src2$$reg),
13995 as_FloatRegister($src3$$reg));
13996 %}
13997
13998 ins_pipe(pipe_class_default);
13999 %}
14000
14001 // src1 * (-src2) - src3
14002 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
14003 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
14004 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
14005
14006 format %{ "fnmadds $dst, $src1, $src2, $src3" %}
14007
14008 ins_encode %{
14009 assert(UseFMA, "Needs FMA instructions support.");
14010 __ fnmadds(as_FloatRegister($dst$$reg),
14011 as_FloatRegister($src1$$reg),
14012 as_FloatRegister($src2$$reg),
14013 as_FloatRegister($src3$$reg));
14014 %}
14015
14016 ins_pipe(pipe_class_default);
14017 %}
14018
14019 // src1 * (-src2) - src3
14020 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
14021 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
14022 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
14023
14024 format %{ "fnmaddd $dst, $src1, $src2, $src3" %}
14025
14026 ins_encode %{
14027 assert(UseFMA, "Needs FMA instructions support.");
14028 __ fnmaddd(as_FloatRegister($dst$$reg),
14029 as_FloatRegister($src1$$reg),
14030 as_FloatRegister($src2$$reg),
14031 as_FloatRegister($src3$$reg));
14032 %}
14033
14034 ins_pipe(pipe_class_default);
14035 %}
14036
14037 // src1 * src2 - src3
14038 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{
14039 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
14040
14041 format %{ "fnmsubs $dst, $src1, $src2, $src3" %}
14042
14043 ins_encode %{
14044 assert(UseFMA, "Needs FMA instructions support.");
14045 __ fnmsubs(as_FloatRegister($dst$$reg),
14046 as_FloatRegister($src1$$reg),
14047 as_FloatRegister($src2$$reg),
14048 as_FloatRegister($src3$$reg));
14049 %}
14050
14051 ins_pipe(pipe_class_default);
14052 %}
14053
14054 // src1 * src2 - src3
14055 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{
14056 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
14057
14058 format %{ "fnmsubd $dst, $src1, $src2, $src3" %}
14059
14060 ins_encode %{
14061 assert(UseFMA, "Needs FMA instructions support.");
14062 // n.b. insn name should be fnmsubd
14063 __ fnmsub(as_FloatRegister($dst$$reg),
14064 as_FloatRegister($src1$$reg),
14065 as_FloatRegister($src2$$reg),
14066 as_FloatRegister($src3$$reg));
14067 %}
14068
14069 ins_pipe(pipe_class_default);
14070 %}
14071
14072 // Math.max(HH)H (half-precision float)
14073 instruct maxHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14074 match(Set dst (MaxHF src1 src2));
14075 format %{ "fmaxh $dst, $src1, $src2" %}
14076 ins_encode %{
14077 __ fmaxh($dst$$FloatRegister,
14078 $src1$$FloatRegister,
14079 $src2$$FloatRegister);
14080 %}
14081 ins_pipe(fp_dop_reg_reg_s);
14082 %}
14083
14084 // Math.min(HH)H (half-precision float)
14085 instruct minHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14086 match(Set dst (MinHF src1 src2));
14087 format %{ "fminh $dst, $src1, $src2" %}
14088 ins_encode %{
14089 __ fminh($dst$$FloatRegister,
14090 $src1$$FloatRegister,
14091 $src2$$FloatRegister);
14092 %}
14093 ins_pipe(fp_dop_reg_reg_s);
14094 %}
14095
14096 // Math.max(FF)F
14097 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14098 match(Set dst (MaxF src1 src2));
14099
14100 format %{ "fmaxs $dst, $src1, $src2" %}
14101 ins_encode %{
14102 __ fmaxs(as_FloatRegister($dst$$reg),
14103 as_FloatRegister($src1$$reg),
14104 as_FloatRegister($src2$$reg));
14105 %}
14106
14107 ins_pipe(fp_dop_reg_reg_s);
14108 %}
14109
14110 // Math.min(FF)F
14111 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14112 match(Set dst (MinF src1 src2));
14113
14114 format %{ "fmins $dst, $src1, $src2" %}
14115 ins_encode %{
14116 __ fmins(as_FloatRegister($dst$$reg),
14117 as_FloatRegister($src1$$reg),
14118 as_FloatRegister($src2$$reg));
14119 %}
14120
14121 ins_pipe(fp_dop_reg_reg_s);
14122 %}
14123
14124 // Math.max(DD)D
14125 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
14126 match(Set dst (MaxD src1 src2));
14127
14128 format %{ "fmaxd $dst, $src1, $src2" %}
14129 ins_encode %{
14130 __ fmaxd(as_FloatRegister($dst$$reg),
14131 as_FloatRegister($src1$$reg),
14132 as_FloatRegister($src2$$reg));
14133 %}
14134
14135 ins_pipe(fp_dop_reg_reg_d);
14136 %}
14137
14138 // Math.min(DD)D
14139 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
14140 match(Set dst (MinD src1 src2));
14141
14142 format %{ "fmind $dst, $src1, $src2" %}
14143 ins_encode %{
14144 __ fmind(as_FloatRegister($dst$$reg),
14145 as_FloatRegister($src1$$reg),
14146 as_FloatRegister($src2$$reg));
14147 %}
14148
14149 ins_pipe(fp_dop_reg_reg_d);
14150 %}
14151
14152 instruct divHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14153 match(Set dst (DivHF src1 src2));
14154 format %{ "fdivh $dst, $src1, $src2" %}
14155 ins_encode %{
14156 __ fdivh($dst$$FloatRegister,
14157 $src1$$FloatRegister,
14158 $src2$$FloatRegister);
14159 %}
14160 ins_pipe(fp_div_s);
14161 %}
14162
14163 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14164 match(Set dst (DivF src1 src2));
14165
14166 ins_cost(INSN_COST * 18);
14167 format %{ "fdivs $dst, $src1, $src2" %}
14168
14169 ins_encode %{
14170 __ fdivs(as_FloatRegister($dst$$reg),
14171 as_FloatRegister($src1$$reg),
14172 as_FloatRegister($src2$$reg));
14173 %}
14174
14175 ins_pipe(fp_div_s);
14176 %}
14177
14178 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
14179 match(Set dst (DivD src1 src2));
14180
14181 ins_cost(INSN_COST * 32);
14182 format %{ "fdivd $dst, $src1, $src2" %}
14183
14184 ins_encode %{
14185 __ fdivd(as_FloatRegister($dst$$reg),
14186 as_FloatRegister($src1$$reg),
14187 as_FloatRegister($src2$$reg));
14188 %}
14189
14190 ins_pipe(fp_div_d);
14191 %}
14192
14193 instruct negF_reg_reg(vRegF dst, vRegF src) %{
14194 match(Set dst (NegF src));
14195
14196 ins_cost(INSN_COST * 3);
14197 format %{ "fneg $dst, $src" %}
14198
14199 ins_encode %{
14200 __ fnegs(as_FloatRegister($dst$$reg),
14201 as_FloatRegister($src$$reg));
14202 %}
14203
14204 ins_pipe(fp_uop_s);
14205 %}
14206
14207 instruct negD_reg_reg(vRegD dst, vRegD src) %{
14208 match(Set dst (NegD src));
14209
14210 ins_cost(INSN_COST * 3);
14211 format %{ "fnegd $dst, $src" %}
14212
14213 ins_encode %{
14214 __ fnegd(as_FloatRegister($dst$$reg),
14215 as_FloatRegister($src$$reg));
14216 %}
14217
14218 ins_pipe(fp_uop_d);
14219 %}
14220
14221 instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
14222 %{
14223 match(Set dst (AbsI src));
14224
14225 effect(KILL cr);
14226 ins_cost(INSN_COST * 2);
14227 format %{ "cmpw $src, zr\n\t"
14228 "cnegw $dst, $src, Assembler::LT\t# int abs"
14229 %}
14230
14231 ins_encode %{
14232 __ cmpw(as_Register($src$$reg), zr);
14233 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT);
14234 %}
14235 ins_pipe(pipe_class_default);
14236 %}
14237
14238 instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr)
14239 %{
14240 match(Set dst (AbsL src));
14241
14242 effect(KILL cr);
14243 ins_cost(INSN_COST * 2);
14244 format %{ "cmp $src, zr\n\t"
14245 "cneg $dst, $src, Assembler::LT\t# long abs"
14246 %}
14247
14248 ins_encode %{
14249 __ cmp(as_Register($src$$reg), zr);
14250 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT);
14251 %}
14252 ins_pipe(pipe_class_default);
14253 %}
14254
14255 instruct absF_reg(vRegF dst, vRegF src) %{
14256 match(Set dst (AbsF src));
14257
14258 ins_cost(INSN_COST * 3);
14259 format %{ "fabss $dst, $src" %}
14260 ins_encode %{
14261 __ fabss(as_FloatRegister($dst$$reg),
14262 as_FloatRegister($src$$reg));
14263 %}
14264
14265 ins_pipe(fp_uop_s);
14266 %}
14267
14268 instruct absD_reg(vRegD dst, vRegD src) %{
14269 match(Set dst (AbsD src));
14270
14271 ins_cost(INSN_COST * 3);
14272 format %{ "fabsd $dst, $src" %}
14273 ins_encode %{
14274 __ fabsd(as_FloatRegister($dst$$reg),
14275 as_FloatRegister($src$$reg));
14276 %}
14277
14278 ins_pipe(fp_uop_d);
14279 %}
14280
14281 instruct absdF_reg(vRegF dst, vRegF src1, vRegF src2) %{
14282 match(Set dst (AbsF (SubF src1 src2)));
14283
14284 ins_cost(INSN_COST * 3);
14285 format %{ "fabds $dst, $src1, $src2" %}
14286 ins_encode %{
14287 __ fabds(as_FloatRegister($dst$$reg),
14288 as_FloatRegister($src1$$reg),
14289 as_FloatRegister($src2$$reg));
14290 %}
14291
14292 ins_pipe(fp_uop_s);
14293 %}
14294
14295 instruct absdD_reg(vRegD dst, vRegD src1, vRegD src2) %{
14296 match(Set dst (AbsD (SubD src1 src2)));
14297
14298 ins_cost(INSN_COST * 3);
14299 format %{ "fabdd $dst, $src1, $src2" %}
14300 ins_encode %{
14301 __ fabdd(as_FloatRegister($dst$$reg),
14302 as_FloatRegister($src1$$reg),
14303 as_FloatRegister($src2$$reg));
14304 %}
14305
14306 ins_pipe(fp_uop_d);
14307 %}
14308
14309 instruct sqrtD_reg(vRegD dst, vRegD src) %{
14310 match(Set dst (SqrtD src));
14311
14312 ins_cost(INSN_COST * 50);
14313 format %{ "fsqrtd $dst, $src" %}
14314 ins_encode %{
14315 __ fsqrtd(as_FloatRegister($dst$$reg),
14316 as_FloatRegister($src$$reg));
14317 %}
14318
14319 ins_pipe(fp_div_s);
14320 %}
14321
14322 instruct sqrtF_reg(vRegF dst, vRegF src) %{
14323 match(Set dst (SqrtF src));
14324
14325 ins_cost(INSN_COST * 50);
14326 format %{ "fsqrts $dst, $src" %}
14327 ins_encode %{
14328 __ fsqrts(as_FloatRegister($dst$$reg),
14329 as_FloatRegister($src$$reg));
14330 %}
14331
14332 ins_pipe(fp_div_d);
14333 %}
14334
14335 instruct sqrtHF_reg(vRegF dst, vRegF src) %{
14336 match(Set dst (SqrtHF src));
14337 format %{ "fsqrth $dst, $src" %}
14338 ins_encode %{
14339 __ fsqrth($dst$$FloatRegister,
14340 $src$$FloatRegister);
14341 %}
14342 ins_pipe(fp_div_s);
14343 %}
14344
14345 // Math.rint, floor, ceil
14346 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{
14347 match(Set dst (RoundDoubleMode src rmode));
14348 format %{ "frint $dst, $src, $rmode" %}
14349 ins_encode %{
14350 switch ($rmode$$constant) {
14351 case RoundDoubleModeNode::rmode_rint:
14352 __ frintnd(as_FloatRegister($dst$$reg),
14353 as_FloatRegister($src$$reg));
14354 break;
14355 case RoundDoubleModeNode::rmode_floor:
14356 __ frintmd(as_FloatRegister($dst$$reg),
14357 as_FloatRegister($src$$reg));
14358 break;
14359 case RoundDoubleModeNode::rmode_ceil:
14360 __ frintpd(as_FloatRegister($dst$$reg),
14361 as_FloatRegister($src$$reg));
14362 break;
14363 }
14364 %}
14365 ins_pipe(fp_uop_d);
14366 %}
14367
14368 instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{
14369 match(Set dst (CopySignD src1 (Binary src2 zero)));
14370 effect(TEMP_DEF dst, USE src1, USE src2, USE zero);
14371 format %{ "CopySignD $dst $src1 $src2" %}
14372 ins_encode %{
14373 FloatRegister dst = as_FloatRegister($dst$$reg),
14374 src1 = as_FloatRegister($src1$$reg),
14375 src2 = as_FloatRegister($src2$$reg),
14376 zero = as_FloatRegister($zero$$reg);
14377 __ fnegd(dst, zero);
14378 __ bsl(dst, __ T8B, src2, src1);
14379 %}
14380 ins_pipe(fp_uop_d);
14381 %}
14382
14383 instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{
14384 match(Set dst (CopySignF src1 src2));
14385 effect(TEMP_DEF dst, USE src1, USE src2);
14386 format %{ "CopySignF $dst $src1 $src2" %}
14387 ins_encode %{
14388 FloatRegister dst = as_FloatRegister($dst$$reg),
14389 src1 = as_FloatRegister($src1$$reg),
14390 src2 = as_FloatRegister($src2$$reg);
14391 __ movi(dst, __ T2S, 0x80, 24);
14392 __ bsl(dst, __ T8B, src2, src1);
14393 %}
14394 ins_pipe(fp_uop_d);
14395 %}
14396
14397 instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{
14398 match(Set dst (SignumD src (Binary zero one)));
14399 effect(TEMP_DEF dst, USE src, USE zero, USE one);
14400 format %{ "signumD $dst, $src" %}
14401 ins_encode %{
14402 FloatRegister src = as_FloatRegister($src$$reg),
14403 dst = as_FloatRegister($dst$$reg),
14404 zero = as_FloatRegister($zero$$reg),
14405 one = as_FloatRegister($one$$reg);
14406 __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise
14407 __ ushrd(dst, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise
14408 // Bit selection instruction gets bit from "one" for each enabled bit in
14409 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or
14410 // NaN the whole "src" will be copied because "dst" is zero. For all other
14411 // "src" values dst is 0x7FF..F, which means only the sign bit is copied
14412 // from "src", and all other bits are copied from 1.0.
14413 __ bsl(dst, __ T8B, one, src);
14414 %}
14415 ins_pipe(fp_uop_d);
14416 %}
14417
14418 instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{
14419 match(Set dst (SignumF src (Binary zero one)));
14420 effect(TEMP_DEF dst, USE src, USE zero, USE one);
14421 format %{ "signumF $dst, $src" %}
14422 ins_encode %{
14423 FloatRegister src = as_FloatRegister($src$$reg),
14424 dst = as_FloatRegister($dst$$reg),
14425 zero = as_FloatRegister($zero$$reg),
14426 one = as_FloatRegister($one$$reg);
14427 __ facgts(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise
14428 __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise
14429 // Bit selection instruction gets bit from "one" for each enabled bit in
14430 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or
14431 // NaN the whole "src" will be copied because "dst" is zero. For all other
14432 // "src" values dst is 0x7FF..F, which means only the sign bit is copied
14433 // from "src", and all other bits are copied from 1.0.
14434 __ bsl(dst, __ T8B, one, src);
14435 %}
14436 ins_pipe(fp_uop_d);
14437 %}
14438
14439 instruct onspinwait() %{
14440 match(OnSpinWait);
14441 ins_cost(INSN_COST);
14442
14443 format %{ "onspinwait" %}
14444
14445 ins_encode %{
14446 __ spin_wait();
14447 %}
14448 ins_pipe(pipe_class_empty);
14449 %}
14450
14451 // ============================================================================
14452 // Logical Instructions
14453
14454 // Integer Logical Instructions
14455
14456 // And Instructions
14457
14458
14459 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{
14460 match(Set dst (AndI src1 src2));
14461
14462 format %{ "andw $dst, $src1, $src2\t# int" %}
14463
14464 ins_cost(INSN_COST);
14465 ins_encode %{
14466 __ andw(as_Register($dst$$reg),
14467 as_Register($src1$$reg),
14468 as_Register($src2$$reg));
14469 %}
14470
14471 ins_pipe(ialu_reg_reg);
14472 %}
14473
14474 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{
14475 match(Set dst (AndI src1 src2));
14476
14477 format %{ "andsw $dst, $src1, $src2\t# int" %}
14478
14479 ins_cost(INSN_COST);
14480 ins_encode %{
14481 __ andw(as_Register($dst$$reg),
14482 as_Register($src1$$reg),
14483 (uint64_t)($src2$$constant));
14484 %}
14485
14486 ins_pipe(ialu_reg_imm);
14487 %}
14488
14489 // Or Instructions
14490
14491 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
14492 match(Set dst (OrI src1 src2));
14493
14494 format %{ "orrw $dst, $src1, $src2\t# int" %}
14495
14496 ins_cost(INSN_COST);
14497 ins_encode %{
14498 __ orrw(as_Register($dst$$reg),
14499 as_Register($src1$$reg),
14500 as_Register($src2$$reg));
14501 %}
14502
14503 ins_pipe(ialu_reg_reg);
14504 %}
14505
14506 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
14507 match(Set dst (OrI src1 src2));
14508
14509 format %{ "orrw $dst, $src1, $src2\t# int" %}
14510
14511 ins_cost(INSN_COST);
14512 ins_encode %{
14513 __ orrw(as_Register($dst$$reg),
14514 as_Register($src1$$reg),
14515 (uint64_t)($src2$$constant));
14516 %}
14517
14518 ins_pipe(ialu_reg_imm);
14519 %}
14520
14521 // Xor Instructions
14522
14523 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
14524 match(Set dst (XorI src1 src2));
14525
14526 format %{ "eorw $dst, $src1, $src2\t# int" %}
14527
14528 ins_cost(INSN_COST);
14529 ins_encode %{
14530 __ eorw(as_Register($dst$$reg),
14531 as_Register($src1$$reg),
14532 as_Register($src2$$reg));
14533 %}
14534
14535 ins_pipe(ialu_reg_reg);
14536 %}
14537
14538 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
14539 match(Set dst (XorI src1 src2));
14540
14541 format %{ "eorw $dst, $src1, $src2\t# int" %}
14542
14543 ins_cost(INSN_COST);
14544 ins_encode %{
14545 __ eorw(as_Register($dst$$reg),
14546 as_Register($src1$$reg),
14547 (uint64_t)($src2$$constant));
14548 %}
14549
14550 ins_pipe(ialu_reg_imm);
14551 %}
14552
14553 // Long Logical Instructions
14554 // TODO
14555
14556 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{
14557 match(Set dst (AndL src1 src2));
14558
14559 format %{ "and $dst, $src1, $src2\t# int" %}
14560
14561 ins_cost(INSN_COST);
14562 ins_encode %{
14563 __ andr(as_Register($dst$$reg),
14564 as_Register($src1$$reg),
14565 as_Register($src2$$reg));
14566 %}
14567
14568 ins_pipe(ialu_reg_reg);
14569 %}
14570
14571 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{
14572 match(Set dst (AndL src1 src2));
14573
14574 format %{ "and $dst, $src1, $src2\t# int" %}
14575
14576 ins_cost(INSN_COST);
14577 ins_encode %{
14578 __ andr(as_Register($dst$$reg),
14579 as_Register($src1$$reg),
14580 (uint64_t)($src2$$constant));
14581 %}
14582
14583 ins_pipe(ialu_reg_imm);
14584 %}
14585
14586 // Or Instructions
14587
14588 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
14589 match(Set dst (OrL src1 src2));
14590
14591 format %{ "orr $dst, $src1, $src2\t# int" %}
14592
14593 ins_cost(INSN_COST);
14594 ins_encode %{
14595 __ orr(as_Register($dst$$reg),
14596 as_Register($src1$$reg),
14597 as_Register($src2$$reg));
14598 %}
14599
14600 ins_pipe(ialu_reg_reg);
14601 %}
14602
14603 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
14604 match(Set dst (OrL src1 src2));
14605
14606 format %{ "orr $dst, $src1, $src2\t# int" %}
14607
14608 ins_cost(INSN_COST);
14609 ins_encode %{
14610 __ orr(as_Register($dst$$reg),
14611 as_Register($src1$$reg),
14612 (uint64_t)($src2$$constant));
14613 %}
14614
14615 ins_pipe(ialu_reg_imm);
14616 %}
14617
14618 // Xor Instructions
14619
14620 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
14621 match(Set dst (XorL src1 src2));
14622
14623 format %{ "eor $dst, $src1, $src2\t# int" %}
14624
14625 ins_cost(INSN_COST);
14626 ins_encode %{
14627 __ eor(as_Register($dst$$reg),
14628 as_Register($src1$$reg),
14629 as_Register($src2$$reg));
14630 %}
14631
14632 ins_pipe(ialu_reg_reg);
14633 %}
14634
14635 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
14636 match(Set dst (XorL src1 src2));
14637
14638 ins_cost(INSN_COST);
14639 format %{ "eor $dst, $src1, $src2\t# int" %}
14640
14641 ins_encode %{
14642 __ eor(as_Register($dst$$reg),
14643 as_Register($src1$$reg),
14644 (uint64_t)($src2$$constant));
14645 %}
14646
14647 ins_pipe(ialu_reg_imm);
14648 %}
14649
14650 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
14651 %{
14652 match(Set dst (ConvI2L src));
14653
14654 ins_cost(INSN_COST);
14655 format %{ "sxtw $dst, $src\t# i2l" %}
14656 ins_encode %{
14657 __ sbfm($dst$$Register, $src$$Register, 0, 31);
14658 %}
14659 ins_pipe(ialu_reg_shift);
14660 %}
14661
14662 // this pattern occurs in bigmath arithmetic
14663 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask)
14664 %{
14665 match(Set dst (AndL (ConvI2L src) mask));
14666
14667 ins_cost(INSN_COST);
14668 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %}
14669 ins_encode %{
14670 __ ubfm($dst$$Register, $src$$Register, 0, 31);
14671 %}
14672
14673 ins_pipe(ialu_reg_shift);
14674 %}
14675
14676 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{
14677 match(Set dst (ConvL2I src));
14678
14679 ins_cost(INSN_COST);
14680 format %{ "movw $dst, $src \t// l2i" %}
14681
14682 ins_encode %{
14683 __ movw(as_Register($dst$$reg), as_Register($src$$reg));
14684 %}
14685
14686 ins_pipe(ialu_reg);
14687 %}
14688
14689 instruct convD2F_reg(vRegF dst, vRegD src) %{
14690 match(Set dst (ConvD2F src));
14691
14692 ins_cost(INSN_COST * 5);
14693 format %{ "fcvtd $dst, $src \t// d2f" %}
14694
14695 ins_encode %{
14696 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
14697 %}
14698
14699 ins_pipe(fp_d2f);
14700 %}
14701
14702 instruct convF2D_reg(vRegD dst, vRegF src) %{
14703 match(Set dst (ConvF2D src));
14704
14705 ins_cost(INSN_COST * 5);
14706 format %{ "fcvts $dst, $src \t// f2d" %}
14707
14708 ins_encode %{
14709 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
14710 %}
14711
14712 ins_pipe(fp_f2d);
14713 %}
14714
14715 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{
14716 match(Set dst (ConvF2I src));
14717
14718 ins_cost(INSN_COST * 5);
14719 format %{ "fcvtzsw $dst, $src \t// f2i" %}
14720
14721 ins_encode %{
14722 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14723 %}
14724
14725 ins_pipe(fp_f2i);
14726 %}
14727
14728 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{
14729 match(Set dst (ConvF2L src));
14730
14731 ins_cost(INSN_COST * 5);
14732 format %{ "fcvtzs $dst, $src \t// f2l" %}
14733
14734 ins_encode %{
14735 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14736 %}
14737
14738 ins_pipe(fp_f2l);
14739 %}
14740
14741 instruct convF2HF_reg_reg(iRegINoSp dst, vRegF src, vRegF tmp) %{
14742 match(Set dst (ConvF2HF src));
14743 format %{ "fcvt $tmp, $src\t# convert single to half precision\n\t"
14744 "smov $dst, $tmp\t# move result from $tmp to $dst"
14745 %}
14746 effect(TEMP tmp);
14747 ins_encode %{
14748 __ flt_to_flt16($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
14749 %}
14750 ins_pipe(pipe_slow);
14751 %}
14752
14753 instruct convHF2F_reg_reg(vRegF dst, iRegINoSp src, vRegF tmp) %{
14754 match(Set dst (ConvHF2F src));
14755 format %{ "mov $tmp, $src\t# move source from $src to $tmp\n\t"
14756 "fcvt $dst, $tmp\t# convert half to single precision"
14757 %}
14758 effect(TEMP tmp);
14759 ins_encode %{
14760 __ flt16_to_flt($dst$$FloatRegister, $src$$Register, $tmp$$FloatRegister);
14761 %}
14762 ins_pipe(pipe_slow);
14763 %}
14764
14765 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{
14766 match(Set dst (ConvI2F src));
14767
14768 ins_cost(INSN_COST * 5);
14769 format %{ "scvtfws $dst, $src \t// i2f" %}
14770
14771 ins_encode %{
14772 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14773 %}
14774
14775 ins_pipe(fp_i2f);
14776 %}
14777
14778 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{
14779 match(Set dst (ConvL2F src));
14780
14781 ins_cost(INSN_COST * 5);
14782 format %{ "scvtfs $dst, $src \t// l2f" %}
14783
14784 ins_encode %{
14785 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14786 %}
14787
14788 ins_pipe(fp_l2f);
14789 %}
14790
14791 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{
14792 match(Set dst (ConvD2I src));
14793
14794 ins_cost(INSN_COST * 5);
14795 format %{ "fcvtzdw $dst, $src \t// d2i" %}
14796
14797 ins_encode %{
14798 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14799 %}
14800
14801 ins_pipe(fp_d2i);
14802 %}
14803
14804 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
14805 match(Set dst (ConvD2L src));
14806
14807 ins_cost(INSN_COST * 5);
14808 format %{ "fcvtzd $dst, $src \t// d2l" %}
14809
14810 ins_encode %{
14811 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14812 %}
14813
14814 ins_pipe(fp_d2l);
14815 %}
14816
14817 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{
14818 match(Set dst (ConvI2D src));
14819
14820 ins_cost(INSN_COST * 5);
14821 format %{ "scvtfwd $dst, $src \t// i2d" %}
14822
14823 ins_encode %{
14824 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14825 %}
14826
14827 ins_pipe(fp_i2d);
14828 %}
14829
14830 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{
14831 match(Set dst (ConvL2D src));
14832
14833 ins_cost(INSN_COST * 5);
14834 format %{ "scvtfd $dst, $src \t// l2d" %}
14835
14836 ins_encode %{
14837 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14838 %}
14839
14840 ins_pipe(fp_l2d);
14841 %}
14842
14843 instruct round_double_reg(iRegLNoSp dst, vRegD src, vRegD ftmp, rFlagsReg cr)
14844 %{
14845 match(Set dst (RoundD src));
14846 effect(TEMP_DEF dst, TEMP ftmp, KILL cr);
14847 format %{ "java_round_double $dst,$src"%}
14848 ins_encode %{
14849 __ java_round_double($dst$$Register, as_FloatRegister($src$$reg),
14850 as_FloatRegister($ftmp$$reg));
14851 %}
14852 ins_pipe(pipe_slow);
14853 %}
14854
14855 instruct round_float_reg(iRegINoSp dst, vRegF src, vRegF ftmp, rFlagsReg cr)
14856 %{
14857 match(Set dst (RoundF src));
14858 effect(TEMP_DEF dst, TEMP ftmp, KILL cr);
14859 format %{ "java_round_float $dst,$src"%}
14860 ins_encode %{
14861 __ java_round_float($dst$$Register, as_FloatRegister($src$$reg),
14862 as_FloatRegister($ftmp$$reg));
14863 %}
14864 ins_pipe(pipe_slow);
14865 %}
14866
14867 // stack <-> reg and reg <-> reg shuffles with no conversion
14868
14869 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{
14870
14871 match(Set dst (MoveF2I src));
14872
14873 effect(DEF dst, USE src);
14874
14875 ins_cost(4 * INSN_COST);
14876
14877 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %}
14878
14879 ins_encode %{
14880 __ ldrw($dst$$Register, Address(sp, $src$$disp));
14881 %}
14882
14883 ins_pipe(iload_reg_reg);
14884
14885 %}
14886
14887 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{
14888
14889 match(Set dst (MoveI2F src));
14890
14891 effect(DEF dst, USE src);
14892
14893 ins_cost(4 * INSN_COST);
14894
14895 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %}
14896
14897 ins_encode %{
14898 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
14899 %}
14900
14901 ins_pipe(pipe_class_memory);
14902
14903 %}
14904
14905 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{
14906
14907 match(Set dst (MoveD2L src));
14908
14909 effect(DEF dst, USE src);
14910
14911 ins_cost(4 * INSN_COST);
14912
14913 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %}
14914
14915 ins_encode %{
14916 __ ldr($dst$$Register, Address(sp, $src$$disp));
14917 %}
14918
14919 ins_pipe(iload_reg_reg);
14920
14921 %}
14922
14923 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{
14924
14925 match(Set dst (MoveL2D src));
14926
14927 effect(DEF dst, USE src);
14928
14929 ins_cost(4 * INSN_COST);
14930
14931 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %}
14932
14933 ins_encode %{
14934 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
14935 %}
14936
14937 ins_pipe(pipe_class_memory);
14938
14939 %}
14940
14941 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{
14942
14943 match(Set dst (MoveF2I src));
14944
14945 effect(DEF dst, USE src);
14946
14947 ins_cost(INSN_COST);
14948
14949 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %}
14950
14951 ins_encode %{
14952 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
14953 %}
14954
14955 ins_pipe(pipe_class_memory);
14956
14957 %}
14958
14959 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
14960
14961 match(Set dst (MoveI2F src));
14962
14963 effect(DEF dst, USE src);
14964
14965 ins_cost(INSN_COST);
14966
14967 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %}
14968
14969 ins_encode %{
14970 __ strw($src$$Register, Address(sp, $dst$$disp));
14971 %}
14972
14973 ins_pipe(istore_reg_reg);
14974
14975 %}
14976
14977 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{
14978
14979 match(Set dst (MoveD2L src));
14980
14981 effect(DEF dst, USE src);
14982
14983 ins_cost(INSN_COST);
14984
14985 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %}
14986
14987 ins_encode %{
14988 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
14989 %}
14990
14991 ins_pipe(pipe_class_memory);
14992
14993 %}
14994
14995 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
14996
14997 match(Set dst (MoveL2D src));
14998
14999 effect(DEF dst, USE src);
15000
15001 ins_cost(INSN_COST);
15002
15003 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %}
15004
15005 ins_encode %{
15006 __ str($src$$Register, Address(sp, $dst$$disp));
15007 %}
15008
15009 ins_pipe(istore_reg_reg);
15010
15011 %}
15012
15013 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{
15014
15015 match(Set dst (MoveF2I src));
15016
15017 effect(DEF dst, USE src);
15018
15019 ins_cost(INSN_COST);
15020
15021 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %}
15022
15023 ins_encode %{
15024 __ fmovs($dst$$Register, as_FloatRegister($src$$reg));
15025 %}
15026
15027 ins_pipe(fp_f2i);
15028
15029 %}
15030
15031 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{
15032
15033 match(Set dst (MoveI2F src));
15034
15035 effect(DEF dst, USE src);
15036
15037 ins_cost(INSN_COST);
15038
15039 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %}
15040
15041 ins_encode %{
15042 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register);
15043 %}
15044
15045 ins_pipe(fp_i2f);
15046
15047 %}
15048
15049 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
15050
15051 match(Set dst (MoveD2L src));
15052
15053 effect(DEF dst, USE src);
15054
15055 ins_cost(INSN_COST);
15056
15057 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %}
15058
15059 ins_encode %{
15060 __ fmovd($dst$$Register, as_FloatRegister($src$$reg));
15061 %}
15062
15063 ins_pipe(fp_d2l);
15064
15065 %}
15066
15067 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{
15068
15069 match(Set dst (MoveL2D src));
15070
15071 effect(DEF dst, USE src);
15072
15073 ins_cost(INSN_COST);
15074
15075 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %}
15076
15077 ins_encode %{
15078 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register);
15079 %}
15080
15081 ins_pipe(fp_l2d);
15082
15083 %}
15084
15085 // ============================================================================
15086 // clearing of an array
15087
15088 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
15089 %{
15090 match(Set dummy (ClearArray cnt base));
15091 effect(USE_KILL cnt, USE_KILL base, KILL cr);
15092
15093 ins_cost(4 * INSN_COST);
15094 format %{ "ClearArray $cnt, $base" %}
15095
15096 ins_encode %{
15097 address tpc = __ zero_words($base$$Register, $cnt$$Register);
15098 if (tpc == nullptr) {
15099 ciEnv::current()->record_failure("CodeCache is full");
15100 return;
15101 }
15102 %}
15103
15104 ins_pipe(pipe_class_memory);
15105 %}
15106
15107 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, Universe dummy, rFlagsReg cr)
15108 %{
15109 predicate((uint64_t)n->in(2)->get_long()
15110 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord));
15111 match(Set dummy (ClearArray cnt base));
15112 effect(TEMP temp, USE_KILL base, KILL cr);
15113
15114 ins_cost(4 * INSN_COST);
15115 format %{ "ClearArray $cnt, $base" %}
15116
15117 ins_encode %{
15118 address tpc = __ zero_words($base$$Register, (uint64_t)$cnt$$constant);
15119 if (tpc == nullptr) {
15120 ciEnv::current()->record_failure("CodeCache is full");
15121 return;
15122 }
15123 %}
15124
15125 ins_pipe(pipe_class_memory);
15126 %}
15127
15128 // ============================================================================
15129 // Overflow Math Instructions
15130
15131 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
15132 %{
15133 match(Set cr (OverflowAddI op1 op2));
15134
15135 format %{ "cmnw $op1, $op2\t# overflow check int" %}
15136 ins_cost(INSN_COST);
15137 ins_encode %{
15138 __ cmnw($op1$$Register, $op2$$Register);
15139 %}
15140
15141 ins_pipe(icmp_reg_reg);
15142 %}
15143
15144 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
15145 %{
15146 match(Set cr (OverflowAddI op1 op2));
15147
15148 format %{ "cmnw $op1, $op2\t# overflow check int" %}
15149 ins_cost(INSN_COST);
15150 ins_encode %{
15151 __ cmnw($op1$$Register, $op2$$constant);
15152 %}
15153
15154 ins_pipe(icmp_reg_imm);
15155 %}
15156
15157 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15158 %{
15159 match(Set cr (OverflowAddL op1 op2));
15160
15161 format %{ "cmn $op1, $op2\t# overflow check long" %}
15162 ins_cost(INSN_COST);
15163 ins_encode %{
15164 __ cmn($op1$$Register, $op2$$Register);
15165 %}
15166
15167 ins_pipe(icmp_reg_reg);
15168 %}
15169
15170 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
15171 %{
15172 match(Set cr (OverflowAddL op1 op2));
15173
15174 format %{ "adds zr, $op1, $op2\t# overflow check long" %}
15175 ins_cost(INSN_COST);
15176 ins_encode %{
15177 __ adds(zr, $op1$$Register, $op2$$constant);
15178 %}
15179
15180 ins_pipe(icmp_reg_imm);
15181 %}
15182
15183 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
15184 %{
15185 match(Set cr (OverflowSubI op1 op2));
15186
15187 format %{ "cmpw $op1, $op2\t# overflow check int" %}
15188 ins_cost(INSN_COST);
15189 ins_encode %{
15190 __ cmpw($op1$$Register, $op2$$Register);
15191 %}
15192
15193 ins_pipe(icmp_reg_reg);
15194 %}
15195
15196 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
15197 %{
15198 match(Set cr (OverflowSubI op1 op2));
15199
15200 format %{ "cmpw $op1, $op2\t# overflow check int" %}
15201 ins_cost(INSN_COST);
15202 ins_encode %{
15203 __ cmpw($op1$$Register, $op2$$constant);
15204 %}
15205
15206 ins_pipe(icmp_reg_imm);
15207 %}
15208
15209 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15210 %{
15211 match(Set cr (OverflowSubL op1 op2));
15212
15213 format %{ "cmp $op1, $op2\t# overflow check long" %}
15214 ins_cost(INSN_COST);
15215 ins_encode %{
15216 __ cmp($op1$$Register, $op2$$Register);
15217 %}
15218
15219 ins_pipe(icmp_reg_reg);
15220 %}
15221
15222 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
15223 %{
15224 match(Set cr (OverflowSubL op1 op2));
15225
15226 format %{ "cmp $op1, $op2\t# overflow check long" %}
15227 ins_cost(INSN_COST);
15228 ins_encode %{
15229 __ subs(zr, $op1$$Register, $op2$$constant);
15230 %}
15231
15232 ins_pipe(icmp_reg_imm);
15233 %}
15234
15235 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1)
15236 %{
15237 match(Set cr (OverflowSubI zero op1));
15238
15239 format %{ "cmpw zr, $op1\t# overflow check int" %}
15240 ins_cost(INSN_COST);
15241 ins_encode %{
15242 __ cmpw(zr, $op1$$Register);
15243 %}
15244
15245 ins_pipe(icmp_reg_imm);
15246 %}
15247
15248 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1)
15249 %{
15250 match(Set cr (OverflowSubL zero op1));
15251
15252 format %{ "cmp zr, $op1\t# overflow check long" %}
15253 ins_cost(INSN_COST);
15254 ins_encode %{
15255 __ cmp(zr, $op1$$Register);
15256 %}
15257
15258 ins_pipe(icmp_reg_imm);
15259 %}
15260
15261 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
15262 %{
15263 match(Set cr (OverflowMulI op1 op2));
15264
15265 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
15266 "cmp rscratch1, rscratch1, sxtw\n\t"
15267 "movw rscratch1, #0x80000000\n\t"
15268 "cselw rscratch1, rscratch1, zr, NE\n\t"
15269 "cmpw rscratch1, #1" %}
15270 ins_cost(5 * INSN_COST);
15271 ins_encode %{
15272 __ smull(rscratch1, $op1$$Register, $op2$$Register);
15273 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow
15274 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ),
15275 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
15276 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS
15277 %}
15278
15279 ins_pipe(pipe_slow);
15280 %}
15281
15282 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr)
15283 %{
15284 match(If cmp (OverflowMulI op1 op2));
15285 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
15286 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
15287 effect(USE labl, KILL cr);
15288
15289 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
15290 "cmp rscratch1, rscratch1, sxtw\n\t"
15291 "b$cmp $labl" %}
15292 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST
15293 ins_encode %{
15294 Label* L = $labl$$label;
15295 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15296 __ smull(rscratch1, $op1$$Register, $op2$$Register);
15297 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow
15298 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
15299 %}
15300
15301 ins_pipe(pipe_serial);
15302 %}
15303
15304 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15305 %{
15306 match(Set cr (OverflowMulL op1 op2));
15307
15308 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t"
15309 "smulh rscratch2, $op1, $op2\n\t"
15310 "cmp rscratch2, rscratch1, ASR #63\n\t"
15311 "movw rscratch1, #0x80000000\n\t"
15312 "cselw rscratch1, rscratch1, zr, NE\n\t"
15313 "cmpw rscratch1, #1" %}
15314 ins_cost(6 * INSN_COST);
15315 ins_encode %{
15316 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63
15317 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
15318 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext
15319 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ),
15320 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
15321 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS
15322 %}
15323
15324 ins_pipe(pipe_slow);
15325 %}
15326
15327 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr)
15328 %{
15329 match(If cmp (OverflowMulL op1 op2));
15330 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
15331 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
15332 effect(USE labl, KILL cr);
15333
15334 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t"
15335 "smulh rscratch2, $op1, $op2\n\t"
15336 "cmp rscratch2, rscratch1, ASR #63\n\t"
15337 "b$cmp $labl" %}
15338 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
15339 ins_encode %{
15340 Label* L = $labl$$label;
15341 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15342 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63
15343 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
15344 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext
15345 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
15346 %}
15347
15348 ins_pipe(pipe_serial);
15349 %}
15350
15351 // ============================================================================
15352 // Compare Instructions
15353
15354 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
15355 %{
15356 match(Set cr (CmpI op1 op2));
15357
15358 effect(DEF cr, USE op1, USE op2);
15359
15360 ins_cost(INSN_COST);
15361 format %{ "cmpw $op1, $op2" %}
15362
15363 ins_encode(aarch64_enc_cmpw(op1, op2));
15364
15365 ins_pipe(icmp_reg_reg);
15366 %}
15367
15368 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero)
15369 %{
15370 match(Set cr (CmpI op1 zero));
15371
15372 effect(DEF cr, USE op1);
15373
15374 ins_cost(INSN_COST);
15375 format %{ "cmpw $op1, 0" %}
15376
15377 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
15378
15379 ins_pipe(icmp_reg_imm);
15380 %}
15381
15382 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2)
15383 %{
15384 match(Set cr (CmpI op1 op2));
15385
15386 effect(DEF cr, USE op1);
15387
15388 ins_cost(INSN_COST);
15389 format %{ "cmpw $op1, $op2" %}
15390
15391 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
15392
15393 ins_pipe(icmp_reg_imm);
15394 %}
15395
15396 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2)
15397 %{
15398 match(Set cr (CmpI op1 op2));
15399
15400 effect(DEF cr, USE op1);
15401
15402 ins_cost(INSN_COST * 2);
15403 format %{ "cmpw $op1, $op2" %}
15404
15405 ins_encode(aarch64_enc_cmpw_imm(op1, op2));
15406
15407 ins_pipe(icmp_reg_imm);
15408 %}
15409
15410 // Unsigned compare Instructions; really, same as signed compare
15411 // except it should only be used to feed an If or a CMovI which takes a
15412 // cmpOpU.
15413
15414 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2)
15415 %{
15416 match(Set cr (CmpU op1 op2));
15417
15418 effect(DEF cr, USE op1, USE op2);
15419
15420 ins_cost(INSN_COST);
15421 format %{ "cmpw $op1, $op2\t# unsigned" %}
15422
15423 ins_encode(aarch64_enc_cmpw(op1, op2));
15424
15425 ins_pipe(icmp_reg_reg);
15426 %}
15427
15428 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero)
15429 %{
15430 match(Set cr (CmpU op1 zero));
15431
15432 effect(DEF cr, USE op1);
15433
15434 ins_cost(INSN_COST);
15435 format %{ "cmpw $op1, #0\t# unsigned" %}
15436
15437 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
15438
15439 ins_pipe(icmp_reg_imm);
15440 %}
15441
15442 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2)
15443 %{
15444 match(Set cr (CmpU op1 op2));
15445
15446 effect(DEF cr, USE op1);
15447
15448 ins_cost(INSN_COST);
15449 format %{ "cmpw $op1, $op2\t# unsigned" %}
15450
15451 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
15452
15453 ins_pipe(icmp_reg_imm);
15454 %}
15455
15456 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2)
15457 %{
15458 match(Set cr (CmpU op1 op2));
15459
15460 effect(DEF cr, USE op1);
15461
15462 ins_cost(INSN_COST * 2);
15463 format %{ "cmpw $op1, $op2\t# unsigned" %}
15464
15465 ins_encode(aarch64_enc_cmpw_imm(op1, op2));
15466
15467 ins_pipe(icmp_reg_imm);
15468 %}
15469
15470 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15471 %{
15472 match(Set cr (CmpL op1 op2));
15473
15474 effect(DEF cr, USE op1, USE op2);
15475
15476 ins_cost(INSN_COST);
15477 format %{ "cmp $op1, $op2" %}
15478
15479 ins_encode(aarch64_enc_cmp(op1, op2));
15480
15481 ins_pipe(icmp_reg_reg);
15482 %}
15483
15484 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero)
15485 %{
15486 match(Set cr (CmpL op1 zero));
15487
15488 effect(DEF cr, USE op1);
15489
15490 ins_cost(INSN_COST);
15491 format %{ "tst $op1" %}
15492
15493 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
15494
15495 ins_pipe(icmp_reg_imm);
15496 %}
15497
15498 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2)
15499 %{
15500 match(Set cr (CmpL op1 op2));
15501
15502 effect(DEF cr, USE op1);
15503
15504 ins_cost(INSN_COST);
15505 format %{ "cmp $op1, $op2" %}
15506
15507 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
15508
15509 ins_pipe(icmp_reg_imm);
15510 %}
15511
15512 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2)
15513 %{
15514 match(Set cr (CmpL op1 op2));
15515
15516 effect(DEF cr, USE op1);
15517
15518 ins_cost(INSN_COST * 2);
15519 format %{ "cmp $op1, $op2" %}
15520
15521 ins_encode(aarch64_enc_cmp_imm(op1, op2));
15522
15523 ins_pipe(icmp_reg_imm);
15524 %}
15525
15526 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2)
15527 %{
15528 match(Set cr (CmpUL op1 op2));
15529
15530 effect(DEF cr, USE op1, USE op2);
15531
15532 ins_cost(INSN_COST);
15533 format %{ "cmp $op1, $op2" %}
15534
15535 ins_encode(aarch64_enc_cmp(op1, op2));
15536
15537 ins_pipe(icmp_reg_reg);
15538 %}
15539
15540 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero)
15541 %{
15542 match(Set cr (CmpUL op1 zero));
15543
15544 effect(DEF cr, USE op1);
15545
15546 ins_cost(INSN_COST);
15547 format %{ "tst $op1" %}
15548
15549 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
15550
15551 ins_pipe(icmp_reg_imm);
15552 %}
15553
15554 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2)
15555 %{
15556 match(Set cr (CmpUL op1 op2));
15557
15558 effect(DEF cr, USE op1);
15559
15560 ins_cost(INSN_COST);
15561 format %{ "cmp $op1, $op2" %}
15562
15563 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
15564
15565 ins_pipe(icmp_reg_imm);
15566 %}
15567
15568 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2)
15569 %{
15570 match(Set cr (CmpUL op1 op2));
15571
15572 effect(DEF cr, USE op1);
15573
15574 ins_cost(INSN_COST * 2);
15575 format %{ "cmp $op1, $op2" %}
15576
15577 ins_encode(aarch64_enc_cmp_imm(op1, op2));
15578
15579 ins_pipe(icmp_reg_imm);
15580 %}
15581
15582 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2)
15583 %{
15584 match(Set cr (CmpP op1 op2));
15585
15586 effect(DEF cr, USE op1, USE op2);
15587
15588 ins_cost(INSN_COST);
15589 format %{ "cmp $op1, $op2\t // ptr" %}
15590
15591 ins_encode(aarch64_enc_cmpp(op1, op2));
15592
15593 ins_pipe(icmp_reg_reg);
15594 %}
15595
15596 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2)
15597 %{
15598 match(Set cr (CmpN op1 op2));
15599
15600 effect(DEF cr, USE op1, USE op2);
15601
15602 ins_cost(INSN_COST);
15603 format %{ "cmp $op1, $op2\t // compressed ptr" %}
15604
15605 ins_encode(aarch64_enc_cmpn(op1, op2));
15606
15607 ins_pipe(icmp_reg_reg);
15608 %}
15609
15610 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero)
15611 %{
15612 match(Set cr (CmpP op1 zero));
15613
15614 effect(DEF cr, USE op1, USE zero);
15615
15616 ins_cost(INSN_COST);
15617 format %{ "cmp $op1, 0\t // ptr" %}
15618
15619 ins_encode(aarch64_enc_testp(op1));
15620
15621 ins_pipe(icmp_reg_imm);
15622 %}
15623
15624 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero)
15625 %{
15626 match(Set cr (CmpN op1 zero));
15627
15628 effect(DEF cr, USE op1, USE zero);
15629
15630 ins_cost(INSN_COST);
15631 format %{ "cmp $op1, 0\t // compressed ptr" %}
15632
15633 ins_encode(aarch64_enc_testn(op1));
15634
15635 ins_pipe(icmp_reg_imm);
15636 %}
15637
15638 // FP comparisons
15639 //
15640 // n.b. CmpF/CmpD set a normal flags reg which then gets compared
15641 // using normal cmpOp. See declaration of rFlagsReg for details.
15642
15643 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2)
15644 %{
15645 match(Set cr (CmpF src1 src2));
15646
15647 ins_cost(3 * INSN_COST);
15648 format %{ "fcmps $src1, $src2" %}
15649
15650 ins_encode %{
15651 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15652 %}
15653
15654 ins_pipe(pipe_class_compare);
15655 %}
15656
15657 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2)
15658 %{
15659 match(Set cr (CmpF src1 src2));
15660
15661 ins_cost(3 * INSN_COST);
15662 format %{ "fcmps $src1, 0.0" %}
15663
15664 ins_encode %{
15665 __ fcmps(as_FloatRegister($src1$$reg), 0.0);
15666 %}
15667
15668 ins_pipe(pipe_class_compare);
15669 %}
15670 // FROM HERE
15671
15672 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2)
15673 %{
15674 match(Set cr (CmpD src1 src2));
15675
15676 ins_cost(3 * INSN_COST);
15677 format %{ "fcmpd $src1, $src2" %}
15678
15679 ins_encode %{
15680 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15681 %}
15682
15683 ins_pipe(pipe_class_compare);
15684 %}
15685
15686 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2)
15687 %{
15688 match(Set cr (CmpD src1 src2));
15689
15690 ins_cost(3 * INSN_COST);
15691 format %{ "fcmpd $src1, 0.0" %}
15692
15693 ins_encode %{
15694 __ fcmpd(as_FloatRegister($src1$$reg), 0.0);
15695 %}
15696
15697 ins_pipe(pipe_class_compare);
15698 %}
15699
15700 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr)
15701 %{
15702 match(Set dst (CmpF3 src1 src2));
15703 effect(KILL cr);
15704
15705 ins_cost(5 * INSN_COST);
15706 format %{ "fcmps $src1, $src2\n\t"
15707 "csinvw($dst, zr, zr, eq\n\t"
15708 "csnegw($dst, $dst, $dst, lt)"
15709 %}
15710
15711 ins_encode %{
15712 Label done;
15713 FloatRegister s1 = as_FloatRegister($src1$$reg);
15714 FloatRegister s2 = as_FloatRegister($src2$$reg);
15715 Register d = as_Register($dst$$reg);
15716 __ fcmps(s1, s2);
15717 // installs 0 if EQ else -1
15718 __ csinvw(d, zr, zr, Assembler::EQ);
15719 // keeps -1 if less or unordered else installs 1
15720 __ csnegw(d, d, d, Assembler::LT);
15721 __ bind(done);
15722 %}
15723
15724 ins_pipe(pipe_class_default);
15725
15726 %}
15727
15728 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr)
15729 %{
15730 match(Set dst (CmpD3 src1 src2));
15731 effect(KILL cr);
15732
15733 ins_cost(5 * INSN_COST);
15734 format %{ "fcmpd $src1, $src2\n\t"
15735 "csinvw($dst, zr, zr, eq\n\t"
15736 "csnegw($dst, $dst, $dst, lt)"
15737 %}
15738
15739 ins_encode %{
15740 Label done;
15741 FloatRegister s1 = as_FloatRegister($src1$$reg);
15742 FloatRegister s2 = as_FloatRegister($src2$$reg);
15743 Register d = as_Register($dst$$reg);
15744 __ fcmpd(s1, s2);
15745 // installs 0 if EQ else -1
15746 __ csinvw(d, zr, zr, Assembler::EQ);
15747 // keeps -1 if less or unordered else installs 1
15748 __ csnegw(d, d, d, Assembler::LT);
15749 __ bind(done);
15750 %}
15751 ins_pipe(pipe_class_default);
15752
15753 %}
15754
15755 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr)
15756 %{
15757 match(Set dst (CmpF3 src1 zero));
15758 effect(KILL cr);
15759
15760 ins_cost(5 * INSN_COST);
15761 format %{ "fcmps $src1, 0.0\n\t"
15762 "csinvw($dst, zr, zr, eq\n\t"
15763 "csnegw($dst, $dst, $dst, lt)"
15764 %}
15765
15766 ins_encode %{
15767 Label done;
15768 FloatRegister s1 = as_FloatRegister($src1$$reg);
15769 Register d = as_Register($dst$$reg);
15770 __ fcmps(s1, 0.0);
15771 // installs 0 if EQ else -1
15772 __ csinvw(d, zr, zr, Assembler::EQ);
15773 // keeps -1 if less or unordered else installs 1
15774 __ csnegw(d, d, d, Assembler::LT);
15775 __ bind(done);
15776 %}
15777
15778 ins_pipe(pipe_class_default);
15779
15780 %}
15781
15782 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr)
15783 %{
15784 match(Set dst (CmpD3 src1 zero));
15785 effect(KILL cr);
15786
15787 ins_cost(5 * INSN_COST);
15788 format %{ "fcmpd $src1, 0.0\n\t"
15789 "csinvw($dst, zr, zr, eq\n\t"
15790 "csnegw($dst, $dst, $dst, lt)"
15791 %}
15792
15793 ins_encode %{
15794 Label done;
15795 FloatRegister s1 = as_FloatRegister($src1$$reg);
15796 Register d = as_Register($dst$$reg);
15797 __ fcmpd(s1, 0.0);
15798 // installs 0 if EQ else -1
15799 __ csinvw(d, zr, zr, Assembler::EQ);
15800 // keeps -1 if less or unordered else installs 1
15801 __ csnegw(d, d, d, Assembler::LT);
15802 __ bind(done);
15803 %}
15804 ins_pipe(pipe_class_default);
15805
15806 %}
15807
15808 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr)
15809 %{
15810 match(Set dst (CmpLTMask p q));
15811 effect(KILL cr);
15812
15813 ins_cost(3 * INSN_COST);
15814
15815 format %{ "cmpw $p, $q\t# cmpLTMask\n\t"
15816 "csetw $dst, lt\n\t"
15817 "subw $dst, zr, $dst"
15818 %}
15819
15820 ins_encode %{
15821 __ cmpw(as_Register($p$$reg), as_Register($q$$reg));
15822 __ csetw(as_Register($dst$$reg), Assembler::LT);
15823 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg));
15824 %}
15825
15826 ins_pipe(ialu_reg_reg);
15827 %}
15828
15829 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr)
15830 %{
15831 match(Set dst (CmpLTMask src zero));
15832 effect(KILL cr);
15833
15834 ins_cost(INSN_COST);
15835
15836 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %}
15837
15838 ins_encode %{
15839 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31);
15840 %}
15841
15842 ins_pipe(ialu_reg_shift);
15843 %}
15844
15845 // ============================================================================
15846 // Max and Min
15847
15848 // Like compI_reg_reg or compI_reg_immI0 but without match rule and second zero parameter.
15849
15850 instruct compI_reg_imm0(rFlagsReg cr, iRegI src)
15851 %{
15852 effect(DEF cr, USE src);
15853 ins_cost(INSN_COST);
15854 format %{ "cmpw $src, 0" %}
15855
15856 ins_encode %{
15857 __ cmpw($src$$Register, 0);
15858 %}
15859 ins_pipe(icmp_reg_imm);
15860 %}
15861
15862 instruct minI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2)
15863 %{
15864 match(Set dst (MinI src1 src2));
15865 ins_cost(INSN_COST * 3);
15866
15867 expand %{
15868 rFlagsReg cr;
15869 compI_reg_reg(cr, src1, src2);
15870 cmovI_reg_reg_lt(dst, src1, src2, cr);
15871 %}
15872 %}
15873
15874 instruct maxI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2)
15875 %{
15876 match(Set dst (MaxI src1 src2));
15877 ins_cost(INSN_COST * 3);
15878
15879 expand %{
15880 rFlagsReg cr;
15881 compI_reg_reg(cr, src1, src2);
15882 cmovI_reg_reg_gt(dst, src1, src2, cr);
15883 %}
15884 %}
15885
15886
15887 // ============================================================================
15888 // Branch Instructions
15889
15890 // Direct Branch.
15891 instruct branch(label lbl)
15892 %{
15893 match(Goto);
15894
15895 effect(USE lbl);
15896
15897 ins_cost(BRANCH_COST);
15898 format %{ "b $lbl" %}
15899
15900 ins_encode(aarch64_enc_b(lbl));
15901
15902 ins_pipe(pipe_branch);
15903 %}
15904
15905 // Conditional Near Branch
15906 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl)
15907 %{
15908 // Same match rule as `branchConFar'.
15909 match(If cmp cr);
15910
15911 effect(USE lbl);
15912
15913 ins_cost(BRANCH_COST);
15914 // If set to 1 this indicates that the current instruction is a
15915 // short variant of a long branch. This avoids using this
15916 // instruction in first-pass matching. It will then only be used in
15917 // the `Shorten_branches' pass.
15918 // ins_short_branch(1);
15919 format %{ "b$cmp $lbl" %}
15920
15921 ins_encode(aarch64_enc_br_con(cmp, lbl));
15922
15923 ins_pipe(pipe_branch_cond);
15924 %}
15925
15926 // Conditional Near Branch Unsigned
15927 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl)
15928 %{
15929 // Same match rule as `branchConFar'.
15930 match(If cmp cr);
15931
15932 effect(USE lbl);
15933
15934 ins_cost(BRANCH_COST);
15935 // If set to 1 this indicates that the current instruction is a
15936 // short variant of a long branch. This avoids using this
15937 // instruction in first-pass matching. It will then only be used in
15938 // the `Shorten_branches' pass.
15939 // ins_short_branch(1);
15940 format %{ "b$cmp $lbl\t# unsigned" %}
15941
15942 ins_encode(aarch64_enc_br_conU(cmp, lbl));
15943
15944 ins_pipe(pipe_branch_cond);
15945 %}
15946
15947 // Make use of CBZ and CBNZ. These instructions, as well as being
15948 // shorter than (cmp; branch), have the additional benefit of not
15949 // killing the flags.
15950
15951 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
15952 match(If cmp (CmpI op1 op2));
15953 effect(USE labl);
15954
15955 ins_cost(BRANCH_COST);
15956 format %{ "cbw$cmp $op1, $labl" %}
15957 ins_encode %{
15958 Label* L = $labl$$label;
15959 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15960 if (cond == Assembler::EQ)
15961 __ cbzw($op1$$Register, *L);
15962 else
15963 __ cbnzw($op1$$Register, *L);
15964 %}
15965 ins_pipe(pipe_cmp_branch);
15966 %}
15967
15968 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{
15969 match(If cmp (CmpL op1 op2));
15970 effect(USE labl);
15971
15972 ins_cost(BRANCH_COST);
15973 format %{ "cb$cmp $op1, $labl" %}
15974 ins_encode %{
15975 Label* L = $labl$$label;
15976 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15977 if (cond == Assembler::EQ)
15978 __ cbz($op1$$Register, *L);
15979 else
15980 __ cbnz($op1$$Register, *L);
15981 %}
15982 ins_pipe(pipe_cmp_branch);
15983 %}
15984
15985 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{
15986 match(If cmp (CmpP op1 op2));
15987 effect(USE labl);
15988
15989 ins_cost(BRANCH_COST);
15990 format %{ "cb$cmp $op1, $labl" %}
15991 ins_encode %{
15992 Label* L = $labl$$label;
15993 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15994 if (cond == Assembler::EQ)
15995 __ cbz($op1$$Register, *L);
15996 else
15997 __ cbnz($op1$$Register, *L);
15998 %}
15999 ins_pipe(pipe_cmp_branch);
16000 %}
16001
16002 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{
16003 match(If cmp (CmpN op1 op2));
16004 effect(USE labl);
16005
16006 ins_cost(BRANCH_COST);
16007 format %{ "cbw$cmp $op1, $labl" %}
16008 ins_encode %{
16009 Label* L = $labl$$label;
16010 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16011 if (cond == Assembler::EQ)
16012 __ cbzw($op1$$Register, *L);
16013 else
16014 __ cbnzw($op1$$Register, *L);
16015 %}
16016 ins_pipe(pipe_cmp_branch);
16017 %}
16018
16019 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{
16020 match(If cmp (CmpP (DecodeN oop) zero));
16021 effect(USE labl);
16022
16023 ins_cost(BRANCH_COST);
16024 format %{ "cb$cmp $oop, $labl" %}
16025 ins_encode %{
16026 Label* L = $labl$$label;
16027 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16028 if (cond == Assembler::EQ)
16029 __ cbzw($oop$$Register, *L);
16030 else
16031 __ cbnzw($oop$$Register, *L);
16032 %}
16033 ins_pipe(pipe_cmp_branch);
16034 %}
16035
16036 instruct cmpUI_imm0_branch(cmpOpUEqNeLeGt cmp, iRegIorL2I op1, immI0 op2, label labl) %{
16037 match(If cmp (CmpU op1 op2));
16038 effect(USE labl);
16039
16040 ins_cost(BRANCH_COST);
16041 format %{ "cbw$cmp $op1, $labl" %}
16042 ins_encode %{
16043 Label* L = $labl$$label;
16044 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16045 if (cond == Assembler::EQ || cond == Assembler::LS) {
16046 __ cbzw($op1$$Register, *L);
16047 } else {
16048 assert(cond == Assembler::NE || cond == Assembler::HI, "unexpected condition");
16049 __ cbnzw($op1$$Register, *L);
16050 }
16051 %}
16052 ins_pipe(pipe_cmp_branch);
16053 %}
16054
16055 instruct cmpUL_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 op2, label labl) %{
16056 match(If cmp (CmpUL op1 op2));
16057 effect(USE labl);
16058
16059 ins_cost(BRANCH_COST);
16060 format %{ "cb$cmp $op1, $labl" %}
16061 ins_encode %{
16062 Label* L = $labl$$label;
16063 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16064 if (cond == Assembler::EQ || cond == Assembler::LS) {
16065 __ cbz($op1$$Register, *L);
16066 } else {
16067 assert(cond == Assembler::NE || cond == Assembler::HI, "unexpected condition");
16068 __ cbnz($op1$$Register, *L);
16069 }
16070 %}
16071 ins_pipe(pipe_cmp_branch);
16072 %}
16073
16074 // Test bit and Branch
16075
16076 // Patterns for short (< 32KiB) variants
16077 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
16078 match(If cmp (CmpL op1 op2));
16079 effect(USE labl);
16080
16081 ins_cost(BRANCH_COST);
16082 format %{ "cb$cmp $op1, $labl # long" %}
16083 ins_encode %{
16084 Label* L = $labl$$label;
16085 Assembler::Condition cond =
16086 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16087 __ tbr(cond, $op1$$Register, 63, *L);
16088 %}
16089 ins_pipe(pipe_cmp_branch);
16090 ins_short_branch(1);
16091 %}
16092
16093 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
16094 match(If cmp (CmpI op1 op2));
16095 effect(USE labl);
16096
16097 ins_cost(BRANCH_COST);
16098 format %{ "cb$cmp $op1, $labl # int" %}
16099 ins_encode %{
16100 Label* L = $labl$$label;
16101 Assembler::Condition cond =
16102 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16103 __ tbr(cond, $op1$$Register, 31, *L);
16104 %}
16105 ins_pipe(pipe_cmp_branch);
16106 ins_short_branch(1);
16107 %}
16108
16109 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
16110 match(If cmp (CmpL (AndL op1 op2) op3));
16111 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long()));
16112 effect(USE labl);
16113
16114 ins_cost(BRANCH_COST);
16115 format %{ "tb$cmp $op1, $op2, $labl" %}
16116 ins_encode %{
16117 Label* L = $labl$$label;
16118 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16119 int bit = exact_log2_long($op2$$constant);
16120 __ tbr(cond, $op1$$Register, bit, *L);
16121 %}
16122 ins_pipe(pipe_cmp_branch);
16123 ins_short_branch(1);
16124 %}
16125
16126 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
16127 match(If cmp (CmpI (AndI op1 op2) op3));
16128 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int()));
16129 effect(USE labl);
16130
16131 ins_cost(BRANCH_COST);
16132 format %{ "tb$cmp $op1, $op2, $labl" %}
16133 ins_encode %{
16134 Label* L = $labl$$label;
16135 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16136 int bit = exact_log2((juint)$op2$$constant);
16137 __ tbr(cond, $op1$$Register, bit, *L);
16138 %}
16139 ins_pipe(pipe_cmp_branch);
16140 ins_short_branch(1);
16141 %}
16142
16143 // And far variants
16144 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
16145 match(If cmp (CmpL op1 op2));
16146 effect(USE labl);
16147
16148 ins_cost(BRANCH_COST);
16149 format %{ "cb$cmp $op1, $labl # long" %}
16150 ins_encode %{
16151 Label* L = $labl$$label;
16152 Assembler::Condition cond =
16153 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16154 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true);
16155 %}
16156 ins_pipe(pipe_cmp_branch);
16157 %}
16158
16159 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
16160 match(If cmp (CmpI op1 op2));
16161 effect(USE labl);
16162
16163 ins_cost(BRANCH_COST);
16164 format %{ "cb$cmp $op1, $labl # int" %}
16165 ins_encode %{
16166 Label* L = $labl$$label;
16167 Assembler::Condition cond =
16168 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16169 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true);
16170 %}
16171 ins_pipe(pipe_cmp_branch);
16172 %}
16173
16174 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
16175 match(If cmp (CmpL (AndL op1 op2) op3));
16176 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long()));
16177 effect(USE labl);
16178
16179 ins_cost(BRANCH_COST);
16180 format %{ "tb$cmp $op1, $op2, $labl" %}
16181 ins_encode %{
16182 Label* L = $labl$$label;
16183 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16184 int bit = exact_log2_long($op2$$constant);
16185 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
16186 %}
16187 ins_pipe(pipe_cmp_branch);
16188 %}
16189
16190 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
16191 match(If cmp (CmpI (AndI op1 op2) op3));
16192 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int()));
16193 effect(USE labl);
16194
16195 ins_cost(BRANCH_COST);
16196 format %{ "tb$cmp $op1, $op2, $labl" %}
16197 ins_encode %{
16198 Label* L = $labl$$label;
16199 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16200 int bit = exact_log2((juint)$op2$$constant);
16201 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
16202 %}
16203 ins_pipe(pipe_cmp_branch);
16204 %}
16205
16206 // Test bits
16207
16208 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{
16209 match(Set cr (CmpL (AndL op1 op2) op3));
16210 predicate(Assembler::operand_valid_for_logical_immediate
16211 (/*is_32*/false, n->in(1)->in(2)->get_long()));
16212
16213 ins_cost(INSN_COST);
16214 format %{ "tst $op1, $op2 # long" %}
16215 ins_encode %{
16216 __ tst($op1$$Register, $op2$$constant);
16217 %}
16218 ins_pipe(ialu_reg_reg);
16219 %}
16220
16221 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{
16222 match(Set cr (CmpI (AndI op1 op2) op3));
16223 predicate(Assembler::operand_valid_for_logical_immediate
16224 (/*is_32*/true, n->in(1)->in(2)->get_int()));
16225
16226 ins_cost(INSN_COST);
16227 format %{ "tst $op1, $op2 # int" %}
16228 ins_encode %{
16229 __ tstw($op1$$Register, $op2$$constant);
16230 %}
16231 ins_pipe(ialu_reg_reg);
16232 %}
16233
16234 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{
16235 match(Set cr (CmpL (AndL op1 op2) op3));
16236
16237 ins_cost(INSN_COST);
16238 format %{ "tst $op1, $op2 # long" %}
16239 ins_encode %{
16240 __ tst($op1$$Register, $op2$$Register);
16241 %}
16242 ins_pipe(ialu_reg_reg);
16243 %}
16244
16245 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{
16246 match(Set cr (CmpI (AndI op1 op2) op3));
16247
16248 ins_cost(INSN_COST);
16249 format %{ "tstw $op1, $op2 # int" %}
16250 ins_encode %{
16251 __ tstw($op1$$Register, $op2$$Register);
16252 %}
16253 ins_pipe(ialu_reg_reg);
16254 %}
16255
16256
16257 // Conditional Far Branch
16258 // Conditional Far Branch Unsigned
16259 // TODO: fixme
16260
16261 // counted loop end branch near
16262 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
16263 %{
16264 match(CountedLoopEnd cmp cr);
16265
16266 effect(USE lbl);
16267
16268 ins_cost(BRANCH_COST);
16269 // short variant.
16270 // ins_short_branch(1);
16271 format %{ "b$cmp $lbl \t// counted loop end" %}
16272
16273 ins_encode(aarch64_enc_br_con(cmp, lbl));
16274
16275 ins_pipe(pipe_branch);
16276 %}
16277
16278 // counted loop end branch far
16279 // TODO: fixme
16280
16281 // ============================================================================
16282 // inlined locking and unlocking
16283
16284 instruct cmpFastLockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3)
16285 %{
16286 match(Set cr (FastLock object box));
16287 effect(TEMP tmp, TEMP tmp2, TEMP tmp3);
16288
16289 ins_cost(5 * INSN_COST);
16290 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2,$tmp3" %}
16291
16292 ins_encode %{
16293 __ fast_lock_lightweight($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
16294 %}
16295
16296 ins_pipe(pipe_serial);
16297 %}
16298
16299 instruct cmpFastUnlockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3)
16300 %{
16301 match(Set cr (FastUnlock object box));
16302 effect(TEMP tmp, TEMP tmp2, TEMP tmp3);
16303
16304 ins_cost(5 * INSN_COST);
16305 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2, $tmp3" %}
16306
16307 ins_encode %{
16308 __ fast_unlock_lightweight($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
16309 %}
16310
16311 ins_pipe(pipe_serial);
16312 %}
16313
16314 // ============================================================================
16315 // Safepoint Instructions
16316
16317 // TODO
16318 // provide a near and far version of this code
16319
16320 instruct safePoint(rFlagsReg cr, iRegP poll)
16321 %{
16322 match(SafePoint poll);
16323 effect(KILL cr);
16324
16325 format %{
16326 "ldrw zr, [$poll]\t# Safepoint: poll for GC"
16327 %}
16328 ins_encode %{
16329 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type);
16330 %}
16331 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem);
16332 %}
16333
16334
16335 // ============================================================================
16336 // Procedure Call/Return Instructions
16337
16338 // Call Java Static Instruction
16339
16340 instruct CallStaticJavaDirect(method meth)
16341 %{
16342 match(CallStaticJava);
16343
16344 effect(USE meth);
16345
16346 ins_cost(CALL_COST);
16347
16348 format %{ "call,static $meth \t// ==> " %}
16349
16350 ins_encode(aarch64_enc_java_static_call(meth),
16351 aarch64_enc_call_epilog);
16352
16353 ins_pipe(pipe_class_call);
16354 %}
16355
16356 // TO HERE
16357
16358 // Call Java Dynamic Instruction
16359 instruct CallDynamicJavaDirect(method meth)
16360 %{
16361 match(CallDynamicJava);
16362
16363 effect(USE meth);
16364
16365 ins_cost(CALL_COST);
16366
16367 format %{ "CALL,dynamic $meth \t// ==> " %}
16368
16369 ins_encode(aarch64_enc_java_dynamic_call(meth),
16370 aarch64_enc_call_epilog);
16371
16372 ins_pipe(pipe_class_call);
16373 %}
16374
16375 // Call Runtime Instruction
16376
16377 instruct CallRuntimeDirect(method meth)
16378 %{
16379 match(CallRuntime);
16380
16381 effect(USE meth);
16382
16383 ins_cost(CALL_COST);
16384
16385 format %{ "CALL, runtime $meth" %}
16386
16387 ins_encode( aarch64_enc_java_to_runtime(meth) );
16388
16389 ins_pipe(pipe_class_call);
16390 %}
16391
16392 // Call Runtime Instruction
16393
16394 instruct CallLeafDirect(method meth)
16395 %{
16396 match(CallLeaf);
16397
16398 effect(USE meth);
16399
16400 ins_cost(CALL_COST);
16401
16402 format %{ "CALL, runtime leaf $meth" %}
16403
16404 ins_encode( aarch64_enc_java_to_runtime(meth) );
16405
16406 ins_pipe(pipe_class_call);
16407 %}
16408
16409 // Call Runtime Instruction without safepoint and with vector arguments
16410 instruct CallLeafDirectVector(method meth)
16411 %{
16412 match(CallLeafVector);
16413
16414 effect(USE meth);
16415
16416 ins_cost(CALL_COST);
16417
16418 format %{ "CALL, runtime leaf vector $meth" %}
16419
16420 ins_encode(aarch64_enc_java_to_runtime(meth));
16421
16422 ins_pipe(pipe_class_call);
16423 %}
16424
16425 // Call Runtime Instruction
16426
16427 instruct CallLeafNoFPDirect(method meth)
16428 %{
16429 match(CallLeafNoFP);
16430
16431 effect(USE meth);
16432
16433 ins_cost(CALL_COST);
16434
16435 format %{ "CALL, runtime leaf nofp $meth" %}
16436
16437 ins_encode( aarch64_enc_java_to_runtime(meth) );
16438
16439 ins_pipe(pipe_class_call);
16440 %}
16441
16442 // Tail Call; Jump from runtime stub to Java code.
16443 // Also known as an 'interprocedural jump'.
16444 // Target of jump will eventually return to caller.
16445 // TailJump below removes the return address.
16446 // Don't use rfp for 'jump_target' because a MachEpilogNode has already been
16447 // emitted just above the TailCall which has reset rfp to the caller state.
16448 instruct TailCalljmpInd(iRegPNoSpNoRfp jump_target, inline_cache_RegP method_ptr)
16449 %{
16450 match(TailCall jump_target method_ptr);
16451
16452 ins_cost(CALL_COST);
16453
16454 format %{ "br $jump_target\t# $method_ptr holds method" %}
16455
16456 ins_encode(aarch64_enc_tail_call(jump_target));
16457
16458 ins_pipe(pipe_class_call);
16459 %}
16460
16461 instruct TailjmpInd(iRegPNoSpNoRfp jump_target, iRegP_R0 ex_oop)
16462 %{
16463 match(TailJump jump_target ex_oop);
16464
16465 ins_cost(CALL_COST);
16466
16467 format %{ "br $jump_target\t# $ex_oop holds exception oop" %}
16468
16469 ins_encode(aarch64_enc_tail_jmp(jump_target));
16470
16471 ins_pipe(pipe_class_call);
16472 %}
16473
16474 // Forward exception.
16475 instruct ForwardExceptionjmp()
16476 %{
16477 match(ForwardException);
16478 ins_cost(CALL_COST);
16479
16480 format %{ "b forward_exception_stub" %}
16481 ins_encode %{
16482 __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
16483 %}
16484 ins_pipe(pipe_class_call);
16485 %}
16486
16487 // Create exception oop: created by stack-crawling runtime code.
16488 // Created exception is now available to this handler, and is setup
16489 // just prior to jumping to this handler. No code emitted.
16490 // TODO check
16491 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1
16492 instruct CreateException(iRegP_R0 ex_oop)
16493 %{
16494 match(Set ex_oop (CreateEx));
16495
16496 format %{ " -- \t// exception oop; no code emitted" %}
16497
16498 size(0);
16499
16500 ins_encode( /*empty*/ );
16501
16502 ins_pipe(pipe_class_empty);
16503 %}
16504
16505 // Rethrow exception: The exception oop will come in the first
16506 // argument position. Then JUMP (not call) to the rethrow stub code.
16507 instruct RethrowException() %{
16508 match(Rethrow);
16509 ins_cost(CALL_COST);
16510
16511 format %{ "b rethrow_stub" %}
16512
16513 ins_encode( aarch64_enc_rethrow() );
16514
16515 ins_pipe(pipe_class_call);
16516 %}
16517
16518
16519 // Return Instruction
16520 // epilog node loads ret address into lr as part of frame pop
16521 instruct Ret()
16522 %{
16523 match(Return);
16524
16525 format %{ "ret\t// return register" %}
16526
16527 ins_encode( aarch64_enc_ret() );
16528
16529 ins_pipe(pipe_branch);
16530 %}
16531
16532 // Die now.
16533 instruct ShouldNotReachHere() %{
16534 match(Halt);
16535
16536 ins_cost(CALL_COST);
16537 format %{ "ShouldNotReachHere" %}
16538
16539 ins_encode %{
16540 if (is_reachable()) {
16541 const char* str = __ code_string(_halt_reason);
16542 __ stop(str);
16543 }
16544 %}
16545
16546 ins_pipe(pipe_class_default);
16547 %}
16548
16549 // ============================================================================
16550 // Partial Subtype Check
16551 //
16552 // superklass array for an instance of the superklass. Set a hidden
16553 // internal cache on a hit (cache is checked with exposed code in
16554 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The
16555 // encoding ALSO sets flags.
16556
16557 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr)
16558 %{
16559 match(Set result (PartialSubtypeCheck sub super));
16560 predicate(!UseSecondarySupersTable);
16561 effect(KILL cr, KILL temp);
16562
16563 ins_cost(20 * INSN_COST); // slightly larger than the next version
16564 format %{ "partialSubtypeCheck $result, $sub, $super" %}
16565
16566 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
16567
16568 opcode(0x1); // Force zero of result reg on hit
16569
16570 ins_pipe(pipe_class_memory);
16571 %}
16572
16573 // Two versions of partialSubtypeCheck, both used when we need to
16574 // search for a super class in the secondary supers array. The first
16575 // is used when we don't know _a priori_ the class being searched
16576 // for. The second, far more common, is used when we do know: this is
16577 // used for instanceof, checkcast, and any case where C2 can determine
16578 // it by constant propagation.
16579
16580 instruct partialSubtypeCheckVarSuper(iRegP_R4 sub, iRegP_R0 super, vRegD_V0 vtemp, iRegP_R5 result,
16581 iRegP_R1 tempR1, iRegP_R2 tempR2, iRegP_R3 tempR3,
16582 rFlagsReg cr)
16583 %{
16584 match(Set result (PartialSubtypeCheck sub super));
16585 predicate(UseSecondarySupersTable);
16586 effect(KILL cr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP vtemp);
16587
16588 ins_cost(10 * INSN_COST); // slightly larger than the next version
16589 format %{ "partialSubtypeCheck $result, $sub, $super" %}
16590
16591 ins_encode %{
16592 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
16593 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register,
16594 $vtemp$$FloatRegister,
16595 $result$$Register, /*L_success*/nullptr);
16596 %}
16597
16598 ins_pipe(pipe_class_memory);
16599 %}
16600
16601 instruct partialSubtypeCheckConstSuper(iRegP_R4 sub, iRegP_R0 super_reg, immP super_con, vRegD_V0 vtemp, iRegP_R5 result,
16602 iRegP_R1 tempR1, iRegP_R2 tempR2, iRegP_R3 tempR3,
16603 rFlagsReg cr)
16604 %{
16605 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
16606 predicate(UseSecondarySupersTable);
16607 effect(KILL cr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP vtemp);
16608
16609 ins_cost(5 * INSN_COST); // smaller than the next version
16610 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %}
16611
16612 ins_encode %{
16613 bool success = false;
16614 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
16615 if (InlineSecondarySupersTest) {
16616 success =
16617 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
16618 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register,
16619 $vtemp$$FloatRegister,
16620 $result$$Register,
16621 super_klass_slot);
16622 } else {
16623 address call = __ trampoline_call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot)));
16624 success = (call != nullptr);
16625 }
16626 if (!success) {
16627 ciEnv::current()->record_failure("CodeCache is full");
16628 return;
16629 }
16630 %}
16631
16632 ins_pipe(pipe_class_memory);
16633 %}
16634
16635 // Intrisics for String.compareTo()
16636
16637 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16638 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
16639 %{
16640 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU));
16641 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16642 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16643
16644 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %}
16645 ins_encode %{
16646 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16647 __ string_compare($str1$$Register, $str2$$Register,
16648 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16649 $tmp1$$Register, $tmp2$$Register,
16650 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::UU);
16651 %}
16652 ins_pipe(pipe_class_memory);
16653 %}
16654
16655 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16656 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
16657 %{
16658 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL));
16659 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16660 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16661
16662 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %}
16663 ins_encode %{
16664 __ string_compare($str1$$Register, $str2$$Register,
16665 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16666 $tmp1$$Register, $tmp2$$Register,
16667 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::LL);
16668 %}
16669 ins_pipe(pipe_class_memory);
16670 %}
16671
16672 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16673 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16674 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
16675 %{
16676 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL));
16677 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16678 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
16679 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16680
16681 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
16682 ins_encode %{
16683 __ string_compare($str1$$Register, $str2$$Register,
16684 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16685 $tmp1$$Register, $tmp2$$Register,
16686 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
16687 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::UL);
16688 %}
16689 ins_pipe(pipe_class_memory);
16690 %}
16691
16692 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16693 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16694 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
16695 %{
16696 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU));
16697 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16698 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
16699 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16700
16701 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
16702 ins_encode %{
16703 __ string_compare($str1$$Register, $str2$$Register,
16704 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16705 $tmp1$$Register, $tmp2$$Register,
16706 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
16707 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::LU);
16708 %}
16709 ins_pipe(pipe_class_memory);
16710 %}
16711
16712 // Note that Z registers alias the corresponding NEON registers, we declare the vector operands of
16713 // these string_compare variants as NEON register type for convenience so that the prototype of
16714 // string_compare can be shared with all variants.
16715
16716 instruct string_compareLL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16717 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16718 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
16719 pRegGov_P1 pgtmp2, rFlagsReg cr)
16720 %{
16721 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL));
16722 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16723 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
16724 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16725
16726 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
16727 ins_encode %{
16728 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16729 __ string_compare($str1$$Register, $str2$$Register,
16730 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16731 $tmp1$$Register, $tmp2$$Register,
16732 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
16733 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
16734 StrIntrinsicNode::LL);
16735 %}
16736 ins_pipe(pipe_class_memory);
16737 %}
16738
16739 instruct string_compareLU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16740 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16741 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
16742 pRegGov_P1 pgtmp2, rFlagsReg cr)
16743 %{
16744 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU));
16745 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16746 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
16747 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16748
16749 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
16750 ins_encode %{
16751 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16752 __ string_compare($str1$$Register, $str2$$Register,
16753 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16754 $tmp1$$Register, $tmp2$$Register,
16755 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
16756 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
16757 StrIntrinsicNode::LU);
16758 %}
16759 ins_pipe(pipe_class_memory);
16760 %}
16761
16762 instruct string_compareUL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16763 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16764 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
16765 pRegGov_P1 pgtmp2, rFlagsReg cr)
16766 %{
16767 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL));
16768 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16769 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
16770 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16771
16772 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
16773 ins_encode %{
16774 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16775 __ string_compare($str1$$Register, $str2$$Register,
16776 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16777 $tmp1$$Register, $tmp2$$Register,
16778 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
16779 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
16780 StrIntrinsicNode::UL);
16781 %}
16782 ins_pipe(pipe_class_memory);
16783 %}
16784
16785 instruct string_compareUU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16786 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16787 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
16788 pRegGov_P1 pgtmp2, rFlagsReg cr)
16789 %{
16790 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU));
16791 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16792 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
16793 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16794
16795 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
16796 ins_encode %{
16797 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16798 __ string_compare($str1$$Register, $str2$$Register,
16799 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16800 $tmp1$$Register, $tmp2$$Register,
16801 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
16802 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
16803 StrIntrinsicNode::UU);
16804 %}
16805 ins_pipe(pipe_class_memory);
16806 %}
16807
16808 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
16809 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
16810 iRegINoSp tmp3, iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6,
16811 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr)
16812 %{
16813 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
16814 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
16815 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
16816 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6,
16817 TEMP vtmp0, TEMP vtmp1, KILL cr);
16818 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU) "
16819 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %}
16820
16821 ins_encode %{
16822 __ string_indexof($str1$$Register, $str2$$Register,
16823 $cnt1$$Register, $cnt2$$Register,
16824 $tmp1$$Register, $tmp2$$Register,
16825 $tmp3$$Register, $tmp4$$Register,
16826 $tmp5$$Register, $tmp6$$Register,
16827 -1, $result$$Register, StrIntrinsicNode::UU);
16828 %}
16829 ins_pipe(pipe_class_memory);
16830 %}
16831
16832 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
16833 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
16834 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6,
16835 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr)
16836 %{
16837 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
16838 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
16839 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
16840 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6,
16841 TEMP vtmp0, TEMP vtmp1, KILL cr);
16842 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL) "
16843 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %}
16844
16845 ins_encode %{
16846 __ string_indexof($str1$$Register, $str2$$Register,
16847 $cnt1$$Register, $cnt2$$Register,
16848 $tmp1$$Register, $tmp2$$Register,
16849 $tmp3$$Register, $tmp4$$Register,
16850 $tmp5$$Register, $tmp6$$Register,
16851 -1, $result$$Register, StrIntrinsicNode::LL);
16852 %}
16853 ins_pipe(pipe_class_memory);
16854 %}
16855
16856 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
16857 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,iRegINoSp tmp3,
16858 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6,
16859 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr)
16860 %{
16861 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
16862 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
16863 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
16864 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
16865 TEMP tmp6, TEMP vtmp0, TEMP vtmp1, KILL cr);
16866 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL) "
16867 "# KILL $str1 cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %}
16868
16869 ins_encode %{
16870 __ string_indexof($str1$$Register, $str2$$Register,
16871 $cnt1$$Register, $cnt2$$Register,
16872 $tmp1$$Register, $tmp2$$Register,
16873 $tmp3$$Register, $tmp4$$Register,
16874 $tmp5$$Register, $tmp6$$Register,
16875 -1, $result$$Register, StrIntrinsicNode::UL);
16876 %}
16877 ins_pipe(pipe_class_memory);
16878 %}
16879
16880 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
16881 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1,
16882 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
16883 %{
16884 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
16885 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
16886 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
16887 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
16888 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU) "
16889 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %}
16890
16891 ins_encode %{
16892 int icnt2 = (int)$int_cnt2$$constant;
16893 __ string_indexof($str1$$Register, $str2$$Register,
16894 $cnt1$$Register, zr,
16895 $tmp1$$Register, $tmp2$$Register,
16896 $tmp3$$Register, $tmp4$$Register, zr, zr,
16897 icnt2, $result$$Register, StrIntrinsicNode::UU);
16898 %}
16899 ins_pipe(pipe_class_memory);
16900 %}
16901
16902 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
16903 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1,
16904 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
16905 %{
16906 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
16907 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
16908 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
16909 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
16910 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL) "
16911 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %}
16912
16913 ins_encode %{
16914 int icnt2 = (int)$int_cnt2$$constant;
16915 __ string_indexof($str1$$Register, $str2$$Register,
16916 $cnt1$$Register, zr,
16917 $tmp1$$Register, $tmp2$$Register,
16918 $tmp3$$Register, $tmp4$$Register, zr, zr,
16919 icnt2, $result$$Register, StrIntrinsicNode::LL);
16920 %}
16921 ins_pipe(pipe_class_memory);
16922 %}
16923
16924 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
16925 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1,
16926 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
16927 %{
16928 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
16929 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
16930 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
16931 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
16932 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL) "
16933 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %}
16934
16935 ins_encode %{
16936 int icnt2 = (int)$int_cnt2$$constant;
16937 __ string_indexof($str1$$Register, $str2$$Register,
16938 $cnt1$$Register, zr,
16939 $tmp1$$Register, $tmp2$$Register,
16940 $tmp3$$Register, $tmp4$$Register, zr, zr,
16941 icnt2, $result$$Register, StrIntrinsicNode::UL);
16942 %}
16943 ins_pipe(pipe_class_memory);
16944 %}
16945
16946 instruct string_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
16947 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
16948 iRegINoSp tmp3, rFlagsReg cr)
16949 %{
16950 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
16951 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U));
16952 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
16953 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
16954
16955 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result" %}
16956
16957 ins_encode %{
16958 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
16959 $result$$Register, $tmp1$$Register, $tmp2$$Register,
16960 $tmp3$$Register);
16961 %}
16962 ins_pipe(pipe_class_memory);
16963 %}
16964
16965 instruct stringL_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
16966 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
16967 iRegINoSp tmp3, rFlagsReg cr)
16968 %{
16969 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
16970 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
16971 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
16972 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
16973
16974 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result" %}
16975
16976 ins_encode %{
16977 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
16978 $result$$Register, $tmp1$$Register, $tmp2$$Register,
16979 $tmp3$$Register);
16980 %}
16981 ins_pipe(pipe_class_memory);
16982 %}
16983
16984 instruct stringL_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
16985 iRegI_R0 result, vecA ztmp1, vecA ztmp2,
16986 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{
16987 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
16988 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
16989 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr);
16990 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %}
16991 ins_encode %{
16992 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register,
16993 $result$$Register, $ztmp1$$FloatRegister,
16994 $ztmp2$$FloatRegister, $pgtmp$$PRegister,
16995 $ptmp$$PRegister, true /* isL */);
16996 %}
16997 ins_pipe(pipe_class_memory);
16998 %}
16999
17000 instruct stringU_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
17001 iRegI_R0 result, vecA ztmp1, vecA ztmp2,
17002 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{
17003 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
17004 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
17005 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr);
17006 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %}
17007 ins_encode %{
17008 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register,
17009 $result$$Register, $ztmp1$$FloatRegister,
17010 $ztmp2$$FloatRegister, $pgtmp$$PRegister,
17011 $ptmp$$PRegister, false /* isL */);
17012 %}
17013 ins_pipe(pipe_class_memory);
17014 %}
17015
17016 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
17017 iRegI_R0 result, rFlagsReg cr)
17018 %{
17019 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
17020 match(Set result (StrEquals (Binary str1 str2) cnt));
17021 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
17022
17023 format %{ "String Equals $str1,$str2,$cnt -> $result" %}
17024 ins_encode %{
17025 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
17026 __ string_equals($str1$$Register, $str2$$Register,
17027 $result$$Register, $cnt$$Register);
17028 %}
17029 ins_pipe(pipe_class_memory);
17030 %}
17031
17032 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
17033 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
17034 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3,
17035 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7,
17036 iRegP_R10 tmp, rFlagsReg cr)
17037 %{
17038 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
17039 match(Set result (AryEq ary1 ary2));
17040 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3,
17041 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5,
17042 TEMP vtmp6, TEMP vtmp7, KILL cr);
17043
17044 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %}
17045 ins_encode %{
17046 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
17047 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
17048 $result$$Register, $tmp$$Register, 1);
17049 if (tpc == nullptr) {
17050 ciEnv::current()->record_failure("CodeCache is full");
17051 return;
17052 }
17053 %}
17054 ins_pipe(pipe_class_memory);
17055 %}
17056
17057 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
17058 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
17059 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3,
17060 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7,
17061 iRegP_R10 tmp, rFlagsReg cr)
17062 %{
17063 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
17064 match(Set result (AryEq ary1 ary2));
17065 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3,
17066 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5,
17067 TEMP vtmp6, TEMP vtmp7, KILL cr);
17068
17069 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %}
17070 ins_encode %{
17071 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
17072 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
17073 $result$$Register, $tmp$$Register, 2);
17074 if (tpc == nullptr) {
17075 ciEnv::current()->record_failure("CodeCache is full");
17076 return;
17077 }
17078 %}
17079 ins_pipe(pipe_class_memory);
17080 %}
17081
17082 instruct arrays_hashcode(iRegP_R1 ary, iRegI_R2 cnt, iRegI_R0 result, immI basic_type,
17083 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3,
17084 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7,
17085 vRegD_V12 vtmp8, vRegD_V13 vtmp9, rFlagsReg cr)
17086 %{
17087 match(Set result (VectorizedHashCode (Binary ary cnt) (Binary result basic_type)));
17088 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, TEMP vtmp6,
17089 TEMP vtmp7, TEMP vtmp8, TEMP vtmp9, USE_KILL ary, USE_KILL cnt, USE basic_type, KILL cr);
17090
17091 format %{ "Array HashCode array[] $ary,$cnt,$result,$basic_type -> $result // KILL all" %}
17092 ins_encode %{
17093 address tpc = __ arrays_hashcode($ary$$Register, $cnt$$Register, $result$$Register,
17094 $vtmp3$$FloatRegister, $vtmp2$$FloatRegister,
17095 $vtmp1$$FloatRegister, $vtmp0$$FloatRegister,
17096 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister,
17097 $vtmp6$$FloatRegister, $vtmp7$$FloatRegister,
17098 $vtmp8$$FloatRegister, $vtmp9$$FloatRegister,
17099 (BasicType)$basic_type$$constant);
17100 if (tpc == nullptr) {
17101 ciEnv::current()->record_failure("CodeCache is full");
17102 return;
17103 }
17104 %}
17105 ins_pipe(pipe_class_memory);
17106 %}
17107
17108 instruct count_positives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr)
17109 %{
17110 match(Set result (CountPositives ary1 len));
17111 effect(USE_KILL ary1, USE_KILL len, KILL cr);
17112 format %{ "count positives byte[] $ary1,$len -> $result" %}
17113 ins_encode %{
17114 address tpc = __ count_positives($ary1$$Register, $len$$Register, $result$$Register);
17115 if (tpc == nullptr) {
17116 ciEnv::current()->record_failure("CodeCache is full");
17117 return;
17118 }
17119 %}
17120 ins_pipe( pipe_slow );
17121 %}
17122
17123 // fast char[] to byte[] compression
17124 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
17125 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2,
17126 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5,
17127 iRegI_R0 result, rFlagsReg cr)
17128 %{
17129 match(Set result (StrCompressedCopy src (Binary dst len)));
17130 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5,
17131 USE_KILL src, USE_KILL dst, USE len, KILL cr);
17132
17133 format %{ "String Compress $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %}
17134 ins_encode %{
17135 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
17136 $result$$Register, $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
17137 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister,
17138 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister);
17139 %}
17140 ins_pipe(pipe_slow);
17141 %}
17142
17143 // fast byte[] to char[] inflation
17144 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, iRegP_R3 tmp,
17145 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3,
17146 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, rFlagsReg cr)
17147 %{
17148 match(Set dummy (StrInflatedCopy src (Binary dst len)));
17149 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3,
17150 TEMP vtmp4, TEMP vtmp5, TEMP vtmp6, TEMP tmp,
17151 USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
17152
17153 format %{ "String Inflate $src,$dst # KILL $tmp $src $dst $len V0-V6 cr" %}
17154 ins_encode %{
17155 address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
17156 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
17157 $vtmp2$$FloatRegister, $tmp$$Register);
17158 if (tpc == nullptr) {
17159 ciEnv::current()->record_failure("CodeCache is full");
17160 return;
17161 }
17162 %}
17163 ins_pipe(pipe_class_memory);
17164 %}
17165
17166 // encode char[] to byte[] in ISO_8859_1
17167 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
17168 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2,
17169 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5,
17170 iRegI_R0 result, rFlagsReg cr)
17171 %{
17172 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
17173 match(Set result (EncodeISOArray src (Binary dst len)));
17174 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1,
17175 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr);
17176
17177 format %{ "Encode ISO array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %}
17178 ins_encode %{
17179 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
17180 $result$$Register, false,
17181 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
17182 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister,
17183 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister);
17184 %}
17185 ins_pipe(pipe_class_memory);
17186 %}
17187
17188 instruct encode_ascii_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
17189 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2,
17190 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5,
17191 iRegI_R0 result, rFlagsReg cr)
17192 %{
17193 predicate(((EncodeISOArrayNode*)n)->is_ascii());
17194 match(Set result (EncodeISOArray src (Binary dst len)));
17195 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1,
17196 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr);
17197
17198 format %{ "Encode ASCII array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %}
17199 ins_encode %{
17200 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
17201 $result$$Register, true,
17202 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
17203 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister,
17204 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister);
17205 %}
17206 ins_pipe(pipe_class_memory);
17207 %}
17208
17209 //----------------------------- CompressBits/ExpandBits ------------------------
17210
17211 instruct compressBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask,
17212 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17213 match(Set dst (CompressBits src mask));
17214 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17215 format %{ "mov $tsrc, $src\n\t"
17216 "mov $tmask, $mask\n\t"
17217 "bext $tdst, $tsrc, $tmask\n\t"
17218 "mov $dst, $tdst"
17219 %}
17220 ins_encode %{
17221 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register);
17222 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register);
17223 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17224 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0);
17225 %}
17226 ins_pipe(pipe_slow);
17227 %}
17228
17229 instruct compressBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask,
17230 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17231 match(Set dst (CompressBits (LoadI mem) mask));
17232 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17233 format %{ "ldrs $tsrc, $mem\n\t"
17234 "ldrs $tmask, $mask\n\t"
17235 "bext $tdst, $tsrc, $tmask\n\t"
17236 "mov $dst, $tdst"
17237 %}
17238 ins_encode %{
17239 loadStore(masm, &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(),
17240 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
17241 __ ldrs($tmask$$FloatRegister, $constantaddress($mask));
17242 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17243 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0);
17244 %}
17245 ins_pipe(pipe_slow);
17246 %}
17247
17248 instruct compressBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask,
17249 vRegD tdst, vRegD tsrc, vRegD tmask) %{
17250 match(Set dst (CompressBits src mask));
17251 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17252 format %{ "mov $tsrc, $src\n\t"
17253 "mov $tmask, $mask\n\t"
17254 "bext $tdst, $tsrc, $tmask\n\t"
17255 "mov $dst, $tdst"
17256 %}
17257 ins_encode %{
17258 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register);
17259 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register);
17260 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17261 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0);
17262 %}
17263 ins_pipe(pipe_slow);
17264 %}
17265
17266 instruct compressBitsL_memcon(iRegLNoSp dst, memory8 mem, immL mask,
17267 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17268 match(Set dst (CompressBits (LoadL mem) mask));
17269 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17270 format %{ "ldrd $tsrc, $mem\n\t"
17271 "ldrd $tmask, $mask\n\t"
17272 "bext $tdst, $tsrc, $tmask\n\t"
17273 "mov $dst, $tdst"
17274 %}
17275 ins_encode %{
17276 loadStore(masm, &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(),
17277 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
17278 __ ldrd($tmask$$FloatRegister, $constantaddress($mask));
17279 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17280 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0);
17281 %}
17282 ins_pipe(pipe_slow);
17283 %}
17284
17285 instruct expandBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask,
17286 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17287 match(Set dst (ExpandBits src mask));
17288 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17289 format %{ "mov $tsrc, $src\n\t"
17290 "mov $tmask, $mask\n\t"
17291 "bdep $tdst, $tsrc, $tmask\n\t"
17292 "mov $dst, $tdst"
17293 %}
17294 ins_encode %{
17295 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register);
17296 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register);
17297 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17298 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0);
17299 %}
17300 ins_pipe(pipe_slow);
17301 %}
17302
17303 instruct expandBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask,
17304 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17305 match(Set dst (ExpandBits (LoadI mem) mask));
17306 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17307 format %{ "ldrs $tsrc, $mem\n\t"
17308 "ldrs $tmask, $mask\n\t"
17309 "bdep $tdst, $tsrc, $tmask\n\t"
17310 "mov $dst, $tdst"
17311 %}
17312 ins_encode %{
17313 loadStore(masm, &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(),
17314 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
17315 __ ldrs($tmask$$FloatRegister, $constantaddress($mask));
17316 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17317 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0);
17318 %}
17319 ins_pipe(pipe_slow);
17320 %}
17321
17322 instruct expandBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask,
17323 vRegD tdst, vRegD tsrc, vRegD tmask) %{
17324 match(Set dst (ExpandBits src mask));
17325 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17326 format %{ "mov $tsrc, $src\n\t"
17327 "mov $tmask, $mask\n\t"
17328 "bdep $tdst, $tsrc, $tmask\n\t"
17329 "mov $dst, $tdst"
17330 %}
17331 ins_encode %{
17332 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register);
17333 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register);
17334 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17335 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0);
17336 %}
17337 ins_pipe(pipe_slow);
17338 %}
17339
17340
17341 instruct expandBitsL_memcon(iRegINoSp dst, memory8 mem, immL mask,
17342 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17343 match(Set dst (ExpandBits (LoadL mem) mask));
17344 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17345 format %{ "ldrd $tsrc, $mem\n\t"
17346 "ldrd $tmask, $mask\n\t"
17347 "bdep $tdst, $tsrc, $tmask\n\t"
17348 "mov $dst, $tdst"
17349 %}
17350 ins_encode %{
17351 loadStore(masm, &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(),
17352 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
17353 __ ldrd($tmask$$FloatRegister, $constantaddress($mask));
17354 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17355 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0);
17356 %}
17357 ins_pipe(pipe_slow);
17358 %}
17359
17360 //----------------------------- Reinterpret ----------------------------------
17361 // Reinterpret a half-precision float value in a floating point register to a general purpose register
17362 instruct reinterpretHF2S(iRegINoSp dst, vRegF src) %{
17363 match(Set dst (ReinterpretHF2S src));
17364 format %{ "reinterpretHF2S $dst, $src" %}
17365 ins_encode %{
17366 __ smov($dst$$Register, $src$$FloatRegister, __ H, 0);
17367 %}
17368 ins_pipe(pipe_slow);
17369 %}
17370
17371 // Reinterpret a half-precision float value in a general purpose register to a floating point register
17372 instruct reinterpretS2HF(vRegF dst, iRegINoSp src) %{
17373 match(Set dst (ReinterpretS2HF src));
17374 format %{ "reinterpretS2HF $dst, $src" %}
17375 ins_encode %{
17376 __ mov($dst$$FloatRegister, __ H, 0, $src$$Register);
17377 %}
17378 ins_pipe(pipe_slow);
17379 %}
17380
17381 // Without this optimization, ReinterpretS2HF (ConvF2HF src) would result in the following
17382 // instructions (the first two are for ConvF2HF and the last instruction is for ReinterpretS2HF) -
17383 // fcvt $tmp1_fpr, $src_fpr // Convert float to half-precision float
17384 // mov $tmp2_gpr, $tmp1_fpr // Move half-precision float in FPR to a GPR
17385 // mov $dst_fpr, $tmp2_gpr // Move the result from a GPR to an FPR
17386 // The move from FPR to GPR in ConvF2HF and the move from GPR to FPR in ReinterpretS2HF
17387 // can be omitted in this pattern, resulting in -
17388 // fcvt $dst, $src // Convert float to half-precision float
17389 instruct convF2HFAndS2HF(vRegF dst, vRegF src)
17390 %{
17391 match(Set dst (ReinterpretS2HF (ConvF2HF src)));
17392 format %{ "convF2HFAndS2HF $dst, $src" %}
17393 ins_encode %{
17394 __ fcvtsh($dst$$FloatRegister, $src$$FloatRegister);
17395 %}
17396 ins_pipe(pipe_slow);
17397 %}
17398
17399 // Without this optimization, ConvHF2F (ReinterpretHF2S src) would result in the following
17400 // instructions (the first one is for ReinterpretHF2S and the last two are for ConvHF2F) -
17401 // mov $tmp1_gpr, $src_fpr // Move the half-precision float from an FPR to a GPR
17402 // mov $tmp2_fpr, $tmp1_gpr // Move the same value from GPR to an FPR
17403 // fcvt $dst_fpr, $tmp2_fpr // Convert the half-precision float to 32-bit float
17404 // The move from FPR to GPR in ReinterpretHF2S and the move from GPR to FPR in ConvHF2F
17405 // can be omitted as the input (src) is already in an FPR required for the fcvths instruction
17406 // resulting in -
17407 // fcvt $dst, $src // Convert half-precision float to a 32-bit float
17408 instruct convHF2SAndHF2F(vRegF dst, vRegF src)
17409 %{
17410 match(Set dst (ConvHF2F (ReinterpretHF2S src)));
17411 format %{ "convHF2SAndHF2F $dst, $src" %}
17412 ins_encode %{
17413 __ fcvths($dst$$FloatRegister, $src$$FloatRegister);
17414 %}
17415 ins_pipe(pipe_slow);
17416 %}
17417
17418 // ============================================================================
17419 // This name is KNOWN by the ADLC and cannot be changed.
17420 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
17421 // for this guy.
17422 instruct tlsLoadP(thread_RegP dst)
17423 %{
17424 match(Set dst (ThreadLocal));
17425
17426 ins_cost(0);
17427
17428 format %{ " -- \t// $dst=Thread::current(), empty" %}
17429
17430 size(0);
17431
17432 ins_encode( /*empty*/ );
17433
17434 ins_pipe(pipe_class_empty);
17435 %}
17436
17437 //----------PEEPHOLE RULES-----------------------------------------------------
17438 // These must follow all instruction definitions as they use the names
17439 // defined in the instructions definitions.
17440 //
17441 // peepmatch ( root_instr_name [preceding_instruction]* );
17442 //
17443 // peepconstraint %{
17444 // (instruction_number.operand_name relational_op instruction_number.operand_name
17445 // [, ...] );
17446 // // instruction numbers are zero-based using left to right order in peepmatch
17447 //
17448 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
17449 // // provide an instruction_number.operand_name for each operand that appears
17450 // // in the replacement instruction's match rule
17451 //
17452 // ---------VM FLAGS---------------------------------------------------------
17453 //
17454 // All peephole optimizations can be turned off using -XX:-OptoPeephole
17455 //
17456 // Each peephole rule is given an identifying number starting with zero and
17457 // increasing by one in the order seen by the parser. An individual peephole
17458 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
17459 // on the command-line.
17460 //
17461 // ---------CURRENT LIMITATIONS----------------------------------------------
17462 //
17463 // Only match adjacent instructions in same basic block
17464 // Only equality constraints
17465 // Only constraints between operands, not (0.dest_reg == RAX_enc)
17466 // Only one replacement instruction
17467 //
17468 // ---------EXAMPLE----------------------------------------------------------
17469 //
17470 // // pertinent parts of existing instructions in architecture description
17471 // instruct movI(iRegINoSp dst, iRegI src)
17472 // %{
17473 // match(Set dst (CopyI src));
17474 // %}
17475 //
17476 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr)
17477 // %{
17478 // match(Set dst (AddI dst src));
17479 // effect(KILL cr);
17480 // %}
17481 //
17482 // // Change (inc mov) to lea
17483 // peephole %{
17484 // // increment preceded by register-register move
17485 // peepmatch ( incI_iReg movI );
17486 // // require that the destination register of the increment
17487 // // match the destination register of the move
17488 // peepconstraint ( 0.dst == 1.dst );
17489 // // construct a replacement instruction that sets
17490 // // the destination to ( move's source register + one )
17491 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) );
17492 // %}
17493 //
17494
17495 // Implementation no longer uses movX instructions since
17496 // machine-independent system no longer uses CopyX nodes.
17497 //
17498 // peephole
17499 // %{
17500 // peepmatch (incI_iReg movI);
17501 // peepconstraint (0.dst == 1.dst);
17502 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
17503 // %}
17504
17505 // peephole
17506 // %{
17507 // peepmatch (decI_iReg movI);
17508 // peepconstraint (0.dst == 1.dst);
17509 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
17510 // %}
17511
17512 // peephole
17513 // %{
17514 // peepmatch (addI_iReg_imm movI);
17515 // peepconstraint (0.dst == 1.dst);
17516 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
17517 // %}
17518
17519 // peephole
17520 // %{
17521 // peepmatch (incL_iReg movL);
17522 // peepconstraint (0.dst == 1.dst);
17523 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
17524 // %}
17525
17526 // peephole
17527 // %{
17528 // peepmatch (decL_iReg movL);
17529 // peepconstraint (0.dst == 1.dst);
17530 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
17531 // %}
17532
17533 // peephole
17534 // %{
17535 // peepmatch (addL_iReg_imm movL);
17536 // peepconstraint (0.dst == 1.dst);
17537 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
17538 // %}
17539
17540 // peephole
17541 // %{
17542 // peepmatch (addP_iReg_imm movP);
17543 // peepconstraint (0.dst == 1.dst);
17544 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src));
17545 // %}
17546
17547 // // Change load of spilled value to only a spill
17548 // instruct storeI(memory mem, iRegI src)
17549 // %{
17550 // match(Set mem (StoreI mem src));
17551 // %}
17552 //
17553 // instruct loadI(iRegINoSp dst, memory mem)
17554 // %{
17555 // match(Set dst (LoadI mem));
17556 // %}
17557 //
17558
17559 //----------SMARTSPILL RULES---------------------------------------------------
17560 // These must follow all instruction definitions as they use the names
17561 // defined in the instructions definitions.
17562
17563 // Local Variables:
17564 // mode: c++
17565 // End: