1//
2// Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3// Copyright (c) 2014, 2021, 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// archtecture.
32
33register %{
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
81reg_def R0      ( SOC, SOC, Op_RegI,  0, r0->as_VMReg()         );
82reg_def R0_H    ( SOC, SOC, Op_RegI,  0, r0->as_VMReg()->next() );
83reg_def R1      ( SOC, SOC, Op_RegI,  1, r1->as_VMReg()         );
84reg_def R1_H    ( SOC, SOC, Op_RegI,  1, r1->as_VMReg()->next() );
85reg_def R2      ( SOC, SOC, Op_RegI,  2, r2->as_VMReg()         );
86reg_def R2_H    ( SOC, SOC, Op_RegI,  2, r2->as_VMReg()->next() );
87reg_def R3      ( SOC, SOC, Op_RegI,  3, r3->as_VMReg()         );
88reg_def R3_H    ( SOC, SOC, Op_RegI,  3, r3->as_VMReg()->next() );
89reg_def R4      ( SOC, SOC, Op_RegI,  4, r4->as_VMReg()         );
90reg_def R4_H    ( SOC, SOC, Op_RegI,  4, r4->as_VMReg()->next() );
91reg_def R5      ( SOC, SOC, Op_RegI,  5, r5->as_VMReg()         );
92reg_def R5_H    ( SOC, SOC, Op_RegI,  5, r5->as_VMReg()->next() );
93reg_def R6      ( SOC, SOC, Op_RegI,  6, r6->as_VMReg()         );
94reg_def R6_H    ( SOC, SOC, Op_RegI,  6, r6->as_VMReg()->next() );
95reg_def R7      ( SOC, SOC, Op_RegI,  7, r7->as_VMReg()         );
96reg_def R7_H    ( SOC, SOC, Op_RegI,  7, r7->as_VMReg()->next() );
97reg_def R8      ( NS,  SOC, Op_RegI,  8, r8->as_VMReg()         ); // rscratch1, non-allocatable
98reg_def R8_H    ( NS,  SOC, Op_RegI,  8, r8->as_VMReg()->next() );
99reg_def R9      ( NS,  SOC, Op_RegI,  9, r9->as_VMReg()         ); // rscratch2, non-allocatable
100reg_def R9_H    ( NS,  SOC, Op_RegI,  9, r9->as_VMReg()->next() );
101reg_def R10     ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()        );
102reg_def R10_H   ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
103reg_def R11     ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()        );
104reg_def R11_H   ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
105reg_def R12     ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()        );
106reg_def R12_H   ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next());
107reg_def R13     ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()        );
108reg_def R13_H   ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next());
109reg_def R14     ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()        );
110reg_def R14_H   ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next());
111reg_def R15     ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()        );
112reg_def R15_H   ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next());
113reg_def R16     ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()        );
114reg_def R16_H   ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next());
115reg_def R17     ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()        );
116reg_def R17_H   ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next());
117reg_def R18     ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg()        );
118reg_def R18_H   ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg()->next());
119reg_def R19     ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()        );
120reg_def R19_H   ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next());
121reg_def R20     ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()        ); // caller esp
122reg_def R20_H   ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next());
123reg_def R21     ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()        );
124reg_def R21_H   ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next());
125reg_def R22     ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()        );
126reg_def R22_H   ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next());
127reg_def R23     ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()        );
128reg_def R23_H   ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next());
129reg_def R24     ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()        );
130reg_def R24_H   ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next());
131reg_def R25     ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()        );
132reg_def R25_H   ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next());
133reg_def R26     ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()        );
134reg_def R26_H   ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next());
135reg_def R27     ( SOC, SOE, Op_RegI, 27, r27->as_VMReg()        ); // heapbase
136reg_def R27_H   ( SOC, SOE, Op_RegI, 27, r27->as_VMReg()->next());
137reg_def R28     (  NS, SOE, Op_RegI, 28, r28->as_VMReg()        ); // thread
138reg_def R28_H   (  NS, SOE, Op_RegI, 28, r28->as_VMReg()->next());
139reg_def R29     (  NS,  NS, Op_RegI, 29, r29->as_VMReg()        ); // fp
140reg_def R29_H   (  NS,  NS, Op_RegI, 29, r29->as_VMReg()->next());
141reg_def R30     (  NS,  NS, Op_RegI, 30, r30->as_VMReg()        ); // lr
142reg_def R30_H   (  NS,  NS, Op_RegI, 30, r30->as_VMReg()->next());
143reg_def R31     (  NS,  NS, Op_RegI, 31, r31_sp->as_VMReg()     ); // sp
144reg_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  reg_def V0_L ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(4) );
183  reg_def V0_M ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(5) );
184  reg_def V0_N ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(6) );
185  reg_def V0_O ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(7) );
186
187  reg_def V1   ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()          );
188  reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next()  );
189  reg_def V1_J ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(2) );
190  reg_def V1_K ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(3) );
191  reg_def V1_L ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(4) );
192  reg_def V1_M ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(5) );
193  reg_def V1_N ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(6) );
194  reg_def V1_O ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(7) );
195
196  reg_def V2   ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()          );
197  reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next()  );
198  reg_def V2_J ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(2) );
199  reg_def V2_K ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(3) );
200  reg_def V2_L ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(4) );
201  reg_def V2_M ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(5) );
202  reg_def V2_N ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(6) );
203  reg_def V2_O ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(7) );
204
205  reg_def V3   ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()          );
206  reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next()  );
207  reg_def V3_J ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(2) );
208  reg_def V3_K ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(3) );
209  reg_def V3_L ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(4) );
210  reg_def V3_M ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(5) );
211  reg_def V3_N ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(6) );
212  reg_def V3_O ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(7) );
213
214  reg_def V4   ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()          );
215  reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next()  );
216  reg_def V4_J ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(2) );
217  reg_def V4_K ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(3) );
218  reg_def V4_L ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(4) );
219  reg_def V4_M ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(5) );
220  reg_def V4_N ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(6) );
221  reg_def V4_O ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(7) );
222
223  reg_def V5   ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()          );
224  reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next()  );
225  reg_def V5_J ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(2) );
226  reg_def V5_K ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(3) );
227  reg_def V5_L ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(4) );
228  reg_def V5_M ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(5) );
229  reg_def V5_N ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(6) );
230  reg_def V5_O ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(7) );
231
232  reg_def V6   ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()          );
233  reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next()  );
234  reg_def V6_J ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(2) );
235  reg_def V6_K ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(3) );
236  reg_def V6_L ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(4) );
237  reg_def V6_M ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(5) );
238  reg_def V6_N ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(6) );
239  reg_def V6_O ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(7) );
240
241  reg_def V7   ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()          );
242  reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next()  );
243  reg_def V7_J ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(2) );
244  reg_def V7_K ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(3) );
245  reg_def V7_L ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(4) );
246  reg_def V7_M ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(5) );
247  reg_def V7_N ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(6) );
248  reg_def V7_O ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(7) );
249
250  reg_def V8   ( SOC, SOE, Op_RegF, 8, v8->as_VMReg()          );
251  reg_def V8_H ( SOC, SOE, Op_RegF, 8, v8->as_VMReg()->next()  );
252  reg_def V8_J ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(2) );
253  reg_def V8_K ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(3) );
254  reg_def V8_L ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(4) );
255  reg_def V8_M ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(5) );
256  reg_def V8_N ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(6) );
257  reg_def V8_O ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(7) );
258
259  reg_def V9   ( SOC, SOE, Op_RegF, 9, v9->as_VMReg()          );
260  reg_def V9_H ( SOC, SOE, Op_RegF, 9, v9->as_VMReg()->next()  );
261  reg_def V9_J ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(2) );
262  reg_def V9_K ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(3) );
263  reg_def V9_L ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(4) );
264  reg_def V9_M ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(5) );
265  reg_def V9_N ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(6) );
266  reg_def V9_O ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(7) );
267
268  reg_def V10   ( SOC, SOE, Op_RegF, 10, v10->as_VMReg()          );
269  reg_def V10_H ( SOC, SOE, Op_RegF, 10, v10->as_VMReg()->next()  );
270  reg_def V10_J ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2) );
271  reg_def V10_K ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3) );
272  reg_def V10_L ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(4) );
273  reg_def V10_M ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(5) );
274  reg_def V10_N ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(6) );
275  reg_def V10_O ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(7) );
276
277  reg_def V11   ( SOC, SOE, Op_RegF, 11, v11->as_VMReg()          );
278  reg_def V11_H ( SOC, SOE, Op_RegF, 11, v11->as_VMReg()->next()  );
279  reg_def V11_J ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2) );
280  reg_def V11_K ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3) );
281  reg_def V11_L ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(4) );
282  reg_def V11_M ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(5) );
283  reg_def V11_N ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(6) );
284  reg_def V11_O ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(7) );
285
286  reg_def V12   ( SOC, SOE, Op_RegF, 12, v12->as_VMReg()          );
287  reg_def V12_H ( SOC, SOE, Op_RegF, 12, v12->as_VMReg()->next()  );
288  reg_def V12_J ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2) );
289  reg_def V12_K ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3) );
290  reg_def V12_L ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(4) );
291  reg_def V12_M ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(5) );
292  reg_def V12_N ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(6) );
293  reg_def V12_O ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(7) );
294
295  reg_def V13   ( SOC, SOE, Op_RegF, 13, v13->as_VMReg()          );
296  reg_def V13_H ( SOC, SOE, Op_RegF, 13, v13->as_VMReg()->next()  );
297  reg_def V13_J ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2) );
298  reg_def V13_K ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3) );
299  reg_def V13_L ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(4) );
300  reg_def V13_M ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(5) );
301  reg_def V13_N ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(6) );
302  reg_def V13_O ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(7) );
303
304  reg_def V14   ( SOC, SOE, Op_RegF, 14, v14->as_VMReg()          );
305  reg_def V14_H ( SOC, SOE, Op_RegF, 14, v14->as_VMReg()->next()  );
306  reg_def V14_J ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2) );
307  reg_def V14_K ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3) );
308  reg_def V14_L ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(4) );
309  reg_def V14_M ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(5) );
310  reg_def V14_N ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(6) );
311  reg_def V14_O ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(7) );
312
313  reg_def V15   ( SOC, SOE, Op_RegF, 15, v15->as_VMReg()          );
314  reg_def V15_H ( SOC, SOE, Op_RegF, 15, v15->as_VMReg()->next()  );
315  reg_def V15_J ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2) );
316  reg_def V15_K ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3) );
317  reg_def V15_L ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(4) );
318  reg_def V15_M ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(5) );
319  reg_def V15_N ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(6) );
320  reg_def V15_O ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(7) );
321
322  reg_def V16   ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()          );
323  reg_def V16_H ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next()  );
324  reg_def V16_J ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2) );
325  reg_def V16_K ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3) );
326  reg_def V16_L ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(4) );
327  reg_def V16_M ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(5) );
328  reg_def V16_N ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(6) );
329  reg_def V16_O ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(7) );
330
331  reg_def V17   ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()          );
332  reg_def V17_H ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next()  );
333  reg_def V17_J ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2) );
334  reg_def V17_K ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3) );
335  reg_def V17_L ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(4) );
336  reg_def V17_M ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(5) );
337  reg_def V17_N ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(6) );
338  reg_def V17_O ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(7) );
339
340  reg_def V18   ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()          );
341  reg_def V18_H ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next()  );
342  reg_def V18_J ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2) );
343  reg_def V18_K ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3) );
344  reg_def V18_L ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(4) );
345  reg_def V18_M ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(5) );
346  reg_def V18_N ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(6) );
347  reg_def V18_O ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(7) );
348
349  reg_def V19   ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()          );
350  reg_def V19_H ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next()  );
351  reg_def V19_J ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2) );
352  reg_def V19_K ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3) );
353  reg_def V19_L ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(4) );
354  reg_def V19_M ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(5) );
355  reg_def V19_N ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(6) );
356  reg_def V19_O ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(7) );
357
358  reg_def V20   ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()          );
359  reg_def V20_H ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next()  );
360  reg_def V20_J ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2) );
361  reg_def V20_K ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3) );
362  reg_def V20_L ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(4) );
363  reg_def V20_M ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(5) );
364  reg_def V20_N ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(6) );
365  reg_def V20_O ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(7) );
366
367  reg_def V21   ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()          );
368  reg_def V21_H ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next()  );
369  reg_def V21_J ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2) );
370  reg_def V21_K ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3) );
371  reg_def V21_L ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(4) );
372  reg_def V21_M ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(5) );
373  reg_def V21_N ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(6) );
374  reg_def V21_O ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(7) );
375
376  reg_def V22   ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()          );
377  reg_def V22_H ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next()  );
378  reg_def V22_J ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2) );
379  reg_def V22_K ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3) );
380  reg_def V22_L ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(4) );
381  reg_def V22_M ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(5) );
382  reg_def V22_N ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(6) );
383  reg_def V22_O ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(7) );
384
385  reg_def V23   ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()          );
386  reg_def V23_H ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next()  );
387  reg_def V23_J ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2) );
388  reg_def V23_K ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3) );
389  reg_def V23_L ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(4) );
390  reg_def V23_M ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(5) );
391  reg_def V23_N ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(6) );
392  reg_def V23_O ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(7) );
393
394  reg_def V24   ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()          );
395  reg_def V24_H ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next()  );
396  reg_def V24_J ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2) );
397  reg_def V24_K ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3) );
398  reg_def V24_L ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(4) );
399  reg_def V24_M ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(5) );
400  reg_def V24_N ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(6) );
401  reg_def V24_O ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(7) );
402
403  reg_def V25   ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()          );
404  reg_def V25_H ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next()  );
405  reg_def V25_J ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2) );
406  reg_def V25_K ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3) );
407  reg_def V25_L ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(4) );
408  reg_def V25_M ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(5) );
409  reg_def V25_N ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(6) );
410  reg_def V25_O ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(7) );
411
412  reg_def V26   ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()          );
413  reg_def V26_H ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next()  );
414  reg_def V26_J ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2) );
415  reg_def V26_K ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3) );
416  reg_def V26_L ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(4) );
417  reg_def V26_M ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(5) );
418  reg_def V26_N ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(6) );
419  reg_def V26_O ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(7) );
420
421  reg_def V27   ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()          );
422  reg_def V27_H ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next()  );
423  reg_def V27_J ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2) );
424  reg_def V27_K ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3) );
425  reg_def V27_L ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(4) );
426  reg_def V27_M ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(5) );
427  reg_def V27_N ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(6) );
428  reg_def V27_O ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(7) );
429
430  reg_def V28   ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()          );
431  reg_def V28_H ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next()  );
432  reg_def V28_J ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2) );
433  reg_def V28_K ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3) );
434  reg_def V28_L ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(4) );
435  reg_def V28_M ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(5) );
436  reg_def V28_N ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(6) );
437  reg_def V28_O ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(7) );
438
439  reg_def V29   ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()          );
440  reg_def V29_H ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next()  );
441  reg_def V29_J ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2) );
442  reg_def V29_K ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3) );
443  reg_def V29_L ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(4) );
444  reg_def V29_M ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(5) );
445  reg_def V29_N ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(6) );
446  reg_def V29_O ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(7) );
447
448  reg_def V30   ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()          );
449  reg_def V30_H ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next()  );
450  reg_def V30_J ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2) );
451  reg_def V30_K ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3) );
452  reg_def V30_L ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(4) );
453  reg_def V30_M ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(5) );
454  reg_def V30_N ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(6) );
455  reg_def V30_O ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(7) );
456
457  reg_def V31   ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()          );
458  reg_def V31_H ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next()  );
459  reg_def V31_J ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2) );
460  reg_def V31_K ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3) );
461  reg_def V31_L ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(4) );
462  reg_def V31_M ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(5) );
463  reg_def V31_N ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(6) );
464  reg_def V31_O ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(7) );
465
466
467// ----------------------------
468// SVE Predicate Registers
469// ----------------------------
470  reg_def P0 (SOC, SOC, Op_RegVectMask, 0, p0->as_VMReg());
471  reg_def P1 (SOC, SOC, Op_RegVectMask, 1, p1->as_VMReg());
472  reg_def P2 (SOC, SOC, Op_RegVectMask, 2, p2->as_VMReg());
473  reg_def P3 (SOC, SOC, Op_RegVectMask, 3, p3->as_VMReg());
474  reg_def P4 (SOC, SOC, Op_RegVectMask, 4, p4->as_VMReg());
475  reg_def P5 (SOC, SOC, Op_RegVectMask, 5, p5->as_VMReg());
476  reg_def P6 (SOC, SOC, Op_RegVectMask, 6, p6->as_VMReg());
477  reg_def P7 (SOC, SOC, Op_RegVectMask, 7, p7->as_VMReg());
478  reg_def P8 (SOC, SOC, Op_RegVectMask, 8, p8->as_VMReg());
479  reg_def P9 (SOC, SOC, Op_RegVectMask, 9, p9->as_VMReg());
480  reg_def P10 (SOC, SOC, Op_RegVectMask, 10, p10->as_VMReg());
481  reg_def P11 (SOC, SOC, Op_RegVectMask, 11, p11->as_VMReg());
482  reg_def P12 (SOC, SOC, Op_RegVectMask, 12, p12->as_VMReg());
483  reg_def P13 (SOC, SOC, Op_RegVectMask, 13, p13->as_VMReg());
484  reg_def P14 (SOC, SOC, Op_RegVectMask, 14, p14->as_VMReg());
485  reg_def P15 (SOC, SOC, Op_RegVectMask, 15, p15->as_VMReg());
486
487// ----------------------------
488// Special Registers
489// ----------------------------
490
491// the AArch64 CSPR status flag register is not directly acessible as
492// instruction operand. the FPSR status flag register is a system
493// register which can be written/read using MSR/MRS but again does not
494// appear as an operand (a code identifying the FSPR occurs as an
495// immediate value in the instruction).
496
497reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad());
498
499// Specify priority of register selection within phases of register
500// allocation.  Highest priority is first.  A useful heuristic is to
501// give registers a low priority when they are required by machine
502// instructions, like EAX and EDX on I486, and choose no-save registers
503// before save-on-call, & save-on-call before save-on-entry.  Registers
504// which participate in fixed calling sequences should come last.
505// Registers which are used as pairs must fall on an even boundary.
506
507alloc_class chunk0(
508    // volatiles
509    R10, R10_H,
510    R11, R11_H,
511    R12, R12_H,
512    R13, R13_H,
513    R14, R14_H,
514    R15, R15_H,
515    R16, R16_H,
516    R17, R17_H,
517    R18, R18_H,
518
519    // arg registers
520    R0, R0_H,
521    R1, R1_H,
522    R2, R2_H,
523    R3, R3_H,
524    R4, R4_H,
525    R5, R5_H,
526    R6, R6_H,
527    R7, R7_H,
528
529    // non-volatiles
530    R19, R19_H,
531    R20, R20_H,
532    R21, R21_H,
533    R22, R22_H,
534    R23, R23_H,
535    R24, R24_H,
536    R25, R25_H,
537    R26, R26_H,
538
539    // non-allocatable registers
540
541    R27, R27_H, // heapbase
542    R28, R28_H, // thread
543    R29, R29_H, // fp
544    R30, R30_H, // lr
545    R31, R31_H, // sp
546    R8, R8_H,   // rscratch1
547    R9, R9_H,   // rscratch2
548);
549
550alloc_class chunk1(
551
552    // no save
553    V16, V16_H, V16_J, V16_K, V16_L, V16_M, V16_N, V16_O,
554    V17, V17_H, V17_J, V17_K, V17_L, V17_M, V17_N, V17_O,
555    V18, V18_H, V18_J, V18_K, V18_L, V18_M, V18_N, V18_O,
556    V19, V19_H, V19_J, V19_K, V19_L, V19_M, V19_N, V19_O,
557    V20, V20_H, V20_J, V20_K, V20_L, V20_M, V20_N, V20_O,
558    V21, V21_H, V21_J, V21_K, V21_L, V21_M, V21_N, V21_O,
559    V22, V22_H, V22_J, V22_K, V22_L, V22_M, V22_N, V22_O,
560    V23, V23_H, V23_J, V23_K, V23_L, V23_M, V23_N, V23_O,
561    V24, V24_H, V24_J, V24_K, V24_L, V24_M, V24_N, V24_O,
562    V25, V25_H, V25_J, V25_K, V25_L, V25_M, V25_N, V25_O,
563    V26, V26_H, V26_J, V26_K, V26_L, V26_M, V26_N, V26_O,
564    V27, V27_H, V27_J, V27_K, V27_L, V27_M, V27_N, V27_O,
565    V28, V28_H, V28_J, V28_K, V28_L, V28_M, V28_N, V28_O,
566    V29, V29_H, V29_J, V29_K, V29_L, V29_M, V29_N, V29_O,
567    V30, V30_H, V30_J, V30_K, V30_L, V30_M, V30_N, V30_O,
568    V31, V31_H, V31_J, V31_K, V31_L, V31_M, V31_N, V31_O,
569
570    // arg registers
571    V0, V0_H, V0_J, V0_K, V0_L, V0_M, V0_N, V0_O,
572    V1, V1_H, V1_J, V1_K, V1_L, V1_M, V1_N, V1_O,
573    V2, V2_H, V2_J, V2_K, V2_L, V2_M, V2_N, V2_O,
574    V3, V3_H, V3_J, V3_K, V3_L, V3_M, V3_N, V3_O,
575    V4, V4_H, V4_J, V4_K, V4_L, V4_M, V4_N, V4_O,
576    V5, V5_H, V5_J, V5_K, V5_L, V5_M, V5_N, V5_O,
577    V6, V6_H, V6_J, V6_K, V6_L, V6_M, V6_N, V6_O,
578    V7, V7_H, V7_J, V7_K, V7_L, V7_M, V7_N, V7_O,
579
580    // non-volatiles
581    V8, V8_H, V8_J, V8_K, V8_L, V8_M, V8_N, V8_O,
582    V9, V9_H, V9_J, V9_K, V9_L, V9_M, V9_N, V9_O,
583    V10, V10_H, V10_J, V10_K, V10_L, V10_M, V10_N, V10_O,
584    V11, V11_H, V11_J, V11_K, V11_L, V11_M, V11_N, V11_O,
585    V12, V12_H, V12_J, V12_K, V12_L, V12_M, V12_N, V12_O,
586    V13, V13_H, V13_J, V13_K, V13_L, V13_M, V13_N, V13_O,
587    V14, V14_H, V14_J, V14_K, V14_L, V14_M, V14_N, V14_O,
588    V15, V15_H, V15_J, V15_K, V15_L, V15_M, V15_N, V15_O,
589);
590
591alloc_class chunk2 (
592    P0,
593    P1,
594    P2,
595    P3,
596    P4,
597    P5,
598    P6,
599    P7,
600
601    P8,
602    P9,
603    P10,
604    P11,
605    P12,
606    P13,
607    P14,
608    P15,
609);
610
611alloc_class chunk3(RFLAGS);
612
613//----------Architecture Description Register Classes--------------------------
614// Several register classes are automatically defined based upon information in
615// this architecture description.
616// 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
617// 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
618//
619
620// Class for all 32 bit general purpose registers
621reg_class all_reg32(
622    R0,
623    R1,
624    R2,
625    R3,
626    R4,
627    R5,
628    R6,
629    R7,
630    R10,
631    R11,
632    R12,
633    R13,
634    R14,
635    R15,
636    R16,
637    R17,
638    R18,
639    R19,
640    R20,
641    R21,
642    R22,
643    R23,
644    R24,
645    R25,
646    R26,
647    R27,
648    R28,
649    R29,
650    R30,
651    R31
652);
653
654
655// Class for all 32 bit integer registers (excluding SP which
656// will never be used as an integer register)
657reg_class any_reg32 %{
658  return _ANY_REG32_mask;
659%}
660
661// Singleton class for R0 int register
662reg_class int_r0_reg(R0);
663
664// Singleton class for R2 int register
665reg_class int_r2_reg(R2);
666
667// Singleton class for R3 int register
668reg_class int_r3_reg(R3);
669
670// Singleton class for R4 int register
671reg_class int_r4_reg(R4);
672
673// Singleton class for R31 int register
674reg_class int_r31_reg(R31);
675
676// Class for all 64 bit general purpose registers
677reg_class all_reg(
678    R0, R0_H,
679    R1, R1_H,
680    R2, R2_H,
681    R3, R3_H,
682    R4, R4_H,
683    R5, R5_H,
684    R6, R6_H,
685    R7, R7_H,
686    R10, R10_H,
687    R11, R11_H,
688    R12, R12_H,
689    R13, R13_H,
690    R14, R14_H,
691    R15, R15_H,
692    R16, R16_H,
693    R17, R17_H,
694    R18, R18_H,
695    R19, R19_H,
696    R20, R20_H,
697    R21, R21_H,
698    R22, R22_H,
699    R23, R23_H,
700    R24, R24_H,
701    R25, R25_H,
702    R26, R26_H,
703    R27, R27_H,
704    R28, R28_H,
705    R29, R29_H,
706    R30, R30_H,
707    R31, R31_H
708);
709
710// Class for all long integer registers (including SP)
711reg_class any_reg %{
712  return _ANY_REG_mask;
713%}
714
715// Class for non-allocatable 32 bit registers
716reg_class non_allocatable_reg32(
717#ifdef R18_RESERVED
718    // See comment in register_aarch64.hpp
719    R18,                        // tls on Windows
720#endif
721    R28,                        // thread
722    R30,                        // lr
723    R31                         // sp
724);
725
726// Class for non-allocatable 64 bit registers
727reg_class non_allocatable_reg(
728#ifdef R18_RESERVED
729    // See comment in register_aarch64.hpp
730    R18, R18_H,                 // tls on Windows, platform register on macOS
731#endif
732    R28, R28_H,                 // thread
733    R30, R30_H,                 // lr
734    R31, R31_H                  // sp
735);
736
737// Class for all non-special integer registers
738reg_class no_special_reg32 %{
739  return _NO_SPECIAL_REG32_mask;
740%}
741
742// Class for all non-special long integer registers
743reg_class no_special_reg %{
744  return _NO_SPECIAL_REG_mask;
745%}
746
747// Class for 64 bit register r0
748reg_class r0_reg(
749    R0, R0_H
750);
751
752// Class for 64 bit register r1
753reg_class r1_reg(
754    R1, R1_H
755);
756
757// Class for 64 bit register r2
758reg_class r2_reg(
759    R2, R2_H
760);
761
762// Class for 64 bit register r3
763reg_class r3_reg(
764    R3, R3_H
765);
766
767// Class for 64 bit register r4
768reg_class r4_reg(
769    R4, R4_H
770);
771
772// Class for 64 bit register r5
773reg_class r5_reg(
774    R5, R5_H
775);
776
777// Class for 64 bit register r10
778reg_class r10_reg(
779    R10, R10_H
780);
781
782// Class for 64 bit register r11
783reg_class r11_reg(
784    R11, R11_H
785);
786
787// Class for method register
788reg_class method_reg(
789    R12, R12_H
790);
791
792// Class for heapbase register
793reg_class heapbase_reg(
794    R27, R27_H
795);
796
797// Class for thread register
798reg_class thread_reg(
799    R28, R28_H
800);
801
802// Class for frame pointer register
803reg_class fp_reg(
804    R29, R29_H
805);
806
807// Class for link register
808reg_class lr_reg(
809    R30, R30_H
810);
811
812// Class for long sp register
813reg_class sp_reg(
814  R31, R31_H
815);
816
817// Class for all pointer registers
818reg_class ptr_reg %{
819  return _PTR_REG_mask;
820%}
821
822// Class for all non_special pointer registers
823reg_class no_special_ptr_reg %{
824  return _NO_SPECIAL_PTR_REG_mask;
825%}
826
827// Class for all float registers
828reg_class float_reg(
829    V0,
830    V1,
831    V2,
832    V3,
833    V4,
834    V5,
835    V6,
836    V7,
837    V8,
838    V9,
839    V10,
840    V11,
841    V12,
842    V13,
843    V14,
844    V15,
845    V16,
846    V17,
847    V18,
848    V19,
849    V20,
850    V21,
851    V22,
852    V23,
853    V24,
854    V25,
855    V26,
856    V27,
857    V28,
858    V29,
859    V30,
860    V31
861);
862
863// Double precision float registers have virtual `high halves' that
864// are needed by the allocator.
865// Class for all double registers
866reg_class double_reg(
867    V0, V0_H,
868    V1, V1_H,
869    V2, V2_H,
870    V3, V3_H,
871    V4, V4_H,
872    V5, V5_H,
873    V6, V6_H,
874    V7, V7_H,
875    V8, V8_H,
876    V9, V9_H,
877    V10, V10_H,
878    V11, V11_H,
879    V12, V12_H,
880    V13, V13_H,
881    V14, V14_H,
882    V15, V15_H,
883    V16, V16_H,
884    V17, V17_H,
885    V18, V18_H,
886    V19, V19_H,
887    V20, V20_H,
888    V21, V21_H,
889    V22, V22_H,
890    V23, V23_H,
891    V24, V24_H,
892    V25, V25_H,
893    V26, V26_H,
894    V27, V27_H,
895    V28, V28_H,
896    V29, V29_H,
897    V30, V30_H,
898    V31, V31_H
899);
900
901// Class for all SVE vector registers.
902reg_class vectora_reg (
903    V0, V0_H, V0_J, V0_K, V0_L, V0_M, V0_N, V0_O,
904    V1, V1_H, V1_J, V1_K, V1_L, V1_M, V1_N, V1_O,
905    V2, V2_H, V2_J, V2_K, V2_L, V2_M, V2_N, V2_O,
906    V3, V3_H, V3_J, V3_K, V3_L, V3_M, V3_N, V3_O,
907    V4, V4_H, V4_J, V4_K, V4_L, V4_M, V4_N, V4_O,
908    V5, V5_H, V5_J, V5_K, V5_L, V5_M, V5_N, V5_O,
909    V6, V6_H, V6_J, V6_K, V6_L, V6_M, V6_N, V6_O,
910    V7, V7_H, V7_J, V7_K, V7_L, V7_M, V7_N, V7_O,
911    V8, V8_H, V8_J, V8_K, V8_L, V8_M, V8_N, V8_O,
912    V9, V9_H, V9_J, V9_K, V9_L, V9_M, V9_N, V9_O,
913    V10, V10_H, V10_J, V10_K, V10_L, V10_M, V10_N, V10_O,
914    V11, V11_H, V11_J, V11_K, V11_L, V11_M, V11_N, V11_O,
915    V12, V12_H, V12_J, V12_K, V12_L, V12_M, V12_N, V12_O,
916    V13, V13_H, V13_J, V13_K, V13_L, V13_M, V13_N, V13_O,
917    V14, V14_H, V14_J, V14_K, V14_L, V14_M, V14_N, V14_O,
918    V15, V15_H, V15_J, V15_K, V15_L, V15_M, V15_N, V15_O,
919    V16, V16_H, V16_J, V16_K, V16_L, V16_M, V16_N, V16_O,
920    V17, V17_H, V17_J, V17_K, V17_L, V17_M, V17_N, V17_O,
921    V18, V18_H, V18_J, V18_K, V18_L, V18_M, V18_N, V18_O,
922    V19, V19_H, V19_J, V19_K, V19_L, V19_M, V19_N, V19_O,
923    V20, V20_H, V20_J, V20_K, V20_L, V20_M, V20_N, V20_O,
924    V21, V21_H, V21_J, V21_K, V21_L, V21_M, V21_N, V21_O,
925    V22, V22_H, V22_J, V22_K, V22_L, V22_M, V22_N, V22_O,
926    V23, V23_H, V23_J, V23_K, V23_L, V23_M, V23_N, V23_O,
927    V24, V24_H, V24_J, V24_K, V24_L, V24_M, V24_N, V24_O,
928    V25, V25_H, V25_J, V25_K, V25_L, V25_M, V25_N, V25_O,
929    V26, V26_H, V26_J, V26_K, V26_L, V26_M, V26_N, V26_O,
930    V27, V27_H, V27_J, V27_K, V27_L, V27_M, V27_N, V27_O,
931    V28, V28_H, V28_J, V28_K, V28_L, V28_M, V28_N, V28_O,
932    V29, V29_H, V29_J, V29_K, V29_L, V29_M, V29_N, V29_O,
933    V30, V30_H, V30_J, V30_K, V30_L, V30_M, V30_N, V30_O,
934    V31, V31_H, V31_J, V31_K, V31_L, V31_M, V31_N, V31_O,
935);
936
937// Class for all 64bit vector registers
938reg_class vectord_reg(
939    V0, V0_H,
940    V1, V1_H,
941    V2, V2_H,
942    V3, V3_H,
943    V4, V4_H,
944    V5, V5_H,
945    V6, V6_H,
946    V7, V7_H,
947    V8, V8_H,
948    V9, V9_H,
949    V10, V10_H,
950    V11, V11_H,
951    V12, V12_H,
952    V13, V13_H,
953    V14, V14_H,
954    V15, V15_H,
955    V16, V16_H,
956    V17, V17_H,
957    V18, V18_H,
958    V19, V19_H,
959    V20, V20_H,
960    V21, V21_H,
961    V22, V22_H,
962    V23, V23_H,
963    V24, V24_H,
964    V25, V25_H,
965    V26, V26_H,
966    V27, V27_H,
967    V28, V28_H,
968    V29, V29_H,
969    V30, V30_H,
970    V31, V31_H
971);
972
973// Class for all 128bit vector registers
974reg_class vectorx_reg(
975    V0, V0_H, V0_J, V0_K,
976    V1, V1_H, V1_J, V1_K,
977    V2, V2_H, V2_J, V2_K,
978    V3, V3_H, V3_J, V3_K,
979    V4, V4_H, V4_J, V4_K,
980    V5, V5_H, V5_J, V5_K,
981    V6, V6_H, V6_J, V6_K,
982    V7, V7_H, V7_J, V7_K,
983    V8, V8_H, V8_J, V8_K,
984    V9, V9_H, V9_J, V9_K,
985    V10, V10_H, V10_J, V10_K,
986    V11, V11_H, V11_J, V11_K,
987    V12, V12_H, V12_J, V12_K,
988    V13, V13_H, V13_J, V13_K,
989    V14, V14_H, V14_J, V14_K,
990    V15, V15_H, V15_J, V15_K,
991    V16, V16_H, V16_J, V16_K,
992    V17, V17_H, V17_J, V17_K,
993    V18, V18_H, V18_J, V18_K,
994    V19, V19_H, V19_J, V19_K,
995    V20, V20_H, V20_J, V20_K,
996    V21, V21_H, V21_J, V21_K,
997    V22, V22_H, V22_J, V22_K,
998    V23, V23_H, V23_J, V23_K,
999    V24, V24_H, V24_J, V24_K,
1000    V25, V25_H, V25_J, V25_K,
1001    V26, V26_H, V26_J, V26_K,
1002    V27, V27_H, V27_J, V27_K,
1003    V28, V28_H, V28_J, V28_K,
1004    V29, V29_H, V29_J, V29_K,
1005    V30, V30_H, V30_J, V30_K,
1006    V31, V31_H, V31_J, V31_K
1007);
1008
1009// Class for 128 bit register v0
1010reg_class v0_reg(
1011    V0, V0_H
1012);
1013
1014// Class for 128 bit register v1
1015reg_class v1_reg(
1016    V1, V1_H
1017);
1018
1019// Class for 128 bit register v2
1020reg_class v2_reg(
1021    V2, V2_H
1022);
1023
1024// Class for 128 bit register v3
1025reg_class v3_reg(
1026    V3, V3_H
1027);
1028
1029// Class for 128 bit register v4
1030reg_class v4_reg(
1031    V4, V4_H
1032);
1033
1034// Class for 128 bit register v5
1035reg_class v5_reg(
1036    V5, V5_H
1037);
1038
1039// Class for 128 bit register v6
1040reg_class v6_reg(
1041    V6, V6_H
1042);
1043
1044// Class for 128 bit register v7
1045reg_class v7_reg(
1046    V7, V7_H
1047);
1048
1049// Class for 128 bit register v8
1050reg_class v8_reg(
1051    V8, V8_H
1052);
1053
1054// Class for 128 bit register v9
1055reg_class v9_reg(
1056    V9, V9_H
1057);
1058
1059// Class for 128 bit register v10
1060reg_class v10_reg(
1061    V10, V10_H
1062);
1063
1064// Class for 128 bit register v11
1065reg_class v11_reg(
1066    V11, V11_H
1067);
1068
1069// Class for 128 bit register v12
1070reg_class v12_reg(
1071    V12, V12_H
1072);
1073
1074// Class for 128 bit register v13
1075reg_class v13_reg(
1076    V13, V13_H
1077);
1078
1079// Class for 128 bit register v14
1080reg_class v14_reg(
1081    V14, V14_H
1082);
1083
1084// Class for 128 bit register v15
1085reg_class v15_reg(
1086    V15, V15_H
1087);
1088
1089// Class for 128 bit register v16
1090reg_class v16_reg(
1091    V16, V16_H
1092);
1093
1094// Class for 128 bit register v17
1095reg_class v17_reg(
1096    V17, V17_H
1097);
1098
1099// Class for 128 bit register v18
1100reg_class v18_reg(
1101    V18, V18_H
1102);
1103
1104// Class for 128 bit register v19
1105reg_class v19_reg(
1106    V19, V19_H
1107);
1108
1109// Class for 128 bit register v20
1110reg_class v20_reg(
1111    V20, V20_H
1112);
1113
1114// Class for 128 bit register v21
1115reg_class v21_reg(
1116    V21, V21_H
1117);
1118
1119// Class for 128 bit register v22
1120reg_class v22_reg(
1121    V22, V22_H
1122);
1123
1124// Class for 128 bit register v23
1125reg_class v23_reg(
1126    V23, V23_H
1127);
1128
1129// Class for 128 bit register v24
1130reg_class v24_reg(
1131    V24, V24_H
1132);
1133
1134// Class for 128 bit register v25
1135reg_class v25_reg(
1136    V25, V25_H
1137);
1138
1139// Class for 128 bit register v26
1140reg_class v26_reg(
1141    V26, V26_H
1142);
1143
1144// Class for 128 bit register v27
1145reg_class v27_reg(
1146    V27, V27_H
1147);
1148
1149// Class for 128 bit register v28
1150reg_class v28_reg(
1151    V28, V28_H
1152);
1153
1154// Class for 128 bit register v29
1155reg_class v29_reg(
1156    V29, V29_H
1157);
1158
1159// Class for 128 bit register v30
1160reg_class v30_reg(
1161    V30, V30_H
1162);
1163
1164// Class for 128 bit register v31
1165reg_class v31_reg(
1166    V31, V31_H
1167);
1168
1169// Class for all SVE predicate registers.
1170reg_class pr_reg (
1171    P0,
1172    P1,
1173    P2,
1174    P3,
1175    P4,
1176    P5,
1177    P6,
1178    // P7, non-allocatable, preserved with all elements preset to TRUE.
1179    P8,
1180    P9,
1181    P10,
1182    P11,
1183    P12,
1184    P13,
1185    P14,
1186    P15
1187);
1188
1189// Class for SVE governing predicate registers, which are used
1190// to determine the active elements of a predicated instruction.
1191reg_class gov_pr (
1192    P0,
1193    P1,
1194    P2,
1195    P3,
1196    P4,
1197    P5,
1198    P6,
1199    // P7, non-allocatable, preserved with all elements preset to TRUE.
1200);
1201
1202// Singleton class for condition codes
1203reg_class int_flags(RFLAGS);
1204
1205%}
1206
1207//----------DEFINITION BLOCK---------------------------------------------------
1208// Define name --> value mappings to inform the ADLC of an integer valued name
1209// Current support includes integer values in the range [0, 0x7FFFFFFF]
1210// Format:
1211//        int_def  <name>         ( <int_value>, <expression>);
1212// Generated Code in ad_<arch>.hpp
1213//        #define  <name>   (<expression>)
1214//        // value == <int_value>
1215// Generated code in ad_<arch>.cpp adlc_verification()
1216//        assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
1217//
1218
1219// we follow the ppc-aix port in using a simple cost model which ranks
1220// register operations as cheap, memory ops as more expensive and
1221// branches as most expensive. the first two have a low as well as a
1222// normal cost. huge cost appears to be a way of saying don't do
1223// something
1224
1225definitions %{
1226  // The default cost (of a register move instruction).
1227  int_def INSN_COST            (    100,     100);
1228  int_def BRANCH_COST          (    200,     2 * INSN_COST);
1229  int_def CALL_COST            (    200,     2 * INSN_COST);
1230  int_def VOLATILE_REF_COST    (   1000,     10 * INSN_COST);
1231%}
1232
1233
1234//----------SOURCE BLOCK-------------------------------------------------------
1235// This is a block of C++ code which provides values, functions, and
1236// definitions necessary in the rest of the architecture description
1237
1238source_hpp %{
1239
1240#include "asm/macroAssembler.hpp"
1241#include "gc/shared/barrierSetAssembler.hpp"
1242#include "gc/shared/cardTable.hpp"
1243#include "gc/shared/cardTableBarrierSet.hpp"
1244#include "gc/shared/collectedHeap.hpp"
1245#include "opto/addnode.hpp"
1246#include "opto/convertnode.hpp"
1247#include "runtime/objectMonitor.hpp"
1248
1249extern RegMask _ANY_REG32_mask;
1250extern RegMask _ANY_REG_mask;
1251extern RegMask _PTR_REG_mask;
1252extern RegMask _NO_SPECIAL_REG32_mask;
1253extern RegMask _NO_SPECIAL_REG_mask;
1254extern RegMask _NO_SPECIAL_PTR_REG_mask;
1255
1256class CallStubImpl {
1257
1258  //--------------------------------------------------------------
1259  //---<  Used for optimization in Compile::shorten_branches  >---
1260  //--------------------------------------------------------------
1261
1262 public:
1263  // Size of call trampoline stub.
1264  static uint size_call_trampoline() {
1265    return 0; // no call trampolines on this platform
1266  }
1267
1268  // number of relocations needed by a call trampoline stub
1269  static uint reloc_call_trampoline() {
1270    return 0; // no call trampolines on this platform
1271  }
1272};
1273
1274class HandlerImpl {
1275
1276 public:
1277
1278  static int emit_exception_handler(CodeBuffer &cbuf);
1279  static int emit_deopt_handler(CodeBuffer& cbuf);
1280
1281  static uint size_exception_handler() {
1282    return MacroAssembler::far_branch_size();
1283  }
1284
1285  static uint size_deopt_handler() {
1286    // count one adr and one far branch instruction
1287    return 4 * NativeInstruction::instruction_size;
1288  }
1289};
1290
1291class Node::PD {
1292public:
1293  enum NodeFlags {
1294    _last_flag = Node::_last_flag
1295  };
1296};
1297
1298 bool is_CAS(int opcode, bool maybe_volatile);
1299
1300  // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
1301
1302  bool unnecessary_acquire(const Node *barrier);
1303  bool needs_acquiring_load(const Node *load);
1304
1305  // predicates controlling emit of str<x>/stlr<x> and associated dmbs
1306
1307  bool unnecessary_release(const Node *barrier);
1308  bool unnecessary_volatile(const Node *barrier);
1309  bool needs_releasing_store(const Node *store);
1310
1311  // predicate controlling translation of CompareAndSwapX
1312  bool needs_acquiring_load_exclusive(const Node *load);
1313
1314  // predicate controlling addressing modes
1315  bool size_fits_all_mem_uses(AddPNode* addp, int shift);
1316%}
1317
1318source %{
1319
1320  // Derived RegMask with conditionally allocatable registers
1321
1322  void PhaseOutput::pd_perform_mach_node_analysis() {
1323  }
1324
1325  int MachNode::pd_alignment_required() const {
1326    return 1;
1327  }
1328
1329  int MachNode::compute_padding(int current_offset) const {
1330    return 0;
1331  }
1332
1333  RegMask _ANY_REG32_mask;
1334  RegMask _ANY_REG_mask;
1335  RegMask _PTR_REG_mask;
1336  RegMask _NO_SPECIAL_REG32_mask;
1337  RegMask _NO_SPECIAL_REG_mask;
1338  RegMask _NO_SPECIAL_PTR_REG_mask;
1339
1340  void reg_mask_init() {
1341    // We derive below RegMask(s) from the ones which are auto-generated from
1342    // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29)
1343    // registers conditionally reserved.
1344
1345    _ANY_REG32_mask = _ALL_REG32_mask;
1346    _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg()));
1347
1348    _ANY_REG_mask = _ALL_REG_mask;
1349
1350    _PTR_REG_mask = _ALL_REG_mask;
1351
1352    _NO_SPECIAL_REG32_mask = _ALL_REG32_mask;
1353    _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask);
1354
1355    _NO_SPECIAL_REG_mask = _ALL_REG_mask;
1356    _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask);
1357
1358    _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask;
1359    _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask);
1360
1361    // r27 is not allocatable when compressed oops is on and heapbase is not
1362    // zero, compressed klass pointers doesn't use r27 after JDK-8234794
1363    if (UseCompressedOops && (CompressedOops::ptrs_base() != NULL)) {
1364      _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg()));
1365      _NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask);
1366      _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask);
1367    }
1368
1369    // r29 is not allocatable when PreserveFramePointer is on
1370    if (PreserveFramePointer) {
1371      _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
1372      _NO_SPECIAL_REG_mask.SUBTRACT(_FP_REG_mask);
1373      _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_FP_REG_mask);
1374    }
1375  }
1376
1377  // Optimizaton of volatile gets and puts
1378  // -------------------------------------
1379  //
1380  // AArch64 has ldar<x> and stlr<x> instructions which we can safely
1381  // use to implement volatile reads and writes. For a volatile read
1382  // we simply need
1383  //
1384  //   ldar<x>
1385  //
1386  // and for a volatile write we need
1387  //
1388  //   stlr<x>
1389  //
1390  // Alternatively, we can implement them by pairing a normal
1391  // load/store with a memory barrier. For a volatile read we need
1392  //
1393  //   ldr<x>
1394  //   dmb ishld
1395  //
1396  // for a volatile write
1397  //
1398  //   dmb ish
1399  //   str<x>
1400  //   dmb ish
1401  //
1402  // We can also use ldaxr and stlxr to implement compare and swap CAS
1403  // sequences. These are normally translated to an instruction
1404  // sequence like the following
1405  //
1406  //   dmb      ish
1407  // retry:
1408  //   ldxr<x>   rval raddr
1409  //   cmp       rval rold
1410  //   b.ne done
1411  //   stlxr<x>  rval, rnew, rold
1412  //   cbnz      rval retry
1413  // done:
1414  //   cset      r0, eq
1415  //   dmb ishld
1416  //
1417  // Note that the exclusive store is already using an stlxr
1418  // instruction. That is required to ensure visibility to other
1419  // threads of the exclusive write (assuming it succeeds) before that
1420  // of any subsequent writes.
1421  //
1422  // The following instruction sequence is an improvement on the above
1423  //
1424  // retry:
1425  //   ldaxr<x>  rval raddr
1426  //   cmp       rval rold
1427  //   b.ne done
1428  //   stlxr<x>  rval, rnew, rold
1429  //   cbnz      rval retry
1430  // done:
1431  //   cset      r0, eq
1432  //
1433  // We don't need the leading dmb ish since the stlxr guarantees
1434  // visibility of prior writes in the case that the swap is
1435  // successful. Crucially we don't have to worry about the case where
1436  // the swap is not successful since no valid program should be
1437  // relying on visibility of prior changes by the attempting thread
1438  // in the case where the CAS fails.
1439  //
1440  // Similarly, we don't need the trailing dmb ishld if we substitute
1441  // an ldaxr instruction since that will provide all the guarantees we
1442  // require regarding observation of changes made by other threads
1443  // before any change to the CAS address observed by the load.
1444  //
1445  // In order to generate the desired instruction sequence we need to
1446  // be able to identify specific 'signature' ideal graph node
1447  // sequences which i) occur as a translation of a volatile reads or
1448  // writes or CAS operations and ii) do not occur through any other
1449  // translation or graph transformation. We can then provide
1450  // alternative aldc matching rules which translate these node
1451  // sequences to the desired machine code sequences. Selection of the
1452  // alternative rules can be implemented by predicates which identify
1453  // the relevant node sequences.
1454  //
1455  // The ideal graph generator translates a volatile read to the node
1456  // sequence
1457  //
1458  //   LoadX[mo_acquire]
1459  //   MemBarAcquire
1460  //
1461  // As a special case when using the compressed oops optimization we
1462  // may also see this variant
1463  //
1464  //   LoadN[mo_acquire]
1465  //   DecodeN
1466  //   MemBarAcquire
1467  //
1468  // A volatile write is translated to the node sequence
1469  //
1470  //   MemBarRelease
1471  //   StoreX[mo_release] {CardMark}-optional
1472  //   MemBarVolatile
1473  //
1474  // n.b. the above node patterns are generated with a strict
1475  // 'signature' configuration of input and output dependencies (see
1476  // the predicates below for exact details). The card mark may be as
1477  // simple as a few extra nodes or, in a few GC configurations, may
1478  // include more complex control flow between the leading and
1479  // trailing memory barriers. However, whatever the card mark
1480  // configuration these signatures are unique to translated volatile
1481  // reads/stores -- they will not appear as a result of any other
1482  // bytecode translation or inlining nor as a consequence of
1483  // optimizing transforms.
1484  //
1485  // We also want to catch inlined unsafe volatile gets and puts and
1486  // be able to implement them using either ldar<x>/stlr<x> or some
1487  // combination of ldr<x>/stlr<x> and dmb instructions.
1488  //
1489  // Inlined unsafe volatiles puts manifest as a minor variant of the
1490  // normal volatile put node sequence containing an extra cpuorder
1491  // membar
1492  //
1493  //   MemBarRelease
1494  //   MemBarCPUOrder
1495  //   StoreX[mo_release] {CardMark}-optional
1496  //   MemBarCPUOrder
1497  //   MemBarVolatile
1498  //
1499  // n.b. as an aside, a cpuorder membar is not itself subject to
1500  // matching and translation by adlc rules.  However, the rule
1501  // predicates need to detect its presence in order to correctly
1502  // select the desired adlc rules.
1503  //
1504  // Inlined unsafe volatile gets manifest as a slightly different
1505  // node sequence to a normal volatile get because of the
1506  // introduction of some CPUOrder memory barriers to bracket the
1507  // Load. However, but the same basic skeleton of a LoadX feeding a
1508  // MemBarAcquire, possibly thorugh an optional DecodeN, is still
1509  // present
1510  //
1511  //   MemBarCPUOrder
1512  //        ||       \\
1513  //   MemBarCPUOrder LoadX[mo_acquire]
1514  //        ||            |
1515  //        ||       {DecodeN} optional
1516  //        ||       /
1517  //     MemBarAcquire
1518  //
1519  // In this case the acquire membar does not directly depend on the
1520  // load. However, we can be sure that the load is generated from an
1521  // inlined unsafe volatile get if we see it dependent on this unique
1522  // sequence of membar nodes. Similarly, given an acquire membar we
1523  // can know that it was added because of an inlined unsafe volatile
1524  // get if it is fed and feeds a cpuorder membar and if its feed
1525  // membar also feeds an acquiring load.
1526  //
1527  // Finally an inlined (Unsafe) CAS operation is translated to the
1528  // following ideal graph
1529  //
1530  //   MemBarRelease
1531  //   MemBarCPUOrder
1532  //   CompareAndSwapX {CardMark}-optional
1533  //   MemBarCPUOrder
1534  //   MemBarAcquire
1535  //
1536  // So, where we can identify these volatile read and write
1537  // signatures we can choose to plant either of the above two code
1538  // sequences. For a volatile read we can simply plant a normal
1539  // ldr<x> and translate the MemBarAcquire to a dmb. However, we can
1540  // also choose to inhibit translation of the MemBarAcquire and
1541  // inhibit planting of the ldr<x>, instead planting an ldar<x>.
1542  //
1543  // When we recognise a volatile store signature we can choose to
1544  // plant at a dmb ish as a translation for the MemBarRelease, a
1545  // normal str<x> and then a dmb ish for the MemBarVolatile.
1546  // Alternatively, we can inhibit translation of the MemBarRelease
1547  // and MemBarVolatile and instead plant a simple stlr<x>
1548  // instruction.
1549  //
1550  // when we recognise a CAS signature we can choose to plant a dmb
1551  // ish as a translation for the MemBarRelease, the conventional
1552  // macro-instruction sequence for the CompareAndSwap node (which
1553  // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire.
1554  // Alternatively, we can elide generation of the dmb instructions
1555  // and plant the alternative CompareAndSwap macro-instruction
1556  // sequence (which uses ldaxr<x>).
1557  //
1558  // Of course, the above only applies when we see these signature
1559  // configurations. We still want to plant dmb instructions in any
1560  // other cases where we may see a MemBarAcquire, MemBarRelease or
1561  // MemBarVolatile. For example, at the end of a constructor which
1562  // writes final/volatile fields we will see a MemBarRelease
1563  // instruction and this needs a 'dmb ish' lest we risk the
1564  // constructed object being visible without making the
1565  // final/volatile field writes visible.
1566  //
1567  // n.b. the translation rules below which rely on detection of the
1568  // volatile signatures and insert ldar<x> or stlr<x> are failsafe.
1569  // If we see anything other than the signature configurations we
1570  // always just translate the loads and stores to ldr<x> and str<x>
1571  // and translate acquire, release and volatile membars to the
1572  // relevant dmb instructions.
1573  //
1574
1575  // is_CAS(int opcode, bool maybe_volatile)
1576  //
1577  // return true if opcode is one of the possible CompareAndSwapX
1578  // values otherwise false.
1579
1580  bool is_CAS(int opcode, bool maybe_volatile)
1581  {
1582    switch(opcode) {
1583      // We handle these
1584    case Op_CompareAndSwapI:
1585    case Op_CompareAndSwapL:
1586    case Op_CompareAndSwapP:
1587    case Op_CompareAndSwapN:
1588    case Op_ShenandoahCompareAndSwapP:
1589    case Op_ShenandoahCompareAndSwapN:
1590    case Op_CompareAndSwapB:
1591    case Op_CompareAndSwapS:
1592    case Op_GetAndSetI:
1593    case Op_GetAndSetL:
1594    case Op_GetAndSetP:
1595    case Op_GetAndSetN:
1596    case Op_GetAndAddI:
1597    case Op_GetAndAddL:
1598      return true;
1599    case Op_CompareAndExchangeI:
1600    case Op_CompareAndExchangeN:
1601    case Op_CompareAndExchangeB:
1602    case Op_CompareAndExchangeS:
1603    case Op_CompareAndExchangeL:
1604    case Op_CompareAndExchangeP:
1605    case Op_WeakCompareAndSwapB:
1606    case Op_WeakCompareAndSwapS:
1607    case Op_WeakCompareAndSwapI:
1608    case Op_WeakCompareAndSwapL:
1609    case Op_WeakCompareAndSwapP:
1610    case Op_WeakCompareAndSwapN:
1611    case Op_ShenandoahWeakCompareAndSwapP:
1612    case Op_ShenandoahWeakCompareAndSwapN:
1613    case Op_ShenandoahCompareAndExchangeP:
1614    case Op_ShenandoahCompareAndExchangeN:
1615      return maybe_volatile;
1616    default:
1617      return false;
1618    }
1619  }
1620
1621  // helper to determine the maximum number of Phi nodes we may need to
1622  // traverse when searching from a card mark membar for the merge mem
1623  // feeding a trailing membar or vice versa
1624
1625// predicates controlling emit of ldr<x>/ldar<x>
1626
1627bool unnecessary_acquire(const Node *barrier)
1628{
1629  assert(barrier->is_MemBar(), "expecting a membar");
1630
1631  MemBarNode* mb = barrier->as_MemBar();
1632
1633  if (mb->trailing_load()) {
1634    return true;
1635  }
1636
1637  if (mb->trailing_load_store()) {
1638    Node* load_store = mb->in(MemBarNode::Precedent);
1639    assert(load_store->is_LoadStore(), "unexpected graph shape");
1640    return is_CAS(load_store->Opcode(), true);
1641  }
1642
1643  return false;
1644}
1645
1646bool needs_acquiring_load(const Node *n)
1647{
1648  assert(n->is_Load(), "expecting a load");
1649  LoadNode *ld = n->as_Load();
1650  return ld->is_acquire();
1651}
1652
1653bool unnecessary_release(const Node *n)
1654{
1655  assert((n->is_MemBar() &&
1656          n->Opcode() == Op_MemBarRelease),
1657         "expecting a release membar");
1658
1659  MemBarNode *barrier = n->as_MemBar();
1660  if (!barrier->leading()) {
1661    return false;
1662  } else {
1663    Node* trailing = barrier->trailing_membar();
1664    MemBarNode* trailing_mb = trailing->as_MemBar();
1665    assert(trailing_mb->trailing(), "Not a trailing membar?");
1666    assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars");
1667
1668    Node* mem = trailing_mb->in(MemBarNode::Precedent);
1669    if (mem->is_Store()) {
1670      assert(mem->as_Store()->is_release(), "");
1671      assert(trailing_mb->Opcode() == Op_MemBarVolatile, "");
1672      return true;
1673    } else {
1674      assert(mem->is_LoadStore(), "");
1675      assert(trailing_mb->Opcode() == Op_MemBarAcquire, "");
1676      return is_CAS(mem->Opcode(), true);
1677    }
1678  }
1679  return false;
1680}
1681
1682bool unnecessary_volatile(const Node *n)
1683{
1684  // assert n->is_MemBar();
1685  MemBarNode *mbvol = n->as_MemBar();
1686
1687  bool release = mbvol->trailing_store();
1688  assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), "");
1689#ifdef ASSERT
1690  if (release) {
1691    Node* leading = mbvol->leading_membar();
1692    assert(leading->Opcode() == Op_MemBarRelease, "");
1693    assert(leading->as_MemBar()->leading_store(), "");
1694    assert(leading->as_MemBar()->trailing_membar() == mbvol, "");
1695  }
1696#endif
1697
1698  return release;
1699}
1700
1701// predicates controlling emit of str<x>/stlr<x>
1702
1703bool needs_releasing_store(const Node *n)
1704{
1705  // assert n->is_Store();
1706  StoreNode *st = n->as_Store();
1707  return st->trailing_membar() != NULL;
1708}
1709
1710// predicate controlling translation of CAS
1711//
1712// returns true if CAS needs to use an acquiring load otherwise false
1713
1714bool needs_acquiring_load_exclusive(const Node *n)
1715{
1716  assert(is_CAS(n->Opcode(), true), "expecting a compare and swap");
1717  LoadStoreNode* ldst = n->as_LoadStore();
1718  if (is_CAS(n->Opcode(), false)) {
1719    assert(ldst->trailing_membar() != NULL, "expected trailing membar");
1720  } else {
1721    return ldst->trailing_membar() != NULL;
1722  }
1723
1724  // so we can just return true here
1725  return true;
1726}
1727
1728#define __ _masm.
1729
1730// advance declarations for helper functions to convert register
1731// indices to register objects
1732
1733// the ad file has to provide implementations of certain methods
1734// expected by the generic code
1735//
1736// REQUIRED FUNCTIONALITY
1737
1738//=============================================================================
1739
1740// !!!!! Special hack to get all types of calls to specify the byte offset
1741//       from the start of the call to the point where the return address
1742//       will point.
1743
1744int MachCallStaticJavaNode::ret_addr_offset()
1745{
1746  // call should be a simple bl
1747  int off = 4;
1748  return off;
1749}
1750
1751int MachCallDynamicJavaNode::ret_addr_offset()
1752{
1753  return 16; // movz, movk, movk, bl
1754}
1755
1756int MachCallRuntimeNode::ret_addr_offset() {
1757  // for generated stubs the call will be
1758  //   bl(addr)
1759  // or with far branches
1760  //   bl(trampoline_stub)
1761  // for real runtime callouts it will be six instructions
1762  // see aarch64_enc_java_to_runtime
1763  //   adr(rscratch2, retaddr)
1764  //   lea(rscratch1, RuntimeAddress(addr)
1765  //   stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)))
1766  //   blr(rscratch1)
1767  CodeBlob *cb = CodeCache::find_blob(_entry_point);
1768  if (cb) {
1769    return 1 * NativeInstruction::instruction_size;
1770  } else {
1771    return 6 * NativeInstruction::instruction_size;
1772  }
1773}
1774
1775int MachCallNativeNode::ret_addr_offset() {
1776  // This is implemented using aarch64_enc_java_to_runtime as above.
1777  CodeBlob *cb = CodeCache::find_blob(_entry_point);
1778  if (cb) {
1779    return 1 * NativeInstruction::instruction_size;
1780  } else {
1781    return 6 * NativeInstruction::instruction_size;
1782  }
1783}
1784
1785//=============================================================================
1786
1787#ifndef PRODUCT
1788void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1789  st->print("BREAKPOINT");
1790}
1791#endif
1792
1793void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1794  C2_MacroAssembler _masm(&cbuf);
1795  __ brk(0);
1796}
1797
1798uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
1799  return MachNode::size(ra_);
1800}
1801
1802//=============================================================================
1803
1804#ifndef PRODUCT
1805  void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
1806    st->print("nop \t# %d bytes pad for loops and calls", _count);
1807  }
1808#endif
1809
1810  void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const {
1811    C2_MacroAssembler _masm(&cbuf);
1812    for (int i = 0; i < _count; i++) {
1813      __ nop();
1814    }
1815  }
1816
1817  uint MachNopNode::size(PhaseRegAlloc*) const {
1818    return _count * NativeInstruction::instruction_size;
1819  }
1820
1821//=============================================================================
1822const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
1823
1824int ConstantTable::calculate_table_base_offset() const {
1825  return 0;  // absolute addressing, no offset
1826}
1827
1828bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1829void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1830  ShouldNotReachHere();
1831}
1832
1833void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1834  // Empty encoding
1835}
1836
1837uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1838  return 0;
1839}
1840
1841#ifndef PRODUCT
1842void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1843  st->print("-- \t// MachConstantBaseNode (empty encoding)");
1844}
1845#endif
1846
1847#ifndef PRODUCT
1848void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1849  Compile* C = ra_->C;
1850
1851  int framesize = C->output()->frame_slots() << LogBytesPerInt;
1852
1853  if (C->output()->need_stack_bang(framesize))
1854    st->print("# stack bang size=%d\n\t", framesize);
1855
1856  if (framesize < ((1 << 9) + 2 * wordSize)) {
1857    st->print("sub  sp, sp, #%d\n\t", framesize);
1858    st->print("stp  rfp, lr, [sp, #%d]", framesize - 2 * wordSize);
1859    if (PreserveFramePointer) st->print("\n\tadd  rfp, sp, #%d", framesize - 2 * wordSize);
1860  } else {
1861    st->print("stp  lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize));
1862    if (PreserveFramePointer) st->print("mov  rfp, sp\n\t");
1863    st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1864    st->print("sub  sp, sp, rscratch1");
1865  }
1866  if (C->stub_function() == NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) {
1867    st->print("\n\t");
1868    st->print("ldr  rscratch1, [guard]\n\t");
1869    st->print("dmb ishld\n\t");
1870    st->print("ldr  rscratch2, [rthread, #thread_disarmed_offset]\n\t");
1871    st->print("cmp  rscratch1, rscratch2\n\t");
1872    st->print("b.eq skip");
1873    st->print("\n\t");
1874    st->print("blr #nmethod_entry_barrier_stub\n\t");
1875    st->print("b skip\n\t");
1876    st->print("guard: int\n\t");
1877    st->print("\n\t");
1878    st->print("skip:\n\t");
1879  }
1880}
1881#endif
1882
1883void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1884  Compile* C = ra_->C;
1885  C2_MacroAssembler _masm(&cbuf);
1886
1887  // n.b. frame size includes space for return pc and rfp
1888  const int framesize = C->output()->frame_size_in_bytes();
1889
1890  // insert a nop at the start of the prolog so we can patch in a
1891  // branch if we need to invalidate the method later
1892  __ nop();
1893
1894  if (C->clinit_barrier_on_entry()) {
1895    assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
1896
1897    Label L_skip_barrier;
1898
1899    __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding());
1900    __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier);
1901    __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
1902    __ bind(L_skip_barrier);
1903  }
1904
1905  if (C->max_vector_size() >= 16) {
1906    __ reinitialize_ptrue();
1907  }
1908
1909  int bangsize = C->output()->bang_size_in_bytes();
1910  if (C->output()->need_stack_bang(bangsize))
1911    __ generate_stack_overflow_check(bangsize);
1912
1913  __ build_frame(framesize);
1914
1915  if (C->stub_function() == NULL) {
1916    BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
1917    bs->nmethod_entry_barrier(&_masm);
1918  }
1919
1920  if (VerifyStackAtCalls) {
1921    Unimplemented();
1922  }
1923
1924  C->output()->set_frame_complete(cbuf.insts_size());
1925
1926  if (C->has_mach_constant_base_node()) {
1927    // NOTE: We set the table base offset here because users might be
1928    // emitted before MachConstantBaseNode.
1929    ConstantTable& constant_table = C->output()->constant_table();
1930    constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1931  }
1932}
1933
1934uint MachPrologNode::size(PhaseRegAlloc* ra_) const
1935{
1936  return MachNode::size(ra_); // too many variables; just compute it
1937                              // the hard way
1938}
1939
1940int MachPrologNode::reloc() const
1941{
1942  return 0;
1943}
1944
1945//=============================================================================
1946
1947#ifndef PRODUCT
1948void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
1949  Compile* C = ra_->C;
1950  int framesize = C->output()->frame_slots() << LogBytesPerInt;
1951
1952  st->print("# pop frame %d\n\t",framesize);
1953
1954  if (framesize == 0) {
1955    st->print("ldp  lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1956  } else if (framesize < ((1 << 9) + 2 * wordSize)) {
1957    st->print("ldp  lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize);
1958    st->print("add  sp, sp, #%d\n\t", framesize);
1959  } else {
1960    st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1961    st->print("add  sp, sp, rscratch1\n\t");
1962    st->print("ldp  lr, rfp, [sp],#%d\n\t", (2 * wordSize));
1963  }
1964
1965  if (do_polling() && C->is_method_compilation()) {
1966    st->print("# test polling word\n\t");
1967    st->print("ldr  rscratch1, [rthread],#%d\n\t", in_bytes(JavaThread::polling_word_offset()));
1968    st->print("cmp  sp, rscratch1\n\t");
1969    st->print("bhi #slow_path");
1970  }
1971}
1972#endif
1973
1974void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1975  Compile* C = ra_->C;
1976  C2_MacroAssembler _masm(&cbuf);
1977  int framesize = C->output()->frame_slots() << LogBytesPerInt;
1978
1979  __ remove_frame(framesize);
1980
1981  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
1982    __ reserved_stack_check();
1983  }
1984
1985  if (do_polling() && C->is_method_compilation()) {
1986    Label dummy_label;
1987    Label* code_stub = &dummy_label;
1988    if (!C->output()->in_scratch_emit_size()) {
1989      code_stub = &C->output()->safepoint_poll_table()->add_safepoint(__ offset());
1990    }
1991    __ relocate(relocInfo::poll_return_type);
1992    __ safepoint_poll(*code_stub, true /* at_return */, false /* acquire */, true /* in_nmethod */);
1993  }
1994}
1995
1996uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1997  // Variable size. Determine dynamically.
1998  return MachNode::size(ra_);
1999}
2000
2001int MachEpilogNode::reloc() const {
2002  // Return number of relocatable values contained in this instruction.
2003  return 1; // 1 for polling page.
2004}
2005
2006const Pipeline * MachEpilogNode::pipeline() const {
2007  return MachNode::pipeline_class();
2008}
2009
2010//=============================================================================
2011
2012// Figure out which register class each belongs in: rc_int, rc_float or
2013// rc_stack.
2014enum RC { rc_bad, rc_int, rc_float, rc_predicate, rc_stack };
2015
2016static enum RC rc_class(OptoReg::Name reg) {
2017
2018  if (reg == OptoReg::Bad) {
2019    return rc_bad;
2020  }
2021
2022  // we have 32 int registers * 2 halves
2023  int slots_of_int_registers = RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers;
2024
2025  if (reg < slots_of_int_registers) {
2026    return rc_int;
2027  }
2028
2029  // we have 32 float register * 8 halves
2030  int slots_of_float_registers = FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers;
2031  if (reg < slots_of_int_registers + slots_of_float_registers) {
2032    return rc_float;
2033  }
2034
2035  int slots_of_predicate_registers = PRegisterImpl::max_slots_per_register * PRegisterImpl::number_of_registers;
2036  if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_predicate_registers) {
2037    return rc_predicate;
2038  }
2039
2040  // Between predicate regs & stack is the flags.
2041  assert(OptoReg::is_stack(reg), "blow up if spilling flags");
2042
2043  return rc_stack;
2044}
2045
2046uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const {
2047  Compile* C = ra_->C;
2048
2049  // Get registers to move.
2050  OptoReg::Name src_hi = ra_->get_reg_second(in(1));
2051  OptoReg::Name src_lo = ra_->get_reg_first(in(1));
2052  OptoReg::Name dst_hi = ra_->get_reg_second(this);
2053  OptoReg::Name dst_lo = ra_->get_reg_first(this);
2054
2055  enum RC src_hi_rc = rc_class(src_hi);
2056  enum RC src_lo_rc = rc_class(src_lo);
2057  enum RC dst_hi_rc = rc_class(dst_hi);
2058  enum RC dst_lo_rc = rc_class(dst_lo);
2059
2060  assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register");
2061
2062  if (src_hi != OptoReg::Bad) {
2063    assert((src_lo&1)==0 && src_lo+1==src_hi &&
2064           (dst_lo&1)==0 && dst_lo+1==dst_hi,
2065           "expected aligned-adjacent pairs");
2066  }
2067
2068  if (src_lo == dst_lo && src_hi == dst_hi) {
2069    return 0;            // Self copy, no move.
2070  }
2071
2072  bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi &&
2073              (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi;
2074  int src_offset = ra_->reg2offset(src_lo);
2075  int dst_offset = ra_->reg2offset(dst_lo);
2076
2077  if (bottom_type()->isa_vect() != NULL) {
2078    uint ireg = ideal_reg();
2079    if (ireg == Op_VecA && cbuf) {
2080      C2_MacroAssembler _masm(cbuf);
2081      int sve_vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE);
2082      if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
2083        // stack->stack
2084        __ spill_copy_sve_vector_stack_to_stack(src_offset, dst_offset,
2085                                                sve_vector_reg_size_in_bytes);
2086      } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
2087        __ spill_sve_vector(as_FloatRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo),
2088                            sve_vector_reg_size_in_bytes);
2089      } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
2090        __ unspill_sve_vector(as_FloatRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo),
2091                              sve_vector_reg_size_in_bytes);
2092      } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
2093        __ sve_orr(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2094                   as_FloatRegister(Matcher::_regEncode[src_lo]),
2095                   as_FloatRegister(Matcher::_regEncode[src_lo]));
2096      } else {
2097        ShouldNotReachHere();
2098      }
2099    } else if (cbuf) {
2100      assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector");
2101      C2_MacroAssembler _masm(cbuf);
2102      assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity");
2103      if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
2104        // stack->stack
2105        assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset");
2106        if (ireg == Op_VecD) {
2107          __ unspill(rscratch1, true, src_offset);
2108          __ spill(rscratch1, true, dst_offset);
2109        } else {
2110          __ spill_copy128(src_offset, dst_offset);
2111        }
2112      } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
2113        __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2114               ireg == Op_VecD ? __ T8B : __ T16B,
2115               as_FloatRegister(Matcher::_regEncode[src_lo]));
2116      } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
2117        __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
2118                 ireg == Op_VecD ? __ D : __ Q,
2119                 ra_->reg2offset(dst_lo));
2120      } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) {
2121        __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2122                   ireg == Op_VecD ? __ D : __ Q,
2123                   ra_->reg2offset(src_lo));
2124      } else {
2125        ShouldNotReachHere();
2126      }
2127    }
2128  } else if (cbuf) {
2129    C2_MacroAssembler _masm(cbuf);
2130    switch (src_lo_rc) {
2131    case rc_int:
2132      if (dst_lo_rc == rc_int) {  // gpr --> gpr copy
2133        if (is64) {
2134            __ mov(as_Register(Matcher::_regEncode[dst_lo]),
2135                   as_Register(Matcher::_regEncode[src_lo]));
2136        } else {
2137            C2_MacroAssembler _masm(cbuf);
2138            __ movw(as_Register(Matcher::_regEncode[dst_lo]),
2139                    as_Register(Matcher::_regEncode[src_lo]));
2140        }
2141      } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
2142        if (is64) {
2143            __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2144                     as_Register(Matcher::_regEncode[src_lo]));
2145        } else {
2146            __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2147                     as_Register(Matcher::_regEncode[src_lo]));
2148        }
2149      } else {                    // gpr --> stack spill
2150        assert(dst_lo_rc == rc_stack, "spill to bad register class");
2151        __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset);
2152      }
2153      break;
2154    case rc_float:
2155      if (dst_lo_rc == rc_int) {  // fpr --> gpr copy
2156        if (is64) {
2157            __ fmovd(as_Register(Matcher::_regEncode[dst_lo]),
2158                     as_FloatRegister(Matcher::_regEncode[src_lo]));
2159        } else {
2160            __ fmovs(as_Register(Matcher::_regEncode[dst_lo]),
2161                     as_FloatRegister(Matcher::_regEncode[src_lo]));
2162        }
2163      } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy
2164          if (cbuf) {
2165            __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2166                     as_FloatRegister(Matcher::_regEncode[src_lo]));
2167        } else {
2168            __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2169                     as_FloatRegister(Matcher::_regEncode[src_lo]));
2170        }
2171      } else {                    // fpr --> stack spill
2172        assert(dst_lo_rc == rc_stack, "spill to bad register class");
2173        __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]),
2174                 is64 ? __ D : __ S, dst_offset);
2175      }
2176      break;
2177    case rc_stack:
2178      if (dst_lo_rc == rc_int) {  // stack --> gpr load
2179        __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset);
2180      } else if (dst_lo_rc == rc_float) { // stack --> fpr load
2181        __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]),
2182                   is64 ? __ D : __ S, src_offset);
2183      } else {                    // stack --> stack copy
2184        assert(dst_lo_rc == rc_stack, "spill to bad register class");
2185        __ unspill(rscratch1, is64, src_offset);
2186        __ spill(rscratch1, is64, dst_offset);
2187      }
2188      break;
2189    default:
2190      assert(false, "bad rc_class for spill");
2191      ShouldNotReachHere();
2192    }
2193  }
2194
2195  if (st) {
2196    st->print("spill ");
2197    if (src_lo_rc == rc_stack) {
2198      st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo));
2199    } else {
2200      st->print("%s -> ", Matcher::regName[src_lo]);
2201    }
2202    if (dst_lo_rc == rc_stack) {
2203      st->print("[sp, #%d]", ra_->reg2offset(dst_lo));
2204    } else {
2205      st->print("%s", Matcher::regName[dst_lo]);
2206    }
2207    if (bottom_type()->isa_vect() != NULL) {
2208      int vsize = 0;
2209      switch (ideal_reg()) {
2210      case Op_VecD:
2211        vsize = 64;
2212        break;
2213      case Op_VecX:
2214        vsize = 128;
2215        break;
2216      case Op_VecA:
2217        vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8;
2218        break;
2219      default:
2220        assert(false, "bad register type for spill");
2221        ShouldNotReachHere();
2222      }
2223      st->print("\t# vector spill size = %d", vsize);
2224    } else {
2225      st->print("\t# spill size = %d", is64 ? 64 : 32);
2226    }
2227  }
2228
2229  return 0;
2230
2231}
2232
2233#ifndef PRODUCT
2234void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2235  if (!ra_)
2236    st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx);
2237  else
2238    implementation(NULL, ra_, false, st);
2239}
2240#endif
2241
2242void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
2243  implementation(&cbuf, ra_, false, NULL);
2244}
2245
2246uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
2247  return MachNode::size(ra_);
2248}
2249
2250//=============================================================================
2251
2252#ifndef PRODUCT
2253void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
2254  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2255  int reg = ra_->get_reg_first(this);
2256  st->print("add %s, rsp, #%d]\t# box lock",
2257            Matcher::regName[reg], offset);
2258}
2259#endif
2260
2261void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
2262  C2_MacroAssembler _masm(&cbuf);
2263
2264  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2265  int reg    = ra_->get_encode(this);
2266
2267  // This add will handle any 24-bit signed offset. 24 bits allows an
2268  // 8 megabyte stack frame.
2269  __ add(as_Register(reg), sp, offset);
2270}
2271
2272uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
2273  // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
2274  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2275
2276  if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
2277    return NativeInstruction::instruction_size;
2278  } else {
2279    return 2 * NativeInstruction::instruction_size;
2280  }
2281}
2282
2283//=============================================================================
2284
2285#ifndef PRODUCT
2286void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
2287{
2288  st->print_cr("# MachUEPNode");
2289  if (UseCompressedClassPointers) {
2290    st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2291    if (CompressedKlassPointers::shift() != 0) {
2292      st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
2293    }
2294  } else {
2295   st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2296  }
2297  st->print_cr("\tcmp r0, rscratch1\t # Inline cache check");
2298  st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
2299}
2300#endif
2301
2302void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
2303{
2304  // This is the unverified entry point.
2305  C2_MacroAssembler _masm(&cbuf);
2306
2307  __ cmp_klass(j_rarg0, rscratch2, rscratch1);
2308  Label skip;
2309  // TODO
2310  // can we avoid this skip and still use a reloc?
2311  __ br(Assembler::EQ, skip);
2312  __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
2313  __ bind(skip);
2314}
2315
2316uint MachUEPNode::size(PhaseRegAlloc* ra_) const
2317{
2318  return MachNode::size(ra_);
2319}
2320
2321// REQUIRED EMIT CODE
2322
2323//=============================================================================
2324
2325// Emit exception handler code.
2326int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf)
2327{
2328  // mov rscratch1 #exception_blob_entry_point
2329  // br rscratch1
2330  // Note that the code buffer's insts_mark is always relative to insts.
2331  // That's why we must use the macroassembler to generate a handler.
2332  C2_MacroAssembler _masm(&cbuf);
2333  address base = __ start_a_stub(size_exception_handler());
2334  if (base == NULL) {
2335    ciEnv::current()->record_failure("CodeCache is full");
2336    return 0;  // CodeBuffer::expand failed
2337  }
2338  int offset = __ offset();
2339  __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
2340  assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
2341  __ end_a_stub();
2342  return offset;
2343}
2344
2345// Emit deopt handler code.
2346int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf)
2347{
2348  // Note that the code buffer's insts_mark is always relative to insts.
2349  // That's why we must use the macroassembler to generate a handler.
2350  C2_MacroAssembler _masm(&cbuf);
2351  address base = __ start_a_stub(size_deopt_handler());
2352  if (base == NULL) {
2353    ciEnv::current()->record_failure("CodeCache is full");
2354    return 0;  // CodeBuffer::expand failed
2355  }
2356  int offset = __ offset();
2357
2358  __ adr(lr, __ pc());
2359  __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
2360
2361  assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
2362  __ end_a_stub();
2363  return offset;
2364}
2365
2366// REQUIRED MATCHER CODE
2367
2368//=============================================================================
2369
2370const bool Matcher::match_rule_supported(int opcode) {
2371  if (!has_match_rule(opcode))
2372    return false;
2373
2374  bool ret_value = true;
2375  switch (opcode) {
2376    case Op_CacheWB:
2377    case Op_CacheWBPreSync:
2378    case Op_CacheWBPostSync:
2379      if (!VM_Version::supports_data_cache_line_flush()) {
2380        ret_value = false;
2381      }
2382      break;
2383  }
2384
2385  return ret_value; // Per default match rules are supported.
2386}
2387
2388// Identify extra cases that we might want to provide match rules for vector nodes and
2389// other intrinsics guarded with vector length (vlen) and element type (bt).
2390const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
2391  if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) {
2392    return false;
2393  }
2394  int bit_size = vlen * type2aelembytes(bt) * 8;
2395  if (UseSVE == 0 && bit_size > 128) {
2396    return false;
2397  }
2398  if (UseSVE > 0) {
2399    return op_sve_supported(opcode);
2400  } else { // NEON
2401    // Special cases
2402    switch (opcode) {
2403    case Op_VectorMaskCmp:
2404    // We don't have VectorReinterpret with bit_size less than 64 support for
2405    // now, even for byte type. To be refined with fully VectorCast support.
2406    case Op_VectorReinterpret:
2407      if (vlen < 2 || bit_size < 64) {
2408        return false;
2409      }
2410      break;
2411    case Op_MulAddVS2VI:
2412      if (bit_size < 128) {
2413        return false;
2414      }
2415      break;
2416    case Op_MulVL:
2417      return false;
2418    case Op_VectorLoadShuffle:
2419    case Op_VectorRearrange:
2420      if (vlen < 4) {
2421        return false;
2422      }
2423      break;
2424    // Some types of VectorCast are not implemented for now.
2425    case Op_VectorCastI2X:
2426      if (bt == T_BYTE) {
2427        return false;
2428      }
2429      break;
2430    case Op_VectorCastS2X:
2431      if (vlen < 4 || bit_size < 64) {
2432        return false;
2433      }
2434      break;
2435    case Op_VectorCastF2X:
2436    case Op_VectorCastD2X:
2437      if (bt == T_INT || bt == T_SHORT || bt == T_BYTE || bt == T_LONG) {
2438        return false;
2439      }
2440      break;
2441    default:
2442      break;
2443    }
2444  }
2445  return true; // Per default match rules are supported.
2446}
2447
2448const RegMask* Matcher::predicate_reg_mask(void) {
2449  return &_PR_REG_mask;
2450}
2451
2452const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) {
2453  return new TypeVectMask(elemTy, length);
2454}
2455
2456// Vector calling convention not yet implemented.
2457const bool Matcher::supports_vector_calling_convention(void) {
2458  return false;
2459}
2460
2461OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
2462  Unimplemented();
2463  return OptoRegPair(0, 0);
2464}
2465
2466const int Matcher::float_pressure(int default_pressure_threshold) {
2467  return default_pressure_threshold;
2468}
2469
2470// Is this branch offset short enough that a short branch can be used?
2471//
2472// NOTE: If the platform does not provide any short branch variants, then
2473//       this method should return false for offset 0.
2474bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2475  // The passed offset is relative to address of the branch.
2476
2477  return (-32768 <= offset && offset < 32768);
2478}
2479
2480// Vector width in bytes.
2481const int Matcher::vector_width_in_bytes(BasicType bt) {
2482  // The MaxVectorSize should have been set by detecting SVE max vector register size.
2483  int size = MIN2((UseSVE > 0) ? 256 : 16, (int)MaxVectorSize);
2484  // Minimum 2 values in vector
2485  if (size < 2*type2aelembytes(bt)) size = 0;
2486  // But never < 4
2487  if (size < 4) size = 0;
2488  return size;
2489}
2490
2491// Limits on vector size (number of elements) loaded into vector.
2492const int Matcher::max_vector_size(const BasicType bt) {
2493  return vector_width_in_bytes(bt)/type2aelembytes(bt);
2494}
2495const int Matcher::min_vector_size(const BasicType bt) {
2496  int max_size = max_vector_size(bt);
2497  if ((UseSVE > 0) && (MaxVectorSize >= 16)) {
2498    // Currently vector length less than SVE vector register size is not supported.
2499    return max_size;
2500  } else { // NEON
2501    // Limit the vector size to 8 bytes
2502    int size = 8 / type2aelembytes(bt);
2503    if (bt == T_BYTE) {
2504      // To support vector api shuffle/rearrange.
2505      size = 4;
2506    } else if (bt == T_BOOLEAN) {
2507      // To support vector api load/store mask.
2508      size = 2;
2509    }
2510    if (size < 2) size = 2;
2511    return MIN2(size,max_size);
2512  }
2513}
2514
2515// Actual max scalable vector register length.
2516const int Matcher::scalable_vector_reg_size(const BasicType bt) {
2517  return Matcher::max_vector_size(bt);
2518}
2519
2520// Vector ideal reg.
2521const uint Matcher::vector_ideal_reg(int len) {
2522  if (UseSVE > 0 && 16 <= len && len <= 256) {
2523    return Op_VecA;
2524  }
2525  switch(len) {
2526    // For 16-bit/32-bit mask vector, reuse VecD.
2527    case  2:
2528    case  4:
2529    case  8: return Op_VecD;
2530    case 16: return Op_VecX;
2531  }
2532  ShouldNotReachHere();
2533  return 0;
2534}
2535
2536MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) {
2537  ShouldNotReachHere(); // generic vector operands not supported
2538  return NULL;
2539}
2540
2541bool Matcher::is_generic_reg2reg_move(MachNode* m) {
2542  ShouldNotReachHere();  // generic vector operands not supported
2543  return false;
2544}
2545
2546bool Matcher::is_generic_vector(MachOper* opnd)  {
2547  ShouldNotReachHere();  // generic vector operands not supported
2548  return false;
2549}
2550
2551// Return whether or not this register is ever used as an argument.
2552// This function is used on startup to build the trampoline stubs in
2553// generateOptoStub.  Registers not mentioned will be killed by the VM
2554// call in the trampoline, and arguments in those registers not be
2555// available to the callee.
2556bool Matcher::can_be_java_arg(int reg)
2557{
2558  return
2559    reg ==  R0_num || reg == R0_H_num ||
2560    reg ==  R1_num || reg == R1_H_num ||
2561    reg ==  R2_num || reg == R2_H_num ||
2562    reg ==  R3_num || reg == R3_H_num ||
2563    reg ==  R4_num || reg == R4_H_num ||
2564    reg ==  R5_num || reg == R5_H_num ||
2565    reg ==  R6_num || reg == R6_H_num ||
2566    reg ==  R7_num || reg == R7_H_num ||
2567    reg ==  V0_num || reg == V0_H_num ||
2568    reg ==  V1_num || reg == V1_H_num ||
2569    reg ==  V2_num || reg == V2_H_num ||
2570    reg ==  V3_num || reg == V3_H_num ||
2571    reg ==  V4_num || reg == V4_H_num ||
2572    reg ==  V5_num || reg == V5_H_num ||
2573    reg ==  V6_num || reg == V6_H_num ||
2574    reg ==  V7_num || reg == V7_H_num;
2575}
2576
2577bool Matcher::is_spillable_arg(int reg)
2578{
2579  return can_be_java_arg(reg);
2580}
2581
2582bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
2583  return false;
2584}
2585
2586RegMask Matcher::divI_proj_mask() {
2587  ShouldNotReachHere();
2588  return RegMask();
2589}
2590
2591// Register for MODI projection of divmodI.
2592RegMask Matcher::modI_proj_mask() {
2593  ShouldNotReachHere();
2594  return RegMask();
2595}
2596
2597// Register for DIVL projection of divmodL.
2598RegMask Matcher::divL_proj_mask() {
2599  ShouldNotReachHere();
2600  return RegMask();
2601}
2602
2603// Register for MODL projection of divmodL.
2604RegMask Matcher::modL_proj_mask() {
2605  ShouldNotReachHere();
2606  return RegMask();
2607}
2608
2609const RegMask Matcher::method_handle_invoke_SP_save_mask() {
2610  return FP_REG_mask();
2611}
2612
2613bool size_fits_all_mem_uses(AddPNode* addp, int shift) {
2614  for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
2615    Node* u = addp->fast_out(i);
2616    if (u->is_Mem()) {
2617      int opsize = u->as_Mem()->memory_size();
2618      assert(opsize > 0, "unexpected memory operand size");
2619      if (u->as_Mem()->memory_size() != (1<<shift)) {
2620        return false;
2621      }
2622    }
2623  }
2624  return true;
2625}
2626
2627// Should the matcher clone input 'm' of node 'n'?
2628bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
2629  if (is_vshift_con_pattern(n, m)) { // ShiftV src (ShiftCntV con)
2630    mstack.push(m, Visit);           // m = ShiftCntV
2631    return true;
2632  }
2633  return false;
2634}
2635
2636// Should the Matcher clone shifts on addressing modes, expecting them
2637// to be subsumed into complex addressing expressions or compute them
2638// into registers?
2639bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
2640  if (clone_base_plus_offset_address(m, mstack, address_visited)) {
2641    return true;
2642  }
2643
2644  Node *off = m->in(AddPNode::Offset);
2645  if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() &&
2646      size_fits_all_mem_uses(m, off->in(2)->get_int()) &&
2647      // Are there other uses besides address expressions?
2648      !is_visited(off)) {
2649    address_visited.set(off->_idx); // Flag as address_visited
2650    mstack.push(off->in(2), Visit);
2651    Node *conv = off->in(1);
2652    if (conv->Opcode() == Op_ConvI2L &&
2653        // Are there other uses besides address expressions?
2654        !is_visited(conv)) {
2655      address_visited.set(conv->_idx); // Flag as address_visited
2656      mstack.push(conv->in(1), Pre_Visit);
2657    } else {
2658      mstack.push(conv, Pre_Visit);
2659    }
2660    address_visited.test_set(m->_idx); // Flag as address_visited
2661    mstack.push(m->in(AddPNode::Address), Pre_Visit);
2662    mstack.push(m->in(AddPNode::Base), Pre_Visit);
2663    return true;
2664  } else if (off->Opcode() == Op_ConvI2L &&
2665             // Are there other uses besides address expressions?
2666             !is_visited(off)) {
2667    address_visited.test_set(m->_idx); // Flag as address_visited
2668    address_visited.set(off->_idx); // Flag as address_visited
2669    mstack.push(off->in(1), Pre_Visit);
2670    mstack.push(m->in(AddPNode::Address), Pre_Visit);
2671    mstack.push(m->in(AddPNode::Base), Pre_Visit);
2672    return true;
2673  }
2674  return false;
2675}
2676
2677#define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN)      \
2678  C2_MacroAssembler _masm(&cbuf);                                       \
2679  {                                                                     \
2680    guarantee(INDEX == -1, "mode not permitted for volatile");          \
2681    guarantee(DISP == 0, "mode not permitted for volatile");            \
2682    guarantee(SCALE == 0, "mode not permitted for volatile");           \
2683    __ INSN(REG, as_Register(BASE));                                    \
2684  }
2685
2686
2687static Address mem2address(int opcode, Register base, int index, int size, int disp)
2688  {
2689    Address::extend scale;
2690
2691    // Hooboy, this is fugly.  We need a way to communicate to the
2692    // encoder that the index needs to be sign extended, so we have to
2693    // enumerate all the cases.
2694    switch (opcode) {
2695    case INDINDEXSCALEDI2L:
2696    case INDINDEXSCALEDI2LN:
2697    case INDINDEXI2L:
2698    case INDINDEXI2LN:
2699      scale = Address::sxtw(size);
2700      break;
2701    default:
2702      scale = Address::lsl(size);
2703    }
2704
2705    if (index == -1) {
2706      return Address(base, disp);
2707    } else {
2708      assert(disp == 0, "unsupported address mode: disp = %d", disp);
2709      return Address(base, as_Register(index), scale);
2710    }
2711  }
2712
2713
2714typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
2715typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr);
2716typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
2717typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
2718                                  MacroAssembler::SIMD_RegVariant T, const Address &adr);
2719
2720  // Used for all non-volatile memory accesses.  The use of
2721  // $mem->opcode() to discover whether this pattern uses sign-extended
2722  // offsets is something of a kludge.
2723  static void loadStore(C2_MacroAssembler masm, mem_insn insn,
2724                        Register reg, int opcode,
2725                        Register base, int index, int scale, int disp,
2726                        int size_in_memory)
2727  {
2728    Address addr = mem2address(opcode, base, index, scale, disp);
2729    if (addr.getMode() == Address::base_plus_offset) {
2730      /* If we get an out-of-range offset it is a bug in the compiler,
2731         so we assert here. */
2732      assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)),
2733             "c2 compiler bug");
2734      /* Fix up any out-of-range offsets. */
2735      assert_different_registers(rscratch1, base);
2736      assert_different_registers(rscratch1, reg);
2737      addr = masm.legitimize_address(addr, size_in_memory, rscratch1);
2738    }
2739    (masm.*insn)(reg, addr);
2740  }
2741
2742  static void loadStore(C2_MacroAssembler masm, mem_float_insn insn,
2743                        FloatRegister reg, int opcode,
2744                        Register base, int index, int size, int disp,
2745                        int size_in_memory)
2746  {
2747    Address::extend scale;
2748
2749    switch (opcode) {
2750    case INDINDEXSCALEDI2L:
2751    case INDINDEXSCALEDI2LN:
2752      scale = Address::sxtw(size);
2753      break;
2754    default:
2755      scale = Address::lsl(size);
2756    }
2757
2758    if (index == -1) {
2759      /* If we get an out-of-range offset it is a bug in the compiler,
2760         so we assert here. */
2761      assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug");
2762      /* Fix up any out-of-range offsets. */
2763      assert_different_registers(rscratch1, base);
2764      Address addr = Address(base, disp);
2765      addr = masm.legitimize_address(addr, size_in_memory, rscratch1);
2766      (masm.*insn)(reg, addr);
2767    } else {
2768      assert(disp == 0, "unsupported address mode: disp = %d", disp);
2769      (masm.*insn)(reg, Address(base, as_Register(index), scale));
2770    }
2771  }
2772
2773  static void loadStore(C2_MacroAssembler masm, mem_vector_insn insn,
2774                        FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
2775                        int opcode, Register base, int index, int size, int disp)
2776  {
2777    if (index == -1) {
2778      (masm.*insn)(reg, T, Address(base, disp));
2779    } else {
2780      assert(disp == 0, "unsupported address mode");
2781      (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size)));
2782    }
2783  }
2784
2785%}
2786
2787
2788
2789//----------ENCODING BLOCK-----------------------------------------------------
2790// This block specifies the encoding classes used by the compiler to
2791// output byte streams.  Encoding classes are parameterized macros
2792// used by Machine Instruction Nodes in order to generate the bit
2793// encoding of the instruction.  Operands specify their base encoding
2794// interface with the interface keyword.  There are currently
2795// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
2796// COND_INTER.  REG_INTER causes an operand to generate a function
2797// which returns its register number when queried.  CONST_INTER causes
2798// an operand to generate a function which returns the value of the
2799// constant when queried.  MEMORY_INTER causes an operand to generate
2800// four functions which return the Base Register, the Index Register,
2801// the Scale Value, and the Offset Value of the operand when queried.
2802// COND_INTER causes an operand to generate six functions which return
2803// the encoding code (ie - encoding bits for the instruction)
2804// associated with each basic boolean condition for a conditional
2805// instruction.
2806//
2807// Instructions specify two basic values for encoding.  Again, a
2808// function is available to check if the constant displacement is an
2809// oop. They use the ins_encode keyword to specify their encoding
2810// classes (which must be a sequence of enc_class names, and their
2811// parameters, specified in the encoding block), and they use the
2812// opcode keyword to specify, in order, their primary, secondary, and
2813// tertiary opcode.  Only the opcode sections which a particular
2814// instruction needs for encoding need to be specified.
2815encode %{
2816  // Build emit functions for each basic byte or larger field in the
2817  // intel encoding scheme (opcode, rm, sib, immediate), and call them
2818  // from C++ code in the enc_class source block.  Emit functions will
2819  // live in the main source block for now.  In future, we can
2820  // generalize this by adding a syntax that specifies the sizes of
2821  // fields in an order, so that the adlc can build the emit functions
2822  // automagically
2823
2824  // catch all for unimplemented encodings
2825  enc_class enc_unimplemented %{
2826    C2_MacroAssembler _masm(&cbuf);
2827    __ unimplemented("C2 catch all");
2828  %}
2829
2830  // BEGIN Non-volatile memory access
2831
2832  // This encoding class is generated automatically from ad_encode.m4.
2833  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2834  enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{
2835    Register dst_reg = as_Register($dst$$reg);
2836    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(),
2837               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2838  %}
2839
2840  // This encoding class is generated automatically from ad_encode.m4.
2841  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2842  enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{
2843    Register dst_reg = as_Register($dst$$reg);
2844    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(),
2845               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2846  %}
2847
2848  // This encoding class is generated automatically from ad_encode.m4.
2849  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2850  enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{
2851    Register dst_reg = as_Register($dst$$reg);
2852    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2853               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2854  %}
2855
2856  // This encoding class is generated automatically from ad_encode.m4.
2857  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2858  enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{
2859    Register dst_reg = as_Register($dst$$reg);
2860    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(),
2861               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2862  %}
2863
2864  // This encoding class is generated automatically from ad_encode.m4.
2865  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2866  enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{
2867    Register dst_reg = as_Register($dst$$reg);
2868    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(),
2869               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2870  %}
2871
2872  // This encoding class is generated automatically from ad_encode.m4.
2873  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2874  enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{
2875    Register dst_reg = as_Register($dst$$reg);
2876    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(),
2877               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2878  %}
2879
2880  // This encoding class is generated automatically from ad_encode.m4.
2881  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2882  enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{
2883    Register dst_reg = as_Register($dst$$reg);
2884    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2885               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2886  %}
2887
2888  // This encoding class is generated automatically from ad_encode.m4.
2889  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2890  enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{
2891    Register dst_reg = as_Register($dst$$reg);
2892    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(),
2893               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2894  %}
2895
2896  // This encoding class is generated automatically from ad_encode.m4.
2897  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2898  enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{
2899    Register dst_reg = as_Register($dst$$reg);
2900    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2901               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2902  %}
2903
2904  // This encoding class is generated automatically from ad_encode.m4.
2905  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2906  enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{
2907    Register dst_reg = as_Register($dst$$reg);
2908    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(),
2909               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2910  %}
2911
2912  // This encoding class is generated automatically from ad_encode.m4.
2913  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2914  enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{
2915    Register dst_reg = as_Register($dst$$reg);
2916    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(),
2917               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2918  %}
2919
2920  // This encoding class is generated automatically from ad_encode.m4.
2921  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2922  enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{
2923    Register dst_reg = as_Register($dst$$reg);
2924    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(),
2925               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
2926  %}
2927
2928  // This encoding class is generated automatically from ad_encode.m4.
2929  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2930  enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{
2931    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2932    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(),
2933               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2934  %}
2935
2936  // This encoding class is generated automatically from ad_encode.m4.
2937  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2938  enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{
2939    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2940    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(),
2941               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
2942  %}
2943
2944  // This encoding class is generated automatically from ad_encode.m4.
2945  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2946  enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{
2947    Register src_reg = as_Register($src$$reg);
2948    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(),
2949               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2950  %}
2951
2952  // This encoding class is generated automatically from ad_encode.m4.
2953  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2954  enc_class aarch64_enc_strb0(memory1 mem) %{
2955    C2_MacroAssembler _masm(&cbuf);
2956    loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(),
2957               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
2958  %}
2959
2960  // This encoding class is generated automatically from ad_encode.m4.
2961  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2962  enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{
2963    Register src_reg = as_Register($src$$reg);
2964    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(),
2965               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2966  %}
2967
2968  // This encoding class is generated automatically from ad_encode.m4.
2969  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2970  enc_class aarch64_enc_strh0(memory2 mem) %{
2971    C2_MacroAssembler _masm(&cbuf);
2972    loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(),
2973               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2);
2974  %}
2975
2976  // This encoding class is generated automatically from ad_encode.m4.
2977  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2978  enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{
2979    Register src_reg = as_Register($src$$reg);
2980    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(),
2981               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2982  %}
2983
2984  // This encoding class is generated automatically from ad_encode.m4.
2985  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2986  enc_class aarch64_enc_strw0(memory4 mem) %{
2987    C2_MacroAssembler _masm(&cbuf);
2988    loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(),
2989               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
2990  %}
2991
2992  // This encoding class is generated automatically from ad_encode.m4.
2993  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
2994  enc_class aarch64_enc_str(iRegL src, memory8 mem) %{
2995    Register src_reg = as_Register($src$$reg);
2996    // we sometimes get asked to store the stack pointer into the
2997    // current thread -- we cannot do that directly on AArch64
2998    if (src_reg == r31_sp) {
2999      C2_MacroAssembler _masm(&cbuf);
3000      assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
3001      __ mov(rscratch2, sp);
3002      src_reg = rscratch2;
3003    }
3004    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(),
3005               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3006  %}
3007
3008  // This encoding class is generated automatically from ad_encode.m4.
3009  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3010  enc_class aarch64_enc_str0(memory8 mem) %{
3011    C2_MacroAssembler _masm(&cbuf);
3012    loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(),
3013               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3014  %}
3015
3016  // This encoding class is generated automatically from ad_encode.m4.
3017  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3018  enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{
3019    FloatRegister src_reg = as_FloatRegister($src$$reg);
3020    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(),
3021               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
3022  %}
3023
3024  // This encoding class is generated automatically from ad_encode.m4.
3025  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3026  enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{
3027    FloatRegister src_reg = as_FloatRegister($src$$reg);
3028    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(),
3029               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
3030  %}
3031
3032  // This encoding class is generated automatically from ad_encode.m4.
3033  // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
3034  enc_class aarch64_enc_strb0_ordered(memory4 mem) %{
3035      C2_MacroAssembler _masm(&cbuf);
3036      __ membar(Assembler::StoreStore);
3037      loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(),
3038               as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
3039  %}
3040
3041  // END Non-volatile memory access
3042
3043  // Vector loads and stores
3044  enc_class aarch64_enc_ldrvH(vecD dst, memory mem) %{
3045    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3046    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::H,
3047       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3048  %}
3049
3050  enc_class aarch64_enc_ldrvS(vecD dst, memory mem) %{
3051    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3052    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S,
3053       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3054  %}
3055
3056  enc_class aarch64_enc_ldrvD(vecD dst, memory mem) %{
3057    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3058    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D,
3059       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3060  %}
3061
3062  enc_class aarch64_enc_ldrvQ(vecX dst, memory mem) %{
3063    FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3064    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q,
3065       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3066  %}
3067
3068  enc_class aarch64_enc_strvH(vecD src, memory mem) %{
3069    FloatRegister src_reg = as_FloatRegister($src$$reg);
3070    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::H,
3071       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3072  %}
3073
3074  enc_class aarch64_enc_strvS(vecD src, memory mem) %{
3075    FloatRegister src_reg = as_FloatRegister($src$$reg);
3076    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S,
3077       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3078  %}
3079
3080  enc_class aarch64_enc_strvD(vecD src, memory mem) %{
3081    FloatRegister src_reg = as_FloatRegister($src$$reg);
3082    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D,
3083       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3084  %}
3085
3086  enc_class aarch64_enc_strvQ(vecX src, memory mem) %{
3087    FloatRegister src_reg = as_FloatRegister($src$$reg);
3088    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q,
3089       $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
3090  %}
3091
3092  // volatile loads and stores
3093
3094  enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{
3095    MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3096                 rscratch1, stlrb);
3097  %}
3098
3099  enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{
3100    MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3101                 rscratch1, stlrh);
3102  %}
3103
3104  enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{
3105    MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3106                 rscratch1, stlrw);
3107  %}
3108
3109
3110  enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{
3111    Register dst_reg = as_Register($dst$$reg);
3112    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3113             rscratch1, ldarb);
3114    __ sxtbw(dst_reg, dst_reg);
3115  %}
3116
3117  enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{
3118    Register dst_reg = as_Register($dst$$reg);
3119    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3120             rscratch1, ldarb);
3121    __ sxtb(dst_reg, dst_reg);
3122  %}
3123
3124  enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{
3125    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3126             rscratch1, ldarb);
3127  %}
3128
3129  enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{
3130    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3131             rscratch1, ldarb);
3132  %}
3133
3134  enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{
3135    Register dst_reg = as_Register($dst$$reg);
3136    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3137             rscratch1, ldarh);
3138    __ sxthw(dst_reg, dst_reg);
3139  %}
3140
3141  enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{
3142    Register dst_reg = as_Register($dst$$reg);
3143    MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3144             rscratch1, ldarh);
3145    __ sxth(dst_reg, dst_reg);
3146  %}
3147
3148  enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{
3149    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3150             rscratch1, ldarh);
3151  %}
3152
3153  enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{
3154    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3155             rscratch1, ldarh);
3156  %}
3157
3158  enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{
3159    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3160             rscratch1, ldarw);
3161  %}
3162
3163  enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{
3164    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3165             rscratch1, ldarw);
3166  %}
3167
3168  enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{
3169    MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3170             rscratch1, ldar);
3171  %}
3172
3173  enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{
3174    MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3175             rscratch1, ldarw);
3176    __ fmovs(as_FloatRegister($dst$$reg), rscratch1);
3177  %}
3178
3179  enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{
3180    MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3181             rscratch1, ldar);
3182    __ fmovd(as_FloatRegister($dst$$reg), rscratch1);
3183  %}
3184
3185  enc_class aarch64_enc_stlr(iRegL src, memory mem) %{
3186    Register src_reg = as_Register($src$$reg);
3187    // we sometimes get asked to store the stack pointer into the
3188    // current thread -- we cannot do that directly on AArch64
3189    if (src_reg == r31_sp) {
3190      C2_MacroAssembler _masm(&cbuf);
3191      assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
3192      __ mov(rscratch2, sp);
3193      src_reg = rscratch2;
3194    }
3195    MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3196                 rscratch1, stlr);
3197  %}
3198
3199  enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{
3200    {
3201      C2_MacroAssembler _masm(&cbuf);
3202      FloatRegister src_reg = as_FloatRegister($src$$reg);
3203      __ fmovs(rscratch2, src_reg);
3204    }
3205    MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3206                 rscratch1, stlrw);
3207  %}
3208
3209  enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{
3210    {
3211      C2_MacroAssembler _masm(&cbuf);
3212      FloatRegister src_reg = as_FloatRegister($src$$reg);
3213      __ fmovd(rscratch2, src_reg);
3214    }
3215    MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp,
3216                 rscratch1, stlr);
3217  %}
3218
3219  // synchronized read/update encodings
3220
3221  enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{
3222    C2_MacroAssembler _masm(&cbuf);
3223    Register dst_reg = as_Register($dst$$reg);
3224    Register base = as_Register($mem$$base);
3225    int index = $mem$$index;
3226    int scale = $mem$$scale;
3227    int disp = $mem$$disp;
3228    if (index == -1) {
3229       if (disp != 0) {
3230        __ lea(rscratch1, Address(base, disp));
3231        __ ldaxr(dst_reg, rscratch1);
3232      } else {
3233        // TODO
3234        // should we ever get anything other than this case?
3235        __ ldaxr(dst_reg, base);
3236      }
3237    } else {
3238      Register index_reg = as_Register(index);
3239      if (disp == 0) {
3240        __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale)));
3241        __ ldaxr(dst_reg, rscratch1);
3242      } else {
3243        __ lea(rscratch1, Address(base, disp));
3244        __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale)));
3245        __ ldaxr(dst_reg, rscratch1);
3246      }
3247    }
3248  %}
3249
3250  enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{
3251    C2_MacroAssembler _masm(&cbuf);
3252    Register src_reg = as_Register($src$$reg);
3253    Register base = as_Register($mem$$base);
3254    int index = $mem$$index;
3255    int scale = $mem$$scale;
3256    int disp = $mem$$disp;
3257    if (index == -1) {
3258       if (disp != 0) {
3259        __ lea(rscratch2, Address(base, disp));
3260        __ stlxr(rscratch1, src_reg, rscratch2);
3261      } else {
3262        // TODO
3263        // should we ever get anything other than this case?
3264        __ stlxr(rscratch1, src_reg, base);
3265      }
3266    } else {
3267      Register index_reg = as_Register(index);
3268      if (disp == 0) {
3269        __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale)));
3270        __ stlxr(rscratch1, src_reg, rscratch2);
3271      } else {
3272        __ lea(rscratch2, Address(base, disp));
3273        __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale)));
3274        __ stlxr(rscratch1, src_reg, rscratch2);
3275      }
3276    }
3277    __ cmpw(rscratch1, zr);
3278  %}
3279
3280  enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
3281    C2_MacroAssembler _masm(&cbuf);
3282    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3283    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3284               Assembler::xword, /*acquire*/ false, /*release*/ true,
3285               /*weak*/ false, noreg);
3286  %}
3287
3288  enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3289    C2_MacroAssembler _masm(&cbuf);
3290    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3291    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3292               Assembler::word, /*acquire*/ false, /*release*/ true,
3293               /*weak*/ false, noreg);
3294  %}
3295
3296  enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3297    C2_MacroAssembler _masm(&cbuf);
3298    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3299    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3300               Assembler::halfword, /*acquire*/ false, /*release*/ true,
3301               /*weak*/ false, noreg);
3302  %}
3303
3304  enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3305    C2_MacroAssembler _masm(&cbuf);
3306    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3307    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3308               Assembler::byte, /*acquire*/ false, /*release*/ true,
3309               /*weak*/ false, noreg);
3310  %}
3311
3312
3313  // The only difference between aarch64_enc_cmpxchg and
3314  // aarch64_enc_cmpxchg_acq is that we use load-acquire in the
3315  // CompareAndSwap sequence to serve as a barrier on acquiring a
3316  // lock.
3317  enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
3318    C2_MacroAssembler _masm(&cbuf);
3319    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3320    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3321               Assembler::xword, /*acquire*/ true, /*release*/ true,
3322               /*weak*/ false, noreg);
3323  %}
3324
3325  enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3326    C2_MacroAssembler _masm(&cbuf);
3327    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3328    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3329               Assembler::word, /*acquire*/ true, /*release*/ true,
3330               /*weak*/ false, noreg);
3331  %}
3332
3333  enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3334    C2_MacroAssembler _masm(&cbuf);
3335    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3336    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3337               Assembler::halfword, /*acquire*/ true, /*release*/ true,
3338               /*weak*/ false, noreg);
3339  %}
3340
3341  enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
3342    C2_MacroAssembler _masm(&cbuf);
3343    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
3344    __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
3345               Assembler::byte, /*acquire*/ true, /*release*/ true,
3346               /*weak*/ false, noreg);
3347  %}
3348
3349  // auxiliary used for CompareAndSwapX to set result register
3350  enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
3351    C2_MacroAssembler _masm(&cbuf);
3352    Register res_reg = as_Register($res$$reg);
3353    __ cset(res_reg, Assembler::EQ);
3354  %}
3355
3356  // prefetch encodings
3357
3358  enc_class aarch64_enc_prefetchw(memory mem) %{
3359    C2_MacroAssembler _masm(&cbuf);
3360    Register base = as_Register($mem$$base);
3361    int index = $mem$$index;
3362    int scale = $mem$$scale;
3363    int disp = $mem$$disp;
3364    if (index == -1) {
3365      __ prfm(Address(base, disp), PSTL1KEEP);
3366    } else {
3367      Register index_reg = as_Register(index);
3368      if (disp == 0) {
3369        __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP);
3370      } else {
3371        __ lea(rscratch1, Address(base, disp));
3372	__ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP);
3373      }
3374    }
3375  %}
3376
3377  /// mov envcodings
3378
3379  enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{
3380    C2_MacroAssembler _masm(&cbuf);
3381    uint32_t con = (uint32_t)$src$$constant;
3382    Register dst_reg = as_Register($dst$$reg);
3383    if (con == 0) {
3384      __ movw(dst_reg, zr);
3385    } else {
3386      __ movw(dst_reg, con);
3387    }
3388  %}
3389
3390  enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{
3391    C2_MacroAssembler _masm(&cbuf);
3392    Register dst_reg = as_Register($dst$$reg);
3393    uint64_t con = (uint64_t)$src$$constant;
3394    if (con == 0) {
3395      __ mov(dst_reg, zr);
3396    } else {
3397      __ mov(dst_reg, con);
3398    }
3399  %}
3400
3401  enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
3402    C2_MacroAssembler _masm(&cbuf);
3403    Register dst_reg = as_Register($dst$$reg);
3404    address con = (address)$src$$constant;
3405    if (con == NULL || con == (address)1) {
3406      ShouldNotReachHere();
3407    } else {
3408      relocInfo::relocType rtype = $src->constant_reloc();
3409      if (rtype == relocInfo::oop_type) {
3410        __ movoop(dst_reg, (jobject)con, /*immediate*/true);
3411      } else if (rtype == relocInfo::metadata_type) {
3412        __ mov_metadata(dst_reg, (Metadata*)con);
3413      } else {
3414        assert(rtype == relocInfo::none, "unexpected reloc type");
3415        if (con < (address)(uintptr_t)os::vm_page_size()) {
3416          __ mov(dst_reg, con);
3417        } else {
3418          uint64_t offset;
3419          __ adrp(dst_reg, con, offset);
3420          __ add(dst_reg, dst_reg, offset);
3421        }
3422      }
3423    }
3424  %}
3425
3426  enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
3427    C2_MacroAssembler _masm(&cbuf);
3428    Register dst_reg = as_Register($dst$$reg);
3429    __ mov(dst_reg, zr);
3430  %}
3431
3432  enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
3433    C2_MacroAssembler _masm(&cbuf);
3434    Register dst_reg = as_Register($dst$$reg);
3435    __ mov(dst_reg, (uint64_t)1);
3436  %}
3437
3438  enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{
3439    C2_MacroAssembler _masm(&cbuf);
3440    __ load_byte_map_base($dst$$Register);
3441  %}
3442
3443  enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{
3444    C2_MacroAssembler _masm(&cbuf);
3445    Register dst_reg = as_Register($dst$$reg);
3446    address con = (address)$src$$constant;
3447    if (con == NULL) {
3448      ShouldNotReachHere();
3449    } else {
3450      relocInfo::relocType rtype = $src->constant_reloc();
3451      assert(rtype == relocInfo::oop_type, "unexpected reloc type");
3452      __ set_narrow_oop(dst_reg, (jobject)con);
3453    }
3454  %}
3455
3456  enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{
3457    C2_MacroAssembler _masm(&cbuf);
3458    Register dst_reg = as_Register($dst$$reg);
3459    __ mov(dst_reg, zr);
3460  %}
3461
3462  enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{
3463    C2_MacroAssembler _masm(&cbuf);
3464    Register dst_reg = as_Register($dst$$reg);
3465    address con = (address)$src$$constant;
3466    if (con == NULL) {
3467      ShouldNotReachHere();
3468    } else {
3469      relocInfo::relocType rtype = $src->constant_reloc();
3470      assert(rtype == relocInfo::metadata_type, "unexpected reloc type");
3471      __ set_narrow_klass(dst_reg, (Klass *)con);
3472    }
3473  %}
3474
3475  // arithmetic encodings
3476
3477  enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{
3478    C2_MacroAssembler _masm(&cbuf);
3479    Register dst_reg = as_Register($dst$$reg);
3480    Register src_reg = as_Register($src1$$reg);
3481    int32_t con = (int32_t)$src2$$constant;
3482    // add has primary == 0, subtract has primary == 1
3483    if ($primary) { con = -con; }
3484    if (con < 0) {
3485      __ subw(dst_reg, src_reg, -con);
3486    } else {
3487      __ addw(dst_reg, src_reg, con);
3488    }
3489  %}
3490
3491  enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{
3492    C2_MacroAssembler _masm(&cbuf);
3493    Register dst_reg = as_Register($dst$$reg);
3494    Register src_reg = as_Register($src1$$reg);
3495    int32_t con = (int32_t)$src2$$constant;
3496    // add has primary == 0, subtract has primary == 1
3497    if ($primary) { con = -con; }
3498    if (con < 0) {
3499      __ sub(dst_reg, src_reg, -con);
3500    } else {
3501      __ add(dst_reg, src_reg, con);
3502    }
3503  %}
3504
3505  enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{
3506    C2_MacroAssembler _masm(&cbuf);
3507   Register dst_reg = as_Register($dst$$reg);
3508   Register src1_reg = as_Register($src1$$reg);
3509   Register src2_reg = as_Register($src2$$reg);
3510    __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1);
3511  %}
3512
3513  enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
3514    C2_MacroAssembler _masm(&cbuf);
3515   Register dst_reg = as_Register($dst$$reg);
3516   Register src1_reg = as_Register($src1$$reg);
3517   Register src2_reg = as_Register($src2$$reg);
3518    __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1);
3519  %}
3520
3521  enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
3522    C2_MacroAssembler _masm(&cbuf);
3523   Register dst_reg = as_Register($dst$$reg);
3524   Register src1_reg = as_Register($src1$$reg);
3525   Register src2_reg = as_Register($src2$$reg);
3526    __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1);
3527  %}
3528
3529  enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
3530    C2_MacroAssembler _masm(&cbuf);
3531   Register dst_reg = as_Register($dst$$reg);
3532   Register src1_reg = as_Register($src1$$reg);
3533   Register src2_reg = as_Register($src2$$reg);
3534    __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1);
3535  %}
3536
3537  // compare instruction encodings
3538
3539  enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{
3540    C2_MacroAssembler _masm(&cbuf);
3541    Register reg1 = as_Register($src1$$reg);
3542    Register reg2 = as_Register($src2$$reg);
3543    __ cmpw(reg1, reg2);
3544  %}
3545
3546  enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{
3547    C2_MacroAssembler _masm(&cbuf);
3548    Register reg = as_Register($src1$$reg);
3549    int32_t val = $src2$$constant;
3550    if (val >= 0) {
3551      __ subsw(zr, reg, val);
3552    } else {
3553      __ addsw(zr, reg, -val);
3554    }
3555  %}
3556
3557  enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{
3558    C2_MacroAssembler _masm(&cbuf);
3559    Register reg1 = as_Register($src1$$reg);
3560    uint32_t val = (uint32_t)$src2$$constant;
3561    __ movw(rscratch1, val);
3562    __ cmpw(reg1, rscratch1);
3563  %}
3564
3565  enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{
3566    C2_MacroAssembler _masm(&cbuf);
3567    Register reg1 = as_Register($src1$$reg);
3568    Register reg2 = as_Register($src2$$reg);
3569    __ cmp(reg1, reg2);
3570  %}
3571
3572  enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{
3573    C2_MacroAssembler _masm(&cbuf);
3574    Register reg = as_Register($src1$$reg);
3575    int64_t val = $src2$$constant;
3576    if (val >= 0) {
3577      __ subs(zr, reg, val);
3578    } else if (val != -val) {
3579      __ adds(zr, reg, -val);
3580    } else {
3581    // aargh, Long.MIN_VALUE is a special case
3582      __ orr(rscratch1, zr, (uint64_t)val);
3583      __ subs(zr, reg, rscratch1);
3584    }
3585  %}
3586
3587  enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{
3588    C2_MacroAssembler _masm(&cbuf);
3589    Register reg1 = as_Register($src1$$reg);
3590    uint64_t val = (uint64_t)$src2$$constant;
3591    __ mov(rscratch1, val);
3592    __ cmp(reg1, rscratch1);
3593  %}
3594
3595  enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{
3596    C2_MacroAssembler _masm(&cbuf);
3597    Register reg1 = as_Register($src1$$reg);
3598    Register reg2 = as_Register($src2$$reg);
3599    __ cmp(reg1, reg2);
3600  %}
3601
3602  enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{
3603    C2_MacroAssembler _masm(&cbuf);
3604    Register reg1 = as_Register($src1$$reg);
3605    Register reg2 = as_Register($src2$$reg);
3606    __ cmpw(reg1, reg2);
3607  %}
3608
3609  enc_class aarch64_enc_testp(iRegP src) %{
3610    C2_MacroAssembler _masm(&cbuf);
3611    Register reg = as_Register($src$$reg);
3612    __ cmp(reg, zr);
3613  %}
3614
3615  enc_class aarch64_enc_testn(iRegN src) %{
3616    C2_MacroAssembler _masm(&cbuf);
3617    Register reg = as_Register($src$$reg);
3618    __ cmpw(reg, zr);
3619  %}
3620
3621  enc_class aarch64_enc_b(label lbl) %{
3622    C2_MacroAssembler _masm(&cbuf);
3623    Label *L = $lbl$$label;
3624    __ b(*L);
3625  %}
3626
3627  enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{
3628    C2_MacroAssembler _masm(&cbuf);
3629    Label *L = $lbl$$label;
3630    __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3631  %}
3632
3633  enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{
3634    C2_MacroAssembler _masm(&cbuf);
3635    Label *L = $lbl$$label;
3636    __ br ((Assembler::Condition)$cmp$$cmpcode, *L);
3637  %}
3638
3639  enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result)
3640  %{
3641     Register sub_reg = as_Register($sub$$reg);
3642     Register super_reg = as_Register($super$$reg);
3643     Register temp_reg = as_Register($temp$$reg);
3644     Register result_reg = as_Register($result$$reg);
3645
3646     Label miss;
3647     C2_MacroAssembler _masm(&cbuf);
3648     __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg,
3649                                     NULL, &miss,
3650                                     /*set_cond_codes:*/ true);
3651     if ($primary) {
3652       __ mov(result_reg, zr);
3653     }
3654     __ bind(miss);
3655  %}
3656
3657  enc_class aarch64_enc_java_static_call(method meth) %{
3658    C2_MacroAssembler _masm(&cbuf);
3659
3660    address addr = (address)$meth$$method;
3661    address call;
3662    if (!_method) {
3663      // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3664      call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf);
3665      if (call == NULL) {
3666        ciEnv::current()->record_failure("CodeCache is full");
3667        return;
3668      }
3669    } else {
3670      int method_index = resolved_method_index(cbuf);
3671      RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3672                                                  : static_call_Relocation::spec(method_index);
3673      call = __ trampoline_call(Address(addr, rspec), &cbuf);
3674      if (call == NULL) {
3675        ciEnv::current()->record_failure("CodeCache is full");
3676        return;
3677      }
3678      // Emit stub for static call
3679      address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
3680      if (stub == NULL) {
3681        ciEnv::current()->record_failure("CodeCache is full");
3682        return;
3683      }
3684    }
3685
3686    // Only non uncommon_trap calls need to reinitialize ptrue.
3687    if (Compile::current()->max_vector_size() >= 16 && uncommon_trap_request() == 0) {
3688      __ reinitialize_ptrue();
3689    }
3690  %}
3691
3692  enc_class aarch64_enc_java_dynamic_call(method meth) %{
3693    C2_MacroAssembler _masm(&cbuf);
3694    int method_index = resolved_method_index(cbuf);
3695    address call = __ ic_call((address)$meth$$method, method_index);
3696    if (call == NULL) {
3697      ciEnv::current()->record_failure("CodeCache is full");
3698      return;
3699    } else if (Compile::current()->max_vector_size() >= 16) {
3700      __ reinitialize_ptrue();
3701    }
3702  %}
3703
3704  enc_class aarch64_enc_call_epilog() %{
3705    C2_MacroAssembler _masm(&cbuf);
3706    if (VerifyStackAtCalls) {
3707      // Check that stack depth is unchanged: find majik cookie on stack
3708      __ call_Unimplemented();
3709    }
3710  %}
3711
3712  enc_class aarch64_enc_java_to_runtime(method meth) %{
3713    C2_MacroAssembler _masm(&cbuf);
3714
3715    // some calls to generated routines (arraycopy code) are scheduled
3716    // by C2 as runtime calls. if so we can call them using a br (they
3717    // will be in a reachable segment) otherwise we have to use a blr
3718    // which loads the absolute address into a register.
3719    address entry = (address)$meth$$method;
3720    CodeBlob *cb = CodeCache::find_blob(entry);
3721    if (cb) {
3722      address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type));
3723      if (call == NULL) {
3724        ciEnv::current()->record_failure("CodeCache is full");
3725        return;
3726      }
3727    } else {
3728      Label retaddr;
3729      __ adr(rscratch2, retaddr);
3730      __ lea(rscratch1, RuntimeAddress(entry));
3731      // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc()
3732      __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize)));
3733      __ blr(rscratch1);
3734      __ bind(retaddr);
3735      __ add(sp, sp, 2 * wordSize);
3736    }
3737    if (Compile::current()->max_vector_size() >= 16) {
3738      __ reinitialize_ptrue();
3739    }
3740  %}
3741
3742  enc_class aarch64_enc_rethrow() %{
3743    C2_MacroAssembler _masm(&cbuf);
3744    __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub()));
3745  %}
3746
3747  enc_class aarch64_enc_ret() %{
3748    C2_MacroAssembler _masm(&cbuf);
3749#ifdef ASSERT
3750    if (Compile::current()->max_vector_size() >= 16) {
3751      __ verify_ptrue();
3752    }
3753#endif
3754    __ ret(lr);
3755  %}
3756
3757  enc_class aarch64_enc_tail_call(iRegP jump_target) %{
3758    C2_MacroAssembler _masm(&cbuf);
3759    Register target_reg = as_Register($jump_target$$reg);
3760    __ br(target_reg);
3761  %}
3762
3763  enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{
3764    C2_MacroAssembler _masm(&cbuf);
3765    Register target_reg = as_Register($jump_target$$reg);
3766    // exception oop should be in r0
3767    // ret addr has been popped into lr
3768    // callee expects it in r3
3769    __ mov(r3, lr);
3770    __ br(target_reg);
3771  %}
3772
3773  enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{
3774    C2_MacroAssembler _masm(&cbuf);
3775    Register oop = as_Register($object$$reg);
3776    Register box = as_Register($box$$reg);
3777    Register disp_hdr = as_Register($tmp$$reg);
3778    Register tmp = as_Register($tmp2$$reg);
3779    Label cont;
3780    Label object_has_monitor;
3781    Label cas_failed;
3782
3783    assert_different_registers(oop, box, tmp, disp_hdr);
3784
3785    // Load markWord from object into displaced_header.
3786    __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
3787
3788    if (DiagnoseSyncOnValueBasedClasses != 0) {
3789      __ load_klass(tmp, oop);
3790      __ ldrw(tmp, Address(tmp, Klass::access_flags_offset()));
3791      __ tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS);
3792      __ br(Assembler::NE, cont);
3793    }
3794
3795    if (UseBiasedLocking && !UseOptoBiasInlining) {
3796      __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont);
3797    }
3798
3799    // Check for existing monitor
3800    __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
3801
3802    // Set tmp to be (markWord of object | UNLOCK_VALUE).
3803    __ orr(tmp, disp_hdr, markWord::unlocked_value);
3804
3805    // Initialize the box. (Must happen before we update the object mark!)
3806    __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3807
3808    // Compare object markWord with an unlocked value (tmp) and if
3809    // equal exchange the stack address of our box with object markWord.
3810    // On failure disp_hdr contains the possibly locked markWord.
3811    __ cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
3812               /*release*/ true, /*weak*/ false, disp_hdr);
3813    __ br(Assembler::EQ, cont);
3814
3815    assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
3816
3817    // If the compare-and-exchange succeeded, then we found an unlocked
3818    // object, will have now locked it will continue at label cont
3819
3820    __ bind(cas_failed);
3821    // We did not see an unlocked object so try the fast recursive case.
3822
3823    // Check if the owner is self by comparing the value in the
3824    // markWord of object (disp_hdr) with the stack pointer.
3825    __ mov(rscratch1, sp);
3826    __ sub(disp_hdr, disp_hdr, rscratch1);
3827    __ mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));
3828    // If condition is true we are cont and hence we can store 0 as the
3829    // displaced header in the box, which indicates that it is a recursive lock.
3830    __ ands(tmp/*==0?*/, disp_hdr, tmp);   // Sets flags for result
3831    __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3832
3833    __ b(cont);
3834
3835    // Handle existing monitor.
3836    __ bind(object_has_monitor);
3837
3838    // The object's monitor m is unlocked iff m->owner == NULL,
3839    // otherwise m->owner may contain a thread or a stack address.
3840    //
3841    // Try to CAS m->owner from NULL to current thread.
3842    __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value));
3843    __ cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true,
3844               /*release*/ true, /*weak*/ false, noreg); // Sets flags for result
3845
3846    // Store a non-null value into the box to avoid looking like a re-entrant
3847    // lock. The fast-path monitor unlock code checks for
3848    // markWord::monitor_value so use markWord::unused_mark which has the
3849    // relevant bit set, and also matches ObjectSynchronizer::enter.
3850    __ mov(tmp, (address)markWord::unused_mark().value());
3851    __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3852
3853    __ bind(cont);
3854    // flag == EQ indicates success
3855    // flag == NE indicates failure
3856  %}
3857
3858  enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{
3859    C2_MacroAssembler _masm(&cbuf);
3860    Register oop = as_Register($object$$reg);
3861    Register box = as_Register($box$$reg);
3862    Register disp_hdr = as_Register($tmp$$reg);
3863    Register tmp = as_Register($tmp2$$reg);
3864    Label cont;
3865    Label object_has_monitor;
3866
3867    assert_different_registers(oop, box, tmp, disp_hdr);
3868
3869    if (UseBiasedLocking && !UseOptoBiasInlining) {
3870      __ biased_locking_exit(oop, tmp, cont);
3871    }
3872
3873    // Find the lock address and load the displaced header from the stack.
3874    __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
3875
3876    // If the displaced header is 0, we have a recursive unlock.
3877    __ cmp(disp_hdr, zr);
3878    __ br(Assembler::EQ, cont);
3879
3880    // Handle existing monitor.
3881    __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
3882    __ tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
3883
3884    // Check if it is still a light weight lock, this is is true if we
3885    // see the stack address of the basicLock in the markWord of the
3886    // object.
3887
3888    __ cmpxchg(oop, box, disp_hdr, Assembler::xword, /*acquire*/ false,
3889               /*release*/ true, /*weak*/ false, tmp);
3890    __ b(cont);
3891
3892    assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
3893
3894    // Handle existing monitor.
3895    __ bind(object_has_monitor);
3896    STATIC_ASSERT(markWord::monitor_value <= INT_MAX);
3897    __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor
3898    __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
3899    __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes()));
3900    __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner.
3901    __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions
3902    __ cmp(rscratch1, zr); // Sets flags for result
3903    __ br(Assembler::NE, cont);
3904
3905    __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes()));
3906    __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes()));
3907    __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0.
3908    __ cmp(rscratch1, zr); // Sets flags for result
3909    __ cbnz(rscratch1, cont);
3910    // need a release store here
3911    __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
3912    __ stlr(zr, tmp); // set unowned
3913
3914    __ bind(cont);
3915    // flag == EQ indicates success
3916    // flag == NE indicates failure
3917  %}
3918
3919%}
3920
3921//----------FRAME--------------------------------------------------------------
3922// Definition of frame structure and management information.
3923//
3924//  S T A C K   L A Y O U T    Allocators stack-slot number
3925//                             |   (to get allocators register number
3926//  G  Owned by    |        |  v    add OptoReg::stack0())
3927//  r   CALLER     |        |
3928//  o     |        +--------+      pad to even-align allocators stack-slot
3929//  w     V        |  pad0  |        numbers; owned by CALLER
3930//  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
3931//  h     ^        |   in   |  5
3932//        |        |  args  |  4   Holes in incoming args owned by SELF
3933//  |     |        |        |  3
3934//  |     |        +--------+
3935//  V     |        | old out|      Empty on Intel, window on Sparc
3936//        |    old |preserve|      Must be even aligned.
3937//        |     SP-+--------+----> Matcher::_old_SP, even aligned
3938//        |        |   in   |  3   area for Intel ret address
3939//     Owned by    |preserve|      Empty on Sparc.
3940//       SELF      +--------+
3941//        |        |  pad2  |  2   pad to align old SP
3942//        |        +--------+  1
3943//        |        | locks  |  0
3944//        |        +--------+----> OptoReg::stack0(), even aligned
3945//        |        |  pad1  | 11   pad to align new SP
3946//        |        +--------+
3947//        |        |        | 10
3948//        |        | spills |  9   spills
3949//        V        |        |  8   (pad0 slot for callee)
3950//      -----------+--------+----> Matcher::_out_arg_limit, unaligned
3951//        ^        |  out   |  7
3952//        |        |  args  |  6   Holes in outgoing args owned by CALLEE
3953//     Owned by    +--------+
3954//      CALLEE     | new out|  6   Empty on Intel, window on Sparc
3955//        |    new |preserve|      Must be even-aligned.
3956//        |     SP-+--------+----> Matcher::_new_SP, even aligned
3957//        |        |        |
3958//
3959// Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
3960//         known from SELF's arguments and the Java calling convention.
3961//         Region 6-7 is determined per call site.
3962// Note 2: If the calling convention leaves holes in the incoming argument
3963//         area, those holes are owned by SELF.  Holes in the outgoing area
3964//         are owned by the CALLEE.  Holes should not be nessecary in the
3965//         incoming area, as the Java calling convention is completely under
3966//         the control of the AD file.  Doubles can be sorted and packed to
3967//         avoid holes.  Holes in the outgoing arguments may be nessecary for
3968//         varargs C calling conventions.
3969// Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
3970//         even aligned with pad0 as needed.
3971//         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
3972//           (the latter is true on Intel but is it false on AArch64?)
3973//         region 6-11 is even aligned; it may be padded out more so that
3974//         the region from SP to FP meets the minimum stack alignment.
3975// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3976//         alignment.  Region 11, pad1, may be dynamically extended so that
3977//         SP meets the minimum alignment.
3978
3979frame %{
3980  // These three registers define part of the calling convention
3981  // between compiled code and the interpreter.
3982
3983  // Inline Cache Register or Method for I2C.
3984  inline_cache_reg(R12);
3985
3986  // Number of stack slots consumed by locking an object
3987  sync_stack_slots(2);
3988
3989  // Compiled code's Frame Pointer
3990  frame_pointer(R31);
3991
3992  // Interpreter stores its frame pointer in a register which is
3993  // stored to the stack by I2CAdaptors.
3994  // I2CAdaptors convert from interpreted java to compiled java.
3995  interpreter_frame_pointer(R29);
3996
3997  // Stack alignment requirement
3998  stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
3999
4000  // Number of outgoing stack slots killed above the out_preserve_stack_slots
4001  // for calls to C.  Supports the var-args backing area for register parms.
4002  varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
4003
4004  // The after-PROLOG location of the return address.  Location of
4005  // return address specifies a type (REG or STACK) and a number
4006  // representing the register number (i.e. - use a register name) or
4007  // stack slot.
4008  // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
4009  // Otherwise, it is above the locks and verification slot and alignment word
4010  // TODO this may well be correct but need to check why that - 2 is there
4011  // ppc port uses 0 but we definitely need to allow for fixed_slots
4012  // which folds in the space used for monitors
4013  return_addr(STACK - 2 +
4014              align_up((Compile::current()->in_preserve_stack_slots() +
4015                        Compile::current()->fixed_slots()),
4016                       stack_alignment_in_slots()));
4017
4018  // Location of compiled Java return values.  Same as C for now.
4019  return_value
4020  %{
4021    // TODO do we allow ideal_reg == Op_RegN???
4022    assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
4023           "only return normal values");
4024
4025    static const int lo[Op_RegL + 1] = { // enum name
4026      0,                                 // Op_Node
4027      0,                                 // Op_Set
4028      R0_num,                            // Op_RegN
4029      R0_num,                            // Op_RegI
4030      R0_num,                            // Op_RegP
4031      V0_num,                            // Op_RegF
4032      V0_num,                            // Op_RegD
4033      R0_num                             // Op_RegL
4034    };
4035
4036    static const int hi[Op_RegL + 1] = { // enum name
4037      0,                                 // Op_Node
4038      0,                                 // Op_Set
4039      OptoReg::Bad,                      // Op_RegN
4040      OptoReg::Bad,                      // Op_RegI
4041      R0_H_num,                          // Op_RegP
4042      OptoReg::Bad,                      // Op_RegF
4043      V0_H_num,                          // Op_RegD
4044      R0_H_num                           // Op_RegL
4045    };
4046
4047    return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
4048  %}
4049%}
4050
4051//----------ATTRIBUTES---------------------------------------------------------
4052//----------Operand Attributes-------------------------------------------------
4053op_attrib op_cost(1);        // Required cost attribute
4054
4055//----------Instruction Attributes---------------------------------------------
4056ins_attrib ins_cost(INSN_COST); // Required cost attribute
4057ins_attrib ins_size(32);        // Required size attribute (in bits)
4058ins_attrib ins_short_branch(0); // Required flag: is this instruction
4059                                // a non-matching short branch variant
4060                                // of some long branch?
4061ins_attrib ins_alignment(4);    // Required alignment attribute (must
4062                                // be a power of 2) specifies the
4063                                // alignment that some part of the
4064                                // instruction (not necessarily the
4065                                // start) requires.  If > 1, a
4066                                // compute_padding() function must be
4067                                // provided for the instruction
4068
4069//----------OPERANDS-----------------------------------------------------------
4070// Operand definitions must precede instruction definitions for correct parsing
4071// in the ADLC because operands constitute user defined types which are used in
4072// instruction definitions.
4073
4074//----------Simple Operands----------------------------------------------------
4075
4076// Integer operands 32 bit
4077// 32 bit immediate
4078operand immI()
4079%{
4080  match(ConI);
4081
4082  op_cost(0);
4083  format %{ %}
4084  interface(CONST_INTER);
4085%}
4086
4087// 32 bit zero
4088operand immI0()
4089%{
4090  predicate(n->get_int() == 0);
4091  match(ConI);
4092
4093  op_cost(0);
4094  format %{ %}
4095  interface(CONST_INTER);
4096%}
4097
4098// 32 bit unit increment
4099operand immI_1()
4100%{
4101  predicate(n->get_int() == 1);
4102  match(ConI);
4103
4104  op_cost(0);
4105  format %{ %}
4106  interface(CONST_INTER);
4107%}
4108
4109// 32 bit unit decrement
4110operand immI_M1()
4111%{
4112  predicate(n->get_int() == -1);
4113  match(ConI);
4114
4115  op_cost(0);
4116  format %{ %}
4117  interface(CONST_INTER);
4118%}
4119
4120// Shift values for add/sub extension shift
4121operand immIExt()
4122%{
4123  predicate(0 <= n->get_int() && (n->get_int() <= 4));
4124  match(ConI);
4125
4126  op_cost(0);
4127  format %{ %}
4128  interface(CONST_INTER);
4129%}
4130
4131operand immI_le_4()
4132%{
4133  predicate(n->get_int() <= 4);
4134  match(ConI);
4135
4136  op_cost(0);
4137  format %{ %}
4138  interface(CONST_INTER);
4139%}
4140
4141operand immI_31()
4142%{
4143  predicate(n->get_int() == 31);
4144  match(ConI);
4145
4146  op_cost(0);
4147  format %{ %}
4148  interface(CONST_INTER);
4149%}
4150
4151operand immI_2()
4152%{
4153  predicate(n->get_int() == 2);
4154  match(ConI);
4155
4156  op_cost(0);
4157  format %{ %}
4158  interface(CONST_INTER);
4159%}
4160
4161operand immI_4()
4162%{
4163  predicate(n->get_int() == 4);
4164  match(ConI);
4165
4166  op_cost(0);
4167  format %{ %}
4168  interface(CONST_INTER);
4169%}
4170
4171operand immI_8()
4172%{
4173  predicate(n->get_int() == 8);
4174  match(ConI);
4175
4176  op_cost(0);
4177  format %{ %}
4178  interface(CONST_INTER);
4179%}
4180
4181operand immI_16()
4182%{
4183  predicate(n->get_int() == 16);
4184  match(ConI);
4185
4186  op_cost(0);
4187  format %{ %}
4188  interface(CONST_INTER);
4189%}
4190
4191operand immI_24()
4192%{
4193  predicate(n->get_int() == 24);
4194  match(ConI);
4195
4196  op_cost(0);
4197  format %{ %}
4198  interface(CONST_INTER);
4199%}
4200
4201operand immI_32()
4202%{
4203  predicate(n->get_int() == 32);
4204  match(ConI);
4205
4206  op_cost(0);
4207  format %{ %}
4208  interface(CONST_INTER);
4209%}
4210
4211operand immI_48()
4212%{
4213  predicate(n->get_int() == 48);
4214  match(ConI);
4215
4216  op_cost(0);
4217  format %{ %}
4218  interface(CONST_INTER);
4219%}
4220
4221operand immI_56()
4222%{
4223  predicate(n->get_int() == 56);
4224  match(ConI);
4225
4226  op_cost(0);
4227  format %{ %}
4228  interface(CONST_INTER);
4229%}
4230
4231operand immI_63()
4232%{
4233  predicate(n->get_int() == 63);
4234  match(ConI);
4235
4236  op_cost(0);
4237  format %{ %}
4238  interface(CONST_INTER);
4239%}
4240
4241operand immI_64()
4242%{
4243  predicate(n->get_int() == 64);
4244  match(ConI);
4245
4246  op_cost(0);
4247  format %{ %}
4248  interface(CONST_INTER);
4249%}
4250
4251operand immI_255()
4252%{
4253  predicate(n->get_int() == 255);
4254  match(ConI);
4255
4256  op_cost(0);
4257  format %{ %}
4258  interface(CONST_INTER);
4259%}
4260
4261operand immI_65535()
4262%{
4263  predicate(n->get_int() == 65535);
4264  match(ConI);
4265
4266  op_cost(0);
4267  format %{ %}
4268  interface(CONST_INTER);
4269%}
4270
4271operand immL_255()
4272%{
4273  predicate(n->get_long() == 255L);
4274  match(ConL);
4275
4276  op_cost(0);
4277  format %{ %}
4278  interface(CONST_INTER);
4279%}
4280
4281operand immL_65535()
4282%{
4283  predicate(n->get_long() == 65535L);
4284  match(ConL);
4285
4286  op_cost(0);
4287  format %{ %}
4288  interface(CONST_INTER);
4289%}
4290
4291operand immL_4294967295()
4292%{
4293  predicate(n->get_long() == 4294967295L);
4294  match(ConL);
4295
4296  op_cost(0);
4297  format %{ %}
4298  interface(CONST_INTER);
4299%}
4300
4301operand immL_bitmask()
4302%{
4303  predicate((n->get_long() != 0)
4304            && ((n->get_long() & 0xc000000000000000l) == 0)
4305            && is_power_of_2(n->get_long() + 1));
4306  match(ConL);
4307
4308  op_cost(0);
4309  format %{ %}
4310  interface(CONST_INTER);
4311%}
4312
4313operand immI_bitmask()
4314%{
4315  predicate((n->get_int() != 0)
4316            && ((n->get_int() & 0xc0000000) == 0)
4317            && is_power_of_2(n->get_int() + 1));
4318  match(ConI);
4319
4320  op_cost(0);
4321  format %{ %}
4322  interface(CONST_INTER);
4323%}
4324
4325operand immL_positive_bitmaskI()
4326%{
4327  predicate((n->get_long() != 0)
4328            && ((julong)n->get_long() < 0x80000000ULL)
4329            && is_power_of_2(n->get_long() + 1));
4330  match(ConL);
4331
4332  op_cost(0);
4333  format %{ %}
4334  interface(CONST_INTER);
4335%}
4336
4337// Scale values for scaled offset addressing modes (up to long but not quad)
4338operand immIScale()
4339%{
4340  predicate(0 <= n->get_int() && (n->get_int() <= 3));
4341  match(ConI);
4342
4343  op_cost(0);
4344  format %{ %}
4345  interface(CONST_INTER);
4346%}
4347
4348// 26 bit signed offset -- for pc-relative branches
4349operand immI26()
4350%{
4351  predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25)));
4352  match(ConI);
4353
4354  op_cost(0);
4355  format %{ %}
4356  interface(CONST_INTER);
4357%}
4358
4359// 19 bit signed offset -- for pc-relative loads
4360operand immI19()
4361%{
4362  predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18)));
4363  match(ConI);
4364
4365  op_cost(0);
4366  format %{ %}
4367  interface(CONST_INTER);
4368%}
4369
4370// 12 bit unsigned offset -- for base plus immediate loads
4371operand immIU12()
4372%{
4373  predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12)));
4374  match(ConI);
4375
4376  op_cost(0);
4377  format %{ %}
4378  interface(CONST_INTER);
4379%}
4380
4381operand immLU12()
4382%{
4383  predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12)));
4384  match(ConL);
4385
4386  op_cost(0);
4387  format %{ %}
4388  interface(CONST_INTER);
4389%}
4390
4391// Offset for scaled or unscaled immediate loads and stores
4392operand immIOffset()
4393%{
4394  predicate(Address::offset_ok_for_immed(n->get_int(), 0));
4395  match(ConI);
4396
4397  op_cost(0);
4398  format %{ %}
4399  interface(CONST_INTER);
4400%}
4401
4402operand immIOffset1()
4403%{
4404  predicate(Address::offset_ok_for_immed(n->get_int(), 0));
4405  match(ConI);
4406
4407  op_cost(0);
4408  format %{ %}
4409  interface(CONST_INTER);
4410%}
4411
4412operand immIOffset2()
4413%{
4414  predicate(Address::offset_ok_for_immed(n->get_int(), 1));
4415  match(ConI);
4416
4417  op_cost(0);
4418  format %{ %}
4419  interface(CONST_INTER);
4420%}
4421
4422operand immIOffset4()
4423%{
4424  predicate(Address::offset_ok_for_immed(n->get_int(), 2));
4425  match(ConI);
4426
4427  op_cost(0);
4428  format %{ %}
4429  interface(CONST_INTER);
4430%}
4431
4432operand immIOffset8()
4433%{
4434  predicate(Address::offset_ok_for_immed(n->get_int(), 3));
4435  match(ConI);
4436
4437  op_cost(0);
4438  format %{ %}
4439  interface(CONST_INTER);
4440%}
4441
4442operand immIOffset16()
4443%{
4444  predicate(Address::offset_ok_for_immed(n->get_int(), 4));
4445  match(ConI);
4446
4447  op_cost(0);
4448  format %{ %}
4449  interface(CONST_INTER);
4450%}
4451
4452operand immLoffset()
4453%{
4454  predicate(Address::offset_ok_for_immed(n->get_long(), 0));
4455  match(ConL);
4456
4457  op_cost(0);
4458  format %{ %}
4459  interface(CONST_INTER);
4460%}
4461
4462operand immLoffset1()
4463%{
4464  predicate(Address::offset_ok_for_immed(n->get_long(), 0));
4465  match(ConL);
4466
4467  op_cost(0);
4468  format %{ %}
4469  interface(CONST_INTER);
4470%}
4471
4472operand immLoffset2()
4473%{
4474  predicate(Address::offset_ok_for_immed(n->get_long(), 1));
4475  match(ConL);
4476
4477  op_cost(0);
4478  format %{ %}
4479  interface(CONST_INTER);
4480%}
4481
4482operand immLoffset4()
4483%{
4484  predicate(Address::offset_ok_for_immed(n->get_long(), 2));
4485  match(ConL);
4486
4487  op_cost(0);
4488  format %{ %}
4489  interface(CONST_INTER);
4490%}
4491
4492operand immLoffset8()
4493%{
4494  predicate(Address::offset_ok_for_immed(n->get_long(), 3));
4495  match(ConL);
4496
4497  op_cost(0);
4498  format %{ %}
4499  interface(CONST_INTER);
4500%}
4501
4502operand immLoffset16()
4503%{
4504  predicate(Address::offset_ok_for_immed(n->get_long(), 4));
4505  match(ConL);
4506
4507  op_cost(0);
4508  format %{ %}
4509  interface(CONST_INTER);
4510%}
4511
4512// 8 bit signed value.
4513operand immI8()
4514%{
4515  predicate(n->get_int() <= 127 && n->get_int() >= -128);
4516  match(ConI);
4517
4518  op_cost(0);
4519  format %{ %}
4520  interface(CONST_INTER);
4521%}
4522
4523// 8 bit signed value (simm8), or #simm8 LSL 8.
4524operand immI8_shift8()
4525%{
4526  predicate((n->get_int() <= 127 && n->get_int() >= -128) ||
4527            (n->get_int() <= 32512 && n->get_int() >= -32768 && (n->get_int() & 0xff) == 0));
4528  match(ConI);
4529
4530  op_cost(0);
4531  format %{ %}
4532  interface(CONST_INTER);
4533%}
4534
4535// 8 bit signed value (simm8), or #simm8 LSL 8.
4536operand immL8_shift8()
4537%{
4538  predicate((n->get_long() <= 127 && n->get_long() >= -128) ||
4539            (n->get_long() <= 32512 && n->get_long() >= -32768 && (n->get_long() & 0xff) == 0));
4540  match(ConL);
4541
4542  op_cost(0);
4543  format %{ %}
4544  interface(CONST_INTER);
4545%}
4546
4547// 32 bit integer valid for add sub immediate
4548operand immIAddSub()
4549%{
4550  predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int()));
4551  match(ConI);
4552  op_cost(0);
4553  format %{ %}
4554  interface(CONST_INTER);
4555%}
4556
4557// 32 bit unsigned integer valid for logical immediate
4558// TODO -- check this is right when e.g the mask is 0x80000000
4559operand immILog()
4560%{
4561  predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int()));
4562  match(ConI);
4563
4564  op_cost(0);
4565  format %{ %}
4566  interface(CONST_INTER);
4567%}
4568
4569// Integer operands 64 bit
4570// 64 bit immediate
4571operand immL()
4572%{
4573  match(ConL);
4574
4575  op_cost(0);
4576  format %{ %}
4577  interface(CONST_INTER);
4578%}
4579
4580// 64 bit zero
4581operand immL0()
4582%{
4583  predicate(n->get_long() == 0);
4584  match(ConL);
4585
4586  op_cost(0);
4587  format %{ %}
4588  interface(CONST_INTER);
4589%}
4590
4591// 64 bit unit increment
4592operand immL_1()
4593%{
4594  predicate(n->get_long() == 1);
4595  match(ConL);
4596
4597  op_cost(0);
4598  format %{ %}
4599  interface(CONST_INTER);
4600%}
4601
4602// 64 bit unit decrement
4603operand immL_M1()
4604%{
4605  predicate(n->get_long() == -1);
4606  match(ConL);
4607
4608  op_cost(0);
4609  format %{ %}
4610  interface(CONST_INTER);
4611%}
4612
4613// 32 bit offset of pc in thread anchor
4614
4615operand immL_pc_off()
4616%{
4617  predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) +
4618                             in_bytes(JavaFrameAnchor::last_Java_pc_offset()));
4619  match(ConL);
4620
4621  op_cost(0);
4622  format %{ %}
4623  interface(CONST_INTER);
4624%}
4625
4626// 64 bit integer valid for add sub immediate
4627operand immLAddSub()
4628%{
4629  predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long()));
4630  match(ConL);
4631  op_cost(0);
4632  format %{ %}
4633  interface(CONST_INTER);
4634%}
4635
4636// 64 bit integer valid for logical immediate
4637operand immLLog()
4638%{
4639  predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long()));
4640  match(ConL);
4641  op_cost(0);
4642  format %{ %}
4643  interface(CONST_INTER);
4644%}
4645
4646// Long Immediate: low 32-bit mask
4647operand immL_32bits()
4648%{
4649  predicate(n->get_long() == 0xFFFFFFFFL);
4650  match(ConL);
4651  op_cost(0);
4652  format %{ %}
4653  interface(CONST_INTER);
4654%}
4655
4656// Pointer operands
4657// Pointer Immediate
4658operand immP()
4659%{
4660  match(ConP);
4661
4662  op_cost(0);
4663  format %{ %}
4664  interface(CONST_INTER);
4665%}
4666
4667// NULL Pointer Immediate
4668operand immP0()
4669%{
4670  predicate(n->get_ptr() == 0);
4671  match(ConP);
4672
4673  op_cost(0);
4674  format %{ %}
4675  interface(CONST_INTER);
4676%}
4677
4678// Pointer Immediate One
4679// this is used in object initialization (initial object header)
4680operand immP_1()
4681%{
4682  predicate(n->get_ptr() == 1);
4683  match(ConP);
4684
4685  op_cost(0);
4686  format %{ %}
4687  interface(CONST_INTER);
4688%}
4689
4690// Card Table Byte Map Base
4691operand immByteMapBase()
4692%{
4693  // Get base of card map
4694  predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) &&
4695            (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base());
4696  match(ConP);
4697
4698  op_cost(0);
4699  format %{ %}
4700  interface(CONST_INTER);
4701%}
4702
4703// Pointer Immediate Minus One
4704// this is used when we want to write the current PC to the thread anchor
4705operand immP_M1()
4706%{
4707  predicate(n->get_ptr() == -1);
4708  match(ConP);
4709
4710  op_cost(0);
4711  format %{ %}
4712  interface(CONST_INTER);
4713%}
4714
4715// Pointer Immediate Minus Two
4716// this is used when we want to write the current PC to the thread anchor
4717operand immP_M2()
4718%{
4719  predicate(n->get_ptr() == -2);
4720  match(ConP);
4721
4722  op_cost(0);
4723  format %{ %}
4724  interface(CONST_INTER);
4725%}
4726
4727// Float and Double operands
4728// Double Immediate
4729operand immD()
4730%{
4731  match(ConD);
4732  op_cost(0);
4733  format %{ %}
4734  interface(CONST_INTER);
4735%}
4736
4737// Double Immediate: +0.0d
4738operand immD0()
4739%{
4740  predicate(jlong_cast(n->getd()) == 0);
4741  match(ConD);
4742
4743  op_cost(0);
4744  format %{ %}
4745  interface(CONST_INTER);
4746%}
4747
4748// constant 'double +0.0'.
4749operand immDPacked()
4750%{
4751  predicate(Assembler::operand_valid_for_float_immediate(n->getd()));
4752  match(ConD);
4753  op_cost(0);
4754  format %{ %}
4755  interface(CONST_INTER);
4756%}
4757
4758// Float Immediate
4759operand immF()
4760%{
4761  match(ConF);
4762  op_cost(0);
4763  format %{ %}
4764  interface(CONST_INTER);
4765%}
4766
4767// Float Immediate: +0.0f.
4768operand immF0()
4769%{
4770  predicate(jint_cast(n->getf()) == 0);
4771  match(ConF);
4772
4773  op_cost(0);
4774  format %{ %}
4775  interface(CONST_INTER);
4776%}
4777
4778//
4779operand immFPacked()
4780%{
4781  predicate(Assembler::operand_valid_for_float_immediate((double)n->getf()));
4782  match(ConF);
4783  op_cost(0);
4784  format %{ %}
4785  interface(CONST_INTER);
4786%}
4787
4788// Narrow pointer operands
4789// Narrow Pointer Immediate
4790operand immN()
4791%{
4792  match(ConN);
4793
4794  op_cost(0);
4795  format %{ %}
4796  interface(CONST_INTER);
4797%}
4798
4799// Narrow NULL Pointer Immediate
4800operand immN0()
4801%{
4802  predicate(n->get_narrowcon() == 0);
4803  match(ConN);
4804
4805  op_cost(0);
4806  format %{ %}
4807  interface(CONST_INTER);
4808%}
4809
4810operand immNKlass()
4811%{
4812  match(ConNKlass);
4813
4814  op_cost(0);
4815  format %{ %}
4816  interface(CONST_INTER);
4817%}
4818
4819// Integer 32 bit Register Operands
4820// Integer 32 bitRegister (excludes SP)
4821operand iRegI()
4822%{
4823  constraint(ALLOC_IN_RC(any_reg32));
4824  match(RegI);
4825  match(iRegINoSp);
4826  op_cost(0);
4827  format %{ %}
4828  interface(REG_INTER);
4829%}
4830
4831// Integer 32 bit Register not Special
4832operand iRegINoSp()
4833%{
4834  constraint(ALLOC_IN_RC(no_special_reg32));
4835  match(RegI);
4836  op_cost(0);
4837  format %{ %}
4838  interface(REG_INTER);
4839%}
4840
4841// Integer 64 bit Register Operands
4842// Integer 64 bit Register (includes SP)
4843operand iRegL()
4844%{
4845  constraint(ALLOC_IN_RC(any_reg));
4846  match(RegL);
4847  match(iRegLNoSp);
4848  op_cost(0);
4849  format %{ %}
4850  interface(REG_INTER);
4851%}
4852
4853// Integer 64 bit Register not Special
4854operand iRegLNoSp()
4855%{
4856  constraint(ALLOC_IN_RC(no_special_reg));
4857  match(RegL);
4858  match(iRegL_R0);
4859  format %{ %}
4860  interface(REG_INTER);
4861%}
4862
4863// Pointer Register Operands
4864// Pointer Register
4865operand iRegP()
4866%{
4867  constraint(ALLOC_IN_RC(ptr_reg));
4868  match(RegP);
4869  match(iRegPNoSp);
4870  match(iRegP_R0);
4871  //match(iRegP_R2);
4872  //match(iRegP_R4);
4873  //match(iRegP_R5);
4874  match(thread_RegP);
4875  op_cost(0);
4876  format %{ %}
4877  interface(REG_INTER);
4878%}
4879
4880// Pointer 64 bit Register not Special
4881operand iRegPNoSp()
4882%{
4883  constraint(ALLOC_IN_RC(no_special_ptr_reg));
4884  match(RegP);
4885  // match(iRegP);
4886  // match(iRegP_R0);
4887  // match(iRegP_R2);
4888  // match(iRegP_R4);
4889  // match(iRegP_R5);
4890  // match(thread_RegP);
4891  op_cost(0);
4892  format %{ %}
4893  interface(REG_INTER);
4894%}
4895
4896// Pointer 64 bit Register R0 only
4897operand iRegP_R0()
4898%{
4899  constraint(ALLOC_IN_RC(r0_reg));
4900  match(RegP);
4901  // match(iRegP);
4902  match(iRegPNoSp);
4903  op_cost(0);
4904  format %{ %}
4905  interface(REG_INTER);
4906%}
4907
4908// Pointer 64 bit Register R1 only
4909operand iRegP_R1()
4910%{
4911  constraint(ALLOC_IN_RC(r1_reg));
4912  match(RegP);
4913  // match(iRegP);
4914  match(iRegPNoSp);
4915  op_cost(0);
4916  format %{ %}
4917  interface(REG_INTER);
4918%}
4919
4920// Pointer 64 bit Register R2 only
4921operand iRegP_R2()
4922%{
4923  constraint(ALLOC_IN_RC(r2_reg));
4924  match(RegP);
4925  // match(iRegP);
4926  match(iRegPNoSp);
4927  op_cost(0);
4928  format %{ %}
4929  interface(REG_INTER);
4930%}
4931
4932// Pointer 64 bit Register R3 only
4933operand iRegP_R3()
4934%{
4935  constraint(ALLOC_IN_RC(r3_reg));
4936  match(RegP);
4937  // match(iRegP);
4938  match(iRegPNoSp);
4939  op_cost(0);
4940  format %{ %}
4941  interface(REG_INTER);
4942%}
4943
4944// Pointer 64 bit Register R4 only
4945operand iRegP_R4()
4946%{
4947  constraint(ALLOC_IN_RC(r4_reg));
4948  match(RegP);
4949  // match(iRegP);
4950  match(iRegPNoSp);
4951  op_cost(0);
4952  format %{ %}
4953  interface(REG_INTER);
4954%}
4955
4956// Pointer 64 bit Register R5 only
4957operand iRegP_R5()
4958%{
4959  constraint(ALLOC_IN_RC(r5_reg));
4960  match(RegP);
4961  // match(iRegP);
4962  match(iRegPNoSp);
4963  op_cost(0);
4964  format %{ %}
4965  interface(REG_INTER);
4966%}
4967
4968// Pointer 64 bit Register R10 only
4969operand iRegP_R10()
4970%{
4971  constraint(ALLOC_IN_RC(r10_reg));
4972  match(RegP);
4973  // match(iRegP);
4974  match(iRegPNoSp);
4975  op_cost(0);
4976  format %{ %}
4977  interface(REG_INTER);
4978%}
4979
4980// Long 64 bit Register R0 only
4981operand iRegL_R0()
4982%{
4983  constraint(ALLOC_IN_RC(r0_reg));
4984  match(RegL);
4985  match(iRegLNoSp);
4986  op_cost(0);
4987  format %{ %}
4988  interface(REG_INTER);
4989%}
4990
4991// Long 64 bit Register R2 only
4992operand iRegL_R2()
4993%{
4994  constraint(ALLOC_IN_RC(r2_reg));
4995  match(RegL);
4996  match(iRegLNoSp);
4997  op_cost(0);
4998  format %{ %}
4999  interface(REG_INTER);
5000%}
5001
5002// Long 64 bit Register R3 only
5003operand iRegL_R3()
5004%{
5005  constraint(ALLOC_IN_RC(r3_reg));
5006  match(RegL);
5007  match(iRegLNoSp);
5008  op_cost(0);
5009  format %{ %}
5010  interface(REG_INTER);
5011%}
5012
5013// Long 64 bit Register R11 only
5014operand iRegL_R11()
5015%{
5016  constraint(ALLOC_IN_RC(r11_reg));
5017  match(RegL);
5018  match(iRegLNoSp);
5019  op_cost(0);
5020  format %{ %}
5021  interface(REG_INTER);
5022%}
5023
5024// Pointer 64 bit Register FP only
5025operand iRegP_FP()
5026%{
5027  constraint(ALLOC_IN_RC(fp_reg));
5028  match(RegP);
5029  // match(iRegP);
5030  op_cost(0);
5031  format %{ %}
5032  interface(REG_INTER);
5033%}
5034
5035// Register R0 only
5036operand iRegI_R0()
5037%{
5038  constraint(ALLOC_IN_RC(int_r0_reg));
5039  match(RegI);
5040  match(iRegINoSp);
5041  op_cost(0);
5042  format %{ %}
5043  interface(REG_INTER);
5044%}
5045
5046// Register R2 only
5047operand iRegI_R2()
5048%{
5049  constraint(ALLOC_IN_RC(int_r2_reg));
5050  match(RegI);
5051  match(iRegINoSp);
5052  op_cost(0);
5053  format %{ %}
5054  interface(REG_INTER);
5055%}
5056
5057// Register R3 only
5058operand iRegI_R3()
5059%{
5060  constraint(ALLOC_IN_RC(int_r3_reg));
5061  match(RegI);
5062  match(iRegINoSp);
5063  op_cost(0);
5064  format %{ %}
5065  interface(REG_INTER);
5066%}
5067
5068
5069// Register R4 only
5070operand iRegI_R4()
5071%{
5072  constraint(ALLOC_IN_RC(int_r4_reg));
5073  match(RegI);
5074  match(iRegINoSp);
5075  op_cost(0);
5076  format %{ %}
5077  interface(REG_INTER);
5078%}
5079
5080
5081// Pointer Register Operands
5082// Narrow Pointer Register
5083operand iRegN()
5084%{
5085  constraint(ALLOC_IN_RC(any_reg32));
5086  match(RegN);
5087  match(iRegNNoSp);
5088  op_cost(0);
5089  format %{ %}
5090  interface(REG_INTER);
5091%}
5092
5093operand iRegN_R0()
5094%{
5095  constraint(ALLOC_IN_RC(r0_reg));
5096  match(iRegN);
5097  op_cost(0);
5098  format %{ %}
5099  interface(REG_INTER);
5100%}
5101
5102operand iRegN_R2()
5103%{
5104  constraint(ALLOC_IN_RC(r2_reg));
5105  match(iRegN);
5106  op_cost(0);
5107  format %{ %}
5108  interface(REG_INTER);
5109%}
5110
5111operand iRegN_R3()
5112%{
5113  constraint(ALLOC_IN_RC(r3_reg));
5114  match(iRegN);
5115  op_cost(0);
5116  format %{ %}
5117  interface(REG_INTER);
5118%}
5119
5120// Integer 64 bit Register not Special
5121operand iRegNNoSp()
5122%{
5123  constraint(ALLOC_IN_RC(no_special_reg32));
5124  match(RegN);
5125  op_cost(0);
5126  format %{ %}
5127  interface(REG_INTER);
5128%}
5129
5130// heap base register -- used for encoding immN0
5131
5132operand iRegIHeapbase()
5133%{
5134  constraint(ALLOC_IN_RC(heapbase_reg));
5135  match(RegI);
5136  op_cost(0);
5137  format %{ %}
5138  interface(REG_INTER);
5139%}
5140
5141// Float Register
5142// Float register operands
5143operand vRegF()
5144%{
5145  constraint(ALLOC_IN_RC(float_reg));
5146  match(RegF);
5147
5148  op_cost(0);
5149  format %{ %}
5150  interface(REG_INTER);
5151%}
5152
5153// Double Register
5154// Double register operands
5155operand vRegD()
5156%{
5157  constraint(ALLOC_IN_RC(double_reg));
5158  match(RegD);
5159
5160  op_cost(0);
5161  format %{ %}
5162  interface(REG_INTER);
5163%}
5164
5165// Generic vector class. This will be used for
5166// all vector operands, including NEON and SVE,
5167// but currently only used for SVE VecA.
5168operand vReg()
5169%{
5170  constraint(ALLOC_IN_RC(vectora_reg));
5171  match(VecA);
5172  op_cost(0);
5173  format %{ %}
5174  interface(REG_INTER);
5175%}
5176
5177operand vecD()
5178%{
5179  constraint(ALLOC_IN_RC(vectord_reg));
5180  match(VecD);
5181
5182  op_cost(0);
5183  format %{ %}
5184  interface(REG_INTER);
5185%}
5186
5187operand vecX()
5188%{
5189  constraint(ALLOC_IN_RC(vectorx_reg));
5190  match(VecX);
5191
5192  op_cost(0);
5193  format %{ %}
5194  interface(REG_INTER);
5195%}
5196
5197operand vRegD_V0()
5198%{
5199  constraint(ALLOC_IN_RC(v0_reg));
5200  match(RegD);
5201  op_cost(0);
5202  format %{ %}
5203  interface(REG_INTER);
5204%}
5205
5206operand vRegD_V1()
5207%{
5208  constraint(ALLOC_IN_RC(v1_reg));
5209  match(RegD);
5210  op_cost(0);
5211  format %{ %}
5212  interface(REG_INTER);
5213%}
5214
5215operand vRegD_V2()
5216%{
5217  constraint(ALLOC_IN_RC(v2_reg));
5218  match(RegD);
5219  op_cost(0);
5220  format %{ %}
5221  interface(REG_INTER);
5222%}
5223
5224operand vRegD_V3()
5225%{
5226  constraint(ALLOC_IN_RC(v3_reg));
5227  match(RegD);
5228  op_cost(0);
5229  format %{ %}
5230  interface(REG_INTER);
5231%}
5232
5233operand vRegD_V4()
5234%{
5235  constraint(ALLOC_IN_RC(v4_reg));
5236  match(RegD);
5237  op_cost(0);
5238  format %{ %}
5239  interface(REG_INTER);
5240%}
5241
5242operand vRegD_V5()
5243%{
5244  constraint(ALLOC_IN_RC(v5_reg));
5245  match(RegD);
5246  op_cost(0);
5247  format %{ %}
5248  interface(REG_INTER);
5249%}
5250
5251operand vRegD_V6()
5252%{
5253  constraint(ALLOC_IN_RC(v6_reg));
5254  match(RegD);
5255  op_cost(0);
5256  format %{ %}
5257  interface(REG_INTER);
5258%}
5259
5260operand vRegD_V7()
5261%{
5262  constraint(ALLOC_IN_RC(v7_reg));
5263  match(RegD);
5264  op_cost(0);
5265  format %{ %}
5266  interface(REG_INTER);
5267%}
5268
5269operand vRegD_V8()
5270%{
5271  constraint(ALLOC_IN_RC(v8_reg));
5272  match(RegD);
5273  op_cost(0);
5274  format %{ %}
5275  interface(REG_INTER);
5276%}
5277
5278operand vRegD_V9()
5279%{
5280  constraint(ALLOC_IN_RC(v9_reg));
5281  match(RegD);
5282  op_cost(0);
5283  format %{ %}
5284  interface(REG_INTER);
5285%}
5286
5287operand vRegD_V10()
5288%{
5289  constraint(ALLOC_IN_RC(v10_reg));
5290  match(RegD);
5291  op_cost(0);
5292  format %{ %}
5293  interface(REG_INTER);
5294%}
5295
5296operand vRegD_V11()
5297%{
5298  constraint(ALLOC_IN_RC(v11_reg));
5299  match(RegD);
5300  op_cost(0);
5301  format %{ %}
5302  interface(REG_INTER);
5303%}
5304
5305operand vRegD_V12()
5306%{
5307  constraint(ALLOC_IN_RC(v12_reg));
5308  match(RegD);
5309  op_cost(0);
5310  format %{ %}
5311  interface(REG_INTER);
5312%}
5313
5314operand vRegD_V13()
5315%{
5316  constraint(ALLOC_IN_RC(v13_reg));
5317  match(RegD);
5318  op_cost(0);
5319  format %{ %}
5320  interface(REG_INTER);
5321%}
5322
5323operand vRegD_V14()
5324%{
5325  constraint(ALLOC_IN_RC(v14_reg));
5326  match(RegD);
5327  op_cost(0);
5328  format %{ %}
5329  interface(REG_INTER);
5330%}
5331
5332operand vRegD_V15()
5333%{
5334  constraint(ALLOC_IN_RC(v15_reg));
5335  match(RegD);
5336  op_cost(0);
5337  format %{ %}
5338  interface(REG_INTER);
5339%}
5340
5341operand vRegD_V16()
5342%{
5343  constraint(ALLOC_IN_RC(v16_reg));
5344  match(RegD);
5345  op_cost(0);
5346  format %{ %}
5347  interface(REG_INTER);
5348%}
5349
5350operand vRegD_V17()
5351%{
5352  constraint(ALLOC_IN_RC(v17_reg));
5353  match(RegD);
5354  op_cost(0);
5355  format %{ %}
5356  interface(REG_INTER);
5357%}
5358
5359operand vRegD_V18()
5360%{
5361  constraint(ALLOC_IN_RC(v18_reg));
5362  match(RegD);
5363  op_cost(0);
5364  format %{ %}
5365  interface(REG_INTER);
5366%}
5367
5368operand vRegD_V19()
5369%{
5370  constraint(ALLOC_IN_RC(v19_reg));
5371  match(RegD);
5372  op_cost(0);
5373  format %{ %}
5374  interface(REG_INTER);
5375%}
5376
5377operand vRegD_V20()
5378%{
5379  constraint(ALLOC_IN_RC(v20_reg));
5380  match(RegD);
5381  op_cost(0);
5382  format %{ %}
5383  interface(REG_INTER);
5384%}
5385
5386operand vRegD_V21()
5387%{
5388  constraint(ALLOC_IN_RC(v21_reg));
5389  match(RegD);
5390  op_cost(0);
5391  format %{ %}
5392  interface(REG_INTER);
5393%}
5394
5395operand vRegD_V22()
5396%{
5397  constraint(ALLOC_IN_RC(v22_reg));
5398  match(RegD);
5399  op_cost(0);
5400  format %{ %}
5401  interface(REG_INTER);
5402%}
5403
5404operand vRegD_V23()
5405%{
5406  constraint(ALLOC_IN_RC(v23_reg));
5407  match(RegD);
5408  op_cost(0);
5409  format %{ %}
5410  interface(REG_INTER);
5411%}
5412
5413operand vRegD_V24()
5414%{
5415  constraint(ALLOC_IN_RC(v24_reg));
5416  match(RegD);
5417  op_cost(0);
5418  format %{ %}
5419  interface(REG_INTER);
5420%}
5421
5422operand vRegD_V25()
5423%{
5424  constraint(ALLOC_IN_RC(v25_reg));
5425  match(RegD);
5426  op_cost(0);
5427  format %{ %}
5428  interface(REG_INTER);
5429%}
5430
5431operand vRegD_V26()
5432%{
5433  constraint(ALLOC_IN_RC(v26_reg));
5434  match(RegD);
5435  op_cost(0);
5436  format %{ %}
5437  interface(REG_INTER);
5438%}
5439
5440operand vRegD_V27()
5441%{
5442  constraint(ALLOC_IN_RC(v27_reg));
5443  match(RegD);
5444  op_cost(0);
5445  format %{ %}
5446  interface(REG_INTER);
5447%}
5448
5449operand vRegD_V28()
5450%{
5451  constraint(ALLOC_IN_RC(v28_reg));
5452  match(RegD);
5453  op_cost(0);
5454  format %{ %}
5455  interface(REG_INTER);
5456%}
5457
5458operand vRegD_V29()
5459%{
5460  constraint(ALLOC_IN_RC(v29_reg));
5461  match(RegD);
5462  op_cost(0);
5463  format %{ %}
5464  interface(REG_INTER);
5465%}
5466
5467operand vRegD_V30()
5468%{
5469  constraint(ALLOC_IN_RC(v30_reg));
5470  match(RegD);
5471  op_cost(0);
5472  format %{ %}
5473  interface(REG_INTER);
5474%}
5475
5476operand vRegD_V31()
5477%{
5478  constraint(ALLOC_IN_RC(v31_reg));
5479  match(RegD);
5480  op_cost(0);
5481  format %{ %}
5482  interface(REG_INTER);
5483%}
5484
5485operand pRegGov()
5486%{
5487  constraint(ALLOC_IN_RC(gov_pr));
5488  match(RegVectMask);
5489  op_cost(0);
5490  format %{ %}
5491  interface(REG_INTER);
5492%}
5493
5494// Flags register, used as output of signed compare instructions
5495
5496// note that on AArch64 we also use this register as the output for
5497// for floating point compare instructions (CmpF CmpD). this ensures
5498// that ordered inequality tests use GT, GE, LT or LE none of which
5499// pass through cases where the result is unordered i.e. one or both
5500// inputs to the compare is a NaN. this means that the ideal code can
5501// replace e.g. a GT with an LE and not end up capturing the NaN case
5502// (where the comparison should always fail). EQ and NE tests are
5503// always generated in ideal code so that unordered folds into the NE
5504// case, matching the behaviour of AArch64 NE.
5505//
5506// This differs from x86 where the outputs of FP compares use a
5507// special FP flags registers and where compares based on this
5508// register are distinguished into ordered inequalities (cmpOpUCF) and
5509// EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests
5510// to explicitly handle the unordered case in branches. x86 also has
5511// to include extra CMoveX rules to accept a cmpOpUCF input.
5512
5513operand rFlagsReg()
5514%{
5515  constraint(ALLOC_IN_RC(int_flags));
5516  match(RegFlags);
5517
5518  op_cost(0);
5519  format %{ "RFLAGS" %}
5520  interface(REG_INTER);
5521%}
5522
5523// Flags register, used as output of unsigned compare instructions
5524operand rFlagsRegU()
5525%{
5526  constraint(ALLOC_IN_RC(int_flags));
5527  match(RegFlags);
5528
5529  op_cost(0);
5530  format %{ "RFLAGSU" %}
5531  interface(REG_INTER);
5532%}
5533
5534// Special Registers
5535
5536// Method Register
5537operand inline_cache_RegP(iRegP reg)
5538%{
5539  constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg
5540  match(reg);
5541  match(iRegPNoSp);
5542  op_cost(0);
5543  format %{ %}
5544  interface(REG_INTER);
5545%}
5546
5547// Thread Register
5548operand thread_RegP(iRegP reg)
5549%{
5550  constraint(ALLOC_IN_RC(thread_reg)); // link_reg
5551  match(reg);
5552  op_cost(0);
5553  format %{ %}
5554  interface(REG_INTER);
5555%}
5556
5557operand lr_RegP(iRegP reg)
5558%{
5559  constraint(ALLOC_IN_RC(lr_reg)); // link_reg
5560  match(reg);
5561  op_cost(0);
5562  format %{ %}
5563  interface(REG_INTER);
5564%}
5565
5566//----------Memory Operands----------------------------------------------------
5567
5568operand indirect(iRegP reg)
5569%{
5570  constraint(ALLOC_IN_RC(ptr_reg));
5571  match(reg);
5572  op_cost(0);
5573  format %{ "[$reg]" %}
5574  interface(MEMORY_INTER) %{
5575    base($reg);
5576    index(0xffffffff);
5577    scale(0x0);
5578    disp(0x0);
5579  %}
5580%}
5581
5582operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale)
5583%{
5584  constraint(ALLOC_IN_RC(ptr_reg));
5585  predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5586  match(AddP reg (LShiftL (ConvI2L ireg) scale));
5587  op_cost(0);
5588  format %{ "$reg, $ireg sxtw($scale), 0, I2L" %}
5589  interface(MEMORY_INTER) %{
5590    base($reg);
5591    index($ireg);
5592    scale($scale);
5593    disp(0x0);
5594  %}
5595%}
5596
5597operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale)
5598%{
5599  constraint(ALLOC_IN_RC(ptr_reg));
5600  predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5601  match(AddP reg (LShiftL lreg scale));
5602  op_cost(0);
5603  format %{ "$reg, $lreg lsl($scale)" %}
5604  interface(MEMORY_INTER) %{
5605    base($reg);
5606    index($lreg);
5607    scale($scale);
5608    disp(0x0);
5609  %}
5610%}
5611
5612operand indIndexI2L(iRegP reg, iRegI ireg)
5613%{
5614  constraint(ALLOC_IN_RC(ptr_reg));
5615  match(AddP reg (ConvI2L ireg));
5616  op_cost(0);
5617  format %{ "$reg, $ireg, 0, I2L" %}
5618  interface(MEMORY_INTER) %{
5619    base($reg);
5620    index($ireg);
5621    scale(0x0);
5622    disp(0x0);
5623  %}
5624%}
5625
5626operand indIndex(iRegP reg, iRegL lreg)
5627%{
5628  constraint(ALLOC_IN_RC(ptr_reg));
5629  match(AddP reg lreg);
5630  op_cost(0);
5631  format %{ "$reg, $lreg" %}
5632  interface(MEMORY_INTER) %{
5633    base($reg);
5634    index($lreg);
5635    scale(0x0);
5636    disp(0x0);
5637  %}
5638%}
5639
5640operand indOffI(iRegP reg, immIOffset off)
5641%{
5642  constraint(ALLOC_IN_RC(ptr_reg));
5643  match(AddP reg off);
5644  op_cost(0);
5645  format %{ "[$reg, $off]" %}
5646  interface(MEMORY_INTER) %{
5647    base($reg);
5648    index(0xffffffff);
5649    scale(0x0);
5650    disp($off);
5651  %}
5652%}
5653
5654operand indOffI1(iRegP reg, immIOffset1 off)
5655%{
5656  constraint(ALLOC_IN_RC(ptr_reg));
5657  match(AddP reg off);
5658  op_cost(0);
5659  format %{ "[$reg, $off]" %}
5660  interface(MEMORY_INTER) %{
5661    base($reg);
5662    index(0xffffffff);
5663    scale(0x0);
5664    disp($off);
5665  %}
5666%}
5667
5668operand indOffI2(iRegP reg, immIOffset2 off)
5669%{
5670  constraint(ALLOC_IN_RC(ptr_reg));
5671  match(AddP reg off);
5672  op_cost(0);
5673  format %{ "[$reg, $off]" %}
5674  interface(MEMORY_INTER) %{
5675    base($reg);
5676    index(0xffffffff);
5677    scale(0x0);
5678    disp($off);
5679  %}
5680%}
5681
5682operand indOffI4(iRegP reg, immIOffset4 off)
5683%{
5684  constraint(ALLOC_IN_RC(ptr_reg));
5685  match(AddP reg off);
5686  op_cost(0);
5687  format %{ "[$reg, $off]" %}
5688  interface(MEMORY_INTER) %{
5689    base($reg);
5690    index(0xffffffff);
5691    scale(0x0);
5692    disp($off);
5693  %}
5694%}
5695
5696operand indOffI8(iRegP reg, immIOffset8 off)
5697%{
5698  constraint(ALLOC_IN_RC(ptr_reg));
5699  match(AddP reg off);
5700  op_cost(0);
5701  format %{ "[$reg, $off]" %}
5702  interface(MEMORY_INTER) %{
5703    base($reg);
5704    index(0xffffffff);
5705    scale(0x0);
5706    disp($off);
5707  %}
5708%}
5709
5710operand indOffI16(iRegP reg, immIOffset16 off)
5711%{
5712  constraint(ALLOC_IN_RC(ptr_reg));
5713  match(AddP reg off);
5714  op_cost(0);
5715  format %{ "[$reg, $off]" %}
5716  interface(MEMORY_INTER) %{
5717    base($reg);
5718    index(0xffffffff);
5719    scale(0x0);
5720    disp($off);
5721  %}
5722%}
5723
5724operand indOffL(iRegP reg, immLoffset off)
5725%{
5726  constraint(ALLOC_IN_RC(ptr_reg));
5727  match(AddP reg off);
5728  op_cost(0);
5729  format %{ "[$reg, $off]" %}
5730  interface(MEMORY_INTER) %{
5731    base($reg);
5732    index(0xffffffff);
5733    scale(0x0);
5734    disp($off);
5735  %}
5736%}
5737
5738operand indOffL1(iRegP reg, immLoffset1 off)
5739%{
5740  constraint(ALLOC_IN_RC(ptr_reg));
5741  match(AddP reg off);
5742  op_cost(0);
5743  format %{ "[$reg, $off]" %}
5744  interface(MEMORY_INTER) %{
5745    base($reg);
5746    index(0xffffffff);
5747    scale(0x0);
5748    disp($off);
5749  %}
5750%}
5751
5752operand indOffL2(iRegP reg, immLoffset2 off)
5753%{
5754  constraint(ALLOC_IN_RC(ptr_reg));
5755  match(AddP reg off);
5756  op_cost(0);
5757  format %{ "[$reg, $off]" %}
5758  interface(MEMORY_INTER) %{
5759    base($reg);
5760    index(0xffffffff);
5761    scale(0x0);
5762    disp($off);
5763  %}
5764%}
5765
5766operand indOffL4(iRegP reg, immLoffset4 off)
5767%{
5768  constraint(ALLOC_IN_RC(ptr_reg));
5769  match(AddP reg off);
5770  op_cost(0);
5771  format %{ "[$reg, $off]" %}
5772  interface(MEMORY_INTER) %{
5773    base($reg);
5774    index(0xffffffff);
5775    scale(0x0);
5776    disp($off);
5777  %}
5778%}
5779
5780operand indOffL8(iRegP reg, immLoffset8 off)
5781%{
5782  constraint(ALLOC_IN_RC(ptr_reg));
5783  match(AddP reg off);
5784  op_cost(0);
5785  format %{ "[$reg, $off]" %}
5786  interface(MEMORY_INTER) %{
5787    base($reg);
5788    index(0xffffffff);
5789    scale(0x0);
5790    disp($off);
5791  %}
5792%}
5793
5794operand indOffL16(iRegP reg, immLoffset16 off)
5795%{
5796  constraint(ALLOC_IN_RC(ptr_reg));
5797  match(AddP reg off);
5798  op_cost(0);
5799  format %{ "[$reg, $off]" %}
5800  interface(MEMORY_INTER) %{
5801    base($reg);
5802    index(0xffffffff);
5803    scale(0x0);
5804    disp($off);
5805  %}
5806%}
5807
5808operand indirectN(iRegN reg)
5809%{
5810  predicate(CompressedOops::shift() == 0);
5811  constraint(ALLOC_IN_RC(ptr_reg));
5812  match(DecodeN reg);
5813  op_cost(0);
5814  format %{ "[$reg]\t# narrow" %}
5815  interface(MEMORY_INTER) %{
5816    base($reg);
5817    index(0xffffffff);
5818    scale(0x0);
5819    disp(0x0);
5820  %}
5821%}
5822
5823operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale)
5824%{
5825  predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5826  constraint(ALLOC_IN_RC(ptr_reg));
5827  match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale));
5828  op_cost(0);
5829  format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %}
5830  interface(MEMORY_INTER) %{
5831    base($reg);
5832    index($ireg);
5833    scale($scale);
5834    disp(0x0);
5835  %}
5836%}
5837
5838operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale)
5839%{
5840  predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int()));
5841  constraint(ALLOC_IN_RC(ptr_reg));
5842  match(AddP (DecodeN reg) (LShiftL lreg scale));
5843  op_cost(0);
5844  format %{ "$reg, $lreg lsl($scale)\t# narrow" %}
5845  interface(MEMORY_INTER) %{
5846    base($reg);
5847    index($lreg);
5848    scale($scale);
5849    disp(0x0);
5850  %}
5851%}
5852
5853operand indIndexI2LN(iRegN reg, iRegI ireg)
5854%{
5855  predicate(CompressedOops::shift() == 0);
5856  constraint(ALLOC_IN_RC(ptr_reg));
5857  match(AddP (DecodeN reg) (ConvI2L ireg));
5858  op_cost(0);
5859  format %{ "$reg, $ireg, 0, I2L\t# narrow" %}
5860  interface(MEMORY_INTER) %{
5861    base($reg);
5862    index($ireg);
5863    scale(0x0);
5864    disp(0x0);
5865  %}
5866%}
5867
5868operand indIndexN(iRegN reg, iRegL lreg)
5869%{
5870  predicate(CompressedOops::shift() == 0);
5871  constraint(ALLOC_IN_RC(ptr_reg));
5872  match(AddP (DecodeN reg) lreg);
5873  op_cost(0);
5874  format %{ "$reg, $lreg\t# narrow" %}
5875  interface(MEMORY_INTER) %{
5876    base($reg);
5877    index($lreg);
5878    scale(0x0);
5879    disp(0x0);
5880  %}
5881%}
5882
5883operand indOffIN(iRegN reg, immIOffset off)
5884%{
5885  predicate(CompressedOops::shift() == 0);
5886  constraint(ALLOC_IN_RC(ptr_reg));
5887  match(AddP (DecodeN reg) off);
5888  op_cost(0);
5889  format %{ "[$reg, $off]\t# narrow" %}
5890  interface(MEMORY_INTER) %{
5891    base($reg);
5892    index(0xffffffff);
5893    scale(0x0);
5894    disp($off);
5895  %}
5896%}
5897
5898operand indOffLN(iRegN reg, immLoffset off)
5899%{
5900  predicate(CompressedOops::shift() == 0);
5901  constraint(ALLOC_IN_RC(ptr_reg));
5902  match(AddP (DecodeN reg) off);
5903  op_cost(0);
5904  format %{ "[$reg, $off]\t# narrow" %}
5905  interface(MEMORY_INTER) %{
5906    base($reg);
5907    index(0xffffffff);
5908    scale(0x0);
5909    disp($off);
5910  %}
5911%}
5912
5913
5914
5915// AArch64 opto stubs need to write to the pc slot in the thread anchor
5916operand thread_anchor_pc(thread_RegP reg, immL_pc_off off)
5917%{
5918  constraint(ALLOC_IN_RC(ptr_reg));
5919  match(AddP reg off);
5920  op_cost(0);
5921  format %{ "[$reg, $off]" %}
5922  interface(MEMORY_INTER) %{
5923    base($reg);
5924    index(0xffffffff);
5925    scale(0x0);
5926    disp($off);
5927  %}
5928%}
5929
5930//----------Special Memory Operands--------------------------------------------
5931// Stack Slot Operand - This operand is used for loading and storing temporary
5932//                      values on the stack where a match requires a value to
5933//                      flow through memory.
5934operand stackSlotP(sRegP reg)
5935%{
5936  constraint(ALLOC_IN_RC(stack_slots));
5937  op_cost(100);
5938  // No match rule because this operand is only generated in matching
5939  // match(RegP);
5940  format %{ "[$reg]" %}
5941  interface(MEMORY_INTER) %{
5942    base(0x1e);  // RSP
5943    index(0x0);  // No Index
5944    scale(0x0);  // No Scale
5945    disp($reg);  // Stack Offset
5946  %}
5947%}
5948
5949operand stackSlotI(sRegI reg)
5950%{
5951  constraint(ALLOC_IN_RC(stack_slots));
5952  // No match rule because this operand is only generated in matching
5953  // match(RegI);
5954  format %{ "[$reg]" %}
5955  interface(MEMORY_INTER) %{
5956    base(0x1e);  // RSP
5957    index(0x0);  // No Index
5958    scale(0x0);  // No Scale
5959    disp($reg);  // Stack Offset
5960  %}
5961%}
5962
5963operand stackSlotF(sRegF reg)
5964%{
5965  constraint(ALLOC_IN_RC(stack_slots));
5966  // No match rule because this operand is only generated in matching
5967  // match(RegF);
5968  format %{ "[$reg]" %}
5969  interface(MEMORY_INTER) %{
5970    base(0x1e);  // RSP
5971    index(0x0);  // No Index
5972    scale(0x0);  // No Scale
5973    disp($reg);  // Stack Offset
5974  %}
5975%}
5976
5977operand stackSlotD(sRegD reg)
5978%{
5979  constraint(ALLOC_IN_RC(stack_slots));
5980  // No match rule because this operand is only generated in matching
5981  // match(RegD);
5982  format %{ "[$reg]" %}
5983  interface(MEMORY_INTER) %{
5984    base(0x1e);  // RSP
5985    index(0x0);  // No Index
5986    scale(0x0);  // No Scale
5987    disp($reg);  // Stack Offset
5988  %}
5989%}
5990
5991operand stackSlotL(sRegL reg)
5992%{
5993  constraint(ALLOC_IN_RC(stack_slots));
5994  // No match rule because this operand is only generated in matching
5995  // match(RegL);
5996  format %{ "[$reg]" %}
5997  interface(MEMORY_INTER) %{
5998    base(0x1e);  // RSP
5999    index(0x0);  // No Index
6000    scale(0x0);  // No Scale
6001    disp($reg);  // Stack Offset
6002  %}
6003%}
6004
6005// Operands for expressing Control Flow
6006// NOTE: Label is a predefined operand which should not be redefined in
6007//       the AD file. It is generically handled within the ADLC.
6008
6009//----------Conditional Branch Operands----------------------------------------
6010// Comparison Op  - This is the operation of the comparison, and is limited to
6011//                  the following set of codes:
6012//                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
6013//
6014// Other attributes of the comparison, such as unsignedness, are specified
6015// by the comparison instruction that sets a condition code flags register.
6016// That result is represented by a flags operand whose subtype is appropriate
6017// to the unsignedness (etc.) of the comparison.
6018//
6019// Later, the instruction which matches both the Comparison Op (a Bool) and
6020// the flags (produced by the Cmp) specifies the coding of the comparison op
6021// by matching a specific subtype of Bool operand below, such as cmpOpU.
6022
6023// used for signed integral comparisons and fp comparisons
6024
6025operand cmpOp()
6026%{
6027  match(Bool);
6028
6029  format %{ "" %}
6030  interface(COND_INTER) %{
6031    equal(0x0, "eq");
6032    not_equal(0x1, "ne");
6033    less(0xb, "lt");
6034    greater_equal(0xa, "ge");
6035    less_equal(0xd, "le");
6036    greater(0xc, "gt");
6037    overflow(0x6, "vs");
6038    no_overflow(0x7, "vc");
6039  %}
6040%}
6041
6042// used for unsigned integral comparisons
6043
6044operand cmpOpU()
6045%{
6046  match(Bool);
6047
6048  format %{ "" %}
6049  interface(COND_INTER) %{
6050    equal(0x0, "eq");
6051    not_equal(0x1, "ne");
6052    less(0x3, "lo");
6053    greater_equal(0x2, "hs");
6054    less_equal(0x9, "ls");
6055    greater(0x8, "hi");
6056    overflow(0x6, "vs");
6057    no_overflow(0x7, "vc");
6058  %}
6059%}
6060
6061// used for certain integral comparisons which can be
6062// converted to cbxx or tbxx instructions
6063
6064operand cmpOpEqNe()
6065%{
6066  match(Bool);
6067  op_cost(0);
6068  predicate(n->as_Bool()->_test._test == BoolTest::ne
6069            || n->as_Bool()->_test._test == BoolTest::eq);
6070
6071  format %{ "" %}
6072  interface(COND_INTER) %{
6073    equal(0x0, "eq");
6074    not_equal(0x1, "ne");
6075    less(0xb, "lt");
6076    greater_equal(0xa, "ge");
6077    less_equal(0xd, "le");
6078    greater(0xc, "gt");
6079    overflow(0x6, "vs");
6080    no_overflow(0x7, "vc");
6081  %}
6082%}
6083
6084// used for certain integral comparisons which can be
6085// converted to cbxx or tbxx instructions
6086
6087operand cmpOpLtGe()
6088%{
6089  match(Bool);
6090  op_cost(0);
6091
6092  predicate(n->as_Bool()->_test._test == BoolTest::lt
6093            || n->as_Bool()->_test._test == BoolTest::ge);
6094
6095  format %{ "" %}
6096  interface(COND_INTER) %{
6097    equal(0x0, "eq");
6098    not_equal(0x1, "ne");
6099    less(0xb, "lt");
6100    greater_equal(0xa, "ge");
6101    less_equal(0xd, "le");
6102    greater(0xc, "gt");
6103    overflow(0x6, "vs");
6104    no_overflow(0x7, "vc");
6105  %}
6106%}
6107
6108// used for certain unsigned integral comparisons which can be
6109// converted to cbxx or tbxx instructions
6110
6111operand cmpOpUEqNeLtGe()
6112%{
6113  match(Bool);
6114  op_cost(0);
6115
6116  predicate(n->as_Bool()->_test._test == BoolTest::eq
6117            || n->as_Bool()->_test._test == BoolTest::ne
6118            || n->as_Bool()->_test._test == BoolTest::lt
6119            || n->as_Bool()->_test._test == BoolTest::ge);
6120
6121  format %{ "" %}
6122  interface(COND_INTER) %{
6123    equal(0x0, "eq");
6124    not_equal(0x1, "ne");
6125    less(0xb, "lt");
6126    greater_equal(0xa, "ge");
6127    less_equal(0xd, "le");
6128    greater(0xc, "gt");
6129    overflow(0x6, "vs");
6130    no_overflow(0x7, "vc");
6131  %}
6132%}
6133
6134// Special operand allowing long args to int ops to be truncated for free
6135
6136operand iRegL2I(iRegL reg) %{
6137
6138  op_cost(0);
6139
6140  match(ConvL2I reg);
6141
6142  format %{ "l2i($reg)" %}
6143
6144  interface(REG_INTER)
6145%}
6146
6147opclass vmem2(indirect, indIndex, indOffI2, indOffL2);
6148opclass vmem4(indirect, indIndex, indOffI4, indOffL4);
6149opclass vmem8(indirect, indIndex, indOffI8, indOffL8);
6150opclass vmem16(indirect, indIndex, indOffI16, indOffL16);
6151
6152//----------OPERAND CLASSES----------------------------------------------------
6153// Operand Classes are groups of operands that are used as to simplify
6154// instruction definitions by not requiring the AD writer to specify
6155// separate instructions for every form of operand when the
6156// instruction accepts multiple operand types with the same basic
6157// encoding and format. The classic case of this is memory operands.
6158
6159// memory is used to define read/write location for load/store
6160// instruction defs. we can turn a memory op into an Address
6161
6162opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1,
6163               indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN);
6164
6165opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2,
6166               indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN);
6167
6168opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4,
6169               indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN);
6170
6171opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8,
6172               indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN);
6173
6174// All of the memory operands. For the pipeline description.
6175opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex,
6176               indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8,
6177               indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN);
6178
6179
6180// iRegIorL2I is used for src inputs in rules for 32 bit int (I)
6181// operations. it allows the src to be either an iRegI or a (ConvL2I
6182// iRegL). in the latter case the l2i normally planted for a ConvL2I
6183// can be elided because the 32-bit instruction will just employ the
6184// lower 32 bits anyway.
6185//
6186// n.b. this does not elide all L2I conversions. if the truncated
6187// value is consumed by more than one operation then the ConvL2I
6188// cannot be bundled into the consuming nodes so an l2i gets planted
6189// (actually a movw $dst $src) and the downstream instructions consume
6190// the result of the l2i as an iRegI input. That's a shame since the
6191// movw is actually redundant but its not too costly.
6192
6193opclass iRegIorL2I(iRegI, iRegL2I);
6194
6195//----------PIPELINE-----------------------------------------------------------
6196// Rules which define the behavior of the target architectures pipeline.
6197
6198// For specific pipelines, eg A53, define the stages of that pipeline
6199//pipe_desc(ISS, EX1, EX2, WR);
6200#define ISS S0
6201#define EX1 S1
6202#define EX2 S2
6203#define WR  S3
6204
6205// Integer ALU reg operation
6206pipeline %{
6207
6208attributes %{
6209  // ARM instructions are of fixed length
6210  fixed_size_instructions;        // Fixed size instructions TODO does
6211  max_instructions_per_bundle = 4;   // A53 = 2, A57 = 4
6212  // ARM instructions come in 32-bit word units
6213  instruction_unit_size = 4;         // An instruction is 4 bytes long
6214  instruction_fetch_unit_size = 64;  // The processor fetches one line
6215  instruction_fetch_units = 1;       // of 64 bytes
6216
6217  // List of nop instructions
6218  nops( MachNop );
6219%}
6220
6221// We don't use an actual pipeline model so don't care about resources
6222// or description. we do use pipeline classes to introduce fixed
6223// latencies
6224
6225//----------RESOURCES----------------------------------------------------------
6226// Resources are the functional units available to the machine
6227
6228resources( INS0, INS1, INS01 = INS0 | INS1,
6229           ALU0, ALU1, ALU = ALU0 | ALU1,
6230           MAC,
6231           DIV,
6232           BRANCH,
6233           LDST,
6234           NEON_FP);
6235
6236//----------PIPELINE DESCRIPTION-----------------------------------------------
6237// Pipeline Description specifies the stages in the machine's pipeline
6238
6239// Define the pipeline as a generic 6 stage pipeline
6240pipe_desc(S0, S1, S2, S3, S4, S5);
6241
6242//----------PIPELINE CLASSES---------------------------------------------------
6243// Pipeline Classes describe the stages in which input and output are
6244// referenced by the hardware pipeline.
6245
6246pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2)
6247%{
6248  single_instruction;
6249  src1   : S1(read);
6250  src2   : S2(read);
6251  dst    : S5(write);
6252  INS01  : ISS;
6253  NEON_FP : S5;
6254%}
6255
6256pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2)
6257%{
6258  single_instruction;
6259  src1   : S1(read);
6260  src2   : S2(read);
6261  dst    : S5(write);
6262  INS01  : ISS;
6263  NEON_FP : S5;
6264%}
6265
6266pipe_class fp_uop_s(vRegF dst, vRegF src)
6267%{
6268  single_instruction;
6269  src    : S1(read);
6270  dst    : S5(write);
6271  INS01  : ISS;
6272  NEON_FP : S5;
6273%}
6274
6275pipe_class fp_uop_d(vRegD dst, vRegD src)
6276%{
6277  single_instruction;
6278  src    : S1(read);
6279  dst    : S5(write);
6280  INS01  : ISS;
6281  NEON_FP : S5;
6282%}
6283
6284pipe_class fp_d2f(vRegF dst, vRegD src)
6285%{
6286  single_instruction;
6287  src    : S1(read);
6288  dst    : S5(write);
6289  INS01  : ISS;
6290  NEON_FP : S5;
6291%}
6292
6293pipe_class fp_f2d(vRegD dst, vRegF src)
6294%{
6295  single_instruction;
6296  src    : S1(read);
6297  dst    : S5(write);
6298  INS01  : ISS;
6299  NEON_FP : S5;
6300%}
6301
6302pipe_class fp_f2i(iRegINoSp dst, vRegF src)
6303%{
6304  single_instruction;
6305  src    : S1(read);
6306  dst    : S5(write);
6307  INS01  : ISS;
6308  NEON_FP : S5;
6309%}
6310
6311pipe_class fp_f2l(iRegLNoSp dst, vRegF src)
6312%{
6313  single_instruction;
6314  src    : S1(read);
6315  dst    : S5(write);
6316  INS01  : ISS;
6317  NEON_FP : S5;
6318%}
6319
6320pipe_class fp_i2f(vRegF dst, iRegIorL2I src)
6321%{
6322  single_instruction;
6323  src    : S1(read);
6324  dst    : S5(write);
6325  INS01  : ISS;
6326  NEON_FP : S5;
6327%}
6328
6329pipe_class fp_l2f(vRegF dst, iRegL src)
6330%{
6331  single_instruction;
6332  src    : S1(read);
6333  dst    : S5(write);
6334  INS01  : ISS;
6335  NEON_FP : S5;
6336%}
6337
6338pipe_class fp_d2i(iRegINoSp dst, vRegD src)
6339%{
6340  single_instruction;
6341  src    : S1(read);
6342  dst    : S5(write);
6343  INS01  : ISS;
6344  NEON_FP : S5;
6345%}
6346
6347pipe_class fp_d2l(iRegLNoSp dst, vRegD src)
6348%{
6349  single_instruction;
6350  src    : S1(read);
6351  dst    : S5(write);
6352  INS01  : ISS;
6353  NEON_FP : S5;
6354%}
6355
6356pipe_class fp_i2d(vRegD dst, iRegIorL2I src)
6357%{
6358  single_instruction;
6359  src    : S1(read);
6360  dst    : S5(write);
6361  INS01  : ISS;
6362  NEON_FP : S5;
6363%}
6364
6365pipe_class fp_l2d(vRegD dst, iRegIorL2I src)
6366%{
6367  single_instruction;
6368  src    : S1(read);
6369  dst    : S5(write);
6370  INS01  : ISS;
6371  NEON_FP : S5;
6372%}
6373
6374pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2)
6375%{
6376  single_instruction;
6377  src1   : S1(read);
6378  src2   : S2(read);
6379  dst    : S5(write);
6380  INS0   : ISS;
6381  NEON_FP : S5;
6382%}
6383
6384pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2)
6385%{
6386  single_instruction;
6387  src1   : S1(read);
6388  src2   : S2(read);
6389  dst    : S5(write);
6390  INS0   : ISS;
6391  NEON_FP : S5;
6392%}
6393
6394pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr)
6395%{
6396  single_instruction;
6397  cr     : S1(read);
6398  src1   : S1(read);
6399  src2   : S1(read);
6400  dst    : S3(write);
6401  INS01  : ISS;
6402  NEON_FP : S3;
6403%}
6404
6405pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr)
6406%{
6407  single_instruction;
6408  cr     : S1(read);
6409  src1   : S1(read);
6410  src2   : S1(read);
6411  dst    : S3(write);
6412  INS01  : ISS;
6413  NEON_FP : S3;
6414%}
6415
6416pipe_class fp_imm_s(vRegF dst)
6417%{
6418  single_instruction;
6419  dst    : S3(write);
6420  INS01  : ISS;
6421  NEON_FP : S3;
6422%}
6423
6424pipe_class fp_imm_d(vRegD dst)
6425%{
6426  single_instruction;
6427  dst    : S3(write);
6428  INS01  : ISS;
6429  NEON_FP : S3;
6430%}
6431
6432pipe_class fp_load_constant_s(vRegF dst)
6433%{
6434  single_instruction;
6435  dst    : S4(write);
6436  INS01  : ISS;
6437  NEON_FP : S4;
6438%}
6439
6440pipe_class fp_load_constant_d(vRegD dst)
6441%{
6442  single_instruction;
6443  dst    : S4(write);
6444  INS01  : ISS;
6445  NEON_FP : S4;
6446%}
6447
6448pipe_class vmul64(vecD dst, vecD src1, vecD src2)
6449%{
6450  single_instruction;
6451  dst    : S5(write);
6452  src1   : S1(read);
6453  src2   : S1(read);
6454  INS01  : ISS;
6455  NEON_FP : S5;
6456%}
6457
6458pipe_class vmul128(vecX dst, vecX src1, vecX src2)
6459%{
6460  single_instruction;
6461  dst    : S5(write);
6462  src1   : S1(read);
6463  src2   : S1(read);
6464  INS0   : ISS;
6465  NEON_FP : S5;
6466%}
6467
6468pipe_class vmla64(vecD dst, vecD src1, vecD src2)
6469%{
6470  single_instruction;
6471  dst    : S5(write);
6472  src1   : S1(read);
6473  src2   : S1(read);
6474  dst    : S1(read);
6475  INS01  : ISS;
6476  NEON_FP : S5;
6477%}
6478
6479pipe_class vmla128(vecX dst, vecX src1, vecX src2)
6480%{
6481  single_instruction;
6482  dst    : S5(write);
6483  src1   : S1(read);
6484  src2   : S1(read);
6485  dst    : S1(read);
6486  INS0   : ISS;
6487  NEON_FP : S5;
6488%}
6489
6490pipe_class vdop64(vecD dst, vecD src1, vecD src2)
6491%{
6492  single_instruction;
6493  dst    : S4(write);
6494  src1   : S2(read);
6495  src2   : S2(read);
6496  INS01  : ISS;
6497  NEON_FP : S4;
6498%}
6499
6500pipe_class vdop128(vecX dst, vecX src1, vecX src2)
6501%{
6502  single_instruction;
6503  dst    : S4(write);
6504  src1   : S2(read);
6505  src2   : S2(read);
6506  INS0   : ISS;
6507  NEON_FP : S4;
6508%}
6509
6510pipe_class vlogical64(vecD dst, vecD src1, vecD src2)
6511%{
6512  single_instruction;
6513  dst    : S3(write);
6514  src1   : S2(read);
6515  src2   : S2(read);
6516  INS01  : ISS;
6517  NEON_FP : S3;
6518%}
6519
6520pipe_class vlogical128(vecX dst, vecX src1, vecX src2)
6521%{
6522  single_instruction;
6523  dst    : S3(write);
6524  src1   : S2(read);
6525  src2   : S2(read);
6526  INS0   : ISS;
6527  NEON_FP : S3;
6528%}
6529
6530pipe_class vshift64(vecD dst, vecD src, vecX shift)
6531%{
6532  single_instruction;
6533  dst    : S3(write);
6534  src    : S1(read);
6535  shift  : S1(read);
6536  INS01  : ISS;
6537  NEON_FP : S3;
6538%}
6539
6540pipe_class vshift128(vecX dst, vecX src, vecX shift)
6541%{
6542  single_instruction;
6543  dst    : S3(write);
6544  src    : S1(read);
6545  shift  : S1(read);
6546  INS0   : ISS;
6547  NEON_FP : S3;
6548%}
6549
6550pipe_class vshift64_imm(vecD dst, vecD src, immI shift)
6551%{
6552  single_instruction;
6553  dst    : S3(write);
6554  src    : S1(read);
6555  INS01  : ISS;
6556  NEON_FP : S3;
6557%}
6558
6559pipe_class vshift128_imm(vecX dst, vecX src, immI shift)
6560%{
6561  single_instruction;
6562  dst    : S3(write);
6563  src    : S1(read);
6564  INS0   : ISS;
6565  NEON_FP : S3;
6566%}
6567
6568pipe_class vdop_fp64(vecD dst, vecD src1, vecD src2)
6569%{
6570  single_instruction;
6571  dst    : S5(write);
6572  src1   : S1(read);
6573  src2   : S1(read);
6574  INS01  : ISS;
6575  NEON_FP : S5;
6576%}
6577
6578pipe_class vdop_fp128(vecX dst, vecX src1, vecX src2)
6579%{
6580  single_instruction;
6581  dst    : S5(write);
6582  src1   : S1(read);
6583  src2   : S1(read);
6584  INS0   : ISS;
6585  NEON_FP : S5;
6586%}
6587
6588pipe_class vmuldiv_fp64(vecD dst, vecD src1, vecD src2)
6589%{
6590  single_instruction;
6591  dst    : S5(write);
6592  src1   : S1(read);
6593  src2   : S1(read);
6594  INS0   : ISS;
6595  NEON_FP : S5;
6596%}
6597
6598pipe_class vmuldiv_fp128(vecX dst, vecX src1, vecX src2)
6599%{
6600  single_instruction;
6601  dst    : S5(write);
6602  src1   : S1(read);
6603  src2   : S1(read);
6604  INS0   : ISS;
6605  NEON_FP : S5;
6606%}
6607
6608pipe_class vsqrt_fp128(vecX dst, vecX src)
6609%{
6610  single_instruction;
6611  dst    : S5(write);
6612  src    : S1(read);
6613  INS0   : ISS;
6614  NEON_FP : S5;
6615%}
6616
6617pipe_class vunop_fp64(vecD dst, vecD src)
6618%{
6619  single_instruction;
6620  dst    : S5(write);
6621  src    : S1(read);
6622  INS01  : ISS;
6623  NEON_FP : S5;
6624%}
6625
6626pipe_class vunop_fp128(vecX dst, vecX src)
6627%{
6628  single_instruction;
6629  dst    : S5(write);
6630  src    : S1(read);
6631  INS0   : ISS;
6632  NEON_FP : S5;
6633%}
6634
6635pipe_class vdup_reg_reg64(vecD dst, iRegI src)
6636%{
6637  single_instruction;
6638  dst    : S3(write);
6639  src    : S1(read);
6640  INS01  : ISS;
6641  NEON_FP : S3;
6642%}
6643
6644pipe_class vdup_reg_reg128(vecX dst, iRegI src)
6645%{
6646  single_instruction;
6647  dst    : S3(write);
6648  src    : S1(read);
6649  INS01  : ISS;
6650  NEON_FP : S3;
6651%}
6652
6653pipe_class vdup_reg_freg64(vecD dst, vRegF src)
6654%{
6655  single_instruction;
6656  dst    : S3(write);
6657  src    : S1(read);
6658  INS01  : ISS;
6659  NEON_FP : S3;
6660%}
6661
6662pipe_class vdup_reg_freg128(vecX dst, vRegF src)
6663%{
6664  single_instruction;
6665  dst    : S3(write);
6666  src    : S1(read);
6667  INS01  : ISS;
6668  NEON_FP : S3;
6669%}
6670
6671pipe_class vdup_reg_dreg128(vecX dst, vRegD src)
6672%{
6673  single_instruction;
6674  dst    : S3(write);
6675  src    : S1(read);
6676  INS01  : ISS;
6677  NEON_FP : S3;
6678%}
6679
6680pipe_class vmovi_reg_imm64(vecD dst)
6681%{
6682  single_instruction;
6683  dst    : S3(write);
6684  INS01  : ISS;
6685  NEON_FP : S3;
6686%}
6687
6688pipe_class vmovi_reg_imm128(vecX dst)
6689%{
6690  single_instruction;
6691  dst    : S3(write);
6692  INS0   : ISS;
6693  NEON_FP : S3;
6694%}
6695
6696pipe_class vload_reg_mem64(vecD dst, vmem8 mem)
6697%{
6698  single_instruction;
6699  dst    : S5(write);
6700  mem    : ISS(read);
6701  INS01  : ISS;
6702  NEON_FP : S3;
6703%}
6704
6705pipe_class vload_reg_mem128(vecX dst, vmem16 mem)
6706%{
6707  single_instruction;
6708  dst    : S5(write);
6709  mem    : ISS(read);
6710  INS01  : ISS;
6711  NEON_FP : S3;
6712%}
6713
6714pipe_class vstore_reg_mem64(vecD src, vmem8 mem)
6715%{
6716  single_instruction;
6717  mem    : ISS(read);
6718  src    : S2(read);
6719  INS01  : ISS;
6720  NEON_FP : S3;
6721%}
6722
6723pipe_class vstore_reg_mem128(vecD src, vmem16 mem)
6724%{
6725  single_instruction;
6726  mem    : ISS(read);
6727  src    : S2(read);
6728  INS01  : ISS;
6729  NEON_FP : S3;
6730%}
6731
6732//------- Integer ALU operations --------------------------
6733
6734// Integer ALU reg-reg operation
6735// Operands needed in EX1, result generated in EX2
6736// Eg.  ADD     x0, x1, x2
6737pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6738%{
6739  single_instruction;
6740  dst    : EX2(write);
6741  src1   : EX1(read);
6742  src2   : EX1(read);
6743  INS01  : ISS; // Dual issue as instruction 0 or 1
6744  ALU    : EX2;
6745%}
6746
6747// Integer ALU reg-reg operation with constant shift
6748// Shifted register must be available in LATE_ISS instead of EX1
6749// Eg.  ADD     x0, x1, x2, LSL #2
6750pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift)
6751%{
6752  single_instruction;
6753  dst    : EX2(write);
6754  src1   : EX1(read);
6755  src2   : ISS(read);
6756  INS01  : ISS;
6757  ALU    : EX2;
6758%}
6759
6760// Integer ALU reg operation with constant shift
6761// Eg.  LSL     x0, x1, #shift
6762pipe_class ialu_reg_shift(iRegI dst, iRegI src1)
6763%{
6764  single_instruction;
6765  dst    : EX2(write);
6766  src1   : ISS(read);
6767  INS01  : ISS;
6768  ALU    : EX2;
6769%}
6770
6771// Integer ALU reg-reg operation with variable shift
6772// Both operands must be available in LATE_ISS instead of EX1
6773// Result is available in EX1 instead of EX2
6774// Eg.  LSLV    x0, x1, x2
6775pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2)
6776%{
6777  single_instruction;
6778  dst    : EX1(write);
6779  src1   : ISS(read);
6780  src2   : ISS(read);
6781  INS01  : ISS;
6782  ALU    : EX1;
6783%}
6784
6785// Integer ALU reg-reg operation with extract
6786// As for _vshift above, but result generated in EX2
6787// Eg.  EXTR    x0, x1, x2, #N
6788pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2)
6789%{
6790  single_instruction;
6791  dst    : EX2(write);
6792  src1   : ISS(read);
6793  src2   : ISS(read);
6794  INS1   : ISS; // Can only dual issue as Instruction 1
6795  ALU    : EX1;
6796%}
6797
6798// Integer ALU reg operation
6799// Eg.  NEG     x0, x1
6800pipe_class ialu_reg(iRegI dst, iRegI src)
6801%{
6802  single_instruction;
6803  dst    : EX2(write);
6804  src    : EX1(read);
6805  INS01  : ISS;
6806  ALU    : EX2;
6807%}
6808
6809// Integer ALU reg mmediate operation
6810// Eg.  ADD     x0, x1, #N
6811pipe_class ialu_reg_imm(iRegI dst, iRegI src1)
6812%{
6813  single_instruction;
6814  dst    : EX2(write);
6815  src1   : EX1(read);
6816  INS01  : ISS;
6817  ALU    : EX2;
6818%}
6819
6820// Integer ALU immediate operation (no source operands)
6821// Eg.  MOV     x0, #N
6822pipe_class ialu_imm(iRegI dst)
6823%{
6824  single_instruction;
6825  dst    : EX1(write);
6826  INS01  : ISS;
6827  ALU    : EX1;
6828%}
6829
6830//------- Compare operation -------------------------------
6831
6832// Compare reg-reg
6833// Eg.  CMP     x0, x1
6834pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
6835%{
6836  single_instruction;
6837//  fixed_latency(16);
6838  cr     : EX2(write);
6839  op1    : EX1(read);
6840  op2    : EX1(read);
6841  INS01  : ISS;
6842  ALU    : EX2;
6843%}
6844
6845// Compare reg-reg
6846// Eg.  CMP     x0, #N
6847pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1)
6848%{
6849  single_instruction;
6850//  fixed_latency(16);
6851  cr     : EX2(write);
6852  op1    : EX1(read);
6853  INS01  : ISS;
6854  ALU    : EX2;
6855%}
6856
6857//------- Conditional instructions ------------------------
6858
6859// Conditional no operands
6860// Eg.  CSINC   x0, zr, zr, <cond>
6861pipe_class icond_none(iRegI dst, rFlagsReg cr)
6862%{
6863  single_instruction;
6864  cr     : EX1(read);
6865  dst    : EX2(write);
6866  INS01  : ISS;
6867  ALU    : EX2;
6868%}
6869
6870// Conditional 2 operand
6871// EG.  CSEL    X0, X1, X2, <cond>
6872pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr)
6873%{
6874  single_instruction;
6875  cr     : EX1(read);
6876  src1   : EX1(read);
6877  src2   : EX1(read);
6878  dst    : EX2(write);
6879  INS01  : ISS;
6880  ALU    : EX2;
6881%}
6882
6883// Conditional 2 operand
6884// EG.  CSEL    X0, X1, X2, <cond>
6885pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr)
6886%{
6887  single_instruction;
6888  cr     : EX1(read);
6889  src    : EX1(read);
6890  dst    : EX2(write);
6891  INS01  : ISS;
6892  ALU    : EX2;
6893%}
6894
6895//------- Multiply pipeline operations --------------------
6896
6897// Multiply reg-reg
6898// Eg.  MUL     w0, w1, w2
6899pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6900%{
6901  single_instruction;
6902  dst    : WR(write);
6903  src1   : ISS(read);
6904  src2   : ISS(read);
6905  INS01  : ISS;
6906  MAC    : WR;
6907%}
6908
6909// Multiply accumulate
6910// Eg.  MADD    w0, w1, w2, w3
6911pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6912%{
6913  single_instruction;
6914  dst    : WR(write);
6915  src1   : ISS(read);
6916  src2   : ISS(read);
6917  src3   : ISS(read);
6918  INS01  : ISS;
6919  MAC    : WR;
6920%}
6921
6922// Eg.  MUL     w0, w1, w2
6923pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6924%{
6925  single_instruction;
6926  fixed_latency(3); // Maximum latency for 64 bit mul
6927  dst    : WR(write);
6928  src1   : ISS(read);
6929  src2   : ISS(read);
6930  INS01  : ISS;
6931  MAC    : WR;
6932%}
6933
6934// Multiply accumulate
6935// Eg.  MADD    w0, w1, w2, w3
6936pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3)
6937%{
6938  single_instruction;
6939  fixed_latency(3); // Maximum latency for 64 bit mul
6940  dst    : WR(write);
6941  src1   : ISS(read);
6942  src2   : ISS(read);
6943  src3   : ISS(read);
6944  INS01  : ISS;
6945  MAC    : WR;
6946%}
6947
6948//------- Divide pipeline operations --------------------
6949
6950// Eg.  SDIV    w0, w1, w2
6951pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6952%{
6953  single_instruction;
6954  fixed_latency(8); // Maximum latency for 32 bit divide
6955  dst    : WR(write);
6956  src1   : ISS(read);
6957  src2   : ISS(read);
6958  INS0   : ISS; // Can only dual issue as instruction 0
6959  DIV    : WR;
6960%}
6961
6962// Eg.  SDIV    x0, x1, x2
6963pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2)
6964%{
6965  single_instruction;
6966  fixed_latency(16); // Maximum latency for 64 bit divide
6967  dst    : WR(write);
6968  src1   : ISS(read);
6969  src2   : ISS(read);
6970  INS0   : ISS; // Can only dual issue as instruction 0
6971  DIV    : WR;
6972%}
6973
6974//------- Load pipeline operations ------------------------
6975
6976// Load - prefetch
6977// Eg.  PFRM    <mem>
6978pipe_class iload_prefetch(memory mem)
6979%{
6980  single_instruction;
6981  mem    : ISS(read);
6982  INS01  : ISS;
6983  LDST   : WR;
6984%}
6985
6986// Load - reg, mem
6987// Eg.  LDR     x0, <mem>
6988pipe_class iload_reg_mem(iRegI dst, memory mem)
6989%{
6990  single_instruction;
6991  dst    : WR(write);
6992  mem    : ISS(read);
6993  INS01  : ISS;
6994  LDST   : WR;
6995%}
6996
6997// Load - reg, reg
6998// Eg.  LDR     x0, [sp, x1]
6999pipe_class iload_reg_reg(iRegI dst, iRegI src)
7000%{
7001  single_instruction;
7002  dst    : WR(write);
7003  src    : ISS(read);
7004  INS01  : ISS;
7005  LDST   : WR;
7006%}
7007
7008//------- Store pipeline operations -----------------------
7009
7010// Store - zr, mem
7011// Eg.  STR     zr, <mem>
7012pipe_class istore_mem(memory mem)
7013%{
7014  single_instruction;
7015  mem    : ISS(read);
7016  INS01  : ISS;
7017  LDST   : WR;
7018%}
7019
7020// Store - reg, mem
7021// Eg.  STR     x0, <mem>
7022pipe_class istore_reg_mem(iRegI src, memory mem)
7023%{
7024  single_instruction;
7025  mem    : ISS(read);
7026  src    : EX2(read);
7027  INS01  : ISS;
7028  LDST   : WR;
7029%}
7030
7031// Store - reg, reg
7032// Eg. STR      x0, [sp, x1]
7033pipe_class istore_reg_reg(iRegI dst, iRegI src)
7034%{
7035  single_instruction;
7036  dst    : ISS(read);
7037  src    : EX2(read);
7038  INS01  : ISS;
7039  LDST   : WR;
7040%}
7041
7042//------- Store pipeline operations -----------------------
7043
7044// Branch
7045pipe_class pipe_branch()
7046%{
7047  single_instruction;
7048  INS01  : ISS;
7049  BRANCH : EX1;
7050%}
7051
7052// Conditional branch
7053pipe_class pipe_branch_cond(rFlagsReg cr)
7054%{
7055  single_instruction;
7056  cr     : EX1(read);
7057  INS01  : ISS;
7058  BRANCH : EX1;
7059%}
7060
7061// Compare & Branch
7062// EG.  CBZ/CBNZ
7063pipe_class pipe_cmp_branch(iRegI op1)
7064%{
7065  single_instruction;
7066  op1    : EX1(read);
7067  INS01  : ISS;
7068  BRANCH : EX1;
7069%}
7070
7071//------- Synchronisation operations ----------------------
7072
7073// Any operation requiring serialization.
7074// EG.  DMB/Atomic Ops/Load Acquire/Str Release
7075pipe_class pipe_serial()
7076%{
7077  single_instruction;
7078  force_serialization;
7079  fixed_latency(16);
7080  INS01  : ISS(2); // Cannot dual issue with any other instruction
7081  LDST   : WR;
7082%}
7083
7084// Generic big/slow expanded idiom - also serialized
7085pipe_class pipe_slow()
7086%{
7087  instruction_count(10);
7088  multiple_bundles;
7089  force_serialization;
7090  fixed_latency(16);
7091  INS01  : ISS(2); // Cannot dual issue with any other instruction
7092  LDST   : WR;
7093%}
7094
7095// Empty pipeline class
7096pipe_class pipe_class_empty()
7097%{
7098  single_instruction;
7099  fixed_latency(0);
7100%}
7101
7102// Default pipeline class.
7103pipe_class pipe_class_default()
7104%{
7105  single_instruction;
7106  fixed_latency(2);
7107%}
7108
7109// Pipeline class for compares.
7110pipe_class pipe_class_compare()
7111%{
7112  single_instruction;
7113  fixed_latency(16);
7114%}
7115
7116// Pipeline class for memory operations.
7117pipe_class pipe_class_memory()
7118%{
7119  single_instruction;
7120  fixed_latency(16);
7121%}
7122
7123// Pipeline class for call.
7124pipe_class pipe_class_call()
7125%{
7126  single_instruction;
7127  fixed_latency(100);
7128%}
7129
7130// Define the class for the Nop node.
7131define %{
7132   MachNop = pipe_class_empty;
7133%}
7134
7135%}
7136//----------INSTRUCTIONS-------------------------------------------------------
7137//
7138// match      -- States which machine-independent subtree may be replaced
7139//               by this instruction.
7140// ins_cost   -- The estimated cost of this instruction is used by instruction
7141//               selection to identify a minimum cost tree of machine
7142//               instructions that matches a tree of machine-independent
7143//               instructions.
7144// format     -- A string providing the disassembly for this instruction.
7145//               The value of an instruction's operand may be inserted
7146//               by referring to it with a '$' prefix.
7147// opcode     -- Three instruction opcodes may be provided.  These are referred
7148//               to within an encode class as $primary, $secondary, and $tertiary
7149//               rrspectively.  The primary opcode is commonly used to
7150//               indicate the type of machine instruction, while secondary
7151//               and tertiary are often used for prefix options or addressing
7152//               modes.
7153// ins_encode -- A list of encode classes with parameters. The encode class
7154//               name must have been defined in an 'enc_class' specification
7155//               in the encode section of the architecture description.
7156
7157// ============================================================================
7158// Memory (Load/Store) Instructions
7159
7160// Load Instructions
7161
7162// Load Byte (8 bit signed)
7163instruct loadB(iRegINoSp dst, memory1 mem)
7164%{
7165  match(Set dst (LoadB mem));
7166  predicate(!needs_acquiring_load(n));
7167
7168  ins_cost(4 * INSN_COST);
7169  format %{ "ldrsbw  $dst, $mem\t# byte" %}
7170
7171  ins_encode(aarch64_enc_ldrsbw(dst, mem));
7172
7173  ins_pipe(iload_reg_mem);
7174%}
7175
7176// Load Byte (8 bit signed) into long
7177instruct loadB2L(iRegLNoSp dst, memory1 mem)
7178%{
7179  match(Set dst (ConvI2L (LoadB mem)));
7180  predicate(!needs_acquiring_load(n->in(1)));
7181
7182  ins_cost(4 * INSN_COST);
7183  format %{ "ldrsb  $dst, $mem\t# byte" %}
7184
7185  ins_encode(aarch64_enc_ldrsb(dst, mem));
7186
7187  ins_pipe(iload_reg_mem);
7188%}
7189
7190// Load Byte (8 bit unsigned)
7191instruct loadUB(iRegINoSp dst, memory1 mem)
7192%{
7193  match(Set dst (LoadUB mem));
7194  predicate(!needs_acquiring_load(n));
7195
7196  ins_cost(4 * INSN_COST);
7197  format %{ "ldrbw  $dst, $mem\t# byte" %}
7198
7199  ins_encode(aarch64_enc_ldrb(dst, mem));
7200
7201  ins_pipe(iload_reg_mem);
7202%}
7203
7204// Load Byte (8 bit unsigned) into long
7205instruct loadUB2L(iRegLNoSp dst, memory1 mem)
7206%{
7207  match(Set dst (ConvI2L (LoadUB mem)));
7208  predicate(!needs_acquiring_load(n->in(1)));
7209
7210  ins_cost(4 * INSN_COST);
7211  format %{ "ldrb  $dst, $mem\t# byte" %}
7212
7213  ins_encode(aarch64_enc_ldrb(dst, mem));
7214
7215  ins_pipe(iload_reg_mem);
7216%}
7217
7218// Load Short (16 bit signed)
7219instruct loadS(iRegINoSp dst, memory2 mem)
7220%{
7221  match(Set dst (LoadS mem));
7222  predicate(!needs_acquiring_load(n));
7223
7224  ins_cost(4 * INSN_COST);
7225  format %{ "ldrshw  $dst, $mem\t# short" %}
7226
7227  ins_encode(aarch64_enc_ldrshw(dst, mem));
7228
7229  ins_pipe(iload_reg_mem);
7230%}
7231
7232// Load Short (16 bit signed) into long
7233instruct loadS2L(iRegLNoSp dst, memory2 mem)
7234%{
7235  match(Set dst (ConvI2L (LoadS mem)));
7236  predicate(!needs_acquiring_load(n->in(1)));
7237
7238  ins_cost(4 * INSN_COST);
7239  format %{ "ldrsh  $dst, $mem\t# short" %}
7240
7241  ins_encode(aarch64_enc_ldrsh(dst, mem));
7242
7243  ins_pipe(iload_reg_mem);
7244%}
7245
7246// Load Char (16 bit unsigned)
7247instruct loadUS(iRegINoSp dst, memory2 mem)
7248%{
7249  match(Set dst (LoadUS mem));
7250  predicate(!needs_acquiring_load(n));
7251
7252  ins_cost(4 * INSN_COST);
7253  format %{ "ldrh  $dst, $mem\t# short" %}
7254
7255  ins_encode(aarch64_enc_ldrh(dst, mem));
7256
7257  ins_pipe(iload_reg_mem);
7258%}
7259
7260// Load Short/Char (16 bit unsigned) into long
7261instruct loadUS2L(iRegLNoSp dst, memory2 mem)
7262%{
7263  match(Set dst (ConvI2L (LoadUS mem)));
7264  predicate(!needs_acquiring_load(n->in(1)));
7265
7266  ins_cost(4 * INSN_COST);
7267  format %{ "ldrh  $dst, $mem\t# short" %}
7268
7269  ins_encode(aarch64_enc_ldrh(dst, mem));
7270
7271  ins_pipe(iload_reg_mem);
7272%}
7273
7274// Load Integer (32 bit signed)
7275instruct loadI(iRegINoSp dst, memory4 mem)
7276%{
7277  match(Set dst (LoadI mem));
7278  predicate(!needs_acquiring_load(n));
7279
7280  ins_cost(4 * INSN_COST);
7281  format %{ "ldrw  $dst, $mem\t# int" %}
7282
7283  ins_encode(aarch64_enc_ldrw(dst, mem));
7284
7285  ins_pipe(iload_reg_mem);
7286%}
7287
7288// Load Integer (32 bit signed) into long
7289instruct loadI2L(iRegLNoSp dst, memory4 mem)
7290%{
7291  match(Set dst (ConvI2L (LoadI mem)));
7292  predicate(!needs_acquiring_load(n->in(1)));
7293
7294  ins_cost(4 * INSN_COST);
7295  format %{ "ldrsw  $dst, $mem\t# int" %}
7296
7297  ins_encode(aarch64_enc_ldrsw(dst, mem));
7298
7299  ins_pipe(iload_reg_mem);
7300%}
7301
7302// Load Integer (32 bit unsigned) into long
7303instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask)
7304%{
7305  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
7306  predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load()));
7307
7308  ins_cost(4 * INSN_COST);
7309  format %{ "ldrw  $dst, $mem\t# int" %}
7310
7311  ins_encode(aarch64_enc_ldrw(dst, mem));
7312
7313  ins_pipe(iload_reg_mem);
7314%}
7315
7316// Load Long (64 bit signed)
7317instruct loadL(iRegLNoSp dst, memory8 mem)
7318%{
7319  match(Set dst (LoadL mem));
7320  predicate(!needs_acquiring_load(n));
7321
7322  ins_cost(4 * INSN_COST);
7323  format %{ "ldr  $dst, $mem\t# int" %}
7324
7325  ins_encode(aarch64_enc_ldr(dst, mem));
7326
7327  ins_pipe(iload_reg_mem);
7328%}
7329
7330// Load Range
7331instruct loadRange(iRegINoSp dst, memory4 mem)
7332%{
7333  match(Set dst (LoadRange mem));
7334
7335  ins_cost(4 * INSN_COST);
7336  format %{ "ldrw  $dst, $mem\t# range" %}
7337
7338  ins_encode(aarch64_enc_ldrw(dst, mem));
7339
7340  ins_pipe(iload_reg_mem);
7341%}
7342
7343// Load Pointer
7344instruct loadP(iRegPNoSp dst, memory8 mem)
7345%{
7346  match(Set dst (LoadP mem));
7347  predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0));
7348
7349  ins_cost(4 * INSN_COST);
7350  format %{ "ldr  $dst, $mem\t# ptr" %}
7351
7352  ins_encode(aarch64_enc_ldr(dst, mem));
7353
7354  ins_pipe(iload_reg_mem);
7355%}
7356
7357// Load Compressed Pointer
7358instruct loadN(iRegNNoSp dst, memory4 mem)
7359%{
7360  match(Set dst (LoadN mem));
7361  predicate(!needs_acquiring_load(n));
7362
7363  ins_cost(4 * INSN_COST);
7364  format %{ "ldrw  $dst, $mem\t# compressed ptr" %}
7365
7366  ins_encode(aarch64_enc_ldrw(dst, mem));
7367
7368  ins_pipe(iload_reg_mem);
7369%}
7370
7371// Load Klass Pointer
7372instruct loadKlass(iRegPNoSp dst, memory8 mem)
7373%{
7374  match(Set dst (LoadKlass mem));
7375  predicate(!needs_acquiring_load(n));
7376
7377  ins_cost(4 * INSN_COST);
7378  format %{ "ldr  $dst, $mem\t# class" %}
7379
7380  ins_encode(aarch64_enc_ldr(dst, mem));
7381
7382  ins_pipe(iload_reg_mem);
7383%}
7384
7385// Load Narrow Klass Pointer
7386instruct loadNKlass(iRegNNoSp dst, memory4 mem)
7387%{
7388  match(Set dst (LoadNKlass mem));
7389  predicate(!needs_acquiring_load(n));
7390
7391  ins_cost(4 * INSN_COST);
7392  format %{ "ldrw  $dst, $mem\t# compressed class ptr" %}
7393
7394  ins_encode(aarch64_enc_ldrw(dst, mem));
7395
7396  ins_pipe(iload_reg_mem);
7397%}
7398
7399// Load Float
7400instruct loadF(vRegF dst, memory4 mem)
7401%{
7402  match(Set dst (LoadF mem));
7403  predicate(!needs_acquiring_load(n));
7404
7405  ins_cost(4 * INSN_COST);
7406  format %{ "ldrs  $dst, $mem\t# float" %}
7407
7408  ins_encode( aarch64_enc_ldrs(dst, mem) );
7409
7410  ins_pipe(pipe_class_memory);
7411%}
7412
7413// Load Double
7414instruct loadD(vRegD dst, memory8 mem)
7415%{
7416  match(Set dst (LoadD mem));
7417  predicate(!needs_acquiring_load(n));
7418
7419  ins_cost(4 * INSN_COST);
7420  format %{ "ldrd  $dst, $mem\t# double" %}
7421
7422  ins_encode( aarch64_enc_ldrd(dst, mem) );
7423
7424  ins_pipe(pipe_class_memory);
7425%}
7426
7427
7428// Load Int Constant
7429instruct loadConI(iRegINoSp dst, immI src)
7430%{
7431  match(Set dst src);
7432
7433  ins_cost(INSN_COST);
7434  format %{ "mov $dst, $src\t# int" %}
7435
7436  ins_encode( aarch64_enc_movw_imm(dst, src) );
7437
7438  ins_pipe(ialu_imm);
7439%}
7440
7441// Load Long Constant
7442instruct loadConL(iRegLNoSp dst, immL src)
7443%{
7444  match(Set dst src);
7445
7446  ins_cost(INSN_COST);
7447  format %{ "mov $dst, $src\t# long" %}
7448
7449  ins_encode( aarch64_enc_mov_imm(dst, src) );
7450
7451  ins_pipe(ialu_imm);
7452%}
7453
7454// Load Pointer Constant
7455
7456instruct loadConP(iRegPNoSp dst, immP con)
7457%{
7458  match(Set dst con);
7459
7460  ins_cost(INSN_COST * 4);
7461  format %{
7462    "mov  $dst, $con\t# ptr\n\t"
7463  %}
7464
7465  ins_encode(aarch64_enc_mov_p(dst, con));
7466
7467  ins_pipe(ialu_imm);
7468%}
7469
7470// Load Null Pointer Constant
7471
7472instruct loadConP0(iRegPNoSp dst, immP0 con)
7473%{
7474  match(Set dst con);
7475
7476  ins_cost(INSN_COST);
7477  format %{ "mov  $dst, $con\t# NULL ptr" %}
7478
7479  ins_encode(aarch64_enc_mov_p0(dst, con));
7480
7481  ins_pipe(ialu_imm);
7482%}
7483
7484// Load Pointer Constant One
7485
7486instruct loadConP1(iRegPNoSp dst, immP_1 con)
7487%{
7488  match(Set dst con);
7489
7490  ins_cost(INSN_COST);
7491  format %{ "mov  $dst, $con\t# NULL ptr" %}
7492
7493  ins_encode(aarch64_enc_mov_p1(dst, con));
7494
7495  ins_pipe(ialu_imm);
7496%}
7497
7498// Load Byte Map Base Constant
7499
7500instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con)
7501%{
7502  match(Set dst con);
7503
7504  ins_cost(INSN_COST);
7505  format %{ "adr  $dst, $con\t# Byte Map Base" %}
7506
7507  ins_encode(aarch64_enc_mov_byte_map_base(dst, con));
7508
7509  ins_pipe(ialu_imm);
7510%}
7511
7512// Load Narrow Pointer Constant
7513
7514instruct loadConN(iRegNNoSp dst, immN con)
7515%{
7516  match(Set dst con);
7517
7518  ins_cost(INSN_COST * 4);
7519  format %{ "mov  $dst, $con\t# compressed ptr" %}
7520
7521  ins_encode(aarch64_enc_mov_n(dst, con));
7522
7523  ins_pipe(ialu_imm);
7524%}
7525
7526// Load Narrow Null Pointer Constant
7527
7528instruct loadConN0(iRegNNoSp dst, immN0 con)
7529%{
7530  match(Set dst con);
7531
7532  ins_cost(INSN_COST);
7533  format %{ "mov  $dst, $con\t# compressed NULL ptr" %}
7534
7535  ins_encode(aarch64_enc_mov_n0(dst, con));
7536
7537  ins_pipe(ialu_imm);
7538%}
7539
7540// Load Narrow Klass Constant
7541
7542instruct loadConNKlass(iRegNNoSp dst, immNKlass con)
7543%{
7544  match(Set dst con);
7545
7546  ins_cost(INSN_COST);
7547  format %{ "mov  $dst, $con\t# compressed klass ptr" %}
7548
7549  ins_encode(aarch64_enc_mov_nk(dst, con));
7550
7551  ins_pipe(ialu_imm);
7552%}
7553
7554// Load Packed Float Constant
7555
7556instruct loadConF_packed(vRegF dst, immFPacked con) %{
7557  match(Set dst con);
7558  ins_cost(INSN_COST * 4);
7559  format %{ "fmovs  $dst, $con"%}
7560  ins_encode %{
7561    __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant);
7562  %}
7563
7564  ins_pipe(fp_imm_s);
7565%}
7566
7567// Load Float Constant
7568
7569instruct loadConF(vRegF dst, immF con) %{
7570  match(Set dst con);
7571
7572  ins_cost(INSN_COST * 4);
7573
7574  format %{
7575    "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
7576  %}
7577
7578  ins_encode %{
7579    __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con));
7580  %}
7581
7582  ins_pipe(fp_load_constant_s);
7583%}
7584
7585// Load Packed Double Constant
7586
7587instruct loadConD_packed(vRegD dst, immDPacked con) %{
7588  match(Set dst con);
7589  ins_cost(INSN_COST);
7590  format %{ "fmovd  $dst, $con"%}
7591  ins_encode %{
7592    __ fmovd(as_FloatRegister($dst$$reg), $con$$constant);
7593  %}
7594
7595  ins_pipe(fp_imm_d);
7596%}
7597
7598// Load Double Constant
7599
7600instruct loadConD(vRegD dst, immD con) %{
7601  match(Set dst con);
7602
7603  ins_cost(INSN_COST * 5);
7604  format %{
7605    "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t"
7606  %}
7607
7608  ins_encode %{
7609    __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con));
7610  %}
7611
7612  ins_pipe(fp_load_constant_d);
7613%}
7614
7615// Store Instructions
7616
7617// Store CMS card-mark Immediate
7618instruct storeimmCM0(immI0 zero, memory1 mem)
7619%{
7620  match(Set mem (StoreCM mem zero));
7621
7622  ins_cost(INSN_COST);
7623  format %{ "storestore (elided)\n\t"
7624            "strb zr, $mem\t# byte" %}
7625
7626  ins_encode(aarch64_enc_strb0(mem));
7627
7628  ins_pipe(istore_mem);
7629%}
7630
7631// Store CMS card-mark Immediate with intervening StoreStore
7632// needed when using CMS with no conditional card marking
7633instruct storeimmCM0_ordered(immI0 zero, memory1 mem)
7634%{
7635  match(Set mem (StoreCM mem zero));
7636
7637  ins_cost(INSN_COST * 2);
7638  format %{ "storestore\n\t"
7639            "dmb ishst"
7640            "\n\tstrb zr, $mem\t# byte" %}
7641
7642  ins_encode(aarch64_enc_strb0_ordered(mem));
7643
7644  ins_pipe(istore_mem);
7645%}
7646
7647// Store Byte
7648instruct storeB(iRegIorL2I src, memory1 mem)
7649%{
7650  match(Set mem (StoreB mem src));
7651  predicate(!needs_releasing_store(n));
7652
7653  ins_cost(INSN_COST);
7654  format %{ "strb  $src, $mem\t# byte" %}
7655
7656  ins_encode(aarch64_enc_strb(src, mem));
7657
7658  ins_pipe(istore_reg_mem);
7659%}
7660
7661
7662instruct storeimmB0(immI0 zero, memory1 mem)
7663%{
7664  match(Set mem (StoreB mem zero));
7665  predicate(!needs_releasing_store(n));
7666
7667  ins_cost(INSN_COST);
7668  format %{ "strb rscractch2, $mem\t# byte" %}
7669
7670  ins_encode(aarch64_enc_strb0(mem));
7671
7672  ins_pipe(istore_mem);
7673%}
7674
7675// Store Char/Short
7676instruct storeC(iRegIorL2I src, memory2 mem)
7677%{
7678  match(Set mem (StoreC mem src));
7679  predicate(!needs_releasing_store(n));
7680
7681  ins_cost(INSN_COST);
7682  format %{ "strh  $src, $mem\t# short" %}
7683
7684  ins_encode(aarch64_enc_strh(src, mem));
7685
7686  ins_pipe(istore_reg_mem);
7687%}
7688
7689instruct storeimmC0(immI0 zero, memory2 mem)
7690%{
7691  match(Set mem (StoreC mem zero));
7692  predicate(!needs_releasing_store(n));
7693
7694  ins_cost(INSN_COST);
7695  format %{ "strh  zr, $mem\t# short" %}
7696
7697  ins_encode(aarch64_enc_strh0(mem));
7698
7699  ins_pipe(istore_mem);
7700%}
7701
7702// Store Integer
7703
7704instruct storeI(iRegIorL2I src, memory4 mem)
7705%{
7706  match(Set mem(StoreI mem src));
7707  predicate(!needs_releasing_store(n));
7708
7709  ins_cost(INSN_COST);
7710  format %{ "strw  $src, $mem\t# int" %}
7711
7712  ins_encode(aarch64_enc_strw(src, mem));
7713
7714  ins_pipe(istore_reg_mem);
7715%}
7716
7717instruct storeimmI0(immI0 zero, memory4 mem)
7718%{
7719  match(Set mem(StoreI mem zero));
7720  predicate(!needs_releasing_store(n));
7721
7722  ins_cost(INSN_COST);
7723  format %{ "strw  zr, $mem\t# int" %}
7724
7725  ins_encode(aarch64_enc_strw0(mem));
7726
7727  ins_pipe(istore_mem);
7728%}
7729
7730// Store Long (64 bit signed)
7731instruct storeL(iRegL src, memory8 mem)
7732%{
7733  match(Set mem (StoreL mem src));
7734  predicate(!needs_releasing_store(n));
7735
7736  ins_cost(INSN_COST);
7737  format %{ "str  $src, $mem\t# int" %}
7738
7739  ins_encode(aarch64_enc_str(src, mem));
7740
7741  ins_pipe(istore_reg_mem);
7742%}
7743
7744// Store Long (64 bit signed)
7745instruct storeimmL0(immL0 zero, memory8 mem)
7746%{
7747  match(Set mem (StoreL mem zero));
7748  predicate(!needs_releasing_store(n));
7749
7750  ins_cost(INSN_COST);
7751  format %{ "str  zr, $mem\t# int" %}
7752
7753  ins_encode(aarch64_enc_str0(mem));
7754
7755  ins_pipe(istore_mem);
7756%}
7757
7758// Store Pointer
7759instruct storeP(iRegP src, memory8 mem)
7760%{
7761  match(Set mem (StoreP mem src));
7762  predicate(!needs_releasing_store(n));
7763
7764  ins_cost(INSN_COST);
7765  format %{ "str  $src, $mem\t# ptr" %}
7766
7767  ins_encode(aarch64_enc_str(src, mem));
7768
7769  ins_pipe(istore_reg_mem);
7770%}
7771
7772// Store Pointer
7773instruct storeimmP0(immP0 zero, memory8 mem)
7774%{
7775  match(Set mem (StoreP mem zero));
7776  predicate(!needs_releasing_store(n));
7777
7778  ins_cost(INSN_COST);
7779  format %{ "str zr, $mem\t# ptr" %}
7780
7781  ins_encode(aarch64_enc_str0(mem));
7782
7783  ins_pipe(istore_mem);
7784%}
7785
7786// Store Compressed Pointer
7787instruct storeN(iRegN src, memory4 mem)
7788%{
7789  match(Set mem (StoreN mem src));
7790  predicate(!needs_releasing_store(n));
7791
7792  ins_cost(INSN_COST);
7793  format %{ "strw  $src, $mem\t# compressed ptr" %}
7794
7795  ins_encode(aarch64_enc_strw(src, mem));
7796
7797  ins_pipe(istore_reg_mem);
7798%}
7799
7800instruct storeImmN0(immN0 zero, memory4 mem)
7801%{
7802  match(Set mem (StoreN mem zero));
7803  predicate(!needs_releasing_store(n));
7804
7805  ins_cost(INSN_COST);
7806  format %{ "strw  zr, $mem\t# compressed ptr" %}
7807
7808  ins_encode(aarch64_enc_strw0(mem));
7809
7810  ins_pipe(istore_mem);
7811%}
7812
7813// Store Float
7814instruct storeF(vRegF src, memory4 mem)
7815%{
7816  match(Set mem (StoreF mem src));
7817  predicate(!needs_releasing_store(n));
7818
7819  ins_cost(INSN_COST);
7820  format %{ "strs  $src, $mem\t# float" %}
7821
7822  ins_encode( aarch64_enc_strs(src, mem) );
7823
7824  ins_pipe(pipe_class_memory);
7825%}
7826
7827// TODO
7828// implement storeImmF0 and storeFImmPacked
7829
7830// Store Double
7831instruct storeD(vRegD src, memory8 mem)
7832%{
7833  match(Set mem (StoreD mem src));
7834  predicate(!needs_releasing_store(n));
7835
7836  ins_cost(INSN_COST);
7837  format %{ "strd  $src, $mem\t# double" %}
7838
7839  ins_encode( aarch64_enc_strd(src, mem) );
7840
7841  ins_pipe(pipe_class_memory);
7842%}
7843
7844// Store Compressed Klass Pointer
7845instruct storeNKlass(iRegN src, memory4 mem)
7846%{
7847  predicate(!needs_releasing_store(n));
7848  match(Set mem (StoreNKlass mem src));
7849
7850  ins_cost(INSN_COST);
7851  format %{ "strw  $src, $mem\t# compressed klass ptr" %}
7852
7853  ins_encode(aarch64_enc_strw(src, mem));
7854
7855  ins_pipe(istore_reg_mem);
7856%}
7857
7858// TODO
7859// implement storeImmD0 and storeDImmPacked
7860
7861// prefetch instructions
7862// Must be safe to execute with invalid address (cannot fault).
7863
7864instruct prefetchalloc( memory8 mem ) %{
7865  match(PrefetchAllocation mem);
7866
7867  ins_cost(INSN_COST);
7868  format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %}
7869
7870  ins_encode( aarch64_enc_prefetchw(mem) );
7871
7872  ins_pipe(iload_prefetch);
7873%}
7874
7875//  ---------------- volatile loads and stores ----------------
7876
7877// Load Byte (8 bit signed)
7878instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7879%{
7880  match(Set dst (LoadB mem));
7881
7882  ins_cost(VOLATILE_REF_COST);
7883  format %{ "ldarsb  $dst, $mem\t# byte" %}
7884
7885  ins_encode(aarch64_enc_ldarsb(dst, mem));
7886
7887  ins_pipe(pipe_serial);
7888%}
7889
7890// Load Byte (8 bit signed) into long
7891instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7892%{
7893  match(Set dst (ConvI2L (LoadB mem)));
7894
7895  ins_cost(VOLATILE_REF_COST);
7896  format %{ "ldarsb  $dst, $mem\t# byte" %}
7897
7898  ins_encode(aarch64_enc_ldarsb(dst, mem));
7899
7900  ins_pipe(pipe_serial);
7901%}
7902
7903// Load Byte (8 bit unsigned)
7904instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7905%{
7906  match(Set dst (LoadUB mem));
7907
7908  ins_cost(VOLATILE_REF_COST);
7909  format %{ "ldarb  $dst, $mem\t# byte" %}
7910
7911  ins_encode(aarch64_enc_ldarb(dst, mem));
7912
7913  ins_pipe(pipe_serial);
7914%}
7915
7916// Load Byte (8 bit unsigned) into long
7917instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7918%{
7919  match(Set dst (ConvI2L (LoadUB mem)));
7920
7921  ins_cost(VOLATILE_REF_COST);
7922  format %{ "ldarb  $dst, $mem\t# byte" %}
7923
7924  ins_encode(aarch64_enc_ldarb(dst, mem));
7925
7926  ins_pipe(pipe_serial);
7927%}
7928
7929// Load Short (16 bit signed)
7930instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7931%{
7932  match(Set dst (LoadS mem));
7933
7934  ins_cost(VOLATILE_REF_COST);
7935  format %{ "ldarshw  $dst, $mem\t# short" %}
7936
7937  ins_encode(aarch64_enc_ldarshw(dst, mem));
7938
7939  ins_pipe(pipe_serial);
7940%}
7941
7942instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7943%{
7944  match(Set dst (LoadUS mem));
7945
7946  ins_cost(VOLATILE_REF_COST);
7947  format %{ "ldarhw  $dst, $mem\t# short" %}
7948
7949  ins_encode(aarch64_enc_ldarhw(dst, mem));
7950
7951  ins_pipe(pipe_serial);
7952%}
7953
7954// Load Short/Char (16 bit unsigned) into long
7955instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7956%{
7957  match(Set dst (ConvI2L (LoadUS mem)));
7958
7959  ins_cost(VOLATILE_REF_COST);
7960  format %{ "ldarh  $dst, $mem\t# short" %}
7961
7962  ins_encode(aarch64_enc_ldarh(dst, mem));
7963
7964  ins_pipe(pipe_serial);
7965%}
7966
7967// Load Short/Char (16 bit signed) into long
7968instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
7969%{
7970  match(Set dst (ConvI2L (LoadS mem)));
7971
7972  ins_cost(VOLATILE_REF_COST);
7973  format %{ "ldarh  $dst, $mem\t# short" %}
7974
7975  ins_encode(aarch64_enc_ldarsh(dst, mem));
7976
7977  ins_pipe(pipe_serial);
7978%}
7979
7980// Load Integer (32 bit signed)
7981instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem)
7982%{
7983  match(Set dst (LoadI mem));
7984
7985  ins_cost(VOLATILE_REF_COST);
7986  format %{ "ldarw  $dst, $mem\t# int" %}
7987
7988  ins_encode(aarch64_enc_ldarw(dst, mem));
7989
7990  ins_pipe(pipe_serial);
7991%}
7992
7993// Load Integer (32 bit unsigned) into long
7994instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask)
7995%{
7996  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
7997
7998  ins_cost(VOLATILE_REF_COST);
7999  format %{ "ldarw  $dst, $mem\t# int" %}
8000
8001  ins_encode(aarch64_enc_ldarw(dst, mem));
8002
8003  ins_pipe(pipe_serial);
8004%}
8005
8006// Load Long (64 bit signed)
8007instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
8008%{
8009  match(Set dst (LoadL mem));
8010
8011  ins_cost(VOLATILE_REF_COST);
8012  format %{ "ldar  $dst, $mem\t# int" %}
8013
8014  ins_encode(aarch64_enc_ldar(dst, mem));
8015
8016  ins_pipe(pipe_serial);
8017%}
8018
8019// Load Pointer
8020instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem)
8021%{
8022  match(Set dst (LoadP mem));
8023  predicate(n->as_Load()->barrier_data() == 0);
8024
8025  ins_cost(VOLATILE_REF_COST);
8026  format %{ "ldar  $dst, $mem\t# ptr" %}
8027
8028  ins_encode(aarch64_enc_ldar(dst, mem));
8029
8030  ins_pipe(pipe_serial);
8031%}
8032
8033// Load Compressed Pointer
8034instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem)
8035%{
8036  match(Set dst (LoadN mem));
8037
8038  ins_cost(VOLATILE_REF_COST);
8039  format %{ "ldarw  $dst, $mem\t# compressed ptr" %}
8040
8041  ins_encode(aarch64_enc_ldarw(dst, mem));
8042
8043  ins_pipe(pipe_serial);
8044%}
8045
8046// Load Float
8047instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem)
8048%{
8049  match(Set dst (LoadF mem));
8050
8051  ins_cost(VOLATILE_REF_COST);
8052  format %{ "ldars  $dst, $mem\t# float" %}
8053
8054  ins_encode( aarch64_enc_fldars(dst, mem) );
8055
8056  ins_pipe(pipe_serial);
8057%}
8058
8059// Load Double
8060instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem)
8061%{
8062  match(Set dst (LoadD mem));
8063
8064  ins_cost(VOLATILE_REF_COST);
8065  format %{ "ldard  $dst, $mem\t# double" %}
8066
8067  ins_encode( aarch64_enc_fldard(dst, mem) );
8068
8069  ins_pipe(pipe_serial);
8070%}
8071
8072// Store Byte
8073instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
8074%{
8075  match(Set mem (StoreB mem src));
8076
8077  ins_cost(VOLATILE_REF_COST);
8078  format %{ "stlrb  $src, $mem\t# byte" %}
8079
8080  ins_encode(aarch64_enc_stlrb(src, mem));
8081
8082  ins_pipe(pipe_class_memory);
8083%}
8084
8085// Store Char/Short
8086instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
8087%{
8088  match(Set mem (StoreC mem src));
8089
8090  ins_cost(VOLATILE_REF_COST);
8091  format %{ "stlrh  $src, $mem\t# short" %}
8092
8093  ins_encode(aarch64_enc_stlrh(src, mem));
8094
8095  ins_pipe(pipe_class_memory);
8096%}
8097
8098// Store Integer
8099
8100instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem)
8101%{
8102  match(Set mem(StoreI mem src));
8103
8104  ins_cost(VOLATILE_REF_COST);
8105  format %{ "stlrw  $src, $mem\t# int" %}
8106
8107  ins_encode(aarch64_enc_stlrw(src, mem));
8108
8109  ins_pipe(pipe_class_memory);
8110%}
8111
8112// Store Long (64 bit signed)
8113instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem)
8114%{
8115  match(Set mem (StoreL mem src));
8116
8117  ins_cost(VOLATILE_REF_COST);
8118  format %{ "stlr  $src, $mem\t# int" %}
8119
8120  ins_encode(aarch64_enc_stlr(src, mem));
8121
8122  ins_pipe(pipe_class_memory);
8123%}
8124
8125// Store Pointer
8126instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem)
8127%{
8128  match(Set mem (StoreP mem src));
8129
8130  ins_cost(VOLATILE_REF_COST);
8131  format %{ "stlr  $src, $mem\t# ptr" %}
8132
8133  ins_encode(aarch64_enc_stlr(src, mem));
8134
8135  ins_pipe(pipe_class_memory);
8136%}
8137
8138// Store Compressed Pointer
8139instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem)
8140%{
8141  match(Set mem (StoreN mem src));
8142
8143  ins_cost(VOLATILE_REF_COST);
8144  format %{ "stlrw  $src, $mem\t# compressed ptr" %}
8145
8146  ins_encode(aarch64_enc_stlrw(src, mem));
8147
8148  ins_pipe(pipe_class_memory);
8149%}
8150
8151// Store Float
8152instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem)
8153%{
8154  match(Set mem (StoreF mem src));
8155
8156  ins_cost(VOLATILE_REF_COST);
8157  format %{ "stlrs  $src, $mem\t# float" %}
8158
8159  ins_encode( aarch64_enc_fstlrs(src, mem) );
8160
8161  ins_pipe(pipe_class_memory);
8162%}
8163
8164// TODO
8165// implement storeImmF0 and storeFImmPacked
8166
8167// Store Double
8168instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem)
8169%{
8170  match(Set mem (StoreD mem src));
8171
8172  ins_cost(VOLATILE_REF_COST);
8173  format %{ "stlrd  $src, $mem\t# double" %}
8174
8175  ins_encode( aarch64_enc_fstlrd(src, mem) );
8176
8177  ins_pipe(pipe_class_memory);
8178%}
8179
8180//  ---------------- end of volatile loads and stores ----------------
8181
8182instruct cacheWB(indirect addr)
8183%{
8184  predicate(VM_Version::supports_data_cache_line_flush());
8185  match(CacheWB addr);
8186
8187  ins_cost(100);
8188  format %{"cache wb $addr" %}
8189  ins_encode %{
8190    assert($addr->index_position() < 0, "should be");
8191    assert($addr$$disp == 0, "should be");
8192    __ cache_wb(Address($addr$$base$$Register, 0));
8193  %}
8194  ins_pipe(pipe_slow); // XXX
8195%}
8196
8197instruct cacheWBPreSync()
8198%{
8199  predicate(VM_Version::supports_data_cache_line_flush());
8200  match(CacheWBPreSync);
8201
8202  ins_cost(100);
8203  format %{"cache wb presync" %}
8204  ins_encode %{
8205    __ cache_wbsync(true);
8206  %}
8207  ins_pipe(pipe_slow); // XXX
8208%}
8209
8210instruct cacheWBPostSync()
8211%{
8212  predicate(VM_Version::supports_data_cache_line_flush());
8213  match(CacheWBPostSync);
8214
8215  ins_cost(100);
8216  format %{"cache wb postsync" %}
8217  ins_encode %{
8218    __ cache_wbsync(false);
8219  %}
8220  ins_pipe(pipe_slow); // XXX
8221%}
8222
8223// ============================================================================
8224// BSWAP Instructions
8225
8226instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{
8227  match(Set dst (ReverseBytesI src));
8228
8229  ins_cost(INSN_COST);
8230  format %{ "revw  $dst, $src" %}
8231
8232  ins_encode %{
8233    __ revw(as_Register($dst$$reg), as_Register($src$$reg));
8234  %}
8235
8236  ins_pipe(ialu_reg);
8237%}
8238
8239instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{
8240  match(Set dst (ReverseBytesL src));
8241
8242  ins_cost(INSN_COST);
8243  format %{ "rev  $dst, $src" %}
8244
8245  ins_encode %{
8246    __ rev(as_Register($dst$$reg), as_Register($src$$reg));
8247  %}
8248
8249  ins_pipe(ialu_reg);
8250%}
8251
8252instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{
8253  match(Set dst (ReverseBytesUS src));
8254
8255  ins_cost(INSN_COST);
8256  format %{ "rev16w  $dst, $src" %}
8257
8258  ins_encode %{
8259    __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
8260  %}
8261
8262  ins_pipe(ialu_reg);
8263%}
8264
8265instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{
8266  match(Set dst (ReverseBytesS src));
8267
8268  ins_cost(INSN_COST);
8269  format %{ "rev16w  $dst, $src\n\t"
8270            "sbfmw $dst, $dst, #0, #15" %}
8271
8272  ins_encode %{
8273    __ rev16w(as_Register($dst$$reg), as_Register($src$$reg));
8274    __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U);
8275  %}
8276
8277  ins_pipe(ialu_reg);
8278%}
8279
8280// ============================================================================
8281// Zero Count Instructions
8282
8283instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{
8284  match(Set dst (CountLeadingZerosI src));
8285
8286  ins_cost(INSN_COST);
8287  format %{ "clzw  $dst, $src" %}
8288  ins_encode %{
8289    __ clzw(as_Register($dst$$reg), as_Register($src$$reg));
8290  %}
8291
8292  ins_pipe(ialu_reg);
8293%}
8294
8295instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{
8296  match(Set dst (CountLeadingZerosL src));
8297
8298  ins_cost(INSN_COST);
8299  format %{ "clz   $dst, $src" %}
8300  ins_encode %{
8301    __ clz(as_Register($dst$$reg), as_Register($src$$reg));
8302  %}
8303
8304  ins_pipe(ialu_reg);
8305%}
8306
8307instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{
8308  match(Set dst (CountTrailingZerosI src));
8309
8310  ins_cost(INSN_COST * 2);
8311  format %{ "rbitw  $dst, $src\n\t"
8312            "clzw   $dst, $dst" %}
8313  ins_encode %{
8314    __ rbitw(as_Register($dst$$reg), as_Register($src$$reg));
8315    __ clzw(as_Register($dst$$reg), as_Register($dst$$reg));
8316  %}
8317
8318  ins_pipe(ialu_reg);
8319%}
8320
8321instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{
8322  match(Set dst (CountTrailingZerosL src));
8323
8324  ins_cost(INSN_COST * 2);
8325  format %{ "rbit   $dst, $src\n\t"
8326            "clz    $dst, $dst" %}
8327  ins_encode %{
8328    __ rbit(as_Register($dst$$reg), as_Register($src$$reg));
8329    __ clz(as_Register($dst$$reg), as_Register($dst$$reg));
8330  %}
8331
8332  ins_pipe(ialu_reg);
8333%}
8334
8335//---------- Population Count Instructions -------------------------------------
8336//
8337
8338instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{
8339  predicate(UsePopCountInstruction);
8340  match(Set dst (PopCountI src));
8341  effect(TEMP tmp);
8342  ins_cost(INSN_COST * 13);
8343
8344  format %{ "movw   $src, $src\n\t"
8345            "mov    $tmp, $src\t# vector (1D)\n\t"
8346            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
8347            "addv   $tmp, $tmp\t# vector (8B)\n\t"
8348            "mov    $dst, $tmp\t# vector (1D)" %}
8349  ins_encode %{
8350    __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0
8351    __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register);
8352    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
8353    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
8354    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
8355  %}
8356
8357  ins_pipe(pipe_class_default);
8358%}
8359
8360instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{
8361  predicate(UsePopCountInstruction);
8362  match(Set dst (PopCountI (LoadI mem)));
8363  effect(TEMP tmp);
8364  ins_cost(INSN_COST * 13);
8365
8366  format %{ "ldrs   $tmp, $mem\n\t"
8367            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
8368            "addv   $tmp, $tmp\t# vector (8B)\n\t"
8369            "mov    $dst, $tmp\t# vector (1D)" %}
8370  ins_encode %{
8371    FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
8372    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(),
8373              as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4);
8374    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
8375    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
8376    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
8377  %}
8378
8379  ins_pipe(pipe_class_default);
8380%}
8381
8382// Note: Long.bitCount(long) returns an int.
8383instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{
8384  predicate(UsePopCountInstruction);
8385  match(Set dst (PopCountL src));
8386  effect(TEMP tmp);
8387  ins_cost(INSN_COST * 13);
8388
8389  format %{ "mov    $tmp, $src\t# vector (1D)\n\t"
8390            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
8391            "addv   $tmp, $tmp\t# vector (8B)\n\t"
8392            "mov    $dst, $tmp\t# vector (1D)" %}
8393  ins_encode %{
8394    __ mov($tmp$$FloatRegister, __ T1D, 0, $src$$Register);
8395    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
8396    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
8397    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
8398  %}
8399
8400  ins_pipe(pipe_class_default);
8401%}
8402
8403instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{
8404  predicate(UsePopCountInstruction);
8405  match(Set dst (PopCountL (LoadL mem)));
8406  effect(TEMP tmp);
8407  ins_cost(INSN_COST * 13);
8408
8409  format %{ "ldrd   $tmp, $mem\n\t"
8410            "cnt    $tmp, $tmp\t# vector (8B)\n\t"
8411            "addv   $tmp, $tmp\t# vector (8B)\n\t"
8412            "mov    $dst, $tmp\t# vector (1D)" %}
8413  ins_encode %{
8414    FloatRegister tmp_reg = as_FloatRegister($tmp$$reg);
8415    loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(),
8416              as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8);
8417    __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
8418    __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister);
8419    __ mov($dst$$Register, $tmp$$FloatRegister, __ T1D, 0);
8420  %}
8421
8422  ins_pipe(pipe_class_default);
8423%}
8424
8425// ============================================================================
8426// MemBar Instruction
8427
8428instruct load_fence() %{
8429  match(LoadFence);
8430  ins_cost(VOLATILE_REF_COST);
8431
8432  format %{ "load_fence" %}
8433
8434  ins_encode %{
8435    __ membar(Assembler::LoadLoad|Assembler::LoadStore);
8436  %}
8437  ins_pipe(pipe_serial);
8438%}
8439
8440instruct unnecessary_membar_acquire() %{
8441  predicate(unnecessary_acquire(n));
8442  match(MemBarAcquire);
8443  ins_cost(0);
8444
8445  format %{ "membar_acquire (elided)" %}
8446
8447  ins_encode %{
8448    __ block_comment("membar_acquire (elided)");
8449  %}
8450
8451  ins_pipe(pipe_class_empty);
8452%}
8453
8454instruct membar_acquire() %{
8455  match(MemBarAcquire);
8456  ins_cost(VOLATILE_REF_COST);
8457
8458  format %{ "membar_acquire\n\t"
8459            "dmb ish" %}
8460
8461  ins_encode %{
8462    __ block_comment("membar_acquire");
8463    __ membar(Assembler::LoadLoad|Assembler::LoadStore);
8464  %}
8465
8466  ins_pipe(pipe_serial);
8467%}
8468
8469
8470instruct membar_acquire_lock() %{
8471  match(MemBarAcquireLock);
8472  ins_cost(VOLATILE_REF_COST);
8473
8474  format %{ "membar_acquire_lock (elided)" %}
8475
8476  ins_encode %{
8477    __ block_comment("membar_acquire_lock (elided)");
8478  %}
8479
8480  ins_pipe(pipe_serial);
8481%}
8482
8483instruct store_fence() %{
8484  match(StoreFence);
8485  ins_cost(VOLATILE_REF_COST);
8486
8487  format %{ "store_fence" %}
8488
8489  ins_encode %{
8490    __ membar(Assembler::LoadStore|Assembler::StoreStore);
8491  %}
8492  ins_pipe(pipe_serial);
8493%}
8494
8495instruct unnecessary_membar_release() %{
8496  predicate(unnecessary_release(n));
8497  match(MemBarRelease);
8498  ins_cost(0);
8499
8500  format %{ "membar_release (elided)" %}
8501
8502  ins_encode %{
8503    __ block_comment("membar_release (elided)");
8504  %}
8505  ins_pipe(pipe_serial);
8506%}
8507
8508instruct membar_release() %{
8509  match(MemBarRelease);
8510  ins_cost(VOLATILE_REF_COST);
8511
8512  format %{ "membar_release\n\t"
8513            "dmb ish" %}
8514
8515  ins_encode %{
8516    __ block_comment("membar_release");
8517    __ membar(Assembler::LoadStore|Assembler::StoreStore);
8518  %}
8519  ins_pipe(pipe_serial);
8520%}
8521
8522instruct membar_storestore() %{
8523  match(MemBarStoreStore);
8524  ins_cost(VOLATILE_REF_COST);
8525
8526  format %{ "MEMBAR-store-store" %}
8527
8528  ins_encode %{
8529    __ membar(Assembler::StoreStore);
8530  %}
8531  ins_pipe(pipe_serial);
8532%}
8533
8534instruct membar_release_lock() %{
8535  match(MemBarReleaseLock);
8536  ins_cost(VOLATILE_REF_COST);
8537
8538  format %{ "membar_release_lock (elided)" %}
8539
8540  ins_encode %{
8541    __ block_comment("membar_release_lock (elided)");
8542  %}
8543
8544  ins_pipe(pipe_serial);
8545%}
8546
8547instruct unnecessary_membar_volatile() %{
8548  predicate(unnecessary_volatile(n));
8549  match(MemBarVolatile);
8550  ins_cost(0);
8551
8552  format %{ "membar_volatile (elided)" %}
8553
8554  ins_encode %{
8555    __ block_comment("membar_volatile (elided)");
8556  %}
8557
8558  ins_pipe(pipe_serial);
8559%}
8560
8561instruct membar_volatile() %{
8562  match(MemBarVolatile);
8563  ins_cost(VOLATILE_REF_COST*100);
8564
8565  format %{ "membar_volatile\n\t"
8566             "dmb ish"%}
8567
8568  ins_encode %{
8569    __ block_comment("membar_volatile");
8570    __ membar(Assembler::StoreLoad);
8571  %}
8572
8573  ins_pipe(pipe_serial);
8574%}
8575
8576// ============================================================================
8577// Cast/Convert Instructions
8578
8579instruct castX2P(iRegPNoSp dst, iRegL src) %{
8580  match(Set dst (CastX2P src));
8581
8582  ins_cost(INSN_COST);
8583  format %{ "mov $dst, $src\t# long -> ptr" %}
8584
8585  ins_encode %{
8586    if ($dst$$reg != $src$$reg) {
8587      __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8588    }
8589  %}
8590
8591  ins_pipe(ialu_reg);
8592%}
8593
8594instruct castP2X(iRegLNoSp dst, iRegP src) %{
8595  match(Set dst (CastP2X src));
8596
8597  ins_cost(INSN_COST);
8598  format %{ "mov $dst, $src\t# ptr -> long" %}
8599
8600  ins_encode %{
8601    if ($dst$$reg != $src$$reg) {
8602      __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8603    }
8604  %}
8605
8606  ins_pipe(ialu_reg);
8607%}
8608
8609// Convert oop into int for vectors alignment masking
8610instruct convP2I(iRegINoSp dst, iRegP src) %{
8611  match(Set dst (ConvL2I (CastP2X src)));
8612
8613  ins_cost(INSN_COST);
8614  format %{ "movw $dst, $src\t# ptr -> int" %}
8615  ins_encode %{
8616    __ movw($dst$$Register, $src$$Register);
8617  %}
8618
8619  ins_pipe(ialu_reg);
8620%}
8621
8622// Convert compressed oop into int for vectors alignment masking
8623// in case of 32bit oops (heap < 4Gb).
8624instruct convN2I(iRegINoSp dst, iRegN src)
8625%{
8626  predicate(CompressedOops::shift() == 0);
8627  match(Set dst (ConvL2I (CastP2X (DecodeN src))));
8628
8629  ins_cost(INSN_COST);
8630  format %{ "mov dst, $src\t# compressed ptr -> int" %}
8631  ins_encode %{
8632    __ movw($dst$$Register, $src$$Register);
8633  %}
8634
8635  ins_pipe(ialu_reg);
8636%}
8637
8638
8639// Convert oop pointer into compressed form
8640instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
8641  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
8642  match(Set dst (EncodeP src));
8643  effect(KILL cr);
8644  ins_cost(INSN_COST * 3);
8645  format %{ "encode_heap_oop $dst, $src" %}
8646  ins_encode %{
8647    Register s = $src$$Register;
8648    Register d = $dst$$Register;
8649    __ encode_heap_oop(d, s);
8650  %}
8651  ins_pipe(ialu_reg);
8652%}
8653
8654instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{
8655  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
8656  match(Set dst (EncodeP src));
8657  ins_cost(INSN_COST * 3);
8658  format %{ "encode_heap_oop_not_null $dst, $src" %}
8659  ins_encode %{
8660    __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
8661  %}
8662  ins_pipe(ialu_reg);
8663%}
8664
8665instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
8666  predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
8667            n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
8668  match(Set dst (DecodeN src));
8669  ins_cost(INSN_COST * 3);
8670  format %{ "decode_heap_oop $dst, $src" %}
8671  ins_encode %{
8672    Register s = $src$$Register;
8673    Register d = $dst$$Register;
8674    __ decode_heap_oop(d, s);
8675  %}
8676  ins_pipe(ialu_reg);
8677%}
8678
8679instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{
8680  predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
8681            n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
8682  match(Set dst (DecodeN src));
8683  ins_cost(INSN_COST * 3);
8684  format %{ "decode_heap_oop_not_null $dst, $src" %}
8685  ins_encode %{
8686    Register s = $src$$Register;
8687    Register d = $dst$$Register;
8688    __ decode_heap_oop_not_null(d, s);
8689  %}
8690  ins_pipe(ialu_reg);
8691%}
8692
8693// n.b. AArch64 implementations of encode_klass_not_null and
8694// decode_klass_not_null do not modify the flags register so, unlike
8695// Intel, we don't kill CR as a side effect here
8696
8697instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{
8698  match(Set dst (EncodePKlass src));
8699
8700  ins_cost(INSN_COST * 3);
8701  format %{ "encode_klass_not_null $dst,$src" %}
8702
8703  ins_encode %{
8704    Register src_reg = as_Register($src$$reg);
8705    Register dst_reg = as_Register($dst$$reg);
8706    __ encode_klass_not_null(dst_reg, src_reg);
8707  %}
8708
8709   ins_pipe(ialu_reg);
8710%}
8711
8712instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{
8713  match(Set dst (DecodeNKlass src));
8714
8715  ins_cost(INSN_COST * 3);
8716  format %{ "decode_klass_not_null $dst,$src" %}
8717
8718  ins_encode %{
8719    Register src_reg = as_Register($src$$reg);
8720    Register dst_reg = as_Register($dst$$reg);
8721    if (dst_reg != src_reg) {
8722      __ decode_klass_not_null(dst_reg, src_reg);
8723    } else {
8724      __ decode_klass_not_null(dst_reg);
8725    }
8726  %}
8727
8728   ins_pipe(ialu_reg);
8729%}
8730
8731instruct checkCastPP(iRegPNoSp dst)
8732%{
8733  match(Set dst (CheckCastPP dst));
8734
8735  size(0);
8736  format %{ "# checkcastPP of $dst" %}
8737  ins_encode(/* empty encoding */);
8738  ins_pipe(pipe_class_empty);
8739%}
8740
8741instruct castPP(iRegPNoSp dst)
8742%{
8743  match(Set dst (CastPP dst));
8744
8745  size(0);
8746  format %{ "# castPP of $dst" %}
8747  ins_encode(/* empty encoding */);
8748  ins_pipe(pipe_class_empty);
8749%}
8750
8751instruct castII(iRegI dst)
8752%{
8753  match(Set dst (CastII dst));
8754
8755  size(0);
8756  format %{ "# castII of $dst" %}
8757  ins_encode(/* empty encoding */);
8758  ins_cost(0);
8759  ins_pipe(pipe_class_empty);
8760%}
8761
8762instruct castLL(iRegL dst)
8763%{
8764  match(Set dst (CastLL dst));
8765
8766  size(0);
8767  format %{ "# castLL of $dst" %}
8768  ins_encode(/* empty encoding */);
8769  ins_cost(0);
8770  ins_pipe(pipe_class_empty);
8771%}
8772
8773instruct castFF(vRegF dst)
8774%{
8775  match(Set dst (CastFF dst));
8776
8777  size(0);
8778  format %{ "# castFF of $dst" %}
8779  ins_encode(/* empty encoding */);
8780  ins_cost(0);
8781  ins_pipe(pipe_class_empty);
8782%}
8783
8784instruct castDD(vRegD dst)
8785%{
8786  match(Set dst (CastDD dst));
8787
8788  size(0);
8789  format %{ "# castDD of $dst" %}
8790  ins_encode(/* empty encoding */);
8791  ins_cost(0);
8792  ins_pipe(pipe_class_empty);
8793%}
8794
8795instruct castVVD(vecD dst)
8796%{
8797  match(Set dst (CastVV dst));
8798
8799  size(0);
8800  format %{ "# castVV of $dst" %}
8801  ins_encode(/* empty encoding */);
8802  ins_cost(0);
8803  ins_pipe(pipe_class_empty);
8804%}
8805
8806instruct castVVX(vecX dst)
8807%{
8808  match(Set dst (CastVV dst));
8809
8810  size(0);
8811  format %{ "# castVV of $dst" %}
8812  ins_encode(/* empty encoding */);
8813  ins_cost(0);
8814  ins_pipe(pipe_class_empty);
8815%}
8816
8817instruct castVV(vReg dst)
8818%{
8819  match(Set dst (CastVV dst));
8820
8821  size(0);
8822  format %{ "# castVV of $dst" %}
8823  ins_encode(/* empty encoding */);
8824  ins_cost(0);
8825  ins_pipe(pipe_class_empty);
8826%}
8827
8828// ============================================================================
8829// Atomic operation instructions
8830//
8831// Intel and SPARC both implement Ideal Node LoadPLocked and
8832// Store{PIL}Conditional instructions using a normal load for the
8833// LoadPLocked and a CAS for the Store{PIL}Conditional.
8834//
8835// The ideal code appears only to use LoadPLocked/StorePLocked as a
8836// pair to lock object allocations from Eden space when not using
8837// TLABs.
8838//
8839// There does not appear to be a Load{IL}Locked Ideal Node and the
8840// Ideal code appears to use Store{IL}Conditional as an alias for CAS
8841// and to use StoreIConditional only for 32-bit and StoreLConditional
8842// only for 64-bit.
8843//
8844// We implement LoadPLocked and StorePLocked instructions using,
8845// respectively the AArch64 hw load-exclusive and store-conditional
8846// instructions. Whereas we must implement each of
8847// Store{IL}Conditional using a CAS which employs a pair of
8848// instructions comprising a load-exclusive followed by a
8849// store-conditional.
8850
8851
8852// Locked-load (linked load) of the current heap-top
8853// used when updating the eden heap top
8854// implemented using ldaxr on AArch64
8855
8856instruct loadPLocked(iRegPNoSp dst, indirect mem)
8857%{
8858  match(Set dst (LoadPLocked mem));
8859
8860  ins_cost(VOLATILE_REF_COST);
8861
8862  format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %}
8863
8864  ins_encode(aarch64_enc_ldaxr(dst, mem));
8865
8866  ins_pipe(pipe_serial);
8867%}
8868
8869// Conditional-store of the updated heap-top.
8870// Used during allocation of the shared heap.
8871// Sets flag (EQ) on success.
8872// implemented using stlxr on AArch64.
8873
8874instruct storePConditional(memory8 heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr)
8875%{
8876  match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
8877
8878  ins_cost(VOLATILE_REF_COST);
8879
8880 // TODO
8881 // do we need to do a store-conditional release or can we just use a
8882 // plain store-conditional?
8883
8884  format %{
8885    "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release"
8886    "cmpw rscratch1, zr\t# EQ on successful write"
8887  %}
8888
8889  ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr));
8890
8891  ins_pipe(pipe_serial);
8892%}
8893
8894
8895// storeLConditional is used by PhaseMacroExpand::expand_lock_node
8896// when attempting to rebias a lock towards the current thread.  We
8897// must use the acquire form of cmpxchg in order to guarantee acquire
8898// semantics in this case.
8899instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr)
8900%{
8901  match(Set cr (StoreLConditional mem (Binary oldval newval)));
8902
8903  ins_cost(VOLATILE_REF_COST);
8904
8905  format %{
8906    "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
8907    "cmpw rscratch1, zr\t# EQ on successful write"
8908  %}
8909
8910  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval));
8911
8912  ins_pipe(pipe_slow);
8913%}
8914
8915// storeIConditional also has acquire semantics, for no better reason
8916// than matching storeLConditional.  At the time of writing this
8917// comment storeIConditional was not used anywhere by AArch64.
8918instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr)
8919%{
8920  match(Set cr (StoreIConditional mem (Binary oldval newval)));
8921
8922  ins_cost(VOLATILE_REF_COST);
8923
8924  format %{
8925    "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval"
8926    "cmpw rscratch1, zr\t# EQ on successful write"
8927  %}
8928
8929  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval));
8930
8931  ins_pipe(pipe_slow);
8932%}
8933
8934// standard CompareAndSwapX when we are using barriers
8935// these have higher priority than the rules selected by a predicate
8936
8937// XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher
8938// can't match them
8939
8940instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8941
8942  match(Set res (CompareAndSwapB mem (Binary oldval newval)));
8943  ins_cost(2 * VOLATILE_REF_COST);
8944
8945  effect(KILL cr);
8946
8947  format %{
8948    "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8949    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8950  %}
8951
8952  ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval),
8953            aarch64_enc_cset_eq(res));
8954
8955  ins_pipe(pipe_slow);
8956%}
8957
8958instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8959
8960  match(Set res (CompareAndSwapS mem (Binary oldval newval)));
8961  ins_cost(2 * VOLATILE_REF_COST);
8962
8963  effect(KILL cr);
8964
8965  format %{
8966    "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8967    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8968  %}
8969
8970  ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval),
8971            aarch64_enc_cset_eq(res));
8972
8973  ins_pipe(pipe_slow);
8974%}
8975
8976instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8977
8978  match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8979  ins_cost(2 * VOLATILE_REF_COST);
8980
8981  effect(KILL cr);
8982
8983 format %{
8984    "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8985    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8986 %}
8987
8988 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8989            aarch64_enc_cset_eq(res));
8990
8991  ins_pipe(pipe_slow);
8992%}
8993
8994instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8995
8996  match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8997  ins_cost(2 * VOLATILE_REF_COST);
8998
8999  effect(KILL cr);
9000
9001 format %{
9002    "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
9003    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9004 %}
9005
9006 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
9007            aarch64_enc_cset_eq(res));
9008
9009  ins_pipe(pipe_slow);
9010%}
9011
9012instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9013
9014  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
9015  predicate(n->as_LoadStore()->barrier_data() == 0);
9016  ins_cost(2 * VOLATILE_REF_COST);
9017
9018  effect(KILL cr);
9019
9020 format %{
9021    "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
9022    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9023 %}
9024
9025 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
9026            aarch64_enc_cset_eq(res));
9027
9028  ins_pipe(pipe_slow);
9029%}
9030
9031instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
9032
9033  match(Set res (CompareAndSwapN mem (Binary oldval newval)));
9034  ins_cost(2 * VOLATILE_REF_COST);
9035
9036  effect(KILL cr);
9037
9038 format %{
9039    "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
9040    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9041 %}
9042
9043 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
9044            aarch64_enc_cset_eq(res));
9045
9046  ins_pipe(pipe_slow);
9047%}
9048
9049// alternative CompareAndSwapX when we are eliding barriers
9050
9051instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
9052
9053  predicate(needs_acquiring_load_exclusive(n));
9054  match(Set res (CompareAndSwapB mem (Binary oldval newval)));
9055  ins_cost(VOLATILE_REF_COST);
9056
9057  effect(KILL cr);
9058
9059  format %{
9060    "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
9061    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9062  %}
9063
9064  ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval),
9065            aarch64_enc_cset_eq(res));
9066
9067  ins_pipe(pipe_slow);
9068%}
9069
9070instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
9071
9072  predicate(needs_acquiring_load_exclusive(n));
9073  match(Set res (CompareAndSwapS mem (Binary oldval newval)));
9074  ins_cost(VOLATILE_REF_COST);
9075
9076  effect(KILL cr);
9077
9078  format %{
9079    "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
9080    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9081  %}
9082
9083  ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval),
9084            aarch64_enc_cset_eq(res));
9085
9086  ins_pipe(pipe_slow);
9087%}
9088
9089instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
9090
9091  predicate(needs_acquiring_load_exclusive(n));
9092  match(Set res (CompareAndSwapI mem (Binary oldval newval)));
9093  ins_cost(VOLATILE_REF_COST);
9094
9095  effect(KILL cr);
9096
9097 format %{
9098    "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
9099    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9100 %}
9101
9102 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
9103            aarch64_enc_cset_eq(res));
9104
9105  ins_pipe(pipe_slow);
9106%}
9107
9108instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
9109
9110  predicate(needs_acquiring_load_exclusive(n));
9111  match(Set res (CompareAndSwapL mem (Binary oldval newval)));
9112  ins_cost(VOLATILE_REF_COST);
9113
9114  effect(KILL cr);
9115
9116 format %{
9117    "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
9118    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9119 %}
9120
9121 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
9122            aarch64_enc_cset_eq(res));
9123
9124  ins_pipe(pipe_slow);
9125%}
9126
9127instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9128
9129  predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
9130  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
9131  ins_cost(VOLATILE_REF_COST);
9132
9133  effect(KILL cr);
9134
9135 format %{
9136    "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
9137    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9138 %}
9139
9140 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
9141            aarch64_enc_cset_eq(res));
9142
9143  ins_pipe(pipe_slow);
9144%}
9145
9146instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
9147
9148  predicate(needs_acquiring_load_exclusive(n));
9149  match(Set res (CompareAndSwapN mem (Binary oldval newval)));
9150  ins_cost(VOLATILE_REF_COST);
9151
9152  effect(KILL cr);
9153
9154 format %{
9155    "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
9156    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9157 %}
9158
9159 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
9160            aarch64_enc_cset_eq(res));
9161
9162  ins_pipe(pipe_slow);
9163%}
9164
9165
9166// ---------------------------------------------------------------------
9167
9168// BEGIN This section of the file is automatically generated. Do not edit --------------
9169
9170// Sundry CAS operations.  Note that release is always true,
9171// regardless of the memory ordering of the CAS.  This is because we
9172// need the volatile case to be sequentially consistent but there is
9173// no trailing StoreLoad barrier emitted by C2.  Unfortunately we
9174// can't check the type of memory ordering here, so we always emit a
9175// STLXR.
9176
9177// This section is generated from aarch64_ad_cas.m4
9178
9179
9180
9181// This pattern is generated automatically from cas.m4.
9182// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9183instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9184
9185  match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
9186  ins_cost(2 * VOLATILE_REF_COST);
9187  effect(TEMP_DEF res, KILL cr);
9188  format %{
9189    "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
9190  %}
9191  ins_encode %{
9192    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9193               Assembler::byte, /*acquire*/ false, /*release*/ true,
9194               /*weak*/ false, $res$$Register);
9195    __ sxtbw($res$$Register, $res$$Register);
9196  %}
9197  ins_pipe(pipe_slow);
9198%}
9199
9200// This pattern is generated automatically from cas.m4.
9201// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9202instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9203
9204  match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
9205  ins_cost(2 * VOLATILE_REF_COST);
9206  effect(TEMP_DEF res, KILL cr);
9207  format %{
9208    "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
9209  %}
9210  ins_encode %{
9211    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9212               Assembler::halfword, /*acquire*/ false, /*release*/ true,
9213               /*weak*/ false, $res$$Register);
9214    __ sxthw($res$$Register, $res$$Register);
9215  %}
9216  ins_pipe(pipe_slow);
9217%}
9218
9219// This pattern is generated automatically from cas.m4.
9220// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9221instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9222
9223  match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
9224  ins_cost(2 * VOLATILE_REF_COST);
9225  effect(TEMP_DEF res, KILL cr);
9226  format %{
9227    "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
9228  %}
9229  ins_encode %{
9230    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9231               Assembler::word, /*acquire*/ false, /*release*/ true,
9232               /*weak*/ false, $res$$Register);
9233  %}
9234  ins_pipe(pipe_slow);
9235%}
9236
9237// This pattern is generated automatically from cas.m4.
9238// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9239instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
9240
9241  match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
9242  ins_cost(2 * VOLATILE_REF_COST);
9243  effect(TEMP_DEF res, KILL cr);
9244  format %{
9245    "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
9246  %}
9247  ins_encode %{
9248    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9249               Assembler::xword, /*acquire*/ false, /*release*/ true,
9250               /*weak*/ false, $res$$Register);
9251  %}
9252  ins_pipe(pipe_slow);
9253%}
9254
9255// This pattern is generated automatically from cas.m4.
9256// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9257instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
9258
9259  match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
9260  ins_cost(2 * VOLATILE_REF_COST);
9261  effect(TEMP_DEF res, KILL cr);
9262  format %{
9263    "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9264  %}
9265  ins_encode %{
9266    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9267               Assembler::word, /*acquire*/ false, /*release*/ true,
9268               /*weak*/ false, $res$$Register);
9269  %}
9270  ins_pipe(pipe_slow);
9271%}
9272
9273// This pattern is generated automatically from cas.m4.
9274// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9275instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9276  predicate(n->as_LoadStore()->barrier_data() == 0);
9277  match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
9278  ins_cost(2 * VOLATILE_REF_COST);
9279  effect(TEMP_DEF res, KILL cr);
9280  format %{
9281    "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
9282  %}
9283  ins_encode %{
9284    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9285               Assembler::xword, /*acquire*/ false, /*release*/ true,
9286               /*weak*/ false, $res$$Register);
9287  %}
9288  ins_pipe(pipe_slow);
9289%}
9290
9291// This pattern is generated automatically from cas.m4.
9292// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9293instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9294  predicate(needs_acquiring_load_exclusive(n));
9295  match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
9296  ins_cost(VOLATILE_REF_COST);
9297  effect(TEMP_DEF res, KILL cr);
9298  format %{
9299    "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
9300  %}
9301  ins_encode %{
9302    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9303               Assembler::byte, /*acquire*/ true, /*release*/ true,
9304               /*weak*/ false, $res$$Register);
9305    __ sxtbw($res$$Register, $res$$Register);
9306  %}
9307  ins_pipe(pipe_slow);
9308%}
9309
9310// This pattern is generated automatically from cas.m4.
9311// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9312instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9313  predicate(needs_acquiring_load_exclusive(n));
9314  match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
9315  ins_cost(VOLATILE_REF_COST);
9316  effect(TEMP_DEF res, KILL cr);
9317  format %{
9318    "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
9319  %}
9320  ins_encode %{
9321    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9322               Assembler::halfword, /*acquire*/ true, /*release*/ true,
9323               /*weak*/ false, $res$$Register);
9324    __ sxthw($res$$Register, $res$$Register);
9325  %}
9326  ins_pipe(pipe_slow);
9327%}
9328
9329// This pattern is generated automatically from cas.m4.
9330// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9331instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9332  predicate(needs_acquiring_load_exclusive(n));
9333  match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
9334  ins_cost(VOLATILE_REF_COST);
9335  effect(TEMP_DEF res, KILL cr);
9336  format %{
9337    "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
9338  %}
9339  ins_encode %{
9340    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9341               Assembler::word, /*acquire*/ true, /*release*/ true,
9342               /*weak*/ false, $res$$Register);
9343  %}
9344  ins_pipe(pipe_slow);
9345%}
9346
9347// This pattern is generated automatically from cas.m4.
9348// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9349instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
9350  predicate(needs_acquiring_load_exclusive(n));
9351  match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
9352  ins_cost(VOLATILE_REF_COST);
9353  effect(TEMP_DEF res, KILL cr);
9354  format %{
9355    "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
9356  %}
9357  ins_encode %{
9358    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9359               Assembler::xword, /*acquire*/ true, /*release*/ true,
9360               /*weak*/ false, $res$$Register);
9361  %}
9362  ins_pipe(pipe_slow);
9363%}
9364
9365// This pattern is generated automatically from cas.m4.
9366// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9367instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
9368  predicate(needs_acquiring_load_exclusive(n));
9369  match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
9370  ins_cost(VOLATILE_REF_COST);
9371  effect(TEMP_DEF res, KILL cr);
9372  format %{
9373    "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9374  %}
9375  ins_encode %{
9376    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9377               Assembler::word, /*acquire*/ true, /*release*/ true,
9378               /*weak*/ false, $res$$Register);
9379  %}
9380  ins_pipe(pipe_slow);
9381%}
9382
9383// This pattern is generated automatically from cas.m4.
9384// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9385instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9386  predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
9387  match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
9388  ins_cost(VOLATILE_REF_COST);
9389  effect(TEMP_DEF res, KILL cr);
9390  format %{
9391    "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
9392  %}
9393  ins_encode %{
9394    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9395               Assembler::xword, /*acquire*/ true, /*release*/ true,
9396               /*weak*/ false, $res$$Register);
9397  %}
9398  ins_pipe(pipe_slow);
9399%}
9400
9401// This pattern is generated automatically from cas.m4.
9402// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9403instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9404
9405  match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
9406  ins_cost(2 * VOLATILE_REF_COST);
9407  effect(KILL cr);
9408  format %{
9409    "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
9410    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9411  %}
9412  ins_encode %{
9413    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9414               Assembler::byte, /*acquire*/ false, /*release*/ true,
9415               /*weak*/ true, noreg);
9416    __ csetw($res$$Register, Assembler::EQ);
9417  %}
9418  ins_pipe(pipe_slow);
9419%}
9420
9421// This pattern is generated automatically from cas.m4.
9422// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9423instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9424
9425  match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
9426  ins_cost(2 * VOLATILE_REF_COST);
9427  effect(KILL cr);
9428  format %{
9429    "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
9430    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9431  %}
9432  ins_encode %{
9433    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9434               Assembler::halfword, /*acquire*/ false, /*release*/ true,
9435               /*weak*/ true, noreg);
9436    __ csetw($res$$Register, Assembler::EQ);
9437  %}
9438  ins_pipe(pipe_slow);
9439%}
9440
9441// This pattern is generated automatically from cas.m4.
9442// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9443instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9444
9445  match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
9446  ins_cost(2 * VOLATILE_REF_COST);
9447  effect(KILL cr);
9448  format %{
9449    "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
9450    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9451  %}
9452  ins_encode %{
9453    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9454               Assembler::word, /*acquire*/ false, /*release*/ true,
9455               /*weak*/ true, noreg);
9456    __ csetw($res$$Register, Assembler::EQ);
9457  %}
9458  ins_pipe(pipe_slow);
9459%}
9460
9461// This pattern is generated automatically from cas.m4.
9462// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9463instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
9464
9465  match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
9466  ins_cost(2 * VOLATILE_REF_COST);
9467  effect(KILL cr);
9468  format %{
9469    "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
9470    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9471  %}
9472  ins_encode %{
9473    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9474               Assembler::xword, /*acquire*/ false, /*release*/ true,
9475               /*weak*/ true, noreg);
9476    __ csetw($res$$Register, Assembler::EQ);
9477  %}
9478  ins_pipe(pipe_slow);
9479%}
9480
9481// This pattern is generated automatically from cas.m4.
9482// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9483instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
9484
9485  match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
9486  ins_cost(2 * VOLATILE_REF_COST);
9487  effect(KILL cr);
9488  format %{
9489    "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9490    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9491  %}
9492  ins_encode %{
9493    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9494               Assembler::word, /*acquire*/ false, /*release*/ true,
9495               /*weak*/ true, noreg);
9496    __ csetw($res$$Register, Assembler::EQ);
9497  %}
9498  ins_pipe(pipe_slow);
9499%}
9500
9501// This pattern is generated automatically from cas.m4.
9502// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9503instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9504  predicate(n->as_LoadStore()->barrier_data() == 0);
9505  match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
9506  ins_cost(2 * VOLATILE_REF_COST);
9507  effect(KILL cr);
9508  format %{
9509    "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
9510    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9511  %}
9512  ins_encode %{
9513    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9514               Assembler::xword, /*acquire*/ false, /*release*/ true,
9515               /*weak*/ true, noreg);
9516    __ csetw($res$$Register, Assembler::EQ);
9517  %}
9518  ins_pipe(pipe_slow);
9519%}
9520
9521// This pattern is generated automatically from cas.m4.
9522// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9523instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9524  predicate(needs_acquiring_load_exclusive(n));
9525  match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
9526  ins_cost(VOLATILE_REF_COST);
9527  effect(KILL cr);
9528  format %{
9529    "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
9530    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9531  %}
9532  ins_encode %{
9533    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9534               Assembler::byte, /*acquire*/ true, /*release*/ true,
9535               /*weak*/ true, noreg);
9536    __ csetw($res$$Register, Assembler::EQ);
9537  %}
9538  ins_pipe(pipe_slow);
9539%}
9540
9541// This pattern is generated automatically from cas.m4.
9542// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9543instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9544  predicate(needs_acquiring_load_exclusive(n));
9545  match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
9546  ins_cost(VOLATILE_REF_COST);
9547  effect(KILL cr);
9548  format %{
9549    "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval"
9550    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9551  %}
9552  ins_encode %{
9553    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9554               Assembler::halfword, /*acquire*/ true, /*release*/ true,
9555               /*weak*/ true, noreg);
9556    __ csetw($res$$Register, Assembler::EQ);
9557  %}
9558  ins_pipe(pipe_slow);
9559%}
9560
9561// This pattern is generated automatically from cas.m4.
9562// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9563instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
9564  predicate(needs_acquiring_load_exclusive(n));
9565  match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
9566  ins_cost(VOLATILE_REF_COST);
9567  effect(KILL cr);
9568  format %{
9569    "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval"
9570    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9571  %}
9572  ins_encode %{
9573    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9574               Assembler::word, /*acquire*/ true, /*release*/ true,
9575               /*weak*/ true, noreg);
9576    __ csetw($res$$Register, Assembler::EQ);
9577  %}
9578  ins_pipe(pipe_slow);
9579%}
9580
9581// This pattern is generated automatically from cas.m4.
9582// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9583instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
9584  predicate(needs_acquiring_load_exclusive(n));
9585  match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
9586  ins_cost(VOLATILE_REF_COST);
9587  effect(KILL cr);
9588  format %{
9589    "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
9590    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9591  %}
9592  ins_encode %{
9593    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9594               Assembler::xword, /*acquire*/ true, /*release*/ true,
9595               /*weak*/ true, noreg);
9596    __ csetw($res$$Register, Assembler::EQ);
9597  %}
9598  ins_pipe(pipe_slow);
9599%}
9600
9601// This pattern is generated automatically from cas.m4.
9602// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9603instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
9604  predicate(needs_acquiring_load_exclusive(n));
9605  match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
9606  ins_cost(VOLATILE_REF_COST);
9607  effect(KILL cr);
9608  format %{
9609    "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9610    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9611  %}
9612  ins_encode %{
9613    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9614               Assembler::word, /*acquire*/ true, /*release*/ true,
9615               /*weak*/ true, noreg);
9616    __ csetw($res$$Register, Assembler::EQ);
9617  %}
9618  ins_pipe(pipe_slow);
9619%}
9620
9621// This pattern is generated automatically from cas.m4.
9622// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
9623instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9624  predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
9625  match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
9626  ins_cost(VOLATILE_REF_COST);
9627  effect(KILL cr);
9628  format %{
9629    "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
9630    "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9631  %}
9632  ins_encode %{
9633    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9634               Assembler::xword, /*acquire*/ true, /*release*/ true,
9635               /*weak*/ true, noreg);
9636    __ csetw($res$$Register, Assembler::EQ);
9637  %}
9638  ins_pipe(pipe_slow);
9639%}
9640
9641// END This section of the file is automatically generated. Do not edit --------------
9642// ---------------------------------------------------------------------
9643
9644instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
9645  match(Set prev (GetAndSetI mem newv));
9646  ins_cost(2 * VOLATILE_REF_COST);
9647  format %{ "atomic_xchgw  $prev, $newv, [$mem]" %}
9648  ins_encode %{
9649    __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9650  %}
9651  ins_pipe(pipe_serial);
9652%}
9653
9654instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
9655  match(Set prev (GetAndSetL mem newv));
9656  ins_cost(2 * VOLATILE_REF_COST);
9657  format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
9658  ins_encode %{
9659    __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
9660  %}
9661  ins_pipe(pipe_serial);
9662%}
9663
9664instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
9665  match(Set prev (GetAndSetN mem newv));
9666  ins_cost(2 * VOLATILE_REF_COST);
9667  format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
9668  ins_encode %{
9669    __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9670  %}
9671  ins_pipe(pipe_serial);
9672%}
9673
9674instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
9675  predicate(n->as_LoadStore()->barrier_data() == 0);
9676  match(Set prev (GetAndSetP mem newv));
9677  ins_cost(2 * VOLATILE_REF_COST);
9678  format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
9679  ins_encode %{
9680    __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
9681  %}
9682  ins_pipe(pipe_serial);
9683%}
9684
9685instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{
9686  predicate(needs_acquiring_load_exclusive(n));
9687  match(Set prev (GetAndSetI mem newv));
9688  ins_cost(VOLATILE_REF_COST);
9689  format %{ "atomic_xchgw_acq  $prev, $newv, [$mem]" %}
9690  ins_encode %{
9691    __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9692  %}
9693  ins_pipe(pipe_serial);
9694%}
9695
9696instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{
9697  predicate(needs_acquiring_load_exclusive(n));
9698  match(Set prev (GetAndSetL mem newv));
9699  ins_cost(VOLATILE_REF_COST);
9700  format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
9701  ins_encode %{
9702    __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
9703  %}
9704  ins_pipe(pipe_serial);
9705%}
9706
9707instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{
9708  predicate(needs_acquiring_load_exclusive(n));
9709  match(Set prev (GetAndSetN mem newv));
9710  ins_cost(VOLATILE_REF_COST);
9711  format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %}
9712  ins_encode %{
9713    __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base));
9714  %}
9715  ins_pipe(pipe_serial);
9716%}
9717
9718instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{
9719  predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
9720  match(Set prev (GetAndSetP mem newv));
9721  ins_cost(VOLATILE_REF_COST);
9722  format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
9723  ins_encode %{
9724    __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
9725  %}
9726  ins_pipe(pipe_serial);
9727%}
9728
9729
9730instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{
9731  match(Set newval (GetAndAddL mem incr));
9732  ins_cost(2 * VOLATILE_REF_COST + 1);
9733  format %{ "get_and_addL $newval, [$mem], $incr" %}
9734  ins_encode %{
9735    __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base));
9736  %}
9737  ins_pipe(pipe_serial);
9738%}
9739
9740instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{
9741  predicate(n->as_LoadStore()->result_not_used());
9742  match(Set dummy (GetAndAddL mem incr));
9743  ins_cost(2 * VOLATILE_REF_COST);
9744  format %{ "get_and_addL [$mem], $incr" %}
9745  ins_encode %{
9746    __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base));
9747  %}
9748  ins_pipe(pipe_serial);
9749%}
9750
9751instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
9752  match(Set newval (GetAndAddL mem incr));
9753  ins_cost(2 * VOLATILE_REF_COST + 1);
9754  format %{ "get_and_addL $newval, [$mem], $incr" %}
9755  ins_encode %{
9756    __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base));
9757  %}
9758  ins_pipe(pipe_serial);
9759%}
9760
9761instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{
9762  predicate(n->as_LoadStore()->result_not_used());
9763  match(Set dummy (GetAndAddL mem incr));
9764  ins_cost(2 * VOLATILE_REF_COST);
9765  format %{ "get_and_addL [$mem], $incr" %}
9766  ins_encode %{
9767    __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base));
9768  %}
9769  ins_pipe(pipe_serial);
9770%}
9771
9772instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
9773  match(Set newval (GetAndAddI mem incr));
9774  ins_cost(2 * VOLATILE_REF_COST + 1);
9775  format %{ "get_and_addI $newval, [$mem], $incr" %}
9776  ins_encode %{
9777    __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base));
9778  %}
9779  ins_pipe(pipe_serial);
9780%}
9781
9782instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{
9783  predicate(n->as_LoadStore()->result_not_used());
9784  match(Set dummy (GetAndAddI mem incr));
9785  ins_cost(2 * VOLATILE_REF_COST);
9786  format %{ "get_and_addI [$mem], $incr" %}
9787  ins_encode %{
9788    __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base));
9789  %}
9790  ins_pipe(pipe_serial);
9791%}
9792
9793instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{
9794  match(Set newval (GetAndAddI mem incr));
9795  ins_cost(2 * VOLATILE_REF_COST + 1);
9796  format %{ "get_and_addI $newval, [$mem], $incr" %}
9797  ins_encode %{
9798    __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base));
9799  %}
9800  ins_pipe(pipe_serial);
9801%}
9802
9803instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{
9804  predicate(n->as_LoadStore()->result_not_used());
9805  match(Set dummy (GetAndAddI mem incr));
9806  ins_cost(2 * VOLATILE_REF_COST);
9807  format %{ "get_and_addI [$mem], $incr" %}
9808  ins_encode %{
9809    __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base));
9810  %}
9811  ins_pipe(pipe_serial);
9812%}
9813
9814instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{
9815  predicate(needs_acquiring_load_exclusive(n));
9816  match(Set newval (GetAndAddL mem incr));
9817  ins_cost(VOLATILE_REF_COST + 1);
9818  format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
9819  ins_encode %{
9820    __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base));
9821  %}
9822  ins_pipe(pipe_serial);
9823%}
9824
9825instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{
9826  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9827  match(Set dummy (GetAndAddL mem incr));
9828  ins_cost(VOLATILE_REF_COST);
9829  format %{ "get_and_addL_acq [$mem], $incr" %}
9830  ins_encode %{
9831    __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base));
9832  %}
9833  ins_pipe(pipe_serial);
9834%}
9835
9836instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
9837  predicate(needs_acquiring_load_exclusive(n));
9838  match(Set newval (GetAndAddL mem incr));
9839  ins_cost(VOLATILE_REF_COST + 1);
9840  format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
9841  ins_encode %{
9842    __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base));
9843  %}
9844  ins_pipe(pipe_serial);
9845%}
9846
9847instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{
9848  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9849  match(Set dummy (GetAndAddL mem incr));
9850  ins_cost(VOLATILE_REF_COST);
9851  format %{ "get_and_addL_acq [$mem], $incr" %}
9852  ins_encode %{
9853    __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base));
9854  %}
9855  ins_pipe(pipe_serial);
9856%}
9857
9858instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
9859  predicate(needs_acquiring_load_exclusive(n));
9860  match(Set newval (GetAndAddI mem incr));
9861  ins_cost(VOLATILE_REF_COST + 1);
9862  format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
9863  ins_encode %{
9864    __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base));
9865  %}
9866  ins_pipe(pipe_serial);
9867%}
9868
9869instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{
9870  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9871  match(Set dummy (GetAndAddI mem incr));
9872  ins_cost(VOLATILE_REF_COST);
9873  format %{ "get_and_addI_acq [$mem], $incr" %}
9874  ins_encode %{
9875    __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base));
9876  %}
9877  ins_pipe(pipe_serial);
9878%}
9879
9880instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{
9881  predicate(needs_acquiring_load_exclusive(n));
9882  match(Set newval (GetAndAddI mem incr));
9883  ins_cost(VOLATILE_REF_COST + 1);
9884  format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
9885  ins_encode %{
9886    __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base));
9887  %}
9888  ins_pipe(pipe_serial);
9889%}
9890
9891instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{
9892  predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
9893  match(Set dummy (GetAndAddI mem incr));
9894  ins_cost(VOLATILE_REF_COST);
9895  format %{ "get_and_addI_acq [$mem], $incr" %}
9896  ins_encode %{
9897    __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base));
9898  %}
9899  ins_pipe(pipe_serial);
9900%}
9901
9902// Manifest a CmpL result in an integer register.
9903// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0)
9904instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags)
9905%{
9906  match(Set dst (CmpL3 src1 src2));
9907  effect(KILL flags);
9908
9909  ins_cost(INSN_COST * 6);
9910  format %{
9911      "cmp $src1, $src2"
9912      "csetw $dst, ne"
9913      "cnegw $dst, lt"
9914  %}
9915  // format %{ "CmpL3 $dst, $src1, $src2" %}
9916  ins_encode %{
9917    __ cmp($src1$$Register, $src2$$Register);
9918    __ csetw($dst$$Register, Assembler::NE);
9919    __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
9920  %}
9921
9922  ins_pipe(pipe_class_default);
9923%}
9924
9925instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags)
9926%{
9927  match(Set dst (CmpL3 src1 src2));
9928  effect(KILL flags);
9929
9930  ins_cost(INSN_COST * 6);
9931  format %{
9932      "cmp $src1, $src2"
9933      "csetw $dst, ne"
9934      "cnegw $dst, lt"
9935  %}
9936  ins_encode %{
9937    int32_t con = (int32_t)$src2$$constant;
9938     if (con < 0) {
9939      __ adds(zr, $src1$$Register, -con);
9940    } else {
9941      __ subs(zr, $src1$$Register, con);
9942    }
9943    __ csetw($dst$$Register, Assembler::NE);
9944    __ cnegw($dst$$Register, $dst$$Register, Assembler::LT);
9945  %}
9946
9947  ins_pipe(pipe_class_default);
9948%}
9949
9950// ============================================================================
9951// Conditional Move Instructions
9952
9953// n.b. we have identical rules for both a signed compare op (cmpOp)
9954// and an unsigned compare op (cmpOpU). it would be nice if we could
9955// define an op class which merged both inputs and use it to type the
9956// argument to a single rule. unfortunatelyt his fails because the
9957// opclass does not live up to the COND_INTER interface of its
9958// component operands. When the generic code tries to negate the
9959// operand it ends up running the generci Machoper::negate method
9960// which throws a ShouldNotHappen. So, we have to provide two flavours
9961// of each rule, one for a cmpOp and a second for a cmpOpU (sigh).
9962
9963instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9964  match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9965
9966  ins_cost(INSN_COST * 2);
9967  format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int"  %}
9968
9969  ins_encode %{
9970    __ cselw(as_Register($dst$$reg),
9971             as_Register($src2$$reg),
9972             as_Register($src1$$reg),
9973             (Assembler::Condition)$cmp$$cmpcode);
9974  %}
9975
9976  ins_pipe(icond_reg_reg);
9977%}
9978
9979instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
9980  match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2)));
9981
9982  ins_cost(INSN_COST * 2);
9983  format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int"  %}
9984
9985  ins_encode %{
9986    __ cselw(as_Register($dst$$reg),
9987             as_Register($src2$$reg),
9988             as_Register($src1$$reg),
9989             (Assembler::Condition)$cmp$$cmpcode);
9990  %}
9991
9992  ins_pipe(icond_reg_reg);
9993%}
9994
9995// special cases where one arg is zero
9996
9997// n.b. this is selected in preference to the rule above because it
9998// avoids loading constant 0 into a source register
9999
10000// TODO
10001// we ought only to be able to cull one of these variants as the ideal
10002// transforms ought always to order the zero consistently (to left/right?)
10003
10004instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
10005  match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
10006
10007  ins_cost(INSN_COST * 2);
10008  format %{ "cselw $dst, $src, zr $cmp\t# signed, int"  %}
10009
10010  ins_encode %{
10011    __ cselw(as_Register($dst$$reg),
10012             as_Register($src$$reg),
10013             zr,
10014             (Assembler::Condition)$cmp$$cmpcode);
10015  %}
10016
10017  ins_pipe(icond_reg);
10018%}
10019
10020instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{
10021  match(Set dst (CMoveI (Binary cmp cr) (Binary zero src)));
10022
10023  ins_cost(INSN_COST * 2);
10024  format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int"  %}
10025
10026  ins_encode %{
10027    __ cselw(as_Register($dst$$reg),
10028             as_Register($src$$reg),
10029             zr,
10030             (Assembler::Condition)$cmp$$cmpcode);
10031  %}
10032
10033  ins_pipe(icond_reg);
10034%}
10035
10036instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
10037  match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
10038
10039  ins_cost(INSN_COST * 2);
10040  format %{ "cselw $dst, zr, $src $cmp\t# signed, int"  %}
10041
10042  ins_encode %{
10043    __ cselw(as_Register($dst$$reg),
10044             zr,
10045             as_Register($src$$reg),
10046             (Assembler::Condition)$cmp$$cmpcode);
10047  %}
10048
10049  ins_pipe(icond_reg);
10050%}
10051
10052instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{
10053  match(Set dst (CMoveI (Binary cmp cr) (Binary src zero)));
10054
10055  ins_cost(INSN_COST * 2);
10056  format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int"  %}
10057
10058  ins_encode %{
10059    __ cselw(as_Register($dst$$reg),
10060             zr,
10061             as_Register($src$$reg),
10062             (Assembler::Condition)$cmp$$cmpcode);
10063  %}
10064
10065  ins_pipe(icond_reg);
10066%}
10067
10068// special case for creating a boolean 0 or 1
10069
10070// n.b. this is selected in preference to the rule above because it
10071// avoids loading constants 0 and 1 into a source register
10072
10073instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
10074  match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
10075
10076  ins_cost(INSN_COST * 2);
10077  format %{ "csincw $dst, zr, zr $cmp\t# signed, int"  %}
10078
10079  ins_encode %{
10080    // equivalently
10081    // cset(as_Register($dst$$reg),
10082    //      negate_condition((Assembler::Condition)$cmp$$cmpcode));
10083    __ csincw(as_Register($dst$$reg),
10084             zr,
10085             zr,
10086             (Assembler::Condition)$cmp$$cmpcode);
10087  %}
10088
10089  ins_pipe(icond_none);
10090%}
10091
10092instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{
10093  match(Set dst (CMoveI (Binary cmp cr) (Binary one zero)));
10094
10095  ins_cost(INSN_COST * 2);
10096  format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int"  %}
10097
10098  ins_encode %{
10099    // equivalently
10100    // cset(as_Register($dst$$reg),
10101    //      negate_condition((Assembler::Condition)$cmp$$cmpcode));
10102    __ csincw(as_Register($dst$$reg),
10103             zr,
10104             zr,
10105             (Assembler::Condition)$cmp$$cmpcode);
10106  %}
10107
10108  ins_pipe(icond_none);
10109%}
10110
10111instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
10112  match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
10113
10114  ins_cost(INSN_COST * 2);
10115  format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long"  %}
10116
10117  ins_encode %{
10118    __ csel(as_Register($dst$$reg),
10119            as_Register($src2$$reg),
10120            as_Register($src1$$reg),
10121            (Assembler::Condition)$cmp$$cmpcode);
10122  %}
10123
10124  ins_pipe(icond_reg_reg);
10125%}
10126
10127instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{
10128  match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2)));
10129
10130  ins_cost(INSN_COST * 2);
10131  format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long"  %}
10132
10133  ins_encode %{
10134    __ csel(as_Register($dst$$reg),
10135            as_Register($src2$$reg),
10136            as_Register($src1$$reg),
10137            (Assembler::Condition)$cmp$$cmpcode);
10138  %}
10139
10140  ins_pipe(icond_reg_reg);
10141%}
10142
10143// special cases where one arg is zero
10144
10145instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
10146  match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
10147
10148  ins_cost(INSN_COST * 2);
10149  format %{ "csel $dst, zr, $src $cmp\t# signed, long"  %}
10150
10151  ins_encode %{
10152    __ csel(as_Register($dst$$reg),
10153            zr,
10154            as_Register($src$$reg),
10155            (Assembler::Condition)$cmp$$cmpcode);
10156  %}
10157
10158  ins_pipe(icond_reg);
10159%}
10160
10161instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{
10162  match(Set dst (CMoveL (Binary cmp cr) (Binary src zero)));
10163
10164  ins_cost(INSN_COST * 2);
10165  format %{ "csel $dst, zr, $src $cmp\t# unsigned, long"  %}
10166
10167  ins_encode %{
10168    __ csel(as_Register($dst$$reg),
10169            zr,
10170            as_Register($src$$reg),
10171            (Assembler::Condition)$cmp$$cmpcode);
10172  %}
10173
10174  ins_pipe(icond_reg);
10175%}
10176
10177instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
10178  match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
10179
10180  ins_cost(INSN_COST * 2);
10181  format %{ "csel $dst, $src, zr $cmp\t# signed, long"  %}
10182
10183  ins_encode %{
10184    __ csel(as_Register($dst$$reg),
10185            as_Register($src$$reg),
10186            zr,
10187            (Assembler::Condition)$cmp$$cmpcode);
10188  %}
10189
10190  ins_pipe(icond_reg);
10191%}
10192
10193instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{
10194  match(Set dst (CMoveL (Binary cmp cr) (Binary zero src)));
10195
10196  ins_cost(INSN_COST * 2);
10197  format %{ "csel $dst, $src, zr $cmp\t# unsigned, long"  %}
10198
10199  ins_encode %{
10200    __ csel(as_Register($dst$$reg),
10201            as_Register($src$$reg),
10202            zr,
10203            (Assembler::Condition)$cmp$$cmpcode);
10204  %}
10205
10206  ins_pipe(icond_reg);
10207%}
10208
10209instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
10210  match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
10211
10212  ins_cost(INSN_COST * 2);
10213  format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr"  %}
10214
10215  ins_encode %{
10216    __ csel(as_Register($dst$$reg),
10217            as_Register($src2$$reg),
10218            as_Register($src1$$reg),
10219            (Assembler::Condition)$cmp$$cmpcode);
10220  %}
10221
10222  ins_pipe(icond_reg_reg);
10223%}
10224
10225instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{
10226  match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2)));
10227
10228  ins_cost(INSN_COST * 2);
10229  format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr"  %}
10230
10231  ins_encode %{
10232    __ csel(as_Register($dst$$reg),
10233            as_Register($src2$$reg),
10234            as_Register($src1$$reg),
10235            (Assembler::Condition)$cmp$$cmpcode);
10236  %}
10237
10238  ins_pipe(icond_reg_reg);
10239%}
10240
10241// special cases where one arg is zero
10242
10243instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
10244  match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
10245
10246  ins_cost(INSN_COST * 2);
10247  format %{ "csel $dst, zr, $src $cmp\t# signed, ptr"  %}
10248
10249  ins_encode %{
10250    __ csel(as_Register($dst$$reg),
10251            zr,
10252            as_Register($src$$reg),
10253            (Assembler::Condition)$cmp$$cmpcode);
10254  %}
10255
10256  ins_pipe(icond_reg);
10257%}
10258
10259instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{
10260  match(Set dst (CMoveP (Binary cmp cr) (Binary src zero)));
10261
10262  ins_cost(INSN_COST * 2);
10263  format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr"  %}
10264
10265  ins_encode %{
10266    __ csel(as_Register($dst$$reg),
10267            zr,
10268            as_Register($src$$reg),
10269            (Assembler::Condition)$cmp$$cmpcode);
10270  %}
10271
10272  ins_pipe(icond_reg);
10273%}
10274
10275instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
10276  match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
10277
10278  ins_cost(INSN_COST * 2);
10279  format %{ "csel $dst, $src, zr $cmp\t# signed, ptr"  %}
10280
10281  ins_encode %{
10282    __ csel(as_Register($dst$$reg),
10283            as_Register($src$$reg),
10284            zr,
10285            (Assembler::Condition)$cmp$$cmpcode);
10286  %}
10287
10288  ins_pipe(icond_reg);
10289%}
10290
10291instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{
10292  match(Set dst (CMoveP (Binary cmp cr) (Binary zero src)));
10293
10294  ins_cost(INSN_COST * 2);
10295  format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr"  %}
10296
10297  ins_encode %{
10298    __ csel(as_Register($dst$$reg),
10299            as_Register($src$$reg),
10300            zr,
10301            (Assembler::Condition)$cmp$$cmpcode);
10302  %}
10303
10304  ins_pipe(icond_reg);
10305%}
10306
10307instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
10308  match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
10309
10310  ins_cost(INSN_COST * 2);
10311  format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr"  %}
10312
10313  ins_encode %{
10314    __ cselw(as_Register($dst$$reg),
10315             as_Register($src2$$reg),
10316             as_Register($src1$$reg),
10317             (Assembler::Condition)$cmp$$cmpcode);
10318  %}
10319
10320  ins_pipe(icond_reg_reg);
10321%}
10322
10323instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{
10324  match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2)));
10325
10326  ins_cost(INSN_COST * 2);
10327  format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr"  %}
10328
10329  ins_encode %{
10330    __ cselw(as_Register($dst$$reg),
10331             as_Register($src2$$reg),
10332             as_Register($src1$$reg),
10333             (Assembler::Condition)$cmp$$cmpcode);
10334  %}
10335
10336  ins_pipe(icond_reg_reg);
10337%}
10338
10339// special cases where one arg is zero
10340
10341instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
10342  match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
10343
10344  ins_cost(INSN_COST * 2);
10345  format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr"  %}
10346
10347  ins_encode %{
10348    __ cselw(as_Register($dst$$reg),
10349             zr,
10350             as_Register($src$$reg),
10351             (Assembler::Condition)$cmp$$cmpcode);
10352  %}
10353
10354  ins_pipe(icond_reg);
10355%}
10356
10357instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{
10358  match(Set dst (CMoveN (Binary cmp cr) (Binary src zero)));
10359
10360  ins_cost(INSN_COST * 2);
10361  format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr"  %}
10362
10363  ins_encode %{
10364    __ cselw(as_Register($dst$$reg),
10365             zr,
10366             as_Register($src$$reg),
10367             (Assembler::Condition)$cmp$$cmpcode);
10368  %}
10369
10370  ins_pipe(icond_reg);
10371%}
10372
10373instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
10374  match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
10375
10376  ins_cost(INSN_COST * 2);
10377  format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr"  %}
10378
10379  ins_encode %{
10380    __ cselw(as_Register($dst$$reg),
10381             as_Register($src$$reg),
10382             zr,
10383             (Assembler::Condition)$cmp$$cmpcode);
10384  %}
10385
10386  ins_pipe(icond_reg);
10387%}
10388
10389instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{
10390  match(Set dst (CMoveN (Binary cmp cr) (Binary zero src)));
10391
10392  ins_cost(INSN_COST * 2);
10393  format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr"  %}
10394
10395  ins_encode %{
10396    __ cselw(as_Register($dst$$reg),
10397             as_Register($src$$reg),
10398             zr,
10399             (Assembler::Condition)$cmp$$cmpcode);
10400  %}
10401
10402  ins_pipe(icond_reg);
10403%}
10404
10405instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1,  vRegF src2)
10406%{
10407  match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
10408
10409  ins_cost(INSN_COST * 3);
10410
10411  format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
10412  ins_encode %{
10413    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
10414    __ fcsels(as_FloatRegister($dst$$reg),
10415              as_FloatRegister($src2$$reg),
10416              as_FloatRegister($src1$$reg),
10417              cond);
10418  %}
10419
10420  ins_pipe(fp_cond_reg_reg_s);
10421%}
10422
10423instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1,  vRegF src2)
10424%{
10425  match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2)));
10426
10427  ins_cost(INSN_COST * 3);
10428
10429  format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
10430  ins_encode %{
10431    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
10432    __ fcsels(as_FloatRegister($dst$$reg),
10433              as_FloatRegister($src2$$reg),
10434              as_FloatRegister($src1$$reg),
10435              cond);
10436  %}
10437
10438  ins_pipe(fp_cond_reg_reg_s);
10439%}
10440
10441instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1,  vRegD src2)
10442%{
10443  match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
10444
10445  ins_cost(INSN_COST * 3);
10446
10447  format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %}
10448  ins_encode %{
10449    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
10450    __ fcseld(as_FloatRegister($dst$$reg),
10451              as_FloatRegister($src2$$reg),
10452              as_FloatRegister($src1$$reg),
10453              cond);
10454  %}
10455
10456  ins_pipe(fp_cond_reg_reg_d);
10457%}
10458
10459instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1,  vRegD src2)
10460%{
10461  match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2)));
10462
10463  ins_cost(INSN_COST * 3);
10464
10465  format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %}
10466  ins_encode %{
10467    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
10468    __ fcseld(as_FloatRegister($dst$$reg),
10469              as_FloatRegister($src2$$reg),
10470              as_FloatRegister($src1$$reg),
10471              cond);
10472  %}
10473
10474  ins_pipe(fp_cond_reg_reg_d);
10475%}
10476
10477// ============================================================================
10478// Arithmetic Instructions
10479//
10480
10481// Integer Addition
10482
10483// TODO
10484// these currently employ operations which do not set CR and hence are
10485// not flagged as killing CR but we would like to isolate the cases
10486// where we want to set flags from those where we don't. need to work
10487// out how to do that.
10488
10489instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10490  match(Set dst (AddI src1 src2));
10491
10492  ins_cost(INSN_COST);
10493  format %{ "addw  $dst, $src1, $src2" %}
10494
10495  ins_encode %{
10496    __ addw(as_Register($dst$$reg),
10497            as_Register($src1$$reg),
10498            as_Register($src2$$reg));
10499  %}
10500
10501  ins_pipe(ialu_reg_reg);
10502%}
10503
10504instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
10505  match(Set dst (AddI src1 src2));
10506
10507  ins_cost(INSN_COST);
10508  format %{ "addw $dst, $src1, $src2" %}
10509
10510  // use opcode to indicate that this is an add not a sub
10511  opcode(0x0);
10512
10513  ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
10514
10515  ins_pipe(ialu_reg_imm);
10516%}
10517
10518instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{
10519  match(Set dst (AddI (ConvL2I src1) src2));
10520
10521  ins_cost(INSN_COST);
10522  format %{ "addw $dst, $src1, $src2" %}
10523
10524  // use opcode to indicate that this is an add not a sub
10525  opcode(0x0);
10526
10527  ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
10528
10529  ins_pipe(ialu_reg_imm);
10530%}
10531
10532// Pointer Addition
10533instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{
10534  match(Set dst (AddP src1 src2));
10535
10536  ins_cost(INSN_COST);
10537  format %{ "add $dst, $src1, $src2\t# ptr" %}
10538
10539  ins_encode %{
10540    __ add(as_Register($dst$$reg),
10541           as_Register($src1$$reg),
10542           as_Register($src2$$reg));
10543  %}
10544
10545  ins_pipe(ialu_reg_reg);
10546%}
10547
10548instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{
10549  match(Set dst (AddP src1 (ConvI2L src2)));
10550
10551  ins_cost(1.9 * INSN_COST);
10552  format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %}
10553
10554  ins_encode %{
10555    __ add(as_Register($dst$$reg),
10556           as_Register($src1$$reg),
10557           as_Register($src2$$reg), ext::sxtw);
10558  %}
10559
10560  ins_pipe(ialu_reg_reg);
10561%}
10562
10563instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{
10564  match(Set dst (AddP src1 (LShiftL src2 scale)));
10565
10566  ins_cost(1.9 * INSN_COST);
10567  format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %}
10568
10569  ins_encode %{
10570    __ lea(as_Register($dst$$reg),
10571           Address(as_Register($src1$$reg), as_Register($src2$$reg),
10572                   Address::lsl($scale$$constant)));
10573  %}
10574
10575  ins_pipe(ialu_reg_reg_shift);
10576%}
10577
10578instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{
10579  match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale)));
10580
10581  ins_cost(1.9 * INSN_COST);
10582  format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %}
10583
10584  ins_encode %{
10585    __ lea(as_Register($dst$$reg),
10586           Address(as_Register($src1$$reg), as_Register($src2$$reg),
10587                   Address::sxtw($scale$$constant)));
10588  %}
10589
10590  ins_pipe(ialu_reg_reg_shift);
10591%}
10592
10593instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{
10594  match(Set dst (LShiftL (ConvI2L src) scale));
10595
10596  ins_cost(INSN_COST);
10597  format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %}
10598
10599  ins_encode %{
10600    __ sbfiz(as_Register($dst$$reg),
10601          as_Register($src$$reg),
10602          $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63)));
10603  %}
10604
10605  ins_pipe(ialu_reg_shift);
10606%}
10607
10608// Pointer Immediate Addition
10609// n.b. this needs to be more expensive than using an indirect memory
10610// operand
10611instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{
10612  match(Set dst (AddP src1 src2));
10613
10614  ins_cost(INSN_COST);
10615  format %{ "add $dst, $src1, $src2\t# ptr" %}
10616
10617  // use opcode to indicate that this is an add not a sub
10618  opcode(0x0);
10619
10620  ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
10621
10622  ins_pipe(ialu_reg_imm);
10623%}
10624
10625// Long Addition
10626instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10627
10628  match(Set dst (AddL src1 src2));
10629
10630  ins_cost(INSN_COST);
10631  format %{ "add  $dst, $src1, $src2" %}
10632
10633  ins_encode %{
10634    __ add(as_Register($dst$$reg),
10635           as_Register($src1$$reg),
10636           as_Register($src2$$reg));
10637  %}
10638
10639  ins_pipe(ialu_reg_reg);
10640%}
10641
10642// No constant pool entries requiredLong Immediate Addition.
10643instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
10644  match(Set dst (AddL src1 src2));
10645
10646  ins_cost(INSN_COST);
10647  format %{ "add $dst, $src1, $src2" %}
10648
10649  // use opcode to indicate that this is an add not a sub
10650  opcode(0x0);
10651
10652  ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
10653
10654  ins_pipe(ialu_reg_imm);
10655%}
10656
10657// Integer Subtraction
10658instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10659  match(Set dst (SubI src1 src2));
10660
10661  ins_cost(INSN_COST);
10662  format %{ "subw  $dst, $src1, $src2" %}
10663
10664  ins_encode %{
10665    __ subw(as_Register($dst$$reg),
10666            as_Register($src1$$reg),
10667            as_Register($src2$$reg));
10668  %}
10669
10670  ins_pipe(ialu_reg_reg);
10671%}
10672
10673// Immediate Subtraction
10674instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{
10675  match(Set dst (SubI src1 src2));
10676
10677  ins_cost(INSN_COST);
10678  format %{ "subw $dst, $src1, $src2" %}
10679
10680  // use opcode to indicate that this is a sub not an add
10681  opcode(0x1);
10682
10683  ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2));
10684
10685  ins_pipe(ialu_reg_imm);
10686%}
10687
10688// Long Subtraction
10689instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10690
10691  match(Set dst (SubL src1 src2));
10692
10693  ins_cost(INSN_COST);
10694  format %{ "sub  $dst, $src1, $src2" %}
10695
10696  ins_encode %{
10697    __ sub(as_Register($dst$$reg),
10698           as_Register($src1$$reg),
10699           as_Register($src2$$reg));
10700  %}
10701
10702  ins_pipe(ialu_reg_reg);
10703%}
10704
10705// No constant pool entries requiredLong Immediate Subtraction.
10706instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{
10707  match(Set dst (SubL src1 src2));
10708
10709  ins_cost(INSN_COST);
10710  format %{ "sub$dst, $src1, $src2" %}
10711
10712  // use opcode to indicate that this is a sub not an add
10713  opcode(0x1);
10714
10715  ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) );
10716
10717  ins_pipe(ialu_reg_imm);
10718%}
10719
10720// Integer Negation (special case for sub)
10721
10722instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{
10723  match(Set dst (SubI zero src));
10724
10725  ins_cost(INSN_COST);
10726  format %{ "negw $dst, $src\t# int" %}
10727
10728  ins_encode %{
10729    __ negw(as_Register($dst$$reg),
10730            as_Register($src$$reg));
10731  %}
10732
10733  ins_pipe(ialu_reg);
10734%}
10735
10736// Long Negation
10737
10738instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{
10739  match(Set dst (SubL zero src));
10740
10741  ins_cost(INSN_COST);
10742  format %{ "neg $dst, $src\t# long" %}
10743
10744  ins_encode %{
10745    __ neg(as_Register($dst$$reg),
10746           as_Register($src$$reg));
10747  %}
10748
10749  ins_pipe(ialu_reg);
10750%}
10751
10752// Integer Multiply
10753
10754instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10755  match(Set dst (MulI src1 src2));
10756
10757  ins_cost(INSN_COST * 3);
10758  format %{ "mulw  $dst, $src1, $src2" %}
10759
10760  ins_encode %{
10761    __ mulw(as_Register($dst$$reg),
10762            as_Register($src1$$reg),
10763            as_Register($src2$$reg));
10764  %}
10765
10766  ins_pipe(imul_reg_reg);
10767%}
10768
10769instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10770  match(Set dst (MulL (ConvI2L src1) (ConvI2L src2)));
10771
10772  ins_cost(INSN_COST * 3);
10773  format %{ "smull  $dst, $src1, $src2" %}
10774
10775  ins_encode %{
10776    __ smull(as_Register($dst$$reg),
10777             as_Register($src1$$reg),
10778             as_Register($src2$$reg));
10779  %}
10780
10781  ins_pipe(imul_reg_reg);
10782%}
10783
10784// Long Multiply
10785
10786instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
10787  match(Set dst (MulL src1 src2));
10788
10789  ins_cost(INSN_COST * 5);
10790  format %{ "mul  $dst, $src1, $src2" %}
10791
10792  ins_encode %{
10793    __ mul(as_Register($dst$$reg),
10794           as_Register($src1$$reg),
10795           as_Register($src2$$reg));
10796  %}
10797
10798  ins_pipe(lmul_reg_reg);
10799%}
10800
10801instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr)
10802%{
10803  match(Set dst (MulHiL src1 src2));
10804
10805  ins_cost(INSN_COST * 7);
10806  format %{ "smulh   $dst, $src1, $src2, \t# mulhi" %}
10807
10808  ins_encode %{
10809    __ smulh(as_Register($dst$$reg),
10810             as_Register($src1$$reg),
10811             as_Register($src2$$reg));
10812  %}
10813
10814  ins_pipe(lmul_reg_reg);
10815%}
10816
10817// Combined Integer Multiply & Add/Sub
10818
10819instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
10820  match(Set dst (AddI src3 (MulI src1 src2)));
10821
10822  ins_cost(INSN_COST * 3);
10823  format %{ "madd  $dst, $src1, $src2, $src3" %}
10824
10825  ins_encode %{
10826    __ maddw(as_Register($dst$$reg),
10827             as_Register($src1$$reg),
10828             as_Register($src2$$reg),
10829             as_Register($src3$$reg));
10830  %}
10831
10832  ins_pipe(imac_reg_reg);
10833%}
10834
10835instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{
10836  match(Set dst (SubI src3 (MulI src1 src2)));
10837
10838  ins_cost(INSN_COST * 3);
10839  format %{ "msub  $dst, $src1, $src2, $src3" %}
10840
10841  ins_encode %{
10842    __ msubw(as_Register($dst$$reg),
10843             as_Register($src1$$reg),
10844             as_Register($src2$$reg),
10845             as_Register($src3$$reg));
10846  %}
10847
10848  ins_pipe(imac_reg_reg);
10849%}
10850
10851// Combined Integer Multiply & Neg
10852
10853instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{
10854  match(Set dst (MulI (SubI zero src1) src2));
10855  match(Set dst (MulI src1 (SubI zero src2)));
10856
10857  ins_cost(INSN_COST * 3);
10858  format %{ "mneg  $dst, $src1, $src2" %}
10859
10860  ins_encode %{
10861    __ mnegw(as_Register($dst$$reg),
10862             as_Register($src1$$reg),
10863             as_Register($src2$$reg));
10864  %}
10865
10866  ins_pipe(imac_reg_reg);
10867%}
10868
10869// Combined Long Multiply & Add/Sub
10870
10871instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
10872  match(Set dst (AddL src3 (MulL src1 src2)));
10873
10874  ins_cost(INSN_COST * 5);
10875  format %{ "madd  $dst, $src1, $src2, $src3" %}
10876
10877  ins_encode %{
10878    __ madd(as_Register($dst$$reg),
10879            as_Register($src1$$reg),
10880            as_Register($src2$$reg),
10881            as_Register($src3$$reg));
10882  %}
10883
10884  ins_pipe(lmac_reg_reg);
10885%}
10886
10887instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{
10888  match(Set dst (SubL src3 (MulL src1 src2)));
10889
10890  ins_cost(INSN_COST * 5);
10891  format %{ "msub  $dst, $src1, $src2, $src3" %}
10892
10893  ins_encode %{
10894    __ msub(as_Register($dst$$reg),
10895            as_Register($src1$$reg),
10896            as_Register($src2$$reg),
10897            as_Register($src3$$reg));
10898  %}
10899
10900  ins_pipe(lmac_reg_reg);
10901%}
10902
10903// Combined Long Multiply & Neg
10904
10905instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{
10906  match(Set dst (MulL (SubL zero src1) src2));
10907  match(Set dst (MulL src1 (SubL zero src2)));
10908
10909  ins_cost(INSN_COST * 5);
10910  format %{ "mneg  $dst, $src1, $src2" %}
10911
10912  ins_encode %{
10913    __ mneg(as_Register($dst$$reg),
10914            as_Register($src1$$reg),
10915            as_Register($src2$$reg));
10916  %}
10917
10918  ins_pipe(lmac_reg_reg);
10919%}
10920
10921// Combine Integer Signed Multiply & Add/Sub/Neg Long
10922
10923instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{
10924  match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2))));
10925
10926  ins_cost(INSN_COST * 3);
10927  format %{ "smaddl  $dst, $src1, $src2, $src3" %}
10928
10929  ins_encode %{
10930    __ smaddl(as_Register($dst$$reg),
10931              as_Register($src1$$reg),
10932              as_Register($src2$$reg),
10933              as_Register($src3$$reg));
10934  %}
10935
10936  ins_pipe(imac_reg_reg);
10937%}
10938
10939instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{
10940  match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2))));
10941
10942  ins_cost(INSN_COST * 3);
10943  format %{ "smsubl  $dst, $src1, $src2, $src3" %}
10944
10945  ins_encode %{
10946    __ smsubl(as_Register($dst$$reg),
10947              as_Register($src1$$reg),
10948              as_Register($src2$$reg),
10949              as_Register($src3$$reg));
10950  %}
10951
10952  ins_pipe(imac_reg_reg);
10953%}
10954
10955instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{
10956  match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2)));
10957  match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2))));
10958
10959  ins_cost(INSN_COST * 3);
10960  format %{ "smnegl  $dst, $src1, $src2" %}
10961
10962  ins_encode %{
10963    __ smnegl(as_Register($dst$$reg),
10964              as_Register($src1$$reg),
10965              as_Register($src2$$reg));
10966  %}
10967
10968  ins_pipe(imac_reg_reg);
10969%}
10970
10971// Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4)
10972
10973instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{
10974  match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4)));
10975
10976  ins_cost(INSN_COST * 5);
10977  format %{ "mulw  rscratch1, $src1, $src2\n\t"
10978            "maddw $dst, $src3, $src4, rscratch1" %}
10979
10980  ins_encode %{
10981    __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg));
10982    __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %}
10983
10984  ins_pipe(imac_reg_reg);
10985%}
10986
10987// Integer Divide
10988
10989instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
10990  match(Set dst (DivI src1 src2));
10991
10992  ins_cost(INSN_COST * 19);
10993  format %{ "sdivw  $dst, $src1, $src2" %}
10994
10995  ins_encode(aarch64_enc_divw(dst, src1, src2));
10996  ins_pipe(idiv_reg_reg);
10997%}
10998
10999// Long Divide
11000
11001instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
11002  match(Set dst (DivL src1 src2));
11003
11004  ins_cost(INSN_COST * 35);
11005  format %{ "sdiv   $dst, $src1, $src2" %}
11006
11007  ins_encode(aarch64_enc_div(dst, src1, src2));
11008  ins_pipe(ldiv_reg_reg);
11009%}
11010
11011// Integer Remainder
11012
11013instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
11014  match(Set dst (ModI src1 src2));
11015
11016  ins_cost(INSN_COST * 22);
11017  format %{ "sdivw  rscratch1, $src1, $src2\n\t"
11018            "msubw($dst, rscratch1, $src2, $src1" %}
11019
11020  ins_encode(aarch64_enc_modw(dst, src1, src2));
11021  ins_pipe(idiv_reg_reg);
11022%}
11023
11024// Long Remainder
11025
11026instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
11027  match(Set dst (ModL src1 src2));
11028
11029  ins_cost(INSN_COST * 38);
11030  format %{ "sdiv   rscratch1, $src1, $src2\n"
11031            "msub($dst, rscratch1, $src2, $src1" %}
11032
11033  ins_encode(aarch64_enc_mod(dst, src1, src2));
11034  ins_pipe(ldiv_reg_reg);
11035%}
11036
11037// Integer Shifts
11038
11039// Shift Left Register
11040instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
11041  match(Set dst (LShiftI src1 src2));
11042
11043  ins_cost(INSN_COST * 2);
11044  format %{ "lslvw  $dst, $src1, $src2" %}
11045
11046  ins_encode %{
11047    __ lslvw(as_Register($dst$$reg),
11048             as_Register($src1$$reg),
11049             as_Register($src2$$reg));
11050  %}
11051
11052  ins_pipe(ialu_reg_reg_vshift);
11053%}
11054
11055// Shift Left Immediate
11056instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
11057  match(Set dst (LShiftI src1 src2));
11058
11059  ins_cost(INSN_COST);
11060  format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %}
11061
11062  ins_encode %{
11063    __ lslw(as_Register($dst$$reg),
11064            as_Register($src1$$reg),
11065            $src2$$constant & 0x1f);
11066  %}
11067
11068  ins_pipe(ialu_reg_shift);
11069%}
11070
11071// Shift Right Logical Register
11072instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
11073  match(Set dst (URShiftI src1 src2));
11074
11075  ins_cost(INSN_COST * 2);
11076  format %{ "lsrvw  $dst, $src1, $src2" %}
11077
11078  ins_encode %{
11079    __ lsrvw(as_Register($dst$$reg),
11080             as_Register($src1$$reg),
11081             as_Register($src2$$reg));
11082  %}
11083
11084  ins_pipe(ialu_reg_reg_vshift);
11085%}
11086
11087// Shift Right Logical Immediate
11088instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
11089  match(Set dst (URShiftI src1 src2));
11090
11091  ins_cost(INSN_COST);
11092  format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %}
11093
11094  ins_encode %{
11095    __ lsrw(as_Register($dst$$reg),
11096            as_Register($src1$$reg),
11097            $src2$$constant & 0x1f);
11098  %}
11099
11100  ins_pipe(ialu_reg_shift);
11101%}
11102
11103// Shift Right Arithmetic Register
11104instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
11105  match(Set dst (RShiftI src1 src2));
11106
11107  ins_cost(INSN_COST * 2);
11108  format %{ "asrvw  $dst, $src1, $src2" %}
11109
11110  ins_encode %{
11111    __ asrvw(as_Register($dst$$reg),
11112             as_Register($src1$$reg),
11113             as_Register($src2$$reg));
11114  %}
11115
11116  ins_pipe(ialu_reg_reg_vshift);
11117%}
11118
11119// Shift Right Arithmetic Immediate
11120instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{
11121  match(Set dst (RShiftI src1 src2));
11122
11123  ins_cost(INSN_COST);
11124  format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %}
11125
11126  ins_encode %{
11127    __ asrw(as_Register($dst$$reg),
11128            as_Register($src1$$reg),
11129            $src2$$constant & 0x1f);
11130  %}
11131
11132  ins_pipe(ialu_reg_shift);
11133%}
11134
11135// Combined Int Mask and Right Shift (using UBFM)
11136// TODO
11137
11138// Long Shifts
11139
11140// Shift Left Register
11141instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
11142  match(Set dst (LShiftL src1 src2));
11143
11144  ins_cost(INSN_COST * 2);
11145  format %{ "lslv  $dst, $src1, $src2" %}
11146
11147  ins_encode %{
11148    __ lslv(as_Register($dst$$reg),
11149            as_Register($src1$$reg),
11150            as_Register($src2$$reg));
11151  %}
11152
11153  ins_pipe(ialu_reg_reg_vshift);
11154%}
11155
11156// Shift Left Immediate
11157instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
11158  match(Set dst (LShiftL src1 src2));
11159
11160  ins_cost(INSN_COST);
11161  format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %}
11162
11163  ins_encode %{
11164    __ lsl(as_Register($dst$$reg),
11165            as_Register($src1$$reg),
11166            $src2$$constant & 0x3f);
11167  %}
11168
11169  ins_pipe(ialu_reg_shift);
11170%}
11171
11172// Shift Right Logical Register
11173instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
11174  match(Set dst (URShiftL src1 src2));
11175
11176  ins_cost(INSN_COST * 2);
11177  format %{ "lsrv  $dst, $src1, $src2" %}
11178
11179  ins_encode %{
11180    __ lsrv(as_Register($dst$$reg),
11181            as_Register($src1$$reg),
11182            as_Register($src2$$reg));
11183  %}
11184
11185  ins_pipe(ialu_reg_reg_vshift);
11186%}
11187
11188// Shift Right Logical Immediate
11189instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
11190  match(Set dst (URShiftL src1 src2));
11191
11192  ins_cost(INSN_COST);
11193  format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %}
11194
11195  ins_encode %{
11196    __ lsr(as_Register($dst$$reg),
11197           as_Register($src1$$reg),
11198           $src2$$constant & 0x3f);
11199  %}
11200
11201  ins_pipe(ialu_reg_shift);
11202%}
11203
11204// A special-case pattern for card table stores.
11205instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{
11206  match(Set dst (URShiftL (CastP2X src1) src2));
11207
11208  ins_cost(INSN_COST);
11209  format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %}
11210
11211  ins_encode %{
11212    __ lsr(as_Register($dst$$reg),
11213           as_Register($src1$$reg),
11214           $src2$$constant & 0x3f);
11215  %}
11216
11217  ins_pipe(ialu_reg_shift);
11218%}
11219
11220// Shift Right Arithmetic Register
11221instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{
11222  match(Set dst (RShiftL src1 src2));
11223
11224  ins_cost(INSN_COST * 2);
11225  format %{ "asrv  $dst, $src1, $src2" %}
11226
11227  ins_encode %{
11228    __ asrv(as_Register($dst$$reg),
11229            as_Register($src1$$reg),
11230            as_Register($src2$$reg));
11231  %}
11232
11233  ins_pipe(ialu_reg_reg_vshift);
11234%}
11235
11236// Shift Right Arithmetic Immediate
11237instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{
11238  match(Set dst (RShiftL src1 src2));
11239
11240  ins_cost(INSN_COST);
11241  format %{ "asr $dst, $src1, ($src2 & 0x3f)" %}
11242
11243  ins_encode %{
11244    __ asr(as_Register($dst$$reg),
11245           as_Register($src1$$reg),
11246           $src2$$constant & 0x3f);
11247  %}
11248
11249  ins_pipe(ialu_reg_shift);
11250%}
11251
11252// BEGIN This section of the file is automatically generated. Do not edit --------------
11253// This section is generated from aarch64_ad.m4
11254
11255
11256// This pattern is automatically generated from aarch64_ad.m4
11257// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11258instruct regL_not_reg(iRegLNoSp dst,
11259                         iRegL src1, immL_M1 m1,
11260                         rFlagsReg cr) %{
11261  match(Set dst (XorL src1 m1));
11262  ins_cost(INSN_COST);
11263  format %{ "eon  $dst, $src1, zr" %}
11264
11265  ins_encode %{
11266    __ eon(as_Register($dst$$reg),
11267              as_Register($src1$$reg),
11268              zr,
11269              Assembler::LSL, 0);
11270  %}
11271
11272  ins_pipe(ialu_reg);
11273%}
11274
11275// This pattern is automatically generated from aarch64_ad.m4
11276// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11277instruct regI_not_reg(iRegINoSp dst,
11278                         iRegIorL2I src1, immI_M1 m1,
11279                         rFlagsReg cr) %{
11280  match(Set dst (XorI src1 m1));
11281  ins_cost(INSN_COST);
11282  format %{ "eonw  $dst, $src1, zr" %}
11283
11284  ins_encode %{
11285    __ eonw(as_Register($dst$$reg),
11286              as_Register($src1$$reg),
11287              zr,
11288              Assembler::LSL, 0);
11289  %}
11290
11291  ins_pipe(ialu_reg);
11292%}
11293
11294// This pattern is automatically generated from aarch64_ad.m4
11295// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11296instruct AndI_reg_not_reg(iRegINoSp dst,
11297                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{
11298  match(Set dst (AndI src1 (XorI src2 m1)));
11299  ins_cost(INSN_COST);
11300  format %{ "bicw  $dst, $src1, $src2" %}
11301
11302  ins_encode %{
11303    __ bicw(as_Register($dst$$reg),
11304              as_Register($src1$$reg),
11305              as_Register($src2$$reg),
11306              Assembler::LSL, 0);
11307  %}
11308
11309  ins_pipe(ialu_reg_reg);
11310%}
11311
11312// This pattern is automatically generated from aarch64_ad.m4
11313// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11314instruct AndL_reg_not_reg(iRegLNoSp dst,
11315                         iRegL src1, iRegL src2, immL_M1 m1) %{
11316  match(Set dst (AndL src1 (XorL src2 m1)));
11317  ins_cost(INSN_COST);
11318  format %{ "bic  $dst, $src1, $src2" %}
11319
11320  ins_encode %{
11321    __ bic(as_Register($dst$$reg),
11322              as_Register($src1$$reg),
11323              as_Register($src2$$reg),
11324              Assembler::LSL, 0);
11325  %}
11326
11327  ins_pipe(ialu_reg_reg);
11328%}
11329
11330// This pattern is automatically generated from aarch64_ad.m4
11331// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11332instruct OrI_reg_not_reg(iRegINoSp dst,
11333                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{
11334  match(Set dst (OrI src1 (XorI src2 m1)));
11335  ins_cost(INSN_COST);
11336  format %{ "ornw  $dst, $src1, $src2" %}
11337
11338  ins_encode %{
11339    __ ornw(as_Register($dst$$reg),
11340              as_Register($src1$$reg),
11341              as_Register($src2$$reg),
11342              Assembler::LSL, 0);
11343  %}
11344
11345  ins_pipe(ialu_reg_reg);
11346%}
11347
11348// This pattern is automatically generated from aarch64_ad.m4
11349// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11350instruct OrL_reg_not_reg(iRegLNoSp dst,
11351                         iRegL src1, iRegL src2, immL_M1 m1) %{
11352  match(Set dst (OrL src1 (XorL src2 m1)));
11353  ins_cost(INSN_COST);
11354  format %{ "orn  $dst, $src1, $src2" %}
11355
11356  ins_encode %{
11357    __ orn(as_Register($dst$$reg),
11358              as_Register($src1$$reg),
11359              as_Register($src2$$reg),
11360              Assembler::LSL, 0);
11361  %}
11362
11363  ins_pipe(ialu_reg_reg);
11364%}
11365
11366// This pattern is automatically generated from aarch64_ad.m4
11367// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11368instruct XorI_reg_not_reg(iRegINoSp dst,
11369                         iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{
11370  match(Set dst (XorI m1 (XorI src2 src1)));
11371  ins_cost(INSN_COST);
11372  format %{ "eonw  $dst, $src1, $src2" %}
11373
11374  ins_encode %{
11375    __ eonw(as_Register($dst$$reg),
11376              as_Register($src1$$reg),
11377              as_Register($src2$$reg),
11378              Assembler::LSL, 0);
11379  %}
11380
11381  ins_pipe(ialu_reg_reg);
11382%}
11383
11384// This pattern is automatically generated from aarch64_ad.m4
11385// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11386instruct XorL_reg_not_reg(iRegLNoSp dst,
11387                         iRegL src1, iRegL src2, immL_M1 m1) %{
11388  match(Set dst (XorL m1 (XorL src2 src1)));
11389  ins_cost(INSN_COST);
11390  format %{ "eon  $dst, $src1, $src2" %}
11391
11392  ins_encode %{
11393    __ eon(as_Register($dst$$reg),
11394              as_Register($src1$$reg),
11395              as_Register($src2$$reg),
11396              Assembler::LSL, 0);
11397  %}
11398
11399  ins_pipe(ialu_reg_reg);
11400%}
11401
11402// This pattern is automatically generated from aarch64_ad.m4
11403// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11404// val & (-1 ^ (val >>> shift)) ==> bicw
11405instruct AndI_reg_URShift_not_reg(iRegINoSp dst,
11406                         iRegIorL2I src1, iRegIorL2I src2,
11407                         immI src3, immI_M1 src4) %{
11408  match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4)));
11409  ins_cost(1.9 * INSN_COST);
11410  format %{ "bicw  $dst, $src1, $src2, LSR $src3" %}
11411
11412  ins_encode %{
11413    __ bicw(as_Register($dst$$reg),
11414              as_Register($src1$$reg),
11415              as_Register($src2$$reg),
11416              Assembler::LSR,
11417              $src3$$constant & 0x1f);
11418  %}
11419
11420  ins_pipe(ialu_reg_reg_shift);
11421%}
11422
11423// This pattern is automatically generated from aarch64_ad.m4
11424// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11425// val & (-1 ^ (val >>> shift)) ==> bic
11426instruct AndL_reg_URShift_not_reg(iRegLNoSp dst,
11427                         iRegL src1, iRegL src2,
11428                         immI src3, immL_M1 src4) %{
11429  match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4)));
11430  ins_cost(1.9 * INSN_COST);
11431  format %{ "bic  $dst, $src1, $src2, LSR $src3" %}
11432
11433  ins_encode %{
11434    __ bic(as_Register($dst$$reg),
11435              as_Register($src1$$reg),
11436              as_Register($src2$$reg),
11437              Assembler::LSR,
11438              $src3$$constant & 0x3f);
11439  %}
11440
11441  ins_pipe(ialu_reg_reg_shift);
11442%}
11443
11444// This pattern is automatically generated from aarch64_ad.m4
11445// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11446// val & (-1 ^ (val >> shift)) ==> bicw
11447instruct AndI_reg_RShift_not_reg(iRegINoSp dst,
11448                         iRegIorL2I src1, iRegIorL2I src2,
11449                         immI src3, immI_M1 src4) %{
11450  match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4)));
11451  ins_cost(1.9 * INSN_COST);
11452  format %{ "bicw  $dst, $src1, $src2, ASR $src3" %}
11453
11454  ins_encode %{
11455    __ bicw(as_Register($dst$$reg),
11456              as_Register($src1$$reg),
11457              as_Register($src2$$reg),
11458              Assembler::ASR,
11459              $src3$$constant & 0x1f);
11460  %}
11461
11462  ins_pipe(ialu_reg_reg_shift);
11463%}
11464
11465// This pattern is automatically generated from aarch64_ad.m4
11466// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11467// val & (-1 ^ (val >> shift)) ==> bic
11468instruct AndL_reg_RShift_not_reg(iRegLNoSp dst,
11469                         iRegL src1, iRegL src2,
11470                         immI src3, immL_M1 src4) %{
11471  match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4)));
11472  ins_cost(1.9 * INSN_COST);
11473  format %{ "bic  $dst, $src1, $src2, ASR $src3" %}
11474
11475  ins_encode %{
11476    __ bic(as_Register($dst$$reg),
11477              as_Register($src1$$reg),
11478              as_Register($src2$$reg),
11479              Assembler::ASR,
11480              $src3$$constant & 0x3f);
11481  %}
11482
11483  ins_pipe(ialu_reg_reg_shift);
11484%}
11485
11486// This pattern is automatically generated from aarch64_ad.m4
11487// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11488// val & (-1 ^ (val ror shift)) ==> bicw
11489instruct AndI_reg_RotateRight_not_reg(iRegINoSp dst,
11490                         iRegIorL2I src1, iRegIorL2I src2,
11491                         immI src3, immI_M1 src4) %{
11492  match(Set dst (AndI src1 (XorI(RotateRight src2 src3) src4)));
11493  ins_cost(1.9 * INSN_COST);
11494  format %{ "bicw  $dst, $src1, $src2, ROR $src3" %}
11495
11496  ins_encode %{
11497    __ bicw(as_Register($dst$$reg),
11498              as_Register($src1$$reg),
11499              as_Register($src2$$reg),
11500              Assembler::ROR,
11501              $src3$$constant & 0x1f);
11502  %}
11503
11504  ins_pipe(ialu_reg_reg_shift);
11505%}
11506
11507// This pattern is automatically generated from aarch64_ad.m4
11508// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11509// val & (-1 ^ (val ror shift)) ==> bic
11510instruct AndL_reg_RotateRight_not_reg(iRegLNoSp dst,
11511                         iRegL src1, iRegL src2,
11512                         immI src3, immL_M1 src4) %{
11513  match(Set dst (AndL src1 (XorL(RotateRight src2 src3) src4)));
11514  ins_cost(1.9 * INSN_COST);
11515  format %{ "bic  $dst, $src1, $src2, ROR $src3" %}
11516
11517  ins_encode %{
11518    __ bic(as_Register($dst$$reg),
11519              as_Register($src1$$reg),
11520              as_Register($src2$$reg),
11521              Assembler::ROR,
11522              $src3$$constant & 0x3f);
11523  %}
11524
11525  ins_pipe(ialu_reg_reg_shift);
11526%}
11527
11528// This pattern is automatically generated from aarch64_ad.m4
11529// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11530// val & (-1 ^ (val << shift)) ==> bicw
11531instruct AndI_reg_LShift_not_reg(iRegINoSp dst,
11532                         iRegIorL2I src1, iRegIorL2I src2,
11533                         immI src3, immI_M1 src4) %{
11534  match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4)));
11535  ins_cost(1.9 * INSN_COST);
11536  format %{ "bicw  $dst, $src1, $src2, LSL $src3" %}
11537
11538  ins_encode %{
11539    __ bicw(as_Register($dst$$reg),
11540              as_Register($src1$$reg),
11541              as_Register($src2$$reg),
11542              Assembler::LSL,
11543              $src3$$constant & 0x1f);
11544  %}
11545
11546  ins_pipe(ialu_reg_reg_shift);
11547%}
11548
11549// This pattern is automatically generated from aarch64_ad.m4
11550// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11551// val & (-1 ^ (val << shift)) ==> bic
11552instruct AndL_reg_LShift_not_reg(iRegLNoSp dst,
11553                         iRegL src1, iRegL src2,
11554                         immI src3, immL_M1 src4) %{
11555  match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4)));
11556  ins_cost(1.9 * INSN_COST);
11557  format %{ "bic  $dst, $src1, $src2, LSL $src3" %}
11558
11559  ins_encode %{
11560    __ bic(as_Register($dst$$reg),
11561              as_Register($src1$$reg),
11562              as_Register($src2$$reg),
11563              Assembler::LSL,
11564              $src3$$constant & 0x3f);
11565  %}
11566
11567  ins_pipe(ialu_reg_reg_shift);
11568%}
11569
11570// This pattern is automatically generated from aarch64_ad.m4
11571// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11572// val ^ (-1 ^ (val >>> shift)) ==> eonw
11573instruct XorI_reg_URShift_not_reg(iRegINoSp dst,
11574                         iRegIorL2I src1, iRegIorL2I src2,
11575                         immI src3, immI_M1 src4) %{
11576  match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1)));
11577  ins_cost(1.9 * INSN_COST);
11578  format %{ "eonw  $dst, $src1, $src2, LSR $src3" %}
11579
11580  ins_encode %{
11581    __ eonw(as_Register($dst$$reg),
11582              as_Register($src1$$reg),
11583              as_Register($src2$$reg),
11584              Assembler::LSR,
11585              $src3$$constant & 0x1f);
11586  %}
11587
11588  ins_pipe(ialu_reg_reg_shift);
11589%}
11590
11591// This pattern is automatically generated from aarch64_ad.m4
11592// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11593// val ^ (-1 ^ (val >>> shift)) ==> eon
11594instruct XorL_reg_URShift_not_reg(iRegLNoSp dst,
11595                         iRegL src1, iRegL src2,
11596                         immI src3, immL_M1 src4) %{
11597  match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1)));
11598  ins_cost(1.9 * INSN_COST);
11599  format %{ "eon  $dst, $src1, $src2, LSR $src3" %}
11600
11601  ins_encode %{
11602    __ eon(as_Register($dst$$reg),
11603              as_Register($src1$$reg),
11604              as_Register($src2$$reg),
11605              Assembler::LSR,
11606              $src3$$constant & 0x3f);
11607  %}
11608
11609  ins_pipe(ialu_reg_reg_shift);
11610%}
11611
11612// This pattern is automatically generated from aarch64_ad.m4
11613// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11614// val ^ (-1 ^ (val >> shift)) ==> eonw
11615instruct XorI_reg_RShift_not_reg(iRegINoSp dst,
11616                         iRegIorL2I src1, iRegIorL2I src2,
11617                         immI src3, immI_M1 src4) %{
11618  match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1)));
11619  ins_cost(1.9 * INSN_COST);
11620  format %{ "eonw  $dst, $src1, $src2, ASR $src3" %}
11621
11622  ins_encode %{
11623    __ eonw(as_Register($dst$$reg),
11624              as_Register($src1$$reg),
11625              as_Register($src2$$reg),
11626              Assembler::ASR,
11627              $src3$$constant & 0x1f);
11628  %}
11629
11630  ins_pipe(ialu_reg_reg_shift);
11631%}
11632
11633// This pattern is automatically generated from aarch64_ad.m4
11634// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11635// val ^ (-1 ^ (val >> shift)) ==> eon
11636instruct XorL_reg_RShift_not_reg(iRegLNoSp dst,
11637                         iRegL src1, iRegL src2,
11638                         immI src3, immL_M1 src4) %{
11639  match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1)));
11640  ins_cost(1.9 * INSN_COST);
11641  format %{ "eon  $dst, $src1, $src2, ASR $src3" %}
11642
11643  ins_encode %{
11644    __ eon(as_Register($dst$$reg),
11645              as_Register($src1$$reg),
11646              as_Register($src2$$reg),
11647              Assembler::ASR,
11648              $src3$$constant & 0x3f);
11649  %}
11650
11651  ins_pipe(ialu_reg_reg_shift);
11652%}
11653
11654// This pattern is automatically generated from aarch64_ad.m4
11655// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11656// val ^ (-1 ^ (val ror shift)) ==> eonw
11657instruct XorI_reg_RotateRight_not_reg(iRegINoSp dst,
11658                         iRegIorL2I src1, iRegIorL2I src2,
11659                         immI src3, immI_M1 src4) %{
11660  match(Set dst (XorI src4 (XorI(RotateRight src2 src3) src1)));
11661  ins_cost(1.9 * INSN_COST);
11662  format %{ "eonw  $dst, $src1, $src2, ROR $src3" %}
11663
11664  ins_encode %{
11665    __ eonw(as_Register($dst$$reg),
11666              as_Register($src1$$reg),
11667              as_Register($src2$$reg),
11668              Assembler::ROR,
11669              $src3$$constant & 0x1f);
11670  %}
11671
11672  ins_pipe(ialu_reg_reg_shift);
11673%}
11674
11675// This pattern is automatically generated from aarch64_ad.m4
11676// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11677// val ^ (-1 ^ (val ror shift)) ==> eon
11678instruct XorL_reg_RotateRight_not_reg(iRegLNoSp dst,
11679                         iRegL src1, iRegL src2,
11680                         immI src3, immL_M1 src4) %{
11681  match(Set dst (XorL src4 (XorL(RotateRight src2 src3) src1)));
11682  ins_cost(1.9 * INSN_COST);
11683  format %{ "eon  $dst, $src1, $src2, ROR $src3" %}
11684
11685  ins_encode %{
11686    __ eon(as_Register($dst$$reg),
11687              as_Register($src1$$reg),
11688              as_Register($src2$$reg),
11689              Assembler::ROR,
11690              $src3$$constant & 0x3f);
11691  %}
11692
11693  ins_pipe(ialu_reg_reg_shift);
11694%}
11695
11696// This pattern is automatically generated from aarch64_ad.m4
11697// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11698// val ^ (-1 ^ (val << shift)) ==> eonw
11699instruct XorI_reg_LShift_not_reg(iRegINoSp dst,
11700                         iRegIorL2I src1, iRegIorL2I src2,
11701                         immI src3, immI_M1 src4) %{
11702  match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1)));
11703  ins_cost(1.9 * INSN_COST);
11704  format %{ "eonw  $dst, $src1, $src2, LSL $src3" %}
11705
11706  ins_encode %{
11707    __ eonw(as_Register($dst$$reg),
11708              as_Register($src1$$reg),
11709              as_Register($src2$$reg),
11710              Assembler::LSL,
11711              $src3$$constant & 0x1f);
11712  %}
11713
11714  ins_pipe(ialu_reg_reg_shift);
11715%}
11716
11717// This pattern is automatically generated from aarch64_ad.m4
11718// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11719// val ^ (-1 ^ (val << shift)) ==> eon
11720instruct XorL_reg_LShift_not_reg(iRegLNoSp dst,
11721                         iRegL src1, iRegL src2,
11722                         immI src3, immL_M1 src4) %{
11723  match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1)));
11724  ins_cost(1.9 * INSN_COST);
11725  format %{ "eon  $dst, $src1, $src2, LSL $src3" %}
11726
11727  ins_encode %{
11728    __ eon(as_Register($dst$$reg),
11729              as_Register($src1$$reg),
11730              as_Register($src2$$reg),
11731              Assembler::LSL,
11732              $src3$$constant & 0x3f);
11733  %}
11734
11735  ins_pipe(ialu_reg_reg_shift);
11736%}
11737
11738// This pattern is automatically generated from aarch64_ad.m4
11739// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11740// val | (-1 ^ (val >>> shift)) ==> ornw
11741instruct OrI_reg_URShift_not_reg(iRegINoSp dst,
11742                         iRegIorL2I src1, iRegIorL2I src2,
11743                         immI src3, immI_M1 src4) %{
11744  match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4)));
11745  ins_cost(1.9 * INSN_COST);
11746  format %{ "ornw  $dst, $src1, $src2, LSR $src3" %}
11747
11748  ins_encode %{
11749    __ ornw(as_Register($dst$$reg),
11750              as_Register($src1$$reg),
11751              as_Register($src2$$reg),
11752              Assembler::LSR,
11753              $src3$$constant & 0x1f);
11754  %}
11755
11756  ins_pipe(ialu_reg_reg_shift);
11757%}
11758
11759// This pattern is automatically generated from aarch64_ad.m4
11760// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11761// val | (-1 ^ (val >>> shift)) ==> orn
11762instruct OrL_reg_URShift_not_reg(iRegLNoSp dst,
11763                         iRegL src1, iRegL src2,
11764                         immI src3, immL_M1 src4) %{
11765  match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4)));
11766  ins_cost(1.9 * INSN_COST);
11767  format %{ "orn  $dst, $src1, $src2, LSR $src3" %}
11768
11769  ins_encode %{
11770    __ orn(as_Register($dst$$reg),
11771              as_Register($src1$$reg),
11772              as_Register($src2$$reg),
11773              Assembler::LSR,
11774              $src3$$constant & 0x3f);
11775  %}
11776
11777  ins_pipe(ialu_reg_reg_shift);
11778%}
11779
11780// This pattern is automatically generated from aarch64_ad.m4
11781// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11782// val | (-1 ^ (val >> shift)) ==> ornw
11783instruct OrI_reg_RShift_not_reg(iRegINoSp dst,
11784                         iRegIorL2I src1, iRegIorL2I src2,
11785                         immI src3, immI_M1 src4) %{
11786  match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4)));
11787  ins_cost(1.9 * INSN_COST);
11788  format %{ "ornw  $dst, $src1, $src2, ASR $src3" %}
11789
11790  ins_encode %{
11791    __ ornw(as_Register($dst$$reg),
11792              as_Register($src1$$reg),
11793              as_Register($src2$$reg),
11794              Assembler::ASR,
11795              $src3$$constant & 0x1f);
11796  %}
11797
11798  ins_pipe(ialu_reg_reg_shift);
11799%}
11800
11801// This pattern is automatically generated from aarch64_ad.m4
11802// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11803// val | (-1 ^ (val >> shift)) ==> orn
11804instruct OrL_reg_RShift_not_reg(iRegLNoSp dst,
11805                         iRegL src1, iRegL src2,
11806                         immI src3, immL_M1 src4) %{
11807  match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4)));
11808  ins_cost(1.9 * INSN_COST);
11809  format %{ "orn  $dst, $src1, $src2, ASR $src3" %}
11810
11811  ins_encode %{
11812    __ orn(as_Register($dst$$reg),
11813              as_Register($src1$$reg),
11814              as_Register($src2$$reg),
11815              Assembler::ASR,
11816              $src3$$constant & 0x3f);
11817  %}
11818
11819  ins_pipe(ialu_reg_reg_shift);
11820%}
11821
11822// This pattern is automatically generated from aarch64_ad.m4
11823// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11824// val | (-1 ^ (val ror shift)) ==> ornw
11825instruct OrI_reg_RotateRight_not_reg(iRegINoSp dst,
11826                         iRegIorL2I src1, iRegIorL2I src2,
11827                         immI src3, immI_M1 src4) %{
11828  match(Set dst (OrI src1 (XorI(RotateRight src2 src3) src4)));
11829  ins_cost(1.9 * INSN_COST);
11830  format %{ "ornw  $dst, $src1, $src2, ROR $src3" %}
11831
11832  ins_encode %{
11833    __ ornw(as_Register($dst$$reg),
11834              as_Register($src1$$reg),
11835              as_Register($src2$$reg),
11836              Assembler::ROR,
11837              $src3$$constant & 0x1f);
11838  %}
11839
11840  ins_pipe(ialu_reg_reg_shift);
11841%}
11842
11843// This pattern is automatically generated from aarch64_ad.m4
11844// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11845// val | (-1 ^ (val ror shift)) ==> orn
11846instruct OrL_reg_RotateRight_not_reg(iRegLNoSp dst,
11847                         iRegL src1, iRegL src2,
11848                         immI src3, immL_M1 src4) %{
11849  match(Set dst (OrL src1 (XorL(RotateRight src2 src3) src4)));
11850  ins_cost(1.9 * INSN_COST);
11851  format %{ "orn  $dst, $src1, $src2, ROR $src3" %}
11852
11853  ins_encode %{
11854    __ orn(as_Register($dst$$reg),
11855              as_Register($src1$$reg),
11856              as_Register($src2$$reg),
11857              Assembler::ROR,
11858              $src3$$constant & 0x3f);
11859  %}
11860
11861  ins_pipe(ialu_reg_reg_shift);
11862%}
11863
11864// This pattern is automatically generated from aarch64_ad.m4
11865// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11866// val | (-1 ^ (val << shift)) ==> ornw
11867instruct OrI_reg_LShift_not_reg(iRegINoSp dst,
11868                         iRegIorL2I src1, iRegIorL2I src2,
11869                         immI src3, immI_M1 src4) %{
11870  match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4)));
11871  ins_cost(1.9 * INSN_COST);
11872  format %{ "ornw  $dst, $src1, $src2, LSL $src3" %}
11873
11874  ins_encode %{
11875    __ ornw(as_Register($dst$$reg),
11876              as_Register($src1$$reg),
11877              as_Register($src2$$reg),
11878              Assembler::LSL,
11879              $src3$$constant & 0x1f);
11880  %}
11881
11882  ins_pipe(ialu_reg_reg_shift);
11883%}
11884
11885// This pattern is automatically generated from aarch64_ad.m4
11886// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11887// val | (-1 ^ (val << shift)) ==> orn
11888instruct OrL_reg_LShift_not_reg(iRegLNoSp dst,
11889                         iRegL src1, iRegL src2,
11890                         immI src3, immL_M1 src4) %{
11891  match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4)));
11892  ins_cost(1.9 * INSN_COST);
11893  format %{ "orn  $dst, $src1, $src2, LSL $src3" %}
11894
11895  ins_encode %{
11896    __ orn(as_Register($dst$$reg),
11897              as_Register($src1$$reg),
11898              as_Register($src2$$reg),
11899              Assembler::LSL,
11900              $src3$$constant & 0x3f);
11901  %}
11902
11903  ins_pipe(ialu_reg_reg_shift);
11904%}
11905
11906// This pattern is automatically generated from aarch64_ad.m4
11907// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11908instruct AndI_reg_URShift_reg(iRegINoSp dst,
11909                         iRegIorL2I src1, iRegIorL2I src2,
11910                         immI src3) %{
11911  match(Set dst (AndI src1 (URShiftI src2 src3)));
11912
11913  ins_cost(1.9 * INSN_COST);
11914  format %{ "andw  $dst, $src1, $src2, LSR $src3" %}
11915
11916  ins_encode %{
11917    __ andw(as_Register($dst$$reg),
11918              as_Register($src1$$reg),
11919              as_Register($src2$$reg),
11920              Assembler::LSR,
11921              $src3$$constant & 0x1f);
11922  %}
11923
11924  ins_pipe(ialu_reg_reg_shift);
11925%}
11926
11927// This pattern is automatically generated from aarch64_ad.m4
11928// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11929instruct AndL_reg_URShift_reg(iRegLNoSp dst,
11930                         iRegL src1, iRegL src2,
11931                         immI src3) %{
11932  match(Set dst (AndL src1 (URShiftL src2 src3)));
11933
11934  ins_cost(1.9 * INSN_COST);
11935  format %{ "andr  $dst, $src1, $src2, LSR $src3" %}
11936
11937  ins_encode %{
11938    __ andr(as_Register($dst$$reg),
11939              as_Register($src1$$reg),
11940              as_Register($src2$$reg),
11941              Assembler::LSR,
11942              $src3$$constant & 0x3f);
11943  %}
11944
11945  ins_pipe(ialu_reg_reg_shift);
11946%}
11947
11948// This pattern is automatically generated from aarch64_ad.m4
11949// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11950instruct AndI_reg_RShift_reg(iRegINoSp dst,
11951                         iRegIorL2I src1, iRegIorL2I src2,
11952                         immI src3) %{
11953  match(Set dst (AndI src1 (RShiftI src2 src3)));
11954
11955  ins_cost(1.9 * INSN_COST);
11956  format %{ "andw  $dst, $src1, $src2, ASR $src3" %}
11957
11958  ins_encode %{
11959    __ andw(as_Register($dst$$reg),
11960              as_Register($src1$$reg),
11961              as_Register($src2$$reg),
11962              Assembler::ASR,
11963              $src3$$constant & 0x1f);
11964  %}
11965
11966  ins_pipe(ialu_reg_reg_shift);
11967%}
11968
11969// This pattern is automatically generated from aarch64_ad.m4
11970// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11971instruct AndL_reg_RShift_reg(iRegLNoSp dst,
11972                         iRegL src1, iRegL src2,
11973                         immI src3) %{
11974  match(Set dst (AndL src1 (RShiftL src2 src3)));
11975
11976  ins_cost(1.9 * INSN_COST);
11977  format %{ "andr  $dst, $src1, $src2, ASR $src3" %}
11978
11979  ins_encode %{
11980    __ andr(as_Register($dst$$reg),
11981              as_Register($src1$$reg),
11982              as_Register($src2$$reg),
11983              Assembler::ASR,
11984              $src3$$constant & 0x3f);
11985  %}
11986
11987  ins_pipe(ialu_reg_reg_shift);
11988%}
11989
11990// This pattern is automatically generated from aarch64_ad.m4
11991// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
11992instruct AndI_reg_LShift_reg(iRegINoSp dst,
11993                         iRegIorL2I src1, iRegIorL2I src2,
11994                         immI src3) %{
11995  match(Set dst (AndI src1 (LShiftI src2 src3)));
11996
11997  ins_cost(1.9 * INSN_COST);
11998  format %{ "andw  $dst, $src1, $src2, LSL $src3" %}
11999
12000  ins_encode %{
12001    __ andw(as_Register($dst$$reg),
12002              as_Register($src1$$reg),
12003              as_Register($src2$$reg),
12004              Assembler::LSL,
12005              $src3$$constant & 0x1f);
12006  %}
12007
12008  ins_pipe(ialu_reg_reg_shift);
12009%}
12010
12011// This pattern is automatically generated from aarch64_ad.m4
12012// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12013instruct AndL_reg_LShift_reg(iRegLNoSp dst,
12014                         iRegL src1, iRegL src2,
12015                         immI src3) %{
12016  match(Set dst (AndL src1 (LShiftL src2 src3)));
12017
12018  ins_cost(1.9 * INSN_COST);
12019  format %{ "andr  $dst, $src1, $src2, LSL $src3" %}
12020
12021  ins_encode %{
12022    __ andr(as_Register($dst$$reg),
12023              as_Register($src1$$reg),
12024              as_Register($src2$$reg),
12025              Assembler::LSL,
12026              $src3$$constant & 0x3f);
12027  %}
12028
12029  ins_pipe(ialu_reg_reg_shift);
12030%}
12031
12032// This pattern is automatically generated from aarch64_ad.m4
12033// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12034instruct AndI_reg_RotateRight_reg(iRegINoSp dst,
12035                         iRegIorL2I src1, iRegIorL2I src2,
12036                         immI src3) %{
12037  match(Set dst (AndI src1 (RotateRight src2 src3)));
12038
12039  ins_cost(1.9 * INSN_COST);
12040  format %{ "andw  $dst, $src1, $src2, ROR $src3" %}
12041
12042  ins_encode %{
12043    __ andw(as_Register($dst$$reg),
12044              as_Register($src1$$reg),
12045              as_Register($src2$$reg),
12046              Assembler::ROR,
12047              $src3$$constant & 0x1f);
12048  %}
12049
12050  ins_pipe(ialu_reg_reg_shift);
12051%}
12052
12053// This pattern is automatically generated from aarch64_ad.m4
12054// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12055instruct AndL_reg_RotateRight_reg(iRegLNoSp dst,
12056                         iRegL src1, iRegL src2,
12057                         immI src3) %{
12058  match(Set dst (AndL src1 (RotateRight src2 src3)));
12059
12060  ins_cost(1.9 * INSN_COST);
12061  format %{ "andr  $dst, $src1, $src2, ROR $src3" %}
12062
12063  ins_encode %{
12064    __ andr(as_Register($dst$$reg),
12065              as_Register($src1$$reg),
12066              as_Register($src2$$reg),
12067              Assembler::ROR,
12068              $src3$$constant & 0x3f);
12069  %}
12070
12071  ins_pipe(ialu_reg_reg_shift);
12072%}
12073
12074// This pattern is automatically generated from aarch64_ad.m4
12075// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12076instruct XorI_reg_URShift_reg(iRegINoSp dst,
12077                         iRegIorL2I src1, iRegIorL2I src2,
12078                         immI src3) %{
12079  match(Set dst (XorI src1 (URShiftI src2 src3)));
12080
12081  ins_cost(1.9 * INSN_COST);
12082  format %{ "eorw  $dst, $src1, $src2, LSR $src3" %}
12083
12084  ins_encode %{
12085    __ eorw(as_Register($dst$$reg),
12086              as_Register($src1$$reg),
12087              as_Register($src2$$reg),
12088              Assembler::LSR,
12089              $src3$$constant & 0x1f);
12090  %}
12091
12092  ins_pipe(ialu_reg_reg_shift);
12093%}
12094
12095// This pattern is automatically generated from aarch64_ad.m4
12096// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12097instruct XorL_reg_URShift_reg(iRegLNoSp dst,
12098                         iRegL src1, iRegL src2,
12099                         immI src3) %{
12100  match(Set dst (XorL src1 (URShiftL src2 src3)));
12101
12102  ins_cost(1.9 * INSN_COST);
12103  format %{ "eor  $dst, $src1, $src2, LSR $src3" %}
12104
12105  ins_encode %{
12106    __ eor(as_Register($dst$$reg),
12107              as_Register($src1$$reg),
12108              as_Register($src2$$reg),
12109              Assembler::LSR,
12110              $src3$$constant & 0x3f);
12111  %}
12112
12113  ins_pipe(ialu_reg_reg_shift);
12114%}
12115
12116// This pattern is automatically generated from aarch64_ad.m4
12117// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12118instruct XorI_reg_RShift_reg(iRegINoSp dst,
12119                         iRegIorL2I src1, iRegIorL2I src2,
12120                         immI src3) %{
12121  match(Set dst (XorI src1 (RShiftI src2 src3)));
12122
12123  ins_cost(1.9 * INSN_COST);
12124  format %{ "eorw  $dst, $src1, $src2, ASR $src3" %}
12125
12126  ins_encode %{
12127    __ eorw(as_Register($dst$$reg),
12128              as_Register($src1$$reg),
12129              as_Register($src2$$reg),
12130              Assembler::ASR,
12131              $src3$$constant & 0x1f);
12132  %}
12133
12134  ins_pipe(ialu_reg_reg_shift);
12135%}
12136
12137// This pattern is automatically generated from aarch64_ad.m4
12138// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12139instruct XorL_reg_RShift_reg(iRegLNoSp dst,
12140                         iRegL src1, iRegL src2,
12141                         immI src3) %{
12142  match(Set dst (XorL src1 (RShiftL src2 src3)));
12143
12144  ins_cost(1.9 * INSN_COST);
12145  format %{ "eor  $dst, $src1, $src2, ASR $src3" %}
12146
12147  ins_encode %{
12148    __ eor(as_Register($dst$$reg),
12149              as_Register($src1$$reg),
12150              as_Register($src2$$reg),
12151              Assembler::ASR,
12152              $src3$$constant & 0x3f);
12153  %}
12154
12155  ins_pipe(ialu_reg_reg_shift);
12156%}
12157
12158// This pattern is automatically generated from aarch64_ad.m4
12159// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12160instruct XorI_reg_LShift_reg(iRegINoSp dst,
12161                         iRegIorL2I src1, iRegIorL2I src2,
12162                         immI src3) %{
12163  match(Set dst (XorI src1 (LShiftI src2 src3)));
12164
12165  ins_cost(1.9 * INSN_COST);
12166  format %{ "eorw  $dst, $src1, $src2, LSL $src3" %}
12167
12168  ins_encode %{
12169    __ eorw(as_Register($dst$$reg),
12170              as_Register($src1$$reg),
12171              as_Register($src2$$reg),
12172              Assembler::LSL,
12173              $src3$$constant & 0x1f);
12174  %}
12175
12176  ins_pipe(ialu_reg_reg_shift);
12177%}
12178
12179// This pattern is automatically generated from aarch64_ad.m4
12180// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12181instruct XorL_reg_LShift_reg(iRegLNoSp dst,
12182                         iRegL src1, iRegL src2,
12183                         immI src3) %{
12184  match(Set dst (XorL src1 (LShiftL src2 src3)));
12185
12186  ins_cost(1.9 * INSN_COST);
12187  format %{ "eor  $dst, $src1, $src2, LSL $src3" %}
12188
12189  ins_encode %{
12190    __ eor(as_Register($dst$$reg),
12191              as_Register($src1$$reg),
12192              as_Register($src2$$reg),
12193              Assembler::LSL,
12194              $src3$$constant & 0x3f);
12195  %}
12196
12197  ins_pipe(ialu_reg_reg_shift);
12198%}
12199
12200// This pattern is automatically generated from aarch64_ad.m4
12201// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12202instruct XorI_reg_RotateRight_reg(iRegINoSp dst,
12203                         iRegIorL2I src1, iRegIorL2I src2,
12204                         immI src3) %{
12205  match(Set dst (XorI src1 (RotateRight src2 src3)));
12206
12207  ins_cost(1.9 * INSN_COST);
12208  format %{ "eorw  $dst, $src1, $src2, ROR $src3" %}
12209
12210  ins_encode %{
12211    __ eorw(as_Register($dst$$reg),
12212              as_Register($src1$$reg),
12213              as_Register($src2$$reg),
12214              Assembler::ROR,
12215              $src3$$constant & 0x1f);
12216  %}
12217
12218  ins_pipe(ialu_reg_reg_shift);
12219%}
12220
12221// This pattern is automatically generated from aarch64_ad.m4
12222// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12223instruct XorL_reg_RotateRight_reg(iRegLNoSp dst,
12224                         iRegL src1, iRegL src2,
12225                         immI src3) %{
12226  match(Set dst (XorL src1 (RotateRight src2 src3)));
12227
12228  ins_cost(1.9 * INSN_COST);
12229  format %{ "eor  $dst, $src1, $src2, ROR $src3" %}
12230
12231  ins_encode %{
12232    __ eor(as_Register($dst$$reg),
12233              as_Register($src1$$reg),
12234              as_Register($src2$$reg),
12235              Assembler::ROR,
12236              $src3$$constant & 0x3f);
12237  %}
12238
12239  ins_pipe(ialu_reg_reg_shift);
12240%}
12241
12242// This pattern is automatically generated from aarch64_ad.m4
12243// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12244instruct OrI_reg_URShift_reg(iRegINoSp dst,
12245                         iRegIorL2I src1, iRegIorL2I src2,
12246                         immI src3) %{
12247  match(Set dst (OrI src1 (URShiftI src2 src3)));
12248
12249  ins_cost(1.9 * INSN_COST);
12250  format %{ "orrw  $dst, $src1, $src2, LSR $src3" %}
12251
12252  ins_encode %{
12253    __ orrw(as_Register($dst$$reg),
12254              as_Register($src1$$reg),
12255              as_Register($src2$$reg),
12256              Assembler::LSR,
12257              $src3$$constant & 0x1f);
12258  %}
12259
12260  ins_pipe(ialu_reg_reg_shift);
12261%}
12262
12263// This pattern is automatically generated from aarch64_ad.m4
12264// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12265instruct OrL_reg_URShift_reg(iRegLNoSp dst,
12266                         iRegL src1, iRegL src2,
12267                         immI src3) %{
12268  match(Set dst (OrL src1 (URShiftL src2 src3)));
12269
12270  ins_cost(1.9 * INSN_COST);
12271  format %{ "orr  $dst, $src1, $src2, LSR $src3" %}
12272
12273  ins_encode %{
12274    __ orr(as_Register($dst$$reg),
12275              as_Register($src1$$reg),
12276              as_Register($src2$$reg),
12277              Assembler::LSR,
12278              $src3$$constant & 0x3f);
12279  %}
12280
12281  ins_pipe(ialu_reg_reg_shift);
12282%}
12283
12284// This pattern is automatically generated from aarch64_ad.m4
12285// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12286instruct OrI_reg_RShift_reg(iRegINoSp dst,
12287                         iRegIorL2I src1, iRegIorL2I src2,
12288                         immI src3) %{
12289  match(Set dst (OrI src1 (RShiftI src2 src3)));
12290
12291  ins_cost(1.9 * INSN_COST);
12292  format %{ "orrw  $dst, $src1, $src2, ASR $src3" %}
12293
12294  ins_encode %{
12295    __ orrw(as_Register($dst$$reg),
12296              as_Register($src1$$reg),
12297              as_Register($src2$$reg),
12298              Assembler::ASR,
12299              $src3$$constant & 0x1f);
12300  %}
12301
12302  ins_pipe(ialu_reg_reg_shift);
12303%}
12304
12305// This pattern is automatically generated from aarch64_ad.m4
12306// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12307instruct OrL_reg_RShift_reg(iRegLNoSp dst,
12308                         iRegL src1, iRegL src2,
12309                         immI src3) %{
12310  match(Set dst (OrL src1 (RShiftL src2 src3)));
12311
12312  ins_cost(1.9 * INSN_COST);
12313  format %{ "orr  $dst, $src1, $src2, ASR $src3" %}
12314
12315  ins_encode %{
12316    __ orr(as_Register($dst$$reg),
12317              as_Register($src1$$reg),
12318              as_Register($src2$$reg),
12319              Assembler::ASR,
12320              $src3$$constant & 0x3f);
12321  %}
12322
12323  ins_pipe(ialu_reg_reg_shift);
12324%}
12325
12326// This pattern is automatically generated from aarch64_ad.m4
12327// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12328instruct OrI_reg_LShift_reg(iRegINoSp dst,
12329                         iRegIorL2I src1, iRegIorL2I src2,
12330                         immI src3) %{
12331  match(Set dst (OrI src1 (LShiftI src2 src3)));
12332
12333  ins_cost(1.9 * INSN_COST);
12334  format %{ "orrw  $dst, $src1, $src2, LSL $src3" %}
12335
12336  ins_encode %{
12337    __ orrw(as_Register($dst$$reg),
12338              as_Register($src1$$reg),
12339              as_Register($src2$$reg),
12340              Assembler::LSL,
12341              $src3$$constant & 0x1f);
12342  %}
12343
12344  ins_pipe(ialu_reg_reg_shift);
12345%}
12346
12347// This pattern is automatically generated from aarch64_ad.m4
12348// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12349instruct OrL_reg_LShift_reg(iRegLNoSp dst,
12350                         iRegL src1, iRegL src2,
12351                         immI src3) %{
12352  match(Set dst (OrL src1 (LShiftL src2 src3)));
12353
12354  ins_cost(1.9 * INSN_COST);
12355  format %{ "orr  $dst, $src1, $src2, LSL $src3" %}
12356
12357  ins_encode %{
12358    __ orr(as_Register($dst$$reg),
12359              as_Register($src1$$reg),
12360              as_Register($src2$$reg),
12361              Assembler::LSL,
12362              $src3$$constant & 0x3f);
12363  %}
12364
12365  ins_pipe(ialu_reg_reg_shift);
12366%}
12367
12368// This pattern is automatically generated from aarch64_ad.m4
12369// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12370instruct OrI_reg_RotateRight_reg(iRegINoSp dst,
12371                         iRegIorL2I src1, iRegIorL2I src2,
12372                         immI src3) %{
12373  match(Set dst (OrI src1 (RotateRight src2 src3)));
12374
12375  ins_cost(1.9 * INSN_COST);
12376  format %{ "orrw  $dst, $src1, $src2, ROR $src3" %}
12377
12378  ins_encode %{
12379    __ orrw(as_Register($dst$$reg),
12380              as_Register($src1$$reg),
12381              as_Register($src2$$reg),
12382              Assembler::ROR,
12383              $src3$$constant & 0x1f);
12384  %}
12385
12386  ins_pipe(ialu_reg_reg_shift);
12387%}
12388
12389// This pattern is automatically generated from aarch64_ad.m4
12390// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12391instruct OrL_reg_RotateRight_reg(iRegLNoSp dst,
12392                         iRegL src1, iRegL src2,
12393                         immI src3) %{
12394  match(Set dst (OrL src1 (RotateRight src2 src3)));
12395
12396  ins_cost(1.9 * INSN_COST);
12397  format %{ "orr  $dst, $src1, $src2, ROR $src3" %}
12398
12399  ins_encode %{
12400    __ orr(as_Register($dst$$reg),
12401              as_Register($src1$$reg),
12402              as_Register($src2$$reg),
12403              Assembler::ROR,
12404              $src3$$constant & 0x3f);
12405  %}
12406
12407  ins_pipe(ialu_reg_reg_shift);
12408%}
12409
12410// This pattern is automatically generated from aarch64_ad.m4
12411// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12412instruct AddI_reg_URShift_reg(iRegINoSp dst,
12413                         iRegIorL2I src1, iRegIorL2I src2,
12414                         immI src3) %{
12415  match(Set dst (AddI src1 (URShiftI src2 src3)));
12416
12417  ins_cost(1.9 * INSN_COST);
12418  format %{ "addw  $dst, $src1, $src2, LSR $src3" %}
12419
12420  ins_encode %{
12421    __ addw(as_Register($dst$$reg),
12422              as_Register($src1$$reg),
12423              as_Register($src2$$reg),
12424              Assembler::LSR,
12425              $src3$$constant & 0x1f);
12426  %}
12427
12428  ins_pipe(ialu_reg_reg_shift);
12429%}
12430
12431// This pattern is automatically generated from aarch64_ad.m4
12432// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12433instruct AddL_reg_URShift_reg(iRegLNoSp dst,
12434                         iRegL src1, iRegL src2,
12435                         immI src3) %{
12436  match(Set dst (AddL src1 (URShiftL src2 src3)));
12437
12438  ins_cost(1.9 * INSN_COST);
12439  format %{ "add  $dst, $src1, $src2, LSR $src3" %}
12440
12441  ins_encode %{
12442    __ add(as_Register($dst$$reg),
12443              as_Register($src1$$reg),
12444              as_Register($src2$$reg),
12445              Assembler::LSR,
12446              $src3$$constant & 0x3f);
12447  %}
12448
12449  ins_pipe(ialu_reg_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
12454instruct AddI_reg_RShift_reg(iRegINoSp dst,
12455                         iRegIorL2I src1, iRegIorL2I src2,
12456                         immI src3) %{
12457  match(Set dst (AddI src1 (RShiftI src2 src3)));
12458
12459  ins_cost(1.9 * INSN_COST);
12460  format %{ "addw  $dst, $src1, $src2, ASR $src3" %}
12461
12462  ins_encode %{
12463    __ addw(as_Register($dst$$reg),
12464              as_Register($src1$$reg),
12465              as_Register($src2$$reg),
12466              Assembler::ASR,
12467              $src3$$constant & 0x1f);
12468  %}
12469
12470  ins_pipe(ialu_reg_reg_shift);
12471%}
12472
12473// This pattern is automatically generated from aarch64_ad.m4
12474// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12475instruct AddL_reg_RShift_reg(iRegLNoSp dst,
12476                         iRegL src1, iRegL src2,
12477                         immI src3) %{
12478  match(Set dst (AddL src1 (RShiftL src2 src3)));
12479
12480  ins_cost(1.9 * INSN_COST);
12481  format %{ "add  $dst, $src1, $src2, ASR $src3" %}
12482
12483  ins_encode %{
12484    __ add(as_Register($dst$$reg),
12485              as_Register($src1$$reg),
12486              as_Register($src2$$reg),
12487              Assembler::ASR,
12488              $src3$$constant & 0x3f);
12489  %}
12490
12491  ins_pipe(ialu_reg_reg_shift);
12492%}
12493
12494// This pattern is automatically generated from aarch64_ad.m4
12495// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12496instruct AddI_reg_LShift_reg(iRegINoSp dst,
12497                         iRegIorL2I src1, iRegIorL2I src2,
12498                         immI src3) %{
12499  match(Set dst (AddI src1 (LShiftI src2 src3)));
12500
12501  ins_cost(1.9 * INSN_COST);
12502  format %{ "addw  $dst, $src1, $src2, LSL $src3" %}
12503
12504  ins_encode %{
12505    __ addw(as_Register($dst$$reg),
12506              as_Register($src1$$reg),
12507              as_Register($src2$$reg),
12508              Assembler::LSL,
12509              $src3$$constant & 0x1f);
12510  %}
12511
12512  ins_pipe(ialu_reg_reg_shift);
12513%}
12514
12515// This pattern is automatically generated from aarch64_ad.m4
12516// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12517instruct AddL_reg_LShift_reg(iRegLNoSp dst,
12518                         iRegL src1, iRegL src2,
12519                         immI src3) %{
12520  match(Set dst (AddL src1 (LShiftL src2 src3)));
12521
12522  ins_cost(1.9 * INSN_COST);
12523  format %{ "add  $dst, $src1, $src2, LSL $src3" %}
12524
12525  ins_encode %{
12526    __ add(as_Register($dst$$reg),
12527              as_Register($src1$$reg),
12528              as_Register($src2$$reg),
12529              Assembler::LSL,
12530              $src3$$constant & 0x3f);
12531  %}
12532
12533  ins_pipe(ialu_reg_reg_shift);
12534%}
12535
12536// This pattern is automatically generated from aarch64_ad.m4
12537// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12538instruct SubI_reg_URShift_reg(iRegINoSp dst,
12539                         iRegIorL2I src1, iRegIorL2I src2,
12540                         immI src3) %{
12541  match(Set dst (SubI src1 (URShiftI src2 src3)));
12542
12543  ins_cost(1.9 * INSN_COST);
12544  format %{ "subw  $dst, $src1, $src2, LSR $src3" %}
12545
12546  ins_encode %{
12547    __ subw(as_Register($dst$$reg),
12548              as_Register($src1$$reg),
12549              as_Register($src2$$reg),
12550              Assembler::LSR,
12551              $src3$$constant & 0x1f);
12552  %}
12553
12554  ins_pipe(ialu_reg_reg_shift);
12555%}
12556
12557// This pattern is automatically generated from aarch64_ad.m4
12558// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12559instruct SubL_reg_URShift_reg(iRegLNoSp dst,
12560                         iRegL src1, iRegL src2,
12561                         immI src3) %{
12562  match(Set dst (SubL src1 (URShiftL src2 src3)));
12563
12564  ins_cost(1.9 * INSN_COST);
12565  format %{ "sub  $dst, $src1, $src2, LSR $src3" %}
12566
12567  ins_encode %{
12568    __ sub(as_Register($dst$$reg),
12569              as_Register($src1$$reg),
12570              as_Register($src2$$reg),
12571              Assembler::LSR,
12572              $src3$$constant & 0x3f);
12573  %}
12574
12575  ins_pipe(ialu_reg_reg_shift);
12576%}
12577
12578// This pattern is automatically generated from aarch64_ad.m4
12579// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12580instruct SubI_reg_RShift_reg(iRegINoSp dst,
12581                         iRegIorL2I src1, iRegIorL2I src2,
12582                         immI src3) %{
12583  match(Set dst (SubI src1 (RShiftI src2 src3)));
12584
12585  ins_cost(1.9 * INSN_COST);
12586  format %{ "subw  $dst, $src1, $src2, ASR $src3" %}
12587
12588  ins_encode %{
12589    __ subw(as_Register($dst$$reg),
12590              as_Register($src1$$reg),
12591              as_Register($src2$$reg),
12592              Assembler::ASR,
12593              $src3$$constant & 0x1f);
12594  %}
12595
12596  ins_pipe(ialu_reg_reg_shift);
12597%}
12598
12599// This pattern is automatically generated from aarch64_ad.m4
12600// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12601instruct SubL_reg_RShift_reg(iRegLNoSp dst,
12602                         iRegL src1, iRegL src2,
12603                         immI src3) %{
12604  match(Set dst (SubL src1 (RShiftL src2 src3)));
12605
12606  ins_cost(1.9 * INSN_COST);
12607  format %{ "sub  $dst, $src1, $src2, ASR $src3" %}
12608
12609  ins_encode %{
12610    __ sub(as_Register($dst$$reg),
12611              as_Register($src1$$reg),
12612              as_Register($src2$$reg),
12613              Assembler::ASR,
12614              $src3$$constant & 0x3f);
12615  %}
12616
12617  ins_pipe(ialu_reg_reg_shift);
12618%}
12619
12620// This pattern is automatically generated from aarch64_ad.m4
12621// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12622instruct SubI_reg_LShift_reg(iRegINoSp dst,
12623                         iRegIorL2I src1, iRegIorL2I src2,
12624                         immI src3) %{
12625  match(Set dst (SubI src1 (LShiftI src2 src3)));
12626
12627  ins_cost(1.9 * INSN_COST);
12628  format %{ "subw  $dst, $src1, $src2, LSL $src3" %}
12629
12630  ins_encode %{
12631    __ subw(as_Register($dst$$reg),
12632              as_Register($src1$$reg),
12633              as_Register($src2$$reg),
12634              Assembler::LSL,
12635              $src3$$constant & 0x1f);
12636  %}
12637
12638  ins_pipe(ialu_reg_reg_shift);
12639%}
12640
12641// This pattern is automatically generated from aarch64_ad.m4
12642// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12643instruct SubL_reg_LShift_reg(iRegLNoSp dst,
12644                         iRegL src1, iRegL src2,
12645                         immI src3) %{
12646  match(Set dst (SubL src1 (LShiftL src2 src3)));
12647
12648  ins_cost(1.9 * INSN_COST);
12649  format %{ "sub  $dst, $src1, $src2, LSL $src3" %}
12650
12651  ins_encode %{
12652    __ sub(as_Register($dst$$reg),
12653              as_Register($src1$$reg),
12654              as_Register($src2$$reg),
12655              Assembler::LSL,
12656              $src3$$constant & 0x3f);
12657  %}
12658
12659  ins_pipe(ialu_reg_reg_shift);
12660%}
12661
12662// This pattern is automatically generated from aarch64_ad.m4
12663// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12664
12665// Shift Left followed by Shift Right.
12666// This idiom is used by the compiler for the i2b bytecode etc.
12667instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
12668%{
12669  match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count));
12670  ins_cost(INSN_COST * 2);
12671  format %{ "sbfm  $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
12672  ins_encode %{
12673    int lshift = $lshift_count$$constant & 63;
12674    int rshift = $rshift_count$$constant & 63;
12675    int s = 63 - lshift;
12676    int r = (rshift - lshift) & 63;
12677    __ sbfm(as_Register($dst$$reg),
12678            as_Register($src$$reg),
12679            r, s);
12680  %}
12681
12682  ins_pipe(ialu_reg_shift);
12683%}
12684
12685// This pattern is automatically generated from aarch64_ad.m4
12686// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12687
12688// Shift Left followed by Shift Right.
12689// This idiom is used by the compiler for the i2b bytecode etc.
12690instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
12691%{
12692  match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count));
12693  ins_cost(INSN_COST * 2);
12694  format %{ "sbfmw  $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
12695  ins_encode %{
12696    int lshift = $lshift_count$$constant & 31;
12697    int rshift = $rshift_count$$constant & 31;
12698    int s = 31 - lshift;
12699    int r = (rshift - lshift) & 31;
12700    __ sbfmw(as_Register($dst$$reg),
12701            as_Register($src$$reg),
12702            r, s);
12703  %}
12704
12705  ins_pipe(ialu_reg_shift);
12706%}
12707
12708// This pattern is automatically generated from aarch64_ad.m4
12709// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12710
12711// Shift Left followed by Shift Right.
12712// This idiom is used by the compiler for the i2b bytecode etc.
12713instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
12714%{
12715  match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count));
12716  ins_cost(INSN_COST * 2);
12717  format %{ "ubfm  $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
12718  ins_encode %{
12719    int lshift = $lshift_count$$constant & 63;
12720    int rshift = $rshift_count$$constant & 63;
12721    int s = 63 - lshift;
12722    int r = (rshift - lshift) & 63;
12723    __ ubfm(as_Register($dst$$reg),
12724            as_Register($src$$reg),
12725            r, s);
12726  %}
12727
12728  ins_pipe(ialu_reg_shift);
12729%}
12730
12731// This pattern is automatically generated from aarch64_ad.m4
12732// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12733
12734// Shift Left followed by Shift Right.
12735// This idiom is used by the compiler for the i2b bytecode etc.
12736instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
12737%{
12738  match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count));
12739  ins_cost(INSN_COST * 2);
12740  format %{ "ubfmw  $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
12741  ins_encode %{
12742    int lshift = $lshift_count$$constant & 31;
12743    int rshift = $rshift_count$$constant & 31;
12744    int s = 31 - lshift;
12745    int r = (rshift - lshift) & 31;
12746    __ ubfmw(as_Register($dst$$reg),
12747            as_Register($src$$reg),
12748            r, s);
12749  %}
12750
12751  ins_pipe(ialu_reg_shift);
12752%}
12753
12754// Bitfield extract with shift & mask
12755
12756// This pattern is automatically generated from aarch64_ad.m4
12757// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12758instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
12759%{
12760  match(Set dst (AndI (URShiftI src rshift) mask));
12761  // Make sure we are not going to exceed what ubfxw can do.
12762  predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
12763
12764  ins_cost(INSN_COST);
12765  format %{ "ubfxw $dst, $src, $rshift, $mask" %}
12766  ins_encode %{
12767    int rshift = $rshift$$constant & 31;
12768    intptr_t mask = $mask$$constant;
12769    int width = exact_log2(mask+1);
12770    __ ubfxw(as_Register($dst$$reg),
12771            as_Register($src$$reg), rshift, width);
12772  %}
12773  ins_pipe(ialu_reg_shift);
12774%}
12775
12776// This pattern is automatically generated from aarch64_ad.m4
12777// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12778instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask)
12779%{
12780  match(Set dst (AndL (URShiftL src rshift) mask));
12781  // Make sure we are not going to exceed what ubfx can do.
12782  predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1));
12783
12784  ins_cost(INSN_COST);
12785  format %{ "ubfx $dst, $src, $rshift, $mask" %}
12786  ins_encode %{
12787    int rshift = $rshift$$constant & 63;
12788    intptr_t mask = $mask$$constant;
12789    int width = exact_log2_long(mask+1);
12790    __ ubfx(as_Register($dst$$reg),
12791            as_Register($src$$reg), rshift, width);
12792  %}
12793  ins_pipe(ialu_reg_shift);
12794%}
12795
12796
12797// This pattern is automatically generated from aarch64_ad.m4
12798// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12799
12800// We can use ubfx when extending an And with a mask when we know mask
12801// is positive.  We know that because immI_bitmask guarantees it.
12802instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
12803%{
12804  match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
12805  // Make sure we are not going to exceed what ubfxw can do.
12806  predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
12807
12808  ins_cost(INSN_COST * 2);
12809  format %{ "ubfx $dst, $src, $rshift, $mask" %}
12810  ins_encode %{
12811    int rshift = $rshift$$constant & 31;
12812    intptr_t mask = $mask$$constant;
12813    int width = exact_log2(mask+1);
12814    __ ubfx(as_Register($dst$$reg),
12815            as_Register($src$$reg), rshift, width);
12816  %}
12817  ins_pipe(ialu_reg_shift);
12818%}
12819
12820
12821// This pattern is automatically generated from aarch64_ad.m4
12822// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12823
12824// We can use ubfiz when masking by a positive number and then left shifting the result.
12825// We know that the mask is positive because immI_bitmask guarantees it.
12826instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
12827%{
12828  match(Set dst (LShiftI (AndI src mask) lshift));
12829  predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1));
12830
12831  ins_cost(INSN_COST);
12832  format %{ "ubfizw $dst, $src, $lshift, $mask" %}
12833  ins_encode %{
12834    int lshift = $lshift$$constant & 31;
12835    intptr_t mask = $mask$$constant;
12836    int width = exact_log2(mask+1);
12837    __ ubfizw(as_Register($dst$$reg),
12838          as_Register($src$$reg), lshift, width);
12839  %}
12840  ins_pipe(ialu_reg_shift);
12841%}
12842
12843// This pattern is automatically generated from aarch64_ad.m4
12844// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12845
12846// We can use ubfiz when masking by a positive number and then left shifting the result.
12847// We know that the mask is positive because immL_bitmask guarantees it.
12848instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
12849%{
12850  match(Set dst (LShiftL (AndL src mask) lshift));
12851  predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
12852
12853  ins_cost(INSN_COST);
12854  format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12855  ins_encode %{
12856    int lshift = $lshift$$constant & 63;
12857    intptr_t mask = $mask$$constant;
12858    int width = exact_log2_long(mask+1);
12859    __ ubfiz(as_Register($dst$$reg),
12860          as_Register($src$$reg), lshift, width);
12861  %}
12862  ins_pipe(ialu_reg_shift);
12863%}
12864
12865// This pattern is automatically generated from aarch64_ad.m4
12866// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12867
12868// We can use ubfiz when masking by a positive number and then left shifting the result.
12869// We know that the mask is positive because immI_bitmask guarantees it.
12870instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
12871%{
12872  match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift)));
12873  predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31);
12874
12875  ins_cost(INSN_COST);
12876  format %{ "ubfizw $dst, $src, $lshift, $mask" %}
12877  ins_encode %{
12878    int lshift = $lshift$$constant & 31;
12879    intptr_t mask = $mask$$constant;
12880    int width = exact_log2(mask+1);
12881    __ ubfizw(as_Register($dst$$reg),
12882          as_Register($src$$reg), lshift, width);
12883  %}
12884  ins_pipe(ialu_reg_shift);
12885%}
12886
12887// This pattern is automatically generated from aarch64_ad.m4
12888// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12889
12890// We can use ubfiz when masking by a positive number and then left shifting the result.
12891// We know that the mask is positive because immL_bitmask guarantees it.
12892instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
12893%{
12894  match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift)));
12895  predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31);
12896
12897  ins_cost(INSN_COST);
12898  format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12899  ins_encode %{
12900    int lshift = $lshift$$constant & 63;
12901    intptr_t mask = $mask$$constant;
12902    int width = exact_log2_long(mask+1);
12903    __ ubfiz(as_Register($dst$$reg),
12904          as_Register($src$$reg), lshift, width);
12905  %}
12906  ins_pipe(ialu_reg_shift);
12907%}
12908
12909
12910// This pattern is automatically generated from aarch64_ad.m4
12911// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12912
12913// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
12914instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
12915%{
12916  match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift));
12917  predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
12918
12919  ins_cost(INSN_COST);
12920  format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12921  ins_encode %{
12922    int lshift = $lshift$$constant & 63;
12923    intptr_t mask = $mask$$constant;
12924    int width = exact_log2(mask+1);
12925    __ ubfiz(as_Register($dst$$reg),
12926             as_Register($src$$reg), lshift, width);
12927  %}
12928  ins_pipe(ialu_reg_shift);
12929%}
12930
12931// This pattern is automatically generated from aarch64_ad.m4
12932// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12933
12934// If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz
12935instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
12936%{
12937  match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift));
12938  predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31);
12939
12940  ins_cost(INSN_COST);
12941  format %{ "ubfiz $dst, $src, $lshift, $mask" %}
12942  ins_encode %{
12943    int lshift = $lshift$$constant & 31;
12944    intptr_t mask = $mask$$constant;
12945    int width = exact_log2(mask+1);
12946    __ ubfiz(as_Register($dst$$reg),
12947             as_Register($src$$reg), lshift, width);
12948  %}
12949  ins_pipe(ialu_reg_shift);
12950%}
12951
12952// This pattern is automatically generated from aarch64_ad.m4
12953// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12954
12955// Can skip int2long conversions after AND with small bitmask
12956instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk)
12957%{
12958  match(Set dst (ConvI2L (AndI src msk)));
12959  ins_cost(INSN_COST);
12960  format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %}
12961  ins_encode %{
12962    __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1));
12963  %}
12964  ins_pipe(ialu_reg_shift);
12965%}
12966
12967
12968// Rotations
12969// This pattern is automatically generated from aarch64_ad.m4
12970// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12971instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
12972%{
12973  match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift)));
12974  predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
12975
12976  ins_cost(INSN_COST);
12977  format %{ "extr $dst, $src1, $src2, #$rshift" %}
12978
12979  ins_encode %{
12980    __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12981            $rshift$$constant & 63);
12982  %}
12983  ins_pipe(ialu_reg_reg_extr);
12984%}
12985
12986
12987// This pattern is automatically generated from aarch64_ad.m4
12988// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
12989instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
12990%{
12991  match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift)));
12992  predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
12993
12994  ins_cost(INSN_COST);
12995  format %{ "extr $dst, $src1, $src2, #$rshift" %}
12996
12997  ins_encode %{
12998    __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
12999            $rshift$$constant & 31);
13000  %}
13001  ins_pipe(ialu_reg_reg_extr);
13002%}
13003
13004
13005// This pattern is automatically generated from aarch64_ad.m4
13006// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13007instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
13008%{
13009  match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift)));
13010  predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
13011
13012  ins_cost(INSN_COST);
13013  format %{ "extr $dst, $src1, $src2, #$rshift" %}
13014
13015  ins_encode %{
13016    __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
13017            $rshift$$constant & 63);
13018  %}
13019  ins_pipe(ialu_reg_reg_extr);
13020%}
13021
13022
13023// This pattern is automatically generated from aarch64_ad.m4
13024// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13025instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
13026%{
13027  match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift)));
13028  predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
13029
13030  ins_cost(INSN_COST);
13031  format %{ "extr $dst, $src1, $src2, #$rshift" %}
13032
13033  ins_encode %{
13034    __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
13035            $rshift$$constant & 31);
13036  %}
13037  ins_pipe(ialu_reg_reg_extr);
13038%}
13039
13040
13041// This pattern is automatically generated from aarch64_ad.m4
13042// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13043instruct rorI_imm(iRegINoSp dst, iRegI src, immI shift)
13044%{
13045  match(Set dst (RotateRight src shift));
13046
13047  ins_cost(INSN_COST);
13048  format %{ "ror    $dst, $src, $shift" %}
13049
13050  ins_encode %{
13051     __ extrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg),
13052               $shift$$constant & 0x1f);
13053  %}
13054  ins_pipe(ialu_reg_reg_vshift);
13055%}
13056
13057// This pattern is automatically generated from aarch64_ad.m4
13058// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13059instruct rorL_imm(iRegLNoSp dst, iRegL src, immI shift)
13060%{
13061  match(Set dst (RotateRight src shift));
13062
13063  ins_cost(INSN_COST);
13064  format %{ "ror    $dst, $src, $shift" %}
13065
13066  ins_encode %{
13067     __ extr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg),
13068               $shift$$constant & 0x3f);
13069  %}
13070  ins_pipe(ialu_reg_reg_vshift);
13071%}
13072
13073// This pattern is automatically generated from aarch64_ad.m4
13074// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13075instruct rorI_reg(iRegINoSp dst, iRegI src, iRegI shift)
13076%{
13077  match(Set dst (RotateRight src shift));
13078
13079  ins_cost(INSN_COST);
13080  format %{ "ror    $dst, $src, $shift" %}
13081
13082  ins_encode %{
13083     __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg));
13084  %}
13085  ins_pipe(ialu_reg_reg_vshift);
13086%}
13087
13088// This pattern is automatically generated from aarch64_ad.m4
13089// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13090instruct rorL_reg(iRegLNoSp dst, iRegL src, iRegI shift)
13091%{
13092  match(Set dst (RotateRight src shift));
13093
13094  ins_cost(INSN_COST);
13095  format %{ "ror    $dst, $src, $shift" %}
13096
13097  ins_encode %{
13098     __ rorv(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg));
13099  %}
13100  ins_pipe(ialu_reg_reg_vshift);
13101%}
13102
13103// This pattern is automatically generated from aarch64_ad.m4
13104// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13105instruct rolI_reg(iRegINoSp dst, iRegI src, iRegI shift)
13106%{
13107  match(Set dst (RotateLeft src shift));
13108
13109  ins_cost(INSN_COST);
13110  format %{ "rol    $dst, $src, $shift" %}
13111
13112  ins_encode %{
13113     __ subw(rscratch1, zr, as_Register($shift$$reg));
13114     __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), rscratch1);
13115  %}
13116  ins_pipe(ialu_reg_reg_vshift);
13117%}
13118
13119// This pattern is automatically generated from aarch64_ad.m4
13120// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13121instruct rolL_reg(iRegLNoSp dst, iRegL src, iRegI shift)
13122%{
13123  match(Set dst (RotateLeft src shift));
13124
13125  ins_cost(INSN_COST);
13126  format %{ "rol    $dst, $src, $shift" %}
13127
13128  ins_encode %{
13129     __ subw(rscratch1, zr, as_Register($shift$$reg));
13130     __ rorv(as_Register($dst$$reg), as_Register($src$$reg), rscratch1);
13131  %}
13132  ins_pipe(ialu_reg_reg_vshift);
13133%}
13134
13135
13136// Add/subtract (extended)
13137
13138// This pattern is automatically generated from aarch64_ad.m4
13139// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13140instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
13141%{
13142  match(Set dst (AddL src1 (ConvI2L src2)));
13143  ins_cost(INSN_COST);
13144  format %{ "add  $dst, $src1, $src2, sxtw" %}
13145
13146   ins_encode %{
13147     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13148            as_Register($src2$$reg), ext::sxtw);
13149   %}
13150  ins_pipe(ialu_reg_reg);
13151%}
13152
13153// This pattern is automatically generated from aarch64_ad.m4
13154// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13155instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr)
13156%{
13157  match(Set dst (SubL src1 (ConvI2L src2)));
13158  ins_cost(INSN_COST);
13159  format %{ "sub  $dst, $src1, $src2, sxtw" %}
13160
13161   ins_encode %{
13162     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13163            as_Register($src2$$reg), ext::sxtw);
13164   %}
13165  ins_pipe(ialu_reg_reg);
13166%}
13167
13168// This pattern is automatically generated from aarch64_ad.m4
13169// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13170instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr)
13171%{
13172  match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
13173  ins_cost(INSN_COST);
13174  format %{ "add  $dst, $src1, $src2, sxth" %}
13175
13176   ins_encode %{
13177     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13178            as_Register($src2$$reg), ext::sxth);
13179   %}
13180  ins_pipe(ialu_reg_reg);
13181%}
13182
13183// This pattern is automatically generated from aarch64_ad.m4
13184// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13185instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
13186%{
13187  match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift)));
13188  ins_cost(INSN_COST);
13189  format %{ "add  $dst, $src1, $src2, sxtb" %}
13190
13191   ins_encode %{
13192     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13193            as_Register($src2$$reg), ext::sxtb);
13194   %}
13195  ins_pipe(ialu_reg_reg);
13196%}
13197
13198// This pattern is automatically generated from aarch64_ad.m4
13199// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13200instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr)
13201%{
13202  match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift)));
13203  ins_cost(INSN_COST);
13204  format %{ "add  $dst, $src1, $src2, uxtb" %}
13205
13206   ins_encode %{
13207     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13208            as_Register($src2$$reg), ext::uxtb);
13209   %}
13210  ins_pipe(ialu_reg_reg);
13211%}
13212
13213// This pattern is automatically generated from aarch64_ad.m4
13214// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13215instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr)
13216%{
13217  match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
13218  ins_cost(INSN_COST);
13219  format %{ "add  $dst, $src1, $src2, sxth" %}
13220
13221   ins_encode %{
13222     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13223            as_Register($src2$$reg), ext::sxth);
13224   %}
13225  ins_pipe(ialu_reg_reg);
13226%}
13227
13228// This pattern is automatically generated from aarch64_ad.m4
13229// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13230instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr)
13231%{
13232  match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
13233  ins_cost(INSN_COST);
13234  format %{ "add  $dst, $src1, $src2, sxtw" %}
13235
13236   ins_encode %{
13237     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13238            as_Register($src2$$reg), ext::sxtw);
13239   %}
13240  ins_pipe(ialu_reg_reg);
13241%}
13242
13243// This pattern is automatically generated from aarch64_ad.m4
13244// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13245instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
13246%{
13247  match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift)));
13248  ins_cost(INSN_COST);
13249  format %{ "add  $dst, $src1, $src2, sxtb" %}
13250
13251   ins_encode %{
13252     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13253            as_Register($src2$$reg), ext::sxtb);
13254   %}
13255  ins_pipe(ialu_reg_reg);
13256%}
13257
13258// This pattern is automatically generated from aarch64_ad.m4
13259// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13260instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr)
13261%{
13262  match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift)));
13263  ins_cost(INSN_COST);
13264  format %{ "add  $dst, $src1, $src2, uxtb" %}
13265
13266   ins_encode %{
13267     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13268            as_Register($src2$$reg), ext::uxtb);
13269   %}
13270  ins_pipe(ialu_reg_reg);
13271%}
13272
13273// This pattern is automatically generated from aarch64_ad.m4
13274// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13275instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
13276%{
13277  match(Set dst (AddI src1 (AndI src2 mask)));
13278  ins_cost(INSN_COST);
13279  format %{ "addw  $dst, $src1, $src2, uxtb" %}
13280
13281   ins_encode %{
13282     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13283            as_Register($src2$$reg), ext::uxtb);
13284   %}
13285  ins_pipe(ialu_reg_reg);
13286%}
13287
13288// This pattern is automatically generated from aarch64_ad.m4
13289// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13290instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
13291%{
13292  match(Set dst (AddI src1 (AndI src2 mask)));
13293  ins_cost(INSN_COST);
13294  format %{ "addw  $dst, $src1, $src2, uxth" %}
13295
13296   ins_encode %{
13297     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13298            as_Register($src2$$reg), ext::uxth);
13299   %}
13300  ins_pipe(ialu_reg_reg);
13301%}
13302
13303// This pattern is automatically generated from aarch64_ad.m4
13304// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13305instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
13306%{
13307  match(Set dst (AddL src1 (AndL src2 mask)));
13308  ins_cost(INSN_COST);
13309  format %{ "add  $dst, $src1, $src2, uxtb" %}
13310
13311   ins_encode %{
13312     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13313            as_Register($src2$$reg), ext::uxtb);
13314   %}
13315  ins_pipe(ialu_reg_reg);
13316%}
13317
13318// This pattern is automatically generated from aarch64_ad.m4
13319// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13320instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
13321%{
13322  match(Set dst (AddL src1 (AndL src2 mask)));
13323  ins_cost(INSN_COST);
13324  format %{ "add  $dst, $src1, $src2, uxth" %}
13325
13326   ins_encode %{
13327     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13328            as_Register($src2$$reg), ext::uxth);
13329   %}
13330  ins_pipe(ialu_reg_reg);
13331%}
13332
13333// This pattern is automatically generated from aarch64_ad.m4
13334// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13335instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
13336%{
13337  match(Set dst (AddL src1 (AndL src2 mask)));
13338  ins_cost(INSN_COST);
13339  format %{ "add  $dst, $src1, $src2, uxtw" %}
13340
13341   ins_encode %{
13342     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13343            as_Register($src2$$reg), ext::uxtw);
13344   %}
13345  ins_pipe(ialu_reg_reg);
13346%}
13347
13348// This pattern is automatically generated from aarch64_ad.m4
13349// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13350instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr)
13351%{
13352  match(Set dst (SubI src1 (AndI src2 mask)));
13353  ins_cost(INSN_COST);
13354  format %{ "subw  $dst, $src1, $src2, uxtb" %}
13355
13356   ins_encode %{
13357     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13358            as_Register($src2$$reg), ext::uxtb);
13359   %}
13360  ins_pipe(ialu_reg_reg);
13361%}
13362
13363// This pattern is automatically generated from aarch64_ad.m4
13364// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13365instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr)
13366%{
13367  match(Set dst (SubI src1 (AndI src2 mask)));
13368  ins_cost(INSN_COST);
13369  format %{ "subw  $dst, $src1, $src2, uxth" %}
13370
13371   ins_encode %{
13372     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13373            as_Register($src2$$reg), ext::uxth);
13374   %}
13375  ins_pipe(ialu_reg_reg);
13376%}
13377
13378// This pattern is automatically generated from aarch64_ad.m4
13379// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13380instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr)
13381%{
13382  match(Set dst (SubL src1 (AndL src2 mask)));
13383  ins_cost(INSN_COST);
13384  format %{ "sub  $dst, $src1, $src2, uxtb" %}
13385
13386   ins_encode %{
13387     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13388            as_Register($src2$$reg), ext::uxtb);
13389   %}
13390  ins_pipe(ialu_reg_reg);
13391%}
13392
13393// This pattern is automatically generated from aarch64_ad.m4
13394// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13395instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr)
13396%{
13397  match(Set dst (SubL src1 (AndL src2 mask)));
13398  ins_cost(INSN_COST);
13399  format %{ "sub  $dst, $src1, $src2, uxth" %}
13400
13401   ins_encode %{
13402     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13403            as_Register($src2$$reg), ext::uxth);
13404   %}
13405  ins_pipe(ialu_reg_reg);
13406%}
13407
13408// This pattern is automatically generated from aarch64_ad.m4
13409// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13410instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr)
13411%{
13412  match(Set dst (SubL src1 (AndL src2 mask)));
13413  ins_cost(INSN_COST);
13414  format %{ "sub  $dst, $src1, $src2, uxtw" %}
13415
13416   ins_encode %{
13417     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13418            as_Register($src2$$reg), ext::uxtw);
13419   %}
13420  ins_pipe(ialu_reg_reg);
13421%}
13422
13423
13424// This pattern is automatically generated from aarch64_ad.m4
13425// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13426instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
13427%{
13428  match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13429  ins_cost(1.9 * INSN_COST);
13430  format %{ "add  $dst, $src1, $src2, sxtb #lshift2" %}
13431
13432   ins_encode %{
13433     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13434            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13435   %}
13436  ins_pipe(ialu_reg_reg_shift);
13437%}
13438
13439// This pattern is automatically generated from aarch64_ad.m4
13440// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13441instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
13442%{
13443  match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13444  ins_cost(1.9 * INSN_COST);
13445  format %{ "add  $dst, $src1, $src2, sxth #lshift2" %}
13446
13447   ins_encode %{
13448     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13449            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13450   %}
13451  ins_pipe(ialu_reg_reg_shift);
13452%}
13453
13454// This pattern is automatically generated from aarch64_ad.m4
13455// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13456instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
13457%{
13458  match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13459  ins_cost(1.9 * INSN_COST);
13460  format %{ "add  $dst, $src1, $src2, sxtw #lshift2" %}
13461
13462   ins_encode %{
13463     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13464            as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
13465   %}
13466  ins_pipe(ialu_reg_reg_shift);
13467%}
13468
13469// This pattern is automatically generated from aarch64_ad.m4
13470// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13471instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr)
13472%{
13473  match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13474  ins_cost(1.9 * INSN_COST);
13475  format %{ "sub  $dst, $src1, $src2, sxtb #lshift2" %}
13476
13477   ins_encode %{
13478     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13479            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13480   %}
13481  ins_pipe(ialu_reg_reg_shift);
13482%}
13483
13484// This pattern is automatically generated from aarch64_ad.m4
13485// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13486instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr)
13487%{
13488  match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13489  ins_cost(1.9 * INSN_COST);
13490  format %{ "sub  $dst, $src1, $src2, sxth #lshift2" %}
13491
13492   ins_encode %{
13493     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13494            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13495   %}
13496  ins_pipe(ialu_reg_reg_shift);
13497%}
13498
13499// This pattern is automatically generated from aarch64_ad.m4
13500// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13501instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr)
13502%{
13503  match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2)));
13504  ins_cost(1.9 * INSN_COST);
13505  format %{ "sub  $dst, $src1, $src2, sxtw #lshift2" %}
13506
13507   ins_encode %{
13508     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13509            as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant));
13510   %}
13511  ins_pipe(ialu_reg_reg_shift);
13512%}
13513
13514// This pattern is automatically generated from aarch64_ad.m4
13515// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13516instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
13517%{
13518  match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13519  ins_cost(1.9 * INSN_COST);
13520  format %{ "addw  $dst, $src1, $src2, sxtb #lshift2" %}
13521
13522   ins_encode %{
13523     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13524            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13525   %}
13526  ins_pipe(ialu_reg_reg_shift);
13527%}
13528
13529// This pattern is automatically generated from aarch64_ad.m4
13530// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13531instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
13532%{
13533  match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13534  ins_cost(1.9 * INSN_COST);
13535  format %{ "addw  $dst, $src1, $src2, sxth #lshift2" %}
13536
13537   ins_encode %{
13538     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13539            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13540   %}
13541  ins_pipe(ialu_reg_reg_shift);
13542%}
13543
13544// This pattern is automatically generated from aarch64_ad.m4
13545// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13546instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr)
13547%{
13548  match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13549  ins_cost(1.9 * INSN_COST);
13550  format %{ "subw  $dst, $src1, $src2, sxtb #lshift2" %}
13551
13552   ins_encode %{
13553     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13554            as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant));
13555   %}
13556  ins_pipe(ialu_reg_reg_shift);
13557%}
13558
13559// This pattern is automatically generated from aarch64_ad.m4
13560// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13561instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr)
13562%{
13563  match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2)));
13564  ins_cost(1.9 * INSN_COST);
13565  format %{ "subw  $dst, $src1, $src2, sxth #lshift2" %}
13566
13567   ins_encode %{
13568     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13569            as_Register($src2$$reg), ext::sxth, ($lshift2$$constant));
13570   %}
13571  ins_pipe(ialu_reg_reg_shift);
13572%}
13573
13574// This pattern is automatically generated from aarch64_ad.m4
13575// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13576instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
13577%{
13578  match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift)));
13579  ins_cost(1.9 * INSN_COST);
13580  format %{ "add  $dst, $src1, $src2, sxtw #lshift" %}
13581
13582   ins_encode %{
13583     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13584            as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
13585   %}
13586  ins_pipe(ialu_reg_reg_shift);
13587%}
13588
13589// This pattern is automatically generated from aarch64_ad.m4
13590// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13591instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr)
13592%{
13593  match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift)));
13594  ins_cost(1.9 * INSN_COST);
13595  format %{ "sub  $dst, $src1, $src2, sxtw #lshift" %}
13596
13597   ins_encode %{
13598     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13599            as_Register($src2$$reg), ext::sxtw, ($lshift$$constant));
13600   %}
13601  ins_pipe(ialu_reg_reg_shift);
13602%}
13603
13604// This pattern is automatically generated from aarch64_ad.m4
13605// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13606instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
13607%{
13608  match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
13609  ins_cost(1.9 * INSN_COST);
13610  format %{ "add  $dst, $src1, $src2, uxtb #lshift" %}
13611
13612   ins_encode %{
13613     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13614            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13615   %}
13616  ins_pipe(ialu_reg_reg_shift);
13617%}
13618
13619// This pattern is automatically generated from aarch64_ad.m4
13620// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13621instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
13622%{
13623  match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
13624  ins_cost(1.9 * INSN_COST);
13625  format %{ "add  $dst, $src1, $src2, uxth #lshift" %}
13626
13627   ins_encode %{
13628     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13629            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13630   %}
13631  ins_pipe(ialu_reg_reg_shift);
13632%}
13633
13634// This pattern is automatically generated from aarch64_ad.m4
13635// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13636instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
13637%{
13638  match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift)));
13639  ins_cost(1.9 * INSN_COST);
13640  format %{ "add  $dst, $src1, $src2, uxtw #lshift" %}
13641
13642   ins_encode %{
13643     __ add(as_Register($dst$$reg), as_Register($src1$$reg),
13644            as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
13645   %}
13646  ins_pipe(ialu_reg_reg_shift);
13647%}
13648
13649// This pattern is automatically generated from aarch64_ad.m4
13650// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13651instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr)
13652%{
13653  match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
13654  ins_cost(1.9 * INSN_COST);
13655  format %{ "sub  $dst, $src1, $src2, uxtb #lshift" %}
13656
13657   ins_encode %{
13658     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13659            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13660   %}
13661  ins_pipe(ialu_reg_reg_shift);
13662%}
13663
13664// This pattern is automatically generated from aarch64_ad.m4
13665// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13666instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr)
13667%{
13668  match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
13669  ins_cost(1.9 * INSN_COST);
13670  format %{ "sub  $dst, $src1, $src2, uxth #lshift" %}
13671
13672   ins_encode %{
13673     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13674            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13675   %}
13676  ins_pipe(ialu_reg_reg_shift);
13677%}
13678
13679// This pattern is automatically generated from aarch64_ad.m4
13680// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13681instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr)
13682%{
13683  match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift)));
13684  ins_cost(1.9 * INSN_COST);
13685  format %{ "sub  $dst, $src1, $src2, uxtw #lshift" %}
13686
13687   ins_encode %{
13688     __ sub(as_Register($dst$$reg), as_Register($src1$$reg),
13689            as_Register($src2$$reg), ext::uxtw, ($lshift$$constant));
13690   %}
13691  ins_pipe(ialu_reg_reg_shift);
13692%}
13693
13694// This pattern is automatically generated from aarch64_ad.m4
13695// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13696instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
13697%{
13698  match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
13699  ins_cost(1.9 * INSN_COST);
13700  format %{ "addw  $dst, $src1, $src2, uxtb #lshift" %}
13701
13702   ins_encode %{
13703     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13704            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13705   %}
13706  ins_pipe(ialu_reg_reg_shift);
13707%}
13708
13709// This pattern is automatically generated from aarch64_ad.m4
13710// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13711instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
13712%{
13713  match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift)));
13714  ins_cost(1.9 * INSN_COST);
13715  format %{ "addw  $dst, $src1, $src2, uxth #lshift" %}
13716
13717   ins_encode %{
13718     __ addw(as_Register($dst$$reg), as_Register($src1$$reg),
13719            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13720   %}
13721  ins_pipe(ialu_reg_reg_shift);
13722%}
13723
13724// This pattern is automatically generated from aarch64_ad.m4
13725// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13726instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr)
13727%{
13728  match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
13729  ins_cost(1.9 * INSN_COST);
13730  format %{ "subw  $dst, $src1, $src2, uxtb #lshift" %}
13731
13732   ins_encode %{
13733     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13734            as_Register($src2$$reg), ext::uxtb, ($lshift$$constant));
13735   %}
13736  ins_pipe(ialu_reg_reg_shift);
13737%}
13738
13739// This pattern is automatically generated from aarch64_ad.m4
13740// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
13741instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr)
13742%{
13743  match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift)));
13744  ins_cost(1.9 * INSN_COST);
13745  format %{ "subw  $dst, $src1, $src2, uxth #lshift" %}
13746
13747   ins_encode %{
13748     __ subw(as_Register($dst$$reg), as_Register($src1$$reg),
13749            as_Register($src2$$reg), ext::uxth, ($lshift$$constant));
13750   %}
13751  ins_pipe(ialu_reg_reg_shift);
13752%}
13753
13754
13755
13756// END This section of the file is automatically generated. Do not edit --------------
13757
13758
13759// ============================================================================
13760// Floating Point Arithmetic Instructions
13761
13762instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13763  match(Set dst (AddF src1 src2));
13764
13765  ins_cost(INSN_COST * 5);
13766  format %{ "fadds   $dst, $src1, $src2" %}
13767
13768  ins_encode %{
13769    __ fadds(as_FloatRegister($dst$$reg),
13770             as_FloatRegister($src1$$reg),
13771             as_FloatRegister($src2$$reg));
13772  %}
13773
13774  ins_pipe(fp_dop_reg_reg_s);
13775%}
13776
13777instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
13778  match(Set dst (AddD src1 src2));
13779
13780  ins_cost(INSN_COST * 5);
13781  format %{ "faddd   $dst, $src1, $src2" %}
13782
13783  ins_encode %{
13784    __ faddd(as_FloatRegister($dst$$reg),
13785             as_FloatRegister($src1$$reg),
13786             as_FloatRegister($src2$$reg));
13787  %}
13788
13789  ins_pipe(fp_dop_reg_reg_d);
13790%}
13791
13792instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13793  match(Set dst (SubF src1 src2));
13794
13795  ins_cost(INSN_COST * 5);
13796  format %{ "fsubs   $dst, $src1, $src2" %}
13797
13798  ins_encode %{
13799    __ fsubs(as_FloatRegister($dst$$reg),
13800             as_FloatRegister($src1$$reg),
13801             as_FloatRegister($src2$$reg));
13802  %}
13803
13804  ins_pipe(fp_dop_reg_reg_s);
13805%}
13806
13807instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
13808  match(Set dst (SubD src1 src2));
13809
13810  ins_cost(INSN_COST * 5);
13811  format %{ "fsubd   $dst, $src1, $src2" %}
13812
13813  ins_encode %{
13814    __ fsubd(as_FloatRegister($dst$$reg),
13815             as_FloatRegister($src1$$reg),
13816             as_FloatRegister($src2$$reg));
13817  %}
13818
13819  ins_pipe(fp_dop_reg_reg_d);
13820%}
13821
13822instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13823  match(Set dst (MulF src1 src2));
13824
13825  ins_cost(INSN_COST * 6);
13826  format %{ "fmuls   $dst, $src1, $src2" %}
13827
13828  ins_encode %{
13829    __ fmuls(as_FloatRegister($dst$$reg),
13830             as_FloatRegister($src1$$reg),
13831             as_FloatRegister($src2$$reg));
13832  %}
13833
13834  ins_pipe(fp_dop_reg_reg_s);
13835%}
13836
13837instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
13838  match(Set dst (MulD src1 src2));
13839
13840  ins_cost(INSN_COST * 6);
13841  format %{ "fmuld   $dst, $src1, $src2" %}
13842
13843  ins_encode %{
13844    __ fmuld(as_FloatRegister($dst$$reg),
13845             as_FloatRegister($src1$$reg),
13846             as_FloatRegister($src2$$reg));
13847  %}
13848
13849  ins_pipe(fp_dop_reg_reg_d);
13850%}
13851
13852// src1 * src2 + src3
13853instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
13854  predicate(UseFMA);
13855  match(Set dst (FmaF src3 (Binary src1 src2)));
13856
13857  format %{ "fmadds   $dst, $src1, $src2, $src3" %}
13858
13859  ins_encode %{
13860    __ fmadds(as_FloatRegister($dst$$reg),
13861             as_FloatRegister($src1$$reg),
13862             as_FloatRegister($src2$$reg),
13863             as_FloatRegister($src3$$reg));
13864  %}
13865
13866  ins_pipe(pipe_class_default);
13867%}
13868
13869// src1 * src2 + src3
13870instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
13871  predicate(UseFMA);
13872  match(Set dst (FmaD src3 (Binary src1 src2)));
13873
13874  format %{ "fmaddd   $dst, $src1, $src2, $src3" %}
13875
13876  ins_encode %{
13877    __ fmaddd(as_FloatRegister($dst$$reg),
13878             as_FloatRegister($src1$$reg),
13879             as_FloatRegister($src2$$reg),
13880             as_FloatRegister($src3$$reg));
13881  %}
13882
13883  ins_pipe(pipe_class_default);
13884%}
13885
13886// -src1 * src2 + src3
13887instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
13888  predicate(UseFMA);
13889  match(Set dst (FmaF src3 (Binary (NegF src1) src2)));
13890  match(Set dst (FmaF src3 (Binary src1 (NegF src2))));
13891
13892  format %{ "fmsubs   $dst, $src1, $src2, $src3" %}
13893
13894  ins_encode %{
13895    __ fmsubs(as_FloatRegister($dst$$reg),
13896              as_FloatRegister($src1$$reg),
13897              as_FloatRegister($src2$$reg),
13898              as_FloatRegister($src3$$reg));
13899  %}
13900
13901  ins_pipe(pipe_class_default);
13902%}
13903
13904// -src1 * src2 + src3
13905instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
13906  predicate(UseFMA);
13907  match(Set dst (FmaD src3 (Binary (NegD src1) src2)));
13908  match(Set dst (FmaD src3 (Binary src1 (NegD src2))));
13909
13910  format %{ "fmsubd   $dst, $src1, $src2, $src3" %}
13911
13912  ins_encode %{
13913    __ fmsubd(as_FloatRegister($dst$$reg),
13914              as_FloatRegister($src1$$reg),
13915              as_FloatRegister($src2$$reg),
13916              as_FloatRegister($src3$$reg));
13917  %}
13918
13919  ins_pipe(pipe_class_default);
13920%}
13921
13922// -src1 * src2 - src3
13923instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{
13924  predicate(UseFMA);
13925  match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2)));
13926  match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2))));
13927
13928  format %{ "fnmadds  $dst, $src1, $src2, $src3" %}
13929
13930  ins_encode %{
13931    __ fnmadds(as_FloatRegister($dst$$reg),
13932               as_FloatRegister($src1$$reg),
13933               as_FloatRegister($src2$$reg),
13934               as_FloatRegister($src3$$reg));
13935  %}
13936
13937  ins_pipe(pipe_class_default);
13938%}
13939
13940// -src1 * src2 - src3
13941instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{
13942  predicate(UseFMA);
13943  match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2)));
13944  match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2))));
13945
13946  format %{ "fnmaddd   $dst, $src1, $src2, $src3" %}
13947
13948  ins_encode %{
13949    __ fnmaddd(as_FloatRegister($dst$$reg),
13950               as_FloatRegister($src1$$reg),
13951               as_FloatRegister($src2$$reg),
13952               as_FloatRegister($src3$$reg));
13953  %}
13954
13955  ins_pipe(pipe_class_default);
13956%}
13957
13958// src1 * src2 - src3
13959instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{
13960  predicate(UseFMA);
13961  match(Set dst (FmaF (NegF src3) (Binary src1 src2)));
13962
13963  format %{ "fnmsubs  $dst, $src1, $src2, $src3" %}
13964
13965  ins_encode %{
13966    __ fnmsubs(as_FloatRegister($dst$$reg),
13967               as_FloatRegister($src1$$reg),
13968               as_FloatRegister($src2$$reg),
13969               as_FloatRegister($src3$$reg));
13970  %}
13971
13972  ins_pipe(pipe_class_default);
13973%}
13974
13975// src1 * src2 - src3
13976instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{
13977  predicate(UseFMA);
13978  match(Set dst (FmaD (NegD src3) (Binary src1 src2)));
13979
13980  format %{ "fnmsubd   $dst, $src1, $src2, $src3" %}
13981
13982  ins_encode %{
13983  // n.b. insn name should be fnmsubd
13984    __ fnmsub(as_FloatRegister($dst$$reg),
13985              as_FloatRegister($src1$$reg),
13986              as_FloatRegister($src2$$reg),
13987              as_FloatRegister($src3$$reg));
13988  %}
13989
13990  ins_pipe(pipe_class_default);
13991%}
13992
13993
13994// Math.max(FF)F
13995instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
13996  match(Set dst (MaxF src1 src2));
13997
13998  format %{ "fmaxs   $dst, $src1, $src2" %}
13999  ins_encode %{
14000    __ fmaxs(as_FloatRegister($dst$$reg),
14001             as_FloatRegister($src1$$reg),
14002             as_FloatRegister($src2$$reg));
14003  %}
14004
14005  ins_pipe(fp_dop_reg_reg_s);
14006%}
14007
14008// Math.min(FF)F
14009instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14010  match(Set dst (MinF src1 src2));
14011
14012  format %{ "fmins   $dst, $src1, $src2" %}
14013  ins_encode %{
14014    __ fmins(as_FloatRegister($dst$$reg),
14015             as_FloatRegister($src1$$reg),
14016             as_FloatRegister($src2$$reg));
14017  %}
14018
14019  ins_pipe(fp_dop_reg_reg_s);
14020%}
14021
14022// Math.max(DD)D
14023instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
14024  match(Set dst (MaxD src1 src2));
14025
14026  format %{ "fmaxd   $dst, $src1, $src2" %}
14027  ins_encode %{
14028    __ fmaxd(as_FloatRegister($dst$$reg),
14029             as_FloatRegister($src1$$reg),
14030             as_FloatRegister($src2$$reg));
14031  %}
14032
14033  ins_pipe(fp_dop_reg_reg_d);
14034%}
14035
14036// Math.min(DD)D
14037instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
14038  match(Set dst (MinD src1 src2));
14039
14040  format %{ "fmind   $dst, $src1, $src2" %}
14041  ins_encode %{
14042    __ fmind(as_FloatRegister($dst$$reg),
14043             as_FloatRegister($src1$$reg),
14044             as_FloatRegister($src2$$reg));
14045  %}
14046
14047  ins_pipe(fp_dop_reg_reg_d);
14048%}
14049
14050
14051instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{
14052  match(Set dst (DivF src1  src2));
14053
14054  ins_cost(INSN_COST * 18);
14055  format %{ "fdivs   $dst, $src1, $src2" %}
14056
14057  ins_encode %{
14058    __ fdivs(as_FloatRegister($dst$$reg),
14059             as_FloatRegister($src1$$reg),
14060             as_FloatRegister($src2$$reg));
14061  %}
14062
14063  ins_pipe(fp_div_s);
14064%}
14065
14066instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{
14067  match(Set dst (DivD src1  src2));
14068
14069  ins_cost(INSN_COST * 32);
14070  format %{ "fdivd   $dst, $src1, $src2" %}
14071
14072  ins_encode %{
14073    __ fdivd(as_FloatRegister($dst$$reg),
14074             as_FloatRegister($src1$$reg),
14075             as_FloatRegister($src2$$reg));
14076  %}
14077
14078  ins_pipe(fp_div_d);
14079%}
14080
14081instruct negF_reg_reg(vRegF dst, vRegF src) %{
14082  match(Set dst (NegF src));
14083
14084  ins_cost(INSN_COST * 3);
14085  format %{ "fneg   $dst, $src" %}
14086
14087  ins_encode %{
14088    __ fnegs(as_FloatRegister($dst$$reg),
14089             as_FloatRegister($src$$reg));
14090  %}
14091
14092  ins_pipe(fp_uop_s);
14093%}
14094
14095instruct negD_reg_reg(vRegD dst, vRegD src) %{
14096  match(Set dst (NegD src));
14097
14098  ins_cost(INSN_COST * 3);
14099  format %{ "fnegd   $dst, $src" %}
14100
14101  ins_encode %{
14102    __ fnegd(as_FloatRegister($dst$$reg),
14103             as_FloatRegister($src$$reg));
14104  %}
14105
14106  ins_pipe(fp_uop_d);
14107%}
14108
14109instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
14110%{
14111  match(Set dst (AbsI src));
14112
14113  effect(KILL cr);
14114  ins_cost(INSN_COST * 2);
14115  format %{ "cmpw  $src, zr\n\t"
14116            "cnegw $dst, $src, Assembler::LT\t# int abs"
14117  %}
14118
14119  ins_encode %{
14120    __ cmpw(as_Register($src$$reg), zr);
14121    __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT);
14122  %}
14123  ins_pipe(pipe_class_default);
14124%}
14125
14126instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr)
14127%{
14128  match(Set dst (AbsL src));
14129
14130  effect(KILL cr);
14131  ins_cost(INSN_COST * 2);
14132  format %{ "cmp  $src, zr\n\t"
14133            "cneg $dst, $src, Assembler::LT\t# long abs"
14134  %}
14135
14136  ins_encode %{
14137    __ cmp(as_Register($src$$reg), zr);
14138    __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT);
14139  %}
14140  ins_pipe(pipe_class_default);
14141%}
14142
14143instruct absF_reg(vRegF dst, vRegF src) %{
14144  match(Set dst (AbsF src));
14145
14146  ins_cost(INSN_COST * 3);
14147  format %{ "fabss   $dst, $src" %}
14148  ins_encode %{
14149    __ fabss(as_FloatRegister($dst$$reg),
14150             as_FloatRegister($src$$reg));
14151  %}
14152
14153  ins_pipe(fp_uop_s);
14154%}
14155
14156instruct absD_reg(vRegD dst, vRegD src) %{
14157  match(Set dst (AbsD src));
14158
14159  ins_cost(INSN_COST * 3);
14160  format %{ "fabsd   $dst, $src" %}
14161  ins_encode %{
14162    __ fabsd(as_FloatRegister($dst$$reg),
14163             as_FloatRegister($src$$reg));
14164  %}
14165
14166  ins_pipe(fp_uop_d);
14167%}
14168
14169instruct absdF_reg(vRegF dst, vRegF src1, vRegF src2) %{
14170  match(Set dst (AbsF (SubF src1 src2)));
14171
14172  ins_cost(INSN_COST * 3);
14173  format %{ "fabds   $dst, $src1, $src2" %}
14174  ins_encode %{
14175    __ fabds(as_FloatRegister($dst$$reg),
14176             as_FloatRegister($src1$$reg),
14177             as_FloatRegister($src2$$reg));
14178  %}
14179
14180  ins_pipe(fp_uop_s);
14181%}
14182
14183instruct absdD_reg(vRegD dst, vRegD src1, vRegD src2) %{
14184  match(Set dst (AbsD (SubD src1 src2)));
14185
14186  ins_cost(INSN_COST * 3);
14187  format %{ "fabdd   $dst, $src1, $src2" %}
14188  ins_encode %{
14189    __ fabdd(as_FloatRegister($dst$$reg),
14190             as_FloatRegister($src1$$reg),
14191             as_FloatRegister($src2$$reg));
14192  %}
14193
14194  ins_pipe(fp_uop_d);
14195%}
14196
14197instruct sqrtD_reg(vRegD dst, vRegD src) %{
14198  match(Set dst (SqrtD src));
14199
14200  ins_cost(INSN_COST * 50);
14201  format %{ "fsqrtd  $dst, $src" %}
14202  ins_encode %{
14203    __ fsqrtd(as_FloatRegister($dst$$reg),
14204             as_FloatRegister($src$$reg));
14205  %}
14206
14207  ins_pipe(fp_div_s);
14208%}
14209
14210instruct sqrtF_reg(vRegF dst, vRegF src) %{
14211  match(Set dst (SqrtF src));
14212
14213  ins_cost(INSN_COST * 50);
14214  format %{ "fsqrts  $dst, $src" %}
14215  ins_encode %{
14216    __ fsqrts(as_FloatRegister($dst$$reg),
14217             as_FloatRegister($src$$reg));
14218  %}
14219
14220  ins_pipe(fp_div_d);
14221%}
14222
14223// Math.rint, floor, ceil
14224instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{
14225  match(Set dst (RoundDoubleMode src rmode));
14226  format %{ "frint  $dst, $src, $rmode" %}
14227  ins_encode %{
14228    switch ($rmode$$constant) {
14229      case RoundDoubleModeNode::rmode_rint:
14230        __ frintnd(as_FloatRegister($dst$$reg),
14231                   as_FloatRegister($src$$reg));
14232        break;
14233      case RoundDoubleModeNode::rmode_floor:
14234        __ frintmd(as_FloatRegister($dst$$reg),
14235                   as_FloatRegister($src$$reg));
14236        break;
14237      case RoundDoubleModeNode::rmode_ceil:
14238        __ frintpd(as_FloatRegister($dst$$reg),
14239                   as_FloatRegister($src$$reg));
14240        break;
14241    }
14242  %}
14243  ins_pipe(fp_uop_d);
14244%}
14245
14246instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{
14247  match(Set dst (CopySignD src1 (Binary src2 zero)));
14248  effect(TEMP_DEF dst, USE src1, USE src2, USE zero);
14249  format %{ "CopySignD  $dst $src1 $src2" %}
14250  ins_encode %{
14251    FloatRegister dst = as_FloatRegister($dst$$reg),
14252                  src1 = as_FloatRegister($src1$$reg),
14253                  src2 = as_FloatRegister($src2$$reg),
14254                  zero = as_FloatRegister($zero$$reg);
14255    __ fnegd(dst, zero);
14256    __ bsl(dst, __ T8B, src2, src1);
14257  %}
14258  ins_pipe(fp_uop_d);
14259%}
14260
14261instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{
14262  match(Set dst (CopySignF src1 src2));
14263  effect(TEMP_DEF dst, USE src1, USE src2);
14264  format %{ "CopySignF  $dst $src1 $src2" %}
14265  ins_encode %{
14266    FloatRegister dst = as_FloatRegister($dst$$reg),
14267                  src1 = as_FloatRegister($src1$$reg),
14268                  src2 = as_FloatRegister($src2$$reg);
14269    __ movi(dst, __ T2S, 0x80, 24);
14270    __ bsl(dst, __ T8B, src2, src1);
14271  %}
14272  ins_pipe(fp_uop_d);
14273%}
14274
14275instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{
14276  match(Set dst (SignumD src (Binary zero one)));
14277  effect(TEMP_DEF dst, USE src, USE zero, USE one);
14278  format %{ "signumD  $dst, $src" %}
14279  ins_encode %{
14280    FloatRegister src = as_FloatRegister($src$$reg),
14281                  dst = as_FloatRegister($dst$$reg),
14282                  zero = as_FloatRegister($zero$$reg),
14283                  one = as_FloatRegister($one$$reg);
14284    __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise
14285    __ ushrd(dst, dst, 1);     // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise
14286    // Bit selection instruction gets bit from "one" for each enabled bit in
14287    // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or
14288    // NaN the whole "src" will be copied because "dst" is zero. For all other
14289    // "src" values dst is 0x7FF..F, which means only the sign bit is copied
14290    // from "src", and all other bits are copied from 1.0.
14291    __ bsl(dst, __ T8B, one, src);
14292  %}
14293  ins_pipe(fp_uop_d);
14294%}
14295
14296instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{
14297  match(Set dst (SignumF src (Binary zero one)));
14298  effect(TEMP_DEF dst, USE src, USE zero, USE one);
14299  format %{ "signumF  $dst, $src" %}
14300  ins_encode %{
14301    FloatRegister src = as_FloatRegister($src$$reg),
14302                  dst = as_FloatRegister($dst$$reg),
14303                  zero = as_FloatRegister($zero$$reg),
14304                  one = as_FloatRegister($one$$reg);
14305    __ facgts(dst, src, zero);    // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise
14306    __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise
14307    // Bit selection instruction gets bit from "one" for each enabled bit in
14308    // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or
14309    // NaN the whole "src" will be copied because "dst" is zero. For all other
14310    // "src" values dst is 0x7FF..F, which means only the sign bit is copied
14311    // from "src", and all other bits are copied from 1.0.
14312    __ bsl(dst, __ T8B, one, src);
14313  %}
14314  ins_pipe(fp_uop_d);
14315%}
14316
14317// ============================================================================
14318// Logical Instructions
14319
14320// Integer Logical Instructions
14321
14322// And Instructions
14323
14324
14325instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{
14326  match(Set dst (AndI src1 src2));
14327
14328  format %{ "andw  $dst, $src1, $src2\t# int" %}
14329
14330  ins_cost(INSN_COST);
14331  ins_encode %{
14332    __ andw(as_Register($dst$$reg),
14333            as_Register($src1$$reg),
14334            as_Register($src2$$reg));
14335  %}
14336
14337  ins_pipe(ialu_reg_reg);
14338%}
14339
14340instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{
14341  match(Set dst (AndI src1 src2));
14342
14343  format %{ "andsw  $dst, $src1, $src2\t# int" %}
14344
14345  ins_cost(INSN_COST);
14346  ins_encode %{
14347    __ andw(as_Register($dst$$reg),
14348            as_Register($src1$$reg),
14349            (uint64_t)($src2$$constant));
14350  %}
14351
14352  ins_pipe(ialu_reg_imm);
14353%}
14354
14355// Or Instructions
14356
14357instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
14358  match(Set dst (OrI src1 src2));
14359
14360  format %{ "orrw  $dst, $src1, $src2\t# int" %}
14361
14362  ins_cost(INSN_COST);
14363  ins_encode %{
14364    __ orrw(as_Register($dst$$reg),
14365            as_Register($src1$$reg),
14366            as_Register($src2$$reg));
14367  %}
14368
14369  ins_pipe(ialu_reg_reg);
14370%}
14371
14372instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
14373  match(Set dst (OrI src1 src2));
14374
14375  format %{ "orrw  $dst, $src1, $src2\t# int" %}
14376
14377  ins_cost(INSN_COST);
14378  ins_encode %{
14379    __ orrw(as_Register($dst$$reg),
14380            as_Register($src1$$reg),
14381            (uint64_t)($src2$$constant));
14382  %}
14383
14384  ins_pipe(ialu_reg_imm);
14385%}
14386
14387// Xor Instructions
14388
14389instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
14390  match(Set dst (XorI src1 src2));
14391
14392  format %{ "eorw  $dst, $src1, $src2\t# int" %}
14393
14394  ins_cost(INSN_COST);
14395  ins_encode %{
14396    __ eorw(as_Register($dst$$reg),
14397            as_Register($src1$$reg),
14398            as_Register($src2$$reg));
14399  %}
14400
14401  ins_pipe(ialu_reg_reg);
14402%}
14403
14404instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{
14405  match(Set dst (XorI src1 src2));
14406
14407  format %{ "eorw  $dst, $src1, $src2\t# int" %}
14408
14409  ins_cost(INSN_COST);
14410  ins_encode %{
14411    __ eorw(as_Register($dst$$reg),
14412            as_Register($src1$$reg),
14413            (uint64_t)($src2$$constant));
14414  %}
14415
14416  ins_pipe(ialu_reg_imm);
14417%}
14418
14419// Long Logical Instructions
14420// TODO
14421
14422instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{
14423  match(Set dst (AndL src1 src2));
14424
14425  format %{ "and  $dst, $src1, $src2\t# int" %}
14426
14427  ins_cost(INSN_COST);
14428  ins_encode %{
14429    __ andr(as_Register($dst$$reg),
14430            as_Register($src1$$reg),
14431            as_Register($src2$$reg));
14432  %}
14433
14434  ins_pipe(ialu_reg_reg);
14435%}
14436
14437instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{
14438  match(Set dst (AndL src1 src2));
14439
14440  format %{ "and  $dst, $src1, $src2\t# int" %}
14441
14442  ins_cost(INSN_COST);
14443  ins_encode %{
14444    __ andr(as_Register($dst$$reg),
14445            as_Register($src1$$reg),
14446            (uint64_t)($src2$$constant));
14447  %}
14448
14449  ins_pipe(ialu_reg_imm);
14450%}
14451
14452// Or Instructions
14453
14454instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
14455  match(Set dst (OrL src1 src2));
14456
14457  format %{ "orr  $dst, $src1, $src2\t# int" %}
14458
14459  ins_cost(INSN_COST);
14460  ins_encode %{
14461    __ orr(as_Register($dst$$reg),
14462           as_Register($src1$$reg),
14463           as_Register($src2$$reg));
14464  %}
14465
14466  ins_pipe(ialu_reg_reg);
14467%}
14468
14469instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
14470  match(Set dst (OrL src1 src2));
14471
14472  format %{ "orr  $dst, $src1, $src2\t# int" %}
14473
14474  ins_cost(INSN_COST);
14475  ins_encode %{
14476    __ orr(as_Register($dst$$reg),
14477           as_Register($src1$$reg),
14478           (uint64_t)($src2$$constant));
14479  %}
14480
14481  ins_pipe(ialu_reg_imm);
14482%}
14483
14484// Xor Instructions
14485
14486instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{
14487  match(Set dst (XorL src1 src2));
14488
14489  format %{ "eor  $dst, $src1, $src2\t# int" %}
14490
14491  ins_cost(INSN_COST);
14492  ins_encode %{
14493    __ eor(as_Register($dst$$reg),
14494           as_Register($src1$$reg),
14495           as_Register($src2$$reg));
14496  %}
14497
14498  ins_pipe(ialu_reg_reg);
14499%}
14500
14501instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{
14502  match(Set dst (XorL src1 src2));
14503
14504  ins_cost(INSN_COST);
14505  format %{ "eor  $dst, $src1, $src2\t# int" %}
14506
14507  ins_encode %{
14508    __ eor(as_Register($dst$$reg),
14509           as_Register($src1$$reg),
14510           (uint64_t)($src2$$constant));
14511  %}
14512
14513  ins_pipe(ialu_reg_imm);
14514%}
14515
14516instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
14517%{
14518  match(Set dst (ConvI2L src));
14519
14520  ins_cost(INSN_COST);
14521  format %{ "sxtw  $dst, $src\t# i2l" %}
14522  ins_encode %{
14523    __ sbfm($dst$$Register, $src$$Register, 0, 31);
14524  %}
14525  ins_pipe(ialu_reg_shift);
14526%}
14527
14528// this pattern occurs in bigmath arithmetic
14529instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask)
14530%{
14531  match(Set dst (AndL (ConvI2L src) mask));
14532
14533  ins_cost(INSN_COST);
14534  format %{ "ubfm  $dst, $src, 0, 31\t# ui2l" %}
14535  ins_encode %{
14536    __ ubfm($dst$$Register, $src$$Register, 0, 31);
14537  %}
14538
14539  ins_pipe(ialu_reg_shift);
14540%}
14541
14542instruct convL2I_reg(iRegINoSp dst, iRegL src) %{
14543  match(Set dst (ConvL2I src));
14544
14545  ins_cost(INSN_COST);
14546  format %{ "movw  $dst, $src \t// l2i" %}
14547
14548  ins_encode %{
14549    __ movw(as_Register($dst$$reg), as_Register($src$$reg));
14550  %}
14551
14552  ins_pipe(ialu_reg);
14553%}
14554
14555instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
14556%{
14557  match(Set dst (Conv2B src));
14558  effect(KILL cr);
14559
14560  format %{
14561    "cmpw $src, zr\n\t"
14562    "cset $dst, ne"
14563  %}
14564
14565  ins_encode %{
14566    __ cmpw(as_Register($src$$reg), zr);
14567    __ cset(as_Register($dst$$reg), Assembler::NE);
14568  %}
14569
14570  ins_pipe(ialu_reg);
14571%}
14572
14573instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr)
14574%{
14575  match(Set dst (Conv2B src));
14576  effect(KILL cr);
14577
14578  format %{
14579    "cmp  $src, zr\n\t"
14580    "cset $dst, ne"
14581  %}
14582
14583  ins_encode %{
14584    __ cmp(as_Register($src$$reg), zr);
14585    __ cset(as_Register($dst$$reg), Assembler::NE);
14586  %}
14587
14588  ins_pipe(ialu_reg);
14589%}
14590
14591instruct convD2F_reg(vRegF dst, vRegD src) %{
14592  match(Set dst (ConvD2F src));
14593
14594  ins_cost(INSN_COST * 5);
14595  format %{ "fcvtd  $dst, $src \t// d2f" %}
14596
14597  ins_encode %{
14598    __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
14599  %}
14600
14601  ins_pipe(fp_d2f);
14602%}
14603
14604instruct convF2D_reg(vRegD dst, vRegF src) %{
14605  match(Set dst (ConvF2D src));
14606
14607  ins_cost(INSN_COST * 5);
14608  format %{ "fcvts  $dst, $src \t// f2d" %}
14609
14610  ins_encode %{
14611    __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg));
14612  %}
14613
14614  ins_pipe(fp_f2d);
14615%}
14616
14617instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{
14618  match(Set dst (ConvF2I src));
14619
14620  ins_cost(INSN_COST * 5);
14621  format %{ "fcvtzsw  $dst, $src \t// f2i" %}
14622
14623  ins_encode %{
14624    __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14625  %}
14626
14627  ins_pipe(fp_f2i);
14628%}
14629
14630instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{
14631  match(Set dst (ConvF2L src));
14632
14633  ins_cost(INSN_COST * 5);
14634  format %{ "fcvtzs  $dst, $src \t// f2l" %}
14635
14636  ins_encode %{
14637    __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14638  %}
14639
14640  ins_pipe(fp_f2l);
14641%}
14642
14643instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{
14644  match(Set dst (ConvI2F src));
14645
14646  ins_cost(INSN_COST * 5);
14647  format %{ "scvtfws  $dst, $src \t// i2f" %}
14648
14649  ins_encode %{
14650    __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14651  %}
14652
14653  ins_pipe(fp_i2f);
14654%}
14655
14656instruct convL2F_reg_reg(vRegF dst, iRegL src) %{
14657  match(Set dst (ConvL2F src));
14658
14659  ins_cost(INSN_COST * 5);
14660  format %{ "scvtfs  $dst, $src \t// l2f" %}
14661
14662  ins_encode %{
14663    __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14664  %}
14665
14666  ins_pipe(fp_l2f);
14667%}
14668
14669instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{
14670  match(Set dst (ConvD2I src));
14671
14672  ins_cost(INSN_COST * 5);
14673  format %{ "fcvtzdw  $dst, $src \t// d2i" %}
14674
14675  ins_encode %{
14676    __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14677  %}
14678
14679  ins_pipe(fp_d2i);
14680%}
14681
14682instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
14683  match(Set dst (ConvD2L src));
14684
14685  ins_cost(INSN_COST * 5);
14686  format %{ "fcvtzd  $dst, $src \t// d2l" %}
14687
14688  ins_encode %{
14689    __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg));
14690  %}
14691
14692  ins_pipe(fp_d2l);
14693%}
14694
14695instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{
14696  match(Set dst (ConvI2D src));
14697
14698  ins_cost(INSN_COST * 5);
14699  format %{ "scvtfwd  $dst, $src \t// i2d" %}
14700
14701  ins_encode %{
14702    __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14703  %}
14704
14705  ins_pipe(fp_i2d);
14706%}
14707
14708instruct convL2D_reg_reg(vRegD dst, iRegL src) %{
14709  match(Set dst (ConvL2D src));
14710
14711  ins_cost(INSN_COST * 5);
14712  format %{ "scvtfd  $dst, $src \t// l2d" %}
14713
14714  ins_encode %{
14715    __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg));
14716  %}
14717
14718  ins_pipe(fp_l2d);
14719%}
14720
14721// stack <-> reg and reg <-> reg shuffles with no conversion
14722
14723instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{
14724
14725  match(Set dst (MoveF2I src));
14726
14727  effect(DEF dst, USE src);
14728
14729  ins_cost(4 * INSN_COST);
14730
14731  format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %}
14732
14733  ins_encode %{
14734    __ ldrw($dst$$Register, Address(sp, $src$$disp));
14735  %}
14736
14737  ins_pipe(iload_reg_reg);
14738
14739%}
14740
14741instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{
14742
14743  match(Set dst (MoveI2F src));
14744
14745  effect(DEF dst, USE src);
14746
14747  ins_cost(4 * INSN_COST);
14748
14749  format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %}
14750
14751  ins_encode %{
14752    __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
14753  %}
14754
14755  ins_pipe(pipe_class_memory);
14756
14757%}
14758
14759instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{
14760
14761  match(Set dst (MoveD2L src));
14762
14763  effect(DEF dst, USE src);
14764
14765  ins_cost(4 * INSN_COST);
14766
14767  format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %}
14768
14769  ins_encode %{
14770    __ ldr($dst$$Register, Address(sp, $src$$disp));
14771  %}
14772
14773  ins_pipe(iload_reg_reg);
14774
14775%}
14776
14777instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{
14778
14779  match(Set dst (MoveL2D src));
14780
14781  effect(DEF dst, USE src);
14782
14783  ins_cost(4 * INSN_COST);
14784
14785  format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %}
14786
14787  ins_encode %{
14788    __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp));
14789  %}
14790
14791  ins_pipe(pipe_class_memory);
14792
14793%}
14794
14795instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{
14796
14797  match(Set dst (MoveF2I src));
14798
14799  effect(DEF dst, USE src);
14800
14801  ins_cost(INSN_COST);
14802
14803  format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %}
14804
14805  ins_encode %{
14806    __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
14807  %}
14808
14809  ins_pipe(pipe_class_memory);
14810
14811%}
14812
14813instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
14814
14815  match(Set dst (MoveI2F src));
14816
14817  effect(DEF dst, USE src);
14818
14819  ins_cost(INSN_COST);
14820
14821  format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %}
14822
14823  ins_encode %{
14824    __ strw($src$$Register, Address(sp, $dst$$disp));
14825  %}
14826
14827  ins_pipe(istore_reg_reg);
14828
14829%}
14830
14831instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{
14832
14833  match(Set dst (MoveD2L src));
14834
14835  effect(DEF dst, USE src);
14836
14837  ins_cost(INSN_COST);
14838
14839  format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %}
14840
14841  ins_encode %{
14842    __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp));
14843  %}
14844
14845  ins_pipe(pipe_class_memory);
14846
14847%}
14848
14849instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
14850
14851  match(Set dst (MoveL2D src));
14852
14853  effect(DEF dst, USE src);
14854
14855  ins_cost(INSN_COST);
14856
14857  format %{ "str $src, $dst\t# MoveL2D_reg_stack" %}
14858
14859  ins_encode %{
14860    __ str($src$$Register, Address(sp, $dst$$disp));
14861  %}
14862
14863  ins_pipe(istore_reg_reg);
14864
14865%}
14866
14867instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{
14868
14869  match(Set dst (MoveF2I src));
14870
14871  effect(DEF dst, USE src);
14872
14873  ins_cost(INSN_COST);
14874
14875  format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %}
14876
14877  ins_encode %{
14878    __ fmovs($dst$$Register, as_FloatRegister($src$$reg));
14879  %}
14880
14881  ins_pipe(fp_f2i);
14882
14883%}
14884
14885instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{
14886
14887  match(Set dst (MoveI2F src));
14888
14889  effect(DEF dst, USE src);
14890
14891  ins_cost(INSN_COST);
14892
14893  format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %}
14894
14895  ins_encode %{
14896    __ fmovs(as_FloatRegister($dst$$reg), $src$$Register);
14897  %}
14898
14899  ins_pipe(fp_i2f);
14900
14901%}
14902
14903instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{
14904
14905  match(Set dst (MoveD2L src));
14906
14907  effect(DEF dst, USE src);
14908
14909  ins_cost(INSN_COST);
14910
14911  format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %}
14912
14913  ins_encode %{
14914    __ fmovd($dst$$Register, as_FloatRegister($src$$reg));
14915  %}
14916
14917  ins_pipe(fp_d2l);
14918
14919%}
14920
14921instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{
14922
14923  match(Set dst (MoveL2D src));
14924
14925  effect(DEF dst, USE src);
14926
14927  ins_cost(INSN_COST);
14928
14929  format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %}
14930
14931  ins_encode %{
14932    __ fmovd(as_FloatRegister($dst$$reg), $src$$Register);
14933  %}
14934
14935  ins_pipe(fp_l2d);
14936
14937%}
14938
14939// ============================================================================
14940// clearing of an array
14941
14942instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
14943%{
14944  match(Set dummy (ClearArray cnt base));
14945  effect(USE_KILL cnt, USE_KILL base, KILL cr);
14946
14947  ins_cost(4 * INSN_COST);
14948  format %{ "ClearArray $cnt, $base" %}
14949
14950  ins_encode %{
14951    address tpc = __ zero_words($base$$Register, $cnt$$Register);
14952    if (tpc == NULL) {
14953      ciEnv::current()->record_failure("CodeCache is full");
14954      return;
14955    }
14956  %}
14957
14958  ins_pipe(pipe_class_memory);
14959%}
14960
14961instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
14962%{
14963  predicate((uint64_t)n->in(2)->get_long()
14964            < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord));
14965  match(Set dummy (ClearArray cnt base));
14966  effect(USE_KILL base);
14967
14968  ins_cost(4 * INSN_COST);
14969  format %{ "ClearArray $cnt, $base" %}
14970
14971  ins_encode %{
14972    __ zero_words($base$$Register, (uint64_t)$cnt$$constant);
14973  %}
14974
14975  ins_pipe(pipe_class_memory);
14976%}
14977
14978// ============================================================================
14979// Overflow Math Instructions
14980
14981instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
14982%{
14983  match(Set cr (OverflowAddI op1 op2));
14984
14985  format %{ "cmnw  $op1, $op2\t# overflow check int" %}
14986  ins_cost(INSN_COST);
14987  ins_encode %{
14988    __ cmnw($op1$$Register, $op2$$Register);
14989  %}
14990
14991  ins_pipe(icmp_reg_reg);
14992%}
14993
14994instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
14995%{
14996  match(Set cr (OverflowAddI op1 op2));
14997
14998  format %{ "cmnw  $op1, $op2\t# overflow check int" %}
14999  ins_cost(INSN_COST);
15000  ins_encode %{
15001    __ cmnw($op1$$Register, $op2$$constant);
15002  %}
15003
15004  ins_pipe(icmp_reg_imm);
15005%}
15006
15007instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15008%{
15009  match(Set cr (OverflowAddL op1 op2));
15010
15011  format %{ "cmn   $op1, $op2\t# overflow check long" %}
15012  ins_cost(INSN_COST);
15013  ins_encode %{
15014    __ cmn($op1$$Register, $op2$$Register);
15015  %}
15016
15017  ins_pipe(icmp_reg_reg);
15018%}
15019
15020instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
15021%{
15022  match(Set cr (OverflowAddL op1 op2));
15023
15024  format %{ "cmn   $op1, $op2\t# overflow check long" %}
15025  ins_cost(INSN_COST);
15026  ins_encode %{
15027    __ cmn($op1$$Register, $op2$$constant);
15028  %}
15029
15030  ins_pipe(icmp_reg_imm);
15031%}
15032
15033instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
15034%{
15035  match(Set cr (OverflowSubI op1 op2));
15036
15037  format %{ "cmpw  $op1, $op2\t# overflow check int" %}
15038  ins_cost(INSN_COST);
15039  ins_encode %{
15040    __ cmpw($op1$$Register, $op2$$Register);
15041  %}
15042
15043  ins_pipe(icmp_reg_reg);
15044%}
15045
15046instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2)
15047%{
15048  match(Set cr (OverflowSubI op1 op2));
15049
15050  format %{ "cmpw  $op1, $op2\t# overflow check int" %}
15051  ins_cost(INSN_COST);
15052  ins_encode %{
15053    __ cmpw($op1$$Register, $op2$$constant);
15054  %}
15055
15056  ins_pipe(icmp_reg_imm);
15057%}
15058
15059instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15060%{
15061  match(Set cr (OverflowSubL op1 op2));
15062
15063  format %{ "cmp   $op1, $op2\t# overflow check long" %}
15064  ins_cost(INSN_COST);
15065  ins_encode %{
15066    __ cmp($op1$$Register, $op2$$Register);
15067  %}
15068
15069  ins_pipe(icmp_reg_reg);
15070%}
15071
15072instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2)
15073%{
15074  match(Set cr (OverflowSubL op1 op2));
15075
15076  format %{ "cmp   $op1, $op2\t# overflow check long" %}
15077  ins_cost(INSN_COST);
15078  ins_encode %{
15079    __ subs(zr, $op1$$Register, $op2$$constant);
15080  %}
15081
15082  ins_pipe(icmp_reg_imm);
15083%}
15084
15085instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1)
15086%{
15087  match(Set cr (OverflowSubI zero op1));
15088
15089  format %{ "cmpw  zr, $op1\t# overflow check int" %}
15090  ins_cost(INSN_COST);
15091  ins_encode %{
15092    __ cmpw(zr, $op1$$Register);
15093  %}
15094
15095  ins_pipe(icmp_reg_imm);
15096%}
15097
15098instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1)
15099%{
15100  match(Set cr (OverflowSubL zero op1));
15101
15102  format %{ "cmp   zr, $op1\t# overflow check long" %}
15103  ins_cost(INSN_COST);
15104  ins_encode %{
15105    __ cmp(zr, $op1$$Register);
15106  %}
15107
15108  ins_pipe(icmp_reg_imm);
15109%}
15110
15111instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
15112%{
15113  match(Set cr (OverflowMulI op1 op2));
15114
15115  format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
15116            "cmp   rscratch1, rscratch1, sxtw\n\t"
15117            "movw  rscratch1, #0x80000000\n\t"
15118            "cselw rscratch1, rscratch1, zr, NE\n\t"
15119            "cmpw  rscratch1, #1" %}
15120  ins_cost(5 * INSN_COST);
15121  ins_encode %{
15122    __ smull(rscratch1, $op1$$Register, $op2$$Register);
15123    __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
15124    __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
15125    __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
15126    __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
15127  %}
15128
15129  ins_pipe(pipe_slow);
15130%}
15131
15132instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr)
15133%{
15134  match(If cmp (OverflowMulI op1 op2));
15135  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
15136            || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
15137  effect(USE labl, KILL cr);
15138
15139  format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t"
15140            "cmp   rscratch1, rscratch1, sxtw\n\t"
15141            "b$cmp   $labl" %}
15142  ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST
15143  ins_encode %{
15144    Label* L = $labl$$label;
15145    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15146    __ smull(rscratch1, $op1$$Register, $op2$$Register);
15147    __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
15148    __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
15149  %}
15150
15151  ins_pipe(pipe_serial);
15152%}
15153
15154instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15155%{
15156  match(Set cr (OverflowMulL op1 op2));
15157
15158  format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
15159            "smulh rscratch2, $op1, $op2\n\t"
15160            "cmp   rscratch2, rscratch1, ASR #63\n\t"
15161            "movw  rscratch1, #0x80000000\n\t"
15162            "cselw rscratch1, rscratch1, zr, NE\n\t"
15163            "cmpw  rscratch1, #1" %}
15164  ins_cost(6 * INSN_COST);
15165  ins_encode %{
15166    __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
15167    __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
15168    __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
15169    __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
15170    __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
15171    __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
15172  %}
15173
15174  ins_pipe(pipe_slow);
15175%}
15176
15177instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr)
15178%{
15179  match(If cmp (OverflowMulL op1 op2));
15180  predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
15181            || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
15182  effect(USE labl, KILL cr);
15183
15184  format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
15185            "smulh rscratch2, $op1, $op2\n\t"
15186            "cmp   rscratch2, rscratch1, ASR #63\n\t"
15187            "b$cmp $labl" %}
15188  ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
15189  ins_encode %{
15190    Label* L = $labl$$label;
15191    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15192    __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
15193    __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
15194    __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
15195    __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
15196  %}
15197
15198  ins_pipe(pipe_serial);
15199%}
15200
15201// ============================================================================
15202// Compare Instructions
15203
15204instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
15205%{
15206  match(Set cr (CmpI op1 op2));
15207
15208  effect(DEF cr, USE op1, USE op2);
15209
15210  ins_cost(INSN_COST);
15211  format %{ "cmpw  $op1, $op2" %}
15212
15213  ins_encode(aarch64_enc_cmpw(op1, op2));
15214
15215  ins_pipe(icmp_reg_reg);
15216%}
15217
15218instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero)
15219%{
15220  match(Set cr (CmpI op1 zero));
15221
15222  effect(DEF cr, USE op1);
15223
15224  ins_cost(INSN_COST);
15225  format %{ "cmpw $op1, 0" %}
15226
15227  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
15228
15229  ins_pipe(icmp_reg_imm);
15230%}
15231
15232instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2)
15233%{
15234  match(Set cr (CmpI op1 op2));
15235
15236  effect(DEF cr, USE op1);
15237
15238  ins_cost(INSN_COST);
15239  format %{ "cmpw  $op1, $op2" %}
15240
15241  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
15242
15243  ins_pipe(icmp_reg_imm);
15244%}
15245
15246instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2)
15247%{
15248  match(Set cr (CmpI op1 op2));
15249
15250  effect(DEF cr, USE op1);
15251
15252  ins_cost(INSN_COST * 2);
15253  format %{ "cmpw  $op1, $op2" %}
15254
15255  ins_encode(aarch64_enc_cmpw_imm(op1, op2));
15256
15257  ins_pipe(icmp_reg_imm);
15258%}
15259
15260// Unsigned compare Instructions; really, same as signed compare
15261// except it should only be used to feed an If or a CMovI which takes a
15262// cmpOpU.
15263
15264instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2)
15265%{
15266  match(Set cr (CmpU op1 op2));
15267
15268  effect(DEF cr, USE op1, USE op2);
15269
15270  ins_cost(INSN_COST);
15271  format %{ "cmpw  $op1, $op2\t# unsigned" %}
15272
15273  ins_encode(aarch64_enc_cmpw(op1, op2));
15274
15275  ins_pipe(icmp_reg_reg);
15276%}
15277
15278instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero)
15279%{
15280  match(Set cr (CmpU op1 zero));
15281
15282  effect(DEF cr, USE op1);
15283
15284  ins_cost(INSN_COST);
15285  format %{ "cmpw $op1, #0\t# unsigned" %}
15286
15287  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero));
15288
15289  ins_pipe(icmp_reg_imm);
15290%}
15291
15292instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2)
15293%{
15294  match(Set cr (CmpU op1 op2));
15295
15296  effect(DEF cr, USE op1);
15297
15298  ins_cost(INSN_COST);
15299  format %{ "cmpw  $op1, $op2\t# unsigned" %}
15300
15301  ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2));
15302
15303  ins_pipe(icmp_reg_imm);
15304%}
15305
15306instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2)
15307%{
15308  match(Set cr (CmpU op1 op2));
15309
15310  effect(DEF cr, USE op1);
15311
15312  ins_cost(INSN_COST * 2);
15313  format %{ "cmpw  $op1, $op2\t# unsigned" %}
15314
15315  ins_encode(aarch64_enc_cmpw_imm(op1, op2));
15316
15317  ins_pipe(icmp_reg_imm);
15318%}
15319
15320instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2)
15321%{
15322  match(Set cr (CmpL op1 op2));
15323
15324  effect(DEF cr, USE op1, USE op2);
15325
15326  ins_cost(INSN_COST);
15327  format %{ "cmp  $op1, $op2" %}
15328
15329  ins_encode(aarch64_enc_cmp(op1, op2));
15330
15331  ins_pipe(icmp_reg_reg);
15332%}
15333
15334instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero)
15335%{
15336  match(Set cr (CmpL op1 zero));
15337
15338  effect(DEF cr, USE op1);
15339
15340  ins_cost(INSN_COST);
15341  format %{ "tst  $op1" %}
15342
15343  ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
15344
15345  ins_pipe(icmp_reg_imm);
15346%}
15347
15348instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2)
15349%{
15350  match(Set cr (CmpL op1 op2));
15351
15352  effect(DEF cr, USE op1);
15353
15354  ins_cost(INSN_COST);
15355  format %{ "cmp  $op1, $op2" %}
15356
15357  ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
15358
15359  ins_pipe(icmp_reg_imm);
15360%}
15361
15362instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2)
15363%{
15364  match(Set cr (CmpL op1 op2));
15365
15366  effect(DEF cr, USE op1);
15367
15368  ins_cost(INSN_COST * 2);
15369  format %{ "cmp  $op1, $op2" %}
15370
15371  ins_encode(aarch64_enc_cmp_imm(op1, op2));
15372
15373  ins_pipe(icmp_reg_imm);
15374%}
15375
15376instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2)
15377%{
15378  match(Set cr (CmpUL op1 op2));
15379
15380  effect(DEF cr, USE op1, USE op2);
15381
15382  ins_cost(INSN_COST);
15383  format %{ "cmp  $op1, $op2" %}
15384
15385  ins_encode(aarch64_enc_cmp(op1, op2));
15386
15387  ins_pipe(icmp_reg_reg);
15388%}
15389
15390instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero)
15391%{
15392  match(Set cr (CmpUL op1 zero));
15393
15394  effect(DEF cr, USE op1);
15395
15396  ins_cost(INSN_COST);
15397  format %{ "tst  $op1" %}
15398
15399  ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero));
15400
15401  ins_pipe(icmp_reg_imm);
15402%}
15403
15404instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2)
15405%{
15406  match(Set cr (CmpUL op1 op2));
15407
15408  effect(DEF cr, USE op1);
15409
15410  ins_cost(INSN_COST);
15411  format %{ "cmp  $op1, $op2" %}
15412
15413  ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2));
15414
15415  ins_pipe(icmp_reg_imm);
15416%}
15417
15418instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2)
15419%{
15420  match(Set cr (CmpUL op1 op2));
15421
15422  effect(DEF cr, USE op1);
15423
15424  ins_cost(INSN_COST * 2);
15425  format %{ "cmp  $op1, $op2" %}
15426
15427  ins_encode(aarch64_enc_cmp_imm(op1, op2));
15428
15429  ins_pipe(icmp_reg_imm);
15430%}
15431
15432instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2)
15433%{
15434  match(Set cr (CmpP op1 op2));
15435
15436  effect(DEF cr, USE op1, USE op2);
15437
15438  ins_cost(INSN_COST);
15439  format %{ "cmp  $op1, $op2\t // ptr" %}
15440
15441  ins_encode(aarch64_enc_cmpp(op1, op2));
15442
15443  ins_pipe(icmp_reg_reg);
15444%}
15445
15446instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2)
15447%{
15448  match(Set cr (CmpN op1 op2));
15449
15450  effect(DEF cr, USE op1, USE op2);
15451
15452  ins_cost(INSN_COST);
15453  format %{ "cmp  $op1, $op2\t // compressed ptr" %}
15454
15455  ins_encode(aarch64_enc_cmpn(op1, op2));
15456
15457  ins_pipe(icmp_reg_reg);
15458%}
15459
15460instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero)
15461%{
15462  match(Set cr (CmpP op1 zero));
15463
15464  effect(DEF cr, USE op1, USE zero);
15465
15466  ins_cost(INSN_COST);
15467  format %{ "cmp  $op1, 0\t // ptr" %}
15468
15469  ins_encode(aarch64_enc_testp(op1));
15470
15471  ins_pipe(icmp_reg_imm);
15472%}
15473
15474instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero)
15475%{
15476  match(Set cr (CmpN op1 zero));
15477
15478  effect(DEF cr, USE op1, USE zero);
15479
15480  ins_cost(INSN_COST);
15481  format %{ "cmp  $op1, 0\t // compressed ptr" %}
15482
15483  ins_encode(aarch64_enc_testn(op1));
15484
15485  ins_pipe(icmp_reg_imm);
15486%}
15487
15488// FP comparisons
15489//
15490// n.b. CmpF/CmpD set a normal flags reg which then gets compared
15491// using normal cmpOp. See declaration of rFlagsReg for details.
15492
15493instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2)
15494%{
15495  match(Set cr (CmpF src1 src2));
15496
15497  ins_cost(3 * INSN_COST);
15498  format %{ "fcmps $src1, $src2" %}
15499
15500  ins_encode %{
15501    __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15502  %}
15503
15504  ins_pipe(pipe_class_compare);
15505%}
15506
15507instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2)
15508%{
15509  match(Set cr (CmpF src1 src2));
15510
15511  ins_cost(3 * INSN_COST);
15512  format %{ "fcmps $src1, 0.0" %}
15513
15514  ins_encode %{
15515    __ fcmps(as_FloatRegister($src1$$reg), 0.0);
15516  %}
15517
15518  ins_pipe(pipe_class_compare);
15519%}
15520// FROM HERE
15521
15522instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2)
15523%{
15524  match(Set cr (CmpD src1 src2));
15525
15526  ins_cost(3 * INSN_COST);
15527  format %{ "fcmpd $src1, $src2" %}
15528
15529  ins_encode %{
15530    __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg));
15531  %}
15532
15533  ins_pipe(pipe_class_compare);
15534%}
15535
15536instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2)
15537%{
15538  match(Set cr (CmpD src1 src2));
15539
15540  ins_cost(3 * INSN_COST);
15541  format %{ "fcmpd $src1, 0.0" %}
15542
15543  ins_encode %{
15544    __ fcmpd(as_FloatRegister($src1$$reg), 0.0);
15545  %}
15546
15547  ins_pipe(pipe_class_compare);
15548%}
15549
15550instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr)
15551%{
15552  match(Set dst (CmpF3 src1 src2));
15553  effect(KILL cr);
15554
15555  ins_cost(5 * INSN_COST);
15556  format %{ "fcmps $src1, $src2\n\t"
15557            "csinvw($dst, zr, zr, eq\n\t"
15558            "csnegw($dst, $dst, $dst, lt)"
15559  %}
15560
15561  ins_encode %{
15562    Label done;
15563    FloatRegister s1 = as_FloatRegister($src1$$reg);
15564    FloatRegister s2 = as_FloatRegister($src2$$reg);
15565    Register d = as_Register($dst$$reg);
15566    __ fcmps(s1, s2);
15567    // installs 0 if EQ else -1
15568    __ csinvw(d, zr, zr, Assembler::EQ);
15569    // keeps -1 if less or unordered else installs 1
15570    __ csnegw(d, d, d, Assembler::LT);
15571    __ bind(done);
15572  %}
15573
15574  ins_pipe(pipe_class_default);
15575
15576%}
15577
15578instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr)
15579%{
15580  match(Set dst (CmpD3 src1 src2));
15581  effect(KILL cr);
15582
15583  ins_cost(5 * INSN_COST);
15584  format %{ "fcmpd $src1, $src2\n\t"
15585            "csinvw($dst, zr, zr, eq\n\t"
15586            "csnegw($dst, $dst, $dst, lt)"
15587  %}
15588
15589  ins_encode %{
15590    Label done;
15591    FloatRegister s1 = as_FloatRegister($src1$$reg);
15592    FloatRegister s2 = as_FloatRegister($src2$$reg);
15593    Register d = as_Register($dst$$reg);
15594    __ fcmpd(s1, s2);
15595    // installs 0 if EQ else -1
15596    __ csinvw(d, zr, zr, Assembler::EQ);
15597    // keeps -1 if less or unordered else installs 1
15598    __ csnegw(d, d, d, Assembler::LT);
15599    __ bind(done);
15600  %}
15601  ins_pipe(pipe_class_default);
15602
15603%}
15604
15605instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr)
15606%{
15607  match(Set dst (CmpF3 src1 zero));
15608  effect(KILL cr);
15609
15610  ins_cost(5 * INSN_COST);
15611  format %{ "fcmps $src1, 0.0\n\t"
15612            "csinvw($dst, zr, zr, eq\n\t"
15613            "csnegw($dst, $dst, $dst, lt)"
15614  %}
15615
15616  ins_encode %{
15617    Label done;
15618    FloatRegister s1 = as_FloatRegister($src1$$reg);
15619    Register d = as_Register($dst$$reg);
15620    __ fcmps(s1, 0.0);
15621    // installs 0 if EQ else -1
15622    __ csinvw(d, zr, zr, Assembler::EQ);
15623    // keeps -1 if less or unordered else installs 1
15624    __ csnegw(d, d, d, Assembler::LT);
15625    __ bind(done);
15626  %}
15627
15628  ins_pipe(pipe_class_default);
15629
15630%}
15631
15632instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr)
15633%{
15634  match(Set dst (CmpD3 src1 zero));
15635  effect(KILL cr);
15636
15637  ins_cost(5 * INSN_COST);
15638  format %{ "fcmpd $src1, 0.0\n\t"
15639            "csinvw($dst, zr, zr, eq\n\t"
15640            "csnegw($dst, $dst, $dst, lt)"
15641  %}
15642
15643  ins_encode %{
15644    Label done;
15645    FloatRegister s1 = as_FloatRegister($src1$$reg);
15646    Register d = as_Register($dst$$reg);
15647    __ fcmpd(s1, 0.0);
15648    // installs 0 if EQ else -1
15649    __ csinvw(d, zr, zr, Assembler::EQ);
15650    // keeps -1 if less or unordered else installs 1
15651    __ csnegw(d, d, d, Assembler::LT);
15652    __ bind(done);
15653  %}
15654  ins_pipe(pipe_class_default);
15655
15656%}
15657
15658instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr)
15659%{
15660  match(Set dst (CmpLTMask p q));
15661  effect(KILL cr);
15662
15663  ins_cost(3 * INSN_COST);
15664
15665  format %{ "cmpw $p, $q\t# cmpLTMask\n\t"
15666            "csetw $dst, lt\n\t"
15667            "subw $dst, zr, $dst"
15668  %}
15669
15670  ins_encode %{
15671    __ cmpw(as_Register($p$$reg), as_Register($q$$reg));
15672    __ csetw(as_Register($dst$$reg), Assembler::LT);
15673    __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg));
15674  %}
15675
15676  ins_pipe(ialu_reg_reg);
15677%}
15678
15679instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr)
15680%{
15681  match(Set dst (CmpLTMask src zero));
15682  effect(KILL cr);
15683
15684  ins_cost(INSN_COST);
15685
15686  format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %}
15687
15688  ins_encode %{
15689    __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31);
15690  %}
15691
15692  ins_pipe(ialu_reg_shift);
15693%}
15694
15695// ============================================================================
15696// Max and Min
15697
15698instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
15699%{
15700  effect( DEF dst, USE src1, USE src2, USE cr );
15701
15702  ins_cost(INSN_COST * 2);
15703  format %{ "cselw $dst, $src1, $src2 lt\t"  %}
15704
15705  ins_encode %{
15706    __ cselw(as_Register($dst$$reg),
15707             as_Register($src1$$reg),
15708             as_Register($src2$$reg),
15709             Assembler::LT);
15710  %}
15711
15712  ins_pipe(icond_reg_reg);
15713%}
15714
15715instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2)
15716%{
15717  match(Set dst (MinI src1 src2));
15718  ins_cost(INSN_COST * 3);
15719
15720  expand %{
15721    rFlagsReg cr;
15722    compI_reg_reg(cr, src1, src2);
15723    cmovI_reg_reg_lt(dst, src1, src2, cr);
15724  %}
15725
15726%}
15727// FROM HERE
15728
15729instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr)
15730%{
15731  effect( DEF dst, USE src1, USE src2, USE cr );
15732
15733  ins_cost(INSN_COST * 2);
15734  format %{ "cselw $dst, $src1, $src2 gt\t"  %}
15735
15736  ins_encode %{
15737    __ cselw(as_Register($dst$$reg),
15738             as_Register($src1$$reg),
15739             as_Register($src2$$reg),
15740             Assembler::GT);
15741  %}
15742
15743  ins_pipe(icond_reg_reg);
15744%}
15745
15746instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2)
15747%{
15748  match(Set dst (MaxI src1 src2));
15749  ins_cost(INSN_COST * 3);
15750  expand %{
15751    rFlagsReg cr;
15752    compI_reg_reg(cr, src1, src2);
15753    cmovI_reg_reg_gt(dst, src1, src2, cr);
15754  %}
15755%}
15756
15757// ============================================================================
15758// Branch Instructions
15759
15760// Direct Branch.
15761instruct branch(label lbl)
15762%{
15763  match(Goto);
15764
15765  effect(USE lbl);
15766
15767  ins_cost(BRANCH_COST);
15768  format %{ "b  $lbl" %}
15769
15770  ins_encode(aarch64_enc_b(lbl));
15771
15772  ins_pipe(pipe_branch);
15773%}
15774
15775// Conditional Near Branch
15776instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl)
15777%{
15778  // Same match rule as `branchConFar'.
15779  match(If cmp cr);
15780
15781  effect(USE lbl);
15782
15783  ins_cost(BRANCH_COST);
15784  // If set to 1 this indicates that the current instruction is a
15785  // short variant of a long branch. This avoids using this
15786  // instruction in first-pass matching. It will then only be used in
15787  // the `Shorten_branches' pass.
15788  // ins_short_branch(1);
15789  format %{ "b$cmp  $lbl" %}
15790
15791  ins_encode(aarch64_enc_br_con(cmp, lbl));
15792
15793  ins_pipe(pipe_branch_cond);
15794%}
15795
15796// Conditional Near Branch Unsigned
15797instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl)
15798%{
15799  // Same match rule as `branchConFar'.
15800  match(If cmp cr);
15801
15802  effect(USE lbl);
15803
15804  ins_cost(BRANCH_COST);
15805  // If set to 1 this indicates that the current instruction is a
15806  // short variant of a long branch. This avoids using this
15807  // instruction in first-pass matching. It will then only be used in
15808  // the `Shorten_branches' pass.
15809  // ins_short_branch(1);
15810  format %{ "b$cmp  $lbl\t# unsigned" %}
15811
15812  ins_encode(aarch64_enc_br_conU(cmp, lbl));
15813
15814  ins_pipe(pipe_branch_cond);
15815%}
15816
15817// Make use of CBZ and CBNZ.  These instructions, as well as being
15818// shorter than (cmp; branch), have the additional benefit of not
15819// killing the flags.
15820
15821instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
15822  match(If cmp (CmpI op1 op2));
15823  effect(USE labl);
15824
15825  ins_cost(BRANCH_COST);
15826  format %{ "cbw$cmp   $op1, $labl" %}
15827  ins_encode %{
15828    Label* L = $labl$$label;
15829    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15830    if (cond == Assembler::EQ)
15831      __ cbzw($op1$$Register, *L);
15832    else
15833      __ cbnzw($op1$$Register, *L);
15834  %}
15835  ins_pipe(pipe_cmp_branch);
15836%}
15837
15838instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{
15839  match(If cmp (CmpL op1 op2));
15840  effect(USE labl);
15841
15842  ins_cost(BRANCH_COST);
15843  format %{ "cb$cmp   $op1, $labl" %}
15844  ins_encode %{
15845    Label* L = $labl$$label;
15846    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15847    if (cond == Assembler::EQ)
15848      __ cbz($op1$$Register, *L);
15849    else
15850      __ cbnz($op1$$Register, *L);
15851  %}
15852  ins_pipe(pipe_cmp_branch);
15853%}
15854
15855instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{
15856  match(If cmp (CmpP op1 op2));
15857  effect(USE labl);
15858
15859  ins_cost(BRANCH_COST);
15860  format %{ "cb$cmp   $op1, $labl" %}
15861  ins_encode %{
15862    Label* L = $labl$$label;
15863    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15864    if (cond == Assembler::EQ)
15865      __ cbz($op1$$Register, *L);
15866    else
15867      __ cbnz($op1$$Register, *L);
15868  %}
15869  ins_pipe(pipe_cmp_branch);
15870%}
15871
15872instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{
15873  match(If cmp (CmpN op1 op2));
15874  effect(USE labl);
15875
15876  ins_cost(BRANCH_COST);
15877  format %{ "cbw$cmp   $op1, $labl" %}
15878  ins_encode %{
15879    Label* L = $labl$$label;
15880    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15881    if (cond == Assembler::EQ)
15882      __ cbzw($op1$$Register, *L);
15883    else
15884      __ cbnzw($op1$$Register, *L);
15885  %}
15886  ins_pipe(pipe_cmp_branch);
15887%}
15888
15889instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{
15890  match(If cmp (CmpP (DecodeN oop) zero));
15891  effect(USE labl);
15892
15893  ins_cost(BRANCH_COST);
15894  format %{ "cb$cmp   $oop, $labl" %}
15895  ins_encode %{
15896    Label* L = $labl$$label;
15897    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15898    if (cond == Assembler::EQ)
15899      __ cbzw($oop$$Register, *L);
15900    else
15901      __ cbnzw($oop$$Register, *L);
15902  %}
15903  ins_pipe(pipe_cmp_branch);
15904%}
15905
15906instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{
15907  match(If cmp (CmpU op1 op2));
15908  effect(USE labl);
15909
15910  ins_cost(BRANCH_COST);
15911  format %{ "cbw$cmp   $op1, $labl" %}
15912  ins_encode %{
15913    Label* L = $labl$$label;
15914    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15915    if (cond == Assembler::EQ || cond == Assembler::LS)
15916      __ cbzw($op1$$Register, *L);
15917    else
15918      __ cbnzw($op1$$Register, *L);
15919  %}
15920  ins_pipe(pipe_cmp_branch);
15921%}
15922
15923instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{
15924  match(If cmp (CmpUL op1 op2));
15925  effect(USE labl);
15926
15927  ins_cost(BRANCH_COST);
15928  format %{ "cb$cmp   $op1, $labl" %}
15929  ins_encode %{
15930    Label* L = $labl$$label;
15931    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15932    if (cond == Assembler::EQ || cond == Assembler::LS)
15933      __ cbz($op1$$Register, *L);
15934    else
15935      __ cbnz($op1$$Register, *L);
15936  %}
15937  ins_pipe(pipe_cmp_branch);
15938%}
15939
15940// Test bit and Branch
15941
15942// Patterns for short (< 32KiB) variants
15943instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
15944  match(If cmp (CmpL op1 op2));
15945  effect(USE labl);
15946
15947  ins_cost(BRANCH_COST);
15948  format %{ "cb$cmp   $op1, $labl # long" %}
15949  ins_encode %{
15950    Label* L = $labl$$label;
15951    Assembler::Condition cond =
15952      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
15953    __ tbr(cond, $op1$$Register, 63, *L);
15954  %}
15955  ins_pipe(pipe_cmp_branch);
15956  ins_short_branch(1);
15957%}
15958
15959instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
15960  match(If cmp (CmpI op1 op2));
15961  effect(USE labl);
15962
15963  ins_cost(BRANCH_COST);
15964  format %{ "cb$cmp   $op1, $labl # int" %}
15965  ins_encode %{
15966    Label* L = $labl$$label;
15967    Assembler::Condition cond =
15968      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
15969    __ tbr(cond, $op1$$Register, 31, *L);
15970  %}
15971  ins_pipe(pipe_cmp_branch);
15972  ins_short_branch(1);
15973%}
15974
15975instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
15976  match(If cmp (CmpL (AndL op1 op2) op3));
15977  predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long()));
15978  effect(USE labl);
15979
15980  ins_cost(BRANCH_COST);
15981  format %{ "tb$cmp   $op1, $op2, $labl" %}
15982  ins_encode %{
15983    Label* L = $labl$$label;
15984    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
15985    int bit = exact_log2_long($op2$$constant);
15986    __ tbr(cond, $op1$$Register, bit, *L);
15987  %}
15988  ins_pipe(pipe_cmp_branch);
15989  ins_short_branch(1);
15990%}
15991
15992instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
15993  match(If cmp (CmpI (AndI op1 op2) op3));
15994  predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int()));
15995  effect(USE labl);
15996
15997  ins_cost(BRANCH_COST);
15998  format %{ "tb$cmp   $op1, $op2, $labl" %}
15999  ins_encode %{
16000    Label* L = $labl$$label;
16001    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16002    int bit = exact_log2((juint)$op2$$constant);
16003    __ tbr(cond, $op1$$Register, bit, *L);
16004  %}
16005  ins_pipe(pipe_cmp_branch);
16006  ins_short_branch(1);
16007%}
16008
16009// And far variants
16010instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{
16011  match(If cmp (CmpL op1 op2));
16012  effect(USE labl);
16013
16014  ins_cost(BRANCH_COST);
16015  format %{ "cb$cmp   $op1, $labl # long" %}
16016  ins_encode %{
16017    Label* L = $labl$$label;
16018    Assembler::Condition cond =
16019      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16020    __ tbr(cond, $op1$$Register, 63, *L, /*far*/true);
16021  %}
16022  ins_pipe(pipe_cmp_branch);
16023%}
16024
16025instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{
16026  match(If cmp (CmpI op1 op2));
16027  effect(USE labl);
16028
16029  ins_cost(BRANCH_COST);
16030  format %{ "cb$cmp   $op1, $labl # int" %}
16031  ins_encode %{
16032    Label* L = $labl$$label;
16033    Assembler::Condition cond =
16034      ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ;
16035    __ tbr(cond, $op1$$Register, 31, *L, /*far*/true);
16036  %}
16037  ins_pipe(pipe_cmp_branch);
16038%}
16039
16040instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{
16041  match(If cmp (CmpL (AndL op1 op2) op3));
16042  predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long()));
16043  effect(USE labl);
16044
16045  ins_cost(BRANCH_COST);
16046  format %{ "tb$cmp   $op1, $op2, $labl" %}
16047  ins_encode %{
16048    Label* L = $labl$$label;
16049    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16050    int bit = exact_log2_long($op2$$constant);
16051    __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
16052  %}
16053  ins_pipe(pipe_cmp_branch);
16054%}
16055
16056instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{
16057  match(If cmp (CmpI (AndI op1 op2) op3));
16058  predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int()));
16059  effect(USE labl);
16060
16061  ins_cost(BRANCH_COST);
16062  format %{ "tb$cmp   $op1, $op2, $labl" %}
16063  ins_encode %{
16064    Label* L = $labl$$label;
16065    Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
16066    int bit = exact_log2((juint)$op2$$constant);
16067    __ tbr(cond, $op1$$Register, bit, *L, /*far*/true);
16068  %}
16069  ins_pipe(pipe_cmp_branch);
16070%}
16071
16072// Test bits
16073
16074instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{
16075  match(Set cr (CmpL (AndL op1 op2) op3));
16076  predicate(Assembler::operand_valid_for_logical_immediate
16077            (/*is_32*/false, n->in(1)->in(2)->get_long()));
16078
16079  ins_cost(INSN_COST);
16080  format %{ "tst $op1, $op2 # long" %}
16081  ins_encode %{
16082    __ tst($op1$$Register, $op2$$constant);
16083  %}
16084  ins_pipe(ialu_reg_reg);
16085%}
16086
16087instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{
16088  match(Set cr (CmpI (AndI op1 op2) op3));
16089  predicate(Assembler::operand_valid_for_logical_immediate
16090            (/*is_32*/true, n->in(1)->in(2)->get_int()));
16091
16092  ins_cost(INSN_COST);
16093  format %{ "tst $op1, $op2 # int" %}
16094  ins_encode %{
16095    __ tstw($op1$$Register, $op2$$constant);
16096  %}
16097  ins_pipe(ialu_reg_reg);
16098%}
16099
16100instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{
16101  match(Set cr (CmpL (AndL op1 op2) op3));
16102
16103  ins_cost(INSN_COST);
16104  format %{ "tst $op1, $op2 # long" %}
16105  ins_encode %{
16106    __ tst($op1$$Register, $op2$$Register);
16107  %}
16108  ins_pipe(ialu_reg_reg);
16109%}
16110
16111instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{
16112  match(Set cr (CmpI (AndI op1 op2) op3));
16113
16114  ins_cost(INSN_COST);
16115  format %{ "tstw $op1, $op2 # int" %}
16116  ins_encode %{
16117    __ tstw($op1$$Register, $op2$$Register);
16118  %}
16119  ins_pipe(ialu_reg_reg);
16120%}
16121
16122
16123// Conditional Far Branch
16124// Conditional Far Branch Unsigned
16125// TODO: fixme
16126
16127// counted loop end branch near
16128instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
16129%{
16130  match(CountedLoopEnd cmp cr);
16131
16132  effect(USE lbl);
16133
16134  ins_cost(BRANCH_COST);
16135  // short variant.
16136  // ins_short_branch(1);
16137  format %{ "b$cmp $lbl \t// counted loop end" %}
16138
16139  ins_encode(aarch64_enc_br_con(cmp, lbl));
16140
16141  ins_pipe(pipe_branch);
16142%}
16143
16144// counted loop end branch near Unsigned
16145instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl)
16146%{
16147  match(CountedLoopEnd cmp cr);
16148
16149  effect(USE lbl);
16150
16151  ins_cost(BRANCH_COST);
16152  // short variant.
16153  // ins_short_branch(1);
16154  format %{ "b$cmp $lbl \t// counted loop end unsigned" %}
16155
16156  ins_encode(aarch64_enc_br_conU(cmp, lbl));
16157
16158  ins_pipe(pipe_branch);
16159%}
16160
16161// counted loop end branch far
16162// counted loop end branch far unsigned
16163// TODO: fixme
16164
16165// ============================================================================
16166// inlined locking and unlocking
16167
16168instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
16169%{
16170  match(Set cr (FastLock object box));
16171  effect(TEMP tmp, TEMP tmp2);
16172
16173  // TODO
16174  // identify correct cost
16175  ins_cost(5 * INSN_COST);
16176  format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %}
16177
16178  ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2));
16179
16180  ins_pipe(pipe_serial);
16181%}
16182
16183instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
16184%{
16185  match(Set cr (FastUnlock object box));
16186  effect(TEMP tmp, TEMP tmp2);
16187
16188  ins_cost(5 * INSN_COST);
16189  format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %}
16190
16191  ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2));
16192
16193  ins_pipe(pipe_serial);
16194%}
16195
16196
16197// ============================================================================
16198// Safepoint Instructions
16199
16200// TODO
16201// provide a near and far version of this code
16202
16203instruct safePoint(rFlagsReg cr, iRegP poll)
16204%{
16205  match(SafePoint poll);
16206  effect(KILL cr);
16207
16208  format %{
16209    "ldrw zr, [$poll]\t# Safepoint: poll for GC"
16210  %}
16211  ins_encode %{
16212    __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type);
16213  %}
16214  ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem);
16215%}
16216
16217
16218// ============================================================================
16219// Procedure Call/Return Instructions
16220
16221// Call Java Static Instruction
16222
16223instruct CallStaticJavaDirect(method meth)
16224%{
16225  match(CallStaticJava);
16226
16227  effect(USE meth);
16228
16229  ins_cost(CALL_COST);
16230
16231  format %{ "call,static $meth \t// ==> " %}
16232
16233  ins_encode(aarch64_enc_java_static_call(meth),
16234             aarch64_enc_call_epilog);
16235
16236  ins_pipe(pipe_class_call);
16237%}
16238
16239// TO HERE
16240
16241// Call Java Dynamic Instruction
16242instruct CallDynamicJavaDirect(method meth)
16243%{
16244  match(CallDynamicJava);
16245
16246  effect(USE meth);
16247
16248  ins_cost(CALL_COST);
16249
16250  format %{ "CALL,dynamic $meth \t// ==> " %}
16251
16252  ins_encode(aarch64_enc_java_dynamic_call(meth),
16253             aarch64_enc_call_epilog);
16254
16255  ins_pipe(pipe_class_call);
16256%}
16257
16258// Call Runtime Instruction
16259
16260instruct CallRuntimeDirect(method meth)
16261%{
16262  match(CallRuntime);
16263
16264  effect(USE meth);
16265
16266  ins_cost(CALL_COST);
16267
16268  format %{ "CALL, runtime $meth" %}
16269
16270  ins_encode( aarch64_enc_java_to_runtime(meth) );
16271
16272  ins_pipe(pipe_class_call);
16273%}
16274
16275// Call Runtime Instruction
16276
16277instruct CallLeafDirect(method meth)
16278%{
16279  match(CallLeaf);
16280
16281  effect(USE meth);
16282
16283  ins_cost(CALL_COST);
16284
16285  format %{ "CALL, runtime leaf $meth" %}
16286
16287  ins_encode( aarch64_enc_java_to_runtime(meth) );
16288
16289  ins_pipe(pipe_class_call);
16290%}
16291
16292// Call Runtime Instruction
16293
16294instruct CallLeafNoFPDirect(method meth)
16295%{
16296  match(CallLeafNoFP);
16297
16298  effect(USE meth);
16299
16300  ins_cost(CALL_COST);
16301
16302  format %{ "CALL, runtime leaf nofp $meth" %}
16303
16304  ins_encode( aarch64_enc_java_to_runtime(meth) );
16305
16306  ins_pipe(pipe_class_call);
16307%}
16308
16309instruct CallNativeDirect(method meth)
16310%{
16311  match(CallNative);
16312
16313  effect(USE meth);
16314
16315  ins_cost(CALL_COST);
16316
16317  format %{ "CALL, native $meth" %}
16318
16319  ins_encode( aarch64_enc_java_to_runtime(meth) );
16320
16321  ins_pipe(pipe_class_call);
16322%}
16323
16324// Tail Call; Jump from runtime stub to Java code.
16325// Also known as an 'interprocedural jump'.
16326// Target of jump will eventually return to caller.
16327// TailJump below removes the return address.
16328instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_ptr)
16329%{
16330  match(TailCall jump_target method_ptr);
16331
16332  ins_cost(CALL_COST);
16333
16334  format %{ "br $jump_target\t# $method_ptr holds method" %}
16335
16336  ins_encode(aarch64_enc_tail_call(jump_target));
16337
16338  ins_pipe(pipe_class_call);
16339%}
16340
16341instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop)
16342%{
16343  match(TailJump jump_target ex_oop);
16344
16345  ins_cost(CALL_COST);
16346
16347  format %{ "br $jump_target\t# $ex_oop holds exception oop" %}
16348
16349  ins_encode(aarch64_enc_tail_jmp(jump_target));
16350
16351  ins_pipe(pipe_class_call);
16352%}
16353
16354// Create exception oop: created by stack-crawling runtime code.
16355// Created exception is now available to this handler, and is setup
16356// just prior to jumping to this handler. No code emitted.
16357// TODO check
16358// should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1
16359instruct CreateException(iRegP_R0 ex_oop)
16360%{
16361  match(Set ex_oop (CreateEx));
16362
16363  format %{ " -- \t// exception oop; no code emitted" %}
16364
16365  size(0);
16366
16367  ins_encode( /*empty*/ );
16368
16369  ins_pipe(pipe_class_empty);
16370%}
16371
16372// Rethrow exception: The exception oop will come in the first
16373// argument position. Then JUMP (not call) to the rethrow stub code.
16374instruct RethrowException() %{
16375  match(Rethrow);
16376  ins_cost(CALL_COST);
16377
16378  format %{ "b rethrow_stub" %}
16379
16380  ins_encode( aarch64_enc_rethrow() );
16381
16382  ins_pipe(pipe_class_call);
16383%}
16384
16385
16386// Return Instruction
16387// epilog node loads ret address into lr as part of frame pop
16388instruct Ret()
16389%{
16390  match(Return);
16391
16392  format %{ "ret\t// return register" %}
16393
16394  ins_encode( aarch64_enc_ret() );
16395
16396  ins_pipe(pipe_branch);
16397%}
16398
16399// Die now.
16400instruct ShouldNotReachHere() %{
16401  match(Halt);
16402
16403  ins_cost(CALL_COST);
16404  format %{ "ShouldNotReachHere" %}
16405
16406  ins_encode %{
16407    if (is_reachable()) {
16408      __ stop(_halt_reason);
16409    }
16410  %}
16411
16412  ins_pipe(pipe_class_default);
16413%}
16414
16415// ============================================================================
16416// Partial Subtype Check
16417//
16418// superklass array for an instance of the superklass.  Set a hidden
16419// internal cache on a hit (cache is checked with exposed code in
16420// gen_subtype_check()).  Return NZ for a miss or zero for a hit.  The
16421// encoding ALSO sets flags.
16422
16423instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr)
16424%{
16425  match(Set result (PartialSubtypeCheck sub super));
16426  effect(KILL cr, KILL temp);
16427
16428  ins_cost(1100);  // slightly larger than the next version
16429  format %{ "partialSubtypeCheck $result, $sub, $super" %}
16430
16431  ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
16432
16433  opcode(0x1); // Force zero of result reg on hit
16434
16435  ins_pipe(pipe_class_memory);
16436%}
16437
16438instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr)
16439%{
16440  match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
16441  effect(KILL temp, KILL result);
16442
16443  ins_cost(1100);  // slightly larger than the next version
16444  format %{ "partialSubtypeCheck $result, $sub, $super == 0" %}
16445
16446  ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result));
16447
16448  opcode(0x0); // Don't zero result reg on hit
16449
16450  ins_pipe(pipe_class_memory);
16451%}
16452
16453instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16454                        iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
16455%{
16456  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
16457  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16458  effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16459
16460  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
16461  ins_encode %{
16462    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16463    __ string_compare($str1$$Register, $str2$$Register,
16464                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
16465                      $tmp1$$Register, $tmp2$$Register,
16466                      fnoreg, fnoreg, fnoreg, StrIntrinsicNode::UU);
16467  %}
16468  ins_pipe(pipe_class_memory);
16469%}
16470
16471instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16472                        iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr)
16473%{
16474  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
16475  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16476  effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16477
16478  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1" %}
16479  ins_encode %{
16480    __ string_compare($str1$$Register, $str2$$Register,
16481                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
16482                      $tmp1$$Register, $tmp2$$Register,
16483                      fnoreg, fnoreg, fnoreg, StrIntrinsicNode::LL);
16484  %}
16485  ins_pipe(pipe_class_memory);
16486%}
16487
16488instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16489                        iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16490                        vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
16491%{
16492  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
16493  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16494  effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
16495         USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16496
16497  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
16498  ins_encode %{
16499    __ string_compare($str1$$Register, $str2$$Register,
16500                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
16501                      $tmp1$$Register, $tmp2$$Register,
16502                      $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
16503                      $vtmp3$$FloatRegister, StrIntrinsicNode::UL);
16504  %}
16505  ins_pipe(pipe_class_memory);
16506%}
16507
16508instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
16509                        iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2,
16510                        vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr)
16511%{
16512  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
16513  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
16514  effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3,
16515         USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
16516
16517  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %}
16518  ins_encode %{
16519    __ string_compare($str1$$Register, $str2$$Register,
16520                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
16521                      $tmp1$$Register, $tmp2$$Register,
16522                      $vtmp1$$FloatRegister, $vtmp2$$FloatRegister,
16523                      $vtmp3$$FloatRegister,StrIntrinsicNode::LU);
16524  %}
16525  ins_pipe(pipe_class_memory);
16526%}
16527
16528instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
16529       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
16530       iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
16531%{
16532  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
16533  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
16534  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
16535         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
16536  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %}
16537
16538  ins_encode %{
16539    __ string_indexof($str1$$Register, $str2$$Register,
16540                      $cnt1$$Register, $cnt2$$Register,
16541                      $tmp1$$Register, $tmp2$$Register,
16542                      $tmp3$$Register, $tmp4$$Register,
16543                      $tmp5$$Register, $tmp6$$Register,
16544                      -1, $result$$Register, StrIntrinsicNode::UU);
16545  %}
16546  ins_pipe(pipe_class_memory);
16547%}
16548
16549instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
16550       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
16551       iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
16552%{
16553  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
16554  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
16555  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
16556         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
16557  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %}
16558
16559  ins_encode %{
16560    __ string_indexof($str1$$Register, $str2$$Register,
16561                      $cnt1$$Register, $cnt2$$Register,
16562                      $tmp1$$Register, $tmp2$$Register,
16563                      $tmp3$$Register, $tmp4$$Register,
16564                      $tmp5$$Register, $tmp6$$Register,
16565                      -1, $result$$Register, StrIntrinsicNode::LL);
16566  %}
16567  ins_pipe(pipe_class_memory);
16568%}
16569
16570instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
16571       iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3,
16572       iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr)
16573%{
16574  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
16575  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
16576  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
16577         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr);
16578  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %}
16579
16580  ins_encode %{
16581    __ string_indexof($str1$$Register, $str2$$Register,
16582                      $cnt1$$Register, $cnt2$$Register,
16583                      $tmp1$$Register, $tmp2$$Register,
16584                      $tmp3$$Register, $tmp4$$Register,
16585                      $tmp5$$Register, $tmp6$$Register,
16586                      -1, $result$$Register, StrIntrinsicNode::UL);
16587  %}
16588  ins_pipe(pipe_class_memory);
16589%}
16590
16591instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
16592                 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
16593                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
16594%{
16595  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
16596  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
16597  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
16598         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
16599  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %}
16600
16601  ins_encode %{
16602    int icnt2 = (int)$int_cnt2$$constant;
16603    __ string_indexof($str1$$Register, $str2$$Register,
16604                      $cnt1$$Register, zr,
16605                      $tmp1$$Register, $tmp2$$Register,
16606                      $tmp3$$Register, $tmp4$$Register, zr, zr,
16607                      icnt2, $result$$Register, StrIntrinsicNode::UU);
16608  %}
16609  ins_pipe(pipe_class_memory);
16610%}
16611
16612instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
16613                 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
16614                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
16615%{
16616  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
16617  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
16618  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
16619         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
16620  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %}
16621
16622  ins_encode %{
16623    int icnt2 = (int)$int_cnt2$$constant;
16624    __ string_indexof($str1$$Register, $str2$$Register,
16625                      $cnt1$$Register, zr,
16626                      $tmp1$$Register, $tmp2$$Register,
16627                      $tmp3$$Register, $tmp4$$Register, zr, zr,
16628                      icnt2, $result$$Register, StrIntrinsicNode::LL);
16629  %}
16630  ins_pipe(pipe_class_memory);
16631%}
16632
16633instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
16634                 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
16635                 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr)
16636%{
16637  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
16638  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
16639  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
16640         TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
16641  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %}
16642
16643  ins_encode %{
16644    int icnt2 = (int)$int_cnt2$$constant;
16645    __ string_indexof($str1$$Register, $str2$$Register,
16646                      $cnt1$$Register, zr,
16647                      $tmp1$$Register, $tmp2$$Register,
16648                      $tmp3$$Register, $tmp4$$Register, zr, zr,
16649                      icnt2, $result$$Register, StrIntrinsicNode::UL);
16650  %}
16651  ins_pipe(pipe_class_memory);
16652%}
16653
16654instruct string_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
16655                              iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
16656                              iRegINoSp tmp3, rFlagsReg cr)
16657%{
16658  match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
16659  predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U);
16660  effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
16661         TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
16662
16663  format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result" %}
16664
16665  ins_encode %{
16666    __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
16667                           $result$$Register, $tmp1$$Register, $tmp2$$Register,
16668                           $tmp3$$Register);
16669  %}
16670  ins_pipe(pipe_class_memory);
16671%}
16672
16673instruct stringL_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
16674                              iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,
16675                              iRegINoSp tmp3, rFlagsReg cr)
16676%{
16677  match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
16678  predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L);
16679  effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
16680         TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
16681
16682  format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result" %}
16683
16684  ins_encode %{
16685    __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
16686                           $result$$Register, $tmp1$$Register, $tmp2$$Register,
16687                           $tmp3$$Register);
16688  %}
16689  ins_pipe(pipe_class_memory);
16690%}
16691
16692instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
16693                        iRegI_R0 result, rFlagsReg cr)
16694%{
16695  predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
16696  match(Set result (StrEquals (Binary str1 str2) cnt));
16697  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
16698
16699  format %{ "String Equals $str1,$str2,$cnt -> $result" %}
16700  ins_encode %{
16701    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16702    __ string_equals($str1$$Register, $str2$$Register,
16703                     $result$$Register, $cnt$$Register, 1);
16704  %}
16705  ins_pipe(pipe_class_memory);
16706%}
16707
16708instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
16709                        iRegI_R0 result, rFlagsReg cr)
16710%{
16711  predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
16712  match(Set result (StrEquals (Binary str1 str2) cnt));
16713  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
16714
16715  format %{ "String Equals $str1,$str2,$cnt -> $result" %}
16716  ins_encode %{
16717    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
16718    __ string_equals($str1$$Register, $str2$$Register,
16719                     $result$$Register, $cnt$$Register, 2);
16720  %}
16721  ins_pipe(pipe_class_memory);
16722%}
16723
16724instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
16725                       iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
16726                       iRegP_R10 tmp, rFlagsReg cr)
16727%{
16728  predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
16729  match(Set result (AryEq ary1 ary2));
16730  effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
16731
16732  format %{ "Array Equals $ary1,ary2 -> $result    // KILL $tmp" %}
16733  ins_encode %{
16734    address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
16735                                   $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
16736                                   $result$$Register, $tmp$$Register, 1);
16737    if (tpc == NULL) {
16738      ciEnv::current()->record_failure("CodeCache is full");
16739      return;
16740    }
16741  %}
16742  ins_pipe(pipe_class_memory);
16743%}
16744
16745instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
16746                       iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3,
16747                       iRegP_R10 tmp, rFlagsReg cr)
16748%{
16749  predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
16750  match(Set result (AryEq ary1 ary2));
16751  effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
16752
16753  format %{ "Array Equals $ary1,ary2 -> $result    // KILL $tmp" %}
16754  ins_encode %{
16755    address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
16756                                   $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
16757                                   $result$$Register, $tmp$$Register, 2);
16758    if (tpc == NULL) {
16759      ciEnv::current()->record_failure("CodeCache is full");
16760      return;
16761    }
16762  %}
16763  ins_pipe(pipe_class_memory);
16764%}
16765
16766instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr)
16767%{
16768  match(Set result (HasNegatives ary1 len));
16769  effect(USE_KILL ary1, USE_KILL len, KILL cr);
16770  format %{ "has negatives byte[] $ary1,$len -> $result" %}
16771  ins_encode %{
16772    address tpc = __ has_negatives($ary1$$Register, $len$$Register, $result$$Register);
16773    if (tpc == NULL) {
16774      ciEnv::current()->record_failure("CodeCache is full");
16775      return;
16776    }
16777  %}
16778  ins_pipe( pipe_slow );
16779%}
16780
16781// fast char[] to byte[] compression
16782instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
16783                         vRegD_V0 tmp1, vRegD_V1 tmp2,
16784                         vRegD_V2 tmp3, vRegD_V3 tmp4,
16785                         iRegI_R0 result, rFlagsReg cr)
16786%{
16787  match(Set result (StrCompressedCopy src (Binary dst len)));
16788  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
16789
16790  format %{ "String Compress $src,$dst -> $result    // KILL R1, R2, R3, R4" %}
16791  ins_encode %{
16792    __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
16793                           $tmp1$$FloatRegister, $tmp2$$FloatRegister,
16794                           $tmp3$$FloatRegister, $tmp4$$FloatRegister,
16795                           $result$$Register);
16796  %}
16797  ins_pipe( pipe_slow );
16798%}
16799
16800// fast byte[] to char[] inflation
16801instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len,
16802                        vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr)
16803%{
16804  match(Set dummy (StrInflatedCopy src (Binary dst len)));
16805  effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
16806
16807  format %{ "String Inflate $src,$dst    // KILL $tmp1, $tmp2" %}
16808  ins_encode %{
16809    address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
16810                                        $tmp1$$FloatRegister, $tmp2$$FloatRegister,
16811                                        $tmp3$$FloatRegister, $tmp4$$Register);
16812    if (tpc == NULL) {
16813      ciEnv::current()->record_failure("CodeCache is full");
16814      return;
16815    }
16816  %}
16817  ins_pipe(pipe_class_memory);
16818%}
16819
16820// encode char[] to byte[] in ISO_8859_1
16821instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
16822                          vRegD_V0 Vtmp1, vRegD_V1 Vtmp2,
16823                          vRegD_V2 Vtmp3, vRegD_V3 Vtmp4,
16824                          iRegI_R0 result, rFlagsReg cr)
16825%{
16826  match(Set result (EncodeISOArray src (Binary dst len)));
16827  effect(USE_KILL src, USE_KILL dst, USE_KILL len,
16828         KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr);
16829
16830  format %{ "Encode array $src,$dst,$len -> $result" %}
16831  ins_encode %{
16832    __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
16833         $result$$Register, $Vtmp1$$FloatRegister,  $Vtmp2$$FloatRegister,
16834         $Vtmp3$$FloatRegister,  $Vtmp4$$FloatRegister);
16835  %}
16836  ins_pipe( pipe_class_memory );
16837%}
16838
16839// ============================================================================
16840// This name is KNOWN by the ADLC and cannot be changed.
16841// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
16842// for this guy.
16843instruct tlsLoadP(thread_RegP dst)
16844%{
16845  match(Set dst (ThreadLocal));
16846
16847  ins_cost(0);
16848
16849  format %{ " -- \t// $dst=Thread::current(), empty" %}
16850
16851  size(0);
16852
16853  ins_encode( /*empty*/ );
16854
16855  ins_pipe(pipe_class_empty);
16856%}
16857
16858//----------PEEPHOLE RULES-----------------------------------------------------
16859// These must follow all instruction definitions as they use the names
16860// defined in the instructions definitions.
16861//
16862// peepmatch ( root_instr_name [preceding_instruction]* );
16863//
16864// peepconstraint %{
16865// (instruction_number.operand_name relational_op instruction_number.operand_name
16866//  [, ...] );
16867// // instruction numbers are zero-based using left to right order in peepmatch
16868//
16869// peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
16870// // provide an instruction_number.operand_name for each operand that appears
16871// // in the replacement instruction's match rule
16872//
16873// ---------VM FLAGS---------------------------------------------------------
16874//
16875// All peephole optimizations can be turned off using -XX:-OptoPeephole
16876//
16877// Each peephole rule is given an identifying number starting with zero and
16878// increasing by one in the order seen by the parser.  An individual peephole
16879// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
16880// on the command-line.
16881//
16882// ---------CURRENT LIMITATIONS----------------------------------------------
16883//
16884// Only match adjacent instructions in same basic block
16885// Only equality constraints
16886// Only constraints between operands, not (0.dest_reg == RAX_enc)
16887// Only one replacement instruction
16888//
16889// ---------EXAMPLE----------------------------------------------------------
16890//
16891// // pertinent parts of existing instructions in architecture description
16892// instruct movI(iRegINoSp dst, iRegI src)
16893// %{
16894//   match(Set dst (CopyI src));
16895// %}
16896//
16897// instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr)
16898// %{
16899//   match(Set dst (AddI dst src));
16900//   effect(KILL cr);
16901// %}
16902//
16903// // Change (inc mov) to lea
16904// peephole %{
16905//   // increment preceeded by register-register move
16906//   peepmatch ( incI_iReg movI );
16907//   // require that the destination register of the increment
16908//   // match the destination register of the move
16909//   peepconstraint ( 0.dst == 1.dst );
16910//   // construct a replacement instruction that sets
16911//   // the destination to ( move's source register + one )
16912//   peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) );
16913// %}
16914//
16915
16916// Implementation no longer uses movX instructions since
16917// machine-independent system no longer uses CopyX nodes.
16918//
16919// peephole
16920// %{
16921//   peepmatch (incI_iReg movI);
16922//   peepconstraint (0.dst == 1.dst);
16923//   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
16924// %}
16925
16926// peephole
16927// %{
16928//   peepmatch (decI_iReg movI);
16929//   peepconstraint (0.dst == 1.dst);
16930//   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
16931// %}
16932
16933// peephole
16934// %{
16935//   peepmatch (addI_iReg_imm movI);
16936//   peepconstraint (0.dst == 1.dst);
16937//   peepreplace (leaI_iReg_immI(0.dst 1.src 0.src));
16938// %}
16939
16940// peephole
16941// %{
16942//   peepmatch (incL_iReg movL);
16943//   peepconstraint (0.dst == 1.dst);
16944//   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
16945// %}
16946
16947// peephole
16948// %{
16949//   peepmatch (decL_iReg movL);
16950//   peepconstraint (0.dst == 1.dst);
16951//   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
16952// %}
16953
16954// peephole
16955// %{
16956//   peepmatch (addL_iReg_imm movL);
16957//   peepconstraint (0.dst == 1.dst);
16958//   peepreplace (leaL_iReg_immL(0.dst 1.src 0.src));
16959// %}
16960
16961// peephole
16962// %{
16963//   peepmatch (addP_iReg_imm movP);
16964//   peepconstraint (0.dst == 1.dst);
16965//   peepreplace (leaP_iReg_imm(0.dst 1.src 0.src));
16966// %}
16967
16968// // Change load of spilled value to only a spill
16969// instruct storeI(memory mem, iRegI src)
16970// %{
16971//   match(Set mem (StoreI mem src));
16972// %}
16973//
16974// instruct loadI(iRegINoSp dst, memory mem)
16975// %{
16976//   match(Set dst (LoadI mem));
16977// %}
16978//
16979
16980//----------SMARTSPILL RULES---------------------------------------------------
16981// These must follow all instruction definitions as they use the names
16982// defined in the instructions definitions.
16983
16984// Local Variables:
16985// mode: c++
16986// End:
16987