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.assignFrom(_ALL_REG32_mask);
1270 _ANY_REG32_mask.remove(OptoReg::as_OptoReg(r31_sp->as_VMReg()));
1271
1272 _ANY_REG_mask.assignFrom(_ALL_REG_mask);
1273
1274 _PTR_REG_mask.assignFrom(_ALL_REG_mask);
1275
1276 _NO_SPECIAL_REG32_mask.assignFrom(_ALL_REG32_mask);
1277 _NO_SPECIAL_REG32_mask.subtract(_NON_ALLOCATABLE_REG32_mask);
1278
1279 _NO_SPECIAL_REG_mask.assignFrom(_ALL_REG_mask);
1280 _NO_SPECIAL_REG_mask.subtract(_NON_ALLOCATABLE_REG_mask);
1281
1282 _NO_SPECIAL_PTR_REG_mask.assignFrom(_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.assignFrom(_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 if (_entry_point == nullptr) {
1698 // See CallLeafNoFPIndirect
1699 return 1 * NativeInstruction::instruction_size;
1700 } else {
1701 return 6 * NativeInstruction::instruction_size;
1702 }
1703 }
1704
1705 //=============================================================================
1706
1707 #ifndef PRODUCT
1708 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1709 st->print("BREAKPOINT");
1710 }
1711 #endif
1712
1713 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1714 __ brk(0);
1715 }
1716
1717 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1718 return MachNode::size(ra_);
1719 }
1720
1721 //=============================================================================
1722
1723 #ifndef PRODUCT
1724 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
1725 st->print("nop \t# %d bytes pad for loops and calls", _count);
1726 }
1727 #endif
1728
1729 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc*) const {
1730 for (int i = 0; i < _count; i++) {
1731 __ nop();
1732 }
1733 }
1734
1735 uint MachNopNode::size(PhaseRegAlloc*) const {
1736 return _count * NativeInstruction::instruction_size;
1737 }
1738
1739 //=============================================================================
1740 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::EMPTY;
1741
1742 int ConstantTable::calculate_table_base_offset() const {
1743 return 0; // absolute addressing, no offset
1744 }
1745
1746 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1747 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1748 ShouldNotReachHere();
1749 }
1750
1751 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const {
1752 // Empty encoding
1753 }
1754
1755 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1756 return 0;
1757 }
1758
1759 #ifndef PRODUCT
1760 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1761 st->print("-- \t// MachConstantBaseNode (empty encoding)");
1762 }
1763 #endif
1764
1765 #ifndef PRODUCT
1766 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1767 Compile* C = ra_->C;
1768
1769 int framesize = C->output()->frame_slots() << LogBytesPerInt;
1770
1771 if (C->output()->need_stack_bang(framesize))
1772 st->print("# stack bang size=%d\n\t", framesize);
1773
1774 if (VM_Version::use_rop_protection()) {
1775 st->print("ldr zr, [lr]\n\t");
1776 st->print("paciaz\n\t");
1777 }
1778 if (framesize < ((1 << 9) + 2 * wordSize)) {
1779 st->print("sub sp, sp, #%d\n\t", framesize);
1780 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize);
1781 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize);
1782 } else {
1783 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize));
1784 if (PreserveFramePointer) st->print("mov rfp, sp\n\t");
1785 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize);
1786 st->print("sub sp, sp, rscratch1");
1787 }
1788 if (C->stub_function() == nullptr) {
1789 st->print("\n\t");
1790 st->print("ldr rscratch1, [guard]\n\t");
1791 st->print("dmb ishld\n\t");
1792 st->print("ldr rscratch2, [rthread, #thread_disarmed_guard_value_offset]\n\t");
1793 st->print("cmp rscratch1, rscratch2\n\t");
1794 st->print("b.eq skip");
1795 st->print("\n\t");
1796 st->print("blr #nmethod_entry_barrier_stub\n\t");
1797 st->print("b skip\n\t");
1798 st->print("guard: int\n\t");
1799 st->print("\n\t");
1800 st->print("skip:\n\t");
1801 }
1802 }
1803 #endif
1804
1805 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1806 Compile* C = ra_->C;
1807
1808
1809 __ verified_entry(C, 0);
1810
1811 if (C->stub_function() == nullptr) {
1812 __ entry_barrier();
1813 }
1814
1815 if (!Compile::current()->output()->in_scratch_emit_size()) {
1816 __ bind(*_verified_entry);
1817 }
1818
1819 if (VerifyStackAtCalls) {
1820 Unimplemented();
1821 }
1822
1823 C->output()->set_frame_complete(__ offset());
1824
1825 if (C->has_mach_constant_base_node()) {
1826 // NOTE: We set the table base offset here because users might be
1827 // emitted before MachConstantBaseNode.
1828 ConstantTable& constant_table = C->output()->constant_table();
1829 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1830 }
1831 }
1832
1833 int MachPrologNode::reloc() const
1834 {
1835 return 0;
1836 }
1837
1838 //=============================================================================
1839
1840 #ifndef PRODUCT
1841 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1842 Compile* C = ra_->C;
1843 int framesize = C->output()->frame_slots() << LogBytesPerInt;
1844
1845 st->print("# pop frame %d\n\t",framesize);
1846
1847 if (framesize == 0) {
1848 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1849 } else if (framesize < ((1 << 9) + 2 * wordSize)) {
1850 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize);
1851 st->print("add sp, sp, #%d\n\t", framesize);
1852 } else {
1853 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize);
1854 st->print("add sp, sp, rscratch1\n\t");
1855 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1856 }
1857 if (VM_Version::use_rop_protection()) {
1858 st->print("autiaz\n\t");
1859 st->print("ldr zr, [lr]\n\t");
1860 }
1861
1862 if (do_polling() && C->is_method_compilation()) {
1863 st->print("# test polling word\n\t");
1864 st->print("ldr rscratch1, [rthread],#%d\n\t", in_bytes(JavaThread::polling_word_offset()));
1865 st->print("cmp sp, rscratch1\n\t");
1866 st->print("bhi #slow_path");
1867 }
1868 }
1869 #endif
1870
1871 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
1872 Compile* C = ra_->C;
1873 int framesize = C->output()->frame_slots() << LogBytesPerInt;
1874
1875 __ remove_frame(framesize, C->needs_stack_repair());
1876
1877 if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1878 __ reserved_stack_check();
1879 }
1880
1881 if (do_polling() && C->is_method_compilation()) {
1882 Label dummy_label;
1883 Label* code_stub = &dummy_label;
1884 if (!C->output()->in_scratch_emit_size()) {
1885 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset());
1886 C->output()->add_stub(stub);
1887 code_stub = &stub->entry();
1888 }
1889 __ relocate(relocInfo::poll_return_type);
1890 __ safepoint_poll(*code_stub, true /* at_return */, true /* in_nmethod */);
1891 }
1892 }
1893
1894 int MachEpilogNode::reloc() const {
1895 // Return number of relocatable values contained in this instruction.
1896 return 1; // 1 for polling page.
1897 }
1898
1899 const Pipeline * MachEpilogNode::pipeline() const {
1900 return MachNode::pipeline_class();
1901 }
1902
1903 //=============================================================================
1904
1905 static enum RC rc_class(OptoReg::Name reg) {
1906
1907 if (reg == OptoReg::Bad) {
1908 return rc_bad;
1909 }
1910
1911 // we have 32 int registers * 2 halves
1912 int slots_of_int_registers = Register::number_of_registers * Register::max_slots_per_register;
1913
1914 if (reg < slots_of_int_registers) {
1915 return rc_int;
1916 }
1917
1918 // we have 32 float register * 8 halves
1919 int slots_of_float_registers = FloatRegister::number_of_registers * FloatRegister::max_slots_per_register;
1920 if (reg < slots_of_int_registers + slots_of_float_registers) {
1921 return rc_float;
1922 }
1923
1924 int slots_of_predicate_registers = PRegister::number_of_registers * PRegister::max_slots_per_register;
1925 if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_predicate_registers) {
1926 return rc_predicate;
1927 }
1928
1929 // Between predicate regs & stack is the flags.
1930 assert(OptoReg::is_stack(reg), "blow up if spilling flags");
1931
1932 return rc_stack;
1933 }
1934
1935 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
1936 Compile* C = ra_->C;
1937
1938 // Get registers to move.
1939 OptoReg::Name src_hi = ra_->get_reg_second(in(1));
1940 OptoReg::Name src_lo = ra_->get_reg_first(in(1));
1941 OptoReg::Name dst_hi = ra_->get_reg_second(this);
1942 OptoReg::Name dst_lo = ra_->get_reg_first(this);
1943
1944 enum RC src_hi_rc = rc_class(src_hi);
1945 enum RC src_lo_rc = rc_class(src_lo);
1946 enum RC dst_hi_rc = rc_class(dst_hi);
1947 enum RC dst_lo_rc = rc_class(dst_lo);
1948
1949 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
1950
1951 if (src_hi != OptoReg::Bad && !bottom_type()->isa_vectmask()) {
1952 assert((src_lo&1)==0 && src_lo+1==src_hi &&
1953 (dst_lo&1)==0 && dst_lo+1==dst_hi,
1954 "expected aligned-adjacent pairs");
1955 }
1956
1957 if (src_lo == dst_lo && src_hi == dst_hi) {
1958 return 0; // Self copy, no move.
1959 }
1960
1961 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi &&
1962 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi;
1963 int src_offset = ra_->reg2offset(src_lo);
1964 int dst_offset = ra_->reg2offset(dst_lo);
1965
1966 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) {
1967 uint ireg = ideal_reg();
1968 if (ireg == Op_VecA && masm) {
1969 int sve_vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE);
1970 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1971 // stack->stack
1972 __ spill_copy_sve_vector_stack_to_stack(src_offset, dst_offset,
1973 sve_vector_reg_size_in_bytes);
1974 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
1975 __ spill_sve_vector(as_FloatRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo),
1976 sve_vector_reg_size_in_bytes);
1977 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
1978 __ unspill_sve_vector(as_FloatRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo),
1979 sve_vector_reg_size_in_bytes);
1980 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
1981 __ sve_orr(as_FloatRegister(Matcher::_regEncode[dst_lo]),
1982 as_FloatRegister(Matcher::_regEncode[src_lo]),
1983 as_FloatRegister(Matcher::_regEncode[src_lo]));
1984 } else {
1985 ShouldNotReachHere();
1986 }
1987 } else if (masm) {
1988 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector");
1989 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity");
1990 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
1991 // stack->stack
1992 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset");
1993 if (ireg == Op_VecD) {
1994 __ unspill(rscratch1, true, src_offset);
1995 __ spill(rscratch1, true, dst_offset);
1996 } else {
1997 __ spill_copy128(src_offset, dst_offset);
1998 }
1999 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
2000 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2001 ireg == Op_VecD ? __ T8B : __ T16B,
2002 as_FloatRegister(Matcher::_regEncode[src_lo]));
2003 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
2004 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
2005 ireg == Op_VecD ? __ D : __ Q,
2006 ra_->reg2offset(dst_lo));
2007 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
2008 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2009 ireg == Op_VecD ? __ D : __ Q,
2010 ra_->reg2offset(src_lo));
2011 } else {
2012 ShouldNotReachHere();
2013 }
2014 }
2015 } else if (masm) {
2016 switch (src_lo_rc) {
2017 case rc_int:
2018 if (dst_lo_rc == rc_int) { // gpr --> gpr copy
2019 if (is64) {
2020 __ mov(as_Register(Matcher::_regEncode[dst_lo]),
2021 as_Register(Matcher::_regEncode[src_lo]));
2022 } else {
2023 __ movw(as_Register(Matcher::_regEncode[dst_lo]),
2024 as_Register(Matcher::_regEncode[src_lo]));
2025 }
2026 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
2027 if (is64) {
2028 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2029 as_Register(Matcher::_regEncode[src_lo]));
2030 } else {
2031 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2032 as_Register(Matcher::_regEncode[src_lo]));
2033 }
2034 } else { // gpr --> stack spill
2035 assert(dst_lo_rc == rc_stack, "spill to bad register class");
2036 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
2037 }
2038 break;
2039 case rc_float:
2040 if (dst_lo_rc == rc_int) { // fpr --> gpr copy
2041 if (is64) {
2042 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
2043 as_FloatRegister(Matcher::_regEncode[src_lo]));
2044 } else {
2045 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
2046 as_FloatRegister(Matcher::_regEncode[src_lo]));
2047 }
2048 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
2049 if (is64) {
2050 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2051 as_FloatRegister(Matcher::_regEncode[src_lo]));
2052 } else {
2053 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2054 as_FloatRegister(Matcher::_regEncode[src_lo]));
2055 }
2056 } else { // fpr --> stack spill
2057 assert(dst_lo_rc == rc_stack, "spill to bad register class");
2058 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
2059 is64 ? __ D : __ S, dst_offset);
2060 }
2061 break;
2062 case rc_stack:
2063 if (dst_lo_rc == rc_int) { // stack --> gpr load
2064 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
2065 } else if (dst_lo_rc == rc_float) { // stack --> fpr load
2066 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2067 is64 ? __ D : __ S, src_offset);
2068 } else if (dst_lo_rc == rc_predicate) {
2069 __ unspill_sve_predicate(as_PRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo),
2070 Matcher::scalable_vector_reg_size(T_BYTE) >> 3);
2071 } else { // stack --> stack copy
2072 assert(dst_lo_rc == rc_stack, "spill to bad register class");
2073 if (ideal_reg() == Op_RegVectMask) {
2074 __ spill_copy_sve_predicate_stack_to_stack(src_offset, dst_offset,
2075 Matcher::scalable_vector_reg_size(T_BYTE) >> 3);
2076 } else {
2077 __ unspill(rscratch1, is64, src_offset);
2078 __ spill(rscratch1, is64, dst_offset);
2079 }
2080 }
2081 break;
2082 case rc_predicate:
2083 if (dst_lo_rc == rc_predicate) {
2084 __ sve_mov(as_PRegister(Matcher::_regEncode[dst_lo]), as_PRegister(Matcher::_regEncode[src_lo]));
2085 } else if (dst_lo_rc == rc_stack) {
2086 __ spill_sve_predicate(as_PRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo),
2087 Matcher::scalable_vector_reg_size(T_BYTE) >> 3);
2088 } else {
2089 assert(false, "bad src and dst rc_class combination.");
2090 ShouldNotReachHere();
2091 }
2092 break;
2093 default:
2094 assert(false, "bad rc_class for spill");
2095 ShouldNotReachHere();
2096 }
2097 }
2098
2099 if (st) {
2100 st->print("spill ");
2101 if (src_lo_rc == rc_stack) {
2102 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
2103 } else {
2104 st->print("%s -> ", Matcher::regName[src_lo]);
2105 }
2106 if (dst_lo_rc == rc_stack) {
2107 st->print("[sp, #%d]", ra_->reg2offset(dst_lo));
2108 } else {
2109 st->print("%s", Matcher::regName[dst_lo]);
2110 }
2111 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) {
2112 int vsize = 0;
2113 switch (ideal_reg()) {
2114 case Op_VecD:
2115 vsize = 64;
2116 break;
2117 case Op_VecX:
2118 vsize = 128;
2119 break;
2120 case Op_VecA:
2121 vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8;
2122 break;
2123 default:
2124 assert(false, "bad register type for spill");
2125 ShouldNotReachHere();
2126 }
2127 st->print("\t# vector spill size = %d", vsize);
2128 } else if (ideal_reg() == Op_RegVectMask) {
2129 assert(Matcher::supports_scalable_vector(), "bad register type for spill");
2130 int vsize = Matcher::scalable_predicate_reg_slots() * 32;
2131 st->print("\t# predicate spill size = %d", vsize);
2132 } else {
2133 st->print("\t# spill size = %d", is64 ? 64 : 32);
2134 }
2135 }
2136
2137 return 0;
2138
2139 }
2140
2141 #ifndef PRODUCT
2142 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2143 if (!ra_)
2144 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
2145 else
2146 implementation(nullptr, ra_, false, st);
2147 }
2148 #endif
2149
2150 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
2151 implementation(masm, ra_, false, nullptr);
2152 }
2153
2154 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
2155 return MachNode::size(ra_);
2156 }
2157
2158 //=============================================================================
2159
2160 #ifndef PRODUCT
2161 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2162 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2163 int reg = ra_->get_reg_first(this);
2164 st->print("add %s, rsp, #%d]\t# box lock",
2165 Matcher::regName[reg], offset);
2166 }
2167 #endif
2168
2169 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
2170 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2171 int reg = ra_->get_encode(this);
2172
2173 // This add will handle any 24-bit signed offset. 24 bits allows an
2174 // 8 megabyte stack frame.
2175 __ add(as_Register(reg), sp, offset);
2176 }
2177
2178 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
2179 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
2180 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2181
2182 if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
2183 return NativeInstruction::instruction_size;
2184 } else {
2185 return 2 * NativeInstruction::instruction_size;
2186 }
2187 }
2188
2189 ///=============================================================================
2190 #ifndef PRODUCT
2191 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
2192 {
2193 st->print_cr("# MachVEPNode");
2194 if (!_verified) {
2195 st->print_cr("\t load_class");
2196 } else {
2197 st->print_cr("\t unpack_inline_arg");
2198 }
2199 }
2200 #endif
2201
2202 void MachVEPNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc* ra_) const
2203 {
2204 if (!_verified) {
2205 __ ic_check(1);
2206 } else {
2207 // TODO 8284443 Avoid creation of temporary frame
2208 if (ra_->C->stub_function() == nullptr) {
2209 __ verified_entry(ra_->C, 0);
2210 __ entry_barrier();
2211 int framesize = ra_->C->output()->frame_slots() << LogBytesPerInt;
2212 __ remove_frame(framesize, false);
2213 }
2214 // Unpack inline type args passed as oop and then jump to
2215 // the verified entry point (skipping the unverified entry).
2216 int sp_inc = __ unpack_inline_args(ra_->C, _receiver_only);
2217 // Emit code for verified entry and save increment for stack repair on return
2218 __ verified_entry(ra_->C, sp_inc);
2219 if (Compile::current()->output()->in_scratch_emit_size()) {
2220 Label dummy_verified_entry;
2221 __ b(dummy_verified_entry);
2222 } else {
2223 __ b(*_verified_entry);
2224 }
2225 }
2226 }
2227
2228 //=============================================================================
2229 #ifndef PRODUCT
2230 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
2231 {
2232 st->print_cr("# MachUEPNode");
2233 if (UseCompressedClassPointers) {
2234 st->print_cr("\tldrw rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2235 st->print_cr("\tldrw r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass");
2236 st->print_cr("\tcmpw rscratch1, r10");
2237 } else {
2238 st->print_cr("\tldr rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2239 st->print_cr("\tldr r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass");
2240 st->print_cr("\tcmp rscratch1, r10");
2241 }
2242 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
2243 }
2244 #endif
2245
2246 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const
2247 {
2248 __ ic_check(InteriorEntryAlignment);
2249 }
2250
2251 // REQUIRED EMIT CODE
2252
2253 //=============================================================================
2254
2255 // Emit exception handler code.
2256 int HandlerImpl::emit_exception_handler(C2_MacroAssembler* masm)
2257 {
2258 // mov rscratch1 #exception_blob_entry_point
2259 // br rscratch1
2260 // Note that the code buffer's insts_mark is always relative to insts.
2261 // That's why we must use the macroassembler to generate a handler.
2262 address base = __ start_a_stub(size_exception_handler());
2263 if (base == nullptr) {
2264 ciEnv::current()->record_failure("CodeCache is full");
2265 return 0; // CodeBuffer::expand failed
2266 }
2267 int offset = __ offset();
2268 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
2269 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
2270 __ end_a_stub();
2271 return offset;
2272 }
2273
2274 // Emit deopt handler code.
2275 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm)
2276 {
2277 // Note that the code buffer's insts_mark is always relative to insts.
2278 // That's why we must use the macroassembler to generate a handler.
2279 address base = __ start_a_stub(size_deopt_handler());
2280 if (base == nullptr) {
2281 ciEnv::current()->record_failure("CodeCache is full");
2282 return 0; // CodeBuffer::expand failed
2283 }
2284 int offset = __ offset();
2285
2286 __ adr(lr, __ pc());
2287 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
2288
2289 assert(__ offset() - offset == (int) size_deopt_handler(), "overflow");
2290 __ end_a_stub();
2291 return offset;
2292 }
2293
2294 // REQUIRED MATCHER CODE
2295
2296 //=============================================================================
2297
2298 bool Matcher::match_rule_supported(int opcode) {
2299 if (!has_match_rule(opcode))
2300 return false;
2301
2302 switch (opcode) {
2303 case Op_OnSpinWait:
2304 return VM_Version::supports_on_spin_wait();
2305 case Op_CacheWB:
2306 case Op_CacheWBPreSync:
2307 case Op_CacheWBPostSync:
2308 if (!VM_Version::supports_data_cache_line_flush()) {
2309 return false;
2310 }
2311 break;
2312 case Op_ExpandBits:
2313 case Op_CompressBits:
2314 if (!VM_Version::supports_svebitperm()) {
2315 return false;
2316 }
2317 break;
2318 case Op_FmaF:
2319 case Op_FmaD:
2320 case Op_FmaVF:
2321 case Op_FmaVD:
2322 if (!UseFMA) {
2323 return false;
2324 }
2325 break;
2326 case Op_FmaHF:
2327 // UseFMA flag also needs to be checked along with FEAT_FP16
2328 if (!UseFMA || !is_feat_fp16_supported()) {
2329 return false;
2330 }
2331 break;
2332 case Op_AddHF:
2333 case Op_SubHF:
2334 case Op_MulHF:
2335 case Op_DivHF:
2336 case Op_MinHF:
2337 case Op_MaxHF:
2338 case Op_SqrtHF:
2339 // Half-precision floating point scalar operations require FEAT_FP16
2340 // to be available. FEAT_FP16 is enabled if both "fphp" and "asimdhp"
2341 // features are supported.
2342 if (!is_feat_fp16_supported()) {
2343 return false;
2344 }
2345 break;
2346 }
2347
2348 return true; // Per default match rules are supported.
2349 }
2350
2351 const RegMask* Matcher::predicate_reg_mask(void) {
2352 return &_PR_REG_mask;
2353 }
2354
2355 bool Matcher::supports_vector_calling_convention(void) {
2356 return EnableVectorSupport;
2357 }
2358
2359 OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2360 assert(EnableVectorSupport, "sanity");
2361 int lo = V0_num;
2362 int hi = V0_H_num;
2363 if (ideal_reg == Op_VecX || ideal_reg == Op_VecA) {
2364 hi = V0_K_num;
2365 }
2366 return OptoRegPair(hi, lo);
2367 }
2368
2369 // Is this branch offset short enough that a short branch can be used?
2370 //
2371 // NOTE: If the platform does not provide any short branch variants, then
2372 // this method should return false for offset 0.
2373 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2374 // The passed offset is relative to address of the branch.
2375
2376 return (-32768 <= offset && offset < 32768);
2377 }
2378
2379 // Vector width in bytes.
2380 int Matcher::vector_width_in_bytes(BasicType bt) {
2381 // The MaxVectorSize should have been set by detecting SVE max vector register size.
2382 int size = MIN2((UseSVE > 0) ? (int)FloatRegister::sve_vl_max : (int)FloatRegister::neon_vl, (int)MaxVectorSize);
2383 // Minimum 2 values in vector
2384 if (size < 2*type2aelembytes(bt)) size = 0;
2385 // But never < 4
2386 if (size < 4) size = 0;
2387 return size;
2388 }
2389
2390 // Limits on vector size (number of elements) loaded into vector.
2391 int Matcher::max_vector_size(const BasicType bt) {
2392 return vector_width_in_bytes(bt)/type2aelembytes(bt);
2393 }
2394
2395 int Matcher::min_vector_size(const BasicType bt) {
2396 // Usually, the shortest vector length supported by AArch64 ISA and
2397 // Vector API species is 64 bits. However, we allow 32-bit or 16-bit
2398 // vectors in a few special cases.
2399 int size;
2400 switch(bt) {
2401 case T_BOOLEAN:
2402 // Load/store a vector mask with only 2 elements for vector types
2403 // such as "2I/2F/2L/2D".
2404 size = 2;
2405 break;
2406 case T_BYTE:
2407 // Generate a "4B" vector, to support vector cast between "8B/16B"
2408 // and "4S/4I/4L/4F/4D".
2409 size = 4;
2410 break;
2411 case T_SHORT:
2412 // Generate a "2S" vector, to support vector cast between "4S/8S"
2413 // and "2I/2L/2F/2D".
2414 size = 2;
2415 break;
2416 default:
2417 // Limit the min vector length to 64-bit.
2418 size = 8 / type2aelembytes(bt);
2419 // The number of elements in a vector should be at least 2.
2420 size = MAX2(size, 2);
2421 }
2422
2423 int max_size = max_vector_size(bt);
2424 return MIN2(size, max_size);
2425 }
2426
2427 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) {
2428 return Matcher::max_vector_size(bt);
2429 }
2430
2431 // Actual max scalable vector register length.
2432 int Matcher::scalable_vector_reg_size(const BasicType bt) {
2433 return Matcher::max_vector_size(bt);
2434 }
2435
2436 // Vector ideal reg.
2437 uint Matcher::vector_ideal_reg(int len) {
2438 if (UseSVE > 0 && FloatRegister::neon_vl < len && len <= FloatRegister::sve_vl_max) {
2439 return Op_VecA;
2440 }
2441 switch(len) {
2442 // For 16-bit/32-bit mask vector, reuse VecD.
2443 case 2:
2444 case 4:
2445 case 8: return Op_VecD;
2446 case 16: return Op_VecX;
2447 }
2448 ShouldNotReachHere();
2449 return 0;
2450 }
2451
2452 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp) {
2453 assert(Matcher::is_generic_vector(generic_opnd), "not generic");
2454 switch (ideal_reg) {
2455 case Op_VecA: return new vecAOper();
2456 case Op_VecD: return new vecDOper();
2457 case Op_VecX: return new vecXOper();
2458 }
2459 ShouldNotReachHere();
2460 return nullptr;
2461 }
2462
2463 bool Matcher::is_reg2reg_move(MachNode* m) {
2464 return false;
2465 }
2466
2467 bool Matcher::is_generic_vector(MachOper* opnd) {
2468 return opnd->opcode() == VREG;
2469 }
2470
2471 // Return whether or not this register is ever used as an argument.
2472 // This function is used on startup to build the trampoline stubs in
2473 // generateOptoStub. Registers not mentioned will be killed by the VM
2474 // call in the trampoline, and arguments in those registers not be
2475 // available to the callee.
2476 bool Matcher::can_be_java_arg(int reg)
2477 {
2478 return
2479 reg == R0_num || reg == R0_H_num ||
2480 reg == R1_num || reg == R1_H_num ||
2481 reg == R2_num || reg == R2_H_num ||
2482 reg == R3_num || reg == R3_H_num ||
2483 reg == R4_num || reg == R4_H_num ||
2484 reg == R5_num || reg == R5_H_num ||
2485 reg == R6_num || reg == R6_H_num ||
2486 reg == R7_num || reg == R7_H_num ||
2487 reg == V0_num || reg == V0_H_num ||
2488 reg == V1_num || reg == V1_H_num ||
2489 reg == V2_num || reg == V2_H_num ||
2490 reg == V3_num || reg == V3_H_num ||
2491 reg == V4_num || reg == V4_H_num ||
2492 reg == V5_num || reg == V5_H_num ||
2493 reg == V6_num || reg == V6_H_num ||
2494 reg == V7_num || reg == V7_H_num;
2495 }
2496
2497 bool Matcher::is_spillable_arg(int reg)
2498 {
2499 return can_be_java_arg(reg);
2500 }
2501
2502 uint Matcher::int_pressure_limit()
2503 {
2504 // JDK-8183543: When taking the number of available registers as int
2505 // register pressure threshold, the jtreg test:
2506 // test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java
2507 // failed due to C2 compilation failure with
2508 // "COMPILE SKIPPED: failed spill-split-recycle sanity check".
2509 //
2510 // A derived pointer is live at CallNode and then is flagged by RA
2511 // as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip
2512 // derived pointers and lastly fail to spill after reaching maximum
2513 // number of iterations. Lowering the default pressure threshold to
2514 // (_NO_SPECIAL_REG32_mask.size() minus 1) forces CallNode to become
2515 // a high register pressure area of the code so that split_DEF can
2516 // generate DefinitionSpillCopy for the derived pointer.
2517 uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.size() - 1;
2518 if (!PreserveFramePointer) {
2519 // When PreserveFramePointer is off, frame pointer is allocatable,
2520 // but different from other SOC registers, it is excluded from
2521 // fatproj's mask because its save type is No-Save. Decrease 1 to
2522 // ensure high pressure at fatproj when PreserveFramePointer is off.
2523 // See check_pressure_at_fatproj().
2524 default_int_pressure_threshold--;
2525 }
2526 return (INTPRESSURE == -1) ? default_int_pressure_threshold : INTPRESSURE;
2527 }
2528
2529 uint Matcher::float_pressure_limit()
2530 {
2531 // _FLOAT_REG_mask is generated by adlc from the float_reg register class.
2532 return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.size() : FLOATPRESSURE;
2533 }
2534
2535 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
2536 return false;
2537 }
2538
2539 const RegMask& Matcher::divI_proj_mask() {
2540 ShouldNotReachHere();
2541 return RegMask::EMPTY;
2542 }
2543
2544 // Register for MODI projection of divmodI.
2545 const RegMask& Matcher::modI_proj_mask() {
2546 ShouldNotReachHere();
2547 return RegMask::EMPTY;
2548 }
2549
2550 // Register for DIVL projection of divmodL.
2551 const RegMask& Matcher::divL_proj_mask() {
2552 ShouldNotReachHere();
2553 return RegMask::EMPTY;
2554 }
2555
2556 // Register for MODL projection of divmodL.
2557 const RegMask& Matcher::modL_proj_mask() {
2558 ShouldNotReachHere();
2559 return RegMask::EMPTY;
2560 }
2561
2562 bool size_fits_all_mem_uses(AddPNode* addp, int shift) {
2563 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
2564 Node* u = addp->fast_out(i);
2565 if (u->is_LoadStore()) {
2566 // On AArch64, LoadStoreNodes (i.e. compare and swap
2567 // instructions) only take register indirect as an operand, so
2568 // any attempt to use an AddPNode as an input to a LoadStoreNode
2569 // must fail.
2570 return false;
2571 }
2572 if (u->is_Mem()) {
2573 int opsize = u->as_Mem()->memory_size();
2574 assert(opsize > 0, "unexpected memory operand size");
2575 if (u->as_Mem()->memory_size() != (1<<shift)) {
2576 return false;
2577 }
2578 }
2579 }
2580 return true;
2581 }
2582
2583 // Convert BootTest condition to Assembler condition.
2584 // Replicate the logic of cmpOpOper::ccode() and cmpOpUOper::ccode().
2585 Assembler::Condition to_assembler_cond(BoolTest::mask cond) {
2586 Assembler::Condition result;
2587 switch(cond) {
2588 case BoolTest::eq:
2589 result = Assembler::EQ; break;
2590 case BoolTest::ne:
2591 result = Assembler::NE; break;
2592 case BoolTest::le:
2593 result = Assembler::LE; break;
2594 case BoolTest::ge:
2595 result = Assembler::GE; break;
2596 case BoolTest::lt:
2597 result = Assembler::LT; break;
2598 case BoolTest::gt:
2599 result = Assembler::GT; break;
2600 case BoolTest::ule:
2601 result = Assembler::LS; break;
2602 case BoolTest::uge:
2603 result = Assembler::HS; break;
2604 case BoolTest::ult:
2605 result = Assembler::LO; break;
2606 case BoolTest::ugt:
2607 result = Assembler::HI; break;
2608 case BoolTest::overflow:
2609 result = Assembler::VS; break;
2610 case BoolTest::no_overflow:
2611 result = Assembler::VC; break;
2612 default:
2613 ShouldNotReachHere();
2614 return Assembler::Condition(-1);
2615 }
2616
2617 // Check conversion
2618 if (cond & BoolTest::unsigned_compare) {
2619 assert(cmpOpUOper((BoolTest::mask)((int)cond & ~(BoolTest::unsigned_compare))).ccode() == result, "Invalid conversion");
2620 } else {
2621 assert(cmpOpOper(cond).ccode() == result, "Invalid conversion");
2622 }
2623
2624 return result;
2625 }
2626
2627 // Binary src (Replicate con)
2628 static bool is_valid_sve_arith_imm_pattern(Node* n, Node* m) {
2629 if (n == nullptr || m == nullptr) {
2630 return false;
2631 }
2632
2633 if (UseSVE == 0 || m->Opcode() != Op_Replicate) {
2634 return false;
2635 }
2636
2637 Node* imm_node = m->in(1);
2638 if (!imm_node->is_Con()) {
2639 return false;
2640 }
2641
2642 const Type* t = imm_node->bottom_type();
2643 if (!(t->isa_int() || t->isa_long())) {
2644 return false;
2645 }
2646
2647 switch (n->Opcode()) {
2648 case Op_AndV:
2649 case Op_OrV:
2650 case Op_XorV: {
2651 Assembler::SIMD_RegVariant T = Assembler::elemType_to_regVariant(Matcher::vector_element_basic_type(n));
2652 uint64_t value = t->isa_long() ? (uint64_t)imm_node->get_long() : (uint64_t)imm_node->get_int();
2653 return Assembler::operand_valid_for_sve_logical_immediate(Assembler::regVariant_to_elemBits(T), value);
2654 }
2655 case Op_AddVB:
2656 return (imm_node->get_int() <= 255 && imm_node->get_int() >= -255);
2657 case Op_AddVS:
2658 case Op_AddVI:
2659 return Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)imm_node->get_int());
2660 case Op_AddVL:
2661 return Assembler::operand_valid_for_sve_add_sub_immediate(imm_node->get_long());
2662 default:
2663 return false;
2664 }
2665 }
2666
2667 // (XorV src (Replicate m1))
2668 // (XorVMask src (MaskAll m1))
2669 static bool is_vector_bitwise_not_pattern(Node* n, Node* m) {
2670 if (n != nullptr && m != nullptr) {
2671 return (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) &&
2672 VectorNode::is_all_ones_vector(m);
2673 }
2674 return false;
2675 }
2676
2677 // Should the matcher clone input 'm' of node 'n'?
2678 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
2679 if (is_vshift_con_pattern(n, m) ||
2680 is_vector_bitwise_not_pattern(n, m) ||
2681 is_valid_sve_arith_imm_pattern(n, m) ||
2682 is_encode_and_store_pattern(n, m)) {
2683 mstack.push(m, Visit);
2684 return true;
2685 }
2686 return false;
2687 }
2688
2689 // Should the Matcher clone shifts on addressing modes, expecting them
2690 // to be subsumed into complex addressing expressions or compute them
2691 // into registers?
2692 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
2693
2694 // Loads and stores with indirect memory input (e.g., volatile loads and
2695 // stores) do not subsume the input into complex addressing expressions. If
2696 // the addressing expression is input to at least one such load or store, do
2697 // not clone the addressing expression. Query needs_acquiring_load and
2698 // needs_releasing_store as a proxy for indirect memory input, as it is not
2699 // possible to directly query for indirect memory input at this stage.
2700 for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) {
2701 Node* n = m->fast_out(i);
2702 if (n->is_Load() && needs_acquiring_load(n)) {
2703 return false;
2704 }
2705 if (n->is_Store() && needs_releasing_store(n)) {
2706 return false;
2707 }
2708 }
2709
2710 if (clone_base_plus_offset_address(m, mstack, address_visited)) {
2711 return true;
2712 }
2713
2714 Node *off = m->in(AddPNode::Offset);
2715 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() &&
2716 size_fits_all_mem_uses(m, off->in(2)->get_int()) &&
2717 // Are there other uses besides address expressions?
2718 !is_visited(off)) {
2719 address_visited.set(off->_idx); // Flag as address_visited
2720 mstack.push(off->in(2), Visit);
2721 Node *conv = off->in(1);
2722 if (conv->Opcode() == Op_ConvI2L &&
2723 // Are there other uses besides address expressions?
2724 !is_visited(conv)) {
2725 address_visited.set(conv->_idx); // Flag as address_visited
2726 mstack.push(conv->in(1), Pre_Visit);
2727 } else {
2728 mstack.push(conv, Pre_Visit);
2729 }
2730 address_visited.test_set(m->_idx); // Flag as address_visited
2731 mstack.push(m->in(AddPNode::Address), Pre_Visit);
2732 mstack.push(m->in(AddPNode::Base), Pre_Visit);
2733 return true;
2734 } else if (off->Opcode() == Op_ConvI2L &&
2735 // Are there other uses besides address expressions?
2736 !is_visited(off)) {
2737 address_visited.test_set(m->_idx); // Flag as address_visited
2738 address_visited.set(off->_idx); // Flag as address_visited
2739 mstack.push(off->in(1), Pre_Visit);
2740 mstack.push(m->in(AddPNode::Address), Pre_Visit);
2741 mstack.push(m->in(AddPNode::Base), Pre_Visit);
2742 return true;
2743 }
2744 return false;
2745 }
2746
2747 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \
2748 { \
2749 guarantee(INDEX == -1, "mode not permitted for volatile"); \
2750 guarantee(DISP == 0, "mode not permitted for volatile"); \
2751 guarantee(SCALE == 0, "mode not permitted for volatile"); \
2752 __ INSN(REG, as_Register(BASE)); \
2753 }
2754
2755
2756 static Address mem2address(int opcode, Register base, int index, int size, int disp)
2757 {
2758 Address::extend scale;
2759
2760 // Hooboy, this is fugly. We need a way to communicate to the
2761 // encoder that the index needs to be sign extended, so we have to
2762 // enumerate all the cases.
2763 switch (opcode) {
2764 case INDINDEXSCALEDI2L:
2765 case INDINDEXSCALEDI2LN:
2766 case INDINDEXI2L:
2767 case INDINDEXI2LN:
2768 scale = Address::sxtw(size);
2769 break;
2770 default:
2771 scale = Address::lsl(size);
2772 }
2773
2774 if (index == -1) {
2775 return Address(base, disp);
2776 } else {
2777 assert(disp == 0, "unsupported address mode: disp = %d", disp);
2778 return Address(base, as_Register(index), scale);
2779 }
2780 }
2781
2782
2783 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
2784 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr);
2785 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
2786 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
2787 MacroAssembler::SIMD_RegVariant T, const Address &adr);
2788
2789 // Used for all non-volatile memory accesses. The use of
2790 // $mem->opcode() to discover whether this pattern uses sign-extended
2791 // offsets is something of a kludge.
2792 static void loadStore(C2_MacroAssembler* masm, mem_insn insn,
2793 Register reg, int opcode,
2794 Register base, int index, int scale, int disp,
2795 int size_in_memory)
2796 {
2797 Address addr = mem2address(opcode, base, index, scale, disp);
2798 if (addr.getMode() == Address::base_plus_offset) {
2799 /* Fix up any out-of-range offsets. */
2800 assert_different_registers(rscratch1, base);
2801 assert_different_registers(rscratch1, reg);
2802 addr = __ legitimize_address(addr, size_in_memory, rscratch1);
2803 }
2804 (masm->*insn)(reg, addr);
2805 }
2806
2807 static void loadStore(C2_MacroAssembler* masm, mem_float_insn insn,
2808 FloatRegister reg, int opcode,
2809 Register base, int index, int size, int disp,
2810 int size_in_memory)
2811 {
2812 Address::extend scale;
2813
2814 switch (opcode) {
2815 case INDINDEXSCALEDI2L:
2816 case INDINDEXSCALEDI2LN:
2817 scale = Address::sxtw(size);
2818 break;
2819 default:
2820 scale = Address::lsl(size);
2821 }
2822
2823 if (index == -1) {
2824 // Fix up any out-of-range offsets.
2825 assert_different_registers(rscratch1, base);
2826 Address addr = Address(base, disp);
2827 addr = __ legitimize_address(addr, size_in_memory, rscratch1);
2828 (masm->*insn)(reg, addr);
2829 } else {
2830 assert(disp == 0, "unsupported address mode: disp = %d", disp);
2831 (masm->*insn)(reg, Address(base, as_Register(index), scale));
2832 }
2833 }
2834
2835 static void loadStore(C2_MacroAssembler* masm, mem_vector_insn insn,
2836 FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
2837 int opcode, Register base, int index, int size, int disp)
2838 {
2839 if (index == -1) {
2840 (masm->*insn)(reg, T, Address(base, disp));
2841 } else {
2842 assert(disp == 0, "unsupported address mode");
2843 (masm->*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size)));
2844 }
2845 }
2846
2847 %}
2848
2849
2850
2851 //----------ENCODING BLOCK-----------------------------------------------------
2852 // This block specifies the encoding classes used by the compiler to
2853 // output byte streams. Encoding classes are parameterized macros
2854 // used by Machine Instruction Nodes in order to generate the bit
2855 // encoding of the instruction. Operands specify their base encoding
2856 // interface with the interface keyword. There are currently
2857 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
2858 // COND_INTER. REG_INTER causes an operand to generate a function
2859 // which returns its register number when queried. CONST_INTER causes
2860 // an operand to generate a function which returns the value of the
2861 // constant when queried. MEMORY_INTER causes an operand to generate
2862 // four functions which return the Base Register, the Index Register,
2863 // the Scale Value, and the Offset Value of the operand when queried.
2864 // COND_INTER causes an operand to generate six functions which return
2865 // the encoding code (ie - encoding bits for the instruction)
2866 // associated with each basic boolean condition for a conditional
2867 // instruction.
2868 //
2869 // Instructions specify two basic values for encoding. Again, a
2870 // function is available to check if the constant displacement is an
2871 // oop. They use the ins_encode keyword to specify their encoding
2872 // classes (which must be a sequence of enc_class names, and their
2873 // parameters, specified in the encoding block), and they use the
2874 // opcode keyword to specify, in order, their primary, secondary, and
2875 // tertiary opcode. Only the opcode sections which a particular
2876 // instruction needs for encoding need to be specified.
2877 encode %{
2878 // Build emit functions for each basic byte or larger field in the
2879 // intel encoding scheme (opcode, rm, sib, immediate), and call them
2880 // from C++ code in the enc_class source block. Emit functions will
2881 // live in the main source block for now. In future, we can
2882 // generalize this by adding a syntax that specifies the sizes of
2883 // fields in an order, so that the adlc can build the emit functions
2884 // automagically
2885
2886 // catch all for unimplemented encodings
2887 enc_class enc_unimplemented %{
2888 __ unimplemented("C2 catch all");
2889 %}
2890
2891 // BEGIN Non-volatile memory access
2892
2893 // This encoding class is generated automatically from ad_encode.m4.
2894 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2895 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{
2896 Register dst_reg = as_Register($dst$$reg);
2897 loadStore(masm, &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(),
2898 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2899 %}
2900
2901 // This encoding class is generated automatically from ad_encode.m4.
2902 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2903 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{
2904 Register dst_reg = as_Register($dst$$reg);
2905 loadStore(masm, &MacroAssembler::ldrsb, dst_reg, $mem->opcode(),
2906 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2907 %}
2908
2909 // This encoding class is generated automatically from ad_encode.m4.
2910 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2911 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{
2912 Register dst_reg = as_Register($dst$$reg);
2913 loadStore(masm, &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2914 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2915 %}
2916
2917 // This encoding class is generated automatically from ad_encode.m4.
2918 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2919 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{
2920 Register dst_reg = as_Register($dst$$reg);
2921 loadStore(masm, &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2922 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2923 %}
2924
2925 // This encoding class is generated automatically from ad_encode.m4.
2926 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2927 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{
2928 Register dst_reg = as_Register($dst$$reg);
2929 loadStore(masm, &MacroAssembler::ldrshw, dst_reg, $mem->opcode(),
2930 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2931 %}
2932
2933 // This encoding class is generated automatically from ad_encode.m4.
2934 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2935 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{
2936 Register dst_reg = as_Register($dst$$reg);
2937 loadStore(masm, &MacroAssembler::ldrsh, dst_reg, $mem->opcode(),
2938 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2939 %}
2940
2941 // This encoding class is generated automatically from ad_encode.m4.
2942 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2943 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{
2944 Register dst_reg = as_Register($dst$$reg);
2945 loadStore(masm, &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2946 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2947 %}
2948
2949 // This encoding class is generated automatically from ad_encode.m4.
2950 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2951 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{
2952 Register dst_reg = as_Register($dst$$reg);
2953 loadStore(masm, &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2954 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2955 %}
2956
2957 // This encoding class is generated automatically from ad_encode.m4.
2958 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2959 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{
2960 Register dst_reg = as_Register($dst$$reg);
2961 loadStore(masm, &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2962 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2963 %}
2964
2965 // This encoding class is generated automatically from ad_encode.m4.
2966 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2967 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{
2968 Register dst_reg = as_Register($dst$$reg);
2969 loadStore(masm, &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2970 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2971 %}
2972
2973 // This encoding class is generated automatically from ad_encode.m4.
2974 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2975 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{
2976 Register dst_reg = as_Register($dst$$reg);
2977 loadStore(masm, &MacroAssembler::ldrsw, dst_reg, $mem->opcode(),
2978 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2979 %}
2980
2981 // This encoding class is generated automatically from ad_encode.m4.
2982 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2983 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{
2984 Register dst_reg = as_Register($dst$$reg);
2985 loadStore(masm, &MacroAssembler::ldr, dst_reg, $mem->opcode(),
2986 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
2987 %}
2988
2989 // This encoding class is generated automatically from ad_encode.m4.
2990 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2991 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{
2992 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2993 loadStore(masm, &MacroAssembler::ldrs, dst_reg, $mem->opcode(),
2994 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2995 %}
2996
2997 // This encoding class is generated automatically from ad_encode.m4.
2998 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2999 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{
3000 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3001 loadStore(masm, &MacroAssembler::ldrd, dst_reg, $mem->opcode(),
3002 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3003 %}
3004
3005 // This encoding class is generated automatically from ad_encode.m4.
3006 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3007 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{
3008 Register src_reg = as_Register($src$$reg);
3009 loadStore(masm, &MacroAssembler::strb, src_reg, $mem->opcode(),
3010 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
3011 %}
3012
3013 // This encoding class is generated automatically from ad_encode.m4.
3014 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3015 enc_class aarch64_enc_strb0(memory1 mem) %{
3016 loadStore(masm, &MacroAssembler::strb, zr, $mem->opcode(),
3017 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
3018 %}
3019
3020 // This encoding class is generated automatically from ad_encode.m4.
3021 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3022 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{
3023 Register src_reg = as_Register($src$$reg);
3024 loadStore(masm, &MacroAssembler::strh, src_reg, $mem->opcode(),
3025 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
3026 %}
3027
3028 // This encoding class is generated automatically from ad_encode.m4.
3029 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3030 enc_class aarch64_enc_strh0(memory2 mem) %{
3031 loadStore(masm, &MacroAssembler::strh, zr, $mem->opcode(),
3032 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
3033 %}
3034
3035 // This encoding class is generated automatically from ad_encode.m4.
3036 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3037 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{
3038 Register src_reg = as_Register($src$$reg);
3039 loadStore(masm, &MacroAssembler::strw, src_reg, $mem->opcode(),
3040 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
3041 %}
3042
3043 // This encoding class is generated automatically from ad_encode.m4.
3044 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3045 enc_class aarch64_enc_strw0(memory4 mem) %{
3046 loadStore(masm, &MacroAssembler::strw, zr, $mem->opcode(),
3047 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
3048 %}
3049
3050 // This encoding class is generated automatically from ad_encode.m4.
3051 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3052 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{
3053 Register src_reg = as_Register($src$$reg);
3054 // we sometimes get asked to store the stack pointer into the
3055 // current thread -- we cannot do that directly on AArch64
3056 if (src_reg == r31_sp) {
3057 assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
3058 __ mov(rscratch2, sp);
3059 src_reg = rscratch2;
3060 }
3061 loadStore(masm, &MacroAssembler::str, src_reg, $mem->opcode(),
3062 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3063 %}
3064
3065 // This encoding class is generated automatically from ad_encode.m4.
3066 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3067 enc_class aarch64_enc_str0(memory8 mem) %{
3068 loadStore(masm, &MacroAssembler::str, zr, $mem->opcode(),
3069 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3070 %}
3071
3072 // This encoding class is generated automatically from ad_encode.m4.
3073 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3074 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{
3075 FloatRegister src_reg = as_FloatRegister($src$$reg);
3076 loadStore(masm, &MacroAssembler::strs, src_reg, $mem->opcode(),
3077 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
3078 %}
3079
3080 // This encoding class is generated automatically from ad_encode.m4.
3081 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3082 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{
3083 FloatRegister src_reg = as_FloatRegister($src$$reg);
3084 loadStore(masm, &MacroAssembler::strd, src_reg, $mem->opcode(),
3085 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3086 %}
3087
3088 // This encoding class is generated automatically from ad_encode.m4.
3089 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3090 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{
3091 __ membar(Assembler::StoreStore);
3092 loadStore(masm, &MacroAssembler::strb, zr, $mem->opcode(),
3093 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
3094 %}
3095
3096 // END Non-volatile memory access
3097
3098 // Vector loads and stores
3099 enc_class aarch64_enc_ldrvH(vReg dst, memory mem) %{
3100 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3101 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::H,
3102 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3103 %}
3104
3105 enc_class aarch64_enc_ldrvS(vReg dst, memory mem) %{
3106 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3107 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::S,
3108 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3109 %}
3110
3111 enc_class aarch64_enc_ldrvD(vReg dst, memory mem) %{
3112 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3113 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::D,
3114 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3115 %}
3116
3117 enc_class aarch64_enc_ldrvQ(vReg dst, memory mem) %{
3118 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3119 loadStore(masm, &MacroAssembler::ldr, dst_reg, MacroAssembler::Q,
3120 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3121 %}
3122
3123 enc_class aarch64_enc_strvH(vReg src, memory mem) %{
3124 FloatRegister src_reg = as_FloatRegister($src$$reg);
3125 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::H,
3126 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3127 %}
3128
3129 enc_class aarch64_enc_strvS(vReg src, memory mem) %{
3130 FloatRegister src_reg = as_FloatRegister($src$$reg);
3131 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::S,
3132 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3133 %}
3134
3135 enc_class aarch64_enc_strvD(vReg src, memory mem) %{
3136 FloatRegister src_reg = as_FloatRegister($src$$reg);
3137 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::D,
3138 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3139 %}
3140
3141 enc_class aarch64_enc_strvQ(vReg src, memory mem) %{
3142 FloatRegister src_reg = as_FloatRegister($src$$reg);
3143 loadStore(masm, &MacroAssembler::str, src_reg, MacroAssembler::Q,
3144 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3145 %}
3146
3147 // volatile loads and stores
3148
3149 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{
3150 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3151 rscratch1, stlrb);
3152 %}
3153
3154 enc_class aarch64_enc_stlrb0(memory mem) %{
3155 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3156 rscratch1, stlrb);
3157 %}
3158
3159 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{
3160 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3161 rscratch1, stlrh);
3162 %}
3163
3164 enc_class aarch64_enc_stlrh0(memory mem) %{
3165 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3166 rscratch1, stlrh);
3167 %}
3168
3169 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{
3170 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3171 rscratch1, stlrw);
3172 %}
3173
3174 enc_class aarch64_enc_stlrw0(memory mem) %{
3175 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3176 rscratch1, stlrw);
3177 %}
3178
3179 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{
3180 Register dst_reg = as_Register($dst$$reg);
3181 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3182 rscratch1, ldarb);
3183 __ sxtbw(dst_reg, dst_reg);
3184 %}
3185
3186 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{
3187 Register dst_reg = as_Register($dst$$reg);
3188 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3189 rscratch1, ldarb);
3190 __ sxtb(dst_reg, dst_reg);
3191 %}
3192
3193 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{
3194 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3195 rscratch1, ldarb);
3196 %}
3197
3198 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{
3199 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3200 rscratch1, ldarb);
3201 %}
3202
3203 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{
3204 Register dst_reg = as_Register($dst$$reg);
3205 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3206 rscratch1, ldarh);
3207 __ sxthw(dst_reg, dst_reg);
3208 %}
3209
3210 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{
3211 Register dst_reg = as_Register($dst$$reg);
3212 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3213 rscratch1, ldarh);
3214 __ sxth(dst_reg, dst_reg);
3215 %}
3216
3217 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{
3218 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3219 rscratch1, ldarh);
3220 %}
3221
3222 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{
3223 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3224 rscratch1, ldarh);
3225 %}
3226
3227 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{
3228 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3229 rscratch1, ldarw);
3230 %}
3231
3232 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{
3233 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3234 rscratch1, ldarw);
3235 %}
3236
3237 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{
3238 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3239 rscratch1, ldar);
3240 %}
3241
3242 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{
3243 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3244 rscratch1, ldarw);
3245 __ fmovs(as_FloatRegister($dst$$reg), rscratch1);
3246 %}
3247
3248 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{
3249 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3250 rscratch1, ldar);
3251 __ fmovd(as_FloatRegister($dst$$reg), rscratch1);
3252 %}
3253
3254 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{
3255 Register src_reg = as_Register($src$$reg);
3256 // we sometimes get asked to store the stack pointer into the
3257 // current thread -- we cannot do that directly on AArch64
3258 if (src_reg == r31_sp) {
3259 assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
3260 __ mov(rscratch2, sp);
3261 src_reg = rscratch2;
3262 }
3263 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3264 rscratch1, stlr);
3265 %}
3266
3267 enc_class aarch64_enc_stlr0(memory mem) %{
3268 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3269 rscratch1, stlr);
3270 %}
3271
3272 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{
3273 {
3274 FloatRegister src_reg = as_FloatRegister($src$$reg);
3275 __ fmovs(rscratch2, src_reg);
3276 }
3277 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3278 rscratch1, stlrw);
3279 %}
3280
3281 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{
3282 {
3283 FloatRegister src_reg = as_FloatRegister($src$$reg);
3284 __ fmovd(rscratch2, src_reg);
3285 }
3286 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3287 rscratch1, stlr);
3288 %}
3289
3290 // synchronized read/update encodings
3291
3292 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{
3293 Register dst_reg = as_Register($dst$$reg);
3294 Register base = as_Register($mem$$base);
3295 int index = $mem$$index;
3296 int scale = $mem$$scale;
3297 int disp = $mem$$disp;
3298 if (index == -1) {
3299 if (disp != 0) {
3300 __ lea(rscratch1, Address(base, disp));
3301 __ ldaxr(dst_reg, rscratch1);
3302 } else {
3303 // TODO
3304 // should we ever get anything other than this case?
3305 __ ldaxr(dst_reg, base);
3306 }
3307 } else {
3308 Register index_reg = as_Register(index);
3309 if (disp == 0) {
3310 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale)));
3311 __ ldaxr(dst_reg, rscratch1);
3312 } else {
3313 __ lea(rscratch1, Address(base, disp));
3314 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale)));
3315 __ ldaxr(dst_reg, rscratch1);
3316 }
3317 }
3318 %}
3319
3320 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{
3321 Register src_reg = as_Register($src$$reg);
3322 Register base = as_Register($mem$$base);
3323 int index = $mem$$index;
3324 int scale = $mem$$scale;
3325 int disp = $mem$$disp;
3326 if (index == -1) {
3327 if (disp != 0) {
3328 __ lea(rscratch2, Address(base, disp));
3329 __ stlxr(rscratch1, src_reg, rscratch2);
3330 } else {
3331 // TODO
3332 // should we ever get anything other than this case?
3333 __ stlxr(rscratch1, src_reg, base);
3334 }
3335 } else {
3336 Register index_reg = as_Register(index);
3337 if (disp == 0) {
3338 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale)));
3339 __ stlxr(rscratch1, src_reg, rscratch2);
3340 } else {
3341 __ lea(rscratch2, Address(base, disp));
3342 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale)));
3343 __ stlxr(rscratch1, src_reg, rscratch2);
3344 }
3345 }
3346 __ cmpw(rscratch1, zr);
3347 %}
3348
3349 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
3350 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3351 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3352 Assembler::xword, /*acquire*/ false, /*release*/ true,
3353 /*weak*/ false, noreg);
3354 %}
3355
3356 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3357 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3358 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3359 Assembler::word, /*acquire*/ false, /*release*/ true,
3360 /*weak*/ false, noreg);
3361 %}
3362
3363 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3364 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3365 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3366 Assembler::halfword, /*acquire*/ false, /*release*/ true,
3367 /*weak*/ false, noreg);
3368 %}
3369
3370 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3371 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3372 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3373 Assembler::byte, /*acquire*/ false, /*release*/ true,
3374 /*weak*/ false, noreg);
3375 %}
3376
3377
3378 // The only difference between aarch64_enc_cmpxchg and
3379 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the
3380 // CompareAndSwap sequence to serve as a barrier on acquiring a
3381 // lock.
3382 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
3383 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3384 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3385 Assembler::xword, /*acquire*/ true, /*release*/ true,
3386 /*weak*/ false, noreg);
3387 %}
3388
3389 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3390 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3391 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3392 Assembler::word, /*acquire*/ true, /*release*/ true,
3393 /*weak*/ false, noreg);
3394 %}
3395
3396 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3397 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3398 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3399 Assembler::halfword, /*acquire*/ true, /*release*/ true,
3400 /*weak*/ false, noreg);
3401 %}
3402
3403 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3404 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3405 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3406 Assembler::byte, /*acquire*/ true, /*release*/ true,
3407 /*weak*/ false, noreg);
3408 %}
3409
3410 // auxiliary used for CompareAndSwapX to set result register
3411 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
3412 Register res_reg = as_Register($res$$reg);
3413 __ cset(res_reg, Assembler::EQ);
3414 %}
3415
3416 // prefetch encodings
3417
3418 enc_class aarch64_enc_prefetchw(memory mem) %{
3419 Register base = as_Register($mem$$base);
3420 int index = $mem$$index;
3421 int scale = $mem$$scale;
3422 int disp = $mem$$disp;
3423 if (index == -1) {
3424 // Fix up any out-of-range offsets.
3425 assert_different_registers(rscratch1, base);
3426 Address addr = Address(base, disp);
3427 addr = __ legitimize_address(addr, 8, rscratch1);
3428 __ prfm(addr, PSTL1KEEP);
3429 } else {
3430 Register index_reg = as_Register(index);
3431 if (disp == 0) {
3432 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP);
3433 } else {
3434 __ lea(rscratch1, Address(base, disp));
3435 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP);
3436 }
3437 }
3438 %}
3439
3440 // mov encodings
3441
3442 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{
3443 uint32_t con = (uint32_t)$src$$constant;
3444 Register dst_reg = as_Register($dst$$reg);
3445 if (con == 0) {
3446 __ movw(dst_reg, zr);
3447 } else {
3448 __ movw(dst_reg, con);
3449 }
3450 %}
3451
3452 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{
3453 Register dst_reg = as_Register($dst$$reg);
3454 uint64_t con = (uint64_t)$src$$constant;
3455 if (con == 0) {
3456 __ mov(dst_reg, zr);
3457 } else {
3458 __ mov(dst_reg, con);
3459 }
3460 %}
3461
3462 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
3463 Register dst_reg = as_Register($dst$$reg);
3464 address con = (address)$src$$constant;
3465 if (con == nullptr || con == (address)1) {
3466 ShouldNotReachHere();
3467 } else {
3468 relocInfo::relocType rtype = $src->constant_reloc();
3469 if (rtype == relocInfo::oop_type) {
3470 __ movoop(dst_reg, (jobject)con);
3471 } else if (rtype == relocInfo::metadata_type) {
3472 __ mov_metadata(dst_reg, (Metadata*)con);
3473 } else {
3474 assert(rtype == relocInfo::none, "unexpected reloc type");
3475 if (! __ is_valid_AArch64_address(con) ||
3476 con < (address)(uintptr_t)os::vm_page_size()) {
3477 __ mov(dst_reg, con);
3478 } else {
3479 uint64_t offset;
3480 __ adrp(dst_reg, con, offset);
3481 __ add(dst_reg, dst_reg, offset);
3482 }
3483 }
3484 }
3485 %}
3486
3487 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
3488 Register dst_reg = as_Register($dst$$reg);
3489 __ mov(dst_reg, zr);
3490 %}
3491
3492 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
3493 Register dst_reg = as_Register($dst$$reg);
3494 __ mov(dst_reg, (uint64_t)1);
3495 %}
3496
3497 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{
3498 Register dst_reg = as_Register($dst$$reg);
3499 address con = (address)$src$$constant;
3500 if (con == nullptr) {
3501 ShouldNotReachHere();
3502 } else {
3503 relocInfo::relocType rtype = $src->constant_reloc();
3504 assert(rtype == relocInfo::oop_type, "unexpected reloc type");
3505 __ set_narrow_oop(dst_reg, (jobject)con);
3506 }
3507 %}
3508
3509 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{
3510 Register dst_reg = as_Register($dst$$reg);
3511 __ mov(dst_reg, zr);
3512 %}
3513
3514 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{
3515 Register dst_reg = as_Register($dst$$reg);
3516 address con = (address)$src$$constant;
3517 if (con == nullptr) {
3518 ShouldNotReachHere();
3519 } else {
3520 relocInfo::relocType rtype = $src->constant_reloc();
3521 assert(rtype == relocInfo::metadata_type, "unexpected reloc type");
3522 __ set_narrow_klass(dst_reg, (Klass *)con);
3523 }
3524 %}
3525
3526 // arithmetic encodings
3527
3528 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{
3529 Register dst_reg = as_Register($dst$$reg);
3530 Register src_reg = as_Register($src1$$reg);
3531 int32_t con = (int32_t)$src2$$constant;
3532 // add has primary == 0, subtract has primary == 1
3533 if ($primary) { con = -con; }
3534 if (con < 0) {
3535 __ subw(dst_reg, src_reg, -con);
3536 } else {
3537 __ addw(dst_reg, src_reg, con);
3538 }
3539 %}
3540
3541 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{
3542 Register dst_reg = as_Register($dst$$reg);
3543 Register src_reg = as_Register($src1$$reg);
3544 int32_t con = (int32_t)$src2$$constant;
3545 // add has primary == 0, subtract has primary == 1
3546 if ($primary) { con = -con; }
3547 if (con < 0) {
3548 __ sub(dst_reg, src_reg, -con);
3549 } else {
3550 __ add(dst_reg, src_reg, con);
3551 }
3552 %}
3553
3554 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{
3555 Register dst_reg = as_Register($dst$$reg);
3556 Register src1_reg = as_Register($src1$$reg);
3557 Register src2_reg = as_Register($src2$$reg);
3558 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1);
3559 %}
3560
3561 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
3562 Register dst_reg = as_Register($dst$$reg);
3563 Register src1_reg = as_Register($src1$$reg);
3564 Register src2_reg = as_Register($src2$$reg);
3565 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1);
3566 %}
3567
3568 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
3569 Register dst_reg = as_Register($dst$$reg);
3570 Register src1_reg = as_Register($src1$$reg);
3571 Register src2_reg = as_Register($src2$$reg);
3572 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1);
3573 %}
3574
3575 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
3576 Register dst_reg = as_Register($dst$$reg);
3577 Register src1_reg = as_Register($src1$$reg);
3578 Register src2_reg = as_Register($src2$$reg);
3579 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1);
3580 %}
3581
3582 // compare instruction encodings
3583
3584 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{
3585 Register reg1 = as_Register($src1$$reg);
3586 Register reg2 = as_Register($src2$$reg);
3587 __ cmpw(reg1, reg2);
3588 %}
3589
3590 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{
3591 Register reg = as_Register($src1$$reg);
3592 int32_t val = $src2$$constant;
3593 if (val >= 0) {
3594 __ subsw(zr, reg, val);
3595 } else {
3596 __ addsw(zr, reg, -val);
3597 }
3598 %}
3599
3600 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{
3601 Register reg1 = as_Register($src1$$reg);
3602 uint32_t val = (uint32_t)$src2$$constant;
3603 __ movw(rscratch1, val);
3604 __ cmpw(reg1, rscratch1);
3605 %}
3606
3607 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{
3608 Register reg1 = as_Register($src1$$reg);
3609 Register reg2 = as_Register($src2$$reg);
3610 __ cmp(reg1, reg2);
3611 %}
3612
3613 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{
3614 Register reg = as_Register($src1$$reg);
3615 int64_t val = $src2$$constant;
3616 if (val >= 0) {
3617 __ subs(zr, reg, val);
3618 } else if (val != -val) {
3619 __ adds(zr, reg, -val);
3620 } else {
3621 // aargh, Long.MIN_VALUE is a special case
3622 __ orr(rscratch1, zr, (uint64_t)val);
3623 __ subs(zr, reg, rscratch1);
3624 }
3625 %}
3626
3627 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{
3628 Register reg1 = as_Register($src1$$reg);
3629 uint64_t val = (uint64_t)$src2$$constant;
3630 __ mov(rscratch1, val);
3631 __ cmp(reg1, rscratch1);
3632 %}
3633
3634 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{
3635 Register reg1 = as_Register($src1$$reg);
3636 Register reg2 = as_Register($src2$$reg);
3637 __ cmp(reg1, reg2);
3638 %}
3639
3640 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{
3641 Register reg1 = as_Register($src1$$reg);
3642 Register reg2 = as_Register($src2$$reg);
3643 __ cmpw(reg1, reg2);
3644 %}
3645
3646 enc_class aarch64_enc_testp(iRegP src) %{
3647 Register reg = as_Register($src$$reg);
3648 __ cmp(reg, zr);
3649 %}
3650
3651 enc_class aarch64_enc_testn(iRegN src) %{
3652 Register reg = as_Register($src$$reg);
3653 __ cmpw(reg, zr);
3654 %}
3655
3656 enc_class aarch64_enc_b(label lbl) %{
3657 Label *L = $lbl$$label;
3658 __ b(*L);
3659 %}
3660
3661 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{
3662 Label *L = $lbl$$label;
3663 __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3664 %}
3665
3666 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{
3667 Label *L = $lbl$$label;
3668 __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3669 %}
3670
3671 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result)
3672 %{
3673 Register sub_reg = as_Register($sub$$reg);
3674 Register super_reg = as_Register($super$$reg);
3675 Register temp_reg = as_Register($temp$$reg);
3676 Register result_reg = as_Register($result$$reg);
3677
3678 Label miss;
3679 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg,
3680 nullptr, &miss,
3681 /*set_cond_codes:*/ true);
3682 if ($primary) {
3683 __ mov(result_reg, zr);
3684 }
3685 __ bind(miss);
3686 %}
3687
3688 enc_class aarch64_enc_java_static_call(method meth) %{
3689 address addr = (address)$meth$$method;
3690 address call;
3691 if (!_method) {
3692 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3693 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type));
3694 if (call == nullptr) {
3695 ciEnv::current()->record_failure("CodeCache is full");
3696 return;
3697 }
3698 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) {
3699 // The NOP here is purely to ensure that eliding a call to
3700 // JVM_EnsureMaterializedForStackWalk doesn't change the code size.
3701 __ nop();
3702 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)");
3703 } else {
3704 int method_index = resolved_method_index(masm);
3705 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3706 : static_call_Relocation::spec(method_index);
3707 call = __ trampoline_call(Address(addr, rspec));
3708 if (call == nullptr) {
3709 ciEnv::current()->record_failure("CodeCache is full");
3710 return;
3711 }
3712 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) {
3713 // Calls of the same statically bound method can share
3714 // a stub to the interpreter.
3715 __ code()->shared_stub_to_interp_for(_method, call - __ begin());
3716 } else {
3717 // Emit stub for static call
3718 address stub = CompiledDirectCall::emit_to_interp_stub(masm, call);
3719 if (stub == nullptr) {
3720 ciEnv::current()->record_failure("CodeCache is full");
3721 return;
3722 }
3723 }
3724 }
3725
3726 __ post_call_nop();
3727
3728 // Only non uncommon_trap calls need to reinitialize ptrue.
3729 if (Compile::current()->max_vector_size() > 0 && uncommon_trap_request() == 0) {
3730 __ reinitialize_ptrue();
3731 }
3732 %}
3733
3734 enc_class aarch64_enc_java_dynamic_call(method meth) %{
3735 int method_index = resolved_method_index(masm);
3736 address call = __ ic_call((address)$meth$$method, method_index);
3737 if (call == nullptr) {
3738 ciEnv::current()->record_failure("CodeCache is full");
3739 return;
3740 }
3741 __ post_call_nop();
3742 if (Compile::current()->max_vector_size() > 0) {
3743 __ reinitialize_ptrue();
3744 }
3745 %}
3746
3747 enc_class aarch64_enc_call_epilog() %{
3748 if (VerifyStackAtCalls) {
3749 // Check that stack depth is unchanged: find majik cookie on stack
3750 __ call_Unimplemented();
3751 }
3752 if (tf()->returns_inline_type_as_fields() && !_method->is_method_handle_intrinsic() && _method->return_type()->is_loaded()) {
3753 // The last return value is not set by the callee but used to pass the null marker to compiled code.
3754 // Search for the corresponding projection, get the register and emit code that initialized it.
3755 uint con = (tf()->range_cc()->cnt() - 1);
3756 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
3757 ProjNode* proj = fast_out(i)->as_Proj();
3758 if (proj->_con == con) {
3759 // Set null marker if r0 is non-null (a non-null value is returned buffered or scalarized)
3760 OptoReg::Name optoReg = ra_->get_reg_first(proj);
3761 VMReg reg = OptoReg::as_VMReg(optoReg, ra_->_framesize, OptoReg::reg2stack(ra_->_matcher._new_SP));
3762 Register toReg = reg->is_reg() ? reg->as_Register() : rscratch1;
3763 __ cmp(r0, zr);
3764 __ cset(toReg, Assembler::NE);
3765 if (reg->is_stack()) {
3766 int st_off = reg->reg2stack() * VMRegImpl::stack_slot_size;
3767 __ str(toReg, Address(sp, st_off));
3768 }
3769 break;
3770 }
3771 }
3772 if (return_value_is_used()) {
3773 // An inline type is returned as fields in multiple registers.
3774 // R0 either contains an oop if the inline type is buffered or a pointer
3775 // to the corresponding InlineKlass with the lowest bit set to 1. Zero r0
3776 // if the lowest bit is set to allow C2 to use the oop after null checking.
3777 // r0 &= (r0 & 1) - 1
3778 __ andr(rscratch1, r0, 0x1);
3779 __ sub(rscratch1, rscratch1, 0x1);
3780 __ andr(r0, r0, rscratch1);
3781 }
3782 }
3783 %}
3784
3785 enc_class aarch64_enc_java_to_runtime(method meth) %{
3786 // some calls to generated routines (arraycopy code) are scheduled
3787 // by C2 as runtime calls. if so we can call them using a br (they
3788 // will be in a reachable segment) otherwise we have to use a blr
3789 // which loads the absolute address into a register.
3790 address entry = (address)$meth$$method;
3791 CodeBlob *cb = CodeCache::find_blob(entry);
3792 if (cb) {
3793 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type));
3794 if (call == nullptr) {
3795 ciEnv::current()->record_failure("CodeCache is full");
3796 return;
3797 }
3798 __ post_call_nop();
3799 } else {
3800 Label retaddr;
3801 // Make the anchor frame walkable
3802 __ adr(rscratch2, retaddr);
3803 __ str(rscratch2, Address(rthread, JavaThread::last_Java_pc_offset()));
3804 __ lea(rscratch1, RuntimeAddress(entry));
3805 __ blr(rscratch1);
3806 __ bind(retaddr);
3807 __ post_call_nop();
3808 }
3809 if (Compile::current()->max_vector_size() > 0) {
3810 __ reinitialize_ptrue();
3811 }
3812 %}
3813
3814 enc_class aarch64_enc_rethrow() %{
3815 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub()));
3816 %}
3817
3818 enc_class aarch64_enc_ret() %{
3819 #ifdef ASSERT
3820 if (Compile::current()->max_vector_size() > 0) {
3821 __ verify_ptrue();
3822 }
3823 #endif
3824 __ ret(lr);
3825 %}
3826
3827 enc_class aarch64_enc_tail_call(iRegP jump_target) %{
3828 Register target_reg = as_Register($jump_target$$reg);
3829 __ br(target_reg);
3830 %}
3831
3832 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{
3833 Register target_reg = as_Register($jump_target$$reg);
3834 // exception oop should be in r0
3835 // ret addr has been popped into lr
3836 // callee expects it in r3
3837 __ mov(r3, lr);
3838 __ br(target_reg);
3839 %}
3840
3841 %}
3842
3843 //----------FRAME--------------------------------------------------------------
3844 // Definition of frame structure and management information.
3845 //
3846 // S T A C K L A Y O U T Allocators stack-slot number
3847 // | (to get allocators register number
3848 // G Owned by | | v add OptoReg::stack0())
3849 // r CALLER | |
3850 // o | +--------+ pad to even-align allocators stack-slot
3851 // w V | pad0 | numbers; owned by CALLER
3852 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
3853 // h ^ | in | 5
3854 // | | args | 4 Holes in incoming args owned by SELF
3855 // | | | | 3
3856 // | | +--------+
3857 // V | | old out| Empty on Intel, window on Sparc
3858 // | old |preserve| Must be even aligned.
3859 // | SP-+--------+----> Matcher::_old_SP, even aligned
3860 // | | in | 3 area for Intel ret address
3861 // Owned by |preserve| Empty on Sparc.
3862 // SELF +--------+
3863 // | | pad2 | 2 pad to align old SP
3864 // | +--------+ 1
3865 // | | locks | 0
3866 // | +--------+----> OptoReg::stack0(), even aligned
3867 // | | pad1 | 11 pad to align new SP
3868 // | +--------+
3869 // | | | 10
3870 // | | spills | 9 spills
3871 // V | | 8 (pad0 slot for callee)
3872 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
3873 // ^ | out | 7
3874 // | | args | 6 Holes in outgoing args owned by CALLEE
3875 // Owned by +--------+
3876 // CALLEE | new out| 6 Empty on Intel, window on Sparc
3877 // | new |preserve| Must be even-aligned.
3878 // | SP-+--------+----> Matcher::_new_SP, even aligned
3879 // | | |
3880 //
3881 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
3882 // known from SELF's arguments and the Java calling convention.
3883 // Region 6-7 is determined per call site.
3884 // Note 2: If the calling convention leaves holes in the incoming argument
3885 // area, those holes are owned by SELF. Holes in the outgoing area
3886 // are owned by the CALLEE. Holes should not be necessary in the
3887 // incoming area, as the Java calling convention is completely under
3888 // the control of the AD file. Doubles can be sorted and packed to
3889 // avoid holes. Holes in the outgoing arguments may be necessary for
3890 // varargs C calling conventions.
3891 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
3892 // even aligned with pad0 as needed.
3893 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
3894 // (the latter is true on Intel but is it false on AArch64?)
3895 // region 6-11 is even aligned; it may be padded out more so that
3896 // the region from SP to FP meets the minimum stack alignment.
3897 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3898 // alignment. Region 11, pad1, may be dynamically extended so that
3899 // SP meets the minimum alignment.
3900
3901 frame %{
3902 // These three registers define part of the calling convention
3903 // between compiled code and the interpreter.
3904
3905 // Inline Cache Register or Method for I2C.
3906 inline_cache_reg(R12);
3907
3908 // Number of stack slots consumed by locking an object
3909 sync_stack_slots(2);
3910
3911 // Compiled code's Frame Pointer
3912 frame_pointer(R31);
3913
3914 // Interpreter stores its frame pointer in a register which is
3915 // stored to the stack by I2CAdaptors.
3916 // I2CAdaptors convert from interpreted java to compiled java.
3917 interpreter_frame_pointer(R29);
3918
3919 // Stack alignment requirement
3920 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
3921
3922 // Number of outgoing stack slots killed above the out_preserve_stack_slots
3923 // for calls to C. Supports the var-args backing area for register parms.
3924 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
3925
3926 // The after-PROLOG location of the return address. Location of
3927 // return address specifies a type (REG or STACK) and a number
3928 // representing the register number (i.e. - use a register name) or
3929 // stack slot.
3930 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3931 // Otherwise, it is above the locks and verification slot and alignment word
3932 // TODO this may well be correct but need to check why that - 2 is there
3933 // ppc port uses 0 but we definitely need to allow for fixed_slots
3934 // which folds in the space used for monitors
3935 return_addr(STACK - 2 +
3936 align_up((Compile::current()->in_preserve_stack_slots() +
3937 Compile::current()->fixed_slots()),
3938 stack_alignment_in_slots()));
3939
3940 // Location of compiled Java return values. Same as C for now.
3941 return_value
3942 %{
3943 // TODO do we allow ideal_reg == Op_RegN???
3944 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
3945 "only return normal values");
3946
3947 static const int lo[Op_RegL + 1] = { // enum name
3948 0, // Op_Node
3949 0, // Op_Set
3950 R0_num, // Op_RegN
3951 R0_num, // Op_RegI
3952 R0_num, // Op_RegP
3953 V0_num, // Op_RegF
3954 V0_num, // Op_RegD
3955 R0_num // Op_RegL
3956 };
3957
3958 static const int hi[Op_RegL + 1] = { // enum name
3959 0, // Op_Node
3960 0, // Op_Set
3961 OptoReg::Bad, // Op_RegN
3962 OptoReg::Bad, // Op_RegI
3963 R0_H_num, // Op_RegP
3964 OptoReg::Bad, // Op_RegF
3965 V0_H_num, // Op_RegD
3966 R0_H_num // Op_RegL
3967 };
3968
3969 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
3970 %}
3971 %}
3972
3973 //----------ATTRIBUTES---------------------------------------------------------
3974 //----------Operand Attributes-------------------------------------------------
3975 op_attrib op_cost(1); // Required cost attribute
3976
3977 //----------Instruction Attributes---------------------------------------------
3978 ins_attrib ins_cost(INSN_COST); // Required cost attribute
3979 ins_attrib ins_size(32); // Required size attribute (in bits)
3980 ins_attrib ins_short_branch(0); // Required flag: is this instruction
3981 // a non-matching short branch variant
3982 // of some long branch?
3983 ins_attrib ins_alignment(4); // Required alignment attribute (must
3984 // be a power of 2) specifies the
3985 // alignment that some part of the
3986 // instruction (not necessarily the
3987 // start) requires. If > 1, a
3988 // compute_padding() function must be
3989 // provided for the instruction
3990
3991 // Whether this node is expanded during code emission into a sequence of
3992 // instructions and the first instruction can perform an implicit null check.
3993 ins_attrib ins_is_late_expanded_null_check_candidate(false);
3994
3995 //----------OPERANDS-----------------------------------------------------------
3996 // Operand definitions must precede instruction definitions for correct parsing
3997 // in the ADLC because operands constitute user defined types which are used in
3998 // instruction definitions.
3999
4000 //----------Simple Operands----------------------------------------------------
4001
4002 // Integer operands 32 bit
4003 // 32 bit immediate
4004 operand immI()
4005 %{
4006 match(ConI);
4007
4008 op_cost(0);
4009 format %{ %}
4010 interface(CONST_INTER);
4011 %}
4012
4013 // 32 bit zero
4014 operand immI0()
4015 %{
4016 predicate(n->get_int() == 0);
4017 match(ConI);
4018
4019 op_cost(0);
4020 format %{ %}
4021 interface(CONST_INTER);
4022 %}
4023
4024 // 32 bit unit increment
4025 operand immI_1()
4026 %{
4027 predicate(n->get_int() == 1);
4028 match(ConI);
4029
4030 op_cost(0);
4031 format %{ %}
4032 interface(CONST_INTER);
4033 %}
4034
4035 // 32 bit unit decrement
4036 operand immI_M1()
4037 %{
4038 predicate(n->get_int() == -1);
4039 match(ConI);
4040
4041 op_cost(0);
4042 format %{ %}
4043 interface(CONST_INTER);
4044 %}
4045
4046 // Shift values for add/sub extension shift
4047 operand immIExt()
4048 %{
4049 predicate(0 <= n->get_int() && (n->get_int() <= 4));
4050 match(ConI);
4051
4052 op_cost(0);
4053 format %{ %}
4054 interface(CONST_INTER);
4055 %}
4056
4057 operand immI_gt_1()
4058 %{
4059 predicate(n->get_int() > 1);
4060 match(ConI);
4061
4062 op_cost(0);
4063 format %{ %}
4064 interface(CONST_INTER);
4065 %}
4066
4067 operand immI_le_4()
4068 %{
4069 predicate(n->get_int() <= 4);
4070 match(ConI);
4071
4072 op_cost(0);
4073 format %{ %}
4074 interface(CONST_INTER);
4075 %}
4076
4077 operand immI_16()
4078 %{
4079 predicate(n->get_int() == 16);
4080 match(ConI);
4081
4082 op_cost(0);
4083 format %{ %}
4084 interface(CONST_INTER);
4085 %}
4086
4087 operand immI_24()
4088 %{
4089 predicate(n->get_int() == 24);
4090 match(ConI);
4091
4092 op_cost(0);
4093 format %{ %}
4094 interface(CONST_INTER);
4095 %}
4096
4097 operand immI_32()
4098 %{
4099 predicate(n->get_int() == 32);
4100 match(ConI);
4101
4102 op_cost(0);
4103 format %{ %}
4104 interface(CONST_INTER);
4105 %}
4106
4107 operand immI_48()
4108 %{
4109 predicate(n->get_int() == 48);
4110 match(ConI);
4111
4112 op_cost(0);
4113 format %{ %}
4114 interface(CONST_INTER);
4115 %}
4116
4117 operand immI_56()
4118 %{
4119 predicate(n->get_int() == 56);
4120 match(ConI);
4121
4122 op_cost(0);
4123 format %{ %}
4124 interface(CONST_INTER);
4125 %}
4126
4127 operand immI_255()
4128 %{
4129 predicate(n->get_int() == 255);
4130 match(ConI);
4131
4132 op_cost(0);
4133 format %{ %}
4134 interface(CONST_INTER);
4135 %}
4136
4137 operand immI_65535()
4138 %{
4139 predicate(n->get_int() == 65535);
4140 match(ConI);
4141
4142 op_cost(0);
4143 format %{ %}
4144 interface(CONST_INTER);
4145 %}
4146
4147 operand immI_positive()
4148 %{
4149 predicate(n->get_int() > 0);
4150 match(ConI);
4151
4152 op_cost(0);
4153 format %{ %}
4154 interface(CONST_INTER);
4155 %}
4156
4157 // BoolTest condition for signed compare
4158 operand immI_cmp_cond()
4159 %{
4160 predicate(!Matcher::is_unsigned_booltest_pred(n->get_int()));
4161 match(ConI);
4162
4163 op_cost(0);
4164 format %{ %}
4165 interface(CONST_INTER);
4166 %}
4167
4168 // BoolTest condition for unsigned compare
4169 operand immI_cmpU_cond()
4170 %{
4171 predicate(Matcher::is_unsigned_booltest_pred(n->get_int()));
4172 match(ConI);
4173
4174 op_cost(0);
4175 format %{ %}
4176 interface(CONST_INTER);
4177 %}
4178
4179 operand immL_255()
4180 %{
4181 predicate(n->get_long() == 255L);
4182 match(ConL);
4183
4184 op_cost(0);
4185 format %{ %}
4186 interface(CONST_INTER);
4187 %}
4188
4189 operand immL_65535()
4190 %{
4191 predicate(n->get_long() == 65535L);
4192 match(ConL);
4193
4194 op_cost(0);
4195 format %{ %}
4196 interface(CONST_INTER);
4197 %}
4198
4199 operand immL_4294967295()
4200 %{
4201 predicate(n->get_long() == 4294967295L);
4202 match(ConL);
4203
4204 op_cost(0);
4205 format %{ %}
4206 interface(CONST_INTER);
4207 %}
4208
4209 operand immL_bitmask()
4210 %{
4211 predicate((n->get_long() != 0)
4212 && ((n->get_long() & 0xc000000000000000l) == 0)
4213 && is_power_of_2(n->get_long() + 1));
4214 match(ConL);
4215
4216 op_cost(0);
4217 format %{ %}
4218 interface(CONST_INTER);
4219 %}
4220
4221 operand immI_bitmask()
4222 %{
4223 predicate((n->get_int() != 0)
4224 && ((n->get_int() & 0xc0000000) == 0)
4225 && is_power_of_2(n->get_int() + 1));
4226 match(ConI);
4227
4228 op_cost(0);
4229 format %{ %}
4230 interface(CONST_INTER);
4231 %}
4232
4233 operand immL_positive_bitmaskI()
4234 %{
4235 predicate((n->get_long() != 0)
4236 && ((julong)n->get_long() < 0x80000000ULL)
4237 && is_power_of_2(n->get_long() + 1));
4238 match(ConL);
4239
4240 op_cost(0);
4241 format %{ %}
4242 interface(CONST_INTER);
4243 %}
4244
4245 // Scale values for scaled offset addressing modes (up to long but not quad)
4246 operand immIScale()
4247 %{
4248 predicate(0 <= n->get_int() && (n->get_int() <= 3));
4249 match(ConI);
4250
4251 op_cost(0);
4252 format %{ %}
4253 interface(CONST_INTER);
4254 %}
4255
4256 // 5 bit signed integer
4257 operand immI5()
4258 %{
4259 predicate(Assembler::is_simm(n->get_int(), 5));
4260 match(ConI);
4261
4262 op_cost(0);
4263 format %{ %}
4264 interface(CONST_INTER);
4265 %}
4266
4267 // 7 bit unsigned integer
4268 operand immIU7()
4269 %{
4270 predicate(Assembler::is_uimm(n->get_int(), 7));
4271 match(ConI);
4272
4273 op_cost(0);
4274 format %{ %}
4275 interface(CONST_INTER);
4276 %}
4277
4278 // Offset for scaled or unscaled immediate loads and stores
4279 operand immIOffset()
4280 %{
4281 predicate(Address::offset_ok_for_immed(n->get_int(), 0));
4282 match(ConI);
4283
4284 op_cost(0);
4285 format %{ %}
4286 interface(CONST_INTER);
4287 %}
4288
4289 operand immIOffset1()
4290 %{
4291 predicate(Address::offset_ok_for_immed(n->get_int(), 0));
4292 match(ConI);
4293
4294 op_cost(0);
4295 format %{ %}
4296 interface(CONST_INTER);
4297 %}
4298
4299 operand immIOffset2()
4300 %{
4301 predicate(Address::offset_ok_for_immed(n->get_int(), 1));
4302 match(ConI);
4303
4304 op_cost(0);
4305 format %{ %}
4306 interface(CONST_INTER);
4307 %}
4308
4309 operand immIOffset4()
4310 %{
4311 predicate(Address::offset_ok_for_immed(n->get_int(), 2));
4312 match(ConI);
4313
4314 op_cost(0);
4315 format %{ %}
4316 interface(CONST_INTER);
4317 %}
4318
4319 operand immIOffset8()
4320 %{
4321 predicate(Address::offset_ok_for_immed(n->get_int(), 3));
4322 match(ConI);
4323
4324 op_cost(0);
4325 format %{ %}
4326 interface(CONST_INTER);
4327 %}
4328
4329 operand immIOffset16()
4330 %{
4331 predicate(Address::offset_ok_for_immed(n->get_int(), 4));
4332 match(ConI);
4333
4334 op_cost(0);
4335 format %{ %}
4336 interface(CONST_INTER);
4337 %}
4338
4339 operand immLOffset()
4340 %{
4341 predicate(n->get_long() >= -256 && n->get_long() <= 65520);
4342 match(ConL);
4343
4344 op_cost(0);
4345 format %{ %}
4346 interface(CONST_INTER);
4347 %}
4348
4349 operand immLoffset1()
4350 %{
4351 predicate(Address::offset_ok_for_immed(n->get_long(), 0));
4352 match(ConL);
4353
4354 op_cost(0);
4355 format %{ %}
4356 interface(CONST_INTER);
4357 %}
4358
4359 operand immLoffset2()
4360 %{
4361 predicate(Address::offset_ok_for_immed(n->get_long(), 1));
4362 match(ConL);
4363
4364 op_cost(0);
4365 format %{ %}
4366 interface(CONST_INTER);
4367 %}
4368
4369 operand immLoffset4()
4370 %{
4371 predicate(Address::offset_ok_for_immed(n->get_long(), 2));
4372 match(ConL);
4373
4374 op_cost(0);
4375 format %{ %}
4376 interface(CONST_INTER);
4377 %}
4378
4379 operand immLoffset8()
4380 %{
4381 predicate(Address::offset_ok_for_immed(n->get_long(), 3));
4382 match(ConL);
4383
4384 op_cost(0);
4385 format %{ %}
4386 interface(CONST_INTER);
4387 %}
4388
4389 operand immLoffset16()
4390 %{
4391 predicate(Address::offset_ok_for_immed(n->get_long(), 4));
4392 match(ConL);
4393
4394 op_cost(0);
4395 format %{ %}
4396 interface(CONST_INTER);
4397 %}
4398
4399 // 5 bit signed long integer
4400 operand immL5()
4401 %{
4402 predicate(Assembler::is_simm(n->get_long(), 5));
4403 match(ConL);
4404
4405 op_cost(0);
4406 format %{ %}
4407 interface(CONST_INTER);
4408 %}
4409
4410 // 7 bit unsigned long integer
4411 operand immLU7()
4412 %{
4413 predicate(Assembler::is_uimm(n->get_long(), 7));
4414 match(ConL);
4415
4416 op_cost(0);
4417 format %{ %}
4418 interface(CONST_INTER);
4419 %}
4420
4421 // 8 bit signed value.
4422 operand immI8()
4423 %{
4424 predicate(n->get_int() <= 127 && n->get_int() >= -128);
4425 match(ConI);
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 immIDupV()
4434 %{
4435 predicate(Assembler::operand_valid_for_sve_dup_immediate((int64_t)n->get_int()));
4436 match(ConI);
4437
4438 op_cost(0);
4439 format %{ %}
4440 interface(CONST_INTER);
4441 %}
4442
4443 // 8 bit signed value (simm8), or #simm8 LSL 8.
4444 operand immLDupV()
4445 %{
4446 predicate(Assembler::operand_valid_for_sve_dup_immediate(n->get_long()));
4447 match(ConL);
4448
4449 op_cost(0);
4450 format %{ %}
4451 interface(CONST_INTER);
4452 %}
4453
4454 // 8 bit signed value (simm8), or #simm8 LSL 8.
4455 operand immHDupV()
4456 %{
4457 predicate(Assembler::operand_valid_for_sve_dup_immediate((int64_t)n->geth()));
4458 match(ConH);
4459
4460 op_cost(0);
4461 format %{ %}
4462 interface(CONST_INTER);
4463 %}
4464
4465 // 8 bit integer valid for vector add sub immediate
4466 operand immBAddSubV()
4467 %{
4468 predicate(n->get_int() <= 255 && n->get_int() >= -255);
4469 match(ConI);
4470
4471 op_cost(0);
4472 format %{ %}
4473 interface(CONST_INTER);
4474 %}
4475
4476 // 32 bit integer valid for add sub immediate
4477 operand immIAddSub()
4478 %{
4479 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int()));
4480 match(ConI);
4481 op_cost(0);
4482 format %{ %}
4483 interface(CONST_INTER);
4484 %}
4485
4486 // 32 bit integer valid for vector add sub immediate
4487 operand immIAddSubV()
4488 %{
4489 predicate(Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)n->get_int()));
4490 match(ConI);
4491
4492 op_cost(0);
4493 format %{ %}
4494 interface(CONST_INTER);
4495 %}
4496
4497 // 32 bit unsigned integer valid for logical immediate
4498
4499 operand immBLog()
4500 %{
4501 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerByte, (uint64_t)n->get_int()));
4502 match(ConI);
4503
4504 op_cost(0);
4505 format %{ %}
4506 interface(CONST_INTER);
4507 %}
4508
4509 operand immSLog()
4510 %{
4511 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerShort, (uint64_t)n->get_int()));
4512 match(ConI);
4513
4514 op_cost(0);
4515 format %{ %}
4516 interface(CONST_INTER);
4517 %}
4518
4519 operand immILog()
4520 %{
4521 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int()));
4522 match(ConI);
4523
4524 op_cost(0);
4525 format %{ %}
4526 interface(CONST_INTER);
4527 %}
4528
4529 // Integer operands 64 bit
4530 // 64 bit immediate
4531 operand immL()
4532 %{
4533 match(ConL);
4534
4535 op_cost(0);
4536 format %{ %}
4537 interface(CONST_INTER);
4538 %}
4539
4540 // 64 bit zero
4541 operand immL0()
4542 %{
4543 predicate(n->get_long() == 0);
4544 match(ConL);
4545
4546 op_cost(0);
4547 format %{ %}
4548 interface(CONST_INTER);
4549 %}
4550
4551 // 64 bit unit decrement
4552 operand immL_M1()
4553 %{
4554 predicate(n->get_long() == -1);
4555 match(ConL);
4556
4557 op_cost(0);
4558 format %{ %}
4559 interface(CONST_INTER);
4560 %}
4561
4562 // 64 bit integer valid for add sub immediate
4563 operand immLAddSub()
4564 %{
4565 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long()));
4566 match(ConL);
4567 op_cost(0);
4568 format %{ %}
4569 interface(CONST_INTER);
4570 %}
4571
4572 // 64 bit integer valid for addv subv immediate
4573 operand immLAddSubV()
4574 %{
4575 predicate(Assembler::operand_valid_for_sve_add_sub_immediate(n->get_long()));
4576 match(ConL);
4577
4578 op_cost(0);
4579 format %{ %}
4580 interface(CONST_INTER);
4581 %}
4582
4583 // 64 bit integer valid for logical immediate
4584 operand immLLog()
4585 %{
4586 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long()));
4587 match(ConL);
4588 op_cost(0);
4589 format %{ %}
4590 interface(CONST_INTER);
4591 %}
4592
4593 // Long Immediate: low 32-bit mask
4594 operand immL_32bits()
4595 %{
4596 predicate(n->get_long() == 0xFFFFFFFFL);
4597 match(ConL);
4598 op_cost(0);
4599 format %{ %}
4600 interface(CONST_INTER);
4601 %}
4602
4603 // Pointer operands
4604 // Pointer Immediate
4605 operand immP()
4606 %{
4607 match(ConP);
4608
4609 op_cost(0);
4610 format %{ %}
4611 interface(CONST_INTER);
4612 %}
4613
4614 // nullptr Pointer Immediate
4615 operand immP0()
4616 %{
4617 predicate(n->get_ptr() == 0);
4618 match(ConP);
4619
4620 op_cost(0);
4621 format %{ %}
4622 interface(CONST_INTER);
4623 %}
4624
4625 // Pointer Immediate One
4626 // this is used in object initialization (initial object header)
4627 operand immP_1()
4628 %{
4629 predicate(n->get_ptr() == 1);
4630 match(ConP);
4631
4632 op_cost(0);
4633 format %{ %}
4634 interface(CONST_INTER);
4635 %}
4636
4637 // Float and Double operands
4638 // Double Immediate
4639 operand immD()
4640 %{
4641 match(ConD);
4642 op_cost(0);
4643 format %{ %}
4644 interface(CONST_INTER);
4645 %}
4646
4647 // Double Immediate: +0.0d
4648 operand immD0()
4649 %{
4650 predicate(jlong_cast(n->getd()) == 0);
4651 match(ConD);
4652
4653 op_cost(0);
4654 format %{ %}
4655 interface(CONST_INTER);
4656 %}
4657
4658 // constant 'double +0.0'.
4659 operand immDPacked()
4660 %{
4661 predicate(Assembler::operand_valid_for_float_immediate(n->getd()));
4662 match(ConD);
4663 op_cost(0);
4664 format %{ %}
4665 interface(CONST_INTER);
4666 %}
4667
4668 // Float Immediate
4669 operand immF()
4670 %{
4671 match(ConF);
4672 op_cost(0);
4673 format %{ %}
4674 interface(CONST_INTER);
4675 %}
4676
4677 // Float Immediate: +0.0f.
4678 operand immF0()
4679 %{
4680 predicate(jint_cast(n->getf()) == 0);
4681 match(ConF);
4682
4683 op_cost(0);
4684 format %{ %}
4685 interface(CONST_INTER);
4686 %}
4687
4688 // Half Float (FP16) Immediate
4689 operand immH()
4690 %{
4691 match(ConH);
4692 op_cost(0);
4693 format %{ %}
4694 interface(CONST_INTER);
4695 %}
4696
4697 //
4698 operand immFPacked()
4699 %{
4700 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf()));
4701 match(ConF);
4702 op_cost(0);
4703 format %{ %}
4704 interface(CONST_INTER);
4705 %}
4706
4707 // Narrow pointer operands
4708 // Narrow Pointer Immediate
4709 operand immN()
4710 %{
4711 match(ConN);
4712
4713 op_cost(0);
4714 format %{ %}
4715 interface(CONST_INTER);
4716 %}
4717
4718 // Narrow nullptr Pointer Immediate
4719 operand immN0()
4720 %{
4721 predicate(n->get_narrowcon() == 0);
4722 match(ConN);
4723
4724 op_cost(0);
4725 format %{ %}
4726 interface(CONST_INTER);
4727 %}
4728
4729 operand immNKlass()
4730 %{
4731 match(ConNKlass);
4732
4733 op_cost(0);
4734 format %{ %}
4735 interface(CONST_INTER);
4736 %}
4737
4738 // Integer 32 bit Register Operands
4739 // Integer 32 bitRegister (excludes SP)
4740 operand iRegI()
4741 %{
4742 constraint(ALLOC_IN_RC(any_reg32));
4743 match(RegI);
4744 match(iRegINoSp);
4745 op_cost(0);
4746 format %{ %}
4747 interface(REG_INTER);
4748 %}
4749
4750 // Integer 32 bit Register not Special
4751 operand iRegINoSp()
4752 %{
4753 constraint(ALLOC_IN_RC(no_special_reg32));
4754 match(RegI);
4755 op_cost(0);
4756 format %{ %}
4757 interface(REG_INTER);
4758 %}
4759
4760 // Integer 64 bit Register Operands
4761 // Integer 64 bit Register (includes SP)
4762 operand iRegL()
4763 %{
4764 constraint(ALLOC_IN_RC(any_reg));
4765 match(RegL);
4766 match(iRegLNoSp);
4767 op_cost(0);
4768 format %{ %}
4769 interface(REG_INTER);
4770 %}
4771
4772 // Integer 64 bit Register not Special
4773 operand iRegLNoSp()
4774 %{
4775 constraint(ALLOC_IN_RC(no_special_reg));
4776 match(RegL);
4777 match(iRegL_R0);
4778 format %{ %}
4779 interface(REG_INTER);
4780 %}
4781
4782 // Pointer Register Operands
4783 // Pointer Register
4784 operand iRegP()
4785 %{
4786 constraint(ALLOC_IN_RC(ptr_reg));
4787 match(RegP);
4788 match(iRegPNoSp);
4789 match(iRegP_R0);
4790 //match(iRegP_R2);
4791 //match(iRegP_R4);
4792 match(iRegP_R5);
4793 match(thread_RegP);
4794 op_cost(0);
4795 format %{ %}
4796 interface(REG_INTER);
4797 %}
4798
4799 // Pointer 64 bit Register not Special
4800 operand iRegPNoSp()
4801 %{
4802 constraint(ALLOC_IN_RC(no_special_ptr_reg));
4803 match(RegP);
4804 // match(iRegP);
4805 // match(iRegP_R0);
4806 // match(iRegP_R2);
4807 // match(iRegP_R4);
4808 // match(iRegP_R5);
4809 // match(thread_RegP);
4810 op_cost(0);
4811 format %{ %}
4812 interface(REG_INTER);
4813 %}
4814
4815 // This operand is not allowed to use rfp even if
4816 // rfp is not used to hold the frame pointer.
4817 operand iRegPNoSpNoRfp()
4818 %{
4819 constraint(ALLOC_IN_RC(no_special_no_rfp_ptr_reg));
4820 match(RegP);
4821 match(iRegPNoSp);
4822 op_cost(0);
4823 format %{ %}
4824 interface(REG_INTER);
4825 %}
4826
4827 // Pointer 64 bit Register R0 only
4828 operand iRegP_R0()
4829 %{
4830 constraint(ALLOC_IN_RC(r0_reg));
4831 match(RegP);
4832 // match(iRegP);
4833 match(iRegPNoSp);
4834 op_cost(0);
4835 format %{ %}
4836 interface(REG_INTER);
4837 %}
4838
4839 // Pointer 64 bit Register R1 only
4840 operand iRegP_R1()
4841 %{
4842 constraint(ALLOC_IN_RC(r1_reg));
4843 match(RegP);
4844 // match(iRegP);
4845 match(iRegPNoSp);
4846 op_cost(0);
4847 format %{ %}
4848 interface(REG_INTER);
4849 %}
4850
4851 // Pointer 64 bit Register R2 only
4852 operand iRegP_R2()
4853 %{
4854 constraint(ALLOC_IN_RC(r2_reg));
4855 match(RegP);
4856 // match(iRegP);
4857 match(iRegPNoSp);
4858 op_cost(0);
4859 format %{ %}
4860 interface(REG_INTER);
4861 %}
4862
4863 // Pointer 64 bit Register R3 only
4864 operand iRegP_R3()
4865 %{
4866 constraint(ALLOC_IN_RC(r3_reg));
4867 match(RegP);
4868 // match(iRegP);
4869 match(iRegPNoSp);
4870 op_cost(0);
4871 format %{ %}
4872 interface(REG_INTER);
4873 %}
4874
4875 // Pointer 64 bit Register R4 only
4876 operand iRegP_R4()
4877 %{
4878 constraint(ALLOC_IN_RC(r4_reg));
4879 match(RegP);
4880 // match(iRegP);
4881 match(iRegPNoSp);
4882 op_cost(0);
4883 format %{ %}
4884 interface(REG_INTER);
4885 %}
4886
4887 // Pointer 64 bit Register R5 only
4888 operand iRegP_R5()
4889 %{
4890 constraint(ALLOC_IN_RC(r5_reg));
4891 match(RegP);
4892 // match(iRegP);
4893 match(iRegPNoSp);
4894 op_cost(0);
4895 format %{ %}
4896 interface(REG_INTER);
4897 %}
4898
4899 // Pointer 64 bit Register R10 only
4900 operand iRegP_R10()
4901 %{
4902 constraint(ALLOC_IN_RC(r10_reg));
4903 match(RegP);
4904 // match(iRegP);
4905 match(iRegPNoSp);
4906 op_cost(0);
4907 format %{ %}
4908 interface(REG_INTER);
4909 %}
4910
4911 // Long 64 bit Register R0 only
4912 operand iRegL_R0()
4913 %{
4914 constraint(ALLOC_IN_RC(r0_reg));
4915 match(RegL);
4916 match(iRegLNoSp);
4917 op_cost(0);
4918 format %{ %}
4919 interface(REG_INTER);
4920 %}
4921
4922 // Long 64 bit Register R11 only
4923 operand iRegL_R11()
4924 %{
4925 constraint(ALLOC_IN_RC(r11_reg));
4926 match(RegL);
4927 match(iRegLNoSp);
4928 op_cost(0);
4929 format %{ %}
4930 interface(REG_INTER);
4931 %}
4932
4933 // Register R0 only
4934 operand iRegI_R0()
4935 %{
4936 constraint(ALLOC_IN_RC(int_r0_reg));
4937 match(RegI);
4938 match(iRegINoSp);
4939 op_cost(0);
4940 format %{ %}
4941 interface(REG_INTER);
4942 %}
4943
4944 // Register R2 only
4945 operand iRegI_R2()
4946 %{
4947 constraint(ALLOC_IN_RC(int_r2_reg));
4948 match(RegI);
4949 match(iRegINoSp);
4950 op_cost(0);
4951 format %{ %}
4952 interface(REG_INTER);
4953 %}
4954
4955 // Register R3 only
4956 operand iRegI_R3()
4957 %{
4958 constraint(ALLOC_IN_RC(int_r3_reg));
4959 match(RegI);
4960 match(iRegINoSp);
4961 op_cost(0);
4962 format %{ %}
4963 interface(REG_INTER);
4964 %}
4965
4966
4967 // Register R4 only
4968 operand iRegI_R4()
4969 %{
4970 constraint(ALLOC_IN_RC(int_r4_reg));
4971 match(RegI);
4972 match(iRegINoSp);
4973 op_cost(0);
4974 format %{ %}
4975 interface(REG_INTER);
4976 %}
4977
4978
4979 // Pointer Register Operands
4980 // Narrow Pointer Register
4981 operand iRegN()
4982 %{
4983 constraint(ALLOC_IN_RC(any_reg32));
4984 match(RegN);
4985 match(iRegNNoSp);
4986 op_cost(0);
4987 format %{ %}
4988 interface(REG_INTER);
4989 %}
4990
4991 // Integer 64 bit Register not Special
4992 operand iRegNNoSp()
4993 %{
4994 constraint(ALLOC_IN_RC(no_special_reg32));
4995 match(RegN);
4996 op_cost(0);
4997 format %{ %}
4998 interface(REG_INTER);
4999 %}
5000
5001 // Float Register
5002 // Float register operands
5003 operand vRegF()
5004 %{
5005 constraint(ALLOC_IN_RC(float_reg));
5006 match(RegF);
5007
5008 op_cost(0);
5009 format %{ %}
5010 interface(REG_INTER);
5011 %}
5012
5013 // Double Register
5014 // Double register operands
5015 operand vRegD()
5016 %{
5017 constraint(ALLOC_IN_RC(double_reg));
5018 match(RegD);
5019
5020 op_cost(0);
5021 format %{ %}
5022 interface(REG_INTER);
5023 %}
5024
5025 // Generic vector class. This will be used for
5026 // all vector operands, including NEON and SVE.
5027 operand vReg()
5028 %{
5029 constraint(ALLOC_IN_RC(dynamic));
5030 match(VecA);
5031 match(VecD);
5032 match(VecX);
5033
5034 op_cost(0);
5035 format %{ %}
5036 interface(REG_INTER);
5037 %}
5038
5039 operand vReg_V10()
5040 %{
5041 constraint(ALLOC_IN_RC(v10_veca_reg));
5042 match(vReg);
5043
5044 op_cost(0);
5045 format %{ %}
5046 interface(REG_INTER);
5047 %}
5048
5049 operand vReg_V11()
5050 %{
5051 constraint(ALLOC_IN_RC(v11_veca_reg));
5052 match(vReg);
5053
5054 op_cost(0);
5055 format %{ %}
5056 interface(REG_INTER);
5057 %}
5058
5059 operand vReg_V12()
5060 %{
5061 constraint(ALLOC_IN_RC(v12_veca_reg));
5062 match(vReg);
5063
5064 op_cost(0);
5065 format %{ %}
5066 interface(REG_INTER);
5067 %}
5068
5069 operand vReg_V13()
5070 %{
5071 constraint(ALLOC_IN_RC(v13_veca_reg));
5072 match(vReg);
5073
5074 op_cost(0);
5075 format %{ %}
5076 interface(REG_INTER);
5077 %}
5078
5079 operand vReg_V17()
5080 %{
5081 constraint(ALLOC_IN_RC(v17_veca_reg));
5082 match(vReg);
5083
5084 op_cost(0);
5085 format %{ %}
5086 interface(REG_INTER);
5087 %}
5088
5089 operand vReg_V18()
5090 %{
5091 constraint(ALLOC_IN_RC(v18_veca_reg));
5092 match(vReg);
5093
5094 op_cost(0);
5095 format %{ %}
5096 interface(REG_INTER);
5097 %}
5098
5099 operand vReg_V23()
5100 %{
5101 constraint(ALLOC_IN_RC(v23_veca_reg));
5102 match(vReg);
5103
5104 op_cost(0);
5105 format %{ %}
5106 interface(REG_INTER);
5107 %}
5108
5109 operand vReg_V24()
5110 %{
5111 constraint(ALLOC_IN_RC(v24_veca_reg));
5112 match(vReg);
5113
5114 op_cost(0);
5115 format %{ %}
5116 interface(REG_INTER);
5117 %}
5118
5119 operand vecA()
5120 %{
5121 constraint(ALLOC_IN_RC(vectora_reg));
5122 match(VecA);
5123
5124 op_cost(0);
5125 format %{ %}
5126 interface(REG_INTER);
5127 %}
5128
5129 operand vecD()
5130 %{
5131 constraint(ALLOC_IN_RC(vectord_reg));
5132 match(VecD);
5133
5134 op_cost(0);
5135 format %{ %}
5136 interface(REG_INTER);
5137 %}
5138
5139 operand vecX()
5140 %{
5141 constraint(ALLOC_IN_RC(vectorx_reg));
5142 match(VecX);
5143
5144 op_cost(0);
5145 format %{ %}
5146 interface(REG_INTER);
5147 %}
5148
5149 operand vRegD_V0()
5150 %{
5151 constraint(ALLOC_IN_RC(v0_reg));
5152 match(RegD);
5153 op_cost(0);
5154 format %{ %}
5155 interface(REG_INTER);
5156 %}
5157
5158 operand vRegD_V1()
5159 %{
5160 constraint(ALLOC_IN_RC(v1_reg));
5161 match(RegD);
5162 op_cost(0);
5163 format %{ %}
5164 interface(REG_INTER);
5165 %}
5166
5167 operand vRegD_V2()
5168 %{
5169 constraint(ALLOC_IN_RC(v2_reg));
5170 match(RegD);
5171 op_cost(0);
5172 format %{ %}
5173 interface(REG_INTER);
5174 %}
5175
5176 operand vRegD_V3()
5177 %{
5178 constraint(ALLOC_IN_RC(v3_reg));
5179 match(RegD);
5180 op_cost(0);
5181 format %{ %}
5182 interface(REG_INTER);
5183 %}
5184
5185 operand vRegD_V4()
5186 %{
5187 constraint(ALLOC_IN_RC(v4_reg));
5188 match(RegD);
5189 op_cost(0);
5190 format %{ %}
5191 interface(REG_INTER);
5192 %}
5193
5194 operand vRegD_V5()
5195 %{
5196 constraint(ALLOC_IN_RC(v5_reg));
5197 match(RegD);
5198 op_cost(0);
5199 format %{ %}
5200 interface(REG_INTER);
5201 %}
5202
5203 operand vRegD_V6()
5204 %{
5205 constraint(ALLOC_IN_RC(v6_reg));
5206 match(RegD);
5207 op_cost(0);
5208 format %{ %}
5209 interface(REG_INTER);
5210 %}
5211
5212 operand vRegD_V7()
5213 %{
5214 constraint(ALLOC_IN_RC(v7_reg));
5215 match(RegD);
5216 op_cost(0);
5217 format %{ %}
5218 interface(REG_INTER);
5219 %}
5220
5221 operand vRegD_V12()
5222 %{
5223 constraint(ALLOC_IN_RC(v12_reg));
5224 match(RegD);
5225 op_cost(0);
5226 format %{ %}
5227 interface(REG_INTER);
5228 %}
5229
5230 operand vRegD_V13()
5231 %{
5232 constraint(ALLOC_IN_RC(v13_reg));
5233 match(RegD);
5234 op_cost(0);
5235 format %{ %}
5236 interface(REG_INTER);
5237 %}
5238
5239 operand pReg()
5240 %{
5241 constraint(ALLOC_IN_RC(pr_reg));
5242 match(RegVectMask);
5243 match(pRegGov);
5244 op_cost(0);
5245 format %{ %}
5246 interface(REG_INTER);
5247 %}
5248
5249 operand pRegGov()
5250 %{
5251 constraint(ALLOC_IN_RC(gov_pr));
5252 match(RegVectMask);
5253 match(pReg);
5254 op_cost(0);
5255 format %{ %}
5256 interface(REG_INTER);
5257 %}
5258
5259 operand pRegGov_P0()
5260 %{
5261 constraint(ALLOC_IN_RC(p0_reg));
5262 match(RegVectMask);
5263 op_cost(0);
5264 format %{ %}
5265 interface(REG_INTER);
5266 %}
5267
5268 operand pRegGov_P1()
5269 %{
5270 constraint(ALLOC_IN_RC(p1_reg));
5271 match(RegVectMask);
5272 op_cost(0);
5273 format %{ %}
5274 interface(REG_INTER);
5275 %}
5276
5277 // Flags register, used as output of signed compare instructions
5278
5279 // note that on AArch64 we also use this register as the output for
5280 // for floating point compare instructions (CmpF CmpD). this ensures
5281 // that ordered inequality tests use GT, GE, LT or LE none of which
5282 // pass through cases where the result is unordered i.e. one or both
5283 // inputs to the compare is a NaN. this means that the ideal code can
5284 // replace e.g. a GT with an LE and not end up capturing the NaN case
5285 // (where the comparison should always fail). EQ and NE tests are
5286 // always generated in ideal code so that unordered folds into the NE
5287 // case, matching the behaviour of AArch64 NE.
5288 //
5289 // This differs from x86 where the outputs of FP compares use a
5290 // special FP flags registers and where compares based on this
5291 // register are distinguished into ordered inequalities (cmpOpUCF) and
5292 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests
5293 // to explicitly handle the unordered case in branches. x86 also has
5294 // to include extra CMoveX rules to accept a cmpOpUCF input.
5295
5296 operand rFlagsReg()
5297 %{
5298 constraint(ALLOC_IN_RC(int_flags));
5299 match(RegFlags);
5300
5301 op_cost(0);
5302 format %{ "RFLAGS" %}
5303 interface(REG_INTER);
5304 %}
5305
5306 // Flags register, used as output of unsigned compare instructions
5307 operand rFlagsRegU()
5308 %{
5309 constraint(ALLOC_IN_RC(int_flags));
5310 match(RegFlags);
5311
5312 op_cost(0);
5313 format %{ "RFLAGSU" %}
5314 interface(REG_INTER);
5315 %}
5316
5317 // Special Registers
5318
5319 // Method Register
5320 operand inline_cache_RegP(iRegP reg)
5321 %{
5322 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg
5323 match(reg);
5324 match(iRegPNoSp);
5325 op_cost(0);
5326 format %{ %}
5327 interface(REG_INTER);
5328 %}
5329
5330 // Thread Register
5331 operand thread_RegP(iRegP reg)
5332 %{
5333 constraint(ALLOC_IN_RC(thread_reg)); // link_reg
5334 match(reg);
5335 op_cost(0);
5336 format %{ %}
5337 interface(REG_INTER);
5338 %}
5339
5340 //----------Memory Operands----------------------------------------------------
5341
5342 operand indirect(iRegP reg)
5343 %{
5344 constraint(ALLOC_IN_RC(ptr_reg));
5345 match(reg);
5346 op_cost(0);
5347 format %{ "[$reg]" %}
5348 interface(MEMORY_INTER) %{
5349 base($reg);
5350 index(0xffffffff);
5351 scale(0x0);
5352 disp(0x0);
5353 %}
5354 %}
5355
5356 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale)
5357 %{
5358 constraint(ALLOC_IN_RC(ptr_reg));
5359 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5360 match(AddP reg (LShiftL (ConvI2L ireg) scale));
5361 op_cost(0);
5362 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %}
5363 interface(MEMORY_INTER) %{
5364 base($reg);
5365 index($ireg);
5366 scale($scale);
5367 disp(0x0);
5368 %}
5369 %}
5370
5371 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale)
5372 %{
5373 constraint(ALLOC_IN_RC(ptr_reg));
5374 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5375 match(AddP reg (LShiftL lreg scale));
5376 op_cost(0);
5377 format %{ "$reg, $lreg lsl($scale)" %}
5378 interface(MEMORY_INTER) %{
5379 base($reg);
5380 index($lreg);
5381 scale($scale);
5382 disp(0x0);
5383 %}
5384 %}
5385
5386 operand indIndexI2L(iRegP reg, iRegI ireg)
5387 %{
5388 constraint(ALLOC_IN_RC(ptr_reg));
5389 match(AddP reg (ConvI2L ireg));
5390 op_cost(0);
5391 format %{ "$reg, $ireg, 0, I2L" %}
5392 interface(MEMORY_INTER) %{
5393 base($reg);
5394 index($ireg);
5395 scale(0x0);
5396 disp(0x0);
5397 %}
5398 %}
5399
5400 operand indIndex(iRegP reg, iRegL lreg)
5401 %{
5402 constraint(ALLOC_IN_RC(ptr_reg));
5403 match(AddP reg lreg);
5404 op_cost(0);
5405 format %{ "$reg, $lreg" %}
5406 interface(MEMORY_INTER) %{
5407 base($reg);
5408 index($lreg);
5409 scale(0x0);
5410 disp(0x0);
5411 %}
5412 %}
5413
5414 operand indOffI1(iRegP reg, immIOffset1 off)
5415 %{
5416 constraint(ALLOC_IN_RC(ptr_reg));
5417 match(AddP reg off);
5418 op_cost(0);
5419 format %{ "[$reg, $off]" %}
5420 interface(MEMORY_INTER) %{
5421 base($reg);
5422 index(0xffffffff);
5423 scale(0x0);
5424 disp($off);
5425 %}
5426 %}
5427
5428 operand indOffI2(iRegP reg, immIOffset2 off)
5429 %{
5430 constraint(ALLOC_IN_RC(ptr_reg));
5431 match(AddP reg off);
5432 op_cost(0);
5433 format %{ "[$reg, $off]" %}
5434 interface(MEMORY_INTER) %{
5435 base($reg);
5436 index(0xffffffff);
5437 scale(0x0);
5438 disp($off);
5439 %}
5440 %}
5441
5442 operand indOffI4(iRegP reg, immIOffset4 off)
5443 %{
5444 constraint(ALLOC_IN_RC(ptr_reg));
5445 match(AddP reg off);
5446 op_cost(0);
5447 format %{ "[$reg, $off]" %}
5448 interface(MEMORY_INTER) %{
5449 base($reg);
5450 index(0xffffffff);
5451 scale(0x0);
5452 disp($off);
5453 %}
5454 %}
5455
5456 operand indOffI8(iRegP reg, immIOffset8 off)
5457 %{
5458 constraint(ALLOC_IN_RC(ptr_reg));
5459 match(AddP reg off);
5460 op_cost(0);
5461 format %{ "[$reg, $off]" %}
5462 interface(MEMORY_INTER) %{
5463 base($reg);
5464 index(0xffffffff);
5465 scale(0x0);
5466 disp($off);
5467 %}
5468 %}
5469
5470 operand indOffI16(iRegP reg, immIOffset16 off)
5471 %{
5472 constraint(ALLOC_IN_RC(ptr_reg));
5473 match(AddP reg off);
5474 op_cost(0);
5475 format %{ "[$reg, $off]" %}
5476 interface(MEMORY_INTER) %{
5477 base($reg);
5478 index(0xffffffff);
5479 scale(0x0);
5480 disp($off);
5481 %}
5482 %}
5483
5484 operand indOffL1(iRegP reg, immLoffset1 off)
5485 %{
5486 constraint(ALLOC_IN_RC(ptr_reg));
5487 match(AddP reg off);
5488 op_cost(0);
5489 format %{ "[$reg, $off]" %}
5490 interface(MEMORY_INTER) %{
5491 base($reg);
5492 index(0xffffffff);
5493 scale(0x0);
5494 disp($off);
5495 %}
5496 %}
5497
5498 operand indOffL2(iRegP reg, immLoffset2 off)
5499 %{
5500 constraint(ALLOC_IN_RC(ptr_reg));
5501 match(AddP reg off);
5502 op_cost(0);
5503 format %{ "[$reg, $off]" %}
5504 interface(MEMORY_INTER) %{
5505 base($reg);
5506 index(0xffffffff);
5507 scale(0x0);
5508 disp($off);
5509 %}
5510 %}
5511
5512 operand indOffL4(iRegP reg, immLoffset4 off)
5513 %{
5514 constraint(ALLOC_IN_RC(ptr_reg));
5515 match(AddP reg off);
5516 op_cost(0);
5517 format %{ "[$reg, $off]" %}
5518 interface(MEMORY_INTER) %{
5519 base($reg);
5520 index(0xffffffff);
5521 scale(0x0);
5522 disp($off);
5523 %}
5524 %}
5525
5526 operand indOffL8(iRegP reg, immLoffset8 off)
5527 %{
5528 constraint(ALLOC_IN_RC(ptr_reg));
5529 match(AddP reg off);
5530 op_cost(0);
5531 format %{ "[$reg, $off]" %}
5532 interface(MEMORY_INTER) %{
5533 base($reg);
5534 index(0xffffffff);
5535 scale(0x0);
5536 disp($off);
5537 %}
5538 %}
5539
5540 operand indOffL16(iRegP reg, immLoffset16 off)
5541 %{
5542 constraint(ALLOC_IN_RC(ptr_reg));
5543 match(AddP reg off);
5544 op_cost(0);
5545 format %{ "[$reg, $off]" %}
5546 interface(MEMORY_INTER) %{
5547 base($reg);
5548 index(0xffffffff);
5549 scale(0x0);
5550 disp($off);
5551 %}
5552 %}
5553
5554 operand indirectX2P(iRegL reg)
5555 %{
5556 constraint(ALLOC_IN_RC(ptr_reg));
5557 match(CastX2P reg);
5558 op_cost(0);
5559 format %{ "[$reg]\t# long -> ptr" %}
5560 interface(MEMORY_INTER) %{
5561 base($reg);
5562 index(0xffffffff);
5563 scale(0x0);
5564 disp(0x0);
5565 %}
5566 %}
5567
5568 operand indOffX2P(iRegL reg, immLOffset off)
5569 %{
5570 constraint(ALLOC_IN_RC(ptr_reg));
5571 match(AddP (CastX2P reg) off);
5572 op_cost(0);
5573 format %{ "[$reg, $off]\t# long -> ptr" %}
5574 interface(MEMORY_INTER) %{
5575 base($reg);
5576 index(0xffffffff);
5577 scale(0x0);
5578 disp($off);
5579 %}
5580 %}
5581
5582 operand indirectN(iRegN reg)
5583 %{
5584 predicate(CompressedOops::shift() == 0);
5585 constraint(ALLOC_IN_RC(ptr_reg));
5586 match(DecodeN reg);
5587 op_cost(0);
5588 format %{ "[$reg]\t# narrow" %}
5589 interface(MEMORY_INTER) %{
5590 base($reg);
5591 index(0xffffffff);
5592 scale(0x0);
5593 disp(0x0);
5594 %}
5595 %}
5596
5597 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale)
5598 %{
5599 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5600 constraint(ALLOC_IN_RC(ptr_reg));
5601 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale));
5602 op_cost(0);
5603 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %}
5604 interface(MEMORY_INTER) %{
5605 base($reg);
5606 index($ireg);
5607 scale($scale);
5608 disp(0x0);
5609 %}
5610 %}
5611
5612 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale)
5613 %{
5614 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5615 constraint(ALLOC_IN_RC(ptr_reg));
5616 match(AddP (DecodeN reg) (LShiftL lreg scale));
5617 op_cost(0);
5618 format %{ "$reg, $lreg lsl($scale)\t# narrow" %}
5619 interface(MEMORY_INTER) %{
5620 base($reg);
5621 index($lreg);
5622 scale($scale);
5623 disp(0x0);
5624 %}
5625 %}
5626
5627 operand indIndexI2LN(iRegN reg, iRegI ireg)
5628 %{
5629 predicate(CompressedOops::shift() == 0);
5630 constraint(ALLOC_IN_RC(ptr_reg));
5631 match(AddP (DecodeN reg) (ConvI2L ireg));
5632 op_cost(0);
5633 format %{ "$reg, $ireg, 0, I2L\t# narrow" %}
5634 interface(MEMORY_INTER) %{
5635 base($reg);
5636 index($ireg);
5637 scale(0x0);
5638 disp(0x0);
5639 %}
5640 %}
5641
5642 operand indIndexN(iRegN reg, iRegL lreg)
5643 %{
5644 predicate(CompressedOops::shift() == 0);
5645 constraint(ALLOC_IN_RC(ptr_reg));
5646 match(AddP (DecodeN reg) lreg);
5647 op_cost(0);
5648 format %{ "$reg, $lreg\t# narrow" %}
5649 interface(MEMORY_INTER) %{
5650 base($reg);
5651 index($lreg);
5652 scale(0x0);
5653 disp(0x0);
5654 %}
5655 %}
5656
5657 operand indOffIN(iRegN reg, immIOffset off)
5658 %{
5659 predicate(CompressedOops::shift() == 0);
5660 constraint(ALLOC_IN_RC(ptr_reg));
5661 match(AddP (DecodeN reg) off);
5662 op_cost(0);
5663 format %{ "[$reg, $off]\t# narrow" %}
5664 interface(MEMORY_INTER) %{
5665 base($reg);
5666 index(0xffffffff);
5667 scale(0x0);
5668 disp($off);
5669 %}
5670 %}
5671
5672 operand indOffLN(iRegN reg, immLOffset off)
5673 %{
5674 predicate(CompressedOops::shift() == 0);
5675 constraint(ALLOC_IN_RC(ptr_reg));
5676 match(AddP (DecodeN reg) off);
5677 op_cost(0);
5678 format %{ "[$reg, $off]\t# narrow" %}
5679 interface(MEMORY_INTER) %{
5680 base($reg);
5681 index(0xffffffff);
5682 scale(0x0);
5683 disp($off);
5684 %}
5685 %}
5686
5687
5688 //----------Special Memory Operands--------------------------------------------
5689 // Stack Slot Operand - This operand is used for loading and storing temporary
5690 // values on the stack where a match requires a value to
5691 // flow through memory.
5692 operand stackSlotP(sRegP reg)
5693 %{
5694 constraint(ALLOC_IN_RC(stack_slots));
5695 op_cost(100);
5696 // No match rule because this operand is only generated in matching
5697 // match(RegP);
5698 format %{ "[$reg]" %}
5699 interface(MEMORY_INTER) %{
5700 base(0x1e); // RSP
5701 index(0x0); // No Index
5702 scale(0x0); // No Scale
5703 disp($reg); // Stack Offset
5704 %}
5705 %}
5706
5707 operand stackSlotI(sRegI reg)
5708 %{
5709 constraint(ALLOC_IN_RC(stack_slots));
5710 // No match rule because this operand is only generated in matching
5711 // match(RegI);
5712 format %{ "[$reg]" %}
5713 interface(MEMORY_INTER) %{
5714 base(0x1e); // RSP
5715 index(0x0); // No Index
5716 scale(0x0); // No Scale
5717 disp($reg); // Stack Offset
5718 %}
5719 %}
5720
5721 operand stackSlotF(sRegF reg)
5722 %{
5723 constraint(ALLOC_IN_RC(stack_slots));
5724 // No match rule because this operand is only generated in matching
5725 // match(RegF);
5726 format %{ "[$reg]" %}
5727 interface(MEMORY_INTER) %{
5728 base(0x1e); // RSP
5729 index(0x0); // No Index
5730 scale(0x0); // No Scale
5731 disp($reg); // Stack Offset
5732 %}
5733 %}
5734
5735 operand stackSlotD(sRegD reg)
5736 %{
5737 constraint(ALLOC_IN_RC(stack_slots));
5738 // No match rule because this operand is only generated in matching
5739 // match(RegD);
5740 format %{ "[$reg]" %}
5741 interface(MEMORY_INTER) %{
5742 base(0x1e); // RSP
5743 index(0x0); // No Index
5744 scale(0x0); // No Scale
5745 disp($reg); // Stack Offset
5746 %}
5747 %}
5748
5749 operand stackSlotL(sRegL reg)
5750 %{
5751 constraint(ALLOC_IN_RC(stack_slots));
5752 // No match rule because this operand is only generated in matching
5753 // match(RegL);
5754 format %{ "[$reg]" %}
5755 interface(MEMORY_INTER) %{
5756 base(0x1e); // RSP
5757 index(0x0); // No Index
5758 scale(0x0); // No Scale
5759 disp($reg); // Stack Offset
5760 %}
5761 %}
5762
5763 // Operands for expressing Control Flow
5764 // NOTE: Label is a predefined operand which should not be redefined in
5765 // the AD file. It is generically handled within the ADLC.
5766
5767 //----------Conditional Branch Operands----------------------------------------
5768 // Comparison Op - This is the operation of the comparison, and is limited to
5769 // the following set of codes:
5770 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5771 //
5772 // Other attributes of the comparison, such as unsignedness, are specified
5773 // by the comparison instruction that sets a condition code flags register.
5774 // That result is represented by a flags operand whose subtype is appropriate
5775 // to the unsignedness (etc.) of the comparison.
5776 //
5777 // Later, the instruction which matches both the Comparison Op (a Bool) and
5778 // the flags (produced by the Cmp) specifies the coding of the comparison op
5779 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5780
5781 // used for signed integral comparisons and fp comparisons
5782
5783 operand cmpOp()
5784 %{
5785 match(Bool);
5786
5787 format %{ "" %}
5788 interface(COND_INTER) %{
5789 equal(0x0, "eq");
5790 not_equal(0x1, "ne");
5791 less(0xb, "lt");
5792 greater_equal(0xa, "ge");
5793 less_equal(0xd, "le");
5794 greater(0xc, "gt");
5795 overflow(0x6, "vs");
5796 no_overflow(0x7, "vc");
5797 %}
5798 %}
5799
5800 // used for unsigned integral comparisons
5801
5802 operand cmpOpU()
5803 %{
5804 match(Bool);
5805
5806 format %{ "" %}
5807 interface(COND_INTER) %{
5808 equal(0x0, "eq");
5809 not_equal(0x1, "ne");
5810 less(0x3, "lo");
5811 greater_equal(0x2, "hs");
5812 less_equal(0x9, "ls");
5813 greater(0x8, "hi");
5814 overflow(0x6, "vs");
5815 no_overflow(0x7, "vc");
5816 %}
5817 %}
5818
5819 // used for certain integral comparisons which can be
5820 // converted to cbxx or tbxx instructions
5821
5822 operand cmpOpEqNe()
5823 %{
5824 match(Bool);
5825 op_cost(0);
5826 predicate(n->as_Bool()->_test._test == BoolTest::ne
5827 || n->as_Bool()->_test._test == BoolTest::eq);
5828
5829 format %{ "" %}
5830 interface(COND_INTER) %{
5831 equal(0x0, "eq");
5832 not_equal(0x1, "ne");
5833 less(0xb, "lt");
5834 greater_equal(0xa, "ge");
5835 less_equal(0xd, "le");
5836 greater(0xc, "gt");
5837 overflow(0x6, "vs");
5838 no_overflow(0x7, "vc");
5839 %}
5840 %}
5841
5842 // used for certain integral comparisons which can be
5843 // converted to cbxx or tbxx instructions
5844
5845 operand cmpOpLtGe()
5846 %{
5847 match(Bool);
5848 op_cost(0);
5849
5850 predicate(n->as_Bool()->_test._test == BoolTest::lt
5851 || n->as_Bool()->_test._test == BoolTest::ge);
5852
5853 format %{ "" %}
5854 interface(COND_INTER) %{
5855 equal(0x0, "eq");
5856 not_equal(0x1, "ne");
5857 less(0xb, "lt");
5858 greater_equal(0xa, "ge");
5859 less_equal(0xd, "le");
5860 greater(0xc, "gt");
5861 overflow(0x6, "vs");
5862 no_overflow(0x7, "vc");
5863 %}
5864 %}
5865
5866 // used for certain unsigned integral comparisons which can be
5867 // converted to cbxx or tbxx instructions
5868
5869 operand cmpOpUEqNeLeGt()
5870 %{
5871 match(Bool);
5872 op_cost(0);
5873
5874 predicate(n->as_Bool()->_test._test == BoolTest::eq ||
5875 n->as_Bool()->_test._test == BoolTest::ne ||
5876 n->as_Bool()->_test._test == BoolTest::le ||
5877 n->as_Bool()->_test._test == BoolTest::gt);
5878
5879 format %{ "" %}
5880 interface(COND_INTER) %{
5881 equal(0x0, "eq");
5882 not_equal(0x1, "ne");
5883 less(0x3, "lo");
5884 greater_equal(0x2, "hs");
5885 less_equal(0x9, "ls");
5886 greater(0x8, "hi");
5887 overflow(0x6, "vs");
5888 no_overflow(0x7, "vc");
5889 %}
5890 %}
5891
5892 // Special operand allowing long args to int ops to be truncated for free
5893
5894 operand iRegL2I(iRegL reg) %{
5895
5896 op_cost(0);
5897
5898 match(ConvL2I reg);
5899
5900 format %{ "l2i($reg)" %}
5901
5902 interface(REG_INTER)
5903 %}
5904
5905 operand iRegL2P(iRegL reg) %{
5906
5907 op_cost(0);
5908
5909 match(CastX2P reg);
5910
5911 format %{ "l2p($reg)" %}
5912
5913 interface(REG_INTER)
5914 %}
5915
5916 opclass vmem2(indirect, indIndex, indOffI2, indOffL2);
5917 opclass vmem4(indirect, indIndex, indOffI4, indOffL4);
5918 opclass vmem8(indirect, indIndex, indOffI8, indOffL8);
5919 opclass vmem16(indirect, indIndex, indOffI16, indOffL16);
5920
5921 //----------OPERAND CLASSES----------------------------------------------------
5922 // Operand Classes are groups of operands that are used as to simplify
5923 // instruction definitions by not requiring the AD writer to specify
5924 // separate instructions for every form of operand when the
5925 // instruction accepts multiple operand types with the same basic
5926 // encoding and format. The classic case of this is memory operands.
5927
5928 // memory is used to define read/write location for load/store
5929 // instruction defs. we can turn a memory op into an Address
5930
5931 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
5932 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5933
5934 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
5935 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indirectX2P, indOffX2P);
5936
5937 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
5938 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5939
5940 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
5941 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5942
5943 // All of the memory operands. For the pipeline description.
5944 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
5945 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
5946 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P);
5947
5948
5949 // iRegIorL2I is used for src inputs in rules for 32 bit int (I)
5950 // operations. it allows the src to be either an iRegI or a (ConvL2I
5951 // iRegL). in the latter case the l2i normally planted for a ConvL2I
5952 // can be elided because the 32-bit instruction will just employ the
5953 // lower 32 bits anyway.
5954 //
5955 // n.b. this does not elide all L2I conversions. if the truncated
5956 // value is consumed by more than one operation then the ConvL2I
5957 // cannot be bundled into the consuming nodes so an l2i gets planted
5958 // (actually a movw $dst $src) and the downstream instructions consume
5959 // the result of the l2i as an iRegI input. That's a shame since the
5960 // movw is actually redundant but its not too costly.
5961
5962 opclass iRegIorL2I(iRegI, iRegL2I);
5963 opclass iRegPorL2P(iRegP, iRegL2P);
5964
5965 //----------PIPELINE-----------------------------------------------------------
5966 // Rules which define the behavior of the target architectures pipeline.
5967
5968 // For specific pipelines, eg A53, define the stages of that pipeline
5969 //pipe_desc(ISS, EX1, EX2, WR);
5970 #define ISS S0
5971 #define EX1 S1
5972 #define EX2 S2
5973 #define WR S3
5974
5975 // Integer ALU reg operation
5976 pipeline %{
5977
5978 attributes %{
5979 // ARM instructions are of fixed length
5980 fixed_size_instructions; // Fixed size instructions TODO does
5981 max_instructions_per_bundle = 4; // A53 = 2, A57 = 4
5982 // ARM instructions come in 32-bit word units
5983 instruction_unit_size = 4; // An instruction is 4 bytes long
5984 instruction_fetch_unit_size = 64; // The processor fetches one line
5985 instruction_fetch_units = 1; // of 64 bytes
5986 %}
5987
5988 // We don't use an actual pipeline model so don't care about resources
5989 // or description. we do use pipeline classes to introduce fixed
5990 // latencies
5991
5992 //----------RESOURCES----------------------------------------------------------
5993 // Resources are the functional units available to the machine
5994
5995 resources( INS0, INS1, INS01 = INS0 | INS1,
5996 ALU0, ALU1, ALU = ALU0 | ALU1,
5997 MAC,
5998 DIV,
5999 BRANCH,
6000 LDST,
6001 NEON_FP);
6002
6003 //----------PIPELINE DESCRIPTION-----------------------------------------------
6004 // Pipeline Description specifies the stages in the machine's pipeline
6005
6006 // Define the pipeline as a generic 6 stage pipeline
6007 pipe_desc(S0, S1, S2, S3, S4, S5);
6008
6009 //----------PIPELINE CLASSES---------------------------------------------------
6010 // Pipeline Classes describe the stages in which input and output are
6011 // referenced by the hardware pipeline.
6012
6013 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2)
6014 %{
6015 single_instruction;
6016 src1 : S1(read);
6017 src2 : S2(read);
6018 dst : S5(write);
6019 INS01 : ISS;
6020 NEON_FP : S5;
6021 %}
6022
6023 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2)
6024 %{
6025 single_instruction;
6026 src1 : S1(read);
6027 src2 : S2(read);
6028 dst : S5(write);
6029 INS01 : ISS;
6030 NEON_FP : S5;
6031 %}
6032
6033 pipe_class fp_uop_s(vRegF dst, vRegF src)
6034 %{
6035 single_instruction;
6036 src : S1(read);
6037 dst : S5(write);
6038 INS01 : ISS;
6039 NEON_FP : S5;
6040 %}
6041
6042 pipe_class fp_uop_d(vRegD dst, vRegD src)
6043 %{
6044 single_instruction;
6045 src : S1(read);
6046 dst : S5(write);
6047 INS01 : ISS;
6048 NEON_FP : S5;
6049 %}
6050
6051 pipe_class fp_d2f(vRegF dst, vRegD src)
6052 %{
6053 single_instruction;
6054 src : S1(read);
6055 dst : S5(write);
6056 INS01 : ISS;
6057 NEON_FP : S5;
6058 %}
6059
6060 pipe_class fp_f2d(vRegD dst, vRegF src)
6061 %{
6062 single_instruction;
6063 src : S1(read);
6064 dst : S5(write);
6065 INS01 : ISS;
6066 NEON_FP : S5;
6067 %}
6068
6069 pipe_class fp_f2i(iRegINoSp dst, vRegF src)
6070 %{
6071 single_instruction;
6072 src : S1(read);
6073 dst : S5(write);
6074 INS01 : ISS;
6075 NEON_FP : S5;
6076 %}
6077
6078 pipe_class fp_f2l(iRegLNoSp dst, vRegF src)
6079 %{
6080 single_instruction;
6081 src : S1(read);
6082 dst : S5(write);
6083 INS01 : ISS;
6084 NEON_FP : S5;
6085 %}
6086
6087 pipe_class fp_i2f(vRegF dst, iRegIorL2I src)
6088 %{
6089 single_instruction;
6090 src : S1(read);
6091 dst : S5(write);
6092 INS01 : ISS;
6093 NEON_FP : S5;
6094 %}
6095
6096 pipe_class fp_l2f(vRegF dst, iRegL src)
6097 %{
6098 single_instruction;
6099 src : S1(read);
6100 dst : S5(write);
6101 INS01 : ISS;
6102 NEON_FP : S5;
6103 %}
6104
6105 pipe_class fp_d2i(iRegINoSp dst, vRegD src)
6106 %{
6107 single_instruction;
6108 src : S1(read);
6109 dst : S5(write);
6110 INS01 : ISS;
6111 NEON_FP : S5;
6112 %}
6113
6114 pipe_class fp_d2l(iRegLNoSp dst, vRegD src)
6115 %{
6116 single_instruction;
6117 src : S1(read);
6118 dst : S5(write);
6119 INS01 : ISS;
6120 NEON_FP : S5;
6121 %}
6122
6123 pipe_class fp_i2d(vRegD dst, iRegIorL2I src)
6124 %{
6125 single_instruction;
6126 src : S1(read);
6127 dst : S5(write);
6128 INS01 : ISS;
6129 NEON_FP : S5;
6130 %}
6131
6132 pipe_class fp_l2d(vRegD dst, iRegIorL2I src)
6133 %{
6134 single_instruction;
6135 src : S1(read);
6136 dst : S5(write);
6137 INS01 : ISS;
6138 NEON_FP : S5;
6139 %}
6140
6141 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2)
6142 %{
6143 single_instruction;
6144 src1 : S1(read);
6145 src2 : S2(read);
6146 dst : S5(write);
6147 INS0 : ISS;
6148 NEON_FP : S5;
6149 %}
6150
6151 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2)
6152 %{
6153 single_instruction;
6154 src1 : S1(read);
6155 src2 : S2(read);
6156 dst : S5(write);
6157 INS0 : ISS;
6158 NEON_FP : S5;
6159 %}
6160
6161 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr)
6162 %{
6163 single_instruction;
6164 cr : S1(read);
6165 src1 : S1(read);
6166 src2 : S1(read);
6167 dst : S3(write);
6168 INS01 : ISS;
6169 NEON_FP : S3;
6170 %}
6171
6172 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr)
6173 %{
6174 single_instruction;
6175 cr : S1(read);
6176 src1 : S1(read);
6177 src2 : S1(read);
6178 dst : S3(write);
6179 INS01 : ISS;
6180 NEON_FP : S3;
6181 %}
6182
6183 pipe_class fp_imm_s(vRegF dst)
6184 %{
6185 single_instruction;
6186 dst : S3(write);
6187 INS01 : ISS;
6188 NEON_FP : S3;
6189 %}
6190
6191 pipe_class fp_imm_d(vRegD dst)
6192 %{
6193 single_instruction;
6194 dst : S3(write);
6195 INS01 : ISS;
6196 NEON_FP : S3;
6197 %}
6198
6199 pipe_class fp_load_constant_s(vRegF dst)
6200 %{
6201 single_instruction;
6202 dst : S4(write);
6203 INS01 : ISS;
6204 NEON_FP : S4;
6205 %}
6206
6207 pipe_class fp_load_constant_d(vRegD dst)
6208 %{
6209 single_instruction;
6210 dst : S4(write);
6211 INS01 : ISS;
6212 NEON_FP : S4;
6213 %}
6214
6215 //------- Integer ALU operations --------------------------
6216
6217 // Integer ALU reg-reg operation
6218 // Operands needed in EX1, result generated in EX2
6219 // Eg. ADD x0, x1, x2
6220 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6221 %{
6222 single_instruction;
6223 dst : EX2(write);
6224 src1 : EX1(read);
6225 src2 : EX1(read);
6226 INS01 : ISS; // Dual issue as instruction 0 or 1
6227 ALU : EX2;
6228 %}
6229
6230 // Integer ALU reg-reg operation with constant shift
6231 // Shifted register must be available in LATE_ISS instead of EX1
6232 // Eg. ADD x0, x1, x2, LSL #2
6233 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift)
6234 %{
6235 single_instruction;
6236 dst : EX2(write);
6237 src1 : EX1(read);
6238 src2 : ISS(read);
6239 INS01 : ISS;
6240 ALU : EX2;
6241 %}
6242
6243 // Integer ALU reg operation with constant shift
6244 // Eg. LSL x0, x1, #shift
6245 pipe_class ialu_reg_shift(iRegI dst, iRegI src1)
6246 %{
6247 single_instruction;
6248 dst : EX2(write);
6249 src1 : ISS(read);
6250 INS01 : ISS;
6251 ALU : EX2;
6252 %}
6253
6254 // Integer ALU reg-reg operation with variable shift
6255 // Both operands must be available in LATE_ISS instead of EX1
6256 // Result is available in EX1 instead of EX2
6257 // Eg. LSLV x0, x1, x2
6258 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2)
6259 %{
6260 single_instruction;
6261 dst : EX1(write);
6262 src1 : ISS(read);
6263 src2 : ISS(read);
6264 INS01 : ISS;
6265 ALU : EX1;
6266 %}
6267
6268 // Integer ALU reg-reg operation with extract
6269 // As for _vshift above, but result generated in EX2
6270 // Eg. EXTR x0, x1, x2, #N
6271 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2)
6272 %{
6273 single_instruction;
6274 dst : EX2(write);
6275 src1 : ISS(read);
6276 src2 : ISS(read);
6277 INS1 : ISS; // Can only dual issue as Instruction 1
6278 ALU : EX1;
6279 %}
6280
6281 // Integer ALU reg operation
6282 // Eg. NEG x0, x1
6283 pipe_class ialu_reg(iRegI dst, iRegI src)
6284 %{
6285 single_instruction;
6286 dst : EX2(write);
6287 src : EX1(read);
6288 INS01 : ISS;
6289 ALU : EX2;
6290 %}
6291
6292 // Integer ALU reg mmediate operation
6293 // Eg. ADD x0, x1, #N
6294 pipe_class ialu_reg_imm(iRegI dst, iRegI src1)
6295 %{
6296 single_instruction;
6297 dst : EX2(write);
6298 src1 : EX1(read);
6299 INS01 : ISS;
6300 ALU : EX2;
6301 %}
6302
6303 // Integer ALU immediate operation (no source operands)
6304 // Eg. MOV x0, #N
6305 pipe_class ialu_imm(iRegI dst)
6306 %{
6307 single_instruction;
6308 dst : EX1(write);
6309 INS01 : ISS;
6310 ALU : EX1;
6311 %}
6312
6313 //------- Compare operation -------------------------------
6314
6315 // Compare reg-reg
6316 // Eg. CMP x0, x1
6317 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
6318 %{
6319 single_instruction;
6320 // fixed_latency(16);
6321 cr : EX2(write);
6322 op1 : EX1(read);
6323 op2 : EX1(read);
6324 INS01 : ISS;
6325 ALU : EX2;
6326 %}
6327
6328 // Compare reg-reg
6329 // Eg. CMP x0, #N
6330 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1)
6331 %{
6332 single_instruction;
6333 // fixed_latency(16);
6334 cr : EX2(write);
6335 op1 : EX1(read);
6336 INS01 : ISS;
6337 ALU : EX2;
6338 %}
6339
6340 //------- Conditional instructions ------------------------
6341
6342 // Conditional no operands
6343 // Eg. CSINC x0, zr, zr, <cond>
6344 pipe_class icond_none(iRegI dst, rFlagsReg cr)
6345 %{
6346 single_instruction;
6347 cr : EX1(read);
6348 dst : EX2(write);
6349 INS01 : ISS;
6350 ALU : EX2;
6351 %}
6352
6353 // Conditional 2 operand
6354 // EG. CSEL X0, X1, X2, <cond>
6355 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr)
6356 %{
6357 single_instruction;
6358 cr : EX1(read);
6359 src1 : EX1(read);
6360 src2 : EX1(read);
6361 dst : EX2(write);
6362 INS01 : ISS;
6363 ALU : EX2;
6364 %}
6365
6366 // Conditional 2 operand
6367 // EG. CSEL X0, X1, X2, <cond>
6368 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr)
6369 %{
6370 single_instruction;
6371 cr : EX1(read);
6372 src : EX1(read);
6373 dst : EX2(write);
6374 INS01 : ISS;
6375 ALU : EX2;
6376 %}
6377
6378 //------- Multiply pipeline operations --------------------
6379
6380 // Multiply reg-reg
6381 // Eg. MUL w0, w1, w2
6382 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6383 %{
6384 single_instruction;
6385 dst : WR(write);
6386 src1 : ISS(read);
6387 src2 : ISS(read);
6388 INS01 : ISS;
6389 MAC : WR;
6390 %}
6391
6392 // Multiply accumulate
6393 // Eg. MADD w0, w1, w2, w3
6394 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6395 %{
6396 single_instruction;
6397 dst : WR(write);
6398 src1 : ISS(read);
6399 src2 : ISS(read);
6400 src3 : ISS(read);
6401 INS01 : ISS;
6402 MAC : WR;
6403 %}
6404
6405 // Eg. MUL w0, w1, w2
6406 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6407 %{
6408 single_instruction;
6409 fixed_latency(3); // Maximum latency for 64 bit mul
6410 dst : WR(write);
6411 src1 : ISS(read);
6412 src2 : ISS(read);
6413 INS01 : ISS;
6414 MAC : WR;
6415 %}
6416
6417 // Multiply accumulate
6418 // Eg. MADD w0, w1, w2, w3
6419 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6420 %{
6421 single_instruction;
6422 fixed_latency(3); // Maximum latency for 64 bit mul
6423 dst : WR(write);
6424 src1 : ISS(read);
6425 src2 : ISS(read);
6426 src3 : ISS(read);
6427 INS01 : ISS;
6428 MAC : WR;
6429 %}
6430
6431 //------- Divide pipeline operations --------------------
6432
6433 // Eg. SDIV w0, w1, w2
6434 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6435 %{
6436 single_instruction;
6437 fixed_latency(8); // Maximum latency for 32 bit divide
6438 dst : WR(write);
6439 src1 : ISS(read);
6440 src2 : ISS(read);
6441 INS0 : ISS; // Can only dual issue as instruction 0
6442 DIV : WR;
6443 %}
6444
6445 // Eg. SDIV x0, x1, x2
6446 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6447 %{
6448 single_instruction;
6449 fixed_latency(16); // Maximum latency for 64 bit divide
6450 dst : WR(write);
6451 src1 : ISS(read);
6452 src2 : ISS(read);
6453 INS0 : ISS; // Can only dual issue as instruction 0
6454 DIV : WR;
6455 %}
6456
6457 //------- Load pipeline operations ------------------------
6458
6459 // Load - prefetch
6460 // Eg. PFRM <mem>
6461 pipe_class iload_prefetch(memory mem)
6462 %{
6463 single_instruction;
6464 mem : ISS(read);
6465 INS01 : ISS;
6466 LDST : WR;
6467 %}
6468
6469 // Load - reg, mem
6470 // Eg. LDR x0, <mem>
6471 pipe_class iload_reg_mem(iRegI dst, memory mem)
6472 %{
6473 single_instruction;
6474 dst : WR(write);
6475 mem : ISS(read);
6476 INS01 : ISS;
6477 LDST : WR;
6478 %}
6479
6480 // Load - reg, reg
6481 // Eg. LDR x0, [sp, x1]
6482 pipe_class iload_reg_reg(iRegI dst, iRegI src)
6483 %{
6484 single_instruction;
6485 dst : WR(write);
6486 src : ISS(read);
6487 INS01 : ISS;
6488 LDST : WR;
6489 %}
6490
6491 //------- Store pipeline operations -----------------------
6492
6493 // Store - zr, mem
6494 // Eg. STR zr, <mem>
6495 pipe_class istore_mem(memory mem)
6496 %{
6497 single_instruction;
6498 mem : ISS(read);
6499 INS01 : ISS;
6500 LDST : WR;
6501 %}
6502
6503 // Store - reg, mem
6504 // Eg. STR x0, <mem>
6505 pipe_class istore_reg_mem(iRegI src, memory mem)
6506 %{
6507 single_instruction;
6508 mem : ISS(read);
6509 src : EX2(read);
6510 INS01 : ISS;
6511 LDST : WR;
6512 %}
6513
6514 // Store - reg, reg
6515 // Eg. STR x0, [sp, x1]
6516 pipe_class istore_reg_reg(iRegI dst, iRegI src)
6517 %{
6518 single_instruction;
6519 dst : ISS(read);
6520 src : EX2(read);
6521 INS01 : ISS;
6522 LDST : WR;
6523 %}
6524
6525 //------- Store pipeline operations -----------------------
6526
6527 // Branch
6528 pipe_class pipe_branch()
6529 %{
6530 single_instruction;
6531 INS01 : ISS;
6532 BRANCH : EX1;
6533 %}
6534
6535 // Conditional branch
6536 pipe_class pipe_branch_cond(rFlagsReg cr)
6537 %{
6538 single_instruction;
6539 cr : EX1(read);
6540 INS01 : ISS;
6541 BRANCH : EX1;
6542 %}
6543
6544 // Compare & Branch
6545 // EG. CBZ/CBNZ
6546 pipe_class pipe_cmp_branch(iRegI op1)
6547 %{
6548 single_instruction;
6549 op1 : EX1(read);
6550 INS01 : ISS;
6551 BRANCH : EX1;
6552 %}
6553
6554 //------- Synchronisation operations ----------------------
6555
6556 // Any operation requiring serialization.
6557 // EG. DMB/Atomic Ops/Load Acquire/Str Release
6558 pipe_class pipe_serial()
6559 %{
6560 single_instruction;
6561 force_serialization;
6562 fixed_latency(16);
6563 INS01 : ISS(2); // Cannot dual issue with any other instruction
6564 LDST : WR;
6565 %}
6566
6567 // Generic big/slow expanded idiom - also serialized
6568 pipe_class pipe_slow()
6569 %{
6570 instruction_count(10);
6571 multiple_bundles;
6572 force_serialization;
6573 fixed_latency(16);
6574 INS01 : ISS(2); // Cannot dual issue with any other instruction
6575 LDST : WR;
6576 %}
6577
6578 // Empty pipeline class
6579 pipe_class pipe_class_empty()
6580 %{
6581 single_instruction;
6582 fixed_latency(0);
6583 %}
6584
6585 // Default pipeline class.
6586 pipe_class pipe_class_default()
6587 %{
6588 single_instruction;
6589 fixed_latency(2);
6590 %}
6591
6592 // Pipeline class for compares.
6593 pipe_class pipe_class_compare()
6594 %{
6595 single_instruction;
6596 fixed_latency(16);
6597 %}
6598
6599 // Pipeline class for memory operations.
6600 pipe_class pipe_class_memory()
6601 %{
6602 single_instruction;
6603 fixed_latency(16);
6604 %}
6605
6606 // Pipeline class for call.
6607 pipe_class pipe_class_call()
6608 %{
6609 single_instruction;
6610 fixed_latency(100);
6611 %}
6612
6613 // Define the class for the Nop node.
6614 define %{
6615 MachNop = pipe_class_empty;
6616 %}
6617
6618 %}
6619 //----------INSTRUCTIONS-------------------------------------------------------
6620 //
6621 // match -- States which machine-independent subtree may be replaced
6622 // by this instruction.
6623 // ins_cost -- The estimated cost of this instruction is used by instruction
6624 // selection to identify a minimum cost tree of machine
6625 // instructions that matches a tree of machine-independent
6626 // instructions.
6627 // format -- A string providing the disassembly for this instruction.
6628 // The value of an instruction's operand may be inserted
6629 // by referring to it with a '$' prefix.
6630 // opcode -- Three instruction opcodes may be provided. These are referred
6631 // to within an encode class as $primary, $secondary, and $tertiary
6632 // rrspectively. The primary opcode is commonly used to
6633 // indicate the type of machine instruction, while secondary
6634 // and tertiary are often used for prefix options or addressing
6635 // modes.
6636 // ins_encode -- A list of encode classes with parameters. The encode class
6637 // name must have been defined in an 'enc_class' specification
6638 // in the encode section of the architecture description.
6639
6640 // ============================================================================
6641 // Memory (Load/Store) Instructions
6642
6643 // Load Instructions
6644
6645 // Load Byte (8 bit signed)
6646 instruct loadB(iRegINoSp dst, memory1 mem)
6647 %{
6648 match(Set dst (LoadB mem));
6649 predicate(!needs_acquiring_load(n));
6650
6651 ins_cost(4 * INSN_COST);
6652 format %{ "ldrsbw $dst, $mem\t# byte" %}
6653
6654 ins_encode(aarch64_enc_ldrsbw(dst, mem));
6655
6656 ins_pipe(iload_reg_mem);
6657 %}
6658
6659 // Load Byte (8 bit signed) into long
6660 instruct loadB2L(iRegLNoSp dst, memory1 mem)
6661 %{
6662 match(Set dst (ConvI2L (LoadB mem)));
6663 predicate(!needs_acquiring_load(n->in(1)));
6664
6665 ins_cost(4 * INSN_COST);
6666 format %{ "ldrsb $dst, $mem\t# byte" %}
6667
6668 ins_encode(aarch64_enc_ldrsb(dst, mem));
6669
6670 ins_pipe(iload_reg_mem);
6671 %}
6672
6673 // Load Byte (8 bit unsigned)
6674 instruct loadUB(iRegINoSp dst, memory1 mem)
6675 %{
6676 match(Set dst (LoadUB mem));
6677 predicate(!needs_acquiring_load(n));
6678
6679 ins_cost(4 * INSN_COST);
6680 format %{ "ldrbw $dst, $mem\t# byte" %}
6681
6682 ins_encode(aarch64_enc_ldrb(dst, mem));
6683
6684 ins_pipe(iload_reg_mem);
6685 %}
6686
6687 // Load Byte (8 bit unsigned) into long
6688 instruct loadUB2L(iRegLNoSp dst, memory1 mem)
6689 %{
6690 match(Set dst (ConvI2L (LoadUB mem)));
6691 predicate(!needs_acquiring_load(n->in(1)));
6692
6693 ins_cost(4 * INSN_COST);
6694 format %{ "ldrb $dst, $mem\t# byte" %}
6695
6696 ins_encode(aarch64_enc_ldrb(dst, mem));
6697
6698 ins_pipe(iload_reg_mem);
6699 %}
6700
6701 // Load Short (16 bit signed)
6702 instruct loadS(iRegINoSp dst, memory2 mem)
6703 %{
6704 match(Set dst (LoadS mem));
6705 predicate(!needs_acquiring_load(n));
6706
6707 ins_cost(4 * INSN_COST);
6708 format %{ "ldrshw $dst, $mem\t# short" %}
6709
6710 ins_encode(aarch64_enc_ldrshw(dst, mem));
6711
6712 ins_pipe(iload_reg_mem);
6713 %}
6714
6715 // Load Short (16 bit signed) into long
6716 instruct loadS2L(iRegLNoSp dst, memory2 mem)
6717 %{
6718 match(Set dst (ConvI2L (LoadS mem)));
6719 predicate(!needs_acquiring_load(n->in(1)));
6720
6721 ins_cost(4 * INSN_COST);
6722 format %{ "ldrsh $dst, $mem\t# short" %}
6723
6724 ins_encode(aarch64_enc_ldrsh(dst, mem));
6725
6726 ins_pipe(iload_reg_mem);
6727 %}
6728
6729 // Load Char (16 bit unsigned)
6730 instruct loadUS(iRegINoSp dst, memory2 mem)
6731 %{
6732 match(Set dst (LoadUS mem));
6733 predicate(!needs_acquiring_load(n));
6734
6735 ins_cost(4 * INSN_COST);
6736 format %{ "ldrh $dst, $mem\t# short" %}
6737
6738 ins_encode(aarch64_enc_ldrh(dst, mem));
6739
6740 ins_pipe(iload_reg_mem);
6741 %}
6742
6743 // Load Short/Char (16 bit unsigned) into long
6744 instruct loadUS2L(iRegLNoSp dst, memory2 mem)
6745 %{
6746 match(Set dst (ConvI2L (LoadUS mem)));
6747 predicate(!needs_acquiring_load(n->in(1)));
6748
6749 ins_cost(4 * INSN_COST);
6750 format %{ "ldrh $dst, $mem\t# short" %}
6751
6752 ins_encode(aarch64_enc_ldrh(dst, mem));
6753
6754 ins_pipe(iload_reg_mem);
6755 %}
6756
6757 // Load Integer (32 bit signed)
6758 instruct loadI(iRegINoSp dst, memory4 mem)
6759 %{
6760 match(Set dst (LoadI mem));
6761 predicate(!needs_acquiring_load(n));
6762
6763 ins_cost(4 * INSN_COST);
6764 format %{ "ldrw $dst, $mem\t# int" %}
6765
6766 ins_encode(aarch64_enc_ldrw(dst, mem));
6767
6768 ins_pipe(iload_reg_mem);
6769 %}
6770
6771 // Load Integer (32 bit signed) into long
6772 instruct loadI2L(iRegLNoSp dst, memory4 mem)
6773 %{
6774 match(Set dst (ConvI2L (LoadI mem)));
6775 predicate(!needs_acquiring_load(n->in(1)));
6776
6777 ins_cost(4 * INSN_COST);
6778 format %{ "ldrsw $dst, $mem\t# int" %}
6779
6780 ins_encode(aarch64_enc_ldrsw(dst, mem));
6781
6782 ins_pipe(iload_reg_mem);
6783 %}
6784
6785 // Load Integer (32 bit unsigned) into long
6786 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask)
6787 %{
6788 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
6789 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load()));
6790
6791 ins_cost(4 * INSN_COST);
6792 format %{ "ldrw $dst, $mem\t# int" %}
6793
6794 ins_encode(aarch64_enc_ldrw(dst, mem));
6795
6796 ins_pipe(iload_reg_mem);
6797 %}
6798
6799 // Load Long (64 bit signed)
6800 instruct loadL(iRegLNoSp dst, memory8 mem)
6801 %{
6802 match(Set dst (LoadL mem));
6803 predicate(!needs_acquiring_load(n));
6804
6805 ins_cost(4 * INSN_COST);
6806 format %{ "ldr $dst, $mem\t# int" %}
6807
6808 ins_encode(aarch64_enc_ldr(dst, mem));
6809
6810 ins_pipe(iload_reg_mem);
6811 %}
6812
6813 // Load Range
6814 instruct loadRange(iRegINoSp dst, memory4 mem)
6815 %{
6816 match(Set dst (LoadRange mem));
6817
6818 ins_cost(4 * INSN_COST);
6819 format %{ "ldrw $dst, $mem\t# range" %}
6820
6821 ins_encode(aarch64_enc_ldrw(dst, mem));
6822
6823 ins_pipe(iload_reg_mem);
6824 %}
6825
6826 // Load Pointer
6827 instruct loadP(iRegPNoSp dst, memory8 mem)
6828 %{
6829 match(Set dst (LoadP mem));
6830 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0));
6831
6832 ins_cost(4 * INSN_COST);
6833 format %{ "ldr $dst, $mem\t# ptr" %}
6834
6835 ins_encode(aarch64_enc_ldr(dst, mem));
6836
6837 ins_pipe(iload_reg_mem);
6838 %}
6839
6840 // Load Compressed Pointer
6841 instruct loadN(iRegNNoSp dst, memory4 mem)
6842 %{
6843 match(Set dst (LoadN mem));
6844 predicate(!needs_acquiring_load(n) && n->as_Load()->barrier_data() == 0);
6845
6846 ins_cost(4 * INSN_COST);
6847 format %{ "ldrw $dst, $mem\t# compressed ptr" %}
6848
6849 ins_encode(aarch64_enc_ldrw(dst, mem));
6850
6851 ins_pipe(iload_reg_mem);
6852 %}
6853
6854 // Load Klass Pointer
6855 instruct loadKlass(iRegPNoSp dst, memory8 mem)
6856 %{
6857 match(Set dst (LoadKlass mem));
6858 predicate(!needs_acquiring_load(n));
6859
6860 ins_cost(4 * INSN_COST);
6861 format %{ "ldr $dst, $mem\t# class" %}
6862
6863 ins_encode(aarch64_enc_ldr(dst, mem));
6864
6865 ins_pipe(iload_reg_mem);
6866 %}
6867
6868 // Load Narrow Klass Pointer
6869 instruct loadNKlass(iRegNNoSp dst, memory4 mem)
6870 %{
6871 match(Set dst (LoadNKlass mem));
6872 predicate(!needs_acquiring_load(n) && !UseCompactObjectHeaders);
6873
6874 ins_cost(4 * INSN_COST);
6875 format %{ "ldrw $dst, $mem\t# compressed class ptr" %}
6876
6877 ins_encode(aarch64_enc_ldrw(dst, mem));
6878
6879 ins_pipe(iload_reg_mem);
6880 %}
6881
6882 instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory4 mem)
6883 %{
6884 match(Set dst (LoadNKlass mem));
6885 predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders);
6886
6887 ins_cost(4 * INSN_COST);
6888 format %{
6889 "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t"
6890 "lsrw $dst, $dst, markWord::klass_shift_at_offset"
6891 %}
6892 ins_encode %{
6893 // inlined aarch64_enc_ldrw
6894 loadStore(masm, &MacroAssembler::ldrw, $dst$$Register, $mem->opcode(),
6895 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
6896 __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift_at_offset);
6897 %}
6898 ins_pipe(iload_reg_mem);
6899 %}
6900
6901 // Load Float
6902 instruct loadF(vRegF dst, memory4 mem)
6903 %{
6904 match(Set dst (LoadF mem));
6905 predicate(!needs_acquiring_load(n));
6906
6907 ins_cost(4 * INSN_COST);
6908 format %{ "ldrs $dst, $mem\t# float" %}
6909
6910 ins_encode( aarch64_enc_ldrs(dst, mem) );
6911
6912 ins_pipe(pipe_class_memory);
6913 %}
6914
6915 // Load Double
6916 instruct loadD(vRegD dst, memory8 mem)
6917 %{
6918 match(Set dst (LoadD mem));
6919 predicate(!needs_acquiring_load(n));
6920
6921 ins_cost(4 * INSN_COST);
6922 format %{ "ldrd $dst, $mem\t# double" %}
6923
6924 ins_encode( aarch64_enc_ldrd(dst, mem) );
6925
6926 ins_pipe(pipe_class_memory);
6927 %}
6928
6929
6930 // Load Int Constant
6931 instruct loadConI(iRegINoSp dst, immI src)
6932 %{
6933 match(Set dst src);
6934
6935 ins_cost(INSN_COST);
6936 format %{ "mov $dst, $src\t# int" %}
6937
6938 ins_encode( aarch64_enc_movw_imm(dst, src) );
6939
6940 ins_pipe(ialu_imm);
6941 %}
6942
6943 // Load Long Constant
6944 instruct loadConL(iRegLNoSp dst, immL src)
6945 %{
6946 match(Set dst src);
6947
6948 ins_cost(INSN_COST);
6949 format %{ "mov $dst, $src\t# long" %}
6950
6951 ins_encode( aarch64_enc_mov_imm(dst, src) );
6952
6953 ins_pipe(ialu_imm);
6954 %}
6955
6956 // Load Pointer Constant
6957
6958 instruct loadConP(iRegPNoSp dst, immP con)
6959 %{
6960 match(Set dst con);
6961
6962 ins_cost(INSN_COST * 4);
6963 format %{
6964 "mov $dst, $con\t# ptr"
6965 %}
6966
6967 ins_encode(aarch64_enc_mov_p(dst, con));
6968
6969 ins_pipe(ialu_imm);
6970 %}
6971
6972 // Load Null Pointer Constant
6973
6974 instruct loadConP0(iRegPNoSp dst, immP0 con)
6975 %{
6976 match(Set dst con);
6977
6978 ins_cost(INSN_COST);
6979 format %{ "mov $dst, $con\t# nullptr ptr" %}
6980
6981 ins_encode(aarch64_enc_mov_p0(dst, con));
6982
6983 ins_pipe(ialu_imm);
6984 %}
6985
6986 // Load Pointer Constant One
6987
6988 instruct loadConP1(iRegPNoSp dst, immP_1 con)
6989 %{
6990 match(Set dst con);
6991
6992 ins_cost(INSN_COST);
6993 format %{ "mov $dst, $con\t# nullptr ptr" %}
6994
6995 ins_encode(aarch64_enc_mov_p1(dst, con));
6996
6997 ins_pipe(ialu_imm);
6998 %}
6999
7000 // Load Narrow Pointer Constant
7001
7002 instruct loadConN(iRegNNoSp dst, immN con)
7003 %{
7004 match(Set dst con);
7005
7006 ins_cost(INSN_COST * 4);
7007 format %{ "mov $dst, $con\t# compressed ptr" %}
7008
7009 ins_encode(aarch64_enc_mov_n(dst, con));
7010
7011 ins_pipe(ialu_imm);
7012 %}
7013
7014 // Load Narrow Null Pointer Constant
7015
7016 instruct loadConN0(iRegNNoSp dst, immN0 con)
7017 %{
7018 match(Set dst con);
7019
7020 ins_cost(INSN_COST);
7021 format %{ "mov $dst, $con\t# compressed nullptr ptr" %}
7022
7023 ins_encode(aarch64_enc_mov_n0(dst, con));
7024
7025 ins_pipe(ialu_imm);
7026 %}
7027
7028 // Load Narrow Klass Constant
7029
7030 instruct loadConNKlass(iRegNNoSp dst, immNKlass con)
7031 %{
7032 match(Set dst con);
7033
7034 ins_cost(INSN_COST);
7035 format %{ "mov $dst, $con\t# compressed klass ptr" %}
7036
7037 ins_encode(aarch64_enc_mov_nk(dst, con));
7038
7039 ins_pipe(ialu_imm);
7040 %}
7041
7042 // Load Packed Float Constant
7043
7044 instruct loadConF_packed(vRegF dst, immFPacked con) %{
7045 match(Set dst con);
7046 ins_cost(INSN_COST * 4);
7047 format %{ "fmovs $dst, $con"%}
7048 ins_encode %{
7049 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant);
7050 %}
7051
7052 ins_pipe(fp_imm_s);
7053 %}
7054
7055 // Load Float Constant
7056
7057 instruct loadConF(vRegF dst, immF con) %{
7058 match(Set dst con);
7059
7060 ins_cost(INSN_COST * 4);
7061
7062 format %{
7063 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
7064 %}
7065
7066 ins_encode %{
7067 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con));
7068 %}
7069
7070 ins_pipe(fp_load_constant_s);
7071 %}
7072
7073 // Load Packed Double Constant
7074
7075 instruct loadConD_packed(vRegD dst, immDPacked con) %{
7076 match(Set dst con);
7077 ins_cost(INSN_COST);
7078 format %{ "fmovd $dst, $con"%}
7079 ins_encode %{
7080 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant);
7081 %}
7082
7083 ins_pipe(fp_imm_d);
7084 %}
7085
7086 // Load Double Constant
7087
7088 instruct loadConD(vRegD dst, immD con) %{
7089 match(Set dst con);
7090
7091 ins_cost(INSN_COST * 5);
7092 format %{
7093 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
7094 %}
7095
7096 ins_encode %{
7097 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con));
7098 %}
7099
7100 ins_pipe(fp_load_constant_d);
7101 %}
7102
7103 // Load Half Float Constant
7104 instruct loadConH(vRegF dst, immH con) %{
7105 match(Set dst con);
7106 format %{ "mov rscratch1, $con\n\t"
7107 "fmov $dst, rscratch1"
7108 %}
7109 ins_encode %{
7110 __ movw(rscratch1, (uint32_t)$con$$constant);
7111 __ fmovs($dst$$FloatRegister, rscratch1);
7112 %}
7113 ins_pipe(pipe_class_default);
7114 %}
7115
7116 // Store Instructions
7117
7118 // Store Byte
7119 instruct storeB(iRegIorL2I src, memory1 mem)
7120 %{
7121 match(Set mem (StoreB mem src));
7122 predicate(!needs_releasing_store(n));
7123
7124 ins_cost(INSN_COST);
7125 format %{ "strb $src, $mem\t# byte" %}
7126
7127 ins_encode(aarch64_enc_strb(src, mem));
7128
7129 ins_pipe(istore_reg_mem);
7130 %}
7131
7132
7133 instruct storeimmB0(immI0 zero, memory1 mem)
7134 %{
7135 match(Set mem (StoreB mem zero));
7136 predicate(!needs_releasing_store(n));
7137
7138 ins_cost(INSN_COST);
7139 format %{ "strb rscractch2, $mem\t# byte" %}
7140
7141 ins_encode(aarch64_enc_strb0(mem));
7142
7143 ins_pipe(istore_mem);
7144 %}
7145
7146 // Store Char/Short
7147 instruct storeC(iRegIorL2I src, memory2 mem)
7148 %{
7149 match(Set mem (StoreC mem src));
7150 predicate(!needs_releasing_store(n));
7151
7152 ins_cost(INSN_COST);
7153 format %{ "strh $src, $mem\t# short" %}
7154
7155 ins_encode(aarch64_enc_strh(src, mem));
7156
7157 ins_pipe(istore_reg_mem);
7158 %}
7159
7160 instruct storeimmC0(immI0 zero, memory2 mem)
7161 %{
7162 match(Set mem (StoreC mem zero));
7163 predicate(!needs_releasing_store(n));
7164
7165 ins_cost(INSN_COST);
7166 format %{ "strh zr, $mem\t# short" %}
7167
7168 ins_encode(aarch64_enc_strh0(mem));
7169
7170 ins_pipe(istore_mem);
7171 %}
7172
7173 // Store Integer
7174
7175 instruct storeI(iRegIorL2I src, memory4 mem)
7176 %{
7177 match(Set mem(StoreI mem src));
7178 predicate(!needs_releasing_store(n));
7179
7180 ins_cost(INSN_COST);
7181 format %{ "strw $src, $mem\t# int" %}
7182
7183 ins_encode(aarch64_enc_strw(src, mem));
7184
7185 ins_pipe(istore_reg_mem);
7186 %}
7187
7188 instruct storeimmI0(immI0 zero, memory4 mem)
7189 %{
7190 match(Set mem(StoreI mem zero));
7191 predicate(!needs_releasing_store(n));
7192
7193 ins_cost(INSN_COST);
7194 format %{ "strw zr, $mem\t# int" %}
7195
7196 ins_encode(aarch64_enc_strw0(mem));
7197
7198 ins_pipe(istore_mem);
7199 %}
7200
7201 // Store Long (64 bit signed)
7202 instruct storeL(iRegL src, memory8 mem)
7203 %{
7204 match(Set mem (StoreL mem src));
7205 predicate(!needs_releasing_store(n));
7206
7207 ins_cost(INSN_COST);
7208 format %{ "str $src, $mem\t# int" %}
7209
7210 ins_encode(aarch64_enc_str(src, mem));
7211
7212 ins_pipe(istore_reg_mem);
7213 %}
7214
7215 // Store Long (64 bit signed)
7216 instruct storeimmL0(immL0 zero, memory8 mem)
7217 %{
7218 match(Set mem (StoreL mem zero));
7219 predicate(!needs_releasing_store(n));
7220
7221 ins_cost(INSN_COST);
7222 format %{ "str zr, $mem\t# int" %}
7223
7224 ins_encode(aarch64_enc_str0(mem));
7225
7226 ins_pipe(istore_mem);
7227 %}
7228
7229 // Store Pointer
7230 instruct storeP(iRegP src, memory8 mem)
7231 %{
7232 match(Set mem (StoreP mem src));
7233 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0);
7234
7235 ins_cost(INSN_COST);
7236 format %{ "str $src, $mem\t# ptr" %}
7237
7238 ins_encode(aarch64_enc_str(src, mem));
7239
7240 ins_pipe(istore_reg_mem);
7241 %}
7242
7243 // Store Pointer
7244 instruct storeimmP0(immP0 zero, memory8 mem)
7245 %{
7246 match(Set mem (StoreP mem zero));
7247 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0);
7248
7249 ins_cost(INSN_COST);
7250 format %{ "str zr, $mem\t# ptr" %}
7251
7252 ins_encode(aarch64_enc_str0(mem));
7253
7254 ins_pipe(istore_mem);
7255 %}
7256
7257 // Store Compressed Pointer
7258 instruct storeN(iRegN src, memory4 mem)
7259 %{
7260 match(Set mem (StoreN mem src));
7261 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0);
7262
7263 ins_cost(INSN_COST);
7264 format %{ "strw $src, $mem\t# compressed ptr" %}
7265
7266 ins_encode(aarch64_enc_strw(src, mem));
7267
7268 ins_pipe(istore_reg_mem);
7269 %}
7270
7271 instruct storeImmN0(immN0 zero, memory4 mem)
7272 %{
7273 match(Set mem (StoreN mem zero));
7274 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0);
7275
7276 ins_cost(INSN_COST);
7277 format %{ "strw zr, $mem\t# compressed ptr" %}
7278
7279 ins_encode(aarch64_enc_strw0(mem));
7280
7281 ins_pipe(istore_mem);
7282 %}
7283
7284 // Store Float
7285 instruct storeF(vRegF src, memory4 mem)
7286 %{
7287 match(Set mem (StoreF mem src));
7288 predicate(!needs_releasing_store(n));
7289
7290 ins_cost(INSN_COST);
7291 format %{ "strs $src, $mem\t# float" %}
7292
7293 ins_encode( aarch64_enc_strs(src, mem) );
7294
7295 ins_pipe(pipe_class_memory);
7296 %}
7297
7298 // TODO
7299 // implement storeImmF0 and storeFImmPacked
7300
7301 // Store Double
7302 instruct storeD(vRegD src, memory8 mem)
7303 %{
7304 match(Set mem (StoreD mem src));
7305 predicate(!needs_releasing_store(n));
7306
7307 ins_cost(INSN_COST);
7308 format %{ "strd $src, $mem\t# double" %}
7309
7310 ins_encode( aarch64_enc_strd(src, mem) );
7311
7312 ins_pipe(pipe_class_memory);
7313 %}
7314
7315 // Store Compressed Klass Pointer
7316 instruct storeNKlass(iRegN src, memory4 mem)
7317 %{
7318 predicate(!needs_releasing_store(n));
7319 match(Set mem (StoreNKlass mem src));
7320
7321 ins_cost(INSN_COST);
7322 format %{ "strw $src, $mem\t# compressed klass ptr" %}
7323
7324 ins_encode(aarch64_enc_strw(src, mem));
7325
7326 ins_pipe(istore_reg_mem);
7327 %}
7328
7329 // TODO
7330 // implement storeImmD0 and storeDImmPacked
7331
7332 // prefetch instructions
7333 // Must be safe to execute with invalid address (cannot fault).
7334
7335 instruct prefetchalloc( memory8 mem ) %{
7336 match(PrefetchAllocation mem);
7337
7338 ins_cost(INSN_COST);
7339 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %}
7340
7341 ins_encode( aarch64_enc_prefetchw(mem) );
7342
7343 ins_pipe(iload_prefetch);
7344 %}
7345
7346 // ---------------- volatile loads and stores ----------------
7347
7348 // Load Byte (8 bit signed)
7349 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7350 %{
7351 match(Set dst (LoadB mem));
7352
7353 ins_cost(VOLATILE_REF_COST);
7354 format %{ "ldarsb $dst, $mem\t# byte" %}
7355
7356 ins_encode(aarch64_enc_ldarsb(dst, mem));
7357
7358 ins_pipe(pipe_serial);
7359 %}
7360
7361 // Load Byte (8 bit signed) into long
7362 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7363 %{
7364 match(Set dst (ConvI2L (LoadB mem)));
7365
7366 ins_cost(VOLATILE_REF_COST);
7367 format %{ "ldarsb $dst, $mem\t# byte" %}
7368
7369 ins_encode(aarch64_enc_ldarsb(dst, mem));
7370
7371 ins_pipe(pipe_serial);
7372 %}
7373
7374 // Load Byte (8 bit unsigned)
7375 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7376 %{
7377 match(Set dst (LoadUB mem));
7378
7379 ins_cost(VOLATILE_REF_COST);
7380 format %{ "ldarb $dst, $mem\t# byte" %}
7381
7382 ins_encode(aarch64_enc_ldarb(dst, mem));
7383
7384 ins_pipe(pipe_serial);
7385 %}
7386
7387 // Load Byte (8 bit unsigned) into long
7388 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7389 %{
7390 match(Set dst (ConvI2L (LoadUB mem)));
7391
7392 ins_cost(VOLATILE_REF_COST);
7393 format %{ "ldarb $dst, $mem\t# byte" %}
7394
7395 ins_encode(aarch64_enc_ldarb(dst, mem));
7396
7397 ins_pipe(pipe_serial);
7398 %}
7399
7400 // Load Short (16 bit signed)
7401 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7402 %{
7403 match(Set dst (LoadS mem));
7404
7405 ins_cost(VOLATILE_REF_COST);
7406 format %{ "ldarshw $dst, $mem\t# short" %}
7407
7408 ins_encode(aarch64_enc_ldarshw(dst, mem));
7409
7410 ins_pipe(pipe_serial);
7411 %}
7412
7413 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7414 %{
7415 match(Set dst (LoadUS mem));
7416
7417 ins_cost(VOLATILE_REF_COST);
7418 format %{ "ldarhw $dst, $mem\t# short" %}
7419
7420 ins_encode(aarch64_enc_ldarhw(dst, mem));
7421
7422 ins_pipe(pipe_serial);
7423 %}
7424
7425 // Load Short/Char (16 bit unsigned) into long
7426 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7427 %{
7428 match(Set dst (ConvI2L (LoadUS mem)));
7429
7430 ins_cost(VOLATILE_REF_COST);
7431 format %{ "ldarh $dst, $mem\t# short" %}
7432
7433 ins_encode(aarch64_enc_ldarh(dst, mem));
7434
7435 ins_pipe(pipe_serial);
7436 %}
7437
7438 // Load Short/Char (16 bit signed) into long
7439 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7440 %{
7441 match(Set dst (ConvI2L (LoadS mem)));
7442
7443 ins_cost(VOLATILE_REF_COST);
7444 format %{ "ldarh $dst, $mem\t# short" %}
7445
7446 ins_encode(aarch64_enc_ldarsh(dst, mem));
7447
7448 ins_pipe(pipe_serial);
7449 %}
7450
7451 // Load Integer (32 bit signed)
7452 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7453 %{
7454 match(Set dst (LoadI mem));
7455
7456 ins_cost(VOLATILE_REF_COST);
7457 format %{ "ldarw $dst, $mem\t# int" %}
7458
7459 ins_encode(aarch64_enc_ldarw(dst, mem));
7460
7461 ins_pipe(pipe_serial);
7462 %}
7463
7464 // Load Integer (32 bit unsigned) into long
7465 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask)
7466 %{
7467 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
7468
7469 ins_cost(VOLATILE_REF_COST);
7470 format %{ "ldarw $dst, $mem\t# int" %}
7471
7472 ins_encode(aarch64_enc_ldarw(dst, mem));
7473
7474 ins_pipe(pipe_serial);
7475 %}
7476
7477 // Load Long (64 bit signed)
7478 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7479 %{
7480 match(Set dst (LoadL mem));
7481
7482 ins_cost(VOLATILE_REF_COST);
7483 format %{ "ldar $dst, $mem\t# int" %}
7484
7485 ins_encode(aarch64_enc_ldar(dst, mem));
7486
7487 ins_pipe(pipe_serial);
7488 %}
7489
7490 // Load Pointer
7491 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem)
7492 %{
7493 match(Set dst (LoadP mem));
7494 predicate(n->as_Load()->barrier_data() == 0);
7495
7496 ins_cost(VOLATILE_REF_COST);
7497 format %{ "ldar $dst, $mem\t# ptr" %}
7498
7499 ins_encode(aarch64_enc_ldar(dst, mem));
7500
7501 ins_pipe(pipe_serial);
7502 %}
7503
7504 // Load Compressed Pointer
7505 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem)
7506 %{
7507 match(Set dst (LoadN mem));
7508 predicate(n->as_Load()->barrier_data() == 0);
7509
7510 ins_cost(VOLATILE_REF_COST);
7511 format %{ "ldarw $dst, $mem\t# compressed ptr" %}
7512
7513 ins_encode(aarch64_enc_ldarw(dst, mem));
7514
7515 ins_pipe(pipe_serial);
7516 %}
7517
7518 // Load Float
7519 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem)
7520 %{
7521 match(Set dst (LoadF mem));
7522
7523 ins_cost(VOLATILE_REF_COST);
7524 format %{ "ldars $dst, $mem\t# float" %}
7525
7526 ins_encode( aarch64_enc_fldars(dst, mem) );
7527
7528 ins_pipe(pipe_serial);
7529 %}
7530
7531 // Load Double
7532 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem)
7533 %{
7534 match(Set dst (LoadD mem));
7535
7536 ins_cost(VOLATILE_REF_COST);
7537 format %{ "ldard $dst, $mem\t# double" %}
7538
7539 ins_encode( aarch64_enc_fldard(dst, mem) );
7540
7541 ins_pipe(pipe_serial);
7542 %}
7543
7544 // Store Byte
7545 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7546 %{
7547 match(Set mem (StoreB mem src));
7548
7549 ins_cost(VOLATILE_REF_COST);
7550 format %{ "stlrb $src, $mem\t# byte" %}
7551
7552 ins_encode(aarch64_enc_stlrb(src, mem));
7553
7554 ins_pipe(pipe_class_memory);
7555 %}
7556
7557 instruct storeimmB0_volatile(immI0 zero, /* sync_memory*/indirect mem)
7558 %{
7559 match(Set mem (StoreB mem zero));
7560
7561 ins_cost(VOLATILE_REF_COST);
7562 format %{ "stlrb zr, $mem\t# byte" %}
7563
7564 ins_encode(aarch64_enc_stlrb0(mem));
7565
7566 ins_pipe(pipe_class_memory);
7567 %}
7568
7569 // Store Char/Short
7570 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7571 %{
7572 match(Set mem (StoreC mem src));
7573
7574 ins_cost(VOLATILE_REF_COST);
7575 format %{ "stlrh $src, $mem\t# short" %}
7576
7577 ins_encode(aarch64_enc_stlrh(src, mem));
7578
7579 ins_pipe(pipe_class_memory);
7580 %}
7581
7582 instruct storeimmC0_volatile(immI0 zero, /* sync_memory*/indirect mem)
7583 %{
7584 match(Set mem (StoreC mem zero));
7585
7586 ins_cost(VOLATILE_REF_COST);
7587 format %{ "stlrh zr, $mem\t# short" %}
7588
7589 ins_encode(aarch64_enc_stlrh0(mem));
7590
7591 ins_pipe(pipe_class_memory);
7592 %}
7593
7594 // Store Integer
7595
7596 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
7597 %{
7598 match(Set mem(StoreI mem src));
7599
7600 ins_cost(VOLATILE_REF_COST);
7601 format %{ "stlrw $src, $mem\t# int" %}
7602
7603 ins_encode(aarch64_enc_stlrw(src, mem));
7604
7605 ins_pipe(pipe_class_memory);
7606 %}
7607
7608 instruct storeimmI0_volatile(immI0 zero, /* sync_memory*/indirect mem)
7609 %{
7610 match(Set mem(StoreI mem zero));
7611
7612 ins_cost(VOLATILE_REF_COST);
7613 format %{ "stlrw zr, $mem\t# int" %}
7614
7615 ins_encode(aarch64_enc_stlrw0(mem));
7616
7617 ins_pipe(pipe_class_memory);
7618 %}
7619
7620 // Store Long (64 bit signed)
7621 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem)
7622 %{
7623 match(Set mem (StoreL mem src));
7624
7625 ins_cost(VOLATILE_REF_COST);
7626 format %{ "stlr $src, $mem\t# int" %}
7627
7628 ins_encode(aarch64_enc_stlr(src, mem));
7629
7630 ins_pipe(pipe_class_memory);
7631 %}
7632
7633 instruct storeimmL0_volatile(immL0 zero, /* sync_memory*/indirect mem)
7634 %{
7635 match(Set mem (StoreL mem zero));
7636
7637 ins_cost(VOLATILE_REF_COST);
7638 format %{ "stlr zr, $mem\t# int" %}
7639
7640 ins_encode(aarch64_enc_stlr0(mem));
7641
7642 ins_pipe(pipe_class_memory);
7643 %}
7644
7645 // Store Pointer
7646 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem)
7647 %{
7648 match(Set mem (StoreP mem src));
7649 predicate(n->as_Store()->barrier_data() == 0);
7650
7651 ins_cost(VOLATILE_REF_COST);
7652 format %{ "stlr $src, $mem\t# ptr" %}
7653
7654 ins_encode(aarch64_enc_stlr(src, mem));
7655
7656 ins_pipe(pipe_class_memory);
7657 %}
7658
7659 instruct storeimmP0_volatile(immP0 zero, /* sync_memory*/indirect mem)
7660 %{
7661 match(Set mem (StoreP mem zero));
7662 predicate(n->as_Store()->barrier_data() == 0);
7663
7664 ins_cost(VOLATILE_REF_COST);
7665 format %{ "stlr zr, $mem\t# ptr" %}
7666
7667 ins_encode(aarch64_enc_stlr0(mem));
7668
7669 ins_pipe(pipe_class_memory);
7670 %}
7671
7672 // Store Compressed Pointer
7673 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem)
7674 %{
7675 match(Set mem (StoreN mem src));
7676 predicate(n->as_Store()->barrier_data() == 0);
7677
7678 ins_cost(VOLATILE_REF_COST);
7679 format %{ "stlrw $src, $mem\t# compressed ptr" %}
7680
7681 ins_encode(aarch64_enc_stlrw(src, mem));
7682
7683 ins_pipe(pipe_class_memory);
7684 %}
7685
7686 instruct storeimmN0_volatile(immN0 zero, /* sync_memory*/indirect mem)
7687 %{
7688 match(Set mem (StoreN mem zero));
7689 predicate(n->as_Store()->barrier_data() == 0);
7690
7691 ins_cost(VOLATILE_REF_COST);
7692 format %{ "stlrw zr, $mem\t# compressed ptr" %}
7693
7694 ins_encode(aarch64_enc_stlrw0(mem));
7695
7696 ins_pipe(pipe_class_memory);
7697 %}
7698
7699 // Store Float
7700 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem)
7701 %{
7702 match(Set mem (StoreF mem src));
7703
7704 ins_cost(VOLATILE_REF_COST);
7705 format %{ "stlrs $src, $mem\t# float" %}
7706
7707 ins_encode( aarch64_enc_fstlrs(src, mem) );
7708
7709 ins_pipe(pipe_class_memory);
7710 %}
7711
7712 // TODO
7713 // implement storeImmF0 and storeFImmPacked
7714
7715 // Store Double
7716 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem)
7717 %{
7718 match(Set mem (StoreD mem src));
7719
7720 ins_cost(VOLATILE_REF_COST);
7721 format %{ "stlrd $src, $mem\t# double" %}
7722
7723 ins_encode( aarch64_enc_fstlrd(src, mem) );
7724
7725 ins_pipe(pipe_class_memory);
7726 %}
7727
7728 // ---------------- end of volatile loads and stores ----------------
7729
7730 instruct cacheWB(indirect addr)
7731 %{
7732 predicate(VM_Version::supports_data_cache_line_flush());
7733 match(CacheWB addr);
7734
7735 ins_cost(100);
7736 format %{"cache wb $addr" %}
7737 ins_encode %{
7738 assert($addr->index_position() < 0, "should be");
7739 assert($addr$$disp == 0, "should be");
7740 __ cache_wb(Address($addr$$base$$Register, 0));
7741 %}
7742 ins_pipe(pipe_slow); // XXX
7743 %}
7744
7745 instruct cacheWBPreSync()
7746 %{
7747 predicate(VM_Version::supports_data_cache_line_flush());
7748 match(CacheWBPreSync);
7749
7750 ins_cost(100);
7751 format %{"cache wb presync" %}
7752 ins_encode %{
7753 __ cache_wbsync(true);
7754 %}
7755 ins_pipe(pipe_slow); // XXX
7756 %}
7757
7758 instruct cacheWBPostSync()
7759 %{
7760 predicate(VM_Version::supports_data_cache_line_flush());
7761 match(CacheWBPostSync);
7762
7763 ins_cost(100);
7764 format %{"cache wb postsync" %}
7765 ins_encode %{
7766 __ cache_wbsync(false);
7767 %}
7768 ins_pipe(pipe_slow); // XXX
7769 %}
7770
7771 // ============================================================================
7772 // BSWAP Instructions
7773
7774 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{
7775 match(Set dst (ReverseBytesI src));
7776
7777 ins_cost(INSN_COST);
7778 format %{ "revw $dst, $src" %}
7779
7780 ins_encode %{
7781 __ revw(as_Register($dst$$reg), as_Register($src$$reg));
7782 %}
7783
7784 ins_pipe(ialu_reg);
7785 %}
7786
7787 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{
7788 match(Set dst (ReverseBytesL src));
7789
7790 ins_cost(INSN_COST);
7791 format %{ "rev $dst, $src" %}
7792
7793 ins_encode %{
7794 __ rev(as_Register($dst$$reg), as_Register($src$$reg));
7795 %}
7796
7797 ins_pipe(ialu_reg);
7798 %}
7799
7800 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{
7801 match(Set dst (ReverseBytesUS src));
7802
7803 ins_cost(INSN_COST);
7804 format %{ "rev16w $dst, $src" %}
7805
7806 ins_encode %{
7807 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7808 %}
7809
7810 ins_pipe(ialu_reg);
7811 %}
7812
7813 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{
7814 match(Set dst (ReverseBytesS src));
7815
7816 ins_cost(INSN_COST);
7817 format %{ "rev16w $dst, $src\n\t"
7818 "sbfmw $dst, $dst, #0, #15" %}
7819
7820 ins_encode %{
7821 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
7822 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U);
7823 %}
7824
7825 ins_pipe(ialu_reg);
7826 %}
7827
7828 // ============================================================================
7829 // Zero Count Instructions
7830
7831 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7832 match(Set dst (CountLeadingZerosI src));
7833
7834 ins_cost(INSN_COST);
7835 format %{ "clzw $dst, $src" %}
7836 ins_encode %{
7837 __ clzw(as_Register($dst$$reg), as_Register($src$$reg));
7838 %}
7839
7840 ins_pipe(ialu_reg);
7841 %}
7842
7843 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{
7844 match(Set dst (CountLeadingZerosL src));
7845
7846 ins_cost(INSN_COST);
7847 format %{ "clz $dst, $src" %}
7848 ins_encode %{
7849 __ clz(as_Register($dst$$reg), as_Register($src$$reg));
7850 %}
7851
7852 ins_pipe(ialu_reg);
7853 %}
7854
7855 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{
7856 match(Set dst (CountTrailingZerosI src));
7857
7858 ins_cost(INSN_COST * 2);
7859 format %{ "rbitw $dst, $src\n\t"
7860 "clzw $dst, $dst" %}
7861 ins_encode %{
7862 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg));
7863 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg));
7864 %}
7865
7866 ins_pipe(ialu_reg);
7867 %}
7868
7869 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{
7870 match(Set dst (CountTrailingZerosL src));
7871
7872 ins_cost(INSN_COST * 2);
7873 format %{ "rbit $dst, $src\n\t"
7874 "clz $dst, $dst" %}
7875 ins_encode %{
7876 __ rbit(as_Register($dst$$reg), as_Register($src$$reg));
7877 __ clz(as_Register($dst$$reg), as_Register($dst$$reg));
7878 %}
7879
7880 ins_pipe(ialu_reg);
7881 %}
7882
7883 //---------- Population Count Instructions -------------------------------------
7884 //
7885
7886 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{
7887 match(Set dst (PopCountI src));
7888 effect(TEMP tmp);
7889 ins_cost(INSN_COST * 13);
7890
7891 format %{ "fmovs $tmp, $src\t# vector (1S)\n\t"
7892 "cnt $tmp, $tmp\t# vector (8B)\n\t"
7893 "addv $tmp, $tmp\t# vector (8B)\n\t"
7894 "mov $dst, $tmp\t# vector (1D)" %}
7895 ins_encode %{
7896 __ fmovs($tmp$$FloatRegister, $src$$Register);
7897 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7898 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7899 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0);
7900 %}
7901
7902 ins_pipe(pipe_class_default);
7903 %}
7904
7905 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{
7906 match(Set dst (PopCountI (LoadI mem)));
7907 effect(TEMP tmp);
7908 ins_cost(INSN_COST * 13);
7909
7910 format %{ "ldrs $tmp, $mem\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 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7916 loadStore(masm, &MacroAssembler::ldrs, tmp_reg, $mem->opcode(),
7917 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
7918 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7919 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7920 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0);
7921 %}
7922
7923 ins_pipe(pipe_class_default);
7924 %}
7925
7926 // Note: Long.bitCount(long) returns an int.
7927 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{
7928 match(Set dst (PopCountL src));
7929 effect(TEMP tmp);
7930 ins_cost(INSN_COST * 13);
7931
7932 format %{ "mov $tmp, $src\t# vector (1D)\n\t"
7933 "cnt $tmp, $tmp\t# vector (8B)\n\t"
7934 "addv $tmp, $tmp\t# vector (8B)\n\t"
7935 "mov $dst, $tmp\t# vector (1D)" %}
7936 ins_encode %{
7937 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register);
7938 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7939 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7940 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0);
7941 %}
7942
7943 ins_pipe(pipe_class_default);
7944 %}
7945
7946 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{
7947 match(Set dst (PopCountL (LoadL mem)));
7948 effect(TEMP tmp);
7949 ins_cost(INSN_COST * 13);
7950
7951 format %{ "ldrd $tmp, $mem\n\t"
7952 "cnt $tmp, $tmp\t# vector (8B)\n\t"
7953 "addv $tmp, $tmp\t# vector (8B)\n\t"
7954 "mov $dst, $tmp\t# vector (1D)" %}
7955 ins_encode %{
7956 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
7957 loadStore(masm, &MacroAssembler::ldrd, tmp_reg, $mem->opcode(),
7958 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
7959 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7960 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
7961 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0);
7962 %}
7963
7964 ins_pipe(pipe_class_default);
7965 %}
7966
7967 // ============================================================================
7968 // VerifyVectorAlignment Instruction
7969
7970 instruct verify_vector_alignment(iRegP addr, immL_positive_bitmaskI mask, rFlagsReg cr) %{
7971 match(Set addr (VerifyVectorAlignment addr mask));
7972 effect(KILL cr);
7973 format %{ "verify_vector_alignment $addr $mask \t! verify alignment" %}
7974 ins_encode %{
7975 Label Lskip;
7976 // check if masked bits of addr are zero
7977 __ tst($addr$$Register, $mask$$constant);
7978 __ br(Assembler::EQ, Lskip);
7979 __ stop("verify_vector_alignment found a misaligned vector memory access");
7980 __ bind(Lskip);
7981 %}
7982 ins_pipe(pipe_slow);
7983 %}
7984
7985 // ============================================================================
7986 // MemBar Instruction
7987
7988 instruct load_fence() %{
7989 match(LoadFence);
7990 ins_cost(VOLATILE_REF_COST);
7991
7992 format %{ "load_fence" %}
7993
7994 ins_encode %{
7995 __ membar(Assembler::LoadLoad|Assembler::LoadStore);
7996 %}
7997 ins_pipe(pipe_serial);
7998 %}
7999
8000 instruct unnecessary_membar_acquire() %{
8001 predicate(unnecessary_acquire(n));
8002 match(MemBarAcquire);
8003 ins_cost(0);
8004
8005 format %{ "membar_acquire (elided)" %}
8006
8007 ins_encode %{
8008 __ block_comment("membar_acquire (elided)");
8009 %}
8010
8011 ins_pipe(pipe_class_empty);
8012 %}
8013
8014 instruct membar_acquire() %{
8015 match(MemBarAcquire);
8016 ins_cost(VOLATILE_REF_COST);
8017
8018 format %{ "membar_acquire\n\t"
8019 "dmb ishld" %}
8020
8021 ins_encode %{
8022 __ block_comment("membar_acquire");
8023 __ membar(Assembler::LoadLoad|Assembler::LoadStore);
8024 %}
8025
8026 ins_pipe(pipe_serial);
8027 %}
8028
8029
8030 instruct membar_acquire_lock() %{
8031 match(MemBarAcquireLock);
8032 ins_cost(VOLATILE_REF_COST);
8033
8034 format %{ "membar_acquire_lock (elided)" %}
8035
8036 ins_encode %{
8037 __ block_comment("membar_acquire_lock (elided)");
8038 %}
8039
8040 ins_pipe(pipe_serial);
8041 %}
8042
8043 instruct store_fence() %{
8044 match(StoreFence);
8045 ins_cost(VOLATILE_REF_COST);
8046
8047 format %{ "store_fence" %}
8048
8049 ins_encode %{
8050 __ membar(Assembler::LoadStore|Assembler::StoreStore);
8051 %}
8052 ins_pipe(pipe_serial);
8053 %}
8054
8055 instruct unnecessary_membar_release() %{
8056 predicate(unnecessary_release(n));
8057 match(MemBarRelease);
8058 ins_cost(0);
8059
8060 format %{ "membar_release (elided)" %}
8061
8062 ins_encode %{
8063 __ block_comment("membar_release (elided)");
8064 %}
8065 ins_pipe(pipe_serial);
8066 %}
8067
8068 instruct membar_release() %{
8069 match(MemBarRelease);
8070 ins_cost(VOLATILE_REF_COST);
8071
8072 format %{ "membar_release\n\t"
8073 "dmb ishst\n\tdmb ishld" %}
8074
8075 ins_encode %{
8076 __ block_comment("membar_release");
8077 // These will be merged if AlwaysMergeDMB is enabled.
8078 __ membar(Assembler::StoreStore);
8079 __ membar(Assembler::LoadStore);
8080 %}
8081 ins_pipe(pipe_serial);
8082 %}
8083
8084 instruct membar_storestore() %{
8085 match(MemBarStoreStore);
8086 match(StoreStoreFence);
8087 ins_cost(VOLATILE_REF_COST);
8088
8089 format %{ "MEMBAR-store-store" %}
8090
8091 ins_encode %{
8092 __ membar(Assembler::StoreStore);
8093 %}
8094 ins_pipe(pipe_serial);
8095 %}
8096
8097 instruct membar_release_lock() %{
8098 match(MemBarReleaseLock);
8099 ins_cost(VOLATILE_REF_COST);
8100
8101 format %{ "membar_release_lock (elided)" %}
8102
8103 ins_encode %{
8104 __ block_comment("membar_release_lock (elided)");
8105 %}
8106
8107 ins_pipe(pipe_serial);
8108 %}
8109
8110 instruct unnecessary_membar_volatile() %{
8111 predicate(unnecessary_volatile(n));
8112 match(MemBarVolatile);
8113 ins_cost(0);
8114
8115 format %{ "membar_volatile (elided)" %}
8116
8117 ins_encode %{
8118 __ block_comment("membar_volatile (elided)");
8119 %}
8120
8121 ins_pipe(pipe_serial);
8122 %}
8123
8124 instruct membar_volatile() %{
8125 match(MemBarVolatile);
8126 ins_cost(VOLATILE_REF_COST*100);
8127
8128 format %{ "membar_volatile\n\t"
8129 "dmb ish"%}
8130
8131 ins_encode %{
8132 __ block_comment("membar_volatile");
8133 __ membar(Assembler::StoreLoad);
8134 %}
8135
8136 ins_pipe(pipe_serial);
8137 %}
8138
8139 // ============================================================================
8140 // Cast/Convert Instructions
8141
8142 instruct castX2P(iRegPNoSp dst, iRegL src) %{
8143 match(Set dst (CastX2P src));
8144
8145 ins_cost(INSN_COST);
8146 format %{ "mov $dst, $src\t# long -> ptr" %}
8147
8148 ins_encode %{
8149 if ($dst$$reg != $src$$reg) {
8150 __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8151 }
8152 %}
8153
8154 ins_pipe(ialu_reg);
8155 %}
8156
8157 instruct castI2N(iRegNNoSp dst, iRegI src) %{
8158 match(Set dst (CastI2N src));
8159
8160 ins_cost(INSN_COST);
8161 format %{ "mov $dst, $src\t# int -> narrow ptr" %}
8162
8163 ins_encode %{
8164 if ($dst$$reg != $src$$reg) {
8165 __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8166 }
8167 %}
8168
8169 ins_pipe(ialu_reg);
8170 %}
8171
8172 instruct castN2X(iRegLNoSp dst, iRegN src) %{
8173 match(Set dst (CastP2X src));
8174
8175 ins_cost(INSN_COST);
8176 format %{ "mov $dst, $src\t# ptr -> long" %}
8177
8178 ins_encode %{
8179 if ($dst$$reg != $src$$reg) {
8180 __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8181 }
8182 %}
8183
8184 ins_pipe(ialu_reg);
8185 %}
8186
8187 instruct castP2X(iRegLNoSp dst, iRegP src) %{
8188 match(Set dst (CastP2X src));
8189
8190 ins_cost(INSN_COST);
8191 format %{ "mov $dst, $src\t# ptr -> long" %}
8192
8193 ins_encode %{
8194 if ($dst$$reg != $src$$reg) {
8195 __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8196 }
8197 %}
8198
8199 ins_pipe(ialu_reg);
8200 %}
8201
8202 // Convert oop into int for vectors alignment masking
8203 instruct convP2I(iRegINoSp dst, iRegP src) %{
8204 match(Set dst (ConvL2I (CastP2X src)));
8205
8206 ins_cost(INSN_COST);
8207 format %{ "movw $dst, $src\t# ptr -> int" %}
8208 ins_encode %{
8209 __ movw($dst$$Register, $src$$Register);
8210 %}
8211
8212 ins_pipe(ialu_reg);
8213 %}
8214
8215 // Convert compressed oop into int for vectors alignment masking
8216 // in case of 32bit oops (heap < 4Gb).
8217 instruct convN2I(iRegINoSp dst, iRegN src)
8218 %{
8219 predicate(CompressedOops::shift() == 0);
8220 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
8221
8222 ins_cost(INSN_COST);
8223 format %{ "mov dst, $src\t# compressed ptr -> int" %}
8224 ins_encode %{
8225 __ movw($dst$$Register, $src$$Register);
8226 %}
8227
8228 ins_pipe(ialu_reg);
8229 %}
8230
8231
8232 // Convert oop pointer into compressed form
8233 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
8234 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
8235 match(Set dst (EncodeP src));
8236 effect(KILL cr);
8237 ins_cost(INSN_COST * 3);
8238 format %{ "encode_heap_oop $dst, $src" %}
8239 ins_encode %{
8240 Register s = $src$$Register;
8241 Register d = $dst$$Register;
8242 __ encode_heap_oop(d, s);
8243 %}
8244 ins_pipe(ialu_reg);
8245 %}
8246
8247 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
8248 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
8249 match(Set dst (EncodeP src));
8250 ins_cost(INSN_COST * 3);
8251 format %{ "encode_heap_oop_not_null $dst, $src" %}
8252 ins_encode %{
8253 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
8254 %}
8255 ins_pipe(ialu_reg);
8256 %}
8257
8258 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
8259 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
8260 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
8261 match(Set dst (DecodeN src));
8262 ins_cost(INSN_COST * 3);
8263 format %{ "decode_heap_oop $dst, $src" %}
8264 ins_encode %{
8265 Register s = $src$$Register;
8266 Register d = $dst$$Register;
8267 __ decode_heap_oop(d, s);
8268 %}
8269 ins_pipe(ialu_reg);
8270 %}
8271
8272 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
8273 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
8274 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
8275 match(Set dst (DecodeN src));
8276 ins_cost(INSN_COST * 3);
8277 format %{ "decode_heap_oop_not_null $dst, $src" %}
8278 ins_encode %{
8279 Register s = $src$$Register;
8280 Register d = $dst$$Register;
8281 __ decode_heap_oop_not_null(d, s);
8282 %}
8283 ins_pipe(ialu_reg);
8284 %}
8285
8286 // n.b. AArch64 implementations of encode_klass_not_null and
8287 // decode_klass_not_null do not modify the flags register so, unlike
8288 // Intel, we don't kill CR as a side effect here
8289
8290 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{
8291 match(Set dst (EncodePKlass src));
8292
8293 ins_cost(INSN_COST * 3);
8294 format %{ "encode_klass_not_null $dst,$src" %}
8295
8296 ins_encode %{
8297 Register src_reg = as_Register($src$$reg);
8298 Register dst_reg = as_Register($dst$$reg);
8299 __ encode_klass_not_null(dst_reg, src_reg);
8300 %}
8301
8302 ins_pipe(ialu_reg);
8303 %}
8304
8305 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{
8306 match(Set dst (DecodeNKlass src));
8307
8308 ins_cost(INSN_COST * 3);
8309 format %{ "decode_klass_not_null $dst,$src" %}
8310
8311 ins_encode %{
8312 Register src_reg = as_Register($src$$reg);
8313 Register dst_reg = as_Register($dst$$reg);
8314 if (dst_reg != src_reg) {
8315 __ decode_klass_not_null(dst_reg, src_reg);
8316 } else {
8317 __ decode_klass_not_null(dst_reg);
8318 }
8319 %}
8320
8321 ins_pipe(ialu_reg);
8322 %}
8323
8324 instruct checkCastPP(iRegPNoSp dst)
8325 %{
8326 match(Set dst (CheckCastPP dst));
8327
8328 size(0);
8329 format %{ "# checkcastPP of $dst" %}
8330 ins_encode(/* empty encoding */);
8331 ins_pipe(pipe_class_empty);
8332 %}
8333
8334 instruct castPP(iRegPNoSp dst)
8335 %{
8336 match(Set dst (CastPP dst));
8337
8338 size(0);
8339 format %{ "# castPP of $dst" %}
8340 ins_encode(/* empty encoding */);
8341 ins_pipe(pipe_class_empty);
8342 %}
8343
8344 instruct castII(iRegI dst)
8345 %{
8346 predicate(VerifyConstraintCasts == 0);
8347 match(Set dst (CastII dst));
8348
8349 size(0);
8350 format %{ "# castII of $dst" %}
8351 ins_encode(/* empty encoding */);
8352 ins_cost(0);
8353 ins_pipe(pipe_class_empty);
8354 %}
8355
8356 instruct castII_checked(iRegI dst, rFlagsReg cr)
8357 %{
8358 predicate(VerifyConstraintCasts > 0);
8359 match(Set dst (CastII dst));
8360 effect(KILL cr);
8361
8362 format %{ "# castII_checked of $dst" %}
8363 ins_encode %{
8364 __ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register, rscratch1);
8365 %}
8366 ins_pipe(pipe_slow);
8367 %}
8368
8369 instruct castLL(iRegL dst)
8370 %{
8371 predicate(VerifyConstraintCasts == 0);
8372 match(Set dst (CastLL dst));
8373
8374 size(0);
8375 format %{ "# castLL of $dst" %}
8376 ins_encode(/* empty encoding */);
8377 ins_cost(0);
8378 ins_pipe(pipe_class_empty);
8379 %}
8380
8381 instruct castLL_checked(iRegL dst, rFlagsReg cr)
8382 %{
8383 predicate(VerifyConstraintCasts > 0);
8384 match(Set dst (CastLL dst));
8385 effect(KILL cr);
8386
8387 format %{ "# castLL_checked of $dst" %}
8388 ins_encode %{
8389 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, rscratch1);
8390 %}
8391 ins_pipe(pipe_slow);
8392 %}
8393
8394 instruct castHH(vRegF dst)
8395 %{
8396 match(Set dst (CastHH dst));
8397 size(0);
8398 format %{ "# castHH of $dst" %}
8399 ins_encode(/* empty encoding */);
8400 ins_cost(0);
8401 ins_pipe(pipe_class_empty);
8402 %}
8403
8404 instruct castFF(vRegF dst)
8405 %{
8406 match(Set dst (CastFF dst));
8407
8408 size(0);
8409 format %{ "# castFF of $dst" %}
8410 ins_encode(/* empty encoding */);
8411 ins_cost(0);
8412 ins_pipe(pipe_class_empty);
8413 %}
8414
8415 instruct castDD(vRegD dst)
8416 %{
8417 match(Set dst (CastDD dst));
8418
8419 size(0);
8420 format %{ "# castDD of $dst" %}
8421 ins_encode(/* empty encoding */);
8422 ins_cost(0);
8423 ins_pipe(pipe_class_empty);
8424 %}
8425
8426 instruct castVV(vReg dst)
8427 %{
8428 match(Set dst (CastVV dst));
8429
8430 size(0);
8431 format %{ "# castVV of $dst" %}
8432 ins_encode(/* empty encoding */);
8433 ins_cost(0);
8434 ins_pipe(pipe_class_empty);
8435 %}
8436
8437 instruct castVVMask(pRegGov dst)
8438 %{
8439 match(Set dst (CastVV dst));
8440
8441 size(0);
8442 format %{ "# castVV of $dst" %}
8443 ins_encode(/* empty encoding */);
8444 ins_cost(0);
8445 ins_pipe(pipe_class_empty);
8446 %}
8447
8448 // ============================================================================
8449 // Atomic operation instructions
8450 //
8451
8452 // standard CompareAndSwapX when we are using barriers
8453 // these have higher priority than the rules selected by a predicate
8454
8455 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher
8456 // can't match them
8457
8458 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8459
8460 match(Set res (CompareAndSwapB mem (Binary oldval newval)));
8461 ins_cost(2 * VOLATILE_REF_COST);
8462
8463 effect(KILL cr);
8464
8465 format %{
8466 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8467 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8468 %}
8469
8470 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval),
8471 aarch64_enc_cset_eq(res));
8472
8473 ins_pipe(pipe_slow);
8474 %}
8475
8476 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8477
8478 match(Set res (CompareAndSwapS mem (Binary oldval newval)));
8479 ins_cost(2 * VOLATILE_REF_COST);
8480
8481 effect(KILL cr);
8482
8483 format %{
8484 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8485 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8486 %}
8487
8488 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval),
8489 aarch64_enc_cset_eq(res));
8490
8491 ins_pipe(pipe_slow);
8492 %}
8493
8494 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8495
8496 match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8497 ins_cost(2 * VOLATILE_REF_COST);
8498
8499 effect(KILL cr);
8500
8501 format %{
8502 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8503 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8504 %}
8505
8506 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8507 aarch64_enc_cset_eq(res));
8508
8509 ins_pipe(pipe_slow);
8510 %}
8511
8512 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8513
8514 match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8515 ins_cost(2 * VOLATILE_REF_COST);
8516
8517 effect(KILL cr);
8518
8519 format %{
8520 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8521 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8522 %}
8523
8524 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8525 aarch64_enc_cset_eq(res));
8526
8527 ins_pipe(pipe_slow);
8528 %}
8529
8530 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8531
8532 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8533 predicate(n->as_LoadStore()->barrier_data() == 0);
8534 ins_cost(2 * VOLATILE_REF_COST);
8535
8536 effect(KILL cr);
8537
8538 format %{
8539 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8540 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8541 %}
8542
8543 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8544 aarch64_enc_cset_eq(res));
8545
8546 ins_pipe(pipe_slow);
8547 %}
8548
8549 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8550
8551 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8552 predicate(n->as_LoadStore()->barrier_data() == 0);
8553 ins_cost(2 * VOLATILE_REF_COST);
8554
8555 effect(KILL cr);
8556
8557 format %{
8558 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8559 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8560 %}
8561
8562 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8563 aarch64_enc_cset_eq(res));
8564
8565 ins_pipe(pipe_slow);
8566 %}
8567
8568 // alternative CompareAndSwapX when we are eliding barriers
8569
8570 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8571
8572 predicate(needs_acquiring_load_exclusive(n));
8573 match(Set res (CompareAndSwapB mem (Binary oldval newval)));
8574 ins_cost(VOLATILE_REF_COST);
8575
8576 effect(KILL cr);
8577
8578 format %{
8579 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8580 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8581 %}
8582
8583 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval),
8584 aarch64_enc_cset_eq(res));
8585
8586 ins_pipe(pipe_slow);
8587 %}
8588
8589 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8590
8591 predicate(needs_acquiring_load_exclusive(n));
8592 match(Set res (CompareAndSwapS mem (Binary oldval newval)));
8593 ins_cost(VOLATILE_REF_COST);
8594
8595 effect(KILL cr);
8596
8597 format %{
8598 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8599 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8600 %}
8601
8602 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval),
8603 aarch64_enc_cset_eq(res));
8604
8605 ins_pipe(pipe_slow);
8606 %}
8607
8608 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8609
8610 predicate(needs_acquiring_load_exclusive(n));
8611 match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8612 ins_cost(VOLATILE_REF_COST);
8613
8614 effect(KILL cr);
8615
8616 format %{
8617 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8618 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8619 %}
8620
8621 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8622 aarch64_enc_cset_eq(res));
8623
8624 ins_pipe(pipe_slow);
8625 %}
8626
8627 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8628
8629 predicate(needs_acquiring_load_exclusive(n));
8630 match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8631 ins_cost(VOLATILE_REF_COST);
8632
8633 effect(KILL cr);
8634
8635 format %{
8636 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8637 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8638 %}
8639
8640 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8641 aarch64_enc_cset_eq(res));
8642
8643 ins_pipe(pipe_slow);
8644 %}
8645
8646 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8647
8648 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
8649 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8650 ins_cost(VOLATILE_REF_COST);
8651
8652 effect(KILL cr);
8653
8654 format %{
8655 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8656 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8657 %}
8658
8659 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8660 aarch64_enc_cset_eq(res));
8661
8662 ins_pipe(pipe_slow);
8663 %}
8664
8665 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8666
8667 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
8668 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8669 ins_cost(VOLATILE_REF_COST);
8670
8671 effect(KILL cr);
8672
8673 format %{
8674 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8675 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8676 %}
8677
8678 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8679 aarch64_enc_cset_eq(res));
8680
8681 ins_pipe(pipe_slow);
8682 %}
8683
8684
8685 // ---------------------------------------------------------------------
8686
8687 // BEGIN This section of the file is automatically generated. Do not edit --------------
8688
8689 // Sundry CAS operations. Note that release is always true,
8690 // regardless of the memory ordering of the CAS. This is because we
8691 // need the volatile case to be sequentially consistent but there is
8692 // no trailing StoreLoad barrier emitted by C2. Unfortunately we
8693 // can't check the type of memory ordering here, so we always emit a
8694 // STLXR.
8695
8696 // This section is generated from cas.m4
8697
8698
8699 // This pattern is generated automatically from cas.m4.
8700 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8701 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8702 match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
8703 ins_cost(2 * VOLATILE_REF_COST);
8704 effect(TEMP_DEF res, KILL cr);
8705 format %{
8706 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8707 %}
8708 ins_encode %{
8709 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8710 Assembler::byte, /*acquire*/ false, /*release*/ true,
8711 /*weak*/ false, $res$$Register);
8712 __ sxtbw($res$$Register, $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 compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8720 match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
8721 ins_cost(2 * VOLATILE_REF_COST);
8722 effect(TEMP_DEF res, KILL cr);
8723 format %{
8724 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8725 %}
8726 ins_encode %{
8727 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8728 Assembler::halfword, /*acquire*/ false, /*release*/ true,
8729 /*weak*/ false, $res$$Register);
8730 __ sxthw($res$$Register, $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 compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8738 match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
8739 ins_cost(2 * VOLATILE_REF_COST);
8740 effect(TEMP_DEF res, KILL cr);
8741 format %{
8742 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8743 %}
8744 ins_encode %{
8745 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8746 Assembler::word, /*acquire*/ false, /*release*/ true,
8747 /*weak*/ false, $res$$Register);
8748 %}
8749 ins_pipe(pipe_slow);
8750 %}
8751
8752 // This pattern is generated automatically from cas.m4.
8753 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8754 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8755 match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
8756 ins_cost(2 * VOLATILE_REF_COST);
8757 effect(TEMP_DEF res, KILL cr);
8758 format %{
8759 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8760 %}
8761 ins_encode %{
8762 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8763 Assembler::xword, /*acquire*/ false, /*release*/ true,
8764 /*weak*/ false, $res$$Register);
8765 %}
8766 ins_pipe(pipe_slow);
8767 %}
8768
8769 // This pattern is generated automatically from cas.m4.
8770 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8771 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8772 predicate(n->as_LoadStore()->barrier_data() == 0);
8773 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
8774 ins_cost(2 * VOLATILE_REF_COST);
8775 effect(TEMP_DEF res, KILL cr);
8776 format %{
8777 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8778 %}
8779 ins_encode %{
8780 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8781 Assembler::word, /*acquire*/ false, /*release*/ true,
8782 /*weak*/ false, $res$$Register);
8783 %}
8784 ins_pipe(pipe_slow);
8785 %}
8786
8787 // This pattern is generated automatically from cas.m4.
8788 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8789 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8790 predicate(n->as_LoadStore()->barrier_data() == 0);
8791 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
8792 ins_cost(2 * VOLATILE_REF_COST);
8793 effect(TEMP_DEF res, KILL cr);
8794 format %{
8795 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8796 %}
8797 ins_encode %{
8798 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8799 Assembler::xword, /*acquire*/ false, /*release*/ true,
8800 /*weak*/ false, $res$$Register);
8801 %}
8802 ins_pipe(pipe_slow);
8803 %}
8804
8805 // This pattern is generated automatically from cas.m4.
8806 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8807 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8808 predicate(needs_acquiring_load_exclusive(n));
8809 match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
8810 ins_cost(VOLATILE_REF_COST);
8811 effect(TEMP_DEF res, KILL cr);
8812 format %{
8813 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8814 %}
8815 ins_encode %{
8816 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8817 Assembler::byte, /*acquire*/ true, /*release*/ true,
8818 /*weak*/ false, $res$$Register);
8819 __ sxtbw($res$$Register, $res$$Register);
8820 %}
8821 ins_pipe(pipe_slow);
8822 %}
8823
8824 // This pattern is generated automatically from cas.m4.
8825 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8826 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8827 predicate(needs_acquiring_load_exclusive(n));
8828 match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
8829 ins_cost(VOLATILE_REF_COST);
8830 effect(TEMP_DEF res, KILL cr);
8831 format %{
8832 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8833 %}
8834 ins_encode %{
8835 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8836 Assembler::halfword, /*acquire*/ true, /*release*/ true,
8837 /*weak*/ false, $res$$Register);
8838 __ sxthw($res$$Register, $res$$Register);
8839 %}
8840 ins_pipe(pipe_slow);
8841 %}
8842
8843 // This pattern is generated automatically from cas.m4.
8844 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8845 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8846 predicate(needs_acquiring_load_exclusive(n));
8847 match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
8848 ins_cost(VOLATILE_REF_COST);
8849 effect(TEMP_DEF res, KILL cr);
8850 format %{
8851 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8852 %}
8853 ins_encode %{
8854 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8855 Assembler::word, /*acquire*/ true, /*release*/ true,
8856 /*weak*/ false, $res$$Register);
8857 %}
8858 ins_pipe(pipe_slow);
8859 %}
8860
8861 // This pattern is generated automatically from cas.m4.
8862 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8863 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8864 predicate(needs_acquiring_load_exclusive(n));
8865 match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
8866 ins_cost(VOLATILE_REF_COST);
8867 effect(TEMP_DEF res, KILL cr);
8868 format %{
8869 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8870 %}
8871 ins_encode %{
8872 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8873 Assembler::xword, /*acquire*/ true, /*release*/ true,
8874 /*weak*/ false, $res$$Register);
8875 %}
8876 ins_pipe(pipe_slow);
8877 %}
8878
8879 // This pattern is generated automatically from cas.m4.
8880 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8881 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8882 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
8883 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
8884 ins_cost(VOLATILE_REF_COST);
8885 effect(TEMP_DEF res, KILL cr);
8886 format %{
8887 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
8888 %}
8889 ins_encode %{
8890 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8891 Assembler::word, /*acquire*/ true, /*release*/ true,
8892 /*weak*/ false, $res$$Register);
8893 %}
8894 ins_pipe(pipe_slow);
8895 %}
8896
8897 // This pattern is generated automatically from cas.m4.
8898 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8899 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8900 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
8901 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
8902 ins_cost(VOLATILE_REF_COST);
8903 effect(TEMP_DEF res, KILL cr);
8904 format %{
8905 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
8906 %}
8907 ins_encode %{
8908 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8909 Assembler::xword, /*acquire*/ true, /*release*/ true,
8910 /*weak*/ false, $res$$Register);
8911 %}
8912 ins_pipe(pipe_slow);
8913 %}
8914
8915 // This pattern is generated automatically from cas.m4.
8916 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8917 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8918 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
8919 ins_cost(2 * VOLATILE_REF_COST);
8920 effect(KILL cr);
8921 format %{
8922 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
8923 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8924 %}
8925 ins_encode %{
8926 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8927 Assembler::byte, /*acquire*/ false, /*release*/ true,
8928 /*weak*/ true, noreg);
8929 __ csetw($res$$Register, Assembler::EQ);
8930 %}
8931 ins_pipe(pipe_slow);
8932 %}
8933
8934 // This pattern is generated automatically from cas.m4.
8935 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8936 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8937 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
8938 ins_cost(2 * VOLATILE_REF_COST);
8939 effect(KILL cr);
8940 format %{
8941 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
8942 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8943 %}
8944 ins_encode %{
8945 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8946 Assembler::halfword, /*acquire*/ false, /*release*/ true,
8947 /*weak*/ true, noreg);
8948 __ csetw($res$$Register, Assembler::EQ);
8949 %}
8950 ins_pipe(pipe_slow);
8951 %}
8952
8953 // This pattern is generated automatically from cas.m4.
8954 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8955 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
8956 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
8957 ins_cost(2 * VOLATILE_REF_COST);
8958 effect(KILL cr);
8959 format %{
8960 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
8961 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8962 %}
8963 ins_encode %{
8964 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8965 Assembler::word, /*acquire*/ false, /*release*/ true,
8966 /*weak*/ true, noreg);
8967 __ csetw($res$$Register, Assembler::EQ);
8968 %}
8969 ins_pipe(pipe_slow);
8970 %}
8971
8972 // This pattern is generated automatically from cas.m4.
8973 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8974 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
8975 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
8976 ins_cost(2 * VOLATILE_REF_COST);
8977 effect(KILL cr);
8978 format %{
8979 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
8980 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8981 %}
8982 ins_encode %{
8983 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
8984 Assembler::xword, /*acquire*/ false, /*release*/ true,
8985 /*weak*/ true, noreg);
8986 __ csetw($res$$Register, Assembler::EQ);
8987 %}
8988 ins_pipe(pipe_slow);
8989 %}
8990
8991 // This pattern is generated automatically from cas.m4.
8992 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
8993 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
8994 predicate(n->as_LoadStore()->barrier_data() == 0);
8995 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
8996 ins_cost(2 * VOLATILE_REF_COST);
8997 effect(KILL cr);
8998 format %{
8999 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9000 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9001 %}
9002 ins_encode %{
9003 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9004 Assembler::word, /*acquire*/ false, /*release*/ true,
9005 /*weak*/ true, noreg);
9006 __ csetw($res$$Register, Assembler::EQ);
9007 %}
9008 ins_pipe(pipe_slow);
9009 %}
9010
9011 // This pattern is generated automatically from cas.m4.
9012 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9013 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9014 predicate(n->as_LoadStore()->barrier_data() == 0);
9015 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
9016 ins_cost(2 * VOLATILE_REF_COST);
9017 effect(KILL cr);
9018 format %{
9019 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
9020 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9021 %}
9022 ins_encode %{
9023 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9024 Assembler::xword, /*acquire*/ false, /*release*/ true,
9025 /*weak*/ true, noreg);
9026 __ csetw($res$$Register, Assembler::EQ);
9027 %}
9028 ins_pipe(pipe_slow);
9029 %}
9030
9031 // This pattern is generated automatically from cas.m4.
9032 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9033 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9034 predicate(needs_acquiring_load_exclusive(n));
9035 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
9036 ins_cost(VOLATILE_REF_COST);
9037 effect(KILL cr);
9038 format %{
9039 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
9040 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9041 %}
9042 ins_encode %{
9043 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9044 Assembler::byte, /*acquire*/ true, /*release*/ true,
9045 /*weak*/ true, noreg);
9046 __ csetw($res$$Register, Assembler::EQ);
9047 %}
9048 ins_pipe(pipe_slow);
9049 %}
9050
9051 // This pattern is generated automatically from cas.m4.
9052 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9053 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9054 predicate(needs_acquiring_load_exclusive(n));
9055 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
9056 ins_cost(VOLATILE_REF_COST);
9057 effect(KILL cr);
9058 format %{
9059 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
9060 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9061 %}
9062 ins_encode %{
9063 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9064 Assembler::halfword, /*acquire*/ true, /*release*/ true,
9065 /*weak*/ true, noreg);
9066 __ csetw($res$$Register, Assembler::EQ);
9067 %}
9068 ins_pipe(pipe_slow);
9069 %}
9070
9071 // This pattern is generated automatically from cas.m4.
9072 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9073 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9074 predicate(needs_acquiring_load_exclusive(n));
9075 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
9076 ins_cost(VOLATILE_REF_COST);
9077 effect(KILL cr);
9078 format %{
9079 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
9080 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9081 %}
9082 ins_encode %{
9083 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9084 Assembler::word, /*acquire*/ true, /*release*/ true,
9085 /*weak*/ true, noreg);
9086 __ csetw($res$$Register, Assembler::EQ);
9087 %}
9088 ins_pipe(pipe_slow);
9089 %}
9090
9091 // This pattern is generated automatically from cas.m4.
9092 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9093 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
9094 predicate(needs_acquiring_load_exclusive(n));
9095 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
9096 ins_cost(VOLATILE_REF_COST);
9097 effect(KILL cr);
9098 format %{
9099 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
9100 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9101 %}
9102 ins_encode %{
9103 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9104 Assembler::xword, /*acquire*/ true, /*release*/ true,
9105 /*weak*/ true, noreg);
9106 __ csetw($res$$Register, Assembler::EQ);
9107 %}
9108 ins_pipe(pipe_slow);
9109 %}
9110
9111 // This pattern is generated automatically from cas.m4.
9112 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9113 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
9114 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
9115 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
9116 ins_cost(VOLATILE_REF_COST);
9117 effect(KILL cr);
9118 format %{
9119 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9120 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9121 %}
9122 ins_encode %{
9123 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9124 Assembler::word, /*acquire*/ true, /*release*/ true,
9125 /*weak*/ true, noreg);
9126 __ csetw($res$$Register, Assembler::EQ);
9127 %}
9128 ins_pipe(pipe_slow);
9129 %}
9130
9131 // This pattern is generated automatically from cas.m4.
9132 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9133 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9134 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
9135 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
9136 ins_cost(VOLATILE_REF_COST);
9137 effect(KILL cr);
9138 format %{
9139 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
9140 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9141 %}
9142 ins_encode %{
9143 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9144 Assembler::xword, /*acquire*/ true, /*release*/ true,
9145 /*weak*/ true, noreg);
9146 __ csetw($res$$Register, Assembler::EQ);
9147 %}
9148 ins_pipe(pipe_slow);
9149 %}
9150
9151 // END This section of the file is automatically generated. Do not edit --------------
9152 // ---------------------------------------------------------------------
9153
9154 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
9155 match(Set prev (GetAndSetI mem newv));
9156 ins_cost(2 * VOLATILE_REF_COST);
9157 format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
9158 ins_encode %{
9159 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9160 %}
9161 ins_pipe(pipe_serial);
9162 %}
9163
9164 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
9165 match(Set prev (GetAndSetL mem newv));
9166 ins_cost(2 * VOLATILE_REF_COST);
9167 format %{ "atomic_xchg $prev, $newv, [$mem]" %}
9168 ins_encode %{
9169 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
9170 %}
9171 ins_pipe(pipe_serial);
9172 %}
9173
9174 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
9175 predicate(n->as_LoadStore()->barrier_data() == 0);
9176 match(Set prev (GetAndSetN mem newv));
9177 ins_cost(2 * VOLATILE_REF_COST);
9178 format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
9179 ins_encode %{
9180 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9181 %}
9182 ins_pipe(pipe_serial);
9183 %}
9184
9185 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
9186 predicate(n->as_LoadStore()->barrier_data() == 0);
9187 match(Set prev (GetAndSetP mem newv));
9188 ins_cost(2 * VOLATILE_REF_COST);
9189 format %{ "atomic_xchg $prev, $newv, [$mem]" %}
9190 ins_encode %{
9191 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
9192 %}
9193 ins_pipe(pipe_serial);
9194 %}
9195
9196 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{
9197 predicate(needs_acquiring_load_exclusive(n));
9198 match(Set prev (GetAndSetI mem newv));
9199 ins_cost(VOLATILE_REF_COST);
9200 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %}
9201 ins_encode %{
9202 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9203 %}
9204 ins_pipe(pipe_serial);
9205 %}
9206
9207 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{
9208 predicate(needs_acquiring_load_exclusive(n));
9209 match(Set prev (GetAndSetL mem newv));
9210 ins_cost(VOLATILE_REF_COST);
9211 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %}
9212 ins_encode %{
9213 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
9214 %}
9215 ins_pipe(pipe_serial);
9216 %}
9217
9218 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{
9219 predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
9220 match(Set prev (GetAndSetN mem newv));
9221 ins_cost(VOLATILE_REF_COST);
9222 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %}
9223 ins_encode %{
9224 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9225 %}
9226 ins_pipe(pipe_serial);
9227 %}
9228
9229 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{
9230 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
9231 match(Set prev (GetAndSetP mem newv));
9232 ins_cost(VOLATILE_REF_COST);
9233 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %}
9234 ins_encode %{
9235 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
9236 %}
9237 ins_pipe(pipe_serial);
9238 %}
9239
9240
9241 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{
9242 match(Set newval (GetAndAddL mem incr));
9243 ins_cost(2 * VOLATILE_REF_COST + 1);
9244 format %{ "get_and_addL $newval, [$mem], $incr" %}
9245 ins_encode %{
9246 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base));
9247 %}
9248 ins_pipe(pipe_serial);
9249 %}
9250
9251 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{
9252 predicate(n->as_LoadStore()->result_not_used());
9253 match(Set dummy (GetAndAddL mem incr));
9254 ins_cost(2 * VOLATILE_REF_COST);
9255 format %{ "get_and_addL [$mem], $incr" %}
9256 ins_encode %{
9257 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base));
9258 %}
9259 ins_pipe(pipe_serial);
9260 %}
9261
9262 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
9263 match(Set newval (GetAndAddL mem incr));
9264 ins_cost(2 * VOLATILE_REF_COST + 1);
9265 format %{ "get_and_addL $newval, [$mem], $incr" %}
9266 ins_encode %{
9267 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base));
9268 %}
9269 ins_pipe(pipe_serial);
9270 %}
9271
9272 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{
9273 predicate(n->as_LoadStore()->result_not_used());
9274 match(Set dummy (GetAndAddL mem incr));
9275 ins_cost(2 * VOLATILE_REF_COST);
9276 format %{ "get_and_addL [$mem], $incr" %}
9277 ins_encode %{
9278 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base));
9279 %}
9280 ins_pipe(pipe_serial);
9281 %}
9282
9283 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
9284 match(Set newval (GetAndAddI mem incr));
9285 ins_cost(2 * VOLATILE_REF_COST + 1);
9286 format %{ "get_and_addI $newval, [$mem], $incr" %}
9287 ins_encode %{
9288 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base));
9289 %}
9290 ins_pipe(pipe_serial);
9291 %}
9292
9293 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{
9294 predicate(n->as_LoadStore()->result_not_used());
9295 match(Set dummy (GetAndAddI mem incr));
9296 ins_cost(2 * VOLATILE_REF_COST);
9297 format %{ "get_and_addI [$mem], $incr" %}
9298 ins_encode %{
9299 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base));
9300 %}
9301 ins_pipe(pipe_serial);
9302 %}
9303
9304 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{
9305 match(Set newval (GetAndAddI mem incr));
9306 ins_cost(2 * VOLATILE_REF_COST + 1);
9307 format %{ "get_and_addI $newval, [$mem], $incr" %}
9308 ins_encode %{
9309 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base));
9310 %}
9311 ins_pipe(pipe_serial);
9312 %}
9313
9314 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{
9315 predicate(n->as_LoadStore()->result_not_used());
9316 match(Set dummy (GetAndAddI mem incr));
9317 ins_cost(2 * VOLATILE_REF_COST);
9318 format %{ "get_and_addI [$mem], $incr" %}
9319 ins_encode %{
9320 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base));
9321 %}
9322 ins_pipe(pipe_serial);
9323 %}
9324
9325 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{
9326 predicate(needs_acquiring_load_exclusive(n));
9327 match(Set newval (GetAndAddL mem incr));
9328 ins_cost(VOLATILE_REF_COST + 1);
9329 format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
9330 ins_encode %{
9331 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base));
9332 %}
9333 ins_pipe(pipe_serial);
9334 %}
9335
9336 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{
9337 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9338 match(Set dummy (GetAndAddL mem incr));
9339 ins_cost(VOLATILE_REF_COST);
9340 format %{ "get_and_addL_acq [$mem], $incr" %}
9341 ins_encode %{
9342 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base));
9343 %}
9344 ins_pipe(pipe_serial);
9345 %}
9346
9347 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
9348 predicate(needs_acquiring_load_exclusive(n));
9349 match(Set newval (GetAndAddL mem incr));
9350 ins_cost(VOLATILE_REF_COST + 1);
9351 format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
9352 ins_encode %{
9353 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base));
9354 %}
9355 ins_pipe(pipe_serial);
9356 %}
9357
9358 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{
9359 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9360 match(Set dummy (GetAndAddL mem incr));
9361 ins_cost(VOLATILE_REF_COST);
9362 format %{ "get_and_addL_acq [$mem], $incr" %}
9363 ins_encode %{
9364 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base));
9365 %}
9366 ins_pipe(pipe_serial);
9367 %}
9368
9369 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
9370 predicate(needs_acquiring_load_exclusive(n));
9371 match(Set newval (GetAndAddI mem incr));
9372 ins_cost(VOLATILE_REF_COST + 1);
9373 format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
9374 ins_encode %{
9375 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base));
9376 %}
9377 ins_pipe(pipe_serial);
9378 %}
9379
9380 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{
9381 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9382 match(Set dummy (GetAndAddI mem incr));
9383 ins_cost(VOLATILE_REF_COST);
9384 format %{ "get_and_addI_acq [$mem], $incr" %}
9385 ins_encode %{
9386 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base));
9387 %}
9388 ins_pipe(pipe_serial);
9389 %}
9390
9391 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{
9392 predicate(needs_acquiring_load_exclusive(n));
9393 match(Set newval (GetAndAddI mem incr));
9394 ins_cost(VOLATILE_REF_COST + 1);
9395 format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
9396 ins_encode %{
9397 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base));
9398 %}
9399 ins_pipe(pipe_serial);
9400 %}
9401
9402 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{
9403 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9404 match(Set dummy (GetAndAddI mem incr));
9405 ins_cost(VOLATILE_REF_COST);
9406 format %{ "get_and_addI_acq [$mem], $incr" %}
9407 ins_encode %{
9408 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base));
9409 %}
9410 ins_pipe(pipe_serial);
9411 %}
9412
9413 // Manifest a CmpU result in an integer register.
9414 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
9415 instruct cmpU3_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg flags)
9416 %{
9417 match(Set dst (CmpU3 src1 src2));
9418 effect(KILL flags);
9419
9420 ins_cost(INSN_COST * 3);
9421 format %{
9422 "cmpw $src1, $src2\n\t"
9423 "csetw $dst, ne\n\t"
9424 "cnegw $dst, lo\t# CmpU3(reg)"
9425 %}
9426 ins_encode %{
9427 __ cmpw($src1$$Register, $src2$$Register);
9428 __ csetw($dst$$Register, Assembler::NE);
9429 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
9430 %}
9431
9432 ins_pipe(pipe_class_default);
9433 %}
9434
9435 instruct cmpU3_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2, rFlagsReg flags)
9436 %{
9437 match(Set dst (CmpU3 src1 src2));
9438 effect(KILL flags);
9439
9440 ins_cost(INSN_COST * 3);
9441 format %{
9442 "subsw zr, $src1, $src2\n\t"
9443 "csetw $dst, ne\n\t"
9444 "cnegw $dst, lo\t# CmpU3(imm)"
9445 %}
9446 ins_encode %{
9447 __ subsw(zr, $src1$$Register, (int32_t)$src2$$constant);
9448 __ csetw($dst$$Register, Assembler::NE);
9449 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
9450 %}
9451
9452 ins_pipe(pipe_class_default);
9453 %}
9454
9455 // Manifest a CmpUL result in an integer register.
9456 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
9457 instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
9458 %{
9459 match(Set dst (CmpUL3 src1 src2));
9460 effect(KILL flags);
9461
9462 ins_cost(INSN_COST * 3);
9463 format %{
9464 "cmp $src1, $src2\n\t"
9465 "csetw $dst, ne\n\t"
9466 "cnegw $dst, lo\t# CmpUL3(reg)"
9467 %}
9468 ins_encode %{
9469 __ cmp($src1$$Register, $src2$$Register);
9470 __ csetw($dst$$Register, Assembler::NE);
9471 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
9472 %}
9473
9474 ins_pipe(pipe_class_default);
9475 %}
9476
9477 instruct cmpUL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags)
9478 %{
9479 match(Set dst (CmpUL3 src1 src2));
9480 effect(KILL flags);
9481
9482 ins_cost(INSN_COST * 3);
9483 format %{
9484 "subs zr, $src1, $src2\n\t"
9485 "csetw $dst, ne\n\t"
9486 "cnegw $dst, lo\t# CmpUL3(imm)"
9487 %}
9488 ins_encode %{
9489 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant);
9490 __ csetw($dst$$Register, Assembler::NE);
9491 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO);
9492 %}
9493
9494 ins_pipe(pipe_class_default);
9495 %}
9496
9497 // Manifest a CmpL result in an integer register.
9498 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
9499 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
9500 %{
9501 match(Set dst (CmpL3 src1 src2));
9502 effect(KILL flags);
9503
9504 ins_cost(INSN_COST * 3);
9505 format %{
9506 "cmp $src1, $src2\n\t"
9507 "csetw $dst, ne\n\t"
9508 "cnegw $dst, lt\t# CmpL3(reg)"
9509 %}
9510 ins_encode %{
9511 __ cmp($src1$$Register, $src2$$Register);
9512 __ csetw($dst$$Register, Assembler::NE);
9513 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
9514 %}
9515
9516 ins_pipe(pipe_class_default);
9517 %}
9518
9519 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags)
9520 %{
9521 match(Set dst (CmpL3 src1 src2));
9522 effect(KILL flags);
9523
9524 ins_cost(INSN_COST * 3);
9525 format %{
9526 "subs zr, $src1, $src2\n\t"
9527 "csetw $dst, ne\n\t"
9528 "cnegw $dst, lt\t# CmpL3(imm)"
9529 %}
9530 ins_encode %{
9531 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant);
9532 __ csetw($dst$$Register, Assembler::NE);
9533 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
9534 %}
9535
9536 ins_pipe(pipe_class_default);
9537 %}
9538
9539 // ============================================================================
9540 // Conditional Move Instructions
9541
9542 // n.b. we have identical rules for both a signed compare op (cmpOp)
9543 // and an unsigned compare op (cmpOpU). it would be nice if we could
9544 // define an op class which merged both inputs and use it to type the
9545 // argument to a single rule. unfortunatelyt his fails because the
9546 // opclass does not live up to the COND_INTER interface of its
9547 // component operands. When the generic code tries to negate the
9548 // operand it ends up running the generci Machoper::negate method
9549 // which throws a ShouldNotHappen. So, we have to provide two flavours
9550 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh).
9551
9552 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9553 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9554
9555 ins_cost(INSN_COST * 2);
9556 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %}
9557
9558 ins_encode %{
9559 __ cselw(as_Register($dst$$reg),
9560 as_Register($src2$$reg),
9561 as_Register($src1$$reg),
9562 (Assembler::Condition)$cmp$$cmpcode);
9563 %}
9564
9565 ins_pipe(icond_reg_reg);
9566 %}
9567
9568 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9569 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9570
9571 ins_cost(INSN_COST * 2);
9572 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %}
9573
9574 ins_encode %{
9575 __ cselw(as_Register($dst$$reg),
9576 as_Register($src2$$reg),
9577 as_Register($src1$$reg),
9578 (Assembler::Condition)$cmp$$cmpcode);
9579 %}
9580
9581 ins_pipe(icond_reg_reg);
9582 %}
9583
9584 // special cases where one arg is zero
9585
9586 // n.b. this is selected in preference to the rule above because it
9587 // avoids loading constant 0 into a source register
9588
9589 // TODO
9590 // we ought only to be able to cull one of these variants as the ideal
9591 // transforms ought always to order the zero consistently (to left/right?)
9592
9593 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
9594 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
9595
9596 ins_cost(INSN_COST * 2);
9597 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %}
9598
9599 ins_encode %{
9600 __ cselw(as_Register($dst$$reg),
9601 as_Register($src$$reg),
9602 zr,
9603 (Assembler::Condition)$cmp$$cmpcode);
9604 %}
9605
9606 ins_pipe(icond_reg);
9607 %}
9608
9609 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
9610 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
9611
9612 ins_cost(INSN_COST * 2);
9613 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %}
9614
9615 ins_encode %{
9616 __ cselw(as_Register($dst$$reg),
9617 as_Register($src$$reg),
9618 zr,
9619 (Assembler::Condition)$cmp$$cmpcode);
9620 %}
9621
9622 ins_pipe(icond_reg);
9623 %}
9624
9625 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
9626 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
9627
9628 ins_cost(INSN_COST * 2);
9629 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %}
9630
9631 ins_encode %{
9632 __ cselw(as_Register($dst$$reg),
9633 zr,
9634 as_Register($src$$reg),
9635 (Assembler::Condition)$cmp$$cmpcode);
9636 %}
9637
9638 ins_pipe(icond_reg);
9639 %}
9640
9641 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
9642 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
9643
9644 ins_cost(INSN_COST * 2);
9645 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %}
9646
9647 ins_encode %{
9648 __ cselw(as_Register($dst$$reg),
9649 zr,
9650 as_Register($src$$reg),
9651 (Assembler::Condition)$cmp$$cmpcode);
9652 %}
9653
9654 ins_pipe(icond_reg);
9655 %}
9656
9657 // special case for creating a boolean 0 or 1
9658
9659 // n.b. this is selected in preference to the rule above because it
9660 // avoids loading constants 0 and 1 into a source register
9661
9662 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
9663 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
9664
9665 ins_cost(INSN_COST * 2);
9666 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %}
9667
9668 ins_encode %{
9669 // equivalently
9670 // cset(as_Register($dst$$reg),
9671 // negate_condition((Assembler::Condition)$cmp$$cmpcode));
9672 __ csincw(as_Register($dst$$reg),
9673 zr,
9674 zr,
9675 (Assembler::Condition)$cmp$$cmpcode);
9676 %}
9677
9678 ins_pipe(icond_none);
9679 %}
9680
9681 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
9682 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
9683
9684 ins_cost(INSN_COST * 2);
9685 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %}
9686
9687 ins_encode %{
9688 // equivalently
9689 // cset(as_Register($dst$$reg),
9690 // negate_condition((Assembler::Condition)$cmp$$cmpcode));
9691 __ csincw(as_Register($dst$$reg),
9692 zr,
9693 zr,
9694 (Assembler::Condition)$cmp$$cmpcode);
9695 %}
9696
9697 ins_pipe(icond_none);
9698 %}
9699
9700 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
9701 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
9702
9703 ins_cost(INSN_COST * 2);
9704 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %}
9705
9706 ins_encode %{
9707 __ csel(as_Register($dst$$reg),
9708 as_Register($src2$$reg),
9709 as_Register($src1$$reg),
9710 (Assembler::Condition)$cmp$$cmpcode);
9711 %}
9712
9713 ins_pipe(icond_reg_reg);
9714 %}
9715
9716 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
9717 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
9718
9719 ins_cost(INSN_COST * 2);
9720 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %}
9721
9722 ins_encode %{
9723 __ csel(as_Register($dst$$reg),
9724 as_Register($src2$$reg),
9725 as_Register($src1$$reg),
9726 (Assembler::Condition)$cmp$$cmpcode);
9727 %}
9728
9729 ins_pipe(icond_reg_reg);
9730 %}
9731
9732 // special cases where one arg is zero
9733
9734 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
9735 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
9736
9737 ins_cost(INSN_COST * 2);
9738 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %}
9739
9740 ins_encode %{
9741 __ csel(as_Register($dst$$reg),
9742 zr,
9743 as_Register($src$$reg),
9744 (Assembler::Condition)$cmp$$cmpcode);
9745 %}
9746
9747 ins_pipe(icond_reg);
9748 %}
9749
9750 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
9751 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
9752
9753 ins_cost(INSN_COST * 2);
9754 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %}
9755
9756 ins_encode %{
9757 __ csel(as_Register($dst$$reg),
9758 zr,
9759 as_Register($src$$reg),
9760 (Assembler::Condition)$cmp$$cmpcode);
9761 %}
9762
9763 ins_pipe(icond_reg);
9764 %}
9765
9766 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
9767 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
9768
9769 ins_cost(INSN_COST * 2);
9770 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %}
9771
9772 ins_encode %{
9773 __ csel(as_Register($dst$$reg),
9774 as_Register($src$$reg),
9775 zr,
9776 (Assembler::Condition)$cmp$$cmpcode);
9777 %}
9778
9779 ins_pipe(icond_reg);
9780 %}
9781
9782 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
9783 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
9784
9785 ins_cost(INSN_COST * 2);
9786 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %}
9787
9788 ins_encode %{
9789 __ csel(as_Register($dst$$reg),
9790 as_Register($src$$reg),
9791 zr,
9792 (Assembler::Condition)$cmp$$cmpcode);
9793 %}
9794
9795 ins_pipe(icond_reg);
9796 %}
9797
9798 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
9799 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
9800
9801 ins_cost(INSN_COST * 2);
9802 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %}
9803
9804 ins_encode %{
9805 __ csel(as_Register($dst$$reg),
9806 as_Register($src2$$reg),
9807 as_Register($src1$$reg),
9808 (Assembler::Condition)$cmp$$cmpcode);
9809 %}
9810
9811 ins_pipe(icond_reg_reg);
9812 %}
9813
9814 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
9815 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
9816
9817 ins_cost(INSN_COST * 2);
9818 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %}
9819
9820 ins_encode %{
9821 __ csel(as_Register($dst$$reg),
9822 as_Register($src2$$reg),
9823 as_Register($src1$$reg),
9824 (Assembler::Condition)$cmp$$cmpcode);
9825 %}
9826
9827 ins_pipe(icond_reg_reg);
9828 %}
9829
9830 // special cases where one arg is zero
9831
9832 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
9833 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
9834
9835 ins_cost(INSN_COST * 2);
9836 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %}
9837
9838 ins_encode %{
9839 __ csel(as_Register($dst$$reg),
9840 zr,
9841 as_Register($src$$reg),
9842 (Assembler::Condition)$cmp$$cmpcode);
9843 %}
9844
9845 ins_pipe(icond_reg);
9846 %}
9847
9848 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
9849 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
9850
9851 ins_cost(INSN_COST * 2);
9852 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %}
9853
9854 ins_encode %{
9855 __ csel(as_Register($dst$$reg),
9856 zr,
9857 as_Register($src$$reg),
9858 (Assembler::Condition)$cmp$$cmpcode);
9859 %}
9860
9861 ins_pipe(icond_reg);
9862 %}
9863
9864 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
9865 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
9866
9867 ins_cost(INSN_COST * 2);
9868 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %}
9869
9870 ins_encode %{
9871 __ csel(as_Register($dst$$reg),
9872 as_Register($src$$reg),
9873 zr,
9874 (Assembler::Condition)$cmp$$cmpcode);
9875 %}
9876
9877 ins_pipe(icond_reg);
9878 %}
9879
9880 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
9881 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
9882
9883 ins_cost(INSN_COST * 2);
9884 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %}
9885
9886 ins_encode %{
9887 __ csel(as_Register($dst$$reg),
9888 as_Register($src$$reg),
9889 zr,
9890 (Assembler::Condition)$cmp$$cmpcode);
9891 %}
9892
9893 ins_pipe(icond_reg);
9894 %}
9895
9896 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
9897 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
9898
9899 ins_cost(INSN_COST * 2);
9900 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %}
9901
9902 ins_encode %{
9903 __ cselw(as_Register($dst$$reg),
9904 as_Register($src2$$reg),
9905 as_Register($src1$$reg),
9906 (Assembler::Condition)$cmp$$cmpcode);
9907 %}
9908
9909 ins_pipe(icond_reg_reg);
9910 %}
9911
9912 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
9913 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
9914
9915 ins_cost(INSN_COST * 2);
9916 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %}
9917
9918 ins_encode %{
9919 __ cselw(as_Register($dst$$reg),
9920 as_Register($src2$$reg),
9921 as_Register($src1$$reg),
9922 (Assembler::Condition)$cmp$$cmpcode);
9923 %}
9924
9925 ins_pipe(icond_reg_reg);
9926 %}
9927
9928 // special cases where one arg is zero
9929
9930 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
9931 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
9932
9933 ins_cost(INSN_COST * 2);
9934 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %}
9935
9936 ins_encode %{
9937 __ cselw(as_Register($dst$$reg),
9938 zr,
9939 as_Register($src$$reg),
9940 (Assembler::Condition)$cmp$$cmpcode);
9941 %}
9942
9943 ins_pipe(icond_reg);
9944 %}
9945
9946 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
9947 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
9948
9949 ins_cost(INSN_COST * 2);
9950 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %}
9951
9952 ins_encode %{
9953 __ cselw(as_Register($dst$$reg),
9954 zr,
9955 as_Register($src$$reg),
9956 (Assembler::Condition)$cmp$$cmpcode);
9957 %}
9958
9959 ins_pipe(icond_reg);
9960 %}
9961
9962 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
9963 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
9964
9965 ins_cost(INSN_COST * 2);
9966 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %}
9967
9968 ins_encode %{
9969 __ cselw(as_Register($dst$$reg),
9970 as_Register($src$$reg),
9971 zr,
9972 (Assembler::Condition)$cmp$$cmpcode);
9973 %}
9974
9975 ins_pipe(icond_reg);
9976 %}
9977
9978 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
9979 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
9980
9981 ins_cost(INSN_COST * 2);
9982 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %}
9983
9984 ins_encode %{
9985 __ cselw(as_Register($dst$$reg),
9986 as_Register($src$$reg),
9987 zr,
9988 (Assembler::Condition)$cmp$$cmpcode);
9989 %}
9990
9991 ins_pipe(icond_reg);
9992 %}
9993
9994 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2)
9995 %{
9996 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
9997
9998 ins_cost(INSN_COST * 3);
9999
10000 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
10001 ins_encode %{
10002 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
10003 __ fcsels(as_FloatRegister($dst$$reg),
10004 as_FloatRegister($src2$$reg),
10005 as_FloatRegister($src1$$reg),
10006 cond);
10007 %}
10008
10009 ins_pipe(fp_cond_reg_reg_s);
10010 %}
10011
10012 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2)
10013 %{
10014 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
10015
10016 ins_cost(INSN_COST * 3);
10017
10018 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
10019 ins_encode %{
10020 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
10021 __ fcsels(as_FloatRegister($dst$$reg),
10022 as_FloatRegister($src2$$reg),
10023 as_FloatRegister($src1$$reg),
10024 cond);
10025 %}
10026
10027 ins_pipe(fp_cond_reg_reg_s);
10028 %}
10029
10030 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2)
10031 %{
10032 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
10033
10034 ins_cost(INSN_COST * 3);
10035
10036 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
10037 ins_encode %{
10038 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
10039 __ fcseld(as_FloatRegister($dst$$reg),
10040 as_FloatRegister($src2$$reg),
10041 as_FloatRegister($src1$$reg),
10042 cond);
10043 %}
10044
10045 ins_pipe(fp_cond_reg_reg_d);
10046 %}
10047
10048 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2)
10049 %{
10050 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
10051
10052 ins_cost(INSN_COST * 3);
10053
10054 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
10055 ins_encode %{
10056 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
10057 __ fcseld(as_FloatRegister($dst$$reg),
10058 as_FloatRegister($src2$$reg),
10059 as_FloatRegister($src1$$reg),
10060 cond);
10061 %}
10062
10063 ins_pipe(fp_cond_reg_reg_d);
10064 %}
10065
10066 // ============================================================================
10067 // Arithmetic Instructions
10068 //
10069
10070 // Integer Addition
10071
10072 // TODO
10073 // these currently employ operations which do not set CR and hence are
10074 // not flagged as killing CR but we would like to isolate the cases
10075 // where we want to set flags from those where we don't. need to work
10076 // out how to do that.
10077
10078 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10079 match(Set dst (AddI src1 src2));
10080
10081 ins_cost(INSN_COST);
10082 format %{ "addw $dst, $src1, $src2" %}
10083
10084 ins_encode %{
10085 __ addw(as_Register($dst$$reg),
10086 as_Register($src1$$reg),
10087 as_Register($src2$$reg));
10088 %}
10089
10090 ins_pipe(ialu_reg_reg);
10091 %}
10092
10093 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
10094 match(Set dst (AddI src1 src2));
10095
10096 ins_cost(INSN_COST);
10097 format %{ "addw $dst, $src1, $src2" %}
10098
10099 // use opcode to indicate that this is an add not a sub
10100 opcode(0x0);
10101
10102 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
10103
10104 ins_pipe(ialu_reg_imm);
10105 %}
10106
10107 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{
10108 match(Set dst (AddI (ConvL2I src1) src2));
10109
10110 ins_cost(INSN_COST);
10111 format %{ "addw $dst, $src1, $src2" %}
10112
10113 // use opcode to indicate that this is an add not a sub
10114 opcode(0x0);
10115
10116 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
10117
10118 ins_pipe(ialu_reg_imm);
10119 %}
10120
10121 // Pointer Addition
10122 instruct addP_reg_reg(iRegPNoSp dst, iRegPorL2P src1, iRegL src2) %{
10123 match(Set dst (AddP src1 src2));
10124
10125 ins_cost(INSN_COST);
10126 format %{ "add $dst, $src1, $src2\t# ptr" %}
10127
10128 ins_encode %{
10129 __ add(as_Register($dst$$reg),
10130 as_Register($src1$$reg),
10131 as_Register($src2$$reg));
10132 %}
10133
10134 ins_pipe(ialu_reg_reg);
10135 %}
10136
10137 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegPorL2P src1, iRegIorL2I src2) %{
10138 match(Set dst (AddP src1 (ConvI2L src2)));
10139
10140 ins_cost(1.9 * INSN_COST);
10141 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %}
10142
10143 ins_encode %{
10144 __ add(as_Register($dst$$reg),
10145 as_Register($src1$$reg),
10146 as_Register($src2$$reg), ext::sxtw);
10147 %}
10148
10149 ins_pipe(ialu_reg_reg);
10150 %}
10151
10152 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegPorL2P src1, iRegL src2, immIScale scale) %{
10153 match(Set dst (AddP src1 (LShiftL src2 scale)));
10154
10155 ins_cost(1.9 * INSN_COST);
10156 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %}
10157
10158 ins_encode %{
10159 __ lea(as_Register($dst$$reg),
10160 Address(as_Register($src1$$reg), as_Register($src2$$reg),
10161 Address::lsl($scale$$constant)));
10162 %}
10163
10164 ins_pipe(ialu_reg_reg_shift);
10165 %}
10166
10167 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegPorL2P src1, iRegIorL2I src2, immIScale scale) %{
10168 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale)));
10169
10170 ins_cost(1.9 * INSN_COST);
10171 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %}
10172
10173 ins_encode %{
10174 __ lea(as_Register($dst$$reg),
10175 Address(as_Register($src1$$reg), as_Register($src2$$reg),
10176 Address::sxtw($scale$$constant)));
10177 %}
10178
10179 ins_pipe(ialu_reg_reg_shift);
10180 %}
10181
10182 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{
10183 match(Set dst (LShiftL (ConvI2L src) scale));
10184
10185 ins_cost(INSN_COST);
10186 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %}
10187
10188 ins_encode %{
10189 __ sbfiz(as_Register($dst$$reg),
10190 as_Register($src$$reg),
10191 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63)));
10192 %}
10193
10194 ins_pipe(ialu_reg_shift);
10195 %}
10196
10197 // Pointer Immediate Addition
10198 // n.b. this needs to be more expensive than using an indirect memory
10199 // operand
10200 instruct addP_reg_imm(iRegPNoSp dst, iRegPorL2P src1, immLAddSub src2) %{
10201 match(Set dst (AddP src1 src2));
10202
10203 ins_cost(INSN_COST);
10204 format %{ "add $dst, $src1, $src2\t# ptr" %}
10205
10206 // use opcode to indicate that this is an add not a sub
10207 opcode(0x0);
10208
10209 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
10210
10211 ins_pipe(ialu_reg_imm);
10212 %}
10213
10214 // Long Addition
10215 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10216
10217 match(Set dst (AddL src1 src2));
10218
10219 ins_cost(INSN_COST);
10220 format %{ "add $dst, $src1, $src2" %}
10221
10222 ins_encode %{
10223 __ add(as_Register($dst$$reg),
10224 as_Register($src1$$reg),
10225 as_Register($src2$$reg));
10226 %}
10227
10228 ins_pipe(ialu_reg_reg);
10229 %}
10230
10231 // No constant pool entries requiredLong Immediate Addition.
10232 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
10233 match(Set dst (AddL src1 src2));
10234
10235 ins_cost(INSN_COST);
10236 format %{ "add $dst, $src1, $src2" %}
10237
10238 // use opcode to indicate that this is an add not a sub
10239 opcode(0x0);
10240
10241 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
10242
10243 ins_pipe(ialu_reg_imm);
10244 %}
10245
10246 // Integer Subtraction
10247 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10248 match(Set dst (SubI src1 src2));
10249
10250 ins_cost(INSN_COST);
10251 format %{ "subw $dst, $src1, $src2" %}
10252
10253 ins_encode %{
10254 __ subw(as_Register($dst$$reg),
10255 as_Register($src1$$reg),
10256 as_Register($src2$$reg));
10257 %}
10258
10259 ins_pipe(ialu_reg_reg);
10260 %}
10261
10262 // Immediate Subtraction
10263 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
10264 match(Set dst (SubI src1 src2));
10265
10266 ins_cost(INSN_COST);
10267 format %{ "subw $dst, $src1, $src2" %}
10268
10269 // use opcode to indicate that this is a sub not an add
10270 opcode(0x1);
10271
10272 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
10273
10274 ins_pipe(ialu_reg_imm);
10275 %}
10276
10277 // Long Subtraction
10278 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10279
10280 match(Set dst (SubL src1 src2));
10281
10282 ins_cost(INSN_COST);
10283 format %{ "sub $dst, $src1, $src2" %}
10284
10285 ins_encode %{
10286 __ sub(as_Register($dst$$reg),
10287 as_Register($src1$$reg),
10288 as_Register($src2$$reg));
10289 %}
10290
10291 ins_pipe(ialu_reg_reg);
10292 %}
10293
10294 // No constant pool entries requiredLong Immediate Subtraction.
10295 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
10296 match(Set dst (SubL src1 src2));
10297
10298 ins_cost(INSN_COST);
10299 format %{ "sub$dst, $src1, $src2" %}
10300
10301 // use opcode to indicate that this is a sub not an add
10302 opcode(0x1);
10303
10304 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
10305
10306 ins_pipe(ialu_reg_imm);
10307 %}
10308
10309 // Integer Negation (special case for sub)
10310
10311 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{
10312 match(Set dst (SubI zero src));
10313
10314 ins_cost(INSN_COST);
10315 format %{ "negw $dst, $src\t# int" %}
10316
10317 ins_encode %{
10318 __ negw(as_Register($dst$$reg),
10319 as_Register($src$$reg));
10320 %}
10321
10322 ins_pipe(ialu_reg);
10323 %}
10324
10325 // Long Negation
10326
10327 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{
10328 match(Set dst (SubL zero src));
10329
10330 ins_cost(INSN_COST);
10331 format %{ "neg $dst, $src\t# long" %}
10332
10333 ins_encode %{
10334 __ neg(as_Register($dst$$reg),
10335 as_Register($src$$reg));
10336 %}
10337
10338 ins_pipe(ialu_reg);
10339 %}
10340
10341 // Integer Multiply
10342
10343 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10344 match(Set dst (MulI src1 src2));
10345
10346 ins_cost(INSN_COST * 3);
10347 format %{ "mulw $dst, $src1, $src2" %}
10348
10349 ins_encode %{
10350 __ mulw(as_Register($dst$$reg),
10351 as_Register($src1$$reg),
10352 as_Register($src2$$reg));
10353 %}
10354
10355 ins_pipe(imul_reg_reg);
10356 %}
10357
10358 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10359 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2)));
10360
10361 ins_cost(INSN_COST * 3);
10362 format %{ "smull $dst, $src1, $src2" %}
10363
10364 ins_encode %{
10365 __ smull(as_Register($dst$$reg),
10366 as_Register($src1$$reg),
10367 as_Register($src2$$reg));
10368 %}
10369
10370 ins_pipe(imul_reg_reg);
10371 %}
10372
10373 // Long Multiply
10374
10375 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10376 match(Set dst (MulL src1 src2));
10377
10378 ins_cost(INSN_COST * 5);
10379 format %{ "mul $dst, $src1, $src2" %}
10380
10381 ins_encode %{
10382 __ mul(as_Register($dst$$reg),
10383 as_Register($src1$$reg),
10384 as_Register($src2$$reg));
10385 %}
10386
10387 ins_pipe(lmul_reg_reg);
10388 %}
10389
10390 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr)
10391 %{
10392 match(Set dst (MulHiL src1 src2));
10393
10394 ins_cost(INSN_COST * 7);
10395 format %{ "smulh $dst, $src1, $src2\t# mulhi" %}
10396
10397 ins_encode %{
10398 __ smulh(as_Register($dst$$reg),
10399 as_Register($src1$$reg),
10400 as_Register($src2$$reg));
10401 %}
10402
10403 ins_pipe(lmul_reg_reg);
10404 %}
10405
10406 instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr)
10407 %{
10408 match(Set dst (UMulHiL src1 src2));
10409
10410 ins_cost(INSN_COST * 7);
10411 format %{ "umulh $dst, $src1, $src2\t# umulhi" %}
10412
10413 ins_encode %{
10414 __ umulh(as_Register($dst$$reg),
10415 as_Register($src1$$reg),
10416 as_Register($src2$$reg));
10417 %}
10418
10419 ins_pipe(lmul_reg_reg);
10420 %}
10421
10422 // Combined Integer Multiply & Add/Sub
10423
10424 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
10425 match(Set dst (AddI src3 (MulI src1 src2)));
10426
10427 ins_cost(INSN_COST * 3);
10428 format %{ "madd $dst, $src1, $src2, $src3" %}
10429
10430 ins_encode %{
10431 __ maddw(as_Register($dst$$reg),
10432 as_Register($src1$$reg),
10433 as_Register($src2$$reg),
10434 as_Register($src3$$reg));
10435 %}
10436
10437 ins_pipe(imac_reg_reg);
10438 %}
10439
10440 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
10441 match(Set dst (SubI src3 (MulI src1 src2)));
10442
10443 ins_cost(INSN_COST * 3);
10444 format %{ "msub $dst, $src1, $src2, $src3" %}
10445
10446 ins_encode %{
10447 __ msubw(as_Register($dst$$reg),
10448 as_Register($src1$$reg),
10449 as_Register($src2$$reg),
10450 as_Register($src3$$reg));
10451 %}
10452
10453 ins_pipe(imac_reg_reg);
10454 %}
10455
10456 // Combined Integer Multiply & Neg
10457
10458 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{
10459 match(Set dst (MulI (SubI zero src1) src2));
10460
10461 ins_cost(INSN_COST * 3);
10462 format %{ "mneg $dst, $src1, $src2" %}
10463
10464 ins_encode %{
10465 __ mnegw(as_Register($dst$$reg),
10466 as_Register($src1$$reg),
10467 as_Register($src2$$reg));
10468 %}
10469
10470 ins_pipe(imac_reg_reg);
10471 %}
10472
10473 // Combined Long Multiply & Add/Sub
10474
10475 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
10476 match(Set dst (AddL src3 (MulL src1 src2)));
10477
10478 ins_cost(INSN_COST * 5);
10479 format %{ "madd $dst, $src1, $src2, $src3" %}
10480
10481 ins_encode %{
10482 __ madd(as_Register($dst$$reg),
10483 as_Register($src1$$reg),
10484 as_Register($src2$$reg),
10485 as_Register($src3$$reg));
10486 %}
10487
10488 ins_pipe(lmac_reg_reg);
10489 %}
10490
10491 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
10492 match(Set dst (SubL src3 (MulL src1 src2)));
10493
10494 ins_cost(INSN_COST * 5);
10495 format %{ "msub $dst, $src1, $src2, $src3" %}
10496
10497 ins_encode %{
10498 __ msub(as_Register($dst$$reg),
10499 as_Register($src1$$reg),
10500 as_Register($src2$$reg),
10501 as_Register($src3$$reg));
10502 %}
10503
10504 ins_pipe(lmac_reg_reg);
10505 %}
10506
10507 // Combined Long Multiply & Neg
10508
10509 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{
10510 match(Set dst (MulL (SubL zero src1) src2));
10511
10512 ins_cost(INSN_COST * 5);
10513 format %{ "mneg $dst, $src1, $src2" %}
10514
10515 ins_encode %{
10516 __ mneg(as_Register($dst$$reg),
10517 as_Register($src1$$reg),
10518 as_Register($src2$$reg));
10519 %}
10520
10521 ins_pipe(lmac_reg_reg);
10522 %}
10523
10524 // Combine Integer Signed Multiply & Add/Sub/Neg Long
10525
10526 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{
10527 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2))));
10528
10529 ins_cost(INSN_COST * 3);
10530 format %{ "smaddl $dst, $src1, $src2, $src3" %}
10531
10532 ins_encode %{
10533 __ smaddl(as_Register($dst$$reg),
10534 as_Register($src1$$reg),
10535 as_Register($src2$$reg),
10536 as_Register($src3$$reg));
10537 %}
10538
10539 ins_pipe(imac_reg_reg);
10540 %}
10541
10542 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{
10543 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2))));
10544
10545 ins_cost(INSN_COST * 3);
10546 format %{ "smsubl $dst, $src1, $src2, $src3" %}
10547
10548 ins_encode %{
10549 __ smsubl(as_Register($dst$$reg),
10550 as_Register($src1$$reg),
10551 as_Register($src2$$reg),
10552 as_Register($src3$$reg));
10553 %}
10554
10555 ins_pipe(imac_reg_reg);
10556 %}
10557
10558 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{
10559 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2)));
10560
10561 ins_cost(INSN_COST * 3);
10562 format %{ "smnegl $dst, $src1, $src2" %}
10563
10564 ins_encode %{
10565 __ smnegl(as_Register($dst$$reg),
10566 as_Register($src1$$reg),
10567 as_Register($src2$$reg));
10568 %}
10569
10570 ins_pipe(imac_reg_reg);
10571 %}
10572
10573 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4)
10574
10575 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{
10576 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4)));
10577
10578 ins_cost(INSN_COST * 5);
10579 format %{ "mulw rscratch1, $src1, $src2\n\t"
10580 "maddw $dst, $src3, $src4, rscratch1" %}
10581
10582 ins_encode %{
10583 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg));
10584 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %}
10585
10586 ins_pipe(imac_reg_reg);
10587 %}
10588
10589 // Integer Divide
10590
10591 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10592 match(Set dst (DivI src1 src2));
10593
10594 ins_cost(INSN_COST * 19);
10595 format %{ "sdivw $dst, $src1, $src2" %}
10596
10597 ins_encode(aarch64_enc_divw(dst, src1, src2));
10598 ins_pipe(idiv_reg_reg);
10599 %}
10600
10601 // Long Divide
10602
10603 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10604 match(Set dst (DivL src1 src2));
10605
10606 ins_cost(INSN_COST * 35);
10607 format %{ "sdiv $dst, $src1, $src2" %}
10608
10609 ins_encode(aarch64_enc_div(dst, src1, src2));
10610 ins_pipe(ldiv_reg_reg);
10611 %}
10612
10613 // Integer Remainder
10614
10615 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10616 match(Set dst (ModI src1 src2));
10617
10618 ins_cost(INSN_COST * 22);
10619 format %{ "sdivw rscratch1, $src1, $src2\n\t"
10620 "msubw $dst, rscratch1, $src2, $src1" %}
10621
10622 ins_encode(aarch64_enc_modw(dst, src1, src2));
10623 ins_pipe(idiv_reg_reg);
10624 %}
10625
10626 // Long Remainder
10627
10628 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10629 match(Set dst (ModL src1 src2));
10630
10631 ins_cost(INSN_COST * 38);
10632 format %{ "sdiv rscratch1, $src1, $src2\n"
10633 "msub $dst, rscratch1, $src2, $src1" %}
10634
10635 ins_encode(aarch64_enc_mod(dst, src1, src2));
10636 ins_pipe(ldiv_reg_reg);
10637 %}
10638
10639 // Unsigned Integer Divide
10640
10641 instruct UdivI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10642 match(Set dst (UDivI src1 src2));
10643
10644 ins_cost(INSN_COST * 19);
10645 format %{ "udivw $dst, $src1, $src2" %}
10646
10647 ins_encode %{
10648 __ udivw($dst$$Register, $src1$$Register, $src2$$Register);
10649 %}
10650
10651 ins_pipe(idiv_reg_reg);
10652 %}
10653
10654 // Unsigned Long Divide
10655
10656 instruct UdivL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10657 match(Set dst (UDivL src1 src2));
10658
10659 ins_cost(INSN_COST * 35);
10660 format %{ "udiv $dst, $src1, $src2" %}
10661
10662 ins_encode %{
10663 __ udiv($dst$$Register, $src1$$Register, $src2$$Register);
10664 %}
10665
10666 ins_pipe(ldiv_reg_reg);
10667 %}
10668
10669 // Unsigned Integer Remainder
10670
10671 instruct UmodI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10672 match(Set dst (UModI src1 src2));
10673
10674 ins_cost(INSN_COST * 22);
10675 format %{ "udivw rscratch1, $src1, $src2\n\t"
10676 "msubw $dst, rscratch1, $src2, $src1" %}
10677
10678 ins_encode %{
10679 __ udivw(rscratch1, $src1$$Register, $src2$$Register);
10680 __ msubw($dst$$Register, rscratch1, $src2$$Register, $src1$$Register);
10681 %}
10682
10683 ins_pipe(idiv_reg_reg);
10684 %}
10685
10686 // Unsigned Long Remainder
10687
10688 instruct UModL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10689 match(Set dst (UModL src1 src2));
10690
10691 ins_cost(INSN_COST * 38);
10692 format %{ "udiv rscratch1, $src1, $src2\n"
10693 "msub $dst, rscratch1, $src2, $src1" %}
10694
10695 ins_encode %{
10696 __ udiv(rscratch1, $src1$$Register, $src2$$Register);
10697 __ msub($dst$$Register, rscratch1, $src2$$Register, $src1$$Register);
10698 %}
10699
10700 ins_pipe(ldiv_reg_reg);
10701 %}
10702
10703 // Integer Shifts
10704
10705 // Shift Left Register
10706 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10707 match(Set dst (LShiftI src1 src2));
10708
10709 ins_cost(INSN_COST * 2);
10710 format %{ "lslvw $dst, $src1, $src2" %}
10711
10712 ins_encode %{
10713 __ lslvw(as_Register($dst$$reg),
10714 as_Register($src1$$reg),
10715 as_Register($src2$$reg));
10716 %}
10717
10718 ins_pipe(ialu_reg_reg_vshift);
10719 %}
10720
10721 // Shift Left Immediate
10722 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10723 match(Set dst (LShiftI src1 src2));
10724
10725 ins_cost(INSN_COST);
10726 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %}
10727
10728 ins_encode %{
10729 __ lslw(as_Register($dst$$reg),
10730 as_Register($src1$$reg),
10731 $src2$$constant & 0x1f);
10732 %}
10733
10734 ins_pipe(ialu_reg_shift);
10735 %}
10736
10737 // Shift Right Logical Register
10738 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10739 match(Set dst (URShiftI src1 src2));
10740
10741 ins_cost(INSN_COST * 2);
10742 format %{ "lsrvw $dst, $src1, $src2" %}
10743
10744 ins_encode %{
10745 __ lsrvw(as_Register($dst$$reg),
10746 as_Register($src1$$reg),
10747 as_Register($src2$$reg));
10748 %}
10749
10750 ins_pipe(ialu_reg_reg_vshift);
10751 %}
10752
10753 // Shift Right Logical Immediate
10754 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10755 match(Set dst (URShiftI src1 src2));
10756
10757 ins_cost(INSN_COST);
10758 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %}
10759
10760 ins_encode %{
10761 __ lsrw(as_Register($dst$$reg),
10762 as_Register($src1$$reg),
10763 $src2$$constant & 0x1f);
10764 %}
10765
10766 ins_pipe(ialu_reg_shift);
10767 %}
10768
10769 // Shift Right Arithmetic Register
10770 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10771 match(Set dst (RShiftI src1 src2));
10772
10773 ins_cost(INSN_COST * 2);
10774 format %{ "asrvw $dst, $src1, $src2" %}
10775
10776 ins_encode %{
10777 __ asrvw(as_Register($dst$$reg),
10778 as_Register($src1$$reg),
10779 as_Register($src2$$reg));
10780 %}
10781
10782 ins_pipe(ialu_reg_reg_vshift);
10783 %}
10784
10785 // Shift Right Arithmetic Immediate
10786 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
10787 match(Set dst (RShiftI src1 src2));
10788
10789 ins_cost(INSN_COST);
10790 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %}
10791
10792 ins_encode %{
10793 __ asrw(as_Register($dst$$reg),
10794 as_Register($src1$$reg),
10795 $src2$$constant & 0x1f);
10796 %}
10797
10798 ins_pipe(ialu_reg_shift);
10799 %}
10800
10801 // Combined Int Mask and Right Shift (using UBFM)
10802 // TODO
10803
10804 // Long Shifts
10805
10806 // Shift Left Register
10807 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10808 match(Set dst (LShiftL src1 src2));
10809
10810 ins_cost(INSN_COST * 2);
10811 format %{ "lslv $dst, $src1, $src2" %}
10812
10813 ins_encode %{
10814 __ lslv(as_Register($dst$$reg),
10815 as_Register($src1$$reg),
10816 as_Register($src2$$reg));
10817 %}
10818
10819 ins_pipe(ialu_reg_reg_vshift);
10820 %}
10821
10822 // Shift Left Immediate
10823 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10824 match(Set dst (LShiftL src1 src2));
10825
10826 ins_cost(INSN_COST);
10827 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %}
10828
10829 ins_encode %{
10830 __ lsl(as_Register($dst$$reg),
10831 as_Register($src1$$reg),
10832 $src2$$constant & 0x3f);
10833 %}
10834
10835 ins_pipe(ialu_reg_shift);
10836 %}
10837
10838 // Shift Right Logical Register
10839 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10840 match(Set dst (URShiftL src1 src2));
10841
10842 ins_cost(INSN_COST * 2);
10843 format %{ "lsrv $dst, $src1, $src2" %}
10844
10845 ins_encode %{
10846 __ lsrv(as_Register($dst$$reg),
10847 as_Register($src1$$reg),
10848 as_Register($src2$$reg));
10849 %}
10850
10851 ins_pipe(ialu_reg_reg_vshift);
10852 %}
10853
10854 // Shift Right Logical Immediate
10855 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10856 match(Set dst (URShiftL src1 src2));
10857
10858 ins_cost(INSN_COST);
10859 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %}
10860
10861 ins_encode %{
10862 __ lsr(as_Register($dst$$reg),
10863 as_Register($src1$$reg),
10864 $src2$$constant & 0x3f);
10865 %}
10866
10867 ins_pipe(ialu_reg_shift);
10868 %}
10869
10870 // A special-case pattern for card table stores.
10871 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{
10872 match(Set dst (URShiftL (CastP2X src1) src2));
10873
10874 ins_cost(INSN_COST);
10875 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %}
10876
10877 ins_encode %{
10878 __ lsr(as_Register($dst$$reg),
10879 as_Register($src1$$reg),
10880 $src2$$constant & 0x3f);
10881 %}
10882
10883 ins_pipe(ialu_reg_shift);
10884 %}
10885
10886 // Shift Right Arithmetic Register
10887 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
10888 match(Set dst (RShiftL src1 src2));
10889
10890 ins_cost(INSN_COST * 2);
10891 format %{ "asrv $dst, $src1, $src2" %}
10892
10893 ins_encode %{
10894 __ asrv(as_Register($dst$$reg),
10895 as_Register($src1$$reg),
10896 as_Register($src2$$reg));
10897 %}
10898
10899 ins_pipe(ialu_reg_reg_vshift);
10900 %}
10901
10902 // Shift Right Arithmetic Immediate
10903 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
10904 match(Set dst (RShiftL src1 src2));
10905
10906 ins_cost(INSN_COST);
10907 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %}
10908
10909 ins_encode %{
10910 __ asr(as_Register($dst$$reg),
10911 as_Register($src1$$reg),
10912 $src2$$constant & 0x3f);
10913 %}
10914
10915 ins_pipe(ialu_reg_shift);
10916 %}
10917
10918 // BEGIN This section of the file is automatically generated. Do not edit --------------
10919 // This section is generated from aarch64_ad.m4
10920
10921 // This pattern is automatically generated from aarch64_ad.m4
10922 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10923 instruct regL_not_reg(iRegLNoSp dst,
10924 iRegL src1, immL_M1 m1,
10925 rFlagsReg cr) %{
10926 match(Set dst (XorL src1 m1));
10927 ins_cost(INSN_COST);
10928 format %{ "eon $dst, $src1, zr" %}
10929
10930 ins_encode %{
10931 __ eon(as_Register($dst$$reg),
10932 as_Register($src1$$reg),
10933 zr,
10934 Assembler::LSL, 0);
10935 %}
10936
10937 ins_pipe(ialu_reg);
10938 %}
10939
10940 // This pattern is automatically generated from aarch64_ad.m4
10941 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10942 instruct regI_not_reg(iRegINoSp dst,
10943 iRegIorL2I src1, immI_M1 m1,
10944 rFlagsReg cr) %{
10945 match(Set dst (XorI src1 m1));
10946 ins_cost(INSN_COST);
10947 format %{ "eonw $dst, $src1, zr" %}
10948
10949 ins_encode %{
10950 __ eonw(as_Register($dst$$reg),
10951 as_Register($src1$$reg),
10952 zr,
10953 Assembler::LSL, 0);
10954 %}
10955
10956 ins_pipe(ialu_reg);
10957 %}
10958
10959 // This pattern is automatically generated from aarch64_ad.m4
10960 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10961 instruct NegI_reg_URShift_reg(iRegINoSp dst,
10962 immI0 zero, iRegIorL2I src1, immI src2) %{
10963 match(Set dst (SubI zero (URShiftI src1 src2)));
10964
10965 ins_cost(1.9 * INSN_COST);
10966 format %{ "negw $dst, $src1, LSR $src2" %}
10967
10968 ins_encode %{
10969 __ negw(as_Register($dst$$reg), as_Register($src1$$reg),
10970 Assembler::LSR, $src2$$constant & 0x1f);
10971 %}
10972
10973 ins_pipe(ialu_reg_shift);
10974 %}
10975
10976 // This pattern is automatically generated from aarch64_ad.m4
10977 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10978 instruct NegI_reg_RShift_reg(iRegINoSp dst,
10979 immI0 zero, iRegIorL2I src1, immI src2) %{
10980 match(Set dst (SubI zero (RShiftI src1 src2)));
10981
10982 ins_cost(1.9 * INSN_COST);
10983 format %{ "negw $dst, $src1, ASR $src2" %}
10984
10985 ins_encode %{
10986 __ negw(as_Register($dst$$reg), as_Register($src1$$reg),
10987 Assembler::ASR, $src2$$constant & 0x1f);
10988 %}
10989
10990 ins_pipe(ialu_reg_shift);
10991 %}
10992
10993 // This pattern is automatically generated from aarch64_ad.m4
10994 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
10995 instruct NegI_reg_LShift_reg(iRegINoSp dst,
10996 immI0 zero, iRegIorL2I src1, immI src2) %{
10997 match(Set dst (SubI zero (LShiftI src1 src2)));
10998
10999 ins_cost(1.9 * INSN_COST);
11000 format %{ "negw $dst, $src1, LSL $src2" %}
11001
11002 ins_encode %{
11003 __ negw(as_Register($dst$$reg), as_Register($src1$$reg),
11004 Assembler::LSL, $src2$$constant & 0x1f);
11005 %}
11006
11007 ins_pipe(ialu_reg_shift);
11008 %}
11009
11010 // This pattern is automatically generated from aarch64_ad.m4
11011 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11012 instruct NegL_reg_URShift_reg(iRegLNoSp dst,
11013 immL0 zero, iRegL src1, immI src2) %{
11014 match(Set dst (SubL zero (URShiftL src1 src2)));
11015
11016 ins_cost(1.9 * INSN_COST);
11017 format %{ "neg $dst, $src1, LSR $src2" %}
11018
11019 ins_encode %{
11020 __ neg(as_Register($dst$$reg), as_Register($src1$$reg),
11021 Assembler::LSR, $src2$$constant & 0x3f);
11022 %}
11023
11024 ins_pipe(ialu_reg_shift);
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 NegL_reg_RShift_reg(iRegLNoSp dst,
11030 immL0 zero, iRegL src1, immI src2) %{
11031 match(Set dst (SubL zero (RShiftL src1 src2)));
11032
11033 ins_cost(1.9 * INSN_COST);
11034 format %{ "neg $dst, $src1, ASR $src2" %}
11035
11036 ins_encode %{
11037 __ neg(as_Register($dst$$reg), as_Register($src1$$reg),
11038 Assembler::ASR, $src2$$constant & 0x3f);
11039 %}
11040
11041 ins_pipe(ialu_reg_shift);
11042 %}
11043
11044 // This pattern is automatically generated from aarch64_ad.m4
11045 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11046 instruct NegL_reg_LShift_reg(iRegLNoSp dst,
11047 immL0 zero, iRegL src1, immI src2) %{
11048 match(Set dst (SubL zero (LShiftL src1 src2)));
11049
11050 ins_cost(1.9 * INSN_COST);
11051 format %{ "neg $dst, $src1, LSL $src2" %}
11052
11053 ins_encode %{
11054 __ neg(as_Register($dst$$reg), as_Register($src1$$reg),
11055 Assembler::LSL, $src2$$constant & 0x3f);
11056 %}
11057
11058 ins_pipe(ialu_reg_shift);
11059 %}
11060
11061 // This pattern is automatically generated from aarch64_ad.m4
11062 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11063 instruct AndI_reg_not_reg(iRegINoSp dst,
11064 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{
11065 match(Set dst (AndI src1 (XorI src2 m1)));
11066 ins_cost(INSN_COST);
11067 format %{ "bicw $dst, $src1, $src2" %}
11068
11069 ins_encode %{
11070 __ bicw(as_Register($dst$$reg),
11071 as_Register($src1$$reg),
11072 as_Register($src2$$reg),
11073 Assembler::LSL, 0);
11074 %}
11075
11076 ins_pipe(ialu_reg_reg);
11077 %}
11078
11079 // This pattern is automatically generated from aarch64_ad.m4
11080 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11081 instruct AndL_reg_not_reg(iRegLNoSp dst,
11082 iRegL src1, iRegL src2, immL_M1 m1) %{
11083 match(Set dst (AndL src1 (XorL src2 m1)));
11084 ins_cost(INSN_COST);
11085 format %{ "bic $dst, $src1, $src2" %}
11086
11087 ins_encode %{
11088 __ bic(as_Register($dst$$reg),
11089 as_Register($src1$$reg),
11090 as_Register($src2$$reg),
11091 Assembler::LSL, 0);
11092 %}
11093
11094 ins_pipe(ialu_reg_reg);
11095 %}
11096
11097 // This pattern is automatically generated from aarch64_ad.m4
11098 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11099 instruct OrI_reg_not_reg(iRegINoSp dst,
11100 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{
11101 match(Set dst (OrI src1 (XorI src2 m1)));
11102 ins_cost(INSN_COST);
11103 format %{ "ornw $dst, $src1, $src2" %}
11104
11105 ins_encode %{
11106 __ ornw(as_Register($dst$$reg),
11107 as_Register($src1$$reg),
11108 as_Register($src2$$reg),
11109 Assembler::LSL, 0);
11110 %}
11111
11112 ins_pipe(ialu_reg_reg);
11113 %}
11114
11115 // This pattern is automatically generated from aarch64_ad.m4
11116 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11117 instruct OrL_reg_not_reg(iRegLNoSp dst,
11118 iRegL src1, iRegL src2, immL_M1 m1) %{
11119 match(Set dst (OrL src1 (XorL src2 m1)));
11120 ins_cost(INSN_COST);
11121 format %{ "orn $dst, $src1, $src2" %}
11122
11123 ins_encode %{
11124 __ orn(as_Register($dst$$reg),
11125 as_Register($src1$$reg),
11126 as_Register($src2$$reg),
11127 Assembler::LSL, 0);
11128 %}
11129
11130 ins_pipe(ialu_reg_reg);
11131 %}
11132
11133 // This pattern is automatically generated from aarch64_ad.m4
11134 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11135 instruct XorI_reg_not_reg(iRegINoSp dst,
11136 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{
11137 match(Set dst (XorI m1 (XorI src2 src1)));
11138 ins_cost(INSN_COST);
11139 format %{ "eonw $dst, $src1, $src2" %}
11140
11141 ins_encode %{
11142 __ eonw(as_Register($dst$$reg),
11143 as_Register($src1$$reg),
11144 as_Register($src2$$reg),
11145 Assembler::LSL, 0);
11146 %}
11147
11148 ins_pipe(ialu_reg_reg);
11149 %}
11150
11151 // This pattern is automatically generated from aarch64_ad.m4
11152 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11153 instruct XorL_reg_not_reg(iRegLNoSp dst,
11154 iRegL src1, iRegL src2, immL_M1 m1) %{
11155 match(Set dst (XorL m1 (XorL src2 src1)));
11156 ins_cost(INSN_COST);
11157 format %{ "eon $dst, $src1, $src2" %}
11158
11159 ins_encode %{
11160 __ eon(as_Register($dst$$reg),
11161 as_Register($src1$$reg),
11162 as_Register($src2$$reg),
11163 Assembler::LSL, 0);
11164 %}
11165
11166 ins_pipe(ialu_reg_reg);
11167 %}
11168
11169 // This pattern is automatically generated from aarch64_ad.m4
11170 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11171 // val & (-1 ^ (val >>> shift)) ==> bicw
11172 instruct AndI_reg_URShift_not_reg(iRegINoSp dst,
11173 iRegIorL2I src1, iRegIorL2I src2,
11174 immI src3, immI_M1 src4) %{
11175 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4)));
11176 ins_cost(1.9 * INSN_COST);
11177 format %{ "bicw $dst, $src1, $src2, LSR $src3" %}
11178
11179 ins_encode %{
11180 __ bicw(as_Register($dst$$reg),
11181 as_Register($src1$$reg),
11182 as_Register($src2$$reg),
11183 Assembler::LSR,
11184 $src3$$constant & 0x1f);
11185 %}
11186
11187 ins_pipe(ialu_reg_reg_shift);
11188 %}
11189
11190 // This pattern is automatically generated from aarch64_ad.m4
11191 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11192 // val & (-1 ^ (val >>> shift)) ==> bic
11193 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst,
11194 iRegL src1, iRegL src2,
11195 immI src3, immL_M1 src4) %{
11196 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4)));
11197 ins_cost(1.9 * INSN_COST);
11198 format %{ "bic $dst, $src1, $src2, LSR $src3" %}
11199
11200 ins_encode %{
11201 __ bic(as_Register($dst$$reg),
11202 as_Register($src1$$reg),
11203 as_Register($src2$$reg),
11204 Assembler::LSR,
11205 $src3$$constant & 0x3f);
11206 %}
11207
11208 ins_pipe(ialu_reg_reg_shift);
11209 %}
11210
11211 // This pattern is automatically generated from aarch64_ad.m4
11212 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11213 // val & (-1 ^ (val >> shift)) ==> bicw
11214 instruct AndI_reg_RShift_not_reg(iRegINoSp dst,
11215 iRegIorL2I src1, iRegIorL2I src2,
11216 immI src3, immI_M1 src4) %{
11217 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4)));
11218 ins_cost(1.9 * INSN_COST);
11219 format %{ "bicw $dst, $src1, $src2, ASR $src3" %}
11220
11221 ins_encode %{
11222 __ bicw(as_Register($dst$$reg),
11223 as_Register($src1$$reg),
11224 as_Register($src2$$reg),
11225 Assembler::ASR,
11226 $src3$$constant & 0x1f);
11227 %}
11228
11229 ins_pipe(ialu_reg_reg_shift);
11230 %}
11231
11232 // This pattern is automatically generated from aarch64_ad.m4
11233 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11234 // val & (-1 ^ (val >> shift)) ==> bic
11235 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst,
11236 iRegL src1, iRegL src2,
11237 immI src3, immL_M1 src4) %{
11238 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4)));
11239 ins_cost(1.9 * INSN_COST);
11240 format %{ "bic $dst, $src1, $src2, ASR $src3" %}
11241
11242 ins_encode %{
11243 __ bic(as_Register($dst$$reg),
11244 as_Register($src1$$reg),
11245 as_Register($src2$$reg),
11246 Assembler::ASR,
11247 $src3$$constant & 0x3f);
11248 %}
11249
11250 ins_pipe(ialu_reg_reg_shift);
11251 %}
11252
11253 // This pattern is automatically generated from aarch64_ad.m4
11254 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11255 // val & (-1 ^ (val ror shift)) ==> bicw
11256 instruct AndI_reg_RotateRight_not_reg(iRegINoSp dst,
11257 iRegIorL2I src1, iRegIorL2I src2,
11258 immI src3, immI_M1 src4) %{
11259 match(Set dst (AndI src1 (XorI(RotateRight src2 src3) src4)));
11260 ins_cost(1.9 * INSN_COST);
11261 format %{ "bicw $dst, $src1, $src2, ROR $src3" %}
11262
11263 ins_encode %{
11264 __ bicw(as_Register($dst$$reg),
11265 as_Register($src1$$reg),
11266 as_Register($src2$$reg),
11267 Assembler::ROR,
11268 $src3$$constant & 0x1f);
11269 %}
11270
11271 ins_pipe(ialu_reg_reg_shift);
11272 %}
11273
11274 // This pattern is automatically generated from aarch64_ad.m4
11275 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11276 // val & (-1 ^ (val ror shift)) ==> bic
11277 instruct AndL_reg_RotateRight_not_reg(iRegLNoSp dst,
11278 iRegL src1, iRegL src2,
11279 immI src3, immL_M1 src4) %{
11280 match(Set dst (AndL src1 (XorL(RotateRight src2 src3) src4)));
11281 ins_cost(1.9 * INSN_COST);
11282 format %{ "bic $dst, $src1, $src2, ROR $src3" %}
11283
11284 ins_encode %{
11285 __ bic(as_Register($dst$$reg),
11286 as_Register($src1$$reg),
11287 as_Register($src2$$reg),
11288 Assembler::ROR,
11289 $src3$$constant & 0x3f);
11290 %}
11291
11292 ins_pipe(ialu_reg_reg_shift);
11293 %}
11294
11295 // This pattern is automatically generated from aarch64_ad.m4
11296 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11297 // val & (-1 ^ (val << shift)) ==> bicw
11298 instruct AndI_reg_LShift_not_reg(iRegINoSp dst,
11299 iRegIorL2I src1, iRegIorL2I src2,
11300 immI src3, immI_M1 src4) %{
11301 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4)));
11302 ins_cost(1.9 * INSN_COST);
11303 format %{ "bicw $dst, $src1, $src2, LSL $src3" %}
11304
11305 ins_encode %{
11306 __ bicw(as_Register($dst$$reg),
11307 as_Register($src1$$reg),
11308 as_Register($src2$$reg),
11309 Assembler::LSL,
11310 $src3$$constant & 0x1f);
11311 %}
11312
11313 ins_pipe(ialu_reg_reg_shift);
11314 %}
11315
11316 // This pattern is automatically generated from aarch64_ad.m4
11317 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11318 // val & (-1 ^ (val << shift)) ==> bic
11319 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst,
11320 iRegL src1, iRegL src2,
11321 immI src3, immL_M1 src4) %{
11322 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4)));
11323 ins_cost(1.9 * INSN_COST);
11324 format %{ "bic $dst, $src1, $src2, LSL $src3" %}
11325
11326 ins_encode %{
11327 __ bic(as_Register($dst$$reg),
11328 as_Register($src1$$reg),
11329 as_Register($src2$$reg),
11330 Assembler::LSL,
11331 $src3$$constant & 0x3f);
11332 %}
11333
11334 ins_pipe(ialu_reg_reg_shift);
11335 %}
11336
11337 // This pattern is automatically generated from aarch64_ad.m4
11338 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11339 // val ^ (-1 ^ (val >>> shift)) ==> eonw
11340 instruct XorI_reg_URShift_not_reg(iRegINoSp dst,
11341 iRegIorL2I src1, iRegIorL2I src2,
11342 immI src3, immI_M1 src4) %{
11343 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1)));
11344 ins_cost(1.9 * INSN_COST);
11345 format %{ "eonw $dst, $src1, $src2, LSR $src3" %}
11346
11347 ins_encode %{
11348 __ eonw(as_Register($dst$$reg),
11349 as_Register($src1$$reg),
11350 as_Register($src2$$reg),
11351 Assembler::LSR,
11352 $src3$$constant & 0x1f);
11353 %}
11354
11355 ins_pipe(ialu_reg_reg_shift);
11356 %}
11357
11358 // This pattern is automatically generated from aarch64_ad.m4
11359 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11360 // val ^ (-1 ^ (val >>> shift)) ==> eon
11361 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst,
11362 iRegL src1, iRegL src2,
11363 immI src3, immL_M1 src4) %{
11364 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1)));
11365 ins_cost(1.9 * INSN_COST);
11366 format %{ "eon $dst, $src1, $src2, LSR $src3" %}
11367
11368 ins_encode %{
11369 __ eon(as_Register($dst$$reg),
11370 as_Register($src1$$reg),
11371 as_Register($src2$$reg),
11372 Assembler::LSR,
11373 $src3$$constant & 0x3f);
11374 %}
11375
11376 ins_pipe(ialu_reg_reg_shift);
11377 %}
11378
11379 // This pattern is automatically generated from aarch64_ad.m4
11380 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11381 // val ^ (-1 ^ (val >> shift)) ==> eonw
11382 instruct XorI_reg_RShift_not_reg(iRegINoSp dst,
11383 iRegIorL2I src1, iRegIorL2I src2,
11384 immI src3, immI_M1 src4) %{
11385 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1)));
11386 ins_cost(1.9 * INSN_COST);
11387 format %{ "eonw $dst, $src1, $src2, ASR $src3" %}
11388
11389 ins_encode %{
11390 __ eonw(as_Register($dst$$reg),
11391 as_Register($src1$$reg),
11392 as_Register($src2$$reg),
11393 Assembler::ASR,
11394 $src3$$constant & 0x1f);
11395 %}
11396
11397 ins_pipe(ialu_reg_reg_shift);
11398 %}
11399
11400 // This pattern is automatically generated from aarch64_ad.m4
11401 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11402 // val ^ (-1 ^ (val >> shift)) ==> eon
11403 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst,
11404 iRegL src1, iRegL src2,
11405 immI src3, immL_M1 src4) %{
11406 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1)));
11407 ins_cost(1.9 * INSN_COST);
11408 format %{ "eon $dst, $src1, $src2, ASR $src3" %}
11409
11410 ins_encode %{
11411 __ eon(as_Register($dst$$reg),
11412 as_Register($src1$$reg),
11413 as_Register($src2$$reg),
11414 Assembler::ASR,
11415 $src3$$constant & 0x3f);
11416 %}
11417
11418 ins_pipe(ialu_reg_reg_shift);
11419 %}
11420
11421 // This pattern is automatically generated from aarch64_ad.m4
11422 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11423 // val ^ (-1 ^ (val ror shift)) ==> eonw
11424 instruct XorI_reg_RotateRight_not_reg(iRegINoSp dst,
11425 iRegIorL2I src1, iRegIorL2I src2,
11426 immI src3, immI_M1 src4) %{
11427 match(Set dst (XorI src4 (XorI(RotateRight src2 src3) src1)));
11428 ins_cost(1.9 * INSN_COST);
11429 format %{ "eonw $dst, $src1, $src2, ROR $src3" %}
11430
11431 ins_encode %{
11432 __ eonw(as_Register($dst$$reg),
11433 as_Register($src1$$reg),
11434 as_Register($src2$$reg),
11435 Assembler::ROR,
11436 $src3$$constant & 0x1f);
11437 %}
11438
11439 ins_pipe(ialu_reg_reg_shift);
11440 %}
11441
11442 // This pattern is automatically generated from aarch64_ad.m4
11443 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11444 // val ^ (-1 ^ (val ror shift)) ==> eon
11445 instruct XorL_reg_RotateRight_not_reg(iRegLNoSp dst,
11446 iRegL src1, iRegL src2,
11447 immI src3, immL_M1 src4) %{
11448 match(Set dst (XorL src4 (XorL(RotateRight src2 src3) src1)));
11449 ins_cost(1.9 * INSN_COST);
11450 format %{ "eon $dst, $src1, $src2, ROR $src3" %}
11451
11452 ins_encode %{
11453 __ eon(as_Register($dst$$reg),
11454 as_Register($src1$$reg),
11455 as_Register($src2$$reg),
11456 Assembler::ROR,
11457 $src3$$constant & 0x3f);
11458 %}
11459
11460 ins_pipe(ialu_reg_reg_shift);
11461 %}
11462
11463 // This pattern is automatically generated from aarch64_ad.m4
11464 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11465 // val ^ (-1 ^ (val << shift)) ==> eonw
11466 instruct XorI_reg_LShift_not_reg(iRegINoSp dst,
11467 iRegIorL2I src1, iRegIorL2I src2,
11468 immI src3, immI_M1 src4) %{
11469 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1)));
11470 ins_cost(1.9 * INSN_COST);
11471 format %{ "eonw $dst, $src1, $src2, LSL $src3" %}
11472
11473 ins_encode %{
11474 __ eonw(as_Register($dst$$reg),
11475 as_Register($src1$$reg),
11476 as_Register($src2$$reg),
11477 Assembler::LSL,
11478 $src3$$constant & 0x1f);
11479 %}
11480
11481 ins_pipe(ialu_reg_reg_shift);
11482 %}
11483
11484 // This pattern is automatically generated from aarch64_ad.m4
11485 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11486 // val ^ (-1 ^ (val << shift)) ==> eon
11487 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst,
11488 iRegL src1, iRegL src2,
11489 immI src3, immL_M1 src4) %{
11490 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1)));
11491 ins_cost(1.9 * INSN_COST);
11492 format %{ "eon $dst, $src1, $src2, LSL $src3" %}
11493
11494 ins_encode %{
11495 __ eon(as_Register($dst$$reg),
11496 as_Register($src1$$reg),
11497 as_Register($src2$$reg),
11498 Assembler::LSL,
11499 $src3$$constant & 0x3f);
11500 %}
11501
11502 ins_pipe(ialu_reg_reg_shift);
11503 %}
11504
11505 // This pattern is automatically generated from aarch64_ad.m4
11506 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11507 // val | (-1 ^ (val >>> shift)) ==> ornw
11508 instruct OrI_reg_URShift_not_reg(iRegINoSp dst,
11509 iRegIorL2I src1, iRegIorL2I src2,
11510 immI src3, immI_M1 src4) %{
11511 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4)));
11512 ins_cost(1.9 * INSN_COST);
11513 format %{ "ornw $dst, $src1, $src2, LSR $src3" %}
11514
11515 ins_encode %{
11516 __ ornw(as_Register($dst$$reg),
11517 as_Register($src1$$reg),
11518 as_Register($src2$$reg),
11519 Assembler::LSR,
11520 $src3$$constant & 0x1f);
11521 %}
11522
11523 ins_pipe(ialu_reg_reg_shift);
11524 %}
11525
11526 // This pattern is automatically generated from aarch64_ad.m4
11527 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11528 // val | (-1 ^ (val >>> shift)) ==> orn
11529 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst,
11530 iRegL src1, iRegL src2,
11531 immI src3, immL_M1 src4) %{
11532 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4)));
11533 ins_cost(1.9 * INSN_COST);
11534 format %{ "orn $dst, $src1, $src2, LSR $src3" %}
11535
11536 ins_encode %{
11537 __ orn(as_Register($dst$$reg),
11538 as_Register($src1$$reg),
11539 as_Register($src2$$reg),
11540 Assembler::LSR,
11541 $src3$$constant & 0x3f);
11542 %}
11543
11544 ins_pipe(ialu_reg_reg_shift);
11545 %}
11546
11547 // This pattern is automatically generated from aarch64_ad.m4
11548 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11549 // val | (-1 ^ (val >> shift)) ==> ornw
11550 instruct OrI_reg_RShift_not_reg(iRegINoSp dst,
11551 iRegIorL2I src1, iRegIorL2I src2,
11552 immI src3, immI_M1 src4) %{
11553 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4)));
11554 ins_cost(1.9 * INSN_COST);
11555 format %{ "ornw $dst, $src1, $src2, ASR $src3" %}
11556
11557 ins_encode %{
11558 __ ornw(as_Register($dst$$reg),
11559 as_Register($src1$$reg),
11560 as_Register($src2$$reg),
11561 Assembler::ASR,
11562 $src3$$constant & 0x1f);
11563 %}
11564
11565 ins_pipe(ialu_reg_reg_shift);
11566 %}
11567
11568 // This pattern is automatically generated from aarch64_ad.m4
11569 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11570 // val | (-1 ^ (val >> shift)) ==> orn
11571 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst,
11572 iRegL src1, iRegL src2,
11573 immI src3, immL_M1 src4) %{
11574 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4)));
11575 ins_cost(1.9 * INSN_COST);
11576 format %{ "orn $dst, $src1, $src2, ASR $src3" %}
11577
11578 ins_encode %{
11579 __ orn(as_Register($dst$$reg),
11580 as_Register($src1$$reg),
11581 as_Register($src2$$reg),
11582 Assembler::ASR,
11583 $src3$$constant & 0x3f);
11584 %}
11585
11586 ins_pipe(ialu_reg_reg_shift);
11587 %}
11588
11589 // This pattern is automatically generated from aarch64_ad.m4
11590 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11591 // val | (-1 ^ (val ror shift)) ==> ornw
11592 instruct OrI_reg_RotateRight_not_reg(iRegINoSp dst,
11593 iRegIorL2I src1, iRegIorL2I src2,
11594 immI src3, immI_M1 src4) %{
11595 match(Set dst (OrI src1 (XorI(RotateRight src2 src3) src4)));
11596 ins_cost(1.9 * INSN_COST);
11597 format %{ "ornw $dst, $src1, $src2, ROR $src3" %}
11598
11599 ins_encode %{
11600 __ ornw(as_Register($dst$$reg),
11601 as_Register($src1$$reg),
11602 as_Register($src2$$reg),
11603 Assembler::ROR,
11604 $src3$$constant & 0x1f);
11605 %}
11606
11607 ins_pipe(ialu_reg_reg_shift);
11608 %}
11609
11610 // This pattern is automatically generated from aarch64_ad.m4
11611 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11612 // val | (-1 ^ (val ror shift)) ==> orn
11613 instruct OrL_reg_RotateRight_not_reg(iRegLNoSp dst,
11614 iRegL src1, iRegL src2,
11615 immI src3, immL_M1 src4) %{
11616 match(Set dst (OrL src1 (XorL(RotateRight src2 src3) src4)));
11617 ins_cost(1.9 * INSN_COST);
11618 format %{ "orn $dst, $src1, $src2, ROR $src3" %}
11619
11620 ins_encode %{
11621 __ orn(as_Register($dst$$reg),
11622 as_Register($src1$$reg),
11623 as_Register($src2$$reg),
11624 Assembler::ROR,
11625 $src3$$constant & 0x3f);
11626 %}
11627
11628 ins_pipe(ialu_reg_reg_shift);
11629 %}
11630
11631 // This pattern is automatically generated from aarch64_ad.m4
11632 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11633 // val | (-1 ^ (val << shift)) ==> ornw
11634 instruct OrI_reg_LShift_not_reg(iRegINoSp dst,
11635 iRegIorL2I src1, iRegIorL2I src2,
11636 immI src3, immI_M1 src4) %{
11637 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4)));
11638 ins_cost(1.9 * INSN_COST);
11639 format %{ "ornw $dst, $src1, $src2, LSL $src3" %}
11640
11641 ins_encode %{
11642 __ ornw(as_Register($dst$$reg),
11643 as_Register($src1$$reg),
11644 as_Register($src2$$reg),
11645 Assembler::LSL,
11646 $src3$$constant & 0x1f);
11647 %}
11648
11649 ins_pipe(ialu_reg_reg_shift);
11650 %}
11651
11652 // This pattern is automatically generated from aarch64_ad.m4
11653 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11654 // val | (-1 ^ (val << shift)) ==> orn
11655 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst,
11656 iRegL src1, iRegL src2,
11657 immI src3, immL_M1 src4) %{
11658 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4)));
11659 ins_cost(1.9 * INSN_COST);
11660 format %{ "orn $dst, $src1, $src2, LSL $src3" %}
11661
11662 ins_encode %{
11663 __ orn(as_Register($dst$$reg),
11664 as_Register($src1$$reg),
11665 as_Register($src2$$reg),
11666 Assembler::LSL,
11667 $src3$$constant & 0x3f);
11668 %}
11669
11670 ins_pipe(ialu_reg_reg_shift);
11671 %}
11672
11673 // This pattern is automatically generated from aarch64_ad.m4
11674 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11675 instruct AndI_reg_URShift_reg(iRegINoSp dst,
11676 iRegIorL2I src1, iRegIorL2I src2,
11677 immI src3) %{
11678 match(Set dst (AndI src1 (URShiftI src2 src3)));
11679
11680 ins_cost(1.9 * INSN_COST);
11681 format %{ "andw $dst, $src1, $src2, LSR $src3" %}
11682
11683 ins_encode %{
11684 __ andw(as_Register($dst$$reg),
11685 as_Register($src1$$reg),
11686 as_Register($src2$$reg),
11687 Assembler::LSR,
11688 $src3$$constant & 0x1f);
11689 %}
11690
11691 ins_pipe(ialu_reg_reg_shift);
11692 %}
11693
11694 // This pattern is automatically generated from aarch64_ad.m4
11695 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11696 instruct AndL_reg_URShift_reg(iRegLNoSp dst,
11697 iRegL src1, iRegL src2,
11698 immI src3) %{
11699 match(Set dst (AndL src1 (URShiftL src2 src3)));
11700
11701 ins_cost(1.9 * INSN_COST);
11702 format %{ "andr $dst, $src1, $src2, LSR $src3" %}
11703
11704 ins_encode %{
11705 __ andr(as_Register($dst$$reg),
11706 as_Register($src1$$reg),
11707 as_Register($src2$$reg),
11708 Assembler::LSR,
11709 $src3$$constant & 0x3f);
11710 %}
11711
11712 ins_pipe(ialu_reg_reg_shift);
11713 %}
11714
11715 // This pattern is automatically generated from aarch64_ad.m4
11716 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11717 instruct AndI_reg_RShift_reg(iRegINoSp dst,
11718 iRegIorL2I src1, iRegIorL2I src2,
11719 immI src3) %{
11720 match(Set dst (AndI src1 (RShiftI src2 src3)));
11721
11722 ins_cost(1.9 * INSN_COST);
11723 format %{ "andw $dst, $src1, $src2, ASR $src3" %}
11724
11725 ins_encode %{
11726 __ andw(as_Register($dst$$reg),
11727 as_Register($src1$$reg),
11728 as_Register($src2$$reg),
11729 Assembler::ASR,
11730 $src3$$constant & 0x1f);
11731 %}
11732
11733 ins_pipe(ialu_reg_reg_shift);
11734 %}
11735
11736 // This pattern is automatically generated from aarch64_ad.m4
11737 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11738 instruct AndL_reg_RShift_reg(iRegLNoSp dst,
11739 iRegL src1, iRegL src2,
11740 immI src3) %{
11741 match(Set dst (AndL src1 (RShiftL src2 src3)));
11742
11743 ins_cost(1.9 * INSN_COST);
11744 format %{ "andr $dst, $src1, $src2, ASR $src3" %}
11745
11746 ins_encode %{
11747 __ andr(as_Register($dst$$reg),
11748 as_Register($src1$$reg),
11749 as_Register($src2$$reg),
11750 Assembler::ASR,
11751 $src3$$constant & 0x3f);
11752 %}
11753
11754 ins_pipe(ialu_reg_reg_shift);
11755 %}
11756
11757 // This pattern is automatically generated from aarch64_ad.m4
11758 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11759 instruct AndI_reg_LShift_reg(iRegINoSp dst,
11760 iRegIorL2I src1, iRegIorL2I src2,
11761 immI src3) %{
11762 match(Set dst (AndI src1 (LShiftI src2 src3)));
11763
11764 ins_cost(1.9 * INSN_COST);
11765 format %{ "andw $dst, $src1, $src2, LSL $src3" %}
11766
11767 ins_encode %{
11768 __ andw(as_Register($dst$$reg),
11769 as_Register($src1$$reg),
11770 as_Register($src2$$reg),
11771 Assembler::LSL,
11772 $src3$$constant & 0x1f);
11773 %}
11774
11775 ins_pipe(ialu_reg_reg_shift);
11776 %}
11777
11778 // This pattern is automatically generated from aarch64_ad.m4
11779 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11780 instruct AndL_reg_LShift_reg(iRegLNoSp dst,
11781 iRegL src1, iRegL src2,
11782 immI src3) %{
11783 match(Set dst (AndL src1 (LShiftL src2 src3)));
11784
11785 ins_cost(1.9 * INSN_COST);
11786 format %{ "andr $dst, $src1, $src2, LSL $src3" %}
11787
11788 ins_encode %{
11789 __ andr(as_Register($dst$$reg),
11790 as_Register($src1$$reg),
11791 as_Register($src2$$reg),
11792 Assembler::LSL,
11793 $src3$$constant & 0x3f);
11794 %}
11795
11796 ins_pipe(ialu_reg_reg_shift);
11797 %}
11798
11799 // This pattern is automatically generated from aarch64_ad.m4
11800 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11801 instruct AndI_reg_RotateRight_reg(iRegINoSp dst,
11802 iRegIorL2I src1, iRegIorL2I src2,
11803 immI src3) %{
11804 match(Set dst (AndI src1 (RotateRight src2 src3)));
11805
11806 ins_cost(1.9 * INSN_COST);
11807 format %{ "andw $dst, $src1, $src2, ROR $src3" %}
11808
11809 ins_encode %{
11810 __ andw(as_Register($dst$$reg),
11811 as_Register($src1$$reg),
11812 as_Register($src2$$reg),
11813 Assembler::ROR,
11814 $src3$$constant & 0x1f);
11815 %}
11816
11817 ins_pipe(ialu_reg_reg_shift);
11818 %}
11819
11820 // This pattern is automatically generated from aarch64_ad.m4
11821 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11822 instruct AndL_reg_RotateRight_reg(iRegLNoSp dst,
11823 iRegL src1, iRegL src2,
11824 immI src3) %{
11825 match(Set dst (AndL src1 (RotateRight src2 src3)));
11826
11827 ins_cost(1.9 * INSN_COST);
11828 format %{ "andr $dst, $src1, $src2, ROR $src3" %}
11829
11830 ins_encode %{
11831 __ andr(as_Register($dst$$reg),
11832 as_Register($src1$$reg),
11833 as_Register($src2$$reg),
11834 Assembler::ROR,
11835 $src3$$constant & 0x3f);
11836 %}
11837
11838 ins_pipe(ialu_reg_reg_shift);
11839 %}
11840
11841 // This pattern is automatically generated from aarch64_ad.m4
11842 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11843 instruct XorI_reg_URShift_reg(iRegINoSp dst,
11844 iRegIorL2I src1, iRegIorL2I src2,
11845 immI src3) %{
11846 match(Set dst (XorI src1 (URShiftI src2 src3)));
11847
11848 ins_cost(1.9 * INSN_COST);
11849 format %{ "eorw $dst, $src1, $src2, LSR $src3" %}
11850
11851 ins_encode %{
11852 __ eorw(as_Register($dst$$reg),
11853 as_Register($src1$$reg),
11854 as_Register($src2$$reg),
11855 Assembler::LSR,
11856 $src3$$constant & 0x1f);
11857 %}
11858
11859 ins_pipe(ialu_reg_reg_shift);
11860 %}
11861
11862 // This pattern is automatically generated from aarch64_ad.m4
11863 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11864 instruct XorL_reg_URShift_reg(iRegLNoSp dst,
11865 iRegL src1, iRegL src2,
11866 immI src3) %{
11867 match(Set dst (XorL src1 (URShiftL src2 src3)));
11868
11869 ins_cost(1.9 * INSN_COST);
11870 format %{ "eor $dst, $src1, $src2, LSR $src3" %}
11871
11872 ins_encode %{
11873 __ eor(as_Register($dst$$reg),
11874 as_Register($src1$$reg),
11875 as_Register($src2$$reg),
11876 Assembler::LSR,
11877 $src3$$constant & 0x3f);
11878 %}
11879
11880 ins_pipe(ialu_reg_reg_shift);
11881 %}
11882
11883 // This pattern is automatically generated from aarch64_ad.m4
11884 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11885 instruct XorI_reg_RShift_reg(iRegINoSp dst,
11886 iRegIorL2I src1, iRegIorL2I src2,
11887 immI src3) %{
11888 match(Set dst (XorI src1 (RShiftI src2 src3)));
11889
11890 ins_cost(1.9 * INSN_COST);
11891 format %{ "eorw $dst, $src1, $src2, ASR $src3" %}
11892
11893 ins_encode %{
11894 __ eorw(as_Register($dst$$reg),
11895 as_Register($src1$$reg),
11896 as_Register($src2$$reg),
11897 Assembler::ASR,
11898 $src3$$constant & 0x1f);
11899 %}
11900
11901 ins_pipe(ialu_reg_reg_shift);
11902 %}
11903
11904 // This pattern is automatically generated from aarch64_ad.m4
11905 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11906 instruct XorL_reg_RShift_reg(iRegLNoSp dst,
11907 iRegL src1, iRegL src2,
11908 immI src3) %{
11909 match(Set dst (XorL src1 (RShiftL src2 src3)));
11910
11911 ins_cost(1.9 * INSN_COST);
11912 format %{ "eor $dst, $src1, $src2, ASR $src3" %}
11913
11914 ins_encode %{
11915 __ eor(as_Register($dst$$reg),
11916 as_Register($src1$$reg),
11917 as_Register($src2$$reg),
11918 Assembler::ASR,
11919 $src3$$constant & 0x3f);
11920 %}
11921
11922 ins_pipe(ialu_reg_reg_shift);
11923 %}
11924
11925 // This pattern is automatically generated from aarch64_ad.m4
11926 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11927 instruct XorI_reg_LShift_reg(iRegINoSp dst,
11928 iRegIorL2I src1, iRegIorL2I src2,
11929 immI src3) %{
11930 match(Set dst (XorI src1 (LShiftI src2 src3)));
11931
11932 ins_cost(1.9 * INSN_COST);
11933 format %{ "eorw $dst, $src1, $src2, LSL $src3" %}
11934
11935 ins_encode %{
11936 __ eorw(as_Register($dst$$reg),
11937 as_Register($src1$$reg),
11938 as_Register($src2$$reg),
11939 Assembler::LSL,
11940 $src3$$constant & 0x1f);
11941 %}
11942
11943 ins_pipe(ialu_reg_reg_shift);
11944 %}
11945
11946 // This pattern is automatically generated from aarch64_ad.m4
11947 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11948 instruct XorL_reg_LShift_reg(iRegLNoSp dst,
11949 iRegL src1, iRegL src2,
11950 immI src3) %{
11951 match(Set dst (XorL src1 (LShiftL src2 src3)));
11952
11953 ins_cost(1.9 * INSN_COST);
11954 format %{ "eor $dst, $src1, $src2, LSL $src3" %}
11955
11956 ins_encode %{
11957 __ eor(as_Register($dst$$reg),
11958 as_Register($src1$$reg),
11959 as_Register($src2$$reg),
11960 Assembler::LSL,
11961 $src3$$constant & 0x3f);
11962 %}
11963
11964 ins_pipe(ialu_reg_reg_shift);
11965 %}
11966
11967 // This pattern is automatically generated from aarch64_ad.m4
11968 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11969 instruct XorI_reg_RotateRight_reg(iRegINoSp dst,
11970 iRegIorL2I src1, iRegIorL2I src2,
11971 immI src3) %{
11972 match(Set dst (XorI src1 (RotateRight src2 src3)));
11973
11974 ins_cost(1.9 * INSN_COST);
11975 format %{ "eorw $dst, $src1, $src2, ROR $src3" %}
11976
11977 ins_encode %{
11978 __ eorw(as_Register($dst$$reg),
11979 as_Register($src1$$reg),
11980 as_Register($src2$$reg),
11981 Assembler::ROR,
11982 $src3$$constant & 0x1f);
11983 %}
11984
11985 ins_pipe(ialu_reg_reg_shift);
11986 %}
11987
11988 // This pattern is automatically generated from aarch64_ad.m4
11989 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11990 instruct XorL_reg_RotateRight_reg(iRegLNoSp dst,
11991 iRegL src1, iRegL src2,
11992 immI src3) %{
11993 match(Set dst (XorL src1 (RotateRight src2 src3)));
11994
11995 ins_cost(1.9 * INSN_COST);
11996 format %{ "eor $dst, $src1, $src2, ROR $src3" %}
11997
11998 ins_encode %{
11999 __ eor(as_Register($dst$$reg),
12000 as_Register($src1$$reg),
12001 as_Register($src2$$reg),
12002 Assembler::ROR,
12003 $src3$$constant & 0x3f);
12004 %}
12005
12006 ins_pipe(ialu_reg_reg_shift);
12007 %}
12008
12009 // This pattern is automatically generated from aarch64_ad.m4
12010 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12011 instruct OrI_reg_URShift_reg(iRegINoSp dst,
12012 iRegIorL2I src1, iRegIorL2I src2,
12013 immI src3) %{
12014 match(Set dst (OrI src1 (URShiftI src2 src3)));
12015
12016 ins_cost(1.9 * INSN_COST);
12017 format %{ "orrw $dst, $src1, $src2, LSR $src3" %}
12018
12019 ins_encode %{
12020 __ orrw(as_Register($dst$$reg),
12021 as_Register($src1$$reg),
12022 as_Register($src2$$reg),
12023 Assembler::LSR,
12024 $src3$$constant & 0x1f);
12025 %}
12026
12027 ins_pipe(ialu_reg_reg_shift);
12028 %}
12029
12030 // This pattern is automatically generated from aarch64_ad.m4
12031 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12032 instruct OrL_reg_URShift_reg(iRegLNoSp dst,
12033 iRegL src1, iRegL src2,
12034 immI src3) %{
12035 match(Set dst (OrL src1 (URShiftL src2 src3)));
12036
12037 ins_cost(1.9 * INSN_COST);
12038 format %{ "orr $dst, $src1, $src2, LSR $src3" %}
12039
12040 ins_encode %{
12041 __ orr(as_Register($dst$$reg),
12042 as_Register($src1$$reg),
12043 as_Register($src2$$reg),
12044 Assembler::LSR,
12045 $src3$$constant & 0x3f);
12046 %}
12047
12048 ins_pipe(ialu_reg_reg_shift);
12049 %}
12050
12051 // This pattern is automatically generated from aarch64_ad.m4
12052 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12053 instruct OrI_reg_RShift_reg(iRegINoSp dst,
12054 iRegIorL2I src1, iRegIorL2I src2,
12055 immI src3) %{
12056 match(Set dst (OrI src1 (RShiftI src2 src3)));
12057
12058 ins_cost(1.9 * INSN_COST);
12059 format %{ "orrw $dst, $src1, $src2, ASR $src3" %}
12060
12061 ins_encode %{
12062 __ orrw(as_Register($dst$$reg),
12063 as_Register($src1$$reg),
12064 as_Register($src2$$reg),
12065 Assembler::ASR,
12066 $src3$$constant & 0x1f);
12067 %}
12068
12069 ins_pipe(ialu_reg_reg_shift);
12070 %}
12071
12072 // This pattern is automatically generated from aarch64_ad.m4
12073 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12074 instruct OrL_reg_RShift_reg(iRegLNoSp dst,
12075 iRegL src1, iRegL src2,
12076 immI src3) %{
12077 match(Set dst (OrL src1 (RShiftL src2 src3)));
12078
12079 ins_cost(1.9 * INSN_COST);
12080 format %{ "orr $dst, $src1, $src2, ASR $src3" %}
12081
12082 ins_encode %{
12083 __ orr(as_Register($dst$$reg),
12084 as_Register($src1$$reg),
12085 as_Register($src2$$reg),
12086 Assembler::ASR,
12087 $src3$$constant & 0x3f);
12088 %}
12089
12090 ins_pipe(ialu_reg_reg_shift);
12091 %}
12092
12093 // This pattern is automatically generated from aarch64_ad.m4
12094 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12095 instruct OrI_reg_LShift_reg(iRegINoSp dst,
12096 iRegIorL2I src1, iRegIorL2I src2,
12097 immI src3) %{
12098 match(Set dst (OrI src1 (LShiftI src2 src3)));
12099
12100 ins_cost(1.9 * INSN_COST);
12101 format %{ "orrw $dst, $src1, $src2, LSL $src3" %}
12102
12103 ins_encode %{
12104 __ orrw(as_Register($dst$$reg),
12105 as_Register($src1$$reg),
12106 as_Register($src2$$reg),
12107 Assembler::LSL,
12108 $src3$$constant & 0x1f);
12109 %}
12110
12111 ins_pipe(ialu_reg_reg_shift);
12112 %}
12113
12114 // This pattern is automatically generated from aarch64_ad.m4
12115 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12116 instruct OrL_reg_LShift_reg(iRegLNoSp dst,
12117 iRegL src1, iRegL src2,
12118 immI src3) %{
12119 match(Set dst (OrL src1 (LShiftL src2 src3)));
12120
12121 ins_cost(1.9 * INSN_COST);
12122 format %{ "orr $dst, $src1, $src2, LSL $src3" %}
12123
12124 ins_encode %{
12125 __ orr(as_Register($dst$$reg),
12126 as_Register($src1$$reg),
12127 as_Register($src2$$reg),
12128 Assembler::LSL,
12129 $src3$$constant & 0x3f);
12130 %}
12131
12132 ins_pipe(ialu_reg_reg_shift);
12133 %}
12134
12135 // This pattern is automatically generated from aarch64_ad.m4
12136 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12137 instruct OrI_reg_RotateRight_reg(iRegINoSp dst,
12138 iRegIorL2I src1, iRegIorL2I src2,
12139 immI src3) %{
12140 match(Set dst (OrI src1 (RotateRight src2 src3)));
12141
12142 ins_cost(1.9 * INSN_COST);
12143 format %{ "orrw $dst, $src1, $src2, ROR $src3" %}
12144
12145 ins_encode %{
12146 __ orrw(as_Register($dst$$reg),
12147 as_Register($src1$$reg),
12148 as_Register($src2$$reg),
12149 Assembler::ROR,
12150 $src3$$constant & 0x1f);
12151 %}
12152
12153 ins_pipe(ialu_reg_reg_shift);
12154 %}
12155
12156 // This pattern is automatically generated from aarch64_ad.m4
12157 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12158 instruct OrL_reg_RotateRight_reg(iRegLNoSp dst,
12159 iRegL src1, iRegL src2,
12160 immI src3) %{
12161 match(Set dst (OrL src1 (RotateRight src2 src3)));
12162
12163 ins_cost(1.9 * INSN_COST);
12164 format %{ "orr $dst, $src1, $src2, ROR $src3" %}
12165
12166 ins_encode %{
12167 __ orr(as_Register($dst$$reg),
12168 as_Register($src1$$reg),
12169 as_Register($src2$$reg),
12170 Assembler::ROR,
12171 $src3$$constant & 0x3f);
12172 %}
12173
12174 ins_pipe(ialu_reg_reg_shift);
12175 %}
12176
12177 // This pattern is automatically generated from aarch64_ad.m4
12178 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12179 instruct AddI_reg_URShift_reg(iRegINoSp dst,
12180 iRegIorL2I src1, iRegIorL2I src2,
12181 immI src3) %{
12182 match(Set dst (AddI src1 (URShiftI src2 src3)));
12183
12184 ins_cost(1.9 * INSN_COST);
12185 format %{ "addw $dst, $src1, $src2, LSR $src3" %}
12186
12187 ins_encode %{
12188 __ addw(as_Register($dst$$reg),
12189 as_Register($src1$$reg),
12190 as_Register($src2$$reg),
12191 Assembler::LSR,
12192 $src3$$constant & 0x1f);
12193 %}
12194
12195 ins_pipe(ialu_reg_reg_shift);
12196 %}
12197
12198 // This pattern is automatically generated from aarch64_ad.m4
12199 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12200 instruct AddL_reg_URShift_reg(iRegLNoSp dst,
12201 iRegL src1, iRegL src2,
12202 immI src3) %{
12203 match(Set dst (AddL src1 (URShiftL src2 src3)));
12204
12205 ins_cost(1.9 * INSN_COST);
12206 format %{ "add $dst, $src1, $src2, LSR $src3" %}
12207
12208 ins_encode %{
12209 __ add(as_Register($dst$$reg),
12210 as_Register($src1$$reg),
12211 as_Register($src2$$reg),
12212 Assembler::LSR,
12213 $src3$$constant & 0x3f);
12214 %}
12215
12216 ins_pipe(ialu_reg_reg_shift);
12217 %}
12218
12219 // This pattern is automatically generated from aarch64_ad.m4
12220 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12221 instruct AddI_reg_RShift_reg(iRegINoSp dst,
12222 iRegIorL2I src1, iRegIorL2I src2,
12223 immI src3) %{
12224 match(Set dst (AddI src1 (RShiftI src2 src3)));
12225
12226 ins_cost(1.9 * INSN_COST);
12227 format %{ "addw $dst, $src1, $src2, ASR $src3" %}
12228
12229 ins_encode %{
12230 __ addw(as_Register($dst$$reg),
12231 as_Register($src1$$reg),
12232 as_Register($src2$$reg),
12233 Assembler::ASR,
12234 $src3$$constant & 0x1f);
12235 %}
12236
12237 ins_pipe(ialu_reg_reg_shift);
12238 %}
12239
12240 // This pattern is automatically generated from aarch64_ad.m4
12241 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12242 instruct AddL_reg_RShift_reg(iRegLNoSp dst,
12243 iRegL src1, iRegL src2,
12244 immI src3) %{
12245 match(Set dst (AddL src1 (RShiftL src2 src3)));
12246
12247 ins_cost(1.9 * INSN_COST);
12248 format %{ "add $dst, $src1, $src2, ASR $src3" %}
12249
12250 ins_encode %{
12251 __ add(as_Register($dst$$reg),
12252 as_Register($src1$$reg),
12253 as_Register($src2$$reg),
12254 Assembler::ASR,
12255 $src3$$constant & 0x3f);
12256 %}
12257
12258 ins_pipe(ialu_reg_reg_shift);
12259 %}
12260
12261 // This pattern is automatically generated from aarch64_ad.m4
12262 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12263 instruct AddI_reg_LShift_reg(iRegINoSp dst,
12264 iRegIorL2I src1, iRegIorL2I src2,
12265 immI src3) %{
12266 match(Set dst (AddI src1 (LShiftI src2 src3)));
12267
12268 ins_cost(1.9 * INSN_COST);
12269 format %{ "addw $dst, $src1, $src2, LSL $src3" %}
12270
12271 ins_encode %{
12272 __ addw(as_Register($dst$$reg),
12273 as_Register($src1$$reg),
12274 as_Register($src2$$reg),
12275 Assembler::LSL,
12276 $src3$$constant & 0x1f);
12277 %}
12278
12279 ins_pipe(ialu_reg_reg_shift);
12280 %}
12281
12282 // This pattern is automatically generated from aarch64_ad.m4
12283 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12284 instruct AddL_reg_LShift_reg(iRegLNoSp dst,
12285 iRegL src1, iRegL src2,
12286 immI src3) %{
12287 match(Set dst (AddL src1 (LShiftL src2 src3)));
12288
12289 ins_cost(1.9 * INSN_COST);
12290 format %{ "add $dst, $src1, $src2, LSL $src3" %}
12291
12292 ins_encode %{
12293 __ add(as_Register($dst$$reg),
12294 as_Register($src1$$reg),
12295 as_Register($src2$$reg),
12296 Assembler::LSL,
12297 $src3$$constant & 0x3f);
12298 %}
12299
12300 ins_pipe(ialu_reg_reg_shift);
12301 %}
12302
12303 // This pattern is automatically generated from aarch64_ad.m4
12304 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12305 instruct SubI_reg_URShift_reg(iRegINoSp dst,
12306 iRegIorL2I src1, iRegIorL2I src2,
12307 immI src3) %{
12308 match(Set dst (SubI src1 (URShiftI src2 src3)));
12309
12310 ins_cost(1.9 * INSN_COST);
12311 format %{ "subw $dst, $src1, $src2, LSR $src3" %}
12312
12313 ins_encode %{
12314 __ subw(as_Register($dst$$reg),
12315 as_Register($src1$$reg),
12316 as_Register($src2$$reg),
12317 Assembler::LSR,
12318 $src3$$constant & 0x1f);
12319 %}
12320
12321 ins_pipe(ialu_reg_reg_shift);
12322 %}
12323
12324 // This pattern is automatically generated from aarch64_ad.m4
12325 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12326 instruct SubL_reg_URShift_reg(iRegLNoSp dst,
12327 iRegL src1, iRegL src2,
12328 immI src3) %{
12329 match(Set dst (SubL src1 (URShiftL src2 src3)));
12330
12331 ins_cost(1.9 * INSN_COST);
12332 format %{ "sub $dst, $src1, $src2, LSR $src3" %}
12333
12334 ins_encode %{
12335 __ sub(as_Register($dst$$reg),
12336 as_Register($src1$$reg),
12337 as_Register($src2$$reg),
12338 Assembler::LSR,
12339 $src3$$constant & 0x3f);
12340 %}
12341
12342 ins_pipe(ialu_reg_reg_shift);
12343 %}
12344
12345 // This pattern is automatically generated from aarch64_ad.m4
12346 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12347 instruct SubI_reg_RShift_reg(iRegINoSp dst,
12348 iRegIorL2I src1, iRegIorL2I src2,
12349 immI src3) %{
12350 match(Set dst (SubI src1 (RShiftI src2 src3)));
12351
12352 ins_cost(1.9 * INSN_COST);
12353 format %{ "subw $dst, $src1, $src2, ASR $src3" %}
12354
12355 ins_encode %{
12356 __ subw(as_Register($dst$$reg),
12357 as_Register($src1$$reg),
12358 as_Register($src2$$reg),
12359 Assembler::ASR,
12360 $src3$$constant & 0x1f);
12361 %}
12362
12363 ins_pipe(ialu_reg_reg_shift);
12364 %}
12365
12366 // This pattern is automatically generated from aarch64_ad.m4
12367 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12368 instruct SubL_reg_RShift_reg(iRegLNoSp dst,
12369 iRegL src1, iRegL src2,
12370 immI src3) %{
12371 match(Set dst (SubL src1 (RShiftL src2 src3)));
12372
12373 ins_cost(1.9 * INSN_COST);
12374 format %{ "sub $dst, $src1, $src2, ASR $src3" %}
12375
12376 ins_encode %{
12377 __ sub(as_Register($dst$$reg),
12378 as_Register($src1$$reg),
12379 as_Register($src2$$reg),
12380 Assembler::ASR,
12381 $src3$$constant & 0x3f);
12382 %}
12383
12384 ins_pipe(ialu_reg_reg_shift);
12385 %}
12386
12387 // This pattern is automatically generated from aarch64_ad.m4
12388 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12389 instruct SubI_reg_LShift_reg(iRegINoSp dst,
12390 iRegIorL2I src1, iRegIorL2I src2,
12391 immI src3) %{
12392 match(Set dst (SubI src1 (LShiftI src2 src3)));
12393
12394 ins_cost(1.9 * INSN_COST);
12395 format %{ "subw $dst, $src1, $src2, LSL $src3" %}
12396
12397 ins_encode %{
12398 __ subw(as_Register($dst$$reg),
12399 as_Register($src1$$reg),
12400 as_Register($src2$$reg),
12401 Assembler::LSL,
12402 $src3$$constant & 0x1f);
12403 %}
12404
12405 ins_pipe(ialu_reg_reg_shift);
12406 %}
12407
12408 // This pattern is automatically generated from aarch64_ad.m4
12409 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12410 instruct SubL_reg_LShift_reg(iRegLNoSp dst,
12411 iRegL src1, iRegL src2,
12412 immI src3) %{
12413 match(Set dst (SubL src1 (LShiftL src2 src3)));
12414
12415 ins_cost(1.9 * INSN_COST);
12416 format %{ "sub $dst, $src1, $src2, LSL $src3" %}
12417
12418 ins_encode %{
12419 __ sub(as_Register($dst$$reg),
12420 as_Register($src1$$reg),
12421 as_Register($src2$$reg),
12422 Assembler::LSL,
12423 $src3$$constant & 0x3f);
12424 %}
12425
12426 ins_pipe(ialu_reg_reg_shift);
12427 %}
12428
12429 // This pattern is automatically generated from aarch64_ad.m4
12430 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12431
12432 // Shift Left followed by Shift Right.
12433 // This idiom is used by the compiler for the i2b bytecode etc.
12434 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
12435 %{
12436 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count));
12437 ins_cost(INSN_COST * 2);
12438 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
12439 ins_encode %{
12440 int lshift = $lshift_count$$constant & 63;
12441 int rshift = $rshift_count$$constant & 63;
12442 int s = 63 - lshift;
12443 int r = (rshift - lshift) & 63;
12444 __ sbfm(as_Register($dst$$reg),
12445 as_Register($src$$reg),
12446 r, s);
12447 %}
12448
12449 ins_pipe(ialu_reg_shift);
12450 %}
12451
12452 // This pattern is automatically generated from aarch64_ad.m4
12453 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12454
12455 // Shift Left followed by Shift Right.
12456 // This idiom is used by the compiler for the i2b bytecode etc.
12457 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
12458 %{
12459 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count));
12460 ins_cost(INSN_COST * 2);
12461 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
12462 ins_encode %{
12463 int lshift = $lshift_count$$constant & 31;
12464 int rshift = $rshift_count$$constant & 31;
12465 int s = 31 - lshift;
12466 int r = (rshift - lshift) & 31;
12467 __ sbfmw(as_Register($dst$$reg),
12468 as_Register($src$$reg),
12469 r, s);
12470 %}
12471
12472 ins_pipe(ialu_reg_shift);
12473 %}
12474
12475 // This pattern is automatically generated from aarch64_ad.m4
12476 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12477
12478 // Shift Left followed by Shift Right.
12479 // This idiom is used by the compiler for the i2b bytecode etc.
12480 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
12481 %{
12482 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count));
12483 ins_cost(INSN_COST * 2);
12484 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
12485 ins_encode %{
12486 int lshift = $lshift_count$$constant & 63;
12487 int rshift = $rshift_count$$constant & 63;
12488 int s = 63 - lshift;
12489 int r = (rshift - lshift) & 63;
12490 __ ubfm(as_Register($dst$$reg),
12491 as_Register($src$$reg),
12492 r, s);
12493 %}
12494
12495 ins_pipe(ialu_reg_shift);
12496 %}
12497
12498 // This pattern is automatically generated from aarch64_ad.m4
12499 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12500
12501 // Shift Left followed by Shift Right.
12502 // This idiom is used by the compiler for the i2b bytecode etc.
12503 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
12504 %{
12505 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count));
12506 ins_cost(INSN_COST * 2);
12507 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
12508 ins_encode %{
12509 int lshift = $lshift_count$$constant & 31;
12510 int rshift = $rshift_count$$constant & 31;
12511 int s = 31 - lshift;
12512 int r = (rshift - lshift) & 31;
12513 __ ubfmw(as_Register($dst$$reg),
12514 as_Register($src$$reg),
12515 r, s);
12516 %}
12517
12518 ins_pipe(ialu_reg_shift);
12519 %}
12520
12521 // Bitfield extract with shift & mask
12522
12523 // This pattern is automatically generated from aarch64_ad.m4
12524 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12525 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
12526 %{
12527 match(Set dst (AndI (URShiftI src rshift) mask));
12528 // Make sure we are not going to exceed what ubfxw can do.
12529 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
12530
12531 ins_cost(INSN_COST);
12532 format %{ "ubfxw $dst, $src, $rshift, $mask" %}
12533 ins_encode %{
12534 int rshift = $rshift$$constant & 31;
12535 intptr_t mask = $mask$$constant;
12536 int width = exact_log2(mask+1);
12537 __ ubfxw(as_Register($dst$$reg),
12538 as_Register($src$$reg), rshift, width);
12539 %}
12540 ins_pipe(ialu_reg_shift);
12541 %}
12542
12543 // This pattern is automatically generated from aarch64_ad.m4
12544 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12545 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask)
12546 %{
12547 match(Set dst (AndL (URShiftL src rshift) mask));
12548 // Make sure we are not going to exceed what ubfx can do.
12549 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1));
12550
12551 ins_cost(INSN_COST);
12552 format %{ "ubfx $dst, $src, $rshift, $mask" %}
12553 ins_encode %{
12554 int rshift = $rshift$$constant & 63;
12555 intptr_t mask = $mask$$constant;
12556 int width = exact_log2_long(mask+1);
12557 __ ubfx(as_Register($dst$$reg),
12558 as_Register($src$$reg), rshift, width);
12559 %}
12560 ins_pipe(ialu_reg_shift);
12561 %}
12562
12563
12564 // This pattern is automatically generated from aarch64_ad.m4
12565 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12566
12567 // We can use ubfx when extending an And with a mask when we know mask
12568 // is positive. We know that because immI_bitmask guarantees it.
12569 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
12570 %{
12571 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
12572 // Make sure we are not going to exceed what ubfxw can do.
12573 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
12574
12575 ins_cost(INSN_COST * 2);
12576 format %{ "ubfx $dst, $src, $rshift, $mask" %}
12577 ins_encode %{
12578 int rshift = $rshift$$constant & 31;
12579 intptr_t mask = $mask$$constant;
12580 int width = exact_log2(mask+1);
12581 __ ubfx(as_Register($dst$$reg),
12582 as_Register($src$$reg), rshift, width);
12583 %}
12584 ins_pipe(ialu_reg_shift);
12585 %}
12586
12587
12588 // This pattern is automatically generated from aarch64_ad.m4
12589 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12590
12591 // We can use ubfiz when masking by a positive number and then left shifting the result.
12592 // We know that the mask is positive because immI_bitmask guarantees it.
12593 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
12594 %{
12595 match(Set dst (LShiftI (AndI src mask) lshift));
12596 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1));
12597
12598 ins_cost(INSN_COST);
12599 format %{ "ubfizw $dst, $src, $lshift, $mask" %}
12600 ins_encode %{
12601 int lshift = $lshift$$constant & 31;
12602 intptr_t mask = $mask$$constant;
12603 int width = exact_log2(mask+1);
12604 __ ubfizw(as_Register($dst$$reg),
12605 as_Register($src$$reg), lshift, width);
12606 %}
12607 ins_pipe(ialu_reg_shift);
12608 %}
12609
12610 // This pattern is automatically generated from aarch64_ad.m4
12611 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12612
12613 // We can use ubfiz when masking by a positive number and then left shifting the result.
12614 // We know that the mask is positive because immL_bitmask guarantees it.
12615 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
12616 %{
12617 match(Set dst (LShiftL (AndL src mask) lshift));
12618 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
12619
12620 ins_cost(INSN_COST);
12621 format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12622 ins_encode %{
12623 int lshift = $lshift$$constant & 63;
12624 intptr_t mask = $mask$$constant;
12625 int width = exact_log2_long(mask+1);
12626 __ ubfiz(as_Register($dst$$reg),
12627 as_Register($src$$reg), lshift, width);
12628 %}
12629 ins_pipe(ialu_reg_shift);
12630 %}
12631
12632 // This pattern is automatically generated from aarch64_ad.m4
12633 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12634
12635 // We can use ubfiz when masking by a positive number and then left shifting the result.
12636 // We know that the mask is positive because immI_bitmask guarantees it.
12637 instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
12638 %{
12639 match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift)));
12640 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31);
12641
12642 ins_cost(INSN_COST);
12643 format %{ "ubfizw $dst, $src, $lshift, $mask" %}
12644 ins_encode %{
12645 int lshift = $lshift$$constant & 31;
12646 intptr_t mask = $mask$$constant;
12647 int width = exact_log2(mask+1);
12648 __ ubfizw(as_Register($dst$$reg),
12649 as_Register($src$$reg), lshift, width);
12650 %}
12651 ins_pipe(ialu_reg_shift);
12652 %}
12653
12654 // This pattern is automatically generated from aarch64_ad.m4
12655 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12656
12657 // We can use ubfiz when masking by a positive number and then left shifting the result.
12658 // We know that the mask is positive because immL_bitmask guarantees it.
12659 instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
12660 %{
12661 match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift)));
12662 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31);
12663
12664 ins_cost(INSN_COST);
12665 format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12666 ins_encode %{
12667 int lshift = $lshift$$constant & 63;
12668 intptr_t mask = $mask$$constant;
12669 int width = exact_log2_long(mask+1);
12670 __ ubfiz(as_Register($dst$$reg),
12671 as_Register($src$$reg), lshift, width);
12672 %}
12673 ins_pipe(ialu_reg_shift);
12674 %}
12675
12676
12677 // This pattern is automatically generated from aarch64_ad.m4
12678 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12679
12680 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
12681 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
12682 %{
12683 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift));
12684 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
12685
12686 ins_cost(INSN_COST);
12687 format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12688 ins_encode %{
12689 int lshift = $lshift$$constant & 63;
12690 intptr_t mask = $mask$$constant;
12691 int width = exact_log2(mask+1);
12692 __ ubfiz(as_Register($dst$$reg),
12693 as_Register($src$$reg), lshift, width);
12694 %}
12695 ins_pipe(ialu_reg_shift);
12696 %}
12697
12698 // This pattern is automatically generated from aarch64_ad.m4
12699 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12700
12701 // If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz
12702 instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
12703 %{
12704 match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift));
12705 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31);
12706
12707 ins_cost(INSN_COST);
12708 format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12709 ins_encode %{
12710 int lshift = $lshift$$constant & 31;
12711 intptr_t mask = $mask$$constant;
12712 int width = exact_log2(mask+1);
12713 __ ubfiz(as_Register($dst$$reg),
12714 as_Register($src$$reg), lshift, width);
12715 %}
12716 ins_pipe(ialu_reg_shift);
12717 %}
12718
12719 // This pattern is automatically generated from aarch64_ad.m4
12720 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12721
12722 // Can skip int2long conversions after AND with small bitmask
12723 instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk)
12724 %{
12725 match(Set dst (ConvI2L (AndI src msk)));
12726 ins_cost(INSN_COST);
12727 format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %}
12728 ins_encode %{
12729 __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1));
12730 %}
12731 ins_pipe(ialu_reg_shift);
12732 %}
12733
12734
12735 // Rotations
12736
12737 // This pattern is automatically generated from aarch64_ad.m4
12738 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12739 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
12740 %{
12741 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift)));
12742 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
12743
12744 ins_cost(INSN_COST);
12745 format %{ "extr $dst, $src1, $src2, #$rshift" %}
12746
12747 ins_encode %{
12748 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12749 $rshift$$constant & 63);
12750 %}
12751 ins_pipe(ialu_reg_reg_extr);
12752 %}
12753
12754
12755 // This pattern is automatically generated from aarch64_ad.m4
12756 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12757 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
12758 %{
12759 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift)));
12760 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
12761
12762 ins_cost(INSN_COST);
12763 format %{ "extr $dst, $src1, $src2, #$rshift" %}
12764
12765 ins_encode %{
12766 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12767 $rshift$$constant & 31);
12768 %}
12769 ins_pipe(ialu_reg_reg_extr);
12770 %}
12771
12772
12773 // This pattern is automatically generated from aarch64_ad.m4
12774 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12775 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
12776 %{
12777 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift)));
12778 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
12779
12780 ins_cost(INSN_COST);
12781 format %{ "extr $dst, $src1, $src2, #$rshift" %}
12782
12783 ins_encode %{
12784 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12785 $rshift$$constant & 63);
12786 %}
12787 ins_pipe(ialu_reg_reg_extr);
12788 %}
12789
12790
12791 // This pattern is automatically generated from aarch64_ad.m4
12792 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12793 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
12794 %{
12795 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift)));
12796 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
12797
12798 ins_cost(INSN_COST);
12799 format %{ "extr $dst, $src1, $src2, #$rshift" %}
12800
12801 ins_encode %{
12802 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12803 $rshift$$constant & 31);
12804 %}
12805 ins_pipe(ialu_reg_reg_extr);
12806 %}
12807
12808 // This pattern is automatically generated from aarch64_ad.m4
12809 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12810 instruct rorI_imm(iRegINoSp dst, iRegI src, immI shift)
12811 %{
12812 match(Set dst (RotateRight src shift));
12813
12814 ins_cost(INSN_COST);
12815 format %{ "ror $dst, $src, $shift" %}
12816
12817 ins_encode %{
12818 __ extrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg),
12819 $shift$$constant & 0x1f);
12820 %}
12821 ins_pipe(ialu_reg_reg_vshift);
12822 %}
12823
12824 // This pattern is automatically generated from aarch64_ad.m4
12825 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12826 instruct rorL_imm(iRegLNoSp dst, iRegL src, immI shift)
12827 %{
12828 match(Set dst (RotateRight src shift));
12829
12830 ins_cost(INSN_COST);
12831 format %{ "ror $dst, $src, $shift" %}
12832
12833 ins_encode %{
12834 __ extr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg),
12835 $shift$$constant & 0x3f);
12836 %}
12837 ins_pipe(ialu_reg_reg_vshift);
12838 %}
12839
12840 // This pattern is automatically generated from aarch64_ad.m4
12841 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12842 instruct rorI_reg(iRegINoSp dst, iRegI src, iRegI shift)
12843 %{
12844 match(Set dst (RotateRight src shift));
12845
12846 ins_cost(INSN_COST);
12847 format %{ "ror $dst, $src, $shift" %}
12848
12849 ins_encode %{
12850 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg));
12851 %}
12852 ins_pipe(ialu_reg_reg_vshift);
12853 %}
12854
12855 // This pattern is automatically generated from aarch64_ad.m4
12856 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12857 instruct rorL_reg(iRegLNoSp dst, iRegL src, iRegI shift)
12858 %{
12859 match(Set dst (RotateRight src shift));
12860
12861 ins_cost(INSN_COST);
12862 format %{ "ror $dst, $src, $shift" %}
12863
12864 ins_encode %{
12865 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg));
12866 %}
12867 ins_pipe(ialu_reg_reg_vshift);
12868 %}
12869
12870 // This pattern is automatically generated from aarch64_ad.m4
12871 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12872 instruct rolI_reg(iRegINoSp dst, iRegI src, iRegI shift)
12873 %{
12874 match(Set dst (RotateLeft src shift));
12875
12876 ins_cost(INSN_COST);
12877 format %{ "rol $dst, $src, $shift" %}
12878
12879 ins_encode %{
12880 __ subw(rscratch1, zr, as_Register($shift$$reg));
12881 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), rscratch1);
12882 %}
12883 ins_pipe(ialu_reg_reg_vshift);
12884 %}
12885
12886 // This pattern is automatically generated from aarch64_ad.m4
12887 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12888 instruct rolL_reg(iRegLNoSp dst, iRegL src, iRegI shift)
12889 %{
12890 match(Set dst (RotateLeft src shift));
12891
12892 ins_cost(INSN_COST);
12893 format %{ "rol $dst, $src, $shift" %}
12894
12895 ins_encode %{
12896 __ subw(rscratch1, zr, as_Register($shift$$reg));
12897 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), rscratch1);
12898 %}
12899 ins_pipe(ialu_reg_reg_vshift);
12900 %}
12901
12902
12903 // Add/subtract (extended)
12904
12905 // This pattern is automatically generated from aarch64_ad.m4
12906 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12907 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
12908 %{
12909 match(Set dst (AddL src1 (ConvI2L src2)));
12910 ins_cost(INSN_COST);
12911 format %{ "add $dst, $src1, $src2, sxtw" %}
12912
12913 ins_encode %{
12914 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12915 as_Register($src2$$reg), ext::sxtw);
12916 %}
12917 ins_pipe(ialu_reg_reg);
12918 %}
12919
12920 // This pattern is automatically generated from aarch64_ad.m4
12921 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12922 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
12923 %{
12924 match(Set dst (SubL src1 (ConvI2L src2)));
12925 ins_cost(INSN_COST);
12926 format %{ "sub $dst, $src1, $src2, sxtw" %}
12927
12928 ins_encode %{
12929 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
12930 as_Register($src2$$reg), ext::sxtw);
12931 %}
12932 ins_pipe(ialu_reg_reg);
12933 %}
12934
12935 // This pattern is automatically generated from aarch64_ad.m4
12936 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12937 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr)
12938 %{
12939 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
12940 ins_cost(INSN_COST);
12941 format %{ "add $dst, $src1, $src2, sxth" %}
12942
12943 ins_encode %{
12944 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12945 as_Register($src2$$reg), ext::sxth);
12946 %}
12947 ins_pipe(ialu_reg_reg);
12948 %}
12949
12950 // This pattern is automatically generated from aarch64_ad.m4
12951 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12952 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
12953 %{
12954 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
12955 ins_cost(INSN_COST);
12956 format %{ "add $dst, $src1, $src2, sxtb" %}
12957
12958 ins_encode %{
12959 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12960 as_Register($src2$$reg), ext::sxtb);
12961 %}
12962 ins_pipe(ialu_reg_reg);
12963 %}
12964
12965 // This pattern is automatically generated from aarch64_ad.m4
12966 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12967 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
12968 %{
12969 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift)));
12970 ins_cost(INSN_COST);
12971 format %{ "add $dst, $src1, $src2, uxtb" %}
12972
12973 ins_encode %{
12974 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12975 as_Register($src2$$reg), ext::uxtb);
12976 %}
12977 ins_pipe(ialu_reg_reg);
12978 %}
12979
12980 // This pattern is automatically generated from aarch64_ad.m4
12981 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12982 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr)
12983 %{
12984 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
12985 ins_cost(INSN_COST);
12986 format %{ "add $dst, $src1, $src2, sxth" %}
12987
12988 ins_encode %{
12989 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
12990 as_Register($src2$$reg), ext::sxth);
12991 %}
12992 ins_pipe(ialu_reg_reg);
12993 %}
12994
12995 // This pattern is automatically generated from aarch64_ad.m4
12996 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12997 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr)
12998 %{
12999 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
13000 ins_cost(INSN_COST);
13001 format %{ "add $dst, $src1, $src2, sxtw" %}
13002
13003 ins_encode %{
13004 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13005 as_Register($src2$$reg), ext::sxtw);
13006 %}
13007 ins_pipe(ialu_reg_reg);
13008 %}
13009
13010 // This pattern is automatically generated from aarch64_ad.m4
13011 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13012 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
13013 %{
13014 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
13015 ins_cost(INSN_COST);
13016 format %{ "add $dst, $src1, $src2, sxtb" %}
13017
13018 ins_encode %{
13019 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13020 as_Register($src2$$reg), ext::sxtb);
13021 %}
13022 ins_pipe(ialu_reg_reg);
13023 %}
13024
13025 // This pattern is automatically generated from aarch64_ad.m4
13026 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13027 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
13028 %{
13029 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift)));
13030 ins_cost(INSN_COST);
13031 format %{ "add $dst, $src1, $src2, uxtb" %}
13032
13033 ins_encode %{
13034 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13035 as_Register($src2$$reg), ext::uxtb);
13036 %}
13037 ins_pipe(ialu_reg_reg);
13038 %}
13039
13040 // This pattern is automatically generated from aarch64_ad.m4
13041 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13042 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
13043 %{
13044 match(Set dst (AddI src1 (AndI src2 mask)));
13045 ins_cost(INSN_COST);
13046 format %{ "addw $dst, $src1, $src2, uxtb" %}
13047
13048 ins_encode %{
13049 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13050 as_Register($src2$$reg), ext::uxtb);
13051 %}
13052 ins_pipe(ialu_reg_reg);
13053 %}
13054
13055 // This pattern is automatically generated from aarch64_ad.m4
13056 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13057 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
13058 %{
13059 match(Set dst (AddI src1 (AndI src2 mask)));
13060 ins_cost(INSN_COST);
13061 format %{ "addw $dst, $src1, $src2, uxth" %}
13062
13063 ins_encode %{
13064 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13065 as_Register($src2$$reg), ext::uxth);
13066 %}
13067 ins_pipe(ialu_reg_reg);
13068 %}
13069
13070 // This pattern is automatically generated from aarch64_ad.m4
13071 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13072 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
13073 %{
13074 match(Set dst (AddL src1 (AndL src2 mask)));
13075 ins_cost(INSN_COST);
13076 format %{ "add $dst, $src1, $src2, uxtb" %}
13077
13078 ins_encode %{
13079 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13080 as_Register($src2$$reg), ext::uxtb);
13081 %}
13082 ins_pipe(ialu_reg_reg);
13083 %}
13084
13085 // This pattern is automatically generated from aarch64_ad.m4
13086 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13087 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
13088 %{
13089 match(Set dst (AddL src1 (AndL src2 mask)));
13090 ins_cost(INSN_COST);
13091 format %{ "add $dst, $src1, $src2, uxth" %}
13092
13093 ins_encode %{
13094 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13095 as_Register($src2$$reg), ext::uxth);
13096 %}
13097 ins_pipe(ialu_reg_reg);
13098 %}
13099
13100 // This pattern is automatically generated from aarch64_ad.m4
13101 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13102 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
13103 %{
13104 match(Set dst (AddL src1 (AndL src2 mask)));
13105 ins_cost(INSN_COST);
13106 format %{ "add $dst, $src1, $src2, uxtw" %}
13107
13108 ins_encode %{
13109 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13110 as_Register($src2$$reg), ext::uxtw);
13111 %}
13112 ins_pipe(ialu_reg_reg);
13113 %}
13114
13115 // This pattern is automatically generated from aarch64_ad.m4
13116 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13117 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
13118 %{
13119 match(Set dst (SubI src1 (AndI src2 mask)));
13120 ins_cost(INSN_COST);
13121 format %{ "subw $dst, $src1, $src2, uxtb" %}
13122
13123 ins_encode %{
13124 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13125 as_Register($src2$$reg), ext::uxtb);
13126 %}
13127 ins_pipe(ialu_reg_reg);
13128 %}
13129
13130 // This pattern is automatically generated from aarch64_ad.m4
13131 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13132 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
13133 %{
13134 match(Set dst (SubI src1 (AndI src2 mask)));
13135 ins_cost(INSN_COST);
13136 format %{ "subw $dst, $src1, $src2, uxth" %}
13137
13138 ins_encode %{
13139 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13140 as_Register($src2$$reg), ext::uxth);
13141 %}
13142 ins_pipe(ialu_reg_reg);
13143 %}
13144
13145 // This pattern is automatically generated from aarch64_ad.m4
13146 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13147 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
13148 %{
13149 match(Set dst (SubL src1 (AndL src2 mask)));
13150 ins_cost(INSN_COST);
13151 format %{ "sub $dst, $src1, $src2, uxtb" %}
13152
13153 ins_encode %{
13154 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13155 as_Register($src2$$reg), ext::uxtb);
13156 %}
13157 ins_pipe(ialu_reg_reg);
13158 %}
13159
13160 // This pattern is automatically generated from aarch64_ad.m4
13161 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13162 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
13163 %{
13164 match(Set dst (SubL src1 (AndL src2 mask)));
13165 ins_cost(INSN_COST);
13166 format %{ "sub $dst, $src1, $src2, uxth" %}
13167
13168 ins_encode %{
13169 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13170 as_Register($src2$$reg), ext::uxth);
13171 %}
13172 ins_pipe(ialu_reg_reg);
13173 %}
13174
13175 // This pattern is automatically generated from aarch64_ad.m4
13176 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13177 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
13178 %{
13179 match(Set dst (SubL src1 (AndL src2 mask)));
13180 ins_cost(INSN_COST);
13181 format %{ "sub $dst, $src1, $src2, uxtw" %}
13182
13183 ins_encode %{
13184 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13185 as_Register($src2$$reg), ext::uxtw);
13186 %}
13187 ins_pipe(ialu_reg_reg);
13188 %}
13189
13190
13191 // This pattern is automatically generated from aarch64_ad.m4
13192 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13193 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
13194 %{
13195 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13196 ins_cost(1.9 * INSN_COST);
13197 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %}
13198
13199 ins_encode %{
13200 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13201 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13202 %}
13203 ins_pipe(ialu_reg_reg_shift);
13204 %}
13205
13206 // This pattern is automatically generated from aarch64_ad.m4
13207 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13208 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
13209 %{
13210 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13211 ins_cost(1.9 * INSN_COST);
13212 format %{ "add $dst, $src1, $src2, sxth #lshift2" %}
13213
13214 ins_encode %{
13215 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13216 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13217 %}
13218 ins_pipe(ialu_reg_reg_shift);
13219 %}
13220
13221 // This pattern is automatically generated from aarch64_ad.m4
13222 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13223 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
13224 %{
13225 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13226 ins_cost(1.9 * INSN_COST);
13227 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %}
13228
13229 ins_encode %{
13230 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13231 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
13232 %}
13233 ins_pipe(ialu_reg_reg_shift);
13234 %}
13235
13236 // This pattern is automatically generated from aarch64_ad.m4
13237 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13238 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
13239 %{
13240 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13241 ins_cost(1.9 * INSN_COST);
13242 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %}
13243
13244 ins_encode %{
13245 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13246 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13247 %}
13248 ins_pipe(ialu_reg_reg_shift);
13249 %}
13250
13251 // This pattern is automatically generated from aarch64_ad.m4
13252 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13253 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
13254 %{
13255 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13256 ins_cost(1.9 * INSN_COST);
13257 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %}
13258
13259 ins_encode %{
13260 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13261 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13262 %}
13263 ins_pipe(ialu_reg_reg_shift);
13264 %}
13265
13266 // This pattern is automatically generated from aarch64_ad.m4
13267 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13268 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
13269 %{
13270 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13271 ins_cost(1.9 * INSN_COST);
13272 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %}
13273
13274 ins_encode %{
13275 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13276 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
13277 %}
13278 ins_pipe(ialu_reg_reg_shift);
13279 %}
13280
13281 // This pattern is automatically generated from aarch64_ad.m4
13282 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13283 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
13284 %{
13285 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13286 ins_cost(1.9 * INSN_COST);
13287 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %}
13288
13289 ins_encode %{
13290 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13291 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13292 %}
13293 ins_pipe(ialu_reg_reg_shift);
13294 %}
13295
13296 // This pattern is automatically generated from aarch64_ad.m4
13297 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13298 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
13299 %{
13300 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13301 ins_cost(1.9 * INSN_COST);
13302 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %}
13303
13304 ins_encode %{
13305 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13306 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13307 %}
13308 ins_pipe(ialu_reg_reg_shift);
13309 %}
13310
13311 // This pattern is automatically generated from aarch64_ad.m4
13312 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13313 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
13314 %{
13315 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13316 ins_cost(1.9 * INSN_COST);
13317 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %}
13318
13319 ins_encode %{
13320 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13321 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13322 %}
13323 ins_pipe(ialu_reg_reg_shift);
13324 %}
13325
13326 // This pattern is automatically generated from aarch64_ad.m4
13327 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13328 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
13329 %{
13330 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13331 ins_cost(1.9 * INSN_COST);
13332 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %}
13333
13334 ins_encode %{
13335 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13336 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13337 %}
13338 ins_pipe(ialu_reg_reg_shift);
13339 %}
13340
13341 // This pattern is automatically generated from aarch64_ad.m4
13342 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13343 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
13344 %{
13345 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift)));
13346 ins_cost(1.9 * INSN_COST);
13347 format %{ "add $dst, $src1, $src2, sxtw #lshift" %}
13348
13349 ins_encode %{
13350 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13351 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
13352 %}
13353 ins_pipe(ialu_reg_reg_shift);
13354 %}
13355
13356 // This pattern is automatically generated from aarch64_ad.m4
13357 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13358 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
13359 %{
13360 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift)));
13361 ins_cost(1.9 * INSN_COST);
13362 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %}
13363
13364 ins_encode %{
13365 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13366 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
13367 %}
13368 ins_pipe(ialu_reg_reg_shift);
13369 %}
13370
13371 // This pattern is automatically generated from aarch64_ad.m4
13372 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13373 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
13374 %{
13375 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
13376 ins_cost(1.9 * INSN_COST);
13377 format %{ "add $dst, $src1, $src2, uxtb #lshift" %}
13378
13379 ins_encode %{
13380 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13381 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13382 %}
13383 ins_pipe(ialu_reg_reg_shift);
13384 %}
13385
13386 // This pattern is automatically generated from aarch64_ad.m4
13387 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13388 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
13389 %{
13390 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
13391 ins_cost(1.9 * INSN_COST);
13392 format %{ "add $dst, $src1, $src2, uxth #lshift" %}
13393
13394 ins_encode %{
13395 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13396 as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13397 %}
13398 ins_pipe(ialu_reg_reg_shift);
13399 %}
13400
13401 // This pattern is automatically generated from aarch64_ad.m4
13402 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13403 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
13404 %{
13405 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
13406 ins_cost(1.9 * INSN_COST);
13407 format %{ "add $dst, $src1, $src2, uxtw #lshift" %}
13408
13409 ins_encode %{
13410 __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13411 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
13412 %}
13413 ins_pipe(ialu_reg_reg_shift);
13414 %}
13415
13416 // This pattern is automatically generated from aarch64_ad.m4
13417 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13418 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
13419 %{
13420 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
13421 ins_cost(1.9 * INSN_COST);
13422 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %}
13423
13424 ins_encode %{
13425 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13426 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13427 %}
13428 ins_pipe(ialu_reg_reg_shift);
13429 %}
13430
13431 // This pattern is automatically generated from aarch64_ad.m4
13432 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13433 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
13434 %{
13435 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
13436 ins_cost(1.9 * INSN_COST);
13437 format %{ "sub $dst, $src1, $src2, uxth #lshift" %}
13438
13439 ins_encode %{
13440 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13441 as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13442 %}
13443 ins_pipe(ialu_reg_reg_shift);
13444 %}
13445
13446 // This pattern is automatically generated from aarch64_ad.m4
13447 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13448 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
13449 %{
13450 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
13451 ins_cost(1.9 * INSN_COST);
13452 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %}
13453
13454 ins_encode %{
13455 __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13456 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
13457 %}
13458 ins_pipe(ialu_reg_reg_shift);
13459 %}
13460
13461 // This pattern is automatically generated from aarch64_ad.m4
13462 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13463 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
13464 %{
13465 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
13466 ins_cost(1.9 * INSN_COST);
13467 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %}
13468
13469 ins_encode %{
13470 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13471 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13472 %}
13473 ins_pipe(ialu_reg_reg_shift);
13474 %}
13475
13476 // This pattern is automatically generated from aarch64_ad.m4
13477 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13478 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
13479 %{
13480 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
13481 ins_cost(1.9 * INSN_COST);
13482 format %{ "addw $dst, $src1, $src2, uxth #lshift" %}
13483
13484 ins_encode %{
13485 __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13486 as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13487 %}
13488 ins_pipe(ialu_reg_reg_shift);
13489 %}
13490
13491 // This pattern is automatically generated from aarch64_ad.m4
13492 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13493 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
13494 %{
13495 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
13496 ins_cost(1.9 * INSN_COST);
13497 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %}
13498
13499 ins_encode %{
13500 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13501 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13502 %}
13503 ins_pipe(ialu_reg_reg_shift);
13504 %}
13505
13506 // This pattern is automatically generated from aarch64_ad.m4
13507 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13508 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
13509 %{
13510 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
13511 ins_cost(1.9 * INSN_COST);
13512 format %{ "subw $dst, $src1, $src2, uxth #lshift" %}
13513
13514 ins_encode %{
13515 __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13516 as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13517 %}
13518 ins_pipe(ialu_reg_reg_shift);
13519 %}
13520
13521 // This pattern is automatically generated from aarch64_ad.m4
13522 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13523 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
13524 %{
13525 effect(DEF dst, USE src1, USE src2, USE cr);
13526 ins_cost(INSN_COST * 2);
13527 format %{ "cselw $dst, $src1, $src2 lt\t" %}
13528
13529 ins_encode %{
13530 __ cselw($dst$$Register,
13531 $src1$$Register,
13532 $src2$$Register,
13533 Assembler::LT);
13534 %}
13535 ins_pipe(icond_reg_reg);
13536 %}
13537
13538 // This pattern is automatically generated from aarch64_ad.m4
13539 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13540 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
13541 %{
13542 effect(DEF dst, USE src1, USE src2, USE cr);
13543 ins_cost(INSN_COST * 2);
13544 format %{ "cselw $dst, $src1, $src2 gt\t" %}
13545
13546 ins_encode %{
13547 __ cselw($dst$$Register,
13548 $src1$$Register,
13549 $src2$$Register,
13550 Assembler::GT);
13551 %}
13552 ins_pipe(icond_reg_reg);
13553 %}
13554
13555 // This pattern is automatically generated from aarch64_ad.m4
13556 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13557 instruct cmovI_reg_imm0_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13558 %{
13559 effect(DEF dst, USE src1, USE cr);
13560 ins_cost(INSN_COST * 2);
13561 format %{ "cselw $dst, $src1, zr lt\t" %}
13562
13563 ins_encode %{
13564 __ cselw($dst$$Register,
13565 $src1$$Register,
13566 zr,
13567 Assembler::LT);
13568 %}
13569 ins_pipe(icond_reg);
13570 %}
13571
13572 // This pattern is automatically generated from aarch64_ad.m4
13573 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13574 instruct cmovI_reg_imm0_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13575 %{
13576 effect(DEF dst, USE src1, USE cr);
13577 ins_cost(INSN_COST * 2);
13578 format %{ "cselw $dst, $src1, zr gt\t" %}
13579
13580 ins_encode %{
13581 __ cselw($dst$$Register,
13582 $src1$$Register,
13583 zr,
13584 Assembler::GT);
13585 %}
13586 ins_pipe(icond_reg);
13587 %}
13588
13589 // This pattern is automatically generated from aarch64_ad.m4
13590 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13591 instruct cmovI_reg_imm1_le(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13592 %{
13593 effect(DEF dst, USE src1, USE cr);
13594 ins_cost(INSN_COST * 2);
13595 format %{ "csincw $dst, $src1, zr le\t" %}
13596
13597 ins_encode %{
13598 __ csincw($dst$$Register,
13599 $src1$$Register,
13600 zr,
13601 Assembler::LE);
13602 %}
13603 ins_pipe(icond_reg);
13604 %}
13605
13606 // This pattern is automatically generated from aarch64_ad.m4
13607 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13608 instruct cmovI_reg_imm1_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13609 %{
13610 effect(DEF dst, USE src1, USE cr);
13611 ins_cost(INSN_COST * 2);
13612 format %{ "csincw $dst, $src1, zr gt\t" %}
13613
13614 ins_encode %{
13615 __ csincw($dst$$Register,
13616 $src1$$Register,
13617 zr,
13618 Assembler::GT);
13619 %}
13620 ins_pipe(icond_reg);
13621 %}
13622
13623 // This pattern is automatically generated from aarch64_ad.m4
13624 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13625 instruct cmovI_reg_immM1_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13626 %{
13627 effect(DEF dst, USE src1, USE cr);
13628 ins_cost(INSN_COST * 2);
13629 format %{ "csinvw $dst, $src1, zr lt\t" %}
13630
13631 ins_encode %{
13632 __ csinvw($dst$$Register,
13633 $src1$$Register,
13634 zr,
13635 Assembler::LT);
13636 %}
13637 ins_pipe(icond_reg);
13638 %}
13639
13640 // This pattern is automatically generated from aarch64_ad.m4
13641 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13642 instruct cmovI_reg_immM1_ge(iRegINoSp dst, iRegI src1, rFlagsReg cr)
13643 %{
13644 effect(DEF dst, USE src1, USE cr);
13645 ins_cost(INSN_COST * 2);
13646 format %{ "csinvw $dst, $src1, zr ge\t" %}
13647
13648 ins_encode %{
13649 __ csinvw($dst$$Register,
13650 $src1$$Register,
13651 zr,
13652 Assembler::GE);
13653 %}
13654 ins_pipe(icond_reg);
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_imm0(iRegINoSp dst, iRegIorL2I src, immI0 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_imm0_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_imm0_reg(iRegINoSp dst, immI0 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_imm0_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 minI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm)
13686 %{
13687 match(Set dst (MinI src imm));
13688 ins_cost(INSN_COST * 3);
13689 expand %{
13690 rFlagsReg cr;
13691 compI_reg_imm0(cr, src);
13692 cmovI_reg_imm1_le(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 minI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src)
13699 %{
13700 match(Set dst (MinI imm src));
13701 ins_cost(INSN_COST * 3);
13702 expand %{
13703 rFlagsReg cr;
13704 compI_reg_imm0(cr, src);
13705 cmovI_reg_imm1_le(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 minI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm)
13712 %{
13713 match(Set dst (MinI src imm));
13714 ins_cost(INSN_COST * 3);
13715 expand %{
13716 rFlagsReg cr;
13717 compI_reg_imm0(cr, src);
13718 cmovI_reg_immM1_lt(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 minI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src)
13725 %{
13726 match(Set dst (MinI imm src));
13727 ins_cost(INSN_COST * 3);
13728 expand %{
13729 rFlagsReg cr;
13730 compI_reg_imm0(cr, src);
13731 cmovI_reg_immM1_lt(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_imm0(iRegINoSp dst, iRegIorL2I src, immI0 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_imm0_gt(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_imm0_reg(iRegINoSp dst, immI0 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_imm0_gt(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 maxI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm)
13764 %{
13765 match(Set dst (MaxI src imm));
13766 ins_cost(INSN_COST * 3);
13767 expand %{
13768 rFlagsReg cr;
13769 compI_reg_imm0(cr, src);
13770 cmovI_reg_imm1_gt(dst, src, cr);
13771 %}
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 maxI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src)
13777 %{
13778 match(Set dst (MaxI imm src));
13779 ins_cost(INSN_COST * 3);
13780 expand %{
13781 rFlagsReg cr;
13782 compI_reg_imm0(cr, src);
13783 cmovI_reg_imm1_gt(dst, src, cr);
13784 %}
13785 %}
13786
13787 // This pattern is automatically generated from aarch64_ad.m4
13788 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13789 instruct maxI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm)
13790 %{
13791 match(Set dst (MaxI src imm));
13792 ins_cost(INSN_COST * 3);
13793 expand %{
13794 rFlagsReg cr;
13795 compI_reg_imm0(cr, src);
13796 cmovI_reg_immM1_ge(dst, src, cr);
13797 %}
13798 %}
13799
13800 // This pattern is automatically generated from aarch64_ad.m4
13801 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13802 instruct maxI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src)
13803 %{
13804 match(Set dst (MaxI imm src));
13805 ins_cost(INSN_COST * 3);
13806 expand %{
13807 rFlagsReg cr;
13808 compI_reg_imm0(cr, src);
13809 cmovI_reg_immM1_ge(dst, src, cr);
13810 %}
13811 %}
13812
13813 // This pattern is automatically generated from aarch64_ad.m4
13814 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13815 instruct bits_reverse_I(iRegINoSp dst, iRegIorL2I src)
13816 %{
13817 match(Set dst (ReverseI src));
13818 ins_cost(INSN_COST);
13819 format %{ "rbitw $dst, $src" %}
13820 ins_encode %{
13821 __ rbitw($dst$$Register, $src$$Register);
13822 %}
13823 ins_pipe(ialu_reg);
13824 %}
13825
13826 // This pattern is automatically generated from aarch64_ad.m4
13827 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13828 instruct bits_reverse_L(iRegLNoSp dst, iRegL src)
13829 %{
13830 match(Set dst (ReverseL src));
13831 ins_cost(INSN_COST);
13832 format %{ "rbit $dst, $src" %}
13833 ins_encode %{
13834 __ rbit($dst$$Register, $src$$Register);
13835 %}
13836 ins_pipe(ialu_reg);
13837 %}
13838
13839
13840 // END This section of the file is automatically generated. Do not edit --------------
13841
13842
13843 // ============================================================================
13844 // Floating Point Arithmetic Instructions
13845
13846 instruct addHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13847 match(Set dst (AddHF src1 src2));
13848 format %{ "faddh $dst, $src1, $src2" %}
13849 ins_encode %{
13850 __ faddh($dst$$FloatRegister,
13851 $src1$$FloatRegister,
13852 $src2$$FloatRegister);
13853 %}
13854 ins_pipe(fp_dop_reg_reg_s);
13855 %}
13856
13857 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13858 match(Set dst (AddF src1 src2));
13859
13860 ins_cost(INSN_COST * 5);
13861 format %{ "fadds $dst, $src1, $src2" %}
13862
13863 ins_encode %{
13864 __ fadds(as_FloatRegister($dst$$reg),
13865 as_FloatRegister($src1$$reg),
13866 as_FloatRegister($src2$$reg));
13867 %}
13868
13869 ins_pipe(fp_dop_reg_reg_s);
13870 %}
13871
13872 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
13873 match(Set dst (AddD src1 src2));
13874
13875 ins_cost(INSN_COST * 5);
13876 format %{ "faddd $dst, $src1, $src2" %}
13877
13878 ins_encode %{
13879 __ faddd(as_FloatRegister($dst$$reg),
13880 as_FloatRegister($src1$$reg),
13881 as_FloatRegister($src2$$reg));
13882 %}
13883
13884 ins_pipe(fp_dop_reg_reg_d);
13885 %}
13886
13887 instruct subHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13888 match(Set dst (SubHF src1 src2));
13889 format %{ "fsubh $dst, $src1, $src2" %}
13890 ins_encode %{
13891 __ fsubh($dst$$FloatRegister,
13892 $src1$$FloatRegister,
13893 $src2$$FloatRegister);
13894 %}
13895 ins_pipe(fp_dop_reg_reg_s);
13896 %}
13897
13898 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13899 match(Set dst (SubF src1 src2));
13900
13901 ins_cost(INSN_COST * 5);
13902 format %{ "fsubs $dst, $src1, $src2" %}
13903
13904 ins_encode %{
13905 __ fsubs(as_FloatRegister($dst$$reg),
13906 as_FloatRegister($src1$$reg),
13907 as_FloatRegister($src2$$reg));
13908 %}
13909
13910 ins_pipe(fp_dop_reg_reg_s);
13911 %}
13912
13913 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
13914 match(Set dst (SubD src1 src2));
13915
13916 ins_cost(INSN_COST * 5);
13917 format %{ "fsubd $dst, $src1, $src2" %}
13918
13919 ins_encode %{
13920 __ fsubd(as_FloatRegister($dst$$reg),
13921 as_FloatRegister($src1$$reg),
13922 as_FloatRegister($src2$$reg));
13923 %}
13924
13925 ins_pipe(fp_dop_reg_reg_d);
13926 %}
13927
13928 instruct mulHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13929 match(Set dst (MulHF src1 src2));
13930 format %{ "fmulh $dst, $src1, $src2" %}
13931 ins_encode %{
13932 __ fmulh($dst$$FloatRegister,
13933 $src1$$FloatRegister,
13934 $src2$$FloatRegister);
13935 %}
13936 ins_pipe(fp_dop_reg_reg_s);
13937 %}
13938
13939 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13940 match(Set dst (MulF src1 src2));
13941
13942 ins_cost(INSN_COST * 6);
13943 format %{ "fmuls $dst, $src1, $src2" %}
13944
13945 ins_encode %{
13946 __ fmuls(as_FloatRegister($dst$$reg),
13947 as_FloatRegister($src1$$reg),
13948 as_FloatRegister($src2$$reg));
13949 %}
13950
13951 ins_pipe(fp_dop_reg_reg_s);
13952 %}
13953
13954 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
13955 match(Set dst (MulD src1 src2));
13956
13957 ins_cost(INSN_COST * 6);
13958 format %{ "fmuld $dst, $src1, $src2" %}
13959
13960 ins_encode %{
13961 __ fmuld(as_FloatRegister($dst$$reg),
13962 as_FloatRegister($src1$$reg),
13963 as_FloatRegister($src2$$reg));
13964 %}
13965
13966 ins_pipe(fp_dop_reg_reg_d);
13967 %}
13968
13969 // src1 * src2 + src3 (half-precision float)
13970 instruct maddHF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
13971 match(Set dst (FmaHF src3 (Binary src1 src2)));
13972 format %{ "fmaddh $dst, $src1, $src2, $src3" %}
13973 ins_encode %{
13974 assert(UseFMA, "Needs FMA instructions support.");
13975 __ fmaddh($dst$$FloatRegister,
13976 $src1$$FloatRegister,
13977 $src2$$FloatRegister,
13978 $src3$$FloatRegister);
13979 %}
13980 ins_pipe(pipe_class_default);
13981 %}
13982
13983 // src1 * src2 + src3
13984 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
13985 match(Set dst (FmaF src3 (Binary src1 src2)));
13986
13987 format %{ "fmadds $dst, $src1, $src2, $src3" %}
13988
13989 ins_encode %{
13990 assert(UseFMA, "Needs FMA instructions support.");
13991 __ fmadds(as_FloatRegister($dst$$reg),
13992 as_FloatRegister($src1$$reg),
13993 as_FloatRegister($src2$$reg),
13994 as_FloatRegister($src3$$reg));
13995 %}
13996
13997 ins_pipe(pipe_class_default);
13998 %}
13999
14000 // src1 * src2 + src3
14001 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
14002 match(Set dst (FmaD src3 (Binary src1 src2)));
14003
14004 format %{ "fmaddd $dst, $src1, $src2, $src3" %}
14005
14006 ins_encode %{
14007 assert(UseFMA, "Needs FMA instructions support.");
14008 __ fmaddd(as_FloatRegister($dst$$reg),
14009 as_FloatRegister($src1$$reg),
14010 as_FloatRegister($src2$$reg),
14011 as_FloatRegister($src3$$reg));
14012 %}
14013
14014 ins_pipe(pipe_class_default);
14015 %}
14016
14017 // src1 * (-src2) + src3
14018 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
14019 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
14020 match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
14021
14022 format %{ "fmsubs $dst, $src1, $src2, $src3" %}
14023
14024 ins_encode %{
14025 assert(UseFMA, "Needs FMA instructions support.");
14026 __ fmsubs(as_FloatRegister($dst$$reg),
14027 as_FloatRegister($src1$$reg),
14028 as_FloatRegister($src2$$reg),
14029 as_FloatRegister($src3$$reg));
14030 %}
14031
14032 ins_pipe(pipe_class_default);
14033 %}
14034
14035 // src1 * (-src2) + src3
14036 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3"
14037 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
14038 match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
14039
14040 format %{ "fmsubd $dst, $src1, $src2, $src3" %}
14041
14042 ins_encode %{
14043 assert(UseFMA, "Needs FMA instructions support.");
14044 __ fmsubd(as_FloatRegister($dst$$reg),
14045 as_FloatRegister($src1$$reg),
14046 as_FloatRegister($src2$$reg),
14047 as_FloatRegister($src3$$reg));
14048 %}
14049
14050 ins_pipe(pipe_class_default);
14051 %}
14052
14053 // src1 * (-src2) - src3
14054 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
14055 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
14056 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
14057
14058 format %{ "fnmadds $dst, $src1, $src2, $src3" %}
14059
14060 ins_encode %{
14061 assert(UseFMA, "Needs FMA instructions support.");
14062 __ fnmadds(as_FloatRegister($dst$$reg),
14063 as_FloatRegister($src1$$reg),
14064 as_FloatRegister($src2$$reg),
14065 as_FloatRegister($src3$$reg));
14066 %}
14067
14068 ins_pipe(pipe_class_default);
14069 %}
14070
14071 // src1 * (-src2) - src3
14072 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3"
14073 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
14074 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
14075
14076 format %{ "fnmaddd $dst, $src1, $src2, $src3" %}
14077
14078 ins_encode %{
14079 assert(UseFMA, "Needs FMA instructions support.");
14080 __ fnmaddd(as_FloatRegister($dst$$reg),
14081 as_FloatRegister($src1$$reg),
14082 as_FloatRegister($src2$$reg),
14083 as_FloatRegister($src3$$reg));
14084 %}
14085
14086 ins_pipe(pipe_class_default);
14087 %}
14088
14089 // src1 * src2 - src3
14090 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{
14091 match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
14092
14093 format %{ "fnmsubs $dst, $src1, $src2, $src3" %}
14094
14095 ins_encode %{
14096 assert(UseFMA, "Needs FMA instructions support.");
14097 __ fnmsubs(as_FloatRegister($dst$$reg),
14098 as_FloatRegister($src1$$reg),
14099 as_FloatRegister($src2$$reg),
14100 as_FloatRegister($src3$$reg));
14101 %}
14102
14103 ins_pipe(pipe_class_default);
14104 %}
14105
14106 // src1 * src2 - src3
14107 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{
14108 match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
14109
14110 format %{ "fnmsubd $dst, $src1, $src2, $src3" %}
14111
14112 ins_encode %{
14113 assert(UseFMA, "Needs FMA instructions support.");
14114 // n.b. insn name should be fnmsubd
14115 __ fnmsub(as_FloatRegister($dst$$reg),
14116 as_FloatRegister($src1$$reg),
14117 as_FloatRegister($src2$$reg),
14118 as_FloatRegister($src3$$reg));
14119 %}
14120
14121 ins_pipe(pipe_class_default);
14122 %}
14123
14124 // Math.max(HH)H (half-precision float)
14125 instruct maxHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14126 match(Set dst (MaxHF src1 src2));
14127 format %{ "fmaxh $dst, $src1, $src2" %}
14128 ins_encode %{
14129 __ fmaxh($dst$$FloatRegister,
14130 $src1$$FloatRegister,
14131 $src2$$FloatRegister);
14132 %}
14133 ins_pipe(fp_dop_reg_reg_s);
14134 %}
14135
14136 // Math.min(HH)H (half-precision float)
14137 instruct minHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14138 match(Set dst (MinHF src1 src2));
14139 format %{ "fminh $dst, $src1, $src2" %}
14140 ins_encode %{
14141 __ fminh($dst$$FloatRegister,
14142 $src1$$FloatRegister,
14143 $src2$$FloatRegister);
14144 %}
14145 ins_pipe(fp_dop_reg_reg_s);
14146 %}
14147
14148 // Math.max(FF)F
14149 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14150 match(Set dst (MaxF src1 src2));
14151
14152 format %{ "fmaxs $dst, $src1, $src2" %}
14153 ins_encode %{
14154 __ fmaxs(as_FloatRegister($dst$$reg),
14155 as_FloatRegister($src1$$reg),
14156 as_FloatRegister($src2$$reg));
14157 %}
14158
14159 ins_pipe(fp_dop_reg_reg_s);
14160 %}
14161
14162 // Math.min(FF)F
14163 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14164 match(Set dst (MinF src1 src2));
14165
14166 format %{ "fmins $dst, $src1, $src2" %}
14167 ins_encode %{
14168 __ fmins(as_FloatRegister($dst$$reg),
14169 as_FloatRegister($src1$$reg),
14170 as_FloatRegister($src2$$reg));
14171 %}
14172
14173 ins_pipe(fp_dop_reg_reg_s);
14174 %}
14175
14176 // Math.max(DD)D
14177 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
14178 match(Set dst (MaxD src1 src2));
14179
14180 format %{ "fmaxd $dst, $src1, $src2" %}
14181 ins_encode %{
14182 __ fmaxd(as_FloatRegister($dst$$reg),
14183 as_FloatRegister($src1$$reg),
14184 as_FloatRegister($src2$$reg));
14185 %}
14186
14187 ins_pipe(fp_dop_reg_reg_d);
14188 %}
14189
14190 // Math.min(DD)D
14191 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
14192 match(Set dst (MinD src1 src2));
14193
14194 format %{ "fmind $dst, $src1, $src2" %}
14195 ins_encode %{
14196 __ fmind(as_FloatRegister($dst$$reg),
14197 as_FloatRegister($src1$$reg),
14198 as_FloatRegister($src2$$reg));
14199 %}
14200
14201 ins_pipe(fp_dop_reg_reg_d);
14202 %}
14203
14204 instruct divHF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14205 match(Set dst (DivHF src1 src2));
14206 format %{ "fdivh $dst, $src1, $src2" %}
14207 ins_encode %{
14208 __ fdivh($dst$$FloatRegister,
14209 $src1$$FloatRegister,
14210 $src2$$FloatRegister);
14211 %}
14212 ins_pipe(fp_div_s);
14213 %}
14214
14215 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14216 match(Set dst (DivF src1 src2));
14217
14218 ins_cost(INSN_COST * 18);
14219 format %{ "fdivs $dst, $src1, $src2" %}
14220
14221 ins_encode %{
14222 __ fdivs(as_FloatRegister($dst$$reg),
14223 as_FloatRegister($src1$$reg),
14224 as_FloatRegister($src2$$reg));
14225 %}
14226
14227 ins_pipe(fp_div_s);
14228 %}
14229
14230 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
14231 match(Set dst (DivD src1 src2));
14232
14233 ins_cost(INSN_COST * 32);
14234 format %{ "fdivd $dst, $src1, $src2" %}
14235
14236 ins_encode %{
14237 __ fdivd(as_FloatRegister($dst$$reg),
14238 as_FloatRegister($src1$$reg),
14239 as_FloatRegister($src2$$reg));
14240 %}
14241
14242 ins_pipe(fp_div_d);
14243 %}
14244
14245 instruct negF_reg_reg(vRegF dst, vRegF src) %{
14246 match(Set dst (NegF src));
14247
14248 ins_cost(INSN_COST * 3);
14249 format %{ "fneg $dst, $src" %}
14250
14251 ins_encode %{
14252 __ fnegs(as_FloatRegister($dst$$reg),
14253 as_FloatRegister($src$$reg));
14254 %}
14255
14256 ins_pipe(fp_uop_s);
14257 %}
14258
14259 instruct negD_reg_reg(vRegD dst, vRegD src) %{
14260 match(Set dst (NegD src));
14261
14262 ins_cost(INSN_COST * 3);
14263 format %{ "fnegd $dst, $src" %}
14264
14265 ins_encode %{
14266 __ fnegd(as_FloatRegister($dst$$reg),
14267 as_FloatRegister($src$$reg));
14268 %}
14269
14270 ins_pipe(fp_uop_d);
14271 %}
14272
14273 instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
14274 %{
14275 match(Set dst (AbsI src));
14276
14277 effect(KILL cr);
14278 ins_cost(INSN_COST * 2);
14279 format %{ "cmpw $src, zr\n\t"
14280 "cnegw $dst, $src, Assembler::LT\t# int abs"
14281 %}
14282
14283 ins_encode %{
14284 __ cmpw(as_Register($src$$reg), zr);
14285 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT);
14286 %}
14287 ins_pipe(pipe_class_default);
14288 %}
14289
14290 instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr)
14291 %{
14292 match(Set dst (AbsL src));
14293
14294 effect(KILL cr);
14295 ins_cost(INSN_COST * 2);
14296 format %{ "cmp $src, zr\n\t"
14297 "cneg $dst, $src, Assembler::LT\t# long abs"
14298 %}
14299
14300 ins_encode %{
14301 __ cmp(as_Register($src$$reg), zr);
14302 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT);
14303 %}
14304 ins_pipe(pipe_class_default);
14305 %}
14306
14307 instruct absF_reg(vRegF dst, vRegF src) %{
14308 match(Set dst (AbsF src));
14309
14310 ins_cost(INSN_COST * 3);
14311 format %{ "fabss $dst, $src" %}
14312 ins_encode %{
14313 __ fabss(as_FloatRegister($dst$$reg),
14314 as_FloatRegister($src$$reg));
14315 %}
14316
14317 ins_pipe(fp_uop_s);
14318 %}
14319
14320 instruct absD_reg(vRegD dst, vRegD src) %{
14321 match(Set dst (AbsD src));
14322
14323 ins_cost(INSN_COST * 3);
14324 format %{ "fabsd $dst, $src" %}
14325 ins_encode %{
14326 __ fabsd(as_FloatRegister($dst$$reg),
14327 as_FloatRegister($src$$reg));
14328 %}
14329
14330 ins_pipe(fp_uop_d);
14331 %}
14332
14333 instruct absdF_reg(vRegF dst, vRegF src1, vRegF src2) %{
14334 match(Set dst (AbsF (SubF src1 src2)));
14335
14336 ins_cost(INSN_COST * 3);
14337 format %{ "fabds $dst, $src1, $src2" %}
14338 ins_encode %{
14339 __ fabds(as_FloatRegister($dst$$reg),
14340 as_FloatRegister($src1$$reg),
14341 as_FloatRegister($src2$$reg));
14342 %}
14343
14344 ins_pipe(fp_uop_s);
14345 %}
14346
14347 instruct absdD_reg(vRegD dst, vRegD src1, vRegD src2) %{
14348 match(Set dst (AbsD (SubD src1 src2)));
14349
14350 ins_cost(INSN_COST * 3);
14351 format %{ "fabdd $dst, $src1, $src2" %}
14352 ins_encode %{
14353 __ fabdd(as_FloatRegister($dst$$reg),
14354 as_FloatRegister($src1$$reg),
14355 as_FloatRegister($src2$$reg));
14356 %}
14357
14358 ins_pipe(fp_uop_d);
14359 %}
14360
14361 instruct sqrtD_reg(vRegD dst, vRegD src) %{
14362 match(Set dst (SqrtD src));
14363
14364 ins_cost(INSN_COST * 50);
14365 format %{ "fsqrtd $dst, $src" %}
14366 ins_encode %{
14367 __ fsqrtd(as_FloatRegister($dst$$reg),
14368 as_FloatRegister($src$$reg));
14369 %}
14370
14371 ins_pipe(fp_div_s);
14372 %}
14373
14374 instruct sqrtF_reg(vRegF dst, vRegF src) %{
14375 match(Set dst (SqrtF src));
14376
14377 ins_cost(INSN_COST * 50);
14378 format %{ "fsqrts $dst, $src" %}
14379 ins_encode %{
14380 __ fsqrts(as_FloatRegister($dst$$reg),
14381 as_FloatRegister($src$$reg));
14382 %}
14383
14384 ins_pipe(fp_div_d);
14385 %}
14386
14387 instruct sqrtHF_reg(vRegF dst, vRegF src) %{
14388 match(Set dst (SqrtHF src));
14389 format %{ "fsqrth $dst, $src" %}
14390 ins_encode %{
14391 __ fsqrth($dst$$FloatRegister,
14392 $src$$FloatRegister);
14393 %}
14394 ins_pipe(fp_div_s);
14395 %}
14396
14397 // Math.rint, floor, ceil
14398 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{
14399 match(Set dst (RoundDoubleMode src rmode));
14400 format %{ "frint $dst, $src, $rmode" %}
14401 ins_encode %{
14402 switch ($rmode$$constant) {
14403 case RoundDoubleModeNode::rmode_rint:
14404 __ frintnd(as_FloatRegister($dst$$reg),
14405 as_FloatRegister($src$$reg));
14406 break;
14407 case RoundDoubleModeNode::rmode_floor:
14408 __ frintmd(as_FloatRegister($dst$$reg),
14409 as_FloatRegister($src$$reg));
14410 break;
14411 case RoundDoubleModeNode::rmode_ceil:
14412 __ frintpd(as_FloatRegister($dst$$reg),
14413 as_FloatRegister($src$$reg));
14414 break;
14415 }
14416 %}
14417 ins_pipe(fp_uop_d);
14418 %}
14419
14420 instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{
14421 match(Set dst (CopySignD src1 (Binary src2 zero)));
14422 effect(TEMP_DEF dst, USE src1, USE src2, USE zero);
14423 format %{ "CopySignD $dst $src1 $src2" %}
14424 ins_encode %{
14425 FloatRegister dst = as_FloatRegister($dst$$reg),
14426 src1 = as_FloatRegister($src1$$reg),
14427 src2 = as_FloatRegister($src2$$reg),
14428 zero = as_FloatRegister($zero$$reg);
14429 __ fnegd(dst, zero);
14430 __ bsl(dst, __ T8B, src2, src1);
14431 %}
14432 ins_pipe(fp_uop_d);
14433 %}
14434
14435 instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{
14436 match(Set dst (CopySignF src1 src2));
14437 effect(TEMP_DEF dst, USE src1, USE src2);
14438 format %{ "CopySignF $dst $src1 $src2" %}
14439 ins_encode %{
14440 FloatRegister dst = as_FloatRegister($dst$$reg),
14441 src1 = as_FloatRegister($src1$$reg),
14442 src2 = as_FloatRegister($src2$$reg);
14443 __ movi(dst, __ T2S, 0x80, 24);
14444 __ bsl(dst, __ T8B, src2, src1);
14445 %}
14446 ins_pipe(fp_uop_d);
14447 %}
14448
14449 instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{
14450 match(Set dst (SignumD src (Binary zero one)));
14451 effect(TEMP_DEF dst, USE src, USE zero, USE one);
14452 format %{ "signumD $dst, $src" %}
14453 ins_encode %{
14454 FloatRegister src = as_FloatRegister($src$$reg),
14455 dst = as_FloatRegister($dst$$reg),
14456 zero = as_FloatRegister($zero$$reg),
14457 one = as_FloatRegister($one$$reg);
14458 __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise
14459 __ ushrd(dst, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise
14460 // Bit selection instruction gets bit from "one" for each enabled bit in
14461 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or
14462 // NaN the whole "src" will be copied because "dst" is zero. For all other
14463 // "src" values dst is 0x7FF..F, which means only the sign bit is copied
14464 // from "src", and all other bits are copied from 1.0.
14465 __ bsl(dst, __ T8B, one, src);
14466 %}
14467 ins_pipe(fp_uop_d);
14468 %}
14469
14470 instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{
14471 match(Set dst (SignumF src (Binary zero one)));
14472 effect(TEMP_DEF dst, USE src, USE zero, USE one);
14473 format %{ "signumF $dst, $src" %}
14474 ins_encode %{
14475 FloatRegister src = as_FloatRegister($src$$reg),
14476 dst = as_FloatRegister($dst$$reg),
14477 zero = as_FloatRegister($zero$$reg),
14478 one = as_FloatRegister($one$$reg);
14479 __ facgts(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise
14480 __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise
14481 // Bit selection instruction gets bit from "one" for each enabled bit in
14482 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or
14483 // NaN the whole "src" will be copied because "dst" is zero. For all other
14484 // "src" values dst is 0x7FF..F, which means only the sign bit is copied
14485 // from "src", and all other bits are copied from 1.0.
14486 __ bsl(dst, __ T8B, one, src);
14487 %}
14488 ins_pipe(fp_uop_d);
14489 %}
14490
14491 instruct onspinwait() %{
14492 match(OnSpinWait);
14493 ins_cost(INSN_COST);
14494
14495 format %{ "onspinwait" %}
14496
14497 ins_encode %{
14498 __ spin_wait();
14499 %}
14500 ins_pipe(pipe_class_empty);
14501 %}
14502
14503 // ============================================================================
14504 // Logical Instructions
14505
14506 // Integer Logical Instructions
14507
14508 // And Instructions
14509
14510
14511 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{
14512 match(Set dst (AndI src1 src2));
14513
14514 format %{ "andw $dst, $src1, $src2\t# int" %}
14515
14516 ins_cost(INSN_COST);
14517 ins_encode %{
14518 __ andw(as_Register($dst$$reg),
14519 as_Register($src1$$reg),
14520 as_Register($src2$$reg));
14521 %}
14522
14523 ins_pipe(ialu_reg_reg);
14524 %}
14525
14526 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{
14527 match(Set dst (AndI src1 src2));
14528
14529 format %{ "andsw $dst, $src1, $src2\t# int" %}
14530
14531 ins_cost(INSN_COST);
14532 ins_encode %{
14533 __ andw(as_Register($dst$$reg),
14534 as_Register($src1$$reg),
14535 (uint64_t)($src2$$constant));
14536 %}
14537
14538 ins_pipe(ialu_reg_imm);
14539 %}
14540
14541 // Or Instructions
14542
14543 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
14544 match(Set dst (OrI src1 src2));
14545
14546 format %{ "orrw $dst, $src1, $src2\t# int" %}
14547
14548 ins_cost(INSN_COST);
14549 ins_encode %{
14550 __ orrw(as_Register($dst$$reg),
14551 as_Register($src1$$reg),
14552 as_Register($src2$$reg));
14553 %}
14554
14555 ins_pipe(ialu_reg_reg);
14556 %}
14557
14558 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
14559 match(Set dst (OrI src1 src2));
14560
14561 format %{ "orrw $dst, $src1, $src2\t# int" %}
14562
14563 ins_cost(INSN_COST);
14564 ins_encode %{
14565 __ orrw(as_Register($dst$$reg),
14566 as_Register($src1$$reg),
14567 (uint64_t)($src2$$constant));
14568 %}
14569
14570 ins_pipe(ialu_reg_imm);
14571 %}
14572
14573 // Xor Instructions
14574
14575 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
14576 match(Set dst (XorI src1 src2));
14577
14578 format %{ "eorw $dst, $src1, $src2\t# int" %}
14579
14580 ins_cost(INSN_COST);
14581 ins_encode %{
14582 __ eorw(as_Register($dst$$reg),
14583 as_Register($src1$$reg),
14584 as_Register($src2$$reg));
14585 %}
14586
14587 ins_pipe(ialu_reg_reg);
14588 %}
14589
14590 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
14591 match(Set dst (XorI src1 src2));
14592
14593 format %{ "eorw $dst, $src1, $src2\t# int" %}
14594
14595 ins_cost(INSN_COST);
14596 ins_encode %{
14597 __ eorw(as_Register($dst$$reg),
14598 as_Register($src1$$reg),
14599 (uint64_t)($src2$$constant));
14600 %}
14601
14602 ins_pipe(ialu_reg_imm);
14603 %}
14604
14605 // Long Logical Instructions
14606 // TODO
14607
14608 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{
14609 match(Set dst (AndL src1 src2));
14610
14611 format %{ "and $dst, $src1, $src2\t# int" %}
14612
14613 ins_cost(INSN_COST);
14614 ins_encode %{
14615 __ andr(as_Register($dst$$reg),
14616 as_Register($src1$$reg),
14617 as_Register($src2$$reg));
14618 %}
14619
14620 ins_pipe(ialu_reg_reg);
14621 %}
14622
14623 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{
14624 match(Set dst (AndL src1 src2));
14625
14626 format %{ "and $dst, $src1, $src2\t# int" %}
14627
14628 ins_cost(INSN_COST);
14629 ins_encode %{
14630 __ andr(as_Register($dst$$reg),
14631 as_Register($src1$$reg),
14632 (uint64_t)($src2$$constant));
14633 %}
14634
14635 ins_pipe(ialu_reg_imm);
14636 %}
14637
14638 // Or Instructions
14639
14640 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
14641 match(Set dst (OrL src1 src2));
14642
14643 format %{ "orr $dst, $src1, $src2\t# int" %}
14644
14645 ins_cost(INSN_COST);
14646 ins_encode %{
14647 __ orr(as_Register($dst$$reg),
14648 as_Register($src1$$reg),
14649 as_Register($src2$$reg));
14650 %}
14651
14652 ins_pipe(ialu_reg_reg);
14653 %}
14654
14655 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
14656 match(Set dst (OrL src1 src2));
14657
14658 format %{ "orr $dst, $src1, $src2\t# int" %}
14659
14660 ins_cost(INSN_COST);
14661 ins_encode %{
14662 __ orr(as_Register($dst$$reg),
14663 as_Register($src1$$reg),
14664 (uint64_t)($src2$$constant));
14665 %}
14666
14667 ins_pipe(ialu_reg_imm);
14668 %}
14669
14670 // Xor Instructions
14671
14672 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
14673 match(Set dst (XorL src1 src2));
14674
14675 format %{ "eor $dst, $src1, $src2\t# int" %}
14676
14677 ins_cost(INSN_COST);
14678 ins_encode %{
14679 __ eor(as_Register($dst$$reg),
14680 as_Register($src1$$reg),
14681 as_Register($src2$$reg));
14682 %}
14683
14684 ins_pipe(ialu_reg_reg);
14685 %}
14686
14687 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
14688 match(Set dst (XorL src1 src2));
14689
14690 ins_cost(INSN_COST);
14691 format %{ "eor $dst, $src1, $src2\t# int" %}
14692
14693 ins_encode %{
14694 __ eor(as_Register($dst$$reg),
14695 as_Register($src1$$reg),
14696 (uint64_t)($src2$$constant));
14697 %}
14698
14699 ins_pipe(ialu_reg_imm);
14700 %}
14701
14702 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
14703 %{
14704 match(Set dst (ConvI2L src));
14705
14706 ins_cost(INSN_COST);
14707 format %{ "sxtw $dst, $src\t# i2l" %}
14708 ins_encode %{
14709 __ sbfm($dst$$Register, $src$$Register, 0, 31);
14710 %}
14711 ins_pipe(ialu_reg_shift);
14712 %}
14713
14714 // this pattern occurs in bigmath arithmetic
14715 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask)
14716 %{
14717 match(Set dst (AndL (ConvI2L src) mask));
14718
14719 ins_cost(INSN_COST);
14720 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %}
14721 ins_encode %{
14722 __ ubfm($dst$$Register, $src$$Register, 0, 31);
14723 %}
14724
14725 ins_pipe(ialu_reg_shift);
14726 %}
14727
14728 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{
14729 match(Set dst (ConvL2I src));
14730
14731 ins_cost(INSN_COST);
14732 format %{ "movw $dst, $src \t// l2i" %}
14733
14734 ins_encode %{
14735 __ movw(as_Register($dst$$reg), as_Register($src$$reg));
14736 %}
14737
14738 ins_pipe(ialu_reg);
14739 %}
14740
14741 instruct convD2F_reg(vRegF dst, vRegD src) %{
14742 match(Set dst (ConvD2F src));
14743
14744 ins_cost(INSN_COST * 5);
14745 format %{ "fcvtd $dst, $src \t// d2f" %}
14746
14747 ins_encode %{
14748 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
14749 %}
14750
14751 ins_pipe(fp_d2f);
14752 %}
14753
14754 instruct convF2D_reg(vRegD dst, vRegF src) %{
14755 match(Set dst (ConvF2D src));
14756
14757 ins_cost(INSN_COST * 5);
14758 format %{ "fcvts $dst, $src \t// f2d" %}
14759
14760 ins_encode %{
14761 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
14762 %}
14763
14764 ins_pipe(fp_f2d);
14765 %}
14766
14767 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{
14768 match(Set dst (ConvF2I src));
14769
14770 ins_cost(INSN_COST * 5);
14771 format %{ "fcvtzsw $dst, $src \t// f2i" %}
14772
14773 ins_encode %{
14774 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14775 %}
14776
14777 ins_pipe(fp_f2i);
14778 %}
14779
14780 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{
14781 match(Set dst (ConvF2L src));
14782
14783 ins_cost(INSN_COST * 5);
14784 format %{ "fcvtzs $dst, $src \t// f2l" %}
14785
14786 ins_encode %{
14787 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14788 %}
14789
14790 ins_pipe(fp_f2l);
14791 %}
14792
14793 instruct convF2HF_reg_reg(iRegINoSp dst, vRegF src, vRegF tmp) %{
14794 match(Set dst (ConvF2HF src));
14795 format %{ "fcvt $tmp, $src\t# convert single to half precision\n\t"
14796 "smov $dst, $tmp\t# move result from $tmp to $dst"
14797 %}
14798 effect(TEMP tmp);
14799 ins_encode %{
14800 __ flt_to_flt16($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister);
14801 %}
14802 ins_pipe(pipe_slow);
14803 %}
14804
14805 instruct convHF2F_reg_reg(vRegF dst, iRegINoSp src, vRegF tmp) %{
14806 match(Set dst (ConvHF2F src));
14807 format %{ "mov $tmp, $src\t# move source from $src to $tmp\n\t"
14808 "fcvt $dst, $tmp\t# convert half to single precision"
14809 %}
14810 effect(TEMP tmp);
14811 ins_encode %{
14812 __ flt16_to_flt($dst$$FloatRegister, $src$$Register, $tmp$$FloatRegister);
14813 %}
14814 ins_pipe(pipe_slow);
14815 %}
14816
14817 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{
14818 match(Set dst (ConvI2F src));
14819
14820 ins_cost(INSN_COST * 5);
14821 format %{ "scvtfws $dst, $src \t// i2f" %}
14822
14823 ins_encode %{
14824 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14825 %}
14826
14827 ins_pipe(fp_i2f);
14828 %}
14829
14830 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{
14831 match(Set dst (ConvL2F src));
14832
14833 ins_cost(INSN_COST * 5);
14834 format %{ "scvtfs $dst, $src \t// l2f" %}
14835
14836 ins_encode %{
14837 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14838 %}
14839
14840 ins_pipe(fp_l2f);
14841 %}
14842
14843 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{
14844 match(Set dst (ConvD2I src));
14845
14846 ins_cost(INSN_COST * 5);
14847 format %{ "fcvtzdw $dst, $src \t// d2i" %}
14848
14849 ins_encode %{
14850 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14851 %}
14852
14853 ins_pipe(fp_d2i);
14854 %}
14855
14856 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
14857 match(Set dst (ConvD2L src));
14858
14859 ins_cost(INSN_COST * 5);
14860 format %{ "fcvtzd $dst, $src \t// d2l" %}
14861
14862 ins_encode %{
14863 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14864 %}
14865
14866 ins_pipe(fp_d2l);
14867 %}
14868
14869 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{
14870 match(Set dst (ConvI2D src));
14871
14872 ins_cost(INSN_COST * 5);
14873 format %{ "scvtfwd $dst, $src \t// i2d" %}
14874
14875 ins_encode %{
14876 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14877 %}
14878
14879 ins_pipe(fp_i2d);
14880 %}
14881
14882 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{
14883 match(Set dst (ConvL2D src));
14884
14885 ins_cost(INSN_COST * 5);
14886 format %{ "scvtfd $dst, $src \t// l2d" %}
14887
14888 ins_encode %{
14889 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14890 %}
14891
14892 ins_pipe(fp_l2d);
14893 %}
14894
14895 instruct round_double_reg(iRegLNoSp dst, vRegD src, vRegD ftmp, rFlagsReg cr)
14896 %{
14897 match(Set dst (RoundD src));
14898 effect(TEMP_DEF dst, TEMP ftmp, KILL cr);
14899 format %{ "java_round_double $dst,$src"%}
14900 ins_encode %{
14901 __ java_round_double($dst$$Register, as_FloatRegister($src$$reg),
14902 as_FloatRegister($ftmp$$reg));
14903 %}
14904 ins_pipe(pipe_slow);
14905 %}
14906
14907 instruct round_float_reg(iRegINoSp dst, vRegF src, vRegF ftmp, rFlagsReg cr)
14908 %{
14909 match(Set dst (RoundF src));
14910 effect(TEMP_DEF dst, TEMP ftmp, KILL cr);
14911 format %{ "java_round_float $dst,$src"%}
14912 ins_encode %{
14913 __ java_round_float($dst$$Register, as_FloatRegister($src$$reg),
14914 as_FloatRegister($ftmp$$reg));
14915 %}
14916 ins_pipe(pipe_slow);
14917 %}
14918
14919 // stack <-> reg and reg <-> reg shuffles with no conversion
14920
14921 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{
14922
14923 match(Set dst (MoveF2I src));
14924
14925 effect(DEF dst, USE src);
14926
14927 ins_cost(4 * INSN_COST);
14928
14929 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %}
14930
14931 ins_encode %{
14932 __ ldrw($dst$$Register, Address(sp, $src$$disp));
14933 %}
14934
14935 ins_pipe(iload_reg_reg);
14936
14937 %}
14938
14939 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{
14940
14941 match(Set dst (MoveI2F src));
14942
14943 effect(DEF dst, USE src);
14944
14945 ins_cost(4 * INSN_COST);
14946
14947 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %}
14948
14949 ins_encode %{
14950 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
14951 %}
14952
14953 ins_pipe(pipe_class_memory);
14954
14955 %}
14956
14957 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{
14958
14959 match(Set dst (MoveD2L src));
14960
14961 effect(DEF dst, USE src);
14962
14963 ins_cost(4 * INSN_COST);
14964
14965 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %}
14966
14967 ins_encode %{
14968 __ ldr($dst$$Register, Address(sp, $src$$disp));
14969 %}
14970
14971 ins_pipe(iload_reg_reg);
14972
14973 %}
14974
14975 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{
14976
14977 match(Set dst (MoveL2D src));
14978
14979 effect(DEF dst, USE src);
14980
14981 ins_cost(4 * INSN_COST);
14982
14983 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %}
14984
14985 ins_encode %{
14986 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
14987 %}
14988
14989 ins_pipe(pipe_class_memory);
14990
14991 %}
14992
14993 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{
14994
14995 match(Set dst (MoveF2I src));
14996
14997 effect(DEF dst, USE src);
14998
14999 ins_cost(INSN_COST);
15000
15001 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %}
15002
15003 ins_encode %{
15004 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
15005 %}
15006
15007 ins_pipe(pipe_class_memory);
15008
15009 %}
15010
15011 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
15012
15013 match(Set dst (MoveI2F src));
15014
15015 effect(DEF dst, USE src);
15016
15017 ins_cost(INSN_COST);
15018
15019 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %}
15020
15021 ins_encode %{
15022 __ strw($src$$Register, Address(sp, $dst$$disp));
15023 %}
15024
15025 ins_pipe(istore_reg_reg);
15026
15027 %}
15028
15029 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{
15030
15031 match(Set dst (MoveD2L src));
15032
15033 effect(DEF dst, USE src);
15034
15035 ins_cost(INSN_COST);
15036
15037 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %}
15038
15039 ins_encode %{
15040 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
15041 %}
15042
15043 ins_pipe(pipe_class_memory);
15044
15045 %}
15046
15047 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
15048
15049 match(Set dst (MoveL2D src));
15050
15051 effect(DEF dst, USE src);
15052
15053 ins_cost(INSN_COST);
15054
15055 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %}
15056
15057 ins_encode %{
15058 __ str($src$$Register, Address(sp, $dst$$disp));
15059 %}
15060
15061 ins_pipe(istore_reg_reg);
15062
15063 %}
15064
15065 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{
15066
15067 match(Set dst (MoveF2I src));
15068
15069 effect(DEF dst, USE src);
15070
15071 ins_cost(INSN_COST);
15072
15073 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %}
15074
15075 ins_encode %{
15076 __ fmovs($dst$$Register, as_FloatRegister($src$$reg));
15077 %}
15078
15079 ins_pipe(fp_f2i);
15080
15081 %}
15082
15083 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{
15084
15085 match(Set dst (MoveI2F src));
15086
15087 effect(DEF dst, USE src);
15088
15089 ins_cost(INSN_COST);
15090
15091 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %}
15092
15093 ins_encode %{
15094 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register);
15095 %}
15096
15097 ins_pipe(fp_i2f);
15098
15099 %}
15100
15101 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
15102
15103 match(Set dst (MoveD2L src));
15104
15105 effect(DEF dst, USE src);
15106
15107 ins_cost(INSN_COST);
15108
15109 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %}
15110
15111 ins_encode %{
15112 __ fmovd($dst$$Register, as_FloatRegister($src$$reg));
15113 %}
15114
15115 ins_pipe(fp_d2l);
15116
15117 %}
15118
15119 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{
15120
15121 match(Set dst (MoveL2D src));
15122
15123 effect(DEF dst, USE src);
15124
15125 ins_cost(INSN_COST);
15126
15127 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %}
15128
15129 ins_encode %{
15130 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register);
15131 %}
15132
15133 ins_pipe(fp_l2d);
15134
15135 %}
15136
15137 // ============================================================================
15138 // clearing of an array
15139
15140 instruct clearArray_reg_reg_immL0(iRegL_R11 cnt, iRegP_R10 base, immL0 zero, Universe dummy, rFlagsReg cr)
15141 %{
15142 match(Set dummy (ClearArray (Binary cnt base) zero));
15143 effect(USE_KILL cnt, USE_KILL base, KILL cr);
15144
15145 ins_cost(4 * INSN_COST);
15146 format %{ "ClearArray $cnt, $base" %}
15147
15148 ins_encode %{
15149 address tpc = __ zero_words($base$$Register, $cnt$$Register);
15150 if (tpc == nullptr) {
15151 ciEnv::current()->record_failure("CodeCache is full");
15152 return;
15153 }
15154 %}
15155
15156 ins_pipe(pipe_class_memory);
15157 %}
15158
15159 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, iRegL val, Universe dummy, rFlagsReg cr)
15160 %{
15161 predicate(((ClearArrayNode*)n)->word_copy_only());
15162 match(Set dummy (ClearArray (Binary cnt base) val));
15163 effect(USE_KILL cnt, USE_KILL base, KILL cr);
15164
15165 ins_cost(4 * INSN_COST);
15166 format %{ "ClearArray $cnt, $base, $val" %}
15167
15168 ins_encode %{
15169 __ fill_words($base$$Register, $cnt$$Register, $val$$Register);
15170 %}
15171
15172 ins_pipe(pipe_class_memory);
15173 %}
15174
15175 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, Universe dummy, rFlagsReg cr)
15176 %{
15177 predicate((uint64_t)n->in(2)->get_long()
15178 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)
15179 && !((ClearArrayNode*)n)->word_copy_only());
15180 match(Set dummy (ClearArray cnt base));
15181 effect(TEMP temp, USE_KILL base, KILL cr);
15182
15183 ins_cost(4 * INSN_COST);
15184 format %{ "ClearArray $cnt, $base" %}
15185
15186 ins_encode %{
15187 address tpc = __ zero_words($base$$Register, (uint64_t)$cnt$$constant);
15188 if (tpc == nullptr) {
15189 ciEnv::current()->record_failure("CodeCache is full");
15190 return;
15191 }
15192 %}
15193
15194 ins_pipe(pipe_class_memory);
15195 %}
15196
15197 // ============================================================================
15198 // Overflow Math Instructions
15199
15200 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
15201 %{
15202 match(Set cr (OverflowAddI op1 op2));
15203
15204 format %{ "cmnw $op1, $op2\t# overflow check int" %}
15205 ins_cost(INSN_COST);
15206 ins_encode %{
15207 __ cmnw($op1$$Register, $op2$$Register);
15208 %}
15209
15210 ins_pipe(icmp_reg_reg);
15211 %}
15212
15213 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
15214 %{
15215 match(Set cr (OverflowAddI op1 op2));
15216
15217 format %{ "cmnw $op1, $op2\t# overflow check int" %}
15218 ins_cost(INSN_COST);
15219 ins_encode %{
15220 __ cmnw($op1$$Register, $op2$$constant);
15221 %}
15222
15223 ins_pipe(icmp_reg_imm);
15224 %}
15225
15226 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15227 %{
15228 match(Set cr (OverflowAddL op1 op2));
15229
15230 format %{ "cmn $op1, $op2\t# overflow check long" %}
15231 ins_cost(INSN_COST);
15232 ins_encode %{
15233 __ cmn($op1$$Register, $op2$$Register);
15234 %}
15235
15236 ins_pipe(icmp_reg_reg);
15237 %}
15238
15239 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
15240 %{
15241 match(Set cr (OverflowAddL op1 op2));
15242
15243 format %{ "adds zr, $op1, $op2\t# overflow check long" %}
15244 ins_cost(INSN_COST);
15245 ins_encode %{
15246 __ adds(zr, $op1$$Register, $op2$$constant);
15247 %}
15248
15249 ins_pipe(icmp_reg_imm);
15250 %}
15251
15252 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
15253 %{
15254 match(Set cr (OverflowSubI op1 op2));
15255
15256 format %{ "cmpw $op1, $op2\t# overflow check int" %}
15257 ins_cost(INSN_COST);
15258 ins_encode %{
15259 __ cmpw($op1$$Register, $op2$$Register);
15260 %}
15261
15262 ins_pipe(icmp_reg_reg);
15263 %}
15264
15265 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
15266 %{
15267 match(Set cr (OverflowSubI op1 op2));
15268
15269 format %{ "cmpw $op1, $op2\t# overflow check int" %}
15270 ins_cost(INSN_COST);
15271 ins_encode %{
15272 __ cmpw($op1$$Register, $op2$$constant);
15273 %}
15274
15275 ins_pipe(icmp_reg_imm);
15276 %}
15277
15278 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15279 %{
15280 match(Set cr (OverflowSubL op1 op2));
15281
15282 format %{ "cmp $op1, $op2\t# overflow check long" %}
15283 ins_cost(INSN_COST);
15284 ins_encode %{
15285 __ cmp($op1$$Register, $op2$$Register);
15286 %}
15287
15288 ins_pipe(icmp_reg_reg);
15289 %}
15290
15291 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
15292 %{
15293 match(Set cr (OverflowSubL op1 op2));
15294
15295 format %{ "cmp $op1, $op2\t# overflow check long" %}
15296 ins_cost(INSN_COST);
15297 ins_encode %{
15298 __ subs(zr, $op1$$Register, $op2$$constant);
15299 %}
15300
15301 ins_pipe(icmp_reg_imm);
15302 %}
15303
15304 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1)
15305 %{
15306 match(Set cr (OverflowSubI zero op1));
15307
15308 format %{ "cmpw zr, $op1\t# overflow check int" %}
15309 ins_cost(INSN_COST);
15310 ins_encode %{
15311 __ cmpw(zr, $op1$$Register);
15312 %}
15313
15314 ins_pipe(icmp_reg_imm);
15315 %}
15316
15317 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1)
15318 %{
15319 match(Set cr (OverflowSubL zero op1));
15320
15321 format %{ "cmp zr, $op1\t# overflow check long" %}
15322 ins_cost(INSN_COST);
15323 ins_encode %{
15324 __ cmp(zr, $op1$$Register);
15325 %}
15326
15327 ins_pipe(icmp_reg_imm);
15328 %}
15329
15330 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
15331 %{
15332 match(Set cr (OverflowMulI op1 op2));
15333
15334 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
15335 "cmp rscratch1, rscratch1, sxtw\n\t"
15336 "movw rscratch1, #0x80000000\n\t"
15337 "cselw rscratch1, rscratch1, zr, NE\n\t"
15338 "cmpw rscratch1, #1" %}
15339 ins_cost(5 * INSN_COST);
15340 ins_encode %{
15341 __ smull(rscratch1, $op1$$Register, $op2$$Register);
15342 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow
15343 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ),
15344 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
15345 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS
15346 %}
15347
15348 ins_pipe(pipe_slow);
15349 %}
15350
15351 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr)
15352 %{
15353 match(If cmp (OverflowMulI op1 op2));
15354 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
15355 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
15356 effect(USE labl, KILL cr);
15357
15358 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
15359 "cmp rscratch1, rscratch1, sxtw\n\t"
15360 "b$cmp $labl" %}
15361 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST
15362 ins_encode %{
15363 Label* L = $labl$$label;
15364 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15365 __ smull(rscratch1, $op1$$Register, $op2$$Register);
15366 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow
15367 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
15368 %}
15369
15370 ins_pipe(pipe_serial);
15371 %}
15372
15373 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15374 %{
15375 match(Set cr (OverflowMulL op1 op2));
15376
15377 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t"
15378 "smulh rscratch2, $op1, $op2\n\t"
15379 "cmp rscratch2, rscratch1, ASR #63\n\t"
15380 "movw rscratch1, #0x80000000\n\t"
15381 "cselw rscratch1, rscratch1, zr, NE\n\t"
15382 "cmpw rscratch1, #1" %}
15383 ins_cost(6 * INSN_COST);
15384 ins_encode %{
15385 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63
15386 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
15387 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext
15388 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ),
15389 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
15390 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS
15391 %}
15392
15393 ins_pipe(pipe_slow);
15394 %}
15395
15396 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr)
15397 %{
15398 match(If cmp (OverflowMulL op1 op2));
15399 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
15400 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
15401 effect(USE labl, KILL cr);
15402
15403 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t"
15404 "smulh rscratch2, $op1, $op2\n\t"
15405 "cmp rscratch2, rscratch1, ASR #63\n\t"
15406 "b$cmp $labl" %}
15407 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
15408 ins_encode %{
15409 Label* L = $labl$$label;
15410 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15411 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63
15412 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
15413 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext
15414 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
15415 %}
15416
15417 ins_pipe(pipe_serial);
15418 %}
15419
15420 // ============================================================================
15421 // Compare Instructions
15422
15423 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
15424 %{
15425 match(Set cr (CmpI op1 op2));
15426
15427 effect(DEF cr, USE op1, USE op2);
15428
15429 ins_cost(INSN_COST);
15430 format %{ "cmpw $op1, $op2" %}
15431
15432 ins_encode(aarch64_enc_cmpw(op1, op2));
15433
15434 ins_pipe(icmp_reg_reg);
15435 %}
15436
15437 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero)
15438 %{
15439 match(Set cr (CmpI op1 zero));
15440
15441 effect(DEF cr, USE op1);
15442
15443 ins_cost(INSN_COST);
15444 format %{ "cmpw $op1, 0" %}
15445
15446 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
15447
15448 ins_pipe(icmp_reg_imm);
15449 %}
15450
15451 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2)
15452 %{
15453 match(Set cr (CmpI op1 op2));
15454
15455 effect(DEF cr, USE op1);
15456
15457 ins_cost(INSN_COST);
15458 format %{ "cmpw $op1, $op2" %}
15459
15460 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
15461
15462 ins_pipe(icmp_reg_imm);
15463 %}
15464
15465 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2)
15466 %{
15467 match(Set cr (CmpI op1 op2));
15468
15469 effect(DEF cr, USE op1);
15470
15471 ins_cost(INSN_COST * 2);
15472 format %{ "cmpw $op1, $op2" %}
15473
15474 ins_encode(aarch64_enc_cmpw_imm(op1, op2));
15475
15476 ins_pipe(icmp_reg_imm);
15477 %}
15478
15479 // Unsigned compare Instructions; really, same as signed compare
15480 // except it should only be used to feed an If or a CMovI which takes a
15481 // cmpOpU.
15482
15483 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2)
15484 %{
15485 match(Set cr (CmpU op1 op2));
15486
15487 effect(DEF cr, USE op1, USE op2);
15488
15489 ins_cost(INSN_COST);
15490 format %{ "cmpw $op1, $op2\t# unsigned" %}
15491
15492 ins_encode(aarch64_enc_cmpw(op1, op2));
15493
15494 ins_pipe(icmp_reg_reg);
15495 %}
15496
15497 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero)
15498 %{
15499 match(Set cr (CmpU op1 zero));
15500
15501 effect(DEF cr, USE op1);
15502
15503 ins_cost(INSN_COST);
15504 format %{ "cmpw $op1, #0\t# unsigned" %}
15505
15506 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
15507
15508 ins_pipe(icmp_reg_imm);
15509 %}
15510
15511 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2)
15512 %{
15513 match(Set cr (CmpU op1 op2));
15514
15515 effect(DEF cr, USE op1);
15516
15517 ins_cost(INSN_COST);
15518 format %{ "cmpw $op1, $op2\t# unsigned" %}
15519
15520 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
15521
15522 ins_pipe(icmp_reg_imm);
15523 %}
15524
15525 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2)
15526 %{
15527 match(Set cr (CmpU op1 op2));
15528
15529 effect(DEF cr, USE op1);
15530
15531 ins_cost(INSN_COST * 2);
15532 format %{ "cmpw $op1, $op2\t# unsigned" %}
15533
15534 ins_encode(aarch64_enc_cmpw_imm(op1, op2));
15535
15536 ins_pipe(icmp_reg_imm);
15537 %}
15538
15539 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15540 %{
15541 match(Set cr (CmpL op1 op2));
15542
15543 effect(DEF cr, USE op1, USE op2);
15544
15545 ins_cost(INSN_COST);
15546 format %{ "cmp $op1, $op2" %}
15547
15548 ins_encode(aarch64_enc_cmp(op1, op2));
15549
15550 ins_pipe(icmp_reg_reg);
15551 %}
15552
15553 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero)
15554 %{
15555 match(Set cr (CmpL op1 zero));
15556
15557 effect(DEF cr, USE op1);
15558
15559 ins_cost(INSN_COST);
15560 format %{ "tst $op1" %}
15561
15562 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
15563
15564 ins_pipe(icmp_reg_imm);
15565 %}
15566
15567 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2)
15568 %{
15569 match(Set cr (CmpL op1 op2));
15570
15571 effect(DEF cr, USE op1);
15572
15573 ins_cost(INSN_COST);
15574 format %{ "cmp $op1, $op2" %}
15575
15576 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
15577
15578 ins_pipe(icmp_reg_imm);
15579 %}
15580
15581 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2)
15582 %{
15583 match(Set cr (CmpL op1 op2));
15584
15585 effect(DEF cr, USE op1);
15586
15587 ins_cost(INSN_COST * 2);
15588 format %{ "cmp $op1, $op2" %}
15589
15590 ins_encode(aarch64_enc_cmp_imm(op1, op2));
15591
15592 ins_pipe(icmp_reg_imm);
15593 %}
15594
15595 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2)
15596 %{
15597 match(Set cr (CmpUL op1 op2));
15598
15599 effect(DEF cr, USE op1, USE op2);
15600
15601 ins_cost(INSN_COST);
15602 format %{ "cmp $op1, $op2" %}
15603
15604 ins_encode(aarch64_enc_cmp(op1, op2));
15605
15606 ins_pipe(icmp_reg_reg);
15607 %}
15608
15609 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero)
15610 %{
15611 match(Set cr (CmpUL op1 zero));
15612
15613 effect(DEF cr, USE op1);
15614
15615 ins_cost(INSN_COST);
15616 format %{ "tst $op1" %}
15617
15618 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
15619
15620 ins_pipe(icmp_reg_imm);
15621 %}
15622
15623 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2)
15624 %{
15625 match(Set cr (CmpUL op1 op2));
15626
15627 effect(DEF cr, USE op1);
15628
15629 ins_cost(INSN_COST);
15630 format %{ "cmp $op1, $op2" %}
15631
15632 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
15633
15634 ins_pipe(icmp_reg_imm);
15635 %}
15636
15637 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2)
15638 %{
15639 match(Set cr (CmpUL op1 op2));
15640
15641 effect(DEF cr, USE op1);
15642
15643 ins_cost(INSN_COST * 2);
15644 format %{ "cmp $op1, $op2" %}
15645
15646 ins_encode(aarch64_enc_cmp_imm(op1, op2));
15647
15648 ins_pipe(icmp_reg_imm);
15649 %}
15650
15651 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2)
15652 %{
15653 match(Set cr (CmpP op1 op2));
15654
15655 effect(DEF cr, USE op1, USE op2);
15656
15657 ins_cost(INSN_COST);
15658 format %{ "cmp $op1, $op2\t // ptr" %}
15659
15660 ins_encode(aarch64_enc_cmpp(op1, op2));
15661
15662 ins_pipe(icmp_reg_reg);
15663 %}
15664
15665 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2)
15666 %{
15667 match(Set cr (CmpN op1 op2));
15668
15669 effect(DEF cr, USE op1, USE op2);
15670
15671 ins_cost(INSN_COST);
15672 format %{ "cmp $op1, $op2\t // compressed ptr" %}
15673
15674 ins_encode(aarch64_enc_cmpn(op1, op2));
15675
15676 ins_pipe(icmp_reg_reg);
15677 %}
15678
15679 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero)
15680 %{
15681 match(Set cr (CmpP op1 zero));
15682
15683 effect(DEF cr, USE op1, USE zero);
15684
15685 ins_cost(INSN_COST);
15686 format %{ "cmp $op1, 0\t // ptr" %}
15687
15688 ins_encode(aarch64_enc_testp(op1));
15689
15690 ins_pipe(icmp_reg_imm);
15691 %}
15692
15693 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero)
15694 %{
15695 match(Set cr (CmpN op1 zero));
15696
15697 effect(DEF cr, USE op1, USE zero);
15698
15699 ins_cost(INSN_COST);
15700 format %{ "cmp $op1, 0\t // compressed ptr" %}
15701
15702 ins_encode(aarch64_enc_testn(op1));
15703
15704 ins_pipe(icmp_reg_imm);
15705 %}
15706
15707 // FP comparisons
15708 //
15709 // n.b. CmpF/CmpD set a normal flags reg which then gets compared
15710 // using normal cmpOp. See declaration of rFlagsReg for details.
15711
15712 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2)
15713 %{
15714 match(Set cr (CmpF src1 src2));
15715
15716 ins_cost(3 * INSN_COST);
15717 format %{ "fcmps $src1, $src2" %}
15718
15719 ins_encode %{
15720 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15721 %}
15722
15723 ins_pipe(pipe_class_compare);
15724 %}
15725
15726 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2)
15727 %{
15728 match(Set cr (CmpF src1 src2));
15729
15730 ins_cost(3 * INSN_COST);
15731 format %{ "fcmps $src1, 0.0" %}
15732
15733 ins_encode %{
15734 __ fcmps(as_FloatRegister($src1$$reg), 0.0);
15735 %}
15736
15737 ins_pipe(pipe_class_compare);
15738 %}
15739 // FROM HERE
15740
15741 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2)
15742 %{
15743 match(Set cr (CmpD src1 src2));
15744
15745 ins_cost(3 * INSN_COST);
15746 format %{ "fcmpd $src1, $src2" %}
15747
15748 ins_encode %{
15749 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15750 %}
15751
15752 ins_pipe(pipe_class_compare);
15753 %}
15754
15755 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2)
15756 %{
15757 match(Set cr (CmpD src1 src2));
15758
15759 ins_cost(3 * INSN_COST);
15760 format %{ "fcmpd $src1, 0.0" %}
15761
15762 ins_encode %{
15763 __ fcmpd(as_FloatRegister($src1$$reg), 0.0);
15764 %}
15765
15766 ins_pipe(pipe_class_compare);
15767 %}
15768
15769 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr)
15770 %{
15771 match(Set dst (CmpF3 src1 src2));
15772 effect(KILL cr);
15773
15774 ins_cost(5 * INSN_COST);
15775 format %{ "fcmps $src1, $src2\n\t"
15776 "csinvw($dst, zr, zr, eq\n\t"
15777 "csnegw($dst, $dst, $dst, lt)"
15778 %}
15779
15780 ins_encode %{
15781 Label done;
15782 FloatRegister s1 = as_FloatRegister($src1$$reg);
15783 FloatRegister s2 = as_FloatRegister($src2$$reg);
15784 Register d = as_Register($dst$$reg);
15785 __ fcmps(s1, s2);
15786 // installs 0 if EQ else -1
15787 __ csinvw(d, zr, zr, Assembler::EQ);
15788 // keeps -1 if less or unordered else installs 1
15789 __ csnegw(d, d, d, Assembler::LT);
15790 __ bind(done);
15791 %}
15792
15793 ins_pipe(pipe_class_default);
15794
15795 %}
15796
15797 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr)
15798 %{
15799 match(Set dst (CmpD3 src1 src2));
15800 effect(KILL cr);
15801
15802 ins_cost(5 * INSN_COST);
15803 format %{ "fcmpd $src1, $src2\n\t"
15804 "csinvw($dst, zr, zr, eq\n\t"
15805 "csnegw($dst, $dst, $dst, lt)"
15806 %}
15807
15808 ins_encode %{
15809 Label done;
15810 FloatRegister s1 = as_FloatRegister($src1$$reg);
15811 FloatRegister s2 = as_FloatRegister($src2$$reg);
15812 Register d = as_Register($dst$$reg);
15813 __ fcmpd(s1, s2);
15814 // installs 0 if EQ else -1
15815 __ csinvw(d, zr, zr, Assembler::EQ);
15816 // keeps -1 if less or unordered else installs 1
15817 __ csnegw(d, d, d, Assembler::LT);
15818 __ bind(done);
15819 %}
15820 ins_pipe(pipe_class_default);
15821
15822 %}
15823
15824 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr)
15825 %{
15826 match(Set dst (CmpF3 src1 zero));
15827 effect(KILL cr);
15828
15829 ins_cost(5 * INSN_COST);
15830 format %{ "fcmps $src1, 0.0\n\t"
15831 "csinvw($dst, zr, zr, eq\n\t"
15832 "csnegw($dst, $dst, $dst, lt)"
15833 %}
15834
15835 ins_encode %{
15836 Label done;
15837 FloatRegister s1 = as_FloatRegister($src1$$reg);
15838 Register d = as_Register($dst$$reg);
15839 __ fcmps(s1, 0.0);
15840 // installs 0 if EQ else -1
15841 __ csinvw(d, zr, zr, Assembler::EQ);
15842 // keeps -1 if less or unordered else installs 1
15843 __ csnegw(d, d, d, Assembler::LT);
15844 __ bind(done);
15845 %}
15846
15847 ins_pipe(pipe_class_default);
15848
15849 %}
15850
15851 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr)
15852 %{
15853 match(Set dst (CmpD3 src1 zero));
15854 effect(KILL cr);
15855
15856 ins_cost(5 * INSN_COST);
15857 format %{ "fcmpd $src1, 0.0\n\t"
15858 "csinvw($dst, zr, zr, eq\n\t"
15859 "csnegw($dst, $dst, $dst, lt)"
15860 %}
15861
15862 ins_encode %{
15863 Label done;
15864 FloatRegister s1 = as_FloatRegister($src1$$reg);
15865 Register d = as_Register($dst$$reg);
15866 __ fcmpd(s1, 0.0);
15867 // installs 0 if EQ else -1
15868 __ csinvw(d, zr, zr, Assembler::EQ);
15869 // keeps -1 if less or unordered else installs 1
15870 __ csnegw(d, d, d, Assembler::LT);
15871 __ bind(done);
15872 %}
15873 ins_pipe(pipe_class_default);
15874
15875 %}
15876
15877 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr)
15878 %{
15879 match(Set dst (CmpLTMask p q));
15880 effect(KILL cr);
15881
15882 ins_cost(3 * INSN_COST);
15883
15884 format %{ "cmpw $p, $q\t# cmpLTMask\n\t"
15885 "csetw $dst, lt\n\t"
15886 "subw $dst, zr, $dst"
15887 %}
15888
15889 ins_encode %{
15890 __ cmpw(as_Register($p$$reg), as_Register($q$$reg));
15891 __ csetw(as_Register($dst$$reg), Assembler::LT);
15892 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg));
15893 %}
15894
15895 ins_pipe(ialu_reg_reg);
15896 %}
15897
15898 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr)
15899 %{
15900 match(Set dst (CmpLTMask src zero));
15901 effect(KILL cr);
15902
15903 ins_cost(INSN_COST);
15904
15905 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %}
15906
15907 ins_encode %{
15908 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31);
15909 %}
15910
15911 ins_pipe(ialu_reg_shift);
15912 %}
15913
15914 // ============================================================================
15915 // Max and Min
15916
15917 // Like compI_reg_reg or compI_reg_immI0 but without match rule and second zero parameter.
15918
15919 instruct compI_reg_imm0(rFlagsReg cr, iRegI src)
15920 %{
15921 effect(DEF cr, USE src);
15922 ins_cost(INSN_COST);
15923 format %{ "cmpw $src, 0" %}
15924
15925 ins_encode %{
15926 __ cmpw($src$$Register, 0);
15927 %}
15928 ins_pipe(icmp_reg_imm);
15929 %}
15930
15931 instruct minI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2)
15932 %{
15933 match(Set dst (MinI src1 src2));
15934 ins_cost(INSN_COST * 3);
15935
15936 expand %{
15937 rFlagsReg cr;
15938 compI_reg_reg(cr, src1, src2);
15939 cmovI_reg_reg_lt(dst, src1, src2, cr);
15940 %}
15941 %}
15942
15943 instruct maxI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2)
15944 %{
15945 match(Set dst (MaxI src1 src2));
15946 ins_cost(INSN_COST * 3);
15947
15948 expand %{
15949 rFlagsReg cr;
15950 compI_reg_reg(cr, src1, src2);
15951 cmovI_reg_reg_gt(dst, src1, src2, cr);
15952 %}
15953 %}
15954
15955
15956 // ============================================================================
15957 // Branch Instructions
15958
15959 // Direct Branch.
15960 instruct branch(label lbl)
15961 %{
15962 match(Goto);
15963
15964 effect(USE lbl);
15965
15966 ins_cost(BRANCH_COST);
15967 format %{ "b $lbl" %}
15968
15969 ins_encode(aarch64_enc_b(lbl));
15970
15971 ins_pipe(pipe_branch);
15972 %}
15973
15974 // Conditional Near Branch
15975 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl)
15976 %{
15977 // Same match rule as `branchConFar'.
15978 match(If cmp cr);
15979
15980 effect(USE lbl);
15981
15982 ins_cost(BRANCH_COST);
15983 // If set to 1 this indicates that the current instruction is a
15984 // short variant of a long branch. This avoids using this
15985 // instruction in first-pass matching. It will then only be used in
15986 // the `Shorten_branches' pass.
15987 // ins_short_branch(1);
15988 format %{ "b$cmp $lbl" %}
15989
15990 ins_encode(aarch64_enc_br_con(cmp, lbl));
15991
15992 ins_pipe(pipe_branch_cond);
15993 %}
15994
15995 // Conditional Near Branch Unsigned
15996 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl)
15997 %{
15998 // Same match rule as `branchConFar'.
15999 match(If cmp cr);
16000
16001 effect(USE lbl);
16002
16003 ins_cost(BRANCH_COST);
16004 // If set to 1 this indicates that the current instruction is a
16005 // short variant of a long branch. This avoids using this
16006 // instruction in first-pass matching. It will then only be used in
16007 // the `Shorten_branches' pass.
16008 // ins_short_branch(1);
16009 format %{ "b$cmp $lbl\t# unsigned" %}
16010
16011 ins_encode(aarch64_enc_br_conU(cmp, lbl));
16012
16013 ins_pipe(pipe_branch_cond);
16014 %}
16015
16016 // Make use of CBZ and CBNZ. These instructions, as well as being
16017 // shorter than (cmp; branch), have the additional benefit of not
16018 // killing the flags.
16019
16020 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
16021 match(If cmp (CmpI op1 op2));
16022 effect(USE labl);
16023
16024 ins_cost(BRANCH_COST);
16025 format %{ "cbw$cmp $op1, $labl" %}
16026 ins_encode %{
16027 Label* L = $labl$$label;
16028 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16029 if (cond == Assembler::EQ)
16030 __ cbzw($op1$$Register, *L);
16031 else
16032 __ cbnzw($op1$$Register, *L);
16033 %}
16034 ins_pipe(pipe_cmp_branch);
16035 %}
16036
16037 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{
16038 match(If cmp (CmpL op1 op2));
16039 effect(USE labl);
16040
16041 ins_cost(BRANCH_COST);
16042 format %{ "cb$cmp $op1, $labl" %}
16043 ins_encode %{
16044 Label* L = $labl$$label;
16045 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16046 if (cond == Assembler::EQ)
16047 __ cbz($op1$$Register, *L);
16048 else
16049 __ cbnz($op1$$Register, *L);
16050 %}
16051 ins_pipe(pipe_cmp_branch);
16052 %}
16053
16054 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{
16055 match(If cmp (CmpP op1 op2));
16056 effect(USE labl);
16057
16058 ins_cost(BRANCH_COST);
16059 format %{ "cb$cmp $op1, $labl" %}
16060 ins_encode %{
16061 Label* L = $labl$$label;
16062 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16063 if (cond == Assembler::EQ)
16064 __ cbz($op1$$Register, *L);
16065 else
16066 __ cbnz($op1$$Register, *L);
16067 %}
16068 ins_pipe(pipe_cmp_branch);
16069 %}
16070
16071 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{
16072 match(If cmp (CmpN op1 op2));
16073 effect(USE labl);
16074
16075 ins_cost(BRANCH_COST);
16076 format %{ "cbw$cmp $op1, $labl" %}
16077 ins_encode %{
16078 Label* L = $labl$$label;
16079 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16080 if (cond == Assembler::EQ)
16081 __ cbzw($op1$$Register, *L);
16082 else
16083 __ cbnzw($op1$$Register, *L);
16084 %}
16085 ins_pipe(pipe_cmp_branch);
16086 %}
16087
16088 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{
16089 match(If cmp (CmpP (DecodeN oop) zero));
16090 effect(USE labl);
16091
16092 ins_cost(BRANCH_COST);
16093 format %{ "cb$cmp $oop, $labl" %}
16094 ins_encode %{
16095 Label* L = $labl$$label;
16096 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16097 if (cond == Assembler::EQ)
16098 __ cbzw($oop$$Register, *L);
16099 else
16100 __ cbnzw($oop$$Register, *L);
16101 %}
16102 ins_pipe(pipe_cmp_branch);
16103 %}
16104
16105 instruct cmpUI_imm0_branch(cmpOpUEqNeLeGt cmp, iRegIorL2I op1, immI0 op2, label labl) %{
16106 match(If cmp (CmpU op1 op2));
16107 effect(USE labl);
16108
16109 ins_cost(BRANCH_COST);
16110 format %{ "cbw$cmp $op1, $labl" %}
16111 ins_encode %{
16112 Label* L = $labl$$label;
16113 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16114 if (cond == Assembler::EQ || cond == Assembler::LS) {
16115 __ cbzw($op1$$Register, *L);
16116 } else {
16117 assert(cond == Assembler::NE || cond == Assembler::HI, "unexpected condition");
16118 __ cbnzw($op1$$Register, *L);
16119 }
16120 %}
16121 ins_pipe(pipe_cmp_branch);
16122 %}
16123
16124 instruct cmpUL_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 op2, label labl) %{
16125 match(If cmp (CmpUL op1 op2));
16126 effect(USE labl);
16127
16128 ins_cost(BRANCH_COST);
16129 format %{ "cb$cmp $op1, $labl" %}
16130 ins_encode %{
16131 Label* L = $labl$$label;
16132 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16133 if (cond == Assembler::EQ || cond == Assembler::LS) {
16134 __ cbz($op1$$Register, *L);
16135 } else {
16136 assert(cond == Assembler::NE || cond == Assembler::HI, "unexpected condition");
16137 __ cbnz($op1$$Register, *L);
16138 }
16139 %}
16140 ins_pipe(pipe_cmp_branch);
16141 %}
16142
16143 // Test bit and Branch
16144
16145 // Patterns for short (< 32KiB) variants
16146 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
16147 match(If cmp (CmpL op1 op2));
16148 effect(USE labl);
16149
16150 ins_cost(BRANCH_COST);
16151 format %{ "cb$cmp $op1, $labl # long" %}
16152 ins_encode %{
16153 Label* L = $labl$$label;
16154 Assembler::Condition cond =
16155 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16156 __ tbr(cond, $op1$$Register, 63, *L);
16157 %}
16158 ins_pipe(pipe_cmp_branch);
16159 ins_short_branch(1);
16160 %}
16161
16162 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
16163 match(If cmp (CmpI op1 op2));
16164 effect(USE labl);
16165
16166 ins_cost(BRANCH_COST);
16167 format %{ "cb$cmp $op1, $labl # int" %}
16168 ins_encode %{
16169 Label* L = $labl$$label;
16170 Assembler::Condition cond =
16171 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16172 __ tbr(cond, $op1$$Register, 31, *L);
16173 %}
16174 ins_pipe(pipe_cmp_branch);
16175 ins_short_branch(1);
16176 %}
16177
16178 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
16179 match(If cmp (CmpL (AndL op1 op2) op3));
16180 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long()));
16181 effect(USE labl);
16182
16183 ins_cost(BRANCH_COST);
16184 format %{ "tb$cmp $op1, $op2, $labl" %}
16185 ins_encode %{
16186 Label* L = $labl$$label;
16187 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16188 int bit = exact_log2_long($op2$$constant);
16189 __ tbr(cond, $op1$$Register, bit, *L);
16190 %}
16191 ins_pipe(pipe_cmp_branch);
16192 ins_short_branch(1);
16193 %}
16194
16195 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
16196 match(If cmp (CmpI (AndI op1 op2) op3));
16197 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int()));
16198 effect(USE labl);
16199
16200 ins_cost(BRANCH_COST);
16201 format %{ "tb$cmp $op1, $op2, $labl" %}
16202 ins_encode %{
16203 Label* L = $labl$$label;
16204 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16205 int bit = exact_log2((juint)$op2$$constant);
16206 __ tbr(cond, $op1$$Register, bit, *L);
16207 %}
16208 ins_pipe(pipe_cmp_branch);
16209 ins_short_branch(1);
16210 %}
16211
16212 // And far variants
16213 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
16214 match(If cmp (CmpL op1 op2));
16215 effect(USE labl);
16216
16217 ins_cost(BRANCH_COST);
16218 format %{ "cb$cmp $op1, $labl # long" %}
16219 ins_encode %{
16220 Label* L = $labl$$label;
16221 Assembler::Condition cond =
16222 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16223 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true);
16224 %}
16225 ins_pipe(pipe_cmp_branch);
16226 %}
16227
16228 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
16229 match(If cmp (CmpI op1 op2));
16230 effect(USE labl);
16231
16232 ins_cost(BRANCH_COST);
16233 format %{ "cb$cmp $op1, $labl # int" %}
16234 ins_encode %{
16235 Label* L = $labl$$label;
16236 Assembler::Condition cond =
16237 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16238 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true);
16239 %}
16240 ins_pipe(pipe_cmp_branch);
16241 %}
16242
16243 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
16244 match(If cmp (CmpL (AndL op1 op2) op3));
16245 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long()));
16246 effect(USE labl);
16247
16248 ins_cost(BRANCH_COST);
16249 format %{ "tb$cmp $op1, $op2, $labl" %}
16250 ins_encode %{
16251 Label* L = $labl$$label;
16252 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16253 int bit = exact_log2_long($op2$$constant);
16254 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
16255 %}
16256 ins_pipe(pipe_cmp_branch);
16257 %}
16258
16259 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
16260 match(If cmp (CmpI (AndI op1 op2) op3));
16261 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int()));
16262 effect(USE labl);
16263
16264 ins_cost(BRANCH_COST);
16265 format %{ "tb$cmp $op1, $op2, $labl" %}
16266 ins_encode %{
16267 Label* L = $labl$$label;
16268 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16269 int bit = exact_log2((juint)$op2$$constant);
16270 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
16271 %}
16272 ins_pipe(pipe_cmp_branch);
16273 %}
16274
16275 // Test bits
16276
16277 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{
16278 match(Set cr (CmpL (AndL op1 op2) op3));
16279 predicate(Assembler::operand_valid_for_logical_immediate
16280 (/*is_32*/false, n->in(1)->in(2)->get_long()));
16281
16282 ins_cost(INSN_COST);
16283 format %{ "tst $op1, $op2 # long" %}
16284 ins_encode %{
16285 __ tst($op1$$Register, $op2$$constant);
16286 %}
16287 ins_pipe(ialu_reg_reg);
16288 %}
16289
16290 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{
16291 match(Set cr (CmpI (AndI op1 op2) op3));
16292 predicate(Assembler::operand_valid_for_logical_immediate
16293 (/*is_32*/true, n->in(1)->in(2)->get_int()));
16294
16295 ins_cost(INSN_COST);
16296 format %{ "tst $op1, $op2 # int" %}
16297 ins_encode %{
16298 __ tstw($op1$$Register, $op2$$constant);
16299 %}
16300 ins_pipe(ialu_reg_reg);
16301 %}
16302
16303 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{
16304 match(Set cr (CmpL (AndL op1 op2) op3));
16305
16306 ins_cost(INSN_COST);
16307 format %{ "tst $op1, $op2 # long" %}
16308 ins_encode %{
16309 __ tst($op1$$Register, $op2$$Register);
16310 %}
16311 ins_pipe(ialu_reg_reg);
16312 %}
16313
16314 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{
16315 match(Set cr (CmpI (AndI op1 op2) op3));
16316
16317 ins_cost(INSN_COST);
16318 format %{ "tstw $op1, $op2 # int" %}
16319 ins_encode %{
16320 __ tstw($op1$$Register, $op2$$Register);
16321 %}
16322 ins_pipe(ialu_reg_reg);
16323 %}
16324
16325
16326 // Conditional Far Branch
16327 // Conditional Far Branch Unsigned
16328 // TODO: fixme
16329
16330 // counted loop end branch near
16331 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
16332 %{
16333 match(CountedLoopEnd cmp cr);
16334
16335 effect(USE lbl);
16336
16337 ins_cost(BRANCH_COST);
16338 // short variant.
16339 // ins_short_branch(1);
16340 format %{ "b$cmp $lbl \t// counted loop end" %}
16341
16342 ins_encode(aarch64_enc_br_con(cmp, lbl));
16343
16344 ins_pipe(pipe_branch);
16345 %}
16346
16347 // counted loop end branch far
16348 // TODO: fixme
16349
16350 // ============================================================================
16351 // inlined locking and unlocking
16352
16353 instruct cmpFastLockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3)
16354 %{
16355 match(Set cr (FastLock object box));
16356 effect(TEMP tmp, TEMP tmp2, TEMP tmp3);
16357
16358 ins_cost(5 * INSN_COST);
16359 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2,$tmp3" %}
16360
16361 ins_encode %{
16362 __ fast_lock_lightweight($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
16363 %}
16364
16365 ins_pipe(pipe_serial);
16366 %}
16367
16368 instruct cmpFastUnlockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3)
16369 %{
16370 match(Set cr (FastUnlock object box));
16371 effect(TEMP tmp, TEMP tmp2, TEMP tmp3);
16372
16373 ins_cost(5 * INSN_COST);
16374 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2, $tmp3" %}
16375
16376 ins_encode %{
16377 __ fast_unlock_lightweight($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
16378 %}
16379
16380 ins_pipe(pipe_serial);
16381 %}
16382
16383 // ============================================================================
16384 // Safepoint Instructions
16385
16386 // TODO
16387 // provide a near and far version of this code
16388
16389 instruct safePoint(rFlagsReg cr, iRegP poll)
16390 %{
16391 match(SafePoint poll);
16392 effect(KILL cr);
16393
16394 format %{
16395 "ldrw zr, [$poll]\t# Safepoint: poll for GC"
16396 %}
16397 ins_encode %{
16398 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type);
16399 %}
16400 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem);
16401 %}
16402
16403
16404 // ============================================================================
16405 // Procedure Call/Return Instructions
16406
16407 // Call Java Static Instruction
16408
16409 instruct CallStaticJavaDirect(method meth)
16410 %{
16411 match(CallStaticJava);
16412
16413 effect(USE meth);
16414
16415 ins_cost(CALL_COST);
16416
16417 format %{ "call,static $meth \t// ==> " %}
16418
16419 ins_encode(aarch64_enc_java_static_call(meth),
16420 aarch64_enc_call_epilog);
16421
16422 ins_pipe(pipe_class_call);
16423 %}
16424
16425 // TO HERE
16426
16427 // Call Java Dynamic Instruction
16428 instruct CallDynamicJavaDirect(method meth)
16429 %{
16430 match(CallDynamicJava);
16431
16432 effect(USE meth);
16433
16434 ins_cost(CALL_COST);
16435
16436 format %{ "CALL,dynamic $meth \t// ==> " %}
16437
16438 ins_encode(aarch64_enc_java_dynamic_call(meth),
16439 aarch64_enc_call_epilog);
16440
16441 ins_pipe(pipe_class_call);
16442 %}
16443
16444 // Call Runtime Instruction
16445
16446 instruct CallRuntimeDirect(method meth)
16447 %{
16448 match(CallRuntime);
16449
16450 effect(USE meth);
16451
16452 ins_cost(CALL_COST);
16453
16454 format %{ "CALL, runtime $meth" %}
16455
16456 ins_encode( aarch64_enc_java_to_runtime(meth) );
16457
16458 ins_pipe(pipe_class_call);
16459 %}
16460
16461 // Call Runtime Instruction
16462
16463 instruct CallLeafDirect(method meth)
16464 %{
16465 match(CallLeaf);
16466
16467 effect(USE meth);
16468
16469 ins_cost(CALL_COST);
16470
16471 format %{ "CALL, runtime leaf $meth" %}
16472
16473 ins_encode( aarch64_enc_java_to_runtime(meth) );
16474
16475 ins_pipe(pipe_class_call);
16476 %}
16477
16478 // Call Runtime Instruction without safepoint and with vector arguments
16479 instruct CallLeafDirectVector(method meth)
16480 %{
16481 match(CallLeafVector);
16482
16483 effect(USE meth);
16484
16485 ins_cost(CALL_COST);
16486
16487 format %{ "CALL, runtime leaf vector $meth" %}
16488
16489 ins_encode(aarch64_enc_java_to_runtime(meth));
16490
16491 ins_pipe(pipe_class_call);
16492 %}
16493
16494 // Call Runtime Instruction
16495
16496 // entry point is null, target holds the address to call
16497 instruct CallLeafNoFPIndirect(iRegP target)
16498 %{
16499 predicate(n->as_Call()->entry_point() == nullptr);
16500
16501 match(CallLeafNoFP target);
16502
16503 ins_cost(CALL_COST);
16504
16505 format %{ "CALL, runtime leaf nofp indirect $target" %}
16506
16507 ins_encode %{
16508 __ blr($target$$Register);
16509 %}
16510
16511 ins_pipe(pipe_class_call);
16512 %}
16513
16514 instruct CallLeafNoFPDirect(method meth)
16515 %{
16516 predicate(n->as_Call()->entry_point() != nullptr);
16517
16518 match(CallLeafNoFP);
16519
16520 effect(USE meth);
16521
16522 ins_cost(CALL_COST);
16523
16524 format %{ "CALL, runtime leaf nofp $meth" %}
16525
16526 ins_encode( aarch64_enc_java_to_runtime(meth) );
16527
16528 ins_pipe(pipe_class_call);
16529 %}
16530
16531 // Tail Call; Jump from runtime stub to Java code.
16532 // Also known as an 'interprocedural jump'.
16533 // Target of jump will eventually return to caller.
16534 // TailJump below removes the return address.
16535 // Don't use rfp for 'jump_target' because a MachEpilogNode has already been
16536 // emitted just above the TailCall which has reset rfp to the caller state.
16537 instruct TailCalljmpInd(iRegPNoSpNoRfp jump_target, inline_cache_RegP method_ptr)
16538 %{
16539 match(TailCall jump_target method_ptr);
16540
16541 ins_cost(CALL_COST);
16542
16543 format %{ "br $jump_target\t# $method_ptr holds method" %}
16544
16545 ins_encode(aarch64_enc_tail_call(jump_target));
16546
16547 ins_pipe(pipe_class_call);
16548 %}
16549
16550 instruct TailjmpInd(iRegPNoSpNoRfp jump_target, iRegP_R0 ex_oop)
16551 %{
16552 match(TailJump jump_target ex_oop);
16553
16554 ins_cost(CALL_COST);
16555
16556 format %{ "br $jump_target\t# $ex_oop holds exception oop" %}
16557
16558 ins_encode(aarch64_enc_tail_jmp(jump_target));
16559
16560 ins_pipe(pipe_class_call);
16561 %}
16562
16563 // Forward exception.
16564 instruct ForwardExceptionjmp()
16565 %{
16566 match(ForwardException);
16567 ins_cost(CALL_COST);
16568
16569 format %{ "b forward_exception_stub" %}
16570 ins_encode %{
16571 __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
16572 %}
16573 ins_pipe(pipe_class_call);
16574 %}
16575
16576 // Create exception oop: created by stack-crawling runtime code.
16577 // Created exception is now available to this handler, and is setup
16578 // just prior to jumping to this handler. No code emitted.
16579 // TODO check
16580 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1
16581 instruct CreateException(iRegP_R0 ex_oop)
16582 %{
16583 match(Set ex_oop (CreateEx));
16584
16585 format %{ " -- \t// exception oop; no code emitted" %}
16586
16587 size(0);
16588
16589 ins_encode( /*empty*/ );
16590
16591 ins_pipe(pipe_class_empty);
16592 %}
16593
16594 // Rethrow exception: The exception oop will come in the first
16595 // argument position. Then JUMP (not call) to the rethrow stub code.
16596 instruct RethrowException() %{
16597 match(Rethrow);
16598 ins_cost(CALL_COST);
16599
16600 format %{ "b rethrow_stub" %}
16601
16602 ins_encode( aarch64_enc_rethrow() );
16603
16604 ins_pipe(pipe_class_call);
16605 %}
16606
16607
16608 // Return Instruction
16609 // epilog node loads ret address into lr as part of frame pop
16610 instruct Ret()
16611 %{
16612 match(Return);
16613
16614 format %{ "ret\t// return register" %}
16615
16616 ins_encode( aarch64_enc_ret() );
16617
16618 ins_pipe(pipe_branch);
16619 %}
16620
16621 // Die now.
16622 instruct ShouldNotReachHere() %{
16623 match(Halt);
16624
16625 ins_cost(CALL_COST);
16626 format %{ "ShouldNotReachHere" %}
16627
16628 ins_encode %{
16629 if (is_reachable()) {
16630 const char* str = __ code_string(_halt_reason);
16631 __ stop(str);
16632 }
16633 %}
16634
16635 ins_pipe(pipe_class_default);
16636 %}
16637
16638 // ============================================================================
16639 // Partial Subtype Check
16640 //
16641 // superklass array for an instance of the superklass. Set a hidden
16642 // internal cache on a hit (cache is checked with exposed code in
16643 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The
16644 // encoding ALSO sets flags.
16645
16646 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr)
16647 %{
16648 match(Set result (PartialSubtypeCheck sub super));
16649 predicate(!UseSecondarySupersTable);
16650 effect(KILL cr, KILL temp);
16651
16652 ins_cost(20 * INSN_COST); // slightly larger than the next version
16653 format %{ "partialSubtypeCheck $result, $sub, $super" %}
16654
16655 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
16656
16657 opcode(0x1); // Force zero of result reg on hit
16658
16659 ins_pipe(pipe_class_memory);
16660 %}
16661
16662 // Two versions of partialSubtypeCheck, both used when we need to
16663 // search for a super class in the secondary supers array. The first
16664 // is used when we don't know _a priori_ the class being searched
16665 // for. The second, far more common, is used when we do know: this is
16666 // used for instanceof, checkcast, and any case where C2 can determine
16667 // it by constant propagation.
16668
16669 instruct partialSubtypeCheckVarSuper(iRegP_R4 sub, iRegP_R0 super, vRegD_V0 vtemp, iRegP_R5 result,
16670 iRegP_R1 tempR1, iRegP_R2 tempR2, iRegP_R3 tempR3,
16671 rFlagsReg cr)
16672 %{
16673 match(Set result (PartialSubtypeCheck sub super));
16674 predicate(UseSecondarySupersTable);
16675 effect(KILL cr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP vtemp);
16676
16677 ins_cost(10 * INSN_COST); // slightly larger than the next version
16678 format %{ "partialSubtypeCheck $result, $sub, $super" %}
16679
16680 ins_encode %{
16681 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register,
16682 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register,
16683 $vtemp$$FloatRegister,
16684 $result$$Register, /*L_success*/nullptr);
16685 %}
16686
16687 ins_pipe(pipe_class_memory);
16688 %}
16689
16690 instruct partialSubtypeCheckConstSuper(iRegP_R4 sub, iRegP_R0 super_reg, immP super_con, vRegD_V0 vtemp, iRegP_R5 result,
16691 iRegP_R1 tempR1, iRegP_R2 tempR2, iRegP_R3 tempR3,
16692 rFlagsReg cr)
16693 %{
16694 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con)));
16695 predicate(UseSecondarySupersTable);
16696 effect(KILL cr, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP vtemp);
16697
16698 ins_cost(5 * INSN_COST); // smaller than the next version
16699 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %}
16700
16701 ins_encode %{
16702 bool success = false;
16703 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot();
16704 if (InlineSecondarySupersTest) {
16705 success =
16706 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register,
16707 $tempR1$$Register, $tempR2$$Register, $tempR3$$Register,
16708 $vtemp$$FloatRegister,
16709 $result$$Register,
16710 super_klass_slot);
16711 } else {
16712 address call = __ trampoline_call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot)));
16713 success = (call != nullptr);
16714 }
16715 if (!success) {
16716 ciEnv::current()->record_failure("CodeCache is full");
16717 return;
16718 }
16719 %}
16720
16721 ins_pipe(pipe_class_memory);
16722 %}
16723
16724 // Intrisics for String.compareTo()
16725
16726 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16727 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
16728 %{
16729 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU));
16730 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16731 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16732
16733 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %}
16734 ins_encode %{
16735 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16736 __ string_compare($str1$$Register, $str2$$Register,
16737 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16738 $tmp1$$Register, $tmp2$$Register,
16739 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::UU);
16740 %}
16741 ins_pipe(pipe_class_memory);
16742 %}
16743
16744 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16745 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
16746 %{
16747 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL));
16748 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16749 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16750
16751 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %}
16752 ins_encode %{
16753 __ string_compare($str1$$Register, $str2$$Register,
16754 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16755 $tmp1$$Register, $tmp2$$Register,
16756 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::LL);
16757 %}
16758 ins_pipe(pipe_class_memory);
16759 %}
16760
16761 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16762 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16763 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
16764 %{
16765 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL));
16766 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16767 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
16768 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16769
16770 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
16771 ins_encode %{
16772 __ string_compare($str1$$Register, $str2$$Register,
16773 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16774 $tmp1$$Register, $tmp2$$Register,
16775 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
16776 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::UL);
16777 %}
16778 ins_pipe(pipe_class_memory);
16779 %}
16780
16781 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16782 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16783 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
16784 %{
16785 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU));
16786 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16787 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
16788 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16789
16790 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
16791 ins_encode %{
16792 __ string_compare($str1$$Register, $str2$$Register,
16793 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16794 $tmp1$$Register, $tmp2$$Register,
16795 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
16796 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::LU);
16797 %}
16798 ins_pipe(pipe_class_memory);
16799 %}
16800
16801 // Note that Z registers alias the corresponding NEON registers, we declare the vector operands of
16802 // these string_compare variants as NEON register type for convenience so that the prototype of
16803 // string_compare can be shared with all variants.
16804
16805 instruct string_compareLL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16806 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16807 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
16808 pRegGov_P1 pgtmp2, rFlagsReg cr)
16809 %{
16810 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL));
16811 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16812 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
16813 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16814
16815 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
16816 ins_encode %{
16817 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16818 __ string_compare($str1$$Register, $str2$$Register,
16819 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16820 $tmp1$$Register, $tmp2$$Register,
16821 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
16822 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
16823 StrIntrinsicNode::LL);
16824 %}
16825 ins_pipe(pipe_class_memory);
16826 %}
16827
16828 instruct string_compareLU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16829 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16830 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
16831 pRegGov_P1 pgtmp2, rFlagsReg cr)
16832 %{
16833 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU));
16834 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16835 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
16836 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16837
16838 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
16839 ins_encode %{
16840 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16841 __ string_compare($str1$$Register, $str2$$Register,
16842 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16843 $tmp1$$Register, $tmp2$$Register,
16844 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
16845 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
16846 StrIntrinsicNode::LU);
16847 %}
16848 ins_pipe(pipe_class_memory);
16849 %}
16850
16851 instruct string_compareUL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16852 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16853 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
16854 pRegGov_P1 pgtmp2, rFlagsReg cr)
16855 %{
16856 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL));
16857 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16858 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
16859 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16860
16861 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
16862 ins_encode %{
16863 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16864 __ string_compare($str1$$Register, $str2$$Register,
16865 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16866 $tmp1$$Register, $tmp2$$Register,
16867 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
16868 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
16869 StrIntrinsicNode::UL);
16870 %}
16871 ins_pipe(pipe_class_memory);
16872 %}
16873
16874 instruct string_compareUU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16875 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16876 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1,
16877 pRegGov_P1 pgtmp2, rFlagsReg cr)
16878 %{
16879 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU));
16880 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16881 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2,
16882 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16883
16884 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %}
16885 ins_encode %{
16886 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16887 __ string_compare($str1$$Register, $str2$$Register,
16888 $cnt1$$Register, $cnt2$$Register, $result$$Register,
16889 $tmp1$$Register, $tmp2$$Register,
16890 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg,
16891 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg),
16892 StrIntrinsicNode::UU);
16893 %}
16894 ins_pipe(pipe_class_memory);
16895 %}
16896
16897 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
16898 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
16899 iRegINoSp tmp3, iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6,
16900 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr)
16901 %{
16902 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
16903 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
16904 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
16905 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6,
16906 TEMP vtmp0, TEMP vtmp1, KILL cr);
16907 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU) "
16908 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %}
16909
16910 ins_encode %{
16911 __ string_indexof($str1$$Register, $str2$$Register,
16912 $cnt1$$Register, $cnt2$$Register,
16913 $tmp1$$Register, $tmp2$$Register,
16914 $tmp3$$Register, $tmp4$$Register,
16915 $tmp5$$Register, $tmp6$$Register,
16916 -1, $result$$Register, StrIntrinsicNode::UU);
16917 %}
16918 ins_pipe(pipe_class_memory);
16919 %}
16920
16921 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
16922 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
16923 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6,
16924 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr)
16925 %{
16926 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
16927 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
16928 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
16929 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6,
16930 TEMP vtmp0, TEMP vtmp1, KILL cr);
16931 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL) "
16932 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %}
16933
16934 ins_encode %{
16935 __ string_indexof($str1$$Register, $str2$$Register,
16936 $cnt1$$Register, $cnt2$$Register,
16937 $tmp1$$Register, $tmp2$$Register,
16938 $tmp3$$Register, $tmp4$$Register,
16939 $tmp5$$Register, $tmp6$$Register,
16940 -1, $result$$Register, StrIntrinsicNode::LL);
16941 %}
16942 ins_pipe(pipe_class_memory);
16943 %}
16944
16945 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
16946 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,iRegINoSp tmp3,
16947 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6,
16948 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr)
16949 %{
16950 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
16951 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
16952 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
16953 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
16954 TEMP tmp6, TEMP vtmp0, TEMP vtmp1, KILL cr);
16955 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL) "
16956 "# KILL $str1 cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %}
16957
16958 ins_encode %{
16959 __ string_indexof($str1$$Register, $str2$$Register,
16960 $cnt1$$Register, $cnt2$$Register,
16961 $tmp1$$Register, $tmp2$$Register,
16962 $tmp3$$Register, $tmp4$$Register,
16963 $tmp5$$Register, $tmp6$$Register,
16964 -1, $result$$Register, StrIntrinsicNode::UL);
16965 %}
16966 ins_pipe(pipe_class_memory);
16967 %}
16968
16969 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
16970 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1,
16971 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
16972 %{
16973 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
16974 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
16975 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
16976 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
16977 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU) "
16978 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %}
16979
16980 ins_encode %{
16981 int icnt2 = (int)$int_cnt2$$constant;
16982 __ string_indexof($str1$$Register, $str2$$Register,
16983 $cnt1$$Register, zr,
16984 $tmp1$$Register, $tmp2$$Register,
16985 $tmp3$$Register, $tmp4$$Register, zr, zr,
16986 icnt2, $result$$Register, StrIntrinsicNode::UU);
16987 %}
16988 ins_pipe(pipe_class_memory);
16989 %}
16990
16991 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
16992 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1,
16993 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
16994 %{
16995 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
16996 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
16997 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
16998 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
16999 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL) "
17000 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %}
17001
17002 ins_encode %{
17003 int icnt2 = (int)$int_cnt2$$constant;
17004 __ string_indexof($str1$$Register, $str2$$Register,
17005 $cnt1$$Register, zr,
17006 $tmp1$$Register, $tmp2$$Register,
17007 $tmp3$$Register, $tmp4$$Register, zr, zr,
17008 icnt2, $result$$Register, StrIntrinsicNode::LL);
17009 %}
17010 ins_pipe(pipe_class_memory);
17011 %}
17012
17013 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
17014 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1,
17015 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
17016 %{
17017 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
17018 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
17019 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
17020 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
17021 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL) "
17022 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %}
17023
17024 ins_encode %{
17025 int icnt2 = (int)$int_cnt2$$constant;
17026 __ string_indexof($str1$$Register, $str2$$Register,
17027 $cnt1$$Register, zr,
17028 $tmp1$$Register, $tmp2$$Register,
17029 $tmp3$$Register, $tmp4$$Register, zr, zr,
17030 icnt2, $result$$Register, StrIntrinsicNode::UL);
17031 %}
17032 ins_pipe(pipe_class_memory);
17033 %}
17034
17035 instruct string_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
17036 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
17037 iRegINoSp tmp3, rFlagsReg cr)
17038 %{
17039 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
17040 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U));
17041 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
17042 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
17043
17044 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result" %}
17045
17046 ins_encode %{
17047 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
17048 $result$$Register, $tmp1$$Register, $tmp2$$Register,
17049 $tmp3$$Register);
17050 %}
17051 ins_pipe(pipe_class_memory);
17052 %}
17053
17054 instruct stringL_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
17055 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
17056 iRegINoSp tmp3, rFlagsReg cr)
17057 %{
17058 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
17059 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L));
17060 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
17061 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
17062
17063 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result" %}
17064
17065 ins_encode %{
17066 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
17067 $result$$Register, $tmp1$$Register, $tmp2$$Register,
17068 $tmp3$$Register);
17069 %}
17070 ins_pipe(pipe_class_memory);
17071 %}
17072
17073 instruct stringL_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
17074 iRegI_R0 result, vecA ztmp1, vecA ztmp2,
17075 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{
17076 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
17077 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
17078 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr);
17079 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %}
17080 ins_encode %{
17081 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register,
17082 $result$$Register, $ztmp1$$FloatRegister,
17083 $ztmp2$$FloatRegister, $pgtmp$$PRegister,
17084 $ptmp$$PRegister, true /* isL */);
17085 %}
17086 ins_pipe(pipe_class_memory);
17087 %}
17088
17089 instruct stringU_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
17090 iRegI_R0 result, vecA ztmp1, vecA ztmp2,
17091 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{
17092 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
17093 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
17094 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr);
17095 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %}
17096 ins_encode %{
17097 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register,
17098 $result$$Register, $ztmp1$$FloatRegister,
17099 $ztmp2$$FloatRegister, $pgtmp$$PRegister,
17100 $ptmp$$PRegister, false /* isL */);
17101 %}
17102 ins_pipe(pipe_class_memory);
17103 %}
17104
17105 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
17106 iRegI_R0 result, rFlagsReg cr)
17107 %{
17108 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
17109 match(Set result (StrEquals (Binary str1 str2) cnt));
17110 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
17111
17112 format %{ "String Equals $str1,$str2,$cnt -> $result" %}
17113 ins_encode %{
17114 // Count is in 8-bit bytes; non-Compact chars are 16 bits.
17115 __ string_equals($str1$$Register, $str2$$Register,
17116 $result$$Register, $cnt$$Register);
17117 %}
17118 ins_pipe(pipe_class_memory);
17119 %}
17120
17121 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
17122 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
17123 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3,
17124 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7,
17125 iRegP_R10 tmp, rFlagsReg cr)
17126 %{
17127 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
17128 match(Set result (AryEq ary1 ary2));
17129 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3,
17130 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5,
17131 TEMP vtmp6, TEMP vtmp7, KILL cr);
17132
17133 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %}
17134 ins_encode %{
17135 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
17136 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
17137 $result$$Register, $tmp$$Register, 1);
17138 if (tpc == nullptr) {
17139 ciEnv::current()->record_failure("CodeCache is full");
17140 return;
17141 }
17142 %}
17143 ins_pipe(pipe_class_memory);
17144 %}
17145
17146 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
17147 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
17148 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3,
17149 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7,
17150 iRegP_R10 tmp, rFlagsReg cr)
17151 %{
17152 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
17153 match(Set result (AryEq ary1 ary2));
17154 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3,
17155 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5,
17156 TEMP vtmp6, TEMP vtmp7, KILL cr);
17157
17158 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %}
17159 ins_encode %{
17160 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
17161 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
17162 $result$$Register, $tmp$$Register, 2);
17163 if (tpc == nullptr) {
17164 ciEnv::current()->record_failure("CodeCache is full");
17165 return;
17166 }
17167 %}
17168 ins_pipe(pipe_class_memory);
17169 %}
17170
17171 instruct arrays_hashcode(iRegP_R1 ary, iRegI_R2 cnt, iRegI_R0 result, immI basic_type,
17172 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3,
17173 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7,
17174 vRegD_V12 vtmp8, vRegD_V13 vtmp9, rFlagsReg cr)
17175 %{
17176 match(Set result (VectorizedHashCode (Binary ary cnt) (Binary result basic_type)));
17177 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, TEMP vtmp6,
17178 TEMP vtmp7, TEMP vtmp8, TEMP vtmp9, USE_KILL ary, USE_KILL cnt, USE basic_type, KILL cr);
17179
17180 format %{ "Array HashCode array[] $ary,$cnt,$result,$basic_type -> $result // KILL all" %}
17181 ins_encode %{
17182 address tpc = __ arrays_hashcode($ary$$Register, $cnt$$Register, $result$$Register,
17183 $vtmp3$$FloatRegister, $vtmp2$$FloatRegister,
17184 $vtmp1$$FloatRegister, $vtmp0$$FloatRegister,
17185 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister,
17186 $vtmp6$$FloatRegister, $vtmp7$$FloatRegister,
17187 $vtmp8$$FloatRegister, $vtmp9$$FloatRegister,
17188 (BasicType)$basic_type$$constant);
17189 if (tpc == nullptr) {
17190 ciEnv::current()->record_failure("CodeCache is full");
17191 return;
17192 }
17193 %}
17194 ins_pipe(pipe_class_memory);
17195 %}
17196
17197 instruct count_positives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr)
17198 %{
17199 match(Set result (CountPositives ary1 len));
17200 effect(USE_KILL ary1, USE_KILL len, KILL cr);
17201 format %{ "count positives byte[] $ary1,$len -> $result" %}
17202 ins_encode %{
17203 address tpc = __ count_positives($ary1$$Register, $len$$Register, $result$$Register);
17204 if (tpc == nullptr) {
17205 ciEnv::current()->record_failure("CodeCache is full");
17206 return;
17207 }
17208 %}
17209 ins_pipe( pipe_slow );
17210 %}
17211
17212 // fast char[] to byte[] compression
17213 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
17214 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2,
17215 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5,
17216 iRegI_R0 result, rFlagsReg cr)
17217 %{
17218 match(Set result (StrCompressedCopy src (Binary dst len)));
17219 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5,
17220 USE_KILL src, USE_KILL dst, USE len, KILL cr);
17221
17222 format %{ "String Compress $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %}
17223 ins_encode %{
17224 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
17225 $result$$Register, $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
17226 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister,
17227 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister);
17228 %}
17229 ins_pipe(pipe_slow);
17230 %}
17231
17232 // fast byte[] to char[] inflation
17233 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, iRegP_R3 tmp,
17234 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3,
17235 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, rFlagsReg cr)
17236 %{
17237 match(Set dummy (StrInflatedCopy src (Binary dst len)));
17238 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3,
17239 TEMP vtmp4, TEMP vtmp5, TEMP vtmp6, TEMP tmp,
17240 USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
17241
17242 format %{ "String Inflate $src,$dst # KILL $tmp $src $dst $len V0-V6 cr" %}
17243 ins_encode %{
17244 address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
17245 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
17246 $vtmp2$$FloatRegister, $tmp$$Register);
17247 if (tpc == nullptr) {
17248 ciEnv::current()->record_failure("CodeCache is full");
17249 return;
17250 }
17251 %}
17252 ins_pipe(pipe_class_memory);
17253 %}
17254
17255 // encode char[] to byte[] in ISO_8859_1
17256 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
17257 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2,
17258 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5,
17259 iRegI_R0 result, rFlagsReg cr)
17260 %{
17261 predicate(!((EncodeISOArrayNode*)n)->is_ascii());
17262 match(Set result (EncodeISOArray src (Binary dst len)));
17263 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1,
17264 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr);
17265
17266 format %{ "Encode ISO array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %}
17267 ins_encode %{
17268 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
17269 $result$$Register, false,
17270 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
17271 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister,
17272 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister);
17273 %}
17274 ins_pipe(pipe_class_memory);
17275 %}
17276
17277 instruct encode_ascii_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
17278 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2,
17279 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5,
17280 iRegI_R0 result, rFlagsReg cr)
17281 %{
17282 predicate(((EncodeISOArrayNode*)n)->is_ascii());
17283 match(Set result (EncodeISOArray src (Binary dst len)));
17284 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1,
17285 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr);
17286
17287 format %{ "Encode ASCII array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %}
17288 ins_encode %{
17289 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
17290 $result$$Register, true,
17291 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
17292 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister,
17293 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister);
17294 %}
17295 ins_pipe(pipe_class_memory);
17296 %}
17297
17298 //----------------------------- CompressBits/ExpandBits ------------------------
17299
17300 instruct compressBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask,
17301 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17302 match(Set dst (CompressBits src mask));
17303 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17304 format %{ "mov $tsrc, $src\n\t"
17305 "mov $tmask, $mask\n\t"
17306 "bext $tdst, $tsrc, $tmask\n\t"
17307 "mov $dst, $tdst"
17308 %}
17309 ins_encode %{
17310 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register);
17311 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register);
17312 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17313 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0);
17314 %}
17315 ins_pipe(pipe_slow);
17316 %}
17317
17318 instruct compressBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask,
17319 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17320 match(Set dst (CompressBits (LoadI mem) mask));
17321 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17322 format %{ "ldrs $tsrc, $mem\n\t"
17323 "ldrs $tmask, $mask\n\t"
17324 "bext $tdst, $tsrc, $tmask\n\t"
17325 "mov $dst, $tdst"
17326 %}
17327 ins_encode %{
17328 loadStore(masm, &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(),
17329 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
17330 __ ldrs($tmask$$FloatRegister, $constantaddress($mask));
17331 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17332 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0);
17333 %}
17334 ins_pipe(pipe_slow);
17335 %}
17336
17337 instruct compressBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask,
17338 vRegD tdst, vRegD tsrc, vRegD tmask) %{
17339 match(Set dst (CompressBits src mask));
17340 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17341 format %{ "mov $tsrc, $src\n\t"
17342 "mov $tmask, $mask\n\t"
17343 "bext $tdst, $tsrc, $tmask\n\t"
17344 "mov $dst, $tdst"
17345 %}
17346 ins_encode %{
17347 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register);
17348 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register);
17349 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17350 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0);
17351 %}
17352 ins_pipe(pipe_slow);
17353 %}
17354
17355 instruct compressBitsL_memcon(iRegLNoSp dst, memory8 mem, immL mask,
17356 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17357 match(Set dst (CompressBits (LoadL mem) mask));
17358 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17359 format %{ "ldrd $tsrc, $mem\n\t"
17360 "ldrd $tmask, $mask\n\t"
17361 "bext $tdst, $tsrc, $tmask\n\t"
17362 "mov $dst, $tdst"
17363 %}
17364 ins_encode %{
17365 loadStore(masm, &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(),
17366 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
17367 __ ldrd($tmask$$FloatRegister, $constantaddress($mask));
17368 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17369 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0);
17370 %}
17371 ins_pipe(pipe_slow);
17372 %}
17373
17374 instruct expandBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask,
17375 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17376 match(Set dst (ExpandBits src mask));
17377 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17378 format %{ "mov $tsrc, $src\n\t"
17379 "mov $tmask, $mask\n\t"
17380 "bdep $tdst, $tsrc, $tmask\n\t"
17381 "mov $dst, $tdst"
17382 %}
17383 ins_encode %{
17384 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register);
17385 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register);
17386 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17387 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0);
17388 %}
17389 ins_pipe(pipe_slow);
17390 %}
17391
17392 instruct expandBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask,
17393 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17394 match(Set dst (ExpandBits (LoadI mem) mask));
17395 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17396 format %{ "ldrs $tsrc, $mem\n\t"
17397 "ldrs $tmask, $mask\n\t"
17398 "bdep $tdst, $tsrc, $tmask\n\t"
17399 "mov $dst, $tdst"
17400 %}
17401 ins_encode %{
17402 loadStore(masm, &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(),
17403 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
17404 __ ldrs($tmask$$FloatRegister, $constantaddress($mask));
17405 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17406 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0);
17407 %}
17408 ins_pipe(pipe_slow);
17409 %}
17410
17411 instruct expandBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask,
17412 vRegD tdst, vRegD tsrc, vRegD tmask) %{
17413 match(Set dst (ExpandBits src mask));
17414 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17415 format %{ "mov $tsrc, $src\n\t"
17416 "mov $tmask, $mask\n\t"
17417 "bdep $tdst, $tsrc, $tmask\n\t"
17418 "mov $dst, $tdst"
17419 %}
17420 ins_encode %{
17421 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register);
17422 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register);
17423 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17424 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0);
17425 %}
17426 ins_pipe(pipe_slow);
17427 %}
17428
17429
17430 instruct expandBitsL_memcon(iRegINoSp dst, memory8 mem, immL mask,
17431 vRegF tdst, vRegF tsrc, vRegF tmask) %{
17432 match(Set dst (ExpandBits (LoadL mem) mask));
17433 effect(TEMP tdst, TEMP tsrc, TEMP tmask);
17434 format %{ "ldrd $tsrc, $mem\n\t"
17435 "ldrd $tmask, $mask\n\t"
17436 "bdep $tdst, $tsrc, $tmask\n\t"
17437 "mov $dst, $tdst"
17438 %}
17439 ins_encode %{
17440 loadStore(masm, &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(),
17441 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
17442 __ ldrd($tmask$$FloatRegister, $constantaddress($mask));
17443 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister);
17444 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0);
17445 %}
17446 ins_pipe(pipe_slow);
17447 %}
17448
17449 //----------------------------- Reinterpret ----------------------------------
17450 // Reinterpret a half-precision float value in a floating point register to a general purpose register
17451 instruct reinterpretHF2S(iRegINoSp dst, vRegF src) %{
17452 match(Set dst (ReinterpretHF2S src));
17453 format %{ "reinterpretHF2S $dst, $src" %}
17454 ins_encode %{
17455 __ smov($dst$$Register, $src$$FloatRegister, __ H, 0);
17456 %}
17457 ins_pipe(pipe_slow);
17458 %}
17459
17460 // Reinterpret a half-precision float value in a general purpose register to a floating point register
17461 instruct reinterpretS2HF(vRegF dst, iRegINoSp src) %{
17462 match(Set dst (ReinterpretS2HF src));
17463 format %{ "reinterpretS2HF $dst, $src" %}
17464 ins_encode %{
17465 __ mov($dst$$FloatRegister, __ H, 0, $src$$Register);
17466 %}
17467 ins_pipe(pipe_slow);
17468 %}
17469
17470 // Without this optimization, ReinterpretS2HF (ConvF2HF src) would result in the following
17471 // instructions (the first two are for ConvF2HF and the last instruction is for ReinterpretS2HF) -
17472 // fcvt $tmp1_fpr, $src_fpr // Convert float to half-precision float
17473 // mov $tmp2_gpr, $tmp1_fpr // Move half-precision float in FPR to a GPR
17474 // mov $dst_fpr, $tmp2_gpr // Move the result from a GPR to an FPR
17475 // The move from FPR to GPR in ConvF2HF and the move from GPR to FPR in ReinterpretS2HF
17476 // can be omitted in this pattern, resulting in -
17477 // fcvt $dst, $src // Convert float to half-precision float
17478 instruct convF2HFAndS2HF(vRegF dst, vRegF src)
17479 %{
17480 match(Set dst (ReinterpretS2HF (ConvF2HF src)));
17481 format %{ "convF2HFAndS2HF $dst, $src" %}
17482 ins_encode %{
17483 __ fcvtsh($dst$$FloatRegister, $src$$FloatRegister);
17484 %}
17485 ins_pipe(pipe_slow);
17486 %}
17487
17488 // Without this optimization, ConvHF2F (ReinterpretHF2S src) would result in the following
17489 // instructions (the first one is for ReinterpretHF2S and the last two are for ConvHF2F) -
17490 // mov $tmp1_gpr, $src_fpr // Move the half-precision float from an FPR to a GPR
17491 // mov $tmp2_fpr, $tmp1_gpr // Move the same value from GPR to an FPR
17492 // fcvt $dst_fpr, $tmp2_fpr // Convert the half-precision float to 32-bit float
17493 // The move from FPR to GPR in ReinterpretHF2S and the move from GPR to FPR in ConvHF2F
17494 // can be omitted as the input (src) is already in an FPR required for the fcvths instruction
17495 // resulting in -
17496 // fcvt $dst, $src // Convert half-precision float to a 32-bit float
17497 instruct convHF2SAndHF2F(vRegF dst, vRegF src)
17498 %{
17499 match(Set dst (ConvHF2F (ReinterpretHF2S src)));
17500 format %{ "convHF2SAndHF2F $dst, $src" %}
17501 ins_encode %{
17502 __ fcvths($dst$$FloatRegister, $src$$FloatRegister);
17503 %}
17504 ins_pipe(pipe_slow);
17505 %}
17506
17507 // ============================================================================
17508 // This name is KNOWN by the ADLC and cannot be changed.
17509 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
17510 // for this guy.
17511 instruct tlsLoadP(thread_RegP dst)
17512 %{
17513 match(Set dst (ThreadLocal));
17514
17515 ins_cost(0);
17516
17517 format %{ " -- \t// $dst=Thread::current(), empty" %}
17518
17519 size(0);
17520
17521 ins_encode( /*empty*/ );
17522
17523 ins_pipe(pipe_class_empty);
17524 %}
17525
17526 //----------PEEPHOLE RULES-----------------------------------------------------
17527 // These must follow all instruction definitions as they use the names
17528 // defined in the instructions definitions.
17529 //
17530 // peepmatch ( root_instr_name [preceding_instruction]* );
17531 //
17532 // peepconstraint %{
17533 // (instruction_number.operand_name relational_op instruction_number.operand_name
17534 // [, ...] );
17535 // // instruction numbers are zero-based using left to right order in peepmatch
17536 //
17537 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
17538 // // provide an instruction_number.operand_name for each operand that appears
17539 // // in the replacement instruction's match rule
17540 //
17541 // ---------VM FLAGS---------------------------------------------------------
17542 //
17543 // All peephole optimizations can be turned off using -XX:-OptoPeephole
17544 //
17545 // Each peephole rule is given an identifying number starting with zero and
17546 // increasing by one in the order seen by the parser. An individual peephole
17547 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
17548 // on the command-line.
17549 //
17550 // ---------CURRENT LIMITATIONS----------------------------------------------
17551 //
17552 // Only match adjacent instructions in same basic block
17553 // Only equality constraints
17554 // Only constraints between operands, not (0.dest_reg == RAX_enc)
17555 // Only one replacement instruction
17556 //
17557 // ---------EXAMPLE----------------------------------------------------------
17558 //
17559 // // pertinent parts of existing instructions in architecture description
17560 // instruct movI(iRegINoSp dst, iRegI src)
17561 // %{
17562 // match(Set dst (CopyI src));
17563 // %}
17564 //
17565 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr)
17566 // %{
17567 // match(Set dst (AddI dst src));
17568 // effect(KILL cr);
17569 // %}
17570 //
17571 // // Change (inc mov) to lea
17572 // peephole %{
17573 // // increment preceded by register-register move
17574 // peepmatch ( incI_iReg movI );
17575 // // require that the destination register of the increment
17576 // // match the destination register of the move
17577 // peepconstraint ( 0.dst == 1.dst );
17578 // // construct a replacement instruction that sets
17579 // // the destination to ( move's source register + one )
17580 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) );
17581 // %}
17582 //
17583
17584 // Implementation no longer uses movX instructions since
17585 // machine-independent system no longer uses CopyX nodes.
17586 //
17587 // peephole
17588 // %{
17589 // peepmatch (incI_iReg movI);
17590 // peepconstraint (0.dst == 1.dst);
17591 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
17592 // %}
17593
17594 // peephole
17595 // %{
17596 // peepmatch (decI_iReg movI);
17597 // peepconstraint (0.dst == 1.dst);
17598 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
17599 // %}
17600
17601 // peephole
17602 // %{
17603 // peepmatch (addI_iReg_imm movI);
17604 // peepconstraint (0.dst == 1.dst);
17605 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
17606 // %}
17607
17608 // peephole
17609 // %{
17610 // peepmatch (incL_iReg movL);
17611 // peepconstraint (0.dst == 1.dst);
17612 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
17613 // %}
17614
17615 // peephole
17616 // %{
17617 // peepmatch (decL_iReg movL);
17618 // peepconstraint (0.dst == 1.dst);
17619 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
17620 // %}
17621
17622 // peephole
17623 // %{
17624 // peepmatch (addL_iReg_imm movL);
17625 // peepconstraint (0.dst == 1.dst);
17626 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
17627 // %}
17628
17629 // peephole
17630 // %{
17631 // peepmatch (addP_iReg_imm movP);
17632 // peepconstraint (0.dst == 1.dst);
17633 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src));
17634 // %}
17635
17636 // // Change load of spilled value to only a spill
17637 // instruct storeI(memory mem, iRegI src)
17638 // %{
17639 // match(Set mem (StoreI mem src));
17640 // %}
17641 //
17642 // instruct loadI(iRegINoSp dst, memory mem)
17643 // %{
17644 // match(Set dst (LoadI mem));
17645 // %}
17646 //
17647
17648 //----------SMARTSPILL RULES---------------------------------------------------
17649 // These must follow all instruction definitions as they use the names
17650 // defined in the instructions definitions.
17651
17652 // Local Variables:
17653 // mode: c++
17654 // End: